add optimization for the simplest dense-only concat case
#include "generic_concat.h"
#include "generic_join.h"
#include <vespa/eval/eval/value.h>
+#include <vespa/eval/tensor/dense/dense_tensor_view.h>
#include <vespa/vespalib/util/overload.h>
#include <vespa/vespalib/util/stash.h>
#include <vespa/vespalib/util/typify.h>
@@ -93,8 +94,36 @@ void my_generic_concat_op(State &state, uint64_t param_in) {
state.pop_pop_push(result_ref);
}
+template <typename LCT, typename RCT>
+void my_dense_simple_concat_op(State &state, uint64_t param_in) {
+ using OCT = typename eval::UnifyCellTypes<LCT, RCT>::type;
+ const auto &param = unwrap_param<ConcatParam>(param_in);
+ const Value &lhs = state.peek(1);
+ const Value &rhs = state.peek(0);
+ const auto a = lhs.cells().typify<LCT>();
+ const auto b = rhs.cells().typify<RCT>();
+ ArrayRef<OCT> result = state.stash.create_array<OCT>(a.size() + b.size());
+ auto pos = result.begin();
+ for (size_t i = 0; i < a.size(); ++i) {
+ *pos++ = a[i];
+ }
+ for (size_t i = 0; i < b.size(); ++i) {
+ *pos++ = b[i];
+ }
+ Value &ref = state.stash.create<tensor::DenseTensorView>(param.res_type, TypedCells(result));
+ state.pop_pop_push(ref);
+}
+
struct SelectGenericConcatOp {
- template <typename LCT, typename RCT> static auto invoke() {
+ template <typename LCT, typename RCT> static auto invoke(const ConcatParam &param) {
+ if (param.sparse_plan.sources.empty() && param.res_type.is_dense()) {
+ auto & dp = param.dense_plan;
+ if ((dp.output_size == (dp.left.input_size + dp.right.input_size))
+ && (dp.right_offset == dp.left.input_size))
+ {
+ return my_dense_simple_concat_op<LCT, RCT>;
+ }
+ }
return my_generic_concat_op<LCT, RCT>;
}
};
@@ -168,7 +197,7 @@ GenericConcat::make_instruction(const ValueType &lhs_type, const ValueType &rhs_
{
auto &param = stash.create<ConcatParam>(lhs_type, rhs_type, dimension, factory);
auto fun = typify_invoke<2,TypifyCellType,SelectGenericConcatOp>(
- lhs_type.cell_type(), rhs_type.cell_type());
+ lhs_type.cell_type(), rhs_type.cell_type(), param);
return Instruction(fun, wrap_param<ConcatParam>(param));
}
