From 16d7902bc1fc911d69d82b0e40c3aef54651a299 Mon Sep 17 00:00:00 2001 From: Arne Juul Date: Thu, 8 Oct 2020 08:27:39 +0000 Subject: add optimization for the simplest dense-only concat case --- eval/src/vespa/eval/instruction/generic_concat.cpp | 33 ++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/eval/src/vespa/eval/instruction/generic_concat.cpp b/eval/src/vespa/eval/instruction/generic_concat.cpp index cf4a98b004e..91ce75b2238 100644 --- a/eval/src/vespa/eval/instruction/generic_concat.cpp +++ b/eval/src/vespa/eval/instruction/generic_concat.cpp @@ -3,6 +3,7 @@ #include "generic_concat.h" #include "generic_join.h" #include +#include #include #include #include @@ -93,8 +94,36 @@ void my_generic_concat_op(State &state, uint64_t param_in) { state.pop_pop_push(result_ref); } +template +void my_dense_simple_concat_op(State &state, uint64_t param_in) { + using OCT = typename eval::UnifyCellTypes::type; + const auto ¶m = unwrap_param(param_in); + const Value &lhs = state.peek(1); + const Value &rhs = state.peek(0); + const auto a = lhs.cells().typify(); + const auto b = rhs.cells().typify(); + ArrayRef result = state.stash.create_array(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(param.res_type, TypedCells(result)); + state.pop_pop_push(ref); +} + struct SelectGenericConcatOp { - template static auto invoke() { + template static auto invoke(const ConcatParam ¶m) { + 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; + } + } return my_generic_concat_op; } }; @@ -168,7 +197,7 @@ GenericConcat::make_instruction(const ValueType &lhs_type, const ValueType &rhs_ { auto ¶m = stash.create(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(param)); } -- cgit v1.2.3 From 08ca6183f9f5a66ca9a1fe7c3150a4bd6761bd9d Mon Sep 17 00:00:00 2001 From: Arne Juul Date: Thu, 8 Oct 2020 16:06:20 +0000 Subject: handle concat(vector of float, double) --- .../generic_concat/generic_concat_test.cpp | 3 +++ eval/src/vespa/eval/instruction/generic_concat.cpp | 25 +++++++++++----------- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/eval/src/tests/instruction/generic_concat/generic_concat_test.cpp b/eval/src/tests/instruction/generic_concat/generic_concat_test.cpp index 8cf18e25928..5405f957afc 100644 --- a/eval/src/tests/instruction/generic_concat/generic_concat_test.cpp +++ b/eval/src/tests/instruction/generic_concat/generic_concat_test.cpp @@ -21,6 +21,8 @@ using vespalib::make_string_short::fmt; std::vector concat_layouts = { {}, {}, {}, {y(5)}, + float_cells({y(5)}), {}, + {}, float_cells({y(5)}), {y(5)}, {}, {y(2)}, {y(3)}, {y(2)}, {x(3)}, @@ -39,6 +41,7 @@ std::vector concat_layouts = { {y(2),x(5),z(2)}, {y(3),x(5),z(2)}, {y(3),x(5)}, {x(5),z(7)}, float_cells({y(3),x(5)}), {x(5),z(7)}, + float_cells({y(3),x(5)}), {}, {y(3),x(5)}, float_cells({x(5),z(7)}), float_cells({y(3),x(5)}), float_cells({x(5),z(7)}), {x({"a","b","c"})}, {x({"a","b","c"})}, diff --git a/eval/src/vespa/eval/instruction/generic_concat.cpp b/eval/src/vespa/eval/instruction/generic_concat.cpp index 91ce75b2238..7c55afafcc1 100644 --- a/eval/src/vespa/eval/instruction/generic_concat.cpp +++ b/eval/src/vespa/eval/instruction/generic_concat.cpp @@ -45,14 +45,13 @@ struct ConcatParam } }; -template +template std::unique_ptr generic_concat(const Value &a, const Value &b, const SparseJoinPlan &sparse_plan, const DenseConcatPlan &dense_plan, const ValueType &res_type, const ValueBuilderFactory &factory) { - using OCT = typename eval::UnifyCellTypes::type; auto a_cells = a.cells().typify(); auto b_cells = b.cells().typify(); SparseJoinState sparse(sparse_plan, a.index(), b.index()); @@ -82,21 +81,22 @@ generic_concat(const Value &a, const Value &b, return builder->build(std::move(builder)); } -template +template void my_generic_concat_op(State &state, uint64_t param_in) { const auto ¶m = unwrap_param(param_in); const Value &lhs = state.peek(1); const Value &rhs = state.peek(0); - auto res_value = generic_concat(lhs, rhs, param.sparse_plan, param.dense_plan, - param.res_type, param.factory); + auto res_value = generic_concat( + lhs, rhs, + param.sparse_plan, param.dense_plan, + param.res_type, param.factory); auto &result = state.stash.create>(std::move(res_value)); const Value &result_ref = *(result.get()); state.pop_pop_push(result_ref); } -template +template void my_dense_simple_concat_op(State &state, uint64_t param_in) { - using OCT = typename eval::UnifyCellTypes::type; const auto ¶m = unwrap_param(param_in); const Value &lhs = state.peek(1); const Value &rhs = state.peek(0); @@ -115,16 +115,16 @@ void my_dense_simple_concat_op(State &state, uint64_t param_in) { } struct SelectGenericConcatOp { - template static auto invoke(const ConcatParam ¶m) { + template static auto invoke(const ConcatParam ¶m) { 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; + return my_dense_simple_concat_op; } } - return my_generic_concat_op; + return my_generic_concat_op; } }; @@ -196,8 +196,9 @@ GenericConcat::make_instruction(const ValueType &lhs_type, const ValueType &rhs_ const ValueBuilderFactory &factory, Stash &stash) { auto ¶m = stash.create(lhs_type, rhs_type, dimension, factory); - auto fun = typify_invoke<2,TypifyCellType,SelectGenericConcatOp>( - lhs_type.cell_type(), rhs_type.cell_type(), param); + auto fun = typify_invoke<3,TypifyCellType,SelectGenericConcatOp>( + lhs_type.cell_type(), rhs_type.cell_type(), param.res_type.cell_type(), + param); return Instruction(fun, wrap_param(param)); } -- cgit v1.2.3