diff options
author | Arne H Juul <arnej27959@users.noreply.github.com> | 2020-12-08 14:53:25 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-12-08 14:53:25 +0100 |
commit | 6ca5863b37cb94b1ebb223cbe3a44a4554f845eb (patch) | |
tree | 9c593a0ffbc04d2ecd44ac6ab1fddac401b6ca15 | |
parent | d1e33a9420805f5d416ca55ed79497fd28f20216 (diff) | |
parent | 73b6d97d322cad6e9da7dfe0808ee91ef3a0ea7e (diff) |
Merge pull request #15738 from vespa-engine/arnej/remove-old-tensors-and-engine
Arnej/remove old tensors and engine
119 files changed, 8 insertions, 4391 deletions
diff --git a/eval/CMakeLists.txt b/eval/CMakeLists.txt index d9dc7e587b0..7022569e6a3 100644 --- a/eval/CMakeLists.txt +++ b/eval/CMakeLists.txt @@ -55,9 +55,7 @@ vespa_define_module( src/tests/instruction/join_with_number src/tests/streamed/value src/tests/tensor/dense_add_dimension_optimizer - src/tests/tensor/dense_dimension_combiner src/tests/tensor/dense_fast_rename_optimizer - src/tests/tensor/dense_generic_join src/tests/tensor/dense_inplace_join_function src/tests/tensor/dense_pow_as_map_optimizer src/tests/tensor/dense_remove_dimension_optimizer @@ -66,14 +64,11 @@ vespa_define_module( src/tests/tensor/dense_simple_map_function src/tests/tensor/dense_single_reduce_function src/tests/tensor/dense_tensor_create_function - src/tests/tensor/direct_dense_tensor_builder - src/tests/tensor/direct_sparse_tensor_builder src/tests/tensor/instruction_benchmark src/tests/tensor/onnx_wrapper src/tests/tensor/partial_add src/tests/tensor/partial_modify src/tests/tensor/partial_remove - src/tests/tensor/tensor_address src/tests/tensor/tensor_conformance src/tests/tensor/typed_cells src/tests/tensor/vector_from_doubles_function @@ -89,5 +84,4 @@ vespa_define_module( src/vespa/eval/streamed src/vespa/eval/tensor src/vespa/eval/tensor/dense - src/vespa/eval/tensor/sparse ) diff --git a/eval/src/tests/eval/tensor_lambda/tensor_lambda_test.cpp b/eval/src/tests/eval/tensor_lambda/tensor_lambda_test.cpp index f1c8e6d3a5e..73a3648a34c 100644 --- a/eval/src/tests/eval/tensor_lambda/tensor_lambda_test.cpp +++ b/eval/src/tests/eval/tensor_lambda/tensor_lambda_test.cpp @@ -7,9 +7,7 @@ #include <vespa/eval/tensor/dense/dense_replace_type_function.h> #include <vespa/eval/instruction/dense_cell_range_function.h> #include <vespa/eval/instruction/dense_lambda_peek_function.h> -#include <vespa/eval/tensor/dense/dense_lambda_function.h> #include <vespa/eval/tensor/dense/dense_fast_rename_optimizer.h> -#include <vespa/eval/tensor/dense/dense_tensor.h> #include <vespa/eval/eval/test/tensor_model.hpp> #include <vespa/eval/eval/test/eval_fixture.h> #include <vespa/eval/eval/tensor_nodes.h> diff --git a/eval/src/tests/eval/value_cache/tensor_loader_test.cpp b/eval/src/tests/eval/value_cache/tensor_loader_test.cpp index 648a6c25c28..3ec57e0eecb 100644 --- a/eval/src/tests/eval/value_cache/tensor_loader_test.cpp +++ b/eval/src/tests/eval/value_cache/tensor_loader_test.cpp @@ -4,7 +4,6 @@ #include <vespa/eval/eval/simple_value.h> #include <vespa/eval/eval/value_codec.h> #include <vespa/eval/eval/tensor_spec.h> -#include <vespa/eval/eval/tensor.h> using namespace vespalib::eval; diff --git a/eval/src/tests/tensor/dense_add_dimension_optimizer/dense_add_dimension_optimizer_test.cpp b/eval/src/tests/tensor/dense_add_dimension_optimizer/dense_add_dimension_optimizer_test.cpp index 4b2ca3ae4ae..0e8e50daae5 100644 --- a/eval/src/tests/tensor/dense_add_dimension_optimizer/dense_add_dimension_optimizer_test.cpp +++ b/eval/src/tests/tensor/dense_add_dimension_optimizer/dense_add_dimension_optimizer_test.cpp @@ -5,7 +5,6 @@ #include <vespa/eval/eval/tensor_function.h> #include <vespa/eval/tensor/dense/dense_replace_type_function.h> #include <vespa/eval/tensor/dense/dense_fast_rename_optimizer.h> -#include <vespa/eval/tensor/dense/dense_tensor.h> #include <vespa/eval/eval/test/tensor_model.hpp> #include <vespa/eval/eval/test/eval_fixture.h> diff --git a/eval/src/tests/tensor/dense_fast_rename_optimizer/dense_fast_rename_optimizer_test.cpp b/eval/src/tests/tensor/dense_fast_rename_optimizer/dense_fast_rename_optimizer_test.cpp index 681b1987a6d..52afde0e92c 100644 --- a/eval/src/tests/tensor/dense_fast_rename_optimizer/dense_fast_rename_optimizer_test.cpp +++ b/eval/src/tests/tensor/dense_fast_rename_optimizer/dense_fast_rename_optimizer_test.cpp @@ -4,7 +4,6 @@ #include <vespa/eval/eval/tensor_function.h> #include <vespa/eval/tensor/dense/dense_replace_type_function.h> #include <vespa/eval/tensor/dense/dense_fast_rename_optimizer.h> -#include <vespa/eval/tensor/dense/dense_tensor.h> #include <vespa/eval/eval/test/tensor_model.hpp> #include <vespa/eval/eval/test/eval_fixture.h> diff --git a/eval/src/tests/tensor/dense_generic_join/CMakeLists.txt b/eval/src/tests/tensor/dense_generic_join/CMakeLists.txt deleted file mode 100644 index 1fbb35cb2b8..00000000000 --- a/eval/src/tests/tensor/dense_generic_join/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -vespa_add_executable(eval_dense_generic_join_test_app TEST - SOURCES - dense_generic_join_test.cpp - DEPENDS - vespaeval -) -vespa_add_test(NAME eval_dense_generic_join_test_app COMMAND eval_dense_generic_join_test_app) diff --git a/eval/src/tests/tensor/dense_generic_join/dense_generic_join_test.cpp b/eval/src/tests/tensor/dense_generic_join/dense_generic_join_test.cpp deleted file mode 100644 index faf6bed2786..00000000000 --- a/eval/src/tests/tensor/dense_generic_join/dense_generic_join_test.cpp +++ /dev/null @@ -1,124 +0,0 @@ -// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#include <vespa/vespalib/testkit/test_kit.h> -#include <vespa/eval/eval/tensor_function.h> -#include <vespa/eval/tensor/dense/typed_dense_tensor_builder.h> -#include <vespa/eval/tensor/dense/dense_tensor.h> -#include <vespa/eval/eval/test/tensor_model.hpp> -#include <vespa/eval/eval/test/eval_fixture.h> - -#include <vespa/vespalib/util/stringfmt.h> -#include <vespa/vespalib/util/stash.h> - -using namespace vespalib; -using namespace vespalib::eval; -using namespace vespalib::eval::test; -using namespace vespalib::tensor; -using namespace vespalib::eval::tensor_function; - -const ValueBuilderFactory &prod_factory = FastValueBuilderFactory::get(); - -double seq_value = 0.0; - -struct GlobalSequence : public Sequence { - GlobalSequence() {} - double operator[](size_t) const override { - seq_value += 1.0; - return seq_value; - } - ~GlobalSequence() {} -}; -GlobalSequence seq; - -EvalFixture::ParamRepo make_params() { - return EvalFixture::ParamRepo() - .add("con_x5_A", spec({x(5) }, seq)) - .add("con_x5y3_B", spec({x(5),y(3) }, seq)) - .add("con_x5z4_C", spec({x(5), z(4)}, seq)) - .add("con_x5y3z4_D", spec({x(5),y(3),z(4)}, seq)) - .add("con_y3_E", spec({ y(3) }, seq)) - .add("con_y3z4_F", spec({ y(3),z(4)}, seq)) - .add("con_z4_G", spec({ z(4)}, seq)) - .add("con_x5f_H", spec({x(5) }, seq), "tensor<float>(x[5])") - .add("con_x5y3_I", spec({x(5),y(3) }, seq), "tensor<float>(x[5],y[3])") - .add("con_x5z4_J", spec({x(5), z(4)}, seq), "tensor<float>(x[5],z[4])") - .add("con_x5y3z4_K", spec({x(5),y(3),z(4)}, seq), "tensor<float>(x[5],y[3],z[4])") - .add("con_y3_L", spec({ y(3) }, seq), "tensor<float>(y[3])") - .add("con_y3z4_M", spec({ y(3),z(4)}, seq), "tensor<float>(y[3],z[4])))") - .add("con_z4_N", spec({ z(4)}, seq), "tensor<float>(z[4]))") - .add("con_y2", spec({y(5)}, seq)) - .add("con_y2f", spec({y(5)}, seq), "tensor<float>(y[2]))"); -} -EvalFixture::ParamRepo param_repo = make_params(); - -void verify_equal(const vespalib::string &expr) { - EvalFixture fixture(prod_factory, expr, param_repo, true, true); - EXPECT_EQUAL(fixture.result(), EvalFixture::ref(expr, param_repo)); -} - - -TEST("require that non-overlapping dense join works") { - TEST_DO(verify_equal("con_x5_A-con_y3_E")); - TEST_DO(verify_equal("con_x5_A+con_y3_E")); - TEST_DO(verify_equal("con_x5_A*con_y3_E")); - - TEST_DO(verify_equal("con_x5_A-con_y3z4_F")); - TEST_DO(verify_equal("con_x5_A+con_y3z4_F")); - TEST_DO(verify_equal("con_x5_A*con_y3z4_F")); - - TEST_DO(verify_equal("con_x5_A-con_z4_G")); - TEST_DO(verify_equal("con_x5_A+con_z4_G")); - TEST_DO(verify_equal("con_x5_A*con_z4_G")); - - TEST_DO(verify_equal("con_x5y3_B-con_z4_G")); - TEST_DO(verify_equal("con_x5y3_B+con_z4_G")); - TEST_DO(verify_equal("con_x5y3_B*con_z4_G")); - - TEST_DO(verify_equal("con_y3_E-con_z4_G")); - TEST_DO(verify_equal("con_y3_E+con_z4_G")); - TEST_DO(verify_equal("con_y3_E*con_z4_G")); -} - -TEST("require that overlapping dense join works") { - TEST_DO(verify_equal("con_x5_A-con_x5y3_B")); - TEST_DO(verify_equal("con_x5_A+con_x5y3_B")); - TEST_DO(verify_equal("con_x5_A*con_x5y3_B")); - - TEST_DO(verify_equal("con_x5_A-con_x5z4_C")); - TEST_DO(verify_equal("con_x5_A+con_x5z4_C")); - TEST_DO(verify_equal("con_x5_A*con_x5z4_C")); - - TEST_DO(verify_equal("con_x5y3_B-con_y3_E")); - TEST_DO(verify_equal("con_x5y3_B+con_y3_E")); - TEST_DO(verify_equal("con_x5y3_B*con_y3_E")); - - TEST_DO(verify_equal("con_x5y3_B-con_y3z4_F")); - TEST_DO(verify_equal("con_x5y3_B+con_y3z4_F")); - TEST_DO(verify_equal("con_x5y3_B*con_y3z4_F")); - - TEST_DO(verify_equal("con_x5y3z4_D-con_x5y3_B")); - TEST_DO(verify_equal("con_x5y3z4_D+con_x5y3_B")); - TEST_DO(verify_equal("con_x5y3z4_D*con_x5y3_B")); - - TEST_DO(verify_equal("con_x5y3z4_D-con_x5z4_C")); - TEST_DO(verify_equal("con_x5y3z4_D+con_x5z4_C")); - TEST_DO(verify_equal("con_x5y3z4_D*con_x5z4_C")); - - TEST_DO(verify_equal("con_x5y3z4_D-con_y3z4_F")); - TEST_DO(verify_equal("con_x5y3z4_D+con_y3z4_F")); - TEST_DO(verify_equal("con_x5y3z4_D*con_y3z4_F")); - - TEST_DO(verify_equal("con_x5y3z4_D-con_y3z4_F")); - TEST_DO(verify_equal("con_x5y3z4_D+con_y3z4_F")); - TEST_DO(verify_equal("con_x5y3z4_D*con_y3z4_F")); - - TEST_DO(verify_equal("con_y3_E-con_y3z4_F")); - TEST_DO(verify_equal("con_y3_E+con_y3z4_F")); - TEST_DO(verify_equal("con_y3_E*con_y3z4_F")); - - TEST_DO(verify_equal("con_y3z4_F-con_z4_G")); - TEST_DO(verify_equal("con_y3z4_F+con_z4_G")); - TEST_DO(verify_equal("con_y3z4_F*con_z4_G")); -} - -TEST_MAIN() { TEST_RUN_ALL(); } diff --git a/eval/src/tests/tensor/dense_inplace_join_function/dense_inplace_join_function_test.cpp b/eval/src/tests/tensor/dense_inplace_join_function/dense_inplace_join_function_test.cpp index 0f3a200bfdd..853607ae76d 100644 --- a/eval/src/tests/tensor/dense_inplace_join_function/dense_inplace_join_function_test.cpp +++ b/eval/src/tests/tensor/dense_inplace_join_function/dense_inplace_join_function_test.cpp @@ -2,7 +2,6 @@ #include <vespa/vespalib/testkit/test_kit.h> #include <vespa/eval/eval/tensor_function.h> -#include <vespa/eval/tensor/dense/dense_tensor.h> #include <vespa/eval/eval/test/tensor_model.hpp> #include <vespa/eval/eval/test/eval_fixture.h> diff --git a/eval/src/tests/tensor/dense_remove_dimension_optimizer/dense_remove_dimension_optimizer_test.cpp b/eval/src/tests/tensor/dense_remove_dimension_optimizer/dense_remove_dimension_optimizer_test.cpp index b655c52c9d3..69910e27b4b 100644 --- a/eval/src/tests/tensor/dense_remove_dimension_optimizer/dense_remove_dimension_optimizer_test.cpp +++ b/eval/src/tests/tensor/dense_remove_dimension_optimizer/dense_remove_dimension_optimizer_test.cpp @@ -4,7 +4,6 @@ #include <vespa/eval/eval/tensor_function.h> #include <vespa/eval/tensor/dense/dense_replace_type_function.h> #include <vespa/eval/tensor/dense/dense_fast_rename_optimizer.h> -#include <vespa/eval/tensor/dense/dense_tensor.h> #include <vespa/eval/eval/test/tensor_model.hpp> #include <vespa/eval/eval/test/eval_fixture.h> diff --git a/eval/src/tests/tensor/dense_replace_type_function/dense_replace_type_function_test.cpp b/eval/src/tests/tensor/dense_replace_type_function/dense_replace_type_function_test.cpp index dd4ddb9044a..2612869e72f 100644 --- a/eval/src/tests/tensor/dense_replace_type_function/dense_replace_type_function_test.cpp +++ b/eval/src/tests/tensor/dense_replace_type_function/dense_replace_type_function_test.cpp @@ -4,7 +4,6 @@ #include <vespa/eval/eval/fast_value.h> #include <vespa/eval/eval/value_codec.h> #include <vespa/eval/eval/interpreted_function.h> -#include <vespa/eval/tensor/dense/dense_tensor_view.h> #include <vespa/eval/tensor/dense/dense_replace_type_function.h> #include <vespa/eval/eval/test/tensor_model.hpp> diff --git a/eval/src/tests/tensor/dense_single_reduce_function/dense_single_reduce_function_test.cpp b/eval/src/tests/tensor/dense_single_reduce_function/dense_single_reduce_function_test.cpp index 1948d8d010a..347228269cf 100644 --- a/eval/src/tests/tensor/dense_single_reduce_function/dense_single_reduce_function_test.cpp +++ b/eval/src/tests/tensor/dense_single_reduce_function/dense_single_reduce_function_test.cpp @@ -4,8 +4,6 @@ #include <vespa/eval/eval/tensor_function.h> #include <vespa/eval/eval/operation.h> #include <vespa/eval/tensor/dense/dense_single_reduce_function.h> -#include <vespa/eval/tensor/dense/dense_tensor.h> -#include <vespa/eval/tensor/dense/dense_tensor_view.h> #include <vespa/eval/eval/test/tensor_model.hpp> #include <vespa/eval/eval/test/eval_fixture.h> diff --git a/eval/src/tests/tensor/dense_tensor_create_function/dense_tensor_create_function_test.cpp b/eval/src/tests/tensor/dense_tensor_create_function/dense_tensor_create_function_test.cpp index 2bc937a26bf..edf999e97b3 100644 --- a/eval/src/tests/tensor/dense_tensor_create_function/dense_tensor_create_function_test.cpp +++ b/eval/src/tests/tensor/dense_tensor_create_function/dense_tensor_create_function_test.cpp @@ -3,7 +3,6 @@ #include <vespa/vespalib/testkit/test_kit.h> #include <vespa/eval/eval/tensor_function.h> #include <vespa/eval/tensor/dense/dense_tensor_create_function.h> -#include <vespa/eval/tensor/dense/dense_tensor.h> #include <vespa/eval/eval/test/tensor_model.hpp> #include <vespa/eval/eval/test/eval_fixture.h> diff --git a/eval/src/tests/tensor/direct_dense_tensor_builder/CMakeLists.txt b/eval/src/tests/tensor/direct_dense_tensor_builder/CMakeLists.txt deleted file mode 100644 index 70ccbddd617..00000000000 --- a/eval/src/tests/tensor/direct_dense_tensor_builder/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -vespa_add_executable(eval_direct_dense_tensor_builder_test_app TEST - SOURCES - direct_dense_tensor_builder_test.cpp - DEPENDS - vespaeval -) -vespa_add_test(NAME eval_direct_dense_tensor_builder_test_app COMMAND eval_direct_dense_tensor_builder_test_app) diff --git a/eval/src/tests/tensor/direct_dense_tensor_builder/direct_dense_tensor_builder_test.cpp b/eval/src/tests/tensor/direct_dense_tensor_builder/direct_dense_tensor_builder_test.cpp deleted file mode 100644 index 52768663647..00000000000 --- a/eval/src/tests/tensor/direct_dense_tensor_builder/direct_dense_tensor_builder_test.cpp +++ /dev/null @@ -1,192 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#include <vespa/vespalib/test/insertion_operators.h> -#include <vespa/vespalib/testkit/test_kit.h> -#include <vespa/eval/tensor/dense/typed_dense_tensor_builder.h> -#include <vespa/vespalib/util/exceptions.h> - -using namespace vespalib::tensor; -using vespalib::IllegalArgumentException; -using BuilderDbl = TypedDenseTensorBuilder<double>; -using BuilderFlt = TypedDenseTensorBuilder<float>; -using vespalib::eval::TensorSpec; -using vespalib::eval::ValueType; -using vespalib::ConstArrayRef; - -struct CallMakeVector { - template <typename T> - static std::vector<double> call(const ConstArrayRef<T> &ref) { - std::vector<double> result; - result.reserve(ref.size()); - for (T v : ref) { - result.push_back(v); - } - return result; - } -}; - -void assertTensor(const vespalib::string &type_spec, - const std::vector<double> &expCells, - const Tensor &tensor) -{ - EXPECT_EQUAL(ValueType::from_spec(type_spec), tensor.type()); - EXPECT_EQUAL(expCells, dispatch_1<CallMakeVector>(tensor.cells())); -} - -void assertTensorSpec(const TensorSpec &expSpec, const Tensor &tensor) { - TensorSpec actSpec = tensor.toSpec(); - EXPECT_EQUAL(expSpec, actSpec); -} - -Tensor::UP build1DTensor() { - BuilderDbl builder(ValueType::from_spec("tensor(x[3])")); - builder.insertCell(0, 10); - builder.insertCell(1, 11); - builder.insertCell(2, 12); - return builder.build(); -} - -TEST("require that 1d tensor can be constructed") { - assertTensor("tensor(x[3])", {10,11,12}, *build1DTensor()); -} - -TEST("require that 1d tensor can be converted to tensor spec") { - assertTensorSpec(TensorSpec("tensor(x[3])"). - add({{"x", 0}}, 10). - add({{"x", 1}}, 11). - add({{"x", 2}}, 12), - *build1DTensor()); -} - -Tensor::UP build2DTensor() { - BuilderDbl builder(ValueType::from_spec("tensor(x[3],y[2])")); - builder.insertCell({0, 0}, 10); - builder.insertCell({0, 1}, 11); - builder.insertCell({1, 0}, 12); - builder.insertCell({1, 1}, 13); - builder.insertCell({2, 0}, 14); - builder.insertCell({2, 1}, 15); - return builder.build(); -} - -TEST("require that 2d tensor can be constructed") { - assertTensor("tensor(x[3],y[2])", {10,11,12,13,14,15}, *build2DTensor()); -} - -TEST("require that 2d tensor can be converted to tensor spec") { - assertTensorSpec(TensorSpec("tensor(x[3],y[2])"). - add({{"x", 0},{"y", 0}}, 10). - add({{"x", 0},{"y", 1}}, 11). - add({{"x", 1},{"y", 0}}, 12). - add({{"x", 1},{"y", 1}}, 13). - add({{"x", 2},{"y", 0}}, 14). - add({{"x", 2},{"y", 1}}, 15), - *build2DTensor()); -} - -TEST("require that 3d tensor can be constructed") { - BuilderDbl builder(ValueType::from_spec("tensor(x[3],y[2],z[2])")); - builder.insertCell({0, 0, 0}, 10); - builder.insertCell({0, 0, 1}, 11); - builder.insertCell({0, 1, 0}, 12); - builder.insertCell({0, 1, 1}, 13); - builder.insertCell({1, 0, 0}, 14); - builder.insertCell({1, 0, 1}, 15); - builder.insertCell({1, 1, 0}, 16); - builder.insertCell({1, 1, 1}, 17); - builder.insertCell({2, 0, 0}, 18); - builder.insertCell({2, 0, 1}, 19); - builder.insertCell({2, 1, 0}, 20); - builder.insertCell({2, 1, 1}, 21); - assertTensor("tensor(x[3],y[2],z[2])", - {10,11,12,13,14,15,16,17,18,19,20,21}, - *builder.build()); -} - -TEST("require that 2d tensor with float cells can be constructed") { - BuilderFlt builder(ValueType::from_spec("tensor<float>(x[3],y[2])")); - builder.insertCell({0, 1}, 2.5); - builder.insertCell({1, 0}, 1.5); - builder.insertCell({2, 0}, -0.25); - builder.insertCell({2, 1}, 0.75); - assertTensor("tensor<float>(x[3],y[2])", {0,2.5,1.5,0,-0.25,0.75}, - *builder.build()); -} - -TEST("require that cells get default value 0 if not specified") { - BuilderDbl builder(ValueType::from_spec("tensor(x[3])")); - builder.insertCell(1, 11); - assertTensor("tensor(x[3])", {0,11,0}, - *builder.build()); -} - -void assertTensorCell(const DenseTensorView::Address &expAddress, - double expCell, - const DenseTensorView::CellsIterator &itr) -{ - EXPECT_TRUE(itr.valid()); - EXPECT_EQUAL(expAddress, itr.address()); - EXPECT_EQUAL(expCell, itr.cell()); -} - -TEST("require that dense tensor cells iterator works for 1d tensor") { - Tensor::UP tensor; - { - BuilderDbl builder(ValueType::from_spec("tensor(x[2])")); - builder.insertCell(0, 2); - builder.insertCell(1, 3); - tensor = builder.build(); - } - - const DenseTensorView &denseTensor = dynamic_cast<const DenseTensorView &>(*tensor); - DenseTensorView::CellsIterator itr = denseTensor.cellsIterator(); - - assertTensorCell({0}, 2, itr); - itr.next(); - assertTensorCell({1}, 3, itr); - itr.next(); - EXPECT_FALSE(itr.valid()); -} - -TEST("require that dense tensor cells iterator works for 2d tensor") { - Tensor::UP tensor; - { - BuilderDbl builder(ValueType::from_spec("tensor(x[2],y[2])")); - builder.insertCell({0, 0}, 2); - builder.insertCell({0, 1}, 3); - builder.insertCell({1, 0}, 5); - builder.insertCell({1, 1}, 7); - tensor = builder.build(); - } - - const DenseTensorView &denseTensor = dynamic_cast<const DenseTensorView &>(*tensor); - DenseTensorView::CellsIterator itr = denseTensor.cellsIterator(); - - assertTensorCell({0,0}, 2, itr); - itr.next(); - assertTensorCell({0,1}, 3, itr); - itr.next(); - assertTensorCell({1,0}, 5, itr); - itr.next(); - assertTensorCell({1,1}, 7, itr); - itr.next(); - EXPECT_FALSE(itr.valid()); -} - -TEST("require that memory used count is reasonable") { - Tensor::UP full = build2DTensor(); - const DenseTensorView &full_view = dynamic_cast<const DenseTensorView &>(*full); - DenseTensorView ref_view(full_view.fast_type(), full_view.cells()); - - size_t full_sz = full->get_memory_usage().usedBytes(); - size_t view_sz = full_view.get_memory_usage().usedBytes(); - size_t ref_sz = ref_view.get_memory_usage().usedBytes(); - - EXPECT_EQUAL(ref_sz, sizeof(DenseTensorView)); - EXPECT_LESS(ref_sz, full_sz); - EXPECT_EQUAL(full_sz, view_sz); - EXPECT_LESS(full_sz, 10000u); - EXPECT_GREATER(full_sz, sizeof(DenseTensor<double>)); -} - -TEST_MAIN() { TEST_RUN_ALL(); } diff --git a/eval/src/tests/tensor/partial_add/partial_add_test.cpp b/eval/src/tests/tensor/partial_add/partial_add_test.cpp index 42db77a311f..893acf07adb 100644 --- a/eval/src/tests/tensor/partial_add/partial_add_test.cpp +++ b/eval/src/tests/tensor/partial_add/partial_add_test.cpp @@ -4,7 +4,6 @@ #include <vespa/eval/eval/test/tensor_model.hpp> #include <vespa/eval/eval/value_codec.h> #include <vespa/eval/tensor/partial_update.h> -#include <vespa/eval/tensor/tensor.h> #include <vespa/vespalib/util/stringfmt.h> #include <vespa/vespalib/gtest/gtest.h> #include <optional> diff --git a/eval/src/tests/tensor/partial_modify/partial_modify_test.cpp b/eval/src/tests/tensor/partial_modify/partial_modify_test.cpp index a39bcc87ab3..a1802540fa5 100644 --- a/eval/src/tests/tensor/partial_modify/partial_modify_test.cpp +++ b/eval/src/tests/tensor/partial_modify/partial_modify_test.cpp @@ -4,7 +4,6 @@ #include <vespa/eval/eval/test/tensor_model.hpp> #include <vespa/eval/eval/value_codec.h> #include <vespa/eval/tensor/partial_update.h> -#include <vespa/eval/tensor/tensor.h> #include <vespa/vespalib/util/stringfmt.h> #include <vespa/vespalib/gtest/gtest.h> #include <optional> diff --git a/eval/src/tests/tensor/partial_remove/partial_remove_test.cpp b/eval/src/tests/tensor/partial_remove/partial_remove_test.cpp index 410331c5eb7..fef6d99519f 100644 --- a/eval/src/tests/tensor/partial_remove/partial_remove_test.cpp +++ b/eval/src/tests/tensor/partial_remove/partial_remove_test.cpp @@ -4,7 +4,6 @@ #include <vespa/eval/eval/test/tensor_model.hpp> #include <vespa/eval/eval/value_codec.h> #include <vespa/eval/tensor/partial_update.h> -#include <vespa/eval/tensor/tensor.h> #include <vespa/vespalib/util/stringfmt.h> #include <vespa/vespalib/gtest/gtest.h> #include <optional> diff --git a/eval/src/tests/tensor/vector_from_doubles_function/vector_from_doubles_function_test.cpp b/eval/src/tests/tensor/vector_from_doubles_function/vector_from_doubles_function_test.cpp index 9881d120a74..c3e1f2f248e 100644 --- a/eval/src/tests/tensor/vector_from_doubles_function/vector_from_doubles_function_test.cpp +++ b/eval/src/tests/tensor/vector_from_doubles_function/vector_from_doubles_function_test.cpp @@ -3,7 +3,6 @@ #include <vespa/vespalib/testkit/test_kit.h> #include <vespa/eval/eval/tensor_function.h> #include <vespa/eval/tensor/dense/vector_from_doubles_function.h> -#include <vespa/eval/tensor/dense/dense_tensor.h> #include <vespa/eval/eval/test/tensor_model.hpp> #include <vespa/eval/eval/test/eval_fixture.h> diff --git a/eval/src/vespa/eval/CMakeLists.txt b/eval/src/vespa/eval/CMakeLists.txt index 65cf5f548f2..9a3c2f817d8 100644 --- a/eval/src/vespa/eval/CMakeLists.txt +++ b/eval/src/vespa/eval/CMakeLists.txt @@ -10,7 +10,6 @@ vespa_add_library(vespaeval $<TARGET_OBJECTS:eval_streamed> $<TARGET_OBJECTS:eval_tensor> $<TARGET_OBJECTS:eval_tensor_dense> - $<TARGET_OBJECTS:eval_tensor_sparse> INSTALL lib64 DEPENDS onnxruntime diff --git a/eval/src/vespa/eval/eval/CMakeLists.txt b/eval/src/vespa/eval/eval/CMakeLists.txt index 57c0db1719b..01eeff49662 100644 --- a/eval/src/vespa/eval/eval/CMakeLists.txt +++ b/eval/src/vespa/eval/eval/CMakeLists.txt @@ -27,8 +27,6 @@ vespa_add_library(eval_eval OBJECT param_usage.cpp simple_value.cpp string_stuff.cpp - tensor.cpp - tensor_engine.cpp tensor_function.cpp tensor_nodes.cpp tensor_spec.cpp diff --git a/eval/src/vespa/eval/eval/optimize_tensor_function.cpp b/eval/src/vespa/eval/eval/optimize_tensor_function.cpp index e13582e0fe9..ed0b122196d 100644 --- a/eval/src/vespa/eval/eval/optimize_tensor_function.cpp +++ b/eval/src/vespa/eval/eval/optimize_tensor_function.cpp @@ -13,7 +13,6 @@ #include <vespa/eval/tensor/dense/dense_single_reduce_function.h> #include <vespa/eval/tensor/dense/dense_remove_dimension_optimizer.h> #include <vespa/eval/instruction/dense_lambda_peek_optimizer.h> -#include <vespa/eval/tensor/dense/dense_lambda_function.h> #include <vespa/eval/instruction/dense_simple_expand_function.h> #include <vespa/eval/tensor/dense/dense_simple_join_function.h> #include <vespa/eval/instruction/join_with_number_function.h> diff --git a/eval/src/vespa/eval/eval/tensor.cpp b/eval/src/vespa/eval/eval/tensor.cpp deleted file mode 100644 index 9de812b46f0..00000000000 --- a/eval/src/vespa/eval/eval/tensor.cpp +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#include "tensor.h" -#include "tensor_engine.h" -#include "tensor_spec.h" - -namespace vespalib { -namespace eval { - -bool -operator==(const Tensor &lhs, const Tensor &rhs) -{ - auto lhs_spec = TensorSpec::from_value(lhs); - auto rhs_spec = TensorSpec::from_value(rhs); - return (lhs_spec == rhs_spec); -} - -std::ostream & -operator<<(std::ostream &out, const Tensor &tensor) -{ - out << TensorSpec::from_value(tensor).to_string(); - return out; -} - -} // namespace vespalib::eval -} // namespace vespalib diff --git a/eval/src/vespa/eval/eval/tensor.h b/eval/src/vespa/eval/eval/tensor.h deleted file mode 100644 index a7cb1f2c516..00000000000 --- a/eval/src/vespa/eval/eval/tensor.h +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#pragma once - -#include "value_type.h" -#include "value.h" - -namespace vespalib { -namespace eval { - -/** - * Base class for all tensors. Tensor operations are defined by the - * TensorEngine interface. The Tensor class itself is used as a tagged - * transport mechanism. Each Tensor is connected to a distinct engine - * which can be used to operate on it. When operating on multiple - * tensors at the same time they all need to be connected to the same - * engine. TensorEngines should only have a single static instance per - * implementation. - **/ -class Tensor : public Value -{ -protected: - Tensor() {} -public: - Tensor(const Tensor &) = delete; - Tensor(Tensor &&) = delete; - Tensor &operator=(const Tensor &) = delete; - Tensor &operator=(Tensor &&) = delete; - bool is_tensor() const override { return true; } - const Tensor *as_tensor() const override { return this; } - virtual ~Tensor() {} -}; - -bool operator==(const Tensor &lhs, const Tensor &rhs); -std::ostream &operator<<(std::ostream &out, const Tensor &tensor); - -} // namespace vespalib::eval -} // namespace vespalib diff --git a/eval/src/vespa/eval/eval/tensor_engine.cpp b/eval/src/vespa/eval/eval/tensor_engine.cpp deleted file mode 100644 index 9e7948920df..00000000000 --- a/eval/src/vespa/eval/eval/tensor_engine.cpp +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#include "tensor_engine.h" - -namespace vespalib { -namespace eval { - -} // namespace vespalib::eval -} // namespace vespalib diff --git a/eval/src/vespa/eval/eval/tensor_engine.h b/eval/src/vespa/eval/eval/tensor_engine.h deleted file mode 100644 index c0625c3e9b8..00000000000 --- a/eval/src/vespa/eval/eval/tensor_engine.h +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#pragma once - -#include "aggr.h" -#include "operation.h" -#include <vespa/vespalib/stllike/string.h> -#include <memory> -#include <vector> -#include <functional> - -namespace vespalib { - -class Stash; -class nbostream; - -namespace eval { - -struct Value; -class ValueType; -class TensorSpec; -struct TensorFunction; - -/** - * Top-level API for a tensor implementation. All Tensor operations - * are defined by the TensorEngine interface. The Tensor class itself - * is used as a tagged transport mechanism. Each Tensor is connected - * to a distinct engine which can be used to operate on it. When - * operating on multiple tensors at the same time they all need to be - * connected to the same engine. TensorEngines should only have a - * single static instance per implementation. - **/ -struct TensorEngine -{ - using Aggr = eval::Aggr; - using TensorFunction = eval::TensorFunction; - using TensorSpec = eval::TensorSpec; - using Value = eval::Value; - using ValueType = eval::ValueType; - using map_fun_t = vespalib::eval::operation::op1_t; - using join_fun_t = vespalib::eval::operation::op2_t; - - virtual TensorSpec to_spec(const Value &value) const = 0; - virtual std::unique_ptr<Value> from_spec(const TensorSpec &spec) const = 0; - - virtual void encode(const Value &value, nbostream &output) const = 0; - virtual std::unique_ptr<Value> decode(nbostream &input) const = 0; - - virtual const TensorFunction &optimize(const TensorFunction &expr, Stash &) const { return expr; } - - virtual const Value &map(const Value &a, map_fun_t function, Stash &stash) const = 0; - virtual const Value &join(const Value &a, const Value &b, join_fun_t function, Stash &stash) const = 0; - virtual const Value &merge(const Value &a, const Value &b, join_fun_t function, Stash &stash) const = 0; - virtual const Value &reduce(const Value &a, Aggr aggr, const std::vector<vespalib::string> &dimensions, Stash &stash) const = 0; - virtual const Value &concat(const Value &a, const Value &b, const vespalib::string &dimension, Stash &stash) const = 0; - virtual const Value &rename(const Value &a, const std::vector<vespalib::string> &from, const std::vector<vespalib::string> &to, Stash &stash) const = 0; - - virtual ~TensorEngine() {} -}; - -} // namespace vespalib::eval -} // namespace vespalib diff --git a/eval/src/vespa/eval/eval/tensor_function.cpp b/eval/src/vespa/eval/eval/tensor_function.cpp index fc83889a853..4ea7348f61e 100644 --- a/eval/src/vespa/eval/eval/tensor_function.cpp +++ b/eval/src/vespa/eval/eval/tensor_function.cpp @@ -3,7 +3,6 @@ #include "tensor_function.h" #include "value.h" #include "operation.h" -#include "tensor.h" #include "visit_stuff.h" #include "string_stuff.h" #include <vespa/eval/instruction/generic_concat.h> diff --git a/eval/src/vespa/eval/eval/tensor_spec.cpp b/eval/src/vespa/eval/eval/tensor_spec.cpp index e082d3bc2ba..2ffbbb7ac66 100644 --- a/eval/src/vespa/eval/eval/tensor_spec.cpp +++ b/eval/src/vespa/eval/eval/tensor_spec.cpp @@ -4,8 +4,6 @@ #include "array_array_map.h" #include "function.h" #include "interpreted_function.h" -#include "tensor.h" -#include "tensor_engine.h" #include "value.h" #include "value_codec.h" #include "value_type.h" diff --git a/eval/src/vespa/eval/eval/test/value_compare.cpp b/eval/src/vespa/eval/eval/test/value_compare.cpp index ff6a4e72ebc..cb6eeca4b86 100644 --- a/eval/src/vespa/eval/eval/test/value_compare.cpp +++ b/eval/src/vespa/eval/eval/test/value_compare.cpp @@ -1,8 +1,6 @@ // Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include "value_compare.h" -#include <vespa/eval/eval/tensor.h> -#include <vespa/eval/eval/tensor_engine.h> #include <vespa/eval/eval/value_codec.h> namespace vespalib::eval { diff --git a/eval/src/vespa/eval/eval/value.h b/eval/src/vespa/eval/eval/value.h index cf4e21029fc..186c3698dcd 100644 --- a/eval/src/vespa/eval/eval/value.h +++ b/eval/src/vespa/eval/eval/value.h @@ -12,8 +12,6 @@ namespace vespalib::eval { -class Tensor; - /** * An abstract Value. **/ @@ -69,7 +67,6 @@ struct Value { virtual bool is_tensor() const { return type().is_tensor(); } virtual double as_double() const; bool as_bool() const { return (as_double() != 0.0); } - virtual const Tensor *as_tensor() const { return nullptr; } // --- end of old interface }; diff --git a/eval/src/vespa/eval/eval/value_cache/constant_tensor_loader.cpp b/eval/src/vespa/eval/eval/value_cache/constant_tensor_loader.cpp index b14892d4c1c..07692474234 100644 --- a/eval/src/vespa/eval/eval/value_cache/constant_tensor_loader.cpp +++ b/eval/src/vespa/eval/eval/value_cache/constant_tensor_loader.cpp @@ -1,7 +1,6 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include "constant_tensor_loader.h" -#include <vespa/eval/eval/tensor.h> #include <vespa/eval/eval/tensor_spec.h> #include <vespa/eval/eval/value_codec.h> #include <vespa/vespalib/objects/nbostream.h> diff --git a/eval/src/vespa/eval/instruction/dense_cell_range_function.cpp b/eval/src/vespa/eval/instruction/dense_cell_range_function.cpp index 18ccb33fadf..4c655c67747 100644 --- a/eval/src/vespa/eval/instruction/dense_cell_range_function.cpp +++ b/eval/src/vespa/eval/instruction/dense_cell_range_function.cpp @@ -1,7 +1,6 @@ // Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include "dense_cell_range_function.h" -#include <vespa/eval/tensor/dense/dense_tensor_view.h> #include <vespa/eval/eval/value.h> namespace vespalib::eval { @@ -15,7 +14,7 @@ void my_cell_range_op(InterpretedFunction::State &state, uint64_t param) { const auto &self = unwrap_param<DenseCellRangeFunction>(param); auto old_cells = state.peek(0).cells().typify<CT>(); ConstArrayRef<CT> new_cells(&old_cells[self.offset()], self.length()); - state.pop_push(state.stash.create<tensor::DenseTensorView>(self.result_type(), TypedCells(new_cells))); + state.pop_push(state.stash.create<DenseValueView>(self.result_type(), TypedCells(new_cells))); } struct MyCellRangeOp { diff --git a/eval/src/vespa/eval/instruction/dense_dot_product_function.cpp b/eval/src/vespa/eval/instruction/dense_dot_product_function.cpp index ce27bec35d4..e3cf52a8e3f 100644 --- a/eval/src/vespa/eval/instruction/dense_dot_product_function.cpp +++ b/eval/src/vespa/eval/instruction/dense_dot_product_function.cpp @@ -1,7 +1,6 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include "dense_dot_product_function.h" -#include <vespa/eval/tensor/dense/dense_tensor_view.h> #include <vespa/eval/eval/operation.h> #include <vespa/eval/eval/value.h> #include <cblas.h> diff --git a/eval/src/vespa/eval/instruction/dense_lambda_peek_function.cpp b/eval/src/vespa/eval/instruction/dense_lambda_peek_function.cpp index bf9d5b10a5f..4a4f6b9be14 100644 --- a/eval/src/vespa/eval/instruction/dense_lambda_peek_function.cpp +++ b/eval/src/vespa/eval/instruction/dense_lambda_peek_function.cpp @@ -2,7 +2,6 @@ #include "dense_lambda_peek_function.h" #include "index_lookup_table.h" -#include <vespa/eval/tensor/dense/dense_tensor_view.h> #include <vespa/eval/eval/value.h> namespace vespalib::eval { diff --git a/eval/src/vespa/eval/instruction/dense_lambda_peek_optimizer.cpp b/eval/src/vespa/eval/instruction/dense_lambda_peek_optimizer.cpp index a2ea24dbf0a..6853b1a078f 100644 --- a/eval/src/vespa/eval/instruction/dense_lambda_peek_optimizer.cpp +++ b/eval/src/vespa/eval/instruction/dense_lambda_peek_optimizer.cpp @@ -3,7 +3,6 @@ #include "dense_lambda_peek_optimizer.h" #include "dense_lambda_peek_function.h" #include "dense_cell_range_function.h" -#include <vespa/eval/tensor/dense/dense_tensor_view.h> #include <vespa/eval/tensor/dense/dense_replace_type_function.h> #include <vespa/eval/eval/value.h> #include <vespa/eval/eval/node_tools.h> diff --git a/eval/src/vespa/eval/instruction/dense_matmul_function.cpp b/eval/src/vespa/eval/instruction/dense_matmul_function.cpp index 1394a201e6d..33d9054820b 100644 --- a/eval/src/vespa/eval/instruction/dense_matmul_function.cpp +++ b/eval/src/vespa/eval/instruction/dense_matmul_function.cpp @@ -1,7 +1,6 @@ // Copyright 2020 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include "dense_matmul_function.h" -#include <vespa/eval/tensor/dense/dense_tensor_view.h> #include <vespa/vespalib/objects/objectvisitor.h> #include <vespa/eval/eval/value.h> #include <vespa/eval/eval/operation.h> diff --git a/eval/src/vespa/eval/instruction/dense_matmul_function.h b/eval/src/vespa/eval/instruction/dense_matmul_function.h index a5432a7d86f..c96f2c35c75 100644 --- a/eval/src/vespa/eval/instruction/dense_matmul_function.h +++ b/eval/src/vespa/eval/instruction/dense_matmul_function.h @@ -3,7 +3,6 @@ #pragma once #include <vespa/eval/eval/tensor_function.h> -#include <vespa/eval/tensor/dense/dense_tensor_view.h> namespace vespalib::eval { diff --git a/eval/src/vespa/eval/instruction/dense_multi_matmul_function.h b/eval/src/vespa/eval/instruction/dense_multi_matmul_function.h index 3038bdf7fdc..7dd99b58a2f 100644 --- a/eval/src/vespa/eval/instruction/dense_multi_matmul_function.h +++ b/eval/src/vespa/eval/instruction/dense_multi_matmul_function.h @@ -2,7 +2,6 @@ #pragma once -#include <vespa/eval/tensor/dense/dense_tensor_view.h> #include <vespa/eval/eval/tensor_function.h> namespace vespalib::eval { diff --git a/eval/src/vespa/eval/instruction/dense_simple_expand_function.cpp b/eval/src/vespa/eval/instruction/dense_simple_expand_function.cpp index a656a0249f9..e67aa042881 100644 --- a/eval/src/vespa/eval/instruction/dense_simple_expand_function.cpp +++ b/eval/src/vespa/eval/instruction/dense_simple_expand_function.cpp @@ -1,7 +1,6 @@ // Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include "dense_simple_expand_function.h" -#include <vespa/eval/tensor/dense/dense_tensor_view.h> #include <vespa/vespalib/objects/objectvisitor.h> #include <vespa/eval/eval/value.h> #include <vespa/eval/eval/operation.h> diff --git a/eval/src/vespa/eval/instruction/dense_tensor_peek_function.cpp b/eval/src/vespa/eval/instruction/dense_tensor_peek_function.cpp index 323909227f7..07fd0f8938c 100644 --- a/eval/src/vespa/eval/instruction/dense_tensor_peek_function.cpp +++ b/eval/src/vespa/eval/instruction/dense_tensor_peek_function.cpp @@ -1,7 +1,6 @@ // Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include "dense_tensor_peek_function.h" -#include <vespa/eval/tensor/dense/dense_tensor_view.h> #include <vespa/eval/eval/value.h> namespace vespalib::eval { diff --git a/eval/src/vespa/eval/instruction/dense_xw_product_function.h b/eval/src/vespa/eval/instruction/dense_xw_product_function.h index 6883c8a981f..7e87377f891 100644 --- a/eval/src/vespa/eval/instruction/dense_xw_product_function.h +++ b/eval/src/vespa/eval/instruction/dense_xw_product_function.h @@ -3,7 +3,6 @@ #pragma once #include <vespa/eval/eval/tensor_function.h> -#include <vespa/eval/tensor/dense/dense_tensor_view.h> namespace vespalib::eval { diff --git a/eval/src/vespa/eval/instruction/generic_concat.cpp b/eval/src/vespa/eval/instruction/generic_concat.cpp index 4d949d5e725..fa9d2192b99 100644 --- a/eval/src/vespa/eval/instruction/generic_concat.cpp +++ b/eval/src/vespa/eval/instruction/generic_concat.cpp @@ -4,7 +4,6 @@ #include "generic_join.h" #include <vespa/eval/eval/value.h> #include <vespa/eval/eval/wrap_param.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> diff --git a/eval/src/vespa/eval/tensor/CMakeLists.txt b/eval/src/vespa/eval/tensor/CMakeLists.txt index c2968bd3efd..8b0178bd656 100644 --- a/eval/src/vespa/eval/tensor/CMakeLists.txt +++ b/eval/src/vespa/eval/tensor/CMakeLists.txt @@ -2,6 +2,4 @@ vespa_add_library(eval_tensor OBJECT SOURCES partial_update.cpp - tensor.cpp - tensor_address.cpp ) diff --git a/eval/src/vespa/eval/tensor/cell_function.h b/eval/src/vespa/eval/tensor/cell_function.h deleted file mode 100644 index a268c9a34b1..00000000000 --- a/eval/src/vespa/eval/tensor/cell_function.h +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#pragma once - -#include <functional> - -namespace vespalib::tensor { - -/** - * Interface for a function to be applied on cells in a tensor. - */ -struct CellFunction -{ - typedef std::reference_wrapper<const CellFunction> CREF; - virtual ~CellFunction() {} - virtual double apply(double value) const = 0; -}; - -} diff --git a/eval/src/vespa/eval/tensor/cell_values.h b/eval/src/vespa/eval/tensor/cell_values.h deleted file mode 100644 index 4b8fd33376a..00000000000 --- a/eval/src/vespa/eval/tensor/cell_values.h +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#pragma once - -#include <vespa/eval/tensor/tensor_visitor.h> -#include <vespa/eval/tensor/sparse/sparse_tensor.h> - -namespace vespalib::tensor { - -/* - * A collection of tensor cells, used as argument for modifying a subset - * of cells in a tensor. - */ -class CellValues { - const SparseTensor &_tensor; - -public: - CellValues(const SparseTensor &tensor) - : _tensor(tensor) - { - } - - void accept(TensorVisitor &visitor) const { - _tensor.accept(visitor); - } - - eval::TensorSpec toSpec() const { - return _tensor.toSpec(); - } -}; - -} diff --git a/eval/src/vespa/eval/tensor/dense/CMakeLists.txt b/eval/src/vespa/eval/tensor/dense/CMakeLists.txt index 2c7732d7720..1431ae53f66 100644 --- a/eval/src/vespa/eval/tensor/dense/CMakeLists.txt +++ b/eval/src/vespa/eval/tensor/dense/CMakeLists.txt @@ -2,27 +2,15 @@ vespa_add_library(eval_tensor_dense OBJECT SOURCES dense_add_dimension_optimizer.cpp - dense_dimension_combiner.cpp dense_fast_rename_optimizer.cpp - dense_lambda_function.cpp - dense_number_join_function.cpp dense_pow_as_map_optimizer.cpp dense_remove_dimension_optimizer.cpp dense_replace_type_function.cpp dense_simple_join_function.cpp dense_simple_map_function.cpp dense_single_reduce_function.cpp - dense_tensor.cpp - dense_tensor_address_mapper.cpp - dense_tensor_cells_iterator.cpp dense_tensor_create_function.cpp - dense_tensor_modify.cpp - dense_tensor_reduce.cpp - dense_tensor_value_builder.cpp - dense_tensor_view.cpp mutable_dense_tensor_view.cpp onnx_wrapper.cpp - typed_cells_dispatch.cpp - typed_dense_tensor_builder.cpp vector_from_doubles_function.cpp ) diff --git a/eval/src/vespa/eval/tensor/dense/dense_dimension_combiner.cpp b/eval/src/vespa/eval/tensor/dense/dense_dimension_combiner.cpp deleted file mode 100644 index 22c8ff12ad1..00000000000 --- a/eval/src/vespa/eval/tensor/dense/dense_dimension_combiner.cpp +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#include "dense_dimension_combiner.h" -#include <cassert> - -namespace vespalib::tensor { - -DenseDimensionCombiner::~DenseDimensionCombiner() = default; - -DenseDimensionCombiner::DenseDimensionCombiner(const eval::ValueType &lhs, - const eval::ValueType &rhs) - : _left(), _right(), - _commonDims(), - _outputIndex(0), - _outputSize(1u), - result_type(eval::ValueType::join(lhs, rhs)) -{ - assert(lhs.is_dense()); - assert(rhs.is_dense()); - assert(result_type.is_dense()); - - const auto &lDims = lhs.dimensions(); - const auto &rDims = rhs.dimensions(); - const auto &oDims = result_type.dimensions(); - - size_t i = lDims.size(); - size_t j = rDims.size(); - size_t k = oDims.size(); - - uint32_t lMul = 1; - uint32_t rMul = 1; - uint32_t oMul = 1; - - while (k-- > 0) { - if ((i > 0) && (lDims[i-1].name == oDims[k].name)) { - --i; - // left dim match - if ((j > 0) && (rDims[j-1].name == oDims[k].name)) { - // both dim match - --j; - CommonDim cd; - cd.idx = 0; - cd.leftMultiplier = lMul; - cd.rightMultiplier = rMul; - cd.outputMultiplier = oMul; - assert(lDims[i].size == oDims[k].size); - assert(rDims[j].size == oDims[k].size); - cd.size = oDims[k].size; - lMul *= cd.size; - rMul *= cd.size; - oMul *= cd.size; - _left.totalSize *= cd.size; - _right.totalSize *= cd.size; - _outputSize *= cd.size; - _commonDims.push_back(cd); - } else { - SideDim ld; - ld.idx = 0; - ld.sideMultiplier = lMul; - ld.outputMultiplier = oMul; - assert(lDims[i].size == oDims[k].size); - ld.size = oDims[k].size; - lMul *= ld.size; - oMul *= ld.size; - _outputSize *= ld.size; - _left.totalSize *= ld.size; - _left.dims.push_back(ld); - } - } else { - // right dim match - assert(j > 0); - assert(rDims[j-1].name == oDims[k].name); - --j; - SideDim rd; - rd.idx = 0; - rd.sideMultiplier = rMul; - rd.outputMultiplier = oMul; - assert(rDims[j].size == oDims[k].size); - rd.size = oDims[k].size; - rMul *= rd.size; - oMul *= rd.size; - _outputSize *= rd.size; - _right.totalSize *= rd.size; - _right.dims.push_back(rd); - } - } -} - - -} // namespace - diff --git a/eval/src/vespa/eval/tensor/dense/dense_dimension_combiner.h b/eval/src/vespa/eval/tensor/dense/dense_dimension_combiner.h deleted file mode 100644 index dd3f74bad9b..00000000000 --- a/eval/src/vespa/eval/tensor/dense/dense_dimension_combiner.h +++ /dev/null @@ -1,114 +0,0 @@ -// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#pragma once - -#include <vespa/eval/tensor/tensor.h> -#include <vespa/eval/tensor/types.h> -#include <vespa/eval/eval/value_type.h> - -namespace vespalib::tensor { - -class DenseDimensionCombiner { - - struct SideDim { - uint32_t idx; - uint32_t size; - uint32_t sideMultiplier; - uint32_t outputMultiplier; - }; - struct CommonDim { - uint32_t idx; - uint32_t size; - uint32_t leftMultiplier; - uint32_t rightMultiplier; - uint32_t outputMultiplier; - }; - - struct SideDims { - std::vector<SideDim> dims; - uint32_t index; - uint32_t totalSize; - - SideDims() : dims(), index(0), totalSize(1u) {} - - void reset(uint32_t &outIndex) { - for (SideDim& d : dims) { - index -= d.idx * d.sideMultiplier; - outIndex -= d.idx * d.outputMultiplier; - d.idx = 0; - } - if (index >= totalSize) { - index -= totalSize; - } - } - void step(uint32_t &outIndex) { - for (SideDim& d : dims) { - d.idx++; - index += d.sideMultiplier; - outIndex += d.outputMultiplier; - if (d.idx < d.size) return; - index -= d.idx * d.sideMultiplier; - outIndex -= d.idx * d.outputMultiplier; - d.idx = 0; - } - index += totalSize; - } - }; - SideDims _left; - SideDims _right; - std::vector<CommonDim> _commonDims; - uint32_t _outputIndex; - uint32_t _outputSize; - -public: - size_t leftIdx() const { return _left.index; } - size_t rightIdx() const { return _right.index; } - size_t outputIdx() const { return _outputIndex; } - - bool leftInRange() const { return _left.index < _left.totalSize; } - bool rightInRange() const { return _right.index < _right.totalSize; } - bool commonInRange() const { return _outputIndex < _outputSize; } - - void leftReset() { _left.reset(_outputIndex); } - void stepLeft() { _left.step(_outputIndex); } - - void rightReset() { _right.reset(_outputIndex); } - void stepRight() { _right.step(_outputIndex); } - - void commonReset() { - for (CommonDim& cd : _commonDims) { - _left.index -= cd.idx * cd.leftMultiplier; - _right.index -= cd.idx * cd.rightMultiplier; - _outputIndex -= cd.idx * cd.outputMultiplier; - cd.idx = 0; - } - if (_outputIndex >= _outputSize) { - _outputIndex -= _outputSize; - } - } - - void stepCommon() { - size_t lim = _commonDims.size(); - for (size_t i = 0; i < lim; ++i) { - CommonDim &cd = _commonDims[i]; - cd.idx++; - _left.index += cd.leftMultiplier; - _right.index += cd.rightMultiplier; - _outputIndex += cd.outputMultiplier; - if (cd.idx < cd.size) return; - _left.index -= cd.idx * cd.leftMultiplier; - _right.index -= cd.idx * cd.rightMultiplier; - _outputIndex -= cd.idx * cd.outputMultiplier; - cd.idx = 0; - } - _outputIndex += _outputSize; - } - - const eval::ValueType result_type; - - DenseDimensionCombiner(const eval::ValueType &lhs, const eval::ValueType &rhs); - - ~DenseDimensionCombiner(); -}; - -} diff --git a/eval/src/vespa/eval/tensor/dense/dense_fast_rename_optimizer.cpp b/eval/src/vespa/eval/tensor/dense/dense_fast_rename_optimizer.cpp index 7c3dde5fa2e..bd84fc4c51a 100644 --- a/eval/src/vespa/eval/tensor/dense/dense_fast_rename_optimizer.cpp +++ b/eval/src/vespa/eval/tensor/dense/dense_fast_rename_optimizer.cpp @@ -2,7 +2,6 @@ #include "dense_fast_rename_optimizer.h" #include "dense_replace_type_function.h" -#include "dense_tensor_view.h" #include <vespa/eval/eval/value.h> namespace vespalib::tensor { diff --git a/eval/src/vespa/eval/tensor/dense/dense_generic_join.h b/eval/src/vespa/eval/tensor/dense/dense_generic_join.h deleted file mode 100644 index daf678d4916..00000000000 --- a/eval/src/vespa/eval/tensor/dense/dense_generic_join.h +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#pragma once - -namespace vespalib::tensor { - class Tensor; -} - -namespace vespalib::tensor::dense { - -/** - * Creates a new tensor using all combinations of input tensor cells with matching - * labels for common dimensions, using func to calculate new cell value - * based on the cell values in the input tensors. - */ -template <typename Function> -std::unique_ptr<Tensor> -generic_join(const DenseTensorView &lhs, const Tensor &rhs, Function &&func); - -template <typename Function> -std::unique_ptr<Tensor> -generic_join(const DenseTensorView &lhs, const DenseTensorView &rhs, Function &&func); - -} diff --git a/eval/src/vespa/eval/tensor/dense/dense_generic_join.hpp b/eval/src/vespa/eval/tensor/dense/dense_generic_join.hpp deleted file mode 100644 index 033ea3631be..00000000000 --- a/eval/src/vespa/eval/tensor/dense/dense_generic_join.hpp +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#pragma once - -#include "dense_generic_join.h" -#include "dense_dimension_combiner.h" -#include "typed_dense_tensor_builder.h" - -namespace vespalib::tensor::dense { - -template <typename LCT, typename RCT, typename OCT, typename Function> -std::unique_ptr<Tensor> -generic_join(DenseDimensionCombiner & combiner, - TypedDenseTensorBuilder<OCT> & builder, - const ConstArrayRef<LCT> & lhsCells, - const ConstArrayRef<RCT> & rhsCells, Function &&func) __attribute__((noinline)); - -template <typename LCT, typename RCT, typename OCT, typename Function> -std::unique_ptr<Tensor> -generic_join(DenseDimensionCombiner & combiner, - TypedDenseTensorBuilder<OCT> & builder, - const ConstArrayRef<LCT> & lhsCells, - const ConstArrayRef<RCT> & rhsCells, Function &&func) -{ - for (combiner.leftReset(); combiner.leftInRange(); combiner.stepLeft()) { - for (combiner.rightReset(); combiner.rightInRange(); combiner.stepRight()) { - for (combiner.commonReset(); combiner.commonInRange(); combiner.stepCommon()) { - size_t outIdx = combiner.outputIdx(); - size_t l = combiner.leftIdx(); - size_t r = combiner.rightIdx(); - builder.insertCell(outIdx, func(lhsCells[l], rhsCells[r])); - } - } - } - return builder.build(); -} - -struct CallGenericJoin { - template <typename LCT, typename RCT, typename Function> - static std::unique_ptr<Tensor> - call(const ConstArrayRef<LCT> & lhsArr, - const ConstArrayRef<RCT> & rhsArr, - DenseDimensionCombiner & combiner, - Function &&func) - { - using OCT = typename eval::UnifyCellTypes<LCT, RCT>::type; - TypedDenseTensorBuilder<OCT> builder(combiner.result_type); - return generic_join(combiner, builder, lhsArr, rhsArr, std::move(func)); - } -}; - -template <typename Function> -std::unique_ptr<Tensor> -generic_join(const DenseTensorView &lhs, const Tensor &rhs, Function &&func) -{ - DenseDimensionCombiner combiner(lhs.fast_type(), rhs.type()); - TypedCells lhsCells = lhs.cells(); - TypedCells rhsCells = rhs.cells(); - return dispatch_2<CallGenericJoin>(lhsCells, rhsCells, combiner, std::move(func)); -} - -} diff --git a/eval/src/vespa/eval/tensor/dense/dense_lambda_function.cpp b/eval/src/vespa/eval/tensor/dense/dense_lambda_function.cpp deleted file mode 100644 index cdbe396dda4..00000000000 --- a/eval/src/vespa/eval/tensor/dense/dense_lambda_function.cpp +++ /dev/null @@ -1,183 +0,0 @@ -// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#include "dense_lambda_function.h" -#include "dense_tensor_view.h" -#include <vespa/vespalib/objects/objectvisitor.h> -#include <vespa/eval/eval/llvm/compiled_function.h> -#include <vespa/eval/eval/llvm/compile_cache.h> -#include <assert.h> - -namespace vespalib::tensor { - -using eval::CompileCache; -using eval::CompiledFunction; -using eval::InterpretedFunction; -using eval::LazyParams; -using eval::PassParams; -using eval::TensorFunction; -using eval::Value; -using eval::DoubleValue; -using eval::ValueType; -using eval::as; -using vespalib::Stash; - -using Instruction = InterpretedFunction::Instruction; -using State = InterpretedFunction::State; - -using namespace eval::tensor_function; - -namespace { - -//----------------------------------------------------------------------------- - -bool step_labels(double *labels, const ValueType &type) { - for (size_t idx = type.dimensions().size(); idx-- > 0; ) { - if ((labels[idx] += 1.0) < type.dimensions()[idx].size) { - return true; - } else { - labels[idx] = 0.0; - } - } - return false; -} - -struct ParamProxy : public LazyParams { - const std::vector<double> &labels; - const LazyParams ¶ms; - const std::vector<size_t> &bindings; - ParamProxy(const std::vector<double> &labels_in, const LazyParams ¶ms_in, const std::vector<size_t> &bindings_in) - : labels(labels_in), params(params_in), bindings(bindings_in) {} - const Value &resolve(size_t idx, Stash &stash) const override { - if (idx < labels.size()) { - return stash.create<DoubleValue>(labels[idx]); - } - return params.resolve(bindings[idx - labels.size()], stash); - } -}; - -//----------------------------------------------------------------------------- - -struct CompiledParams { - const ValueType &result_type; - const std::vector<size_t> &bindings; - size_t num_cells; - CompileCache::Token::UP token; - CompiledParams(const Lambda &lambda) - : result_type(lambda.result_type()), - bindings(lambda.bindings()), - num_cells(result_type.dense_subspace_size()), - token(CompileCache::compile(lambda.lambda(), PassParams::ARRAY)) - { - assert(lambda.lambda().num_params() == (result_type.dimensions().size() + bindings.size())); - } -}; - -template <typename CT> -void my_compiled_lambda_op(eval::InterpretedFunction::State &state, uint64_t param) { - const CompiledParams ¶ms = unwrap_param<CompiledParams>(param); - std::vector<double> args(params.result_type.dimensions().size() + params.bindings.size(), 0.0); - double *bind_next = &args[params.result_type.dimensions().size()]; - for (size_t binding: params.bindings) { - *bind_next++ = state.params->resolve(binding, state.stash).as_double(); - } - auto fun = params.token->get().get_function(); - ArrayRef<CT> dst_cells = state.stash.create_uninitialized_array<CT>(params.num_cells); - CT *dst = &dst_cells[0]; - do { - *dst++ = fun(&args[0]); - } while (step_labels(&args[0], params.result_type)); - state.stack.push_back(state.stash.create<DenseTensorView>(params.result_type, TypedCells(dst_cells))); -} - -struct MyCompiledLambdaOp { - template <typename CT> - static auto invoke() { return my_compiled_lambda_op<CT>; } -}; - -//----------------------------------------------------------------------------- - -struct InterpretedParams { - const ValueType &result_type; - const std::vector<size_t> &bindings; - size_t num_cells; - InterpretedFunction fun; - InterpretedParams(const Lambda &lambda, const ValueBuilderFactory &factory) - : result_type(lambda.result_type()), - bindings(lambda.bindings()), - num_cells(result_type.dense_subspace_size()), - fun(factory, lambda.lambda().root(), lambda.types()) - { - assert(lambda.lambda().num_params() == (result_type.dimensions().size() + bindings.size())); - } -}; - -template <typename CT> -void my_interpreted_lambda_op(eval::InterpretedFunction::State &state, uint64_t param) { - const InterpretedParams ¶ms = unwrap_param<InterpretedParams>(param); - std::vector<double> labels(params.result_type.dimensions().size(), 0.0); - ParamProxy param_proxy(labels, *state.params, params.bindings); - InterpretedFunction::Context ctx(params.fun); - ArrayRef<CT> dst_cells = state.stash.create_uninitialized_array<CT>(params.num_cells); - CT *dst = &dst_cells[0]; - do { - *dst++ = params.fun.eval(ctx, param_proxy).as_double(); - } while (step_labels(&labels[0], params.result_type)); - state.stack.push_back(state.stash.create<DenseTensorView>(params.result_type, TypedCells(dst_cells))); -} - -struct MyInterpretedLambdaOp { - template <typename CT> - static auto invoke() { return my_interpreted_lambda_op<CT>; } -}; - -//----------------------------------------------------------------------------- - -} - -DenseLambdaFunction::DenseLambdaFunction(const Lambda &lambda_in) - : Super(lambda_in.result_type()), - _lambda(lambda_in) -{ -} - -DenseLambdaFunction::~DenseLambdaFunction() = default; - -DenseLambdaFunction::EvalMode -DenseLambdaFunction::eval_mode() const -{ - if (!CompiledFunction::detect_issues(_lambda.lambda()) && - _lambda.types().all_types_are_double()) - { - return EvalMode::COMPILED; - } else { - return EvalMode::INTERPRETED; - } -} - -Instruction -DenseLambdaFunction::compile_self(const ValueBuilderFactory &factory, Stash &stash) const -{ - auto mode = eval_mode(); - using MyTypify = eval::TypifyCellType; - if (mode == EvalMode::COMPILED) { - CompiledParams ¶ms = stash.create<CompiledParams>(_lambda); - auto op = typify_invoke<1,MyTypify,MyCompiledLambdaOp>(result_type().cell_type()); - return Instruction(op, wrap_param<CompiledParams>(params)); - } else { - assert(mode == EvalMode::INTERPRETED); - InterpretedParams ¶ms = stash.create<InterpretedParams>(_lambda, factory); - auto op = typify_invoke<1,MyTypify,MyInterpretedLambdaOp>(result_type().cell_type()); - return Instruction(op, wrap_param<InterpretedParams>(params)); - } -} - -const eval::TensorFunction & -DenseLambdaFunction::optimize(const TensorFunction &expr, Stash &stash) -{ - if (auto lambda = as<Lambda>(expr)) { - return stash.create<DenseLambdaFunction>(*lambda); - } - return expr; -} - -} diff --git a/eval/src/vespa/eval/tensor/dense/dense_lambda_function.h b/eval/src/vespa/eval/tensor/dense/dense_lambda_function.h deleted file mode 100644 index 6698bb44ef0..00000000000 --- a/eval/src/vespa/eval/tensor/dense/dense_lambda_function.h +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#pragma once - -#include <vespa/eval/eval/tensor_function.h> - -namespace vespalib::tensor { - -/** - * Tensor function for generic tensor lambda producing dense tensor - * views directly. This is the catch-all fall-back used by the default - * (production) tensor engine to avoid having a TensorSpec as an - * intermediate result. - **/ -class DenseLambdaFunction : public eval::tensor_function::Leaf -{ - using Super = eval::tensor_function::Leaf; -private: - const eval::tensor_function::Lambda &_lambda; -public: - enum class EvalMode : uint8_t { COMPILED, INTERPRETED }; - DenseLambdaFunction(const eval::tensor_function::Lambda &lambda_in); - ~DenseLambdaFunction() override; - bool result_is_mutable() const override { return true; } - EvalMode eval_mode() const; - eval::InterpretedFunction::Instruction compile_self(const ValueBuilderFactory &factory, Stash &stash) const override; - static const eval::TensorFunction &optimize(const eval::TensorFunction &expr, Stash &stash); -}; - -} diff --git a/eval/src/vespa/eval/tensor/dense/dense_number_join_function.cpp b/eval/src/vespa/eval/tensor/dense/dense_number_join_function.cpp deleted file mode 100644 index e0e66aae01c..00000000000 --- a/eval/src/vespa/eval/tensor/dense/dense_number_join_function.cpp +++ /dev/null @@ -1,123 +0,0 @@ -// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#include "dense_number_join_function.h" -#include "dense_tensor_view.h" -#include <vespa/vespalib/util/typify.h> -#include <vespa/eval/eval/value.h> -#include <vespa/eval/eval/operation.h> -#include <vespa/eval/eval/inline_operation.h> - -namespace vespalib::tensor { - -using vespalib::ArrayRef; - -using eval::CellType; -using eval::Value; -using eval::ValueType; -using eval::TensorFunction; -using eval::TypifyCellType; -using eval::as; - -using namespace eval::operation; -using namespace eval::tensor_function; - -using Primary = DenseNumberJoinFunction::Primary; - -using op_function = eval::InterpretedFunction::op_function; -using Instruction = eval::InterpretedFunction::Instruction; -using State = eval::InterpretedFunction::State; - -namespace { - -template <typename CT, bool inplace> -ArrayRef<CT> make_dst_cells(ConstArrayRef<CT> src_cells, Stash &stash) { - if (inplace) { - return unconstify(src_cells); - } else { - return stash.create_uninitialized_array<CT>(src_cells.size()); - } -} - -template <typename CT, typename Fun, bool inplace, bool swap> -void my_number_join_op(State &state, uint64_t param) { - using OP = typename std::conditional<swap,SwapArgs2<Fun>,Fun>::type; - OP my_op((join_fun_t)param); - const Value &tensor = state.peek(swap ? 0 : 1); - CT number = state.peek(swap ? 1 : 0).as_double(); - auto src_cells = tensor.cells().typify<CT>(); - auto dst_cells = make_dst_cells<CT, inplace>(src_cells, state.stash); - apply_op2_vec_num(dst_cells.begin(), src_cells.begin(), number, dst_cells.size(), my_op); - if (inplace) { - state.pop_pop_push(tensor); - } else { - state.pop_pop_push(state.stash.create<DenseTensorView>(tensor.type(), TypedCells(dst_cells))); - } -} - -//----------------------------------------------------------------------------- - -struct MyGetFun { - template <typename R1, typename R2, typename R3, typename R4> static auto invoke() { - return my_number_join_op<R1, R2, R3::value, R4::value>; - } -}; - -using MyTypify = TypifyValue<TypifyCellType,TypifyOp2,TypifyBool>; - -bool is_dense(const TensorFunction &tf) { return tf.result_type().is_dense(); } -bool is_double(const TensorFunction &tf) { return tf.result_type().is_double(); } -CellType cell_type(const TensorFunction &tf) { return tf.result_type().cell_type(); } - -} // namespace vespalib::tensor::<unnamed> - -//----------------------------------------------------------------------------- - -DenseNumberJoinFunction::DenseNumberJoinFunction(const ValueType &result_type, - const TensorFunction &lhs, - const TensorFunction &rhs, - join_fun_t function_in, - Primary primary_in) - : Join(result_type, lhs, rhs, function_in), - _primary(primary_in) -{ -} - -DenseNumberJoinFunction::~DenseNumberJoinFunction() = default; - -bool -DenseNumberJoinFunction::inplace() const -{ - if (_primary == Primary::LHS) { - return lhs().result_is_mutable(); - } else { - return rhs().result_is_mutable(); - } -} - -Instruction -DenseNumberJoinFunction::compile_self(const ValueBuilderFactory &, Stash &) const -{ - auto op = typify_invoke<4,MyTypify,MyGetFun>(result_type().cell_type(), function(), - inplace(), (_primary == Primary::RHS)); - static_assert(sizeof(uint64_t) == sizeof(function())); - return Instruction(op, (uint64_t)(function())); -} - -const TensorFunction & -DenseNumberJoinFunction::optimize(const TensorFunction &expr, Stash &stash) -{ - if (auto join = as<Join>(expr)) { - const TensorFunction &lhs = join->lhs(); - const TensorFunction &rhs = join->rhs(); - if (is_dense(lhs) && is_double(rhs)) { - assert(cell_type(expr) == cell_type(lhs)); - return stash.create<DenseNumberJoinFunction>(join->result_type(), lhs, rhs, join->function(), Primary::LHS); - } else if (is_double(lhs) && is_dense(rhs)) { - assert(cell_type(expr) == cell_type(rhs)); - return stash.create<DenseNumberJoinFunction>(join->result_type(), lhs, rhs, join->function(), Primary::RHS); - } - } - return expr; -} - -} // namespace vespalib::tensor diff --git a/eval/src/vespa/eval/tensor/dense/dense_number_join_function.h b/eval/src/vespa/eval/tensor/dense/dense_number_join_function.h deleted file mode 100644 index 3acbd83e1bb..00000000000 --- a/eval/src/vespa/eval/tensor/dense/dense_number_join_function.h +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#pragma once - -#include <vespa/eval/eval/tensor_function.h> -#include <vespa/eval/eval/operation.h> - -namespace vespalib::tensor { - -/** - * Tensor function for join operations between dense tensors and - * numbers. - **/ -class DenseNumberJoinFunction : public eval::tensor_function::Join -{ -public: - enum class Primary : uint8_t { LHS, RHS }; - using join_fun_t = vespalib::eval::operation::op2_t; -private: - Primary _primary; -public: - DenseNumberJoinFunction(const eval::ValueType &result_type, - const TensorFunction &lhs, - const TensorFunction &rhs, - join_fun_t function_in, - Primary primary_in); - ~DenseNumberJoinFunction() override; - Primary primary() const { return _primary; } - bool inplace() const; - eval::InterpretedFunction::Instruction compile_self(const ValueBuilderFactory &factory, Stash &stash) const override; - static const eval::TensorFunction &optimize(const eval::TensorFunction &expr, Stash &stash); -}; - -} // namespace vespalib::tensor diff --git a/eval/src/vespa/eval/tensor/dense/dense_single_reduce_function.cpp b/eval/src/vespa/eval/tensor/dense/dense_single_reduce_function.cpp index f107e85eaa2..c10fd6c0fe7 100644 --- a/eval/src/vespa/eval/tensor/dense/dense_single_reduce_function.cpp +++ b/eval/src/vespa/eval/tensor/dense/dense_single_reduce_function.cpp @@ -1,7 +1,6 @@ // Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include "dense_single_reduce_function.h" -#include "dense_tensor_view.h" #include <vespa/vespalib/util/typify.h> #include <vespa/eval/eval/value.h> #include <cassert> diff --git a/eval/src/vespa/eval/tensor/dense/dense_tensor.h b/eval/src/vespa/eval/tensor/dense/dense_tensor.h deleted file mode 100644 index f4b2b0a584f..00000000000 --- a/eval/src/vespa/eval/tensor/dense/dense_tensor.h +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#pragma once - -#include "dense_tensor_view.h" - -namespace vespalib::tensor { - -/** - * A dense tensor where all dimensions are indexed. - * Tensor cells are stored in an underlying array according to the order of the dimensions. - */ -template <typename CT> -class DenseTensor : public DenseTensorView -{ -public: - DenseTensor() = delete; - ~DenseTensor() override; - DenseTensor(eval::ValueType type_in, std::vector<CT> &&cells_in); - - // for unit tests - template <typename RCT> - bool operator==(const DenseTensor<RCT> &rhs) const; - - MemoryUsage get_memory_usage() const override { - size_t alloc = sizeof(DenseTensor) + (sizeof(CT) * _cells.capacity()); - size_t used = sizeof(DenseTensor) + (sizeof(CT) * _cells.size()); - // missing: extra memory used by _type - return MemoryUsage(alloc, used, 0, 0); - } - -private: - eval::ValueType _type; - std::vector<CT> _cells; -}; - -} diff --git a/eval/src/vespa/eval/tensor/dense/dense_tensor_address_mapper.cpp b/eval/src/vespa/eval/tensor/dense/dense_tensor_address_mapper.cpp deleted file mode 100644 index f32af0d097b..00000000000 --- a/eval/src/vespa/eval/tensor/dense/dense_tensor_address_mapper.cpp +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#include "dense_tensor_address_mapper.h" -#include <vespa/eval/eval/value_type.h> -#include <vespa/eval/tensor/tensor_address.h> -#include <vespa/eval/tensor/tensor_address_element_iterator.h> - -namespace vespalib::tensor { - -uint32_t -DenseTensorAddressMapper::mapLabelToNumber(stringref label) -{ - uint32_t result = 0; - for (char c : label) { - if (c < '0' || c > '9') { - return BAD_LABEL; // bad char - } - result = result * 10 + (c - '0'); - if (result > 100000000) { - return BAD_LABEL; // overflow - } - } - return result; -} - -uint32_t -DenseTensorAddressMapper::mapAddressToIndex(const TensorAddress &address, const eval::ValueType &type) -{ - uint32_t idx = 0; - TensorAddressElementIterator<TensorAddress> addressIterator(address); - for (const auto &dimension : type.dimensions()) { - if (addressIterator.skipToDimension(dimension.name)) { - uint32_t label = mapLabelToNumber(addressIterator.label()); - if (label == BAD_LABEL || label >= dimension.size) { - return BAD_ADDRESS; - } - idx = idx * dimension.size + label; - addressIterator.next(); - } else { - // output dimension not in input - idx = idx * dimension.size; - } - } - return idx; -} - -} diff --git a/eval/src/vespa/eval/tensor/dense/dense_tensor_address_mapper.h b/eval/src/vespa/eval/tensor/dense/dense_tensor_address_mapper.h deleted file mode 100644 index 7cd776a260c..00000000000 --- a/eval/src/vespa/eval/tensor/dense/dense_tensor_address_mapper.h +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#pragma once - -#include <limits> -#include <cstdint> - -namespace vespalib::eval { class ValueType; } -namespace vespalib { class stringref; } - -namespace vespalib::tensor { - -class TensorAddress; - -/** - * Utility class for mapping of tensor adress to index - */ -class DenseTensorAddressMapper -{ -public: - static constexpr uint32_t BAD_LABEL = std::numeric_limits<uint32_t>::max(); - static constexpr uint32_t BAD_ADDRESS = std::numeric_limits<uint32_t>::max(); - static uint32_t mapLabelToNumber(stringref label); - static uint32_t mapAddressToIndex(const TensorAddress &address, const eval::ValueType &type); -}; - -} diff --git a/eval/src/vespa/eval/tensor/dense/dense_tensor_cells_iterator.cpp b/eval/src/vespa/eval/tensor/dense/dense_tensor_cells_iterator.cpp deleted file mode 100644 index 55d0e29bc35..00000000000 --- a/eval/src/vespa/eval/tensor/dense/dense_tensor_cells_iterator.cpp +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#include "dense_tensor_cells_iterator.h" - -namespace vespalib::tensor { - -DenseTensorCellsIterator::DenseTensorCellsIterator(const eval::ValueType &type_in, TypedCells cells) - : _type(type_in), - _cells(cells), - _cellIdx(0), - _lastDimension(type_in.dimensions().size() - 1), - _address(type_in.dimensions().size(), 0) -{} -DenseTensorCellsIterator::~DenseTensorCellsIterator() = default; - -} diff --git a/eval/src/vespa/eval/tensor/dense/dense_tensor_cells_iterator.h b/eval/src/vespa/eval/tensor/dense/dense_tensor_cells_iterator.h deleted file mode 100644 index 4611ffaf1d1..00000000000 --- a/eval/src/vespa/eval/tensor/dense/dense_tensor_cells_iterator.h +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#pragma once - -#include <vespa/eval/eval/value_type.h> -#include <vespa/vespalib/util/arrayref.h> -#include "typed_cells_dispatch.h" - -namespace vespalib::tensor { - -/** - * Utility class to iterate over cells in a dense tensor. - */ -class DenseTensorCellsIterator -{ -public: - using size_type = eval::ValueType::Dimension::size_type; - using Address = std::vector<size_type>; -private: - - const eval::ValueType &_type; - TypedCells _cells; - size_t _cellIdx; - const int32_t _lastDimension; - Address _address; -public: - DenseTensorCellsIterator(const eval::ValueType &type_in, TypedCells cells); - ~DenseTensorCellsIterator(); - void next() { - ++_cellIdx; - for (int32_t i = _lastDimension; i >= 0; --i) { - _address[i]++; - if (__builtin_expect((_address[i] != _type.dimensions()[i].size), true)) { - // Outer dimension labels can only be increased when this label wraps around. - break; - } else { - _address[i] = 0; - } - } - } - bool valid() const { return _cellIdx < _cells.size; } - double cell() const { return GetCell::from(_cells, _cellIdx); } - const Address &address() const { return _address; } - const eval::ValueType &fast_type() const { return _type; } -}; - -} diff --git a/eval/src/vespa/eval/tensor/dense/dense_tensor_create_function.cpp b/eval/src/vespa/eval/tensor/dense/dense_tensor_create_function.cpp index e38cf638e9c..c233a51a473 100644 --- a/eval/src/vespa/eval/tensor/dense/dense_tensor_create_function.cpp +++ b/eval/src/vespa/eval/tensor/dense/dense_tensor_create_function.cpp @@ -1,18 +1,17 @@ // Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include "dense_tensor_create_function.h" -#include "dense_tensor_view.h" #include <vespa/eval/eval/value.h> -#include <vespa/eval/tensor/tensor.h> namespace vespalib::tensor { using eval::DenseValueView; -using eval::Value; using eval::DoubleValue; -using eval::ValueType; -using eval::TensorSpec; using eval::TensorFunction; +using eval::TensorSpec; +using eval::TypedCells; +using eval::Value; +using eval::ValueType; using Child = eval::TensorFunction::Child; using eval::as; using namespace eval::tensor_function; diff --git a/eval/src/vespa/eval/tensor/dense/dense_tensor_modify.cpp b/eval/src/vespa/eval/tensor/dense/dense_tensor_modify.cpp deleted file mode 100644 index 4777abcbdef..00000000000 --- a/eval/src/vespa/eval/tensor/dense/dense_tensor_modify.cpp +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#include "dense_tensor_modify.h" -#include "dense_tensor_address_mapper.h" -#include "dense_tensor.h" - -namespace vespalib::tensor { - -template <class CT> -DenseTensorModify<CT>::DenseTensorModify(join_fun_t op, const eval::ValueType &type, std::vector<CT> &&cells) - : _op(op), - _type(type), - _cells(std::move(cells)) -{ - assert(vespalib::eval::check_cell_type<CT>(type.cell_type())); -} - -template <class CT> -DenseTensorModify<CT>::~DenseTensorModify() = default; - -template <class CT> -void -DenseTensorModify<CT>::visit(const TensorAddress &address, double value) -{ - uint32_t idx = DenseTensorAddressMapper::mapAddressToIndex(address, _type); - if (idx != DenseTensorAddressMapper::BAD_ADDRESS) { - double nv = _op(_cells[idx], value); - _cells[idx] = (CT) nv; - } -} - -template <class CT> -std::unique_ptr<Tensor> -DenseTensorModify<CT>::build() -{ - return std::make_unique<DenseTensor<CT>>(_type, std::move(_cells)); -} - -template class DenseTensorModify<float>; -template class DenseTensorModify<double>; - -} // namespace diff --git a/eval/src/vespa/eval/tensor/dense/dense_tensor_modify.h b/eval/src/vespa/eval/tensor/dense/dense_tensor_modify.h deleted file mode 100644 index 13ed735eb6a..00000000000 --- a/eval/src/vespa/eval/tensor/dense/dense_tensor_modify.h +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#pragma once - -#include <vespa/eval/eval/operation.h> -#include <vespa/eval/tensor/tensor_visitor.h> -#include "dense_tensor_view.h" - -namespace vespalib::tensor { - -/* - * This class handles tensor modify update on a dense tensor. - * For all cells visited, a join function is applied to determine - * the new cell value. - */ -template <class CT> -class DenseTensorModify : public TensorVisitor -{ - using join_fun_t = vespalib::eval::operation::op2_t; - join_fun_t _op; - const eval::ValueType &_type; - std::vector<CT> _cells; - -public: - DenseTensorModify(join_fun_t op, const eval::ValueType &type, std::vector<CT> &&cells); - ~DenseTensorModify(); - void visit(const TensorAddress &address, double value) override; - std::unique_ptr<Tensor> build(); -}; - -} diff --git a/eval/src/vespa/eval/tensor/dense/dense_tensor_reduce.cpp b/eval/src/vespa/eval/tensor/dense/dense_tensor_reduce.cpp deleted file mode 100644 index d44fe88bb10..00000000000 --- a/eval/src/vespa/eval/tensor/dense/dense_tensor_reduce.cpp +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#include "dense_tensor_reduce.hpp" - -namespace vespalib::tensor::dense { - -size_t -DimensionReducer::calcCellsSize(const eval::ValueType &type) -{ - size_t cellsSize = 1; - for (const auto &dim : type.dimensions()) { - cellsSize *= dim.size; - } - return cellsSize; -} - -DimensionReducer::DimensionReducer(const eval::ValueType &oldType, const string &dimensionToRemove) - : _type(oldType.reduce({ dimensionToRemove })), - _innerDimSize(1), - _sumDimSize(1), - _outerDimSize(1) -{ - setup(oldType, dimensionToRemove); -} - -DimensionReducer::~DimensionReducer() = default; - -void -DimensionReducer::setup(const eval::ValueType &oldType, const vespalib::string &dimensionToRemove) -{ - auto itr = std::lower_bound(oldType.dimensions().cbegin(), - oldType.dimensions().cend(), - dimensionToRemove, - [](const auto &dim, const auto &dimension) - { return dim.name < dimension; }); - if ((itr != oldType.dimensions().end()) && (itr->name == dimensionToRemove)) { - for (auto outerItr = oldType.dimensions().cbegin(); outerItr != itr; ++outerItr) { - _outerDimSize *= outerItr->size; - } - _sumDimSize = itr->size; - for (++itr; itr != oldType.dimensions().cend(); ++itr) { - _innerDimSize *= itr->size; - } - } else { - _outerDimSize = calcCellsSize(oldType); - } -} - -} - diff --git a/eval/src/vespa/eval/tensor/dense/dense_tensor_reduce.h b/eval/src/vespa/eval/tensor/dense/dense_tensor_reduce.h deleted file mode 100644 index fb054318985..00000000000 --- a/eval/src/vespa/eval/tensor/dense/dense_tensor_reduce.h +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#pragma once - -#include "dense_tensor.h" - -namespace vespalib::tensor::dense { - -/** - * Returns a tensor with the given dimension(s) removed and the cell values in that dimension(s) - * combined using the given func. - */ -template<typename Function> -std::unique_ptr<Tensor> -reduce(const DenseTensorView &tensor, const std::vector<vespalib::string> &dimensions, Function &&func); - -} - diff --git a/eval/src/vespa/eval/tensor/dense/dense_tensor_reduce.hpp b/eval/src/vespa/eval/tensor/dense/dense_tensor_reduce.hpp deleted file mode 100644 index cbdf7e0a3ca..00000000000 --- a/eval/src/vespa/eval/tensor/dense/dense_tensor_reduce.hpp +++ /dev/null @@ -1,112 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#include "dense_tensor_reduce.h" -#include <cassert> -#include <algorithm> - -namespace vespalib::tensor::dense { - -class DimensionReducer -{ -private: - eval::ValueType _type; - size_t _innerDimSize; - size_t _sumDimSize; - size_t _outerDimSize; - - static size_t calcCellsSize(const eval::ValueType &type); - void setup(const eval::ValueType &oldType, const vespalib::string &dimensionToRemove); -public: - DimensionReducer(const eval::ValueType &oldType, const string &dimensionToRemove); - ~DimensionReducer(); - - template <typename T, typename Function> - std::unique_ptr<DenseTensorView> - reduceCells(ConstArrayRef<T> cellsIn, Function &&func) { - size_t resultSize = calcCellsSize(_type); - std::vector<T> cellsOut(resultSize); - auto itr_in = cellsIn.cbegin(); - auto itr_out = cellsOut.begin(); - for (size_t outerDim = 0; outerDim < _outerDimSize; ++outerDim) { - auto saved_itr = itr_out; - for (size_t innerDim = 0; innerDim < _innerDimSize; ++innerDim) { - *itr_out = *itr_in; - ++itr_out; - ++itr_in; - } - for (size_t sumDim = 1; sumDim < _sumDimSize; ++sumDim) { - itr_out = saved_itr; - for (size_t innerDim = 0; innerDim < _innerDimSize; ++innerDim) { - *itr_out = func(*itr_out, *itr_in); - ++itr_out; - ++itr_in; - } - } - } - assert(itr_out == cellsOut.end()); - assert(itr_in == cellsIn.cend()); - return std::make_unique<DenseTensor<T>>(std::move(_type), std::move(cellsOut)); - } -}; - -namespace { - -struct CallReduceCells { - template <typename CT, typename Function> - static std::unique_ptr<DenseTensorView> - call(const ConstArrayRef<CT> &oldCells, DimensionReducer &reducer, Function &&func) { - return reducer.reduceCells(oldCells, func); - } - - template <typename CT, typename Function> - static double - call(const ConstArrayRef<CT> &oldCells, Function &&func) { - assert(oldCells.size() > 0); - double result = oldCells[0]; - for (size_t i = 1; i < oldCells.size(); ++i) { - result = func(result, oldCells[i]); - } - return result; - } -}; - -template <typename Function> -std::unique_ptr<DenseTensorView> -reduce(const DenseTensorView &tensor, const vespalib::string &dimensionToRemove, Function &&func) -{ - DimensionReducer reducer(tensor.fast_type(), dimensionToRemove); - TypedCells oldCells = tensor.cells(); - return dispatch_1<CallReduceCells>(oldCells, reducer, func); -} - -template <typename Function> -double -reduce_all_dimensions(TypedCells oldCells, Function &&func) -{ - return dispatch_1<CallReduceCells>(oldCells, func); -} - -} - -template <typename Function> -std::unique_ptr<Tensor> -reduce(const DenseTensorView &tensor, const std::vector<vespalib::string> &dimensions, Function &&func) -{ - if ((dimensions.size() == 0) || - (dimensions.size() == tensor.fast_type().dimensions().size())) - { - eval::ValueType newType = tensor.fast_type().reduce(dimensions); - assert(newType.is_double()); - double result = reduce_all_dimensions(tensor.cells(), func); - std::vector<double> newCells({result}); - return std::make_unique<DenseTensor<double>>(std::move(newType), std::move(newCells)); - } - std::unique_ptr<DenseTensorView> result = reduce(tensor, dimensions[0], func); - for (size_t i = 1; i < dimensions.size(); ++i) { - std::unique_ptr<DenseTensorView> tmpResult = reduce(*result, dimensions[i], func); - result = std::move(tmpResult); - } - return result; -} - -} diff --git a/eval/src/vespa/eval/tensor/dense/dense_tensor_value_builder.cpp b/eval/src/vespa/eval/tensor/dense/dense_tensor_value_builder.cpp deleted file mode 100644 index 6a5bb33ca06..00000000000 --- a/eval/src/vespa/eval/tensor/dense/dense_tensor_value_builder.cpp +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#include "dense_tensor_value_builder.h" - -namespace vespalib::tensor { - -template<typename T> -DenseTensorValueBuilder<T>::DenseTensorValueBuilder(const eval::ValueType &type, - size_t subspace_size_in) - : _type(type), - _cells(subspace_size_in) -{ -} - -template<typename T> -DenseTensorValueBuilder<T>::~DenseTensorValueBuilder() = default; - -template class DenseTensorValueBuilder<float>; -template class DenseTensorValueBuilder<double>; - -} diff --git a/eval/src/vespa/eval/tensor/dense/dense_tensor_value_builder.h b/eval/src/vespa/eval/tensor/dense/dense_tensor_value_builder.h deleted file mode 100644 index 49a660553ee..00000000000 --- a/eval/src/vespa/eval/tensor/dense/dense_tensor_value_builder.h +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#pragma once - -#include "dense_tensor.h" - -namespace vespalib::tensor { - -/** - * A builder for DenseTensor objects - **/ -template<typename T> -class DenseTensorValueBuilder : public eval::ValueBuilder<T> -{ -private: - eval::ValueType _type; - std::vector<T> _cells; -public: - DenseTensorValueBuilder(const eval::ValueType &type, size_t subspace_size_in); - ~DenseTensorValueBuilder() override; - ArrayRef<T> - add_subspace(ConstArrayRef<vespalib::stringref>) override { - return _cells; - } - std::unique_ptr<eval::Value> - build(std::unique_ptr<eval::ValueBuilder<T>>) override { - return std::make_unique<DenseTensor<T>>(std::move(_type), std::move(_cells)); - } -}; - -} // namespace diff --git a/eval/src/vespa/eval/tensor/dense/dense_tensor_view.cpp b/eval/src/vespa/eval/tensor/dense/dense_tensor_view.cpp deleted file mode 100644 index 757072e74c4..00000000000 --- a/eval/src/vespa/eval/tensor/dense/dense_tensor_view.cpp +++ /dev/null @@ -1,324 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#include "dense_tensor_view.h" -#include "dense_generic_join.hpp" -#include "dense_tensor_reduce.hpp" -#include "dense_tensor_modify.h" -#include <vespa/vespalib/util/stringfmt.h> -#include <vespa/vespalib/util/exceptions.h> -#include <vespa/vespalib/stllike/asciistream.h> -#include <vespa/eval/tensor/cell_values.h> -#include <vespa/eval/tensor/tensor_address_builder.h> -#include <vespa/eval/tensor/tensor_visitor.h> -#include <vespa/eval/eval/operation.h> -#include <sstream> - -#include <vespa/log/log.h> -LOG_SETUP(".eval.tensor.dense.dense_tensor_view"); - -using vespalib::eval::TensorSpec; - -namespace vespalib::tensor { - -namespace { - -string -dimensionsAsString(const eval::ValueType &type) -{ - std::ostringstream oss; - bool first = true; - oss << "["; - for (const auto &dim : type.dimensions()) { - if (!first) { - oss << ","; - } - first = false; - oss << dim.name << ":" << dim.size; - } - oss << "]"; - return oss.str(); -} - -void -checkCellsSize(const eval::ValueType &type, TypedCells cells) -{ - auto cellsSize = type.dense_subspace_size(); - if (cells.size != cellsSize) { - throw IllegalStateException(make_string("wrong cell size, " - "expected=%zu, " - "actual=%zu", - cellsSize, - cells.size)); - } -} - -void -checkDimensions(const eval::ValueType &lhs, const eval::ValueType &rhs, - vespalib::stringref operation) -{ - if (lhs.dimensions() != rhs.dimensions()) { - throw IllegalStateException(make_string("mismatching dimensions for " - "dense tensor %s, " - "lhs dimensions = '%s', " - "rhs dimensions = '%s'", - operation.data(), - dimensionsAsString(lhs).c_str(), - dimensionsAsString(rhs).c_str())); - } -} - -/* - * Join the cells of two tensors. - * - * The given function is used to calculate the resulting cell value - * for overlapping cells. - */ -template <typename LCT, typename RCT, typename Function> -static Tensor::UP -sameShapeJoin(const ConstArrayRef<LCT> &lhs, const ConstArrayRef<RCT> &rhs, - const std::vector<eval::ValueType::Dimension> &lhs_dims, - Function &&func) -{ - size_t sz = lhs.size(); - assert(sz == rhs.size()); - using OCT = typename eval::UnifyCellTypes<LCT,RCT>::type; - std::vector<OCT> newCells; - newCells.reserve(sz); - auto rhsCellItr = rhs.cbegin(); - for (const auto &lhsCell : lhs) { - OCT v = func(lhsCell, *rhsCellItr); - newCells.push_back(v); - ++rhsCellItr; - } - assert(rhsCellItr == rhs.cend()); - assert(newCells.size() == sz); - auto newType = eval::ValueType::tensor_type(lhs_dims, eval::get_cell_type<OCT>()); - return std::make_unique<DenseTensor<OCT>>(std::move(newType), std::move(newCells)); -} - -struct CallJoin -{ - template <typename LCT, typename RCT, typename Function> - static Tensor::UP - call(const ConstArrayRef<LCT> &lhs, const ConstArrayRef<RCT> &rhs, - const std::vector<eval::ValueType::Dimension> &lhs_dims, - Function &&func) - { - return sameShapeJoin(lhs, rhs, lhs_dims, std::move(func)); - } -}; - -template <typename Function> -Tensor::UP -joinDenseTensors(const DenseTensorView &lhs, const Tensor &rhs, - vespalib::stringref operation, - Function &&func) -{ - const auto & lhs_type = lhs.fast_type(); - const auto & rhs_type = rhs.type(); - TypedCells lhs_cells = lhs.cells(); - TypedCells rhs_cells = rhs.cells(); - checkDimensions(lhs_type, rhs_type, operation); - checkCellsSize(lhs_type, lhs_cells); - checkCellsSize(rhs_type, rhs_cells); - return dispatch_2<CallJoin>(lhs_cells, rhs_cells, lhs_type.dimensions(), std::move(func)); -} - -bool sameCells(TypedCells lhs, TypedCells rhs) -{ - if (lhs.size != rhs.size) { - return false; - } - for (size_t i = 0; i < lhs.size; ++i) { - if (GetCell::from(lhs, i) != GetCell::from(rhs, i)) { - return false; - } - } - return true; -} - -} - -bool -DenseTensorView::operator==(const DenseTensorView &rhs) const -{ - return (_typeRef == rhs._typeRef) && sameCells(_cellsRef, rhs._cellsRef); -} - -const eval::ValueType & -DenseTensorView::type() const -{ - return _typeRef; -} - -struct CallSum { - template <typename CT> - static double - call(const ConstArrayRef<CT> &arr) { - double res = 0.0; - for (CT val : arr) { - res += val; - } - return res; - } -}; - -double -DenseTensorView::as_double() const -{ - return dispatch_1<CallSum>(_cellsRef); -} - -struct CallApply { - template <typename CT> - static Tensor::UP - call(const ConstArrayRef<CT> &oldCells, const eval::ValueType &newType, const CellFunction &func) - { - std::vector<CT> newCells; - newCells.reserve(oldCells.size()); - for (const auto &cell : oldCells) { - CT nv = func.apply(cell); - newCells.push_back(nv); - } - return std::make_unique<DenseTensor<CT>>(newType, std::move(newCells)); - } -}; - -Tensor::UP -DenseTensorView::apply(const CellFunction &func) const -{ - return dispatch_1<CallApply>(_cellsRef, _typeRef, func); -} - -namespace { - -void -buildAddress(const DenseTensorCellsIterator &itr, TensorSpec::Address &address) -{ - auto addressItr = itr.address().begin(); - for (const auto &dim : itr.fast_type().dimensions()) { - address.emplace(std::make_pair(dim.name, TensorSpec::Label(*addressItr++))); - } - assert(addressItr == itr.address().end()); -} - -} - -TensorSpec -DenseTensorView::toSpec() const -{ - TensorSpec result(type().to_spec()); - TensorSpec::Address address; - for (CellsIterator itr(_typeRef, _cellsRef); itr.valid(); itr.next()) { - buildAddress(itr, address); - result.add(address, itr.cell()); - address.clear(); - } - return result; -} - -void -DenseTensorView::accept(TensorVisitor &visitor) const -{ - CellsIterator iterator(_typeRef, _cellsRef); - TensorAddressBuilder addressBuilder; - TensorAddress address; - vespalib::string label; - while (iterator.valid()) { - addressBuilder.clear(); - auto rawIndex = iterator.address().begin(); - for (const auto &dimension : _typeRef.dimensions()) { - label = vespalib::make_string("%u", *rawIndex); - addressBuilder.add(dimension.name, label); - ++rawIndex; - } - address = addressBuilder.build(); - visitor.visit(address, iterator.cell()); - iterator.next(); - } -} - -Tensor::UP -DenseTensorView::join(join_fun_t function, const Tensor &arg) const -{ - if (fast_type().dimensions() == arg.type().dimensions()) { - if (function == eval::operation::Mul::f) { - return joinDenseTensors(*this, arg, "mul", - [](double a, double b) { return (a * b); }); - } - if (function == eval::operation::Add::f) { - return joinDenseTensors(*this, arg, "add", - [](double a, double b) { return (a + b); }); - } - return joinDenseTensors(*this, arg, "join", function); - } - if (function == eval::operation::Mul::f) { - return dense::generic_join(*this, arg, [](auto a, auto b) { return (a * b); }); - } - if (function == eval::operation::Add::f) { - return dense::generic_join(*this, arg, [](double a, double b) { return (a + b); }); - } - return dense::generic_join(*this, arg, function); -} - -Tensor::UP -DenseTensorView::merge(join_fun_t function, const Tensor &arg) const -{ - assert(fast_type().dimensions() == arg.type().dimensions()); - return join(function, arg); -} - -Tensor::UP -DenseTensorView::reduce_all(join_fun_t op, const std::vector<vespalib::string> &dims) const -{ - if (op == eval::operation::Mul::f) { - return dense::reduce(*this, dims, [](double a, double b) { return (a * b);}); - } - if (op == eval::operation::Add::f) { - return dense::reduce(*this, dims, [](auto a, auto b) { return (a + b);}); - } - return dense::reduce(*this, dims, op); -} - -Tensor::UP -DenseTensorView::reduce(join_fun_t op, const std::vector<vespalib::string> &dimensions) const -{ - return dimensions.empty() - ? reduce_all(op, _typeRef.dimension_names()) - : reduce_all(op, dimensions); -} - -struct CallModify -{ - using join_fun_t = vespalib::eval::operation::op2_t; - - template <typename CT> - static std::unique_ptr<Tensor> - call(const ConstArrayRef<CT> &arr, join_fun_t op, const eval::ValueType &typeRef, const CellValues &cellValues) - { - std::vector newCells(arr.begin(), arr.end()); - DenseTensorModify<CT> modifier(op, typeRef, std::move(newCells)); - cellValues.accept(modifier); - return modifier.build(); - } -}; - -std::unique_ptr<Tensor> -DenseTensorView::modify(join_fun_t op, const CellValues &cellValues) const -{ - return dispatch_1<CallModify>(_cellsRef, op, _typeRef, cellValues); -} - -std::unique_ptr<Tensor> -DenseTensorView::add(const Tensor &) const -{ - LOG_ABORT("should not be reached"); -} - -std::unique_ptr<Tensor> -DenseTensorView::remove(const CellValues &) const -{ - LOG_ABORT("should not be reached"); -} - -} diff --git a/eval/src/vespa/eval/tensor/dense/dense_tensor_view.h b/eval/src/vespa/eval/tensor/dense/dense_tensor_view.h deleted file mode 100644 index 3ebd62208c3..00000000000 --- a/eval/src/vespa/eval/tensor/dense/dense_tensor_view.h +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#pragma once - -#include "typed_cells_dispatch.h" -#include "dense_tensor_cells_iterator.h" -#include <vespa/eval/tensor/tensor.h> - -namespace vespalib::tensor { - -/** - * A view to a dense tensor where all dimensions are indexed. - * Tensor cells are stored in an underlying array according to the order of the dimensions. - */ -class DenseTensorView : public Tensor -{ -public: - using CellsIterator = DenseTensorCellsIterator; - using Address = std::vector<eval::ValueType::Dimension::size_type>; - - DenseTensorView(const DenseTensorView &rhs) : DenseTensorView(rhs._typeRef, rhs._cellsRef) {} - DenseTensorView(const eval::ValueType &type_in, TypedCells cells_in) - : _typeRef(type_in), - _cellsRef(cells_in) - { - assert(_typeRef.cell_type() == cells_in.type); - } - - const eval::ValueType &fast_type() const { return _typeRef; } - TypedCells cells() const final override { return _cellsRef; } - const Index &index() const override { return eval::TrivialIndex::get(); } - bool operator==(const DenseTensorView &rhs) const; - CellsIterator cellsIterator() const { return CellsIterator(_typeRef, _cellsRef); } - - const eval::ValueType &type() const override; - double as_double() const override; - Tensor::UP apply(const CellFunction &func) const override; - Tensor::UP join(join_fun_t function, const Tensor &arg) const override; - Tensor::UP merge(join_fun_t function, const Tensor &arg) const override; - Tensor::UP reduce(join_fun_t op, const std::vector<vespalib::string> &dimensions) const override; - std::unique_ptr<Tensor> modify(join_fun_t op, const CellValues &cellValues) const override; - std::unique_ptr<Tensor> add(const Tensor &arg) const override; - std::unique_ptr<Tensor> remove(const CellValues &) const override; - eval::TensorSpec toSpec() const override; - void accept(TensorVisitor &visitor) const override; - MemoryUsage get_memory_usage() const override { - size_t sz = sizeof(DenseTensorView); - return MemoryUsage(sz, sz, 0, 0); - } - -protected: - explicit DenseTensorView(const eval::ValueType &type_in) - : _typeRef(type_in), - _cellsRef() - {} - - void initCellsRef(TypedCells cells_in) { - assert(_typeRef.cell_type() == cells_in.type); - _cellsRef = cells_in; - } -private: - Tensor::UP reduce_all(join_fun_t op, const std::vector<vespalib::string> &dimensions) const; - - const eval::ValueType &_typeRef; - TypedCells _cellsRef; -}; - -} diff --git a/eval/src/vespa/eval/tensor/dense/typed_cells_dispatch.cpp b/eval/src/vespa/eval/tensor/dense/typed_cells_dispatch.cpp deleted file mode 100644 index 874a530e767..00000000000 --- a/eval/src/vespa/eval/tensor/dense/typed_cells_dispatch.cpp +++ /dev/null @@ -1,3 +0,0 @@ -// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#include "typed_cells_dispatch.h" diff --git a/eval/src/vespa/eval/tensor/dense/typed_cells_dispatch.h b/eval/src/vespa/eval/tensor/dense/typed_cells_dispatch.h deleted file mode 100644 index 7a35966cef8..00000000000 --- a/eval/src/vespa/eval/tensor/dense/typed_cells_dispatch.h +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#pragma once - -#include <vespa/eval/eval/typed_cells.h> - -namespace vespalib::tensor { - -using vespalib::eval::CellType; -using TypedCells = vespalib::eval::TypedCells; - -template <typename TGT, typename... Args> -decltype(auto) dispatch_1(const TypedCells &a, Args &&...args) { - switch (a.type) { - case CellType::DOUBLE: return TGT::call(a.unsafe_typify<double>(), std::forward<Args>(args)...); - case CellType::FLOAT: return TGT::call(a.unsafe_typify<float>(), std::forward<Args>(args)...); - } - abort(); -} - -template <typename TGT, typename A1, typename... Args> -decltype(auto) dispatch_2(A1 &&a, const TypedCells &b, Args &&...args) { - switch (b.type) { - case CellType::DOUBLE: return dispatch_1<TGT>(std::forward<A1>(a), b.unsafe_typify<double>(), std::forward<Args>(args)...); - case CellType::FLOAT: return dispatch_1<TGT>(std::forward<A1>(a), b.unsafe_typify<float>(), std::forward<Args>(args)...); - } - abort(); -} - -struct GetCell { - template<typename T> - static double call(ConstArrayRef<T> arr, size_t idx) { - return arr[idx]; - } - static double from(TypedCells src, size_t idx) { - return dispatch_1<GetCell>(src, idx); - } -}; - -} // namespace diff --git a/eval/src/vespa/eval/tensor/join_tensors.h b/eval/src/vespa/eval/tensor/join_tensors.h deleted file mode 100644 index d66d0c1bf8e..00000000000 --- a/eval/src/vespa/eval/tensor/join_tensors.h +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#pragma once - -#include "tensor.h" -#include "direct_tensor_builder.h" - -namespace vespalib::tensor { - -/* - * Join the cells of two tensors. - * The given function is used to calculate the resulting cell value for overlapping cells. - */ -template <typename TensorImplType, typename Function> -Tensor::UP -joinTensors(const TensorImplType &lhs, - const TensorImplType &rhs, - Function &&func) -{ - DirectSparseTensorBuilder - builder(lhs.combineDimensionsWith(rhs), lhs.my_cells()); - for (const auto &rhsCell : rhs.my_cells()) { - builder.insertCell(rhsCell.first, rhsCell.second, func); - } - return builder.build(); -} - -/* - * Join the cells of two tensors, where the rhs values are treated as negated values. - * The given function is used to calculate the resulting cell value for overlapping cells. - */ -template <typename TensorImplType, typename Function> -Tensor::UP -joinTensorsNegated(const TensorImplType &lhs, - const TensorImplType &rhs, - Function &&func) -{ - DirectSparseTensorBuilder - builder(lhs.combineDimensionsWith(rhs), lhs.my_cells()); - for (const auto &rhsCell : rhs.my_cells()) { - builder.insertCell(rhsCell.first, -rhsCell.second, func); - } - return builder.build(); -} - -} diff --git a/eval/src/vespa/eval/tensor/partial_update.cpp b/eval/src/vespa/eval/tensor/partial_update.cpp index 0f3ebe9537b..fba42988f92 100644 --- a/eval/src/vespa/eval/tensor/partial_update.cpp +++ b/eval/src/vespa/eval/tensor/partial_update.cpp @@ -7,7 +7,6 @@ #include <vespa/vespalib/util/visit_ranges.h> #include <cassert> #include <set> -#include "tensor.h" #include <vespa/log/log.h> LOG_SETUP(".eval.tensor.partial_update"); diff --git a/eval/src/vespa/eval/tensor/sparse/CMakeLists.txt b/eval/src/vespa/eval/tensor/sparse/CMakeLists.txt deleted file mode 100644 index 45baefe24c3..00000000000 --- a/eval/src/vespa/eval/tensor/sparse/CMakeLists.txt +++ /dev/null @@ -1,17 +0,0 @@ -# Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -vespa_add_library(eval_tensor_sparse OBJECT - SOURCES - direct_sparse_tensor_builder.cpp - sparse_tensor.cpp - sparse_tensor_t.cpp - sparse_tensor_add.cpp - sparse_tensor_address_builder.cpp - sparse_tensor_address_combiner.cpp - sparse_tensor_address_reducer.cpp - sparse_tensor_address_ref.cpp - sparse_tensor_index.cpp - sparse_tensor_match.cpp - sparse_tensor_modify.cpp - sparse_tensor_remove.cpp - sparse_tensor_value_builder.cpp -) diff --git a/eval/src/vespa/eval/tensor/sparse/direct_sparse_tensor_builder.cpp b/eval/src/vespa/eval/tensor/sparse/direct_sparse_tensor_builder.cpp deleted file mode 100644 index d6471f07191..00000000000 --- a/eval/src/vespa/eval/tensor/sparse/direct_sparse_tensor_builder.cpp +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#include "direct_sparse_tensor_builder.h" -#include "sparse_tensor_t.h" -#include <type_traits> - -namespace vespalib::tensor { - -template<typename T> -DirectSparseTensorBuilder<T>::DirectSparseTensorBuilder() - : _type(eval::ValueType::double_type()), - _index(0), - _values() -{ - assert((std::is_same_v<T,double>)); -} - -template<typename T> -DirectSparseTensorBuilder<T>::DirectSparseTensorBuilder(const eval::ValueType &type_in) - : _type(type_in), - _index(_type.count_mapped_dimensions()), - _values() -{ -} - -template<typename T> -DirectSparseTensorBuilder<T>::~DirectSparseTensorBuilder() = default; - -template<typename T> -std::unique_ptr<SparseTensorT<T>> -DirectSparseTensorBuilder<T>::build() { - using tt = SparseTensorT<T>; - return std::make_unique<tt>(std::move(_type), std::move(_index), std::move(_values)); -} - -template<typename T> -void -DirectSparseTensorBuilder<T>::reserve(uint32_t estimatedCells) { - _index.reserve(estimatedCells); - _values.reserve(estimatedCells); -} - -template class DirectSparseTensorBuilder<float>; -template class DirectSparseTensorBuilder<double>; - -} diff --git a/eval/src/vespa/eval/tensor/sparse/direct_sparse_tensor_builder.h b/eval/src/vespa/eval/tensor/sparse/direct_sparse_tensor_builder.h deleted file mode 100644 index 9570f744ae0..00000000000 --- a/eval/src/vespa/eval/tensor/sparse/direct_sparse_tensor_builder.h +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#pragma once - -#include <vespa/vespalib/util/hdr_abort.h> -#include "sparse_tensor.h" -#include "sparse_tensor_t.h" -#include "sparse_tensor_address_builder.h" - -namespace vespalib::tensor { - -/** - * Utility class to build tensors of type SparseTensor, to be used by - * tensor operations. - */ -template<typename T> -class DirectSparseTensorBuilder -{ -public: - using AddressBuilderType = SparseTensorAddressBuilder; - using AddressRefType = SparseTensorAddressRef; - -private: - eval::ValueType _type; - SparseTensorIndex _index; - std::vector<T> _values; - -public: - DirectSparseTensorBuilder(); - DirectSparseTensorBuilder(const eval::ValueType &type_in); - ~DirectSparseTensorBuilder(); - - std::unique_ptr<SparseTensorT<T>> build(); - - template <class Function> - void insertCell(SparseTensorAddressRef address, T value, Function &&func) - { - size_t idx; - if (_index.lookup_address(address, idx)) { - _values[idx] = func(_values[idx], value); - } else { - idx = _index.lookup_or_add(address); - assert(idx == _values.size()); - _values.push_back(value); - } - } - - void insertCell(SparseTensorAddressRef address, T value) { - // This address should not already exist and a new cell should be inserted. - _index.add_address(address); - _values.push_back(value); - } - - template <class Function> - void insertCell(SparseTensorAddressBuilder &address, T value, Function &&func) { - insertCell(address.getAddressRef(), value, func); - } - - void insertCell(SparseTensorAddressBuilder &address, T value) { - // This address should not already exist and a new cell should be inserted. - insertCell(address.getAddressRef(), value); - } - - eval::ValueType &fast_type() { return _type; } - - void reserve(uint32_t estimatedCells); -}; - -} diff --git a/eval/src/vespa/eval/tensor/sparse/sparse_tensor.cpp b/eval/src/vespa/eval/tensor/sparse/sparse_tensor.cpp deleted file mode 100644 index 5149b5bfb86..00000000000 --- a/eval/src/vespa/eval/tensor/sparse/sparse_tensor.cpp +++ /dev/null @@ -1,88 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#include "sparse_tensor.h" -#include "sparse_tensor_add.h" -#include "sparse_tensor_address_builder.h" -#include "sparse_tensor_join.hpp" -#include "sparse_tensor_match.h" -#include "direct_sparse_tensor_builder.h" -#include <vespa/eval/eval/value.h> -#include <vespa/eval/eval/value_codec.h> -#include <vespa/eval/eval/operation.h> -#include <vespa/eval/tensor/cell_values.h> -#include <vespa/eval/tensor/tensor_address_builder.h> -#include <vespa/eval/tensor/tensor_visitor.h> -#include <vespa/vespalib/stllike/hash_map.hpp> -#include <vespa/vespalib/stllike/hash_map_equal.hpp> -#include <vespa/vespalib/util/array_equal.hpp> - -#include <vespa/log/log.h> -LOG_SETUP(".eval.tensor.sparse.sparse_tensor"); - -using vespalib::eval::TensorSpec; - -namespace vespalib::tensor { - -SparseTensor::SparseTensor(eval::ValueType type_in, SparseTensorIndex index_in) - : _type(std::move(type_in)), - _index(std::move(index_in)) -{} - -SparseTensor::~SparseTensor() = default; - -struct CompareValues { - template <typename T> - static bool invoke(const SparseTensor &lhs_in, - const SparseTensor &rhs_in) - { - auto & lhs = static_cast<const SparseTensorT<T> &>(lhs_in); - auto & rhs = static_cast<const SparseTensorT<T> &>(rhs_in); - auto lhs_cells = lhs.cells().template typify<T>(); - auto rhs_cells = rhs.cells().template typify<T>(); - size_t rhs_idx; - for (const auto & kv : lhs.index().get_map()) { - if (rhs.index().lookup_address(kv.first, rhs_idx)) { - size_t lhs_idx = kv.second; - if (lhs_cells[lhs_idx] != rhs_cells[rhs_idx]) { - return false; - } - } else { - return false; - } - } - return true; - } -}; - -bool -SparseTensor::operator==(const SparseTensor &rhs) const -{ - if (fast_type() == rhs.fast_type() && my_size() == rhs.my_size()) { - return typify_invoke<1,eval::TypifyCellType,CompareValues>(_type.cell_type(), *this, rhs); - } - return false; -} - -eval::ValueType -SparseTensor::combineDimensionsWith(const SparseTensor &rhs) const -{ - return eval::ValueType::join(_type, rhs._type); -} - -const eval::ValueType & -SparseTensor::type() const -{ - return _type; -} - -TensorSpec -SparseTensor::toSpec() const -{ - return vespalib::eval::spec_from_value(*this); -} - - - -} - -VESPALIB_HASH_MAP_INSTANTIATE(vespalib::tensor::SparseTensorAddressRef, double); diff --git a/eval/src/vespa/eval/tensor/sparse/sparse_tensor.h b/eval/src/vespa/eval/tensor/sparse/sparse_tensor.h deleted file mode 100644 index 5fdd466d15f..00000000000 --- a/eval/src/vespa/eval/tensor/sparse/sparse_tensor.h +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#pragma once - -#include "sparse_tensor_index.h" -#include <vespa/eval/tensor/cell_function.h> -#include <vespa/eval/tensor/tensor.h> -#include <vespa/eval/tensor/tensor_address.h> -#include <vespa/eval/tensor/types.h> -#include <vespa/vespalib/stllike/string.h> - -namespace vespalib::tensor { - -/** - * A tensor implementation using serialized tensor addresses to - * improve CPU cache and TLB hit ratio, relative to SimpleTensor - * implementation. - */ -class SparseTensor : public Tensor -{ -private: - eval::ValueType _type; - SparseTensorIndex _index; - -public: - SparseTensor(eval::ValueType type_in, SparseTensorIndex index_in); - ~SparseTensor() override; - size_t my_size() const { return _index.get_map().size(); } - const SparseTensorIndex &index() const final override { return _index; } - const eval::ValueType &fast_type() const { return _type; } - bool operator==(const SparseTensor &rhs) const; - eval::ValueType combineDimensionsWith(const SparseTensor &rhs) const; - - const eval::ValueType &type() const override; - eval::TensorSpec toSpec() const override; -}; - -} diff --git a/eval/src/vespa/eval/tensor/sparse/sparse_tensor_add.cpp b/eval/src/vespa/eval/tensor/sparse/sparse_tensor_add.cpp deleted file mode 100644 index bb44826db9c..00000000000 --- a/eval/src/vespa/eval/tensor/sparse/sparse_tensor_add.cpp +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#include "sparse_tensor_add.h" -#include "sparse_tensor_t.h" - -namespace vespalib::tensor { - -template<typename T> -SparseTensorAdd<T>::SparseTensorAdd(eval::ValueType type, SparseTensorIndex index, std::vector<T> values) - : _type(std::move(type)), - _index(std::move(index)), - _values(std::move(values)), - _addressBuilder() -{ -} - -template<typename T> -SparseTensorAdd<T>::~SparseTensorAdd() = default; - -template<typename T> -void -SparseTensorAdd<T>::visit(const TensorAddress &address, double value) -{ - _addressBuilder.populate(_type, address); - auto addressRef = _addressBuilder.getAddressRef(); - size_t idx = _index.lookup_or_add(addressRef); - if (idx < _values.size()) { - _values[idx] = value; - } else { - assert(idx == _values.size()); - _values.push_back(value); - } -} - -template<typename T> -std::unique_ptr<Tensor> -SparseTensorAdd<T>::build() -{ - using tt = SparseTensorT<T>; - return std::make_unique<tt>(std::move(_type), std::move(_index), std::move(_values)); -} - -template class SparseTensorAdd<float>; -template class SparseTensorAdd<double>; - -} diff --git a/eval/src/vespa/eval/tensor/sparse/sparse_tensor_add.h b/eval/src/vespa/eval/tensor/sparse/sparse_tensor_add.h deleted file mode 100644 index 7baea13440a..00000000000 --- a/eval/src/vespa/eval/tensor/sparse/sparse_tensor_add.h +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#pragma once - -#include "sparse_tensor.h" -#include "sparse_tensor_address_builder.h" -#include <vespa/eval/tensor/tensor_visitor.h> - -namespace vespalib::tensor { - -/** - * This class handles a tensor add operation on a sparse tensor. - * - * Creates a new tensor by adding the cells of the argument tensor to this tensor. - * Existing cell values are overwritten. - */ -template<typename T> -class SparseTensorAdd : public TensorVisitor -{ - eval::ValueType _type; - SparseTensorIndex _index; - std::vector<T> _values; - SparseTensorAddressBuilder _addressBuilder; -public: - SparseTensorAdd(eval::ValueType type, SparseTensorIndex index, std::vector<T> values); - ~SparseTensorAdd(); - void visit(const TensorAddress &address, double value) override; - std::unique_ptr<Tensor> build(); -}; - -} diff --git a/eval/src/vespa/eval/tensor/sparse/sparse_tensor_address_builder.cpp b/eval/src/vespa/eval/tensor/sparse/sparse_tensor_address_builder.cpp deleted file mode 100644 index 3eb7d64f060..00000000000 --- a/eval/src/vespa/eval/tensor/sparse/sparse_tensor_address_builder.cpp +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#include "sparse_tensor_address_builder.h" -#include <vespa/eval/eval/value_type.h> -#include <vespa/eval/tensor/tensor_address.h> -#include <vespa/eval/tensor/tensor_address_element_iterator.h> - -namespace vespalib::tensor { - -SparseTensorAddressBuilder::SparseTensorAddressBuilder() - : _address() -{ -} - -void -SparseTensorAddressBuilder::populate(const eval::ValueType &type, const TensorAddress &address) -{ - clear(); - TensorAddressElementIterator itr(address); - for (const auto &dimension : type.dimensions()) { - if (itr.skipToDimension(dimension.name)) { - add(itr.label()); - } else { - addUndefined(); - } - } -} - -} diff --git a/eval/src/vespa/eval/tensor/sparse/sparse_tensor_address_builder.h b/eval/src/vespa/eval/tensor/sparse/sparse_tensor_address_builder.h deleted file mode 100644 index 32b9b57fb26..00000000000 --- a/eval/src/vespa/eval/tensor/sparse/sparse_tensor_address_builder.h +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#pragma once - -#include "sparse_tensor_address_ref.h" -#include <vespa/vespalib/stllike/string.h> - -namespace vespalib::eval { class ValueType; } - -namespace vespalib::tensor { - -class TensorAddress; - - -/** - * A writer to serialize tensor addresses into a compact representation. - * All dimensions in the tensors are present, empty label is the "undefined" - * value. - * - * Format: (labelStr NUL)* - */ -class SparseTensorAddressBuilder -{ -private: - vespalib::Array<char> _address; - -protected: - void append(vespalib::stringref str) { - for (size_t i(0); i < str.size(); i++) { - _address.push_back_fast(str[i]); - } - _address.push_back_fast('\0'); - } - void ensure_room(size_t additional) { - if (_address.capacity() < (_address.size() + additional)) { - _address.reserve(_address.size() + additional); - } - } -public: - SparseTensorAddressBuilder(); - void add(vespalib::stringref label) { - ensure_room(label.size()+1); - append(label); - } - void addUndefined() { _address.push_back('\0'); } - void clear() { _address.clear(); } - void set(std::initializer_list<vespalib::stringref> labels) { - clear(); - for (const auto &label: labels) { - add(label); - } - } - SparseTensorAddressRef getAddressRef() const { - return SparseTensorAddressRef(&_address[0], _address.size()); - } - bool empty() const { return _address.empty(); } - void populate(const eval::ValueType &type, const TensorAddress &address); -}; - -} diff --git a/eval/src/vespa/eval/tensor/sparse/sparse_tensor_address_combiner.cpp b/eval/src/vespa/eval/tensor/sparse/sparse_tensor_address_combiner.cpp deleted file mode 100644 index 95b004a9bd2..00000000000 --- a/eval/src/vespa/eval/tensor/sparse/sparse_tensor_address_combiner.cpp +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#include "sparse_tensor_address_combiner.h" -#include "sparse_tensor_address_decoder.h" -#include <vespa/eval/eval/value_type.h> -#include <vespa/vespalib/util/overload.h> -#include <vespa/vespalib/util/visit_ranges.h> - -namespace vespalib::tensor::sparse { - -TensorAddressCombiner::TensorAddressCombiner(const eval::ValueType &lhs, const eval::ValueType &rhs) -{ - auto visitor = overload{ - [this](visit_ranges_first, const auto &) { _ops.push_back(AddressOp::LHS); }, - [this](visit_ranges_second, const auto &) { _ops.push_back(AddressOp::RHS); }, - [this](visit_ranges_both, const auto &, const auto &) { _ops.push_back(AddressOp::BOTH); } - }; - visit_ranges(visitor, - lhs.dimensions().cbegin(), lhs.dimensions().cend(), - rhs.dimensions().cbegin(), rhs.dimensions().cend(), - [](const auto & li, const auto & ri) { return li.name < ri.name; }); -} - -TensorAddressCombiner::~TensorAddressCombiner() = default; - -size_t -TensorAddressCombiner::numOverlappingDimensions() const { - size_t count = 0; - for (AddressOp op : _ops) { - if (op == AddressOp::BOTH) { - count++; - } - } - return count; -} - -bool -TensorAddressCombiner::combine(SparseTensorAddressRef lhsRef, - SparseTensorAddressRef rhsRef) -{ - clear(); - ensure_room(lhsRef.size() + rhsRef.size()); - SparseTensorAddressDecoder lhs(lhsRef); - SparseTensorAddressDecoder rhs(rhsRef); - for (auto op : _ops) { - switch (op) { - case AddressOp::LHS: - append(lhs.decodeLabel()); - break; - case AddressOp::RHS: - append(rhs.decodeLabel()); - break; - case AddressOp::BOTH: - auto lhsLabel(lhs.decodeLabel()); - auto rhsLabel(rhs.decodeLabel()); - if (lhsLabel != rhsLabel) { - return false; - } - append(lhsLabel); - } - } - return true; -} - -} diff --git a/eval/src/vespa/eval/tensor/sparse/sparse_tensor_address_combiner.h b/eval/src/vespa/eval/tensor/sparse/sparse_tensor_address_combiner.h deleted file mode 100644 index 1a7f2fd8d3c..00000000000 --- a/eval/src/vespa/eval/tensor/sparse/sparse_tensor_address_combiner.h +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#pragma once - -#include "sparse_tensor_address_builder.h" - -#define VESPA_DLL_LOCAL __attribute__ ((visibility("hidden"))) - -namespace vespalib::eval { class ValueType; } -namespace vespalib::tensor::sparse { - -/** - * Combine two tensor addresses to a new tensor address. Common dimensions - * must have matching labels. - */ -class TensorAddressCombiner : public SparseTensorAddressBuilder -{ - enum class AddressOp { LHS, RHS, BOTH }; - - std::vector<AddressOp> _ops; -public: - TensorAddressCombiner(const eval::ValueType &lhs, const eval::ValueType &rhs); - ~TensorAddressCombiner(); - - VESPA_DLL_LOCAL bool combine(SparseTensorAddressRef lhsRef, SparseTensorAddressRef rhsRef); - size_t numOverlappingDimensions() const; - size_t numDimensions() const { return _ops.size(); } -}; - -} - diff --git a/eval/src/vespa/eval/tensor/sparse/sparse_tensor_address_decoder.h b/eval/src/vespa/eval/tensor/sparse/sparse_tensor_address_decoder.h deleted file mode 100644 index 2fbd9932009..00000000000 --- a/eval/src/vespa/eval/tensor/sparse/sparse_tensor_address_decoder.h +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#pragma once - -#include <vespa/vespalib/stllike/string.h> -#include "sparse_tensor_address_ref.h" - -namespace vespalib::tensor { - -/** - * A decoder for a serialized tensor address, with only labels present. - */ -class SparseTensorAddressDecoder -{ - const char *_cur; - const char *_end; -public: - SparseTensorAddressDecoder(SparseTensorAddressRef ref) - : _cur(static_cast<const char *>(ref.start())), - _end(_cur + ref.size()) - { - } - - bool valid() const { return _cur != _end; } - - void skipLabel() { - while (*_cur != '\0') { - ++_cur; - } - ++_cur; - } - vespalib::stringref decodeLabel() { - const char *base = _cur; - skipLabel(); - return vespalib::stringref(base, _cur - base - 1); - } - -}; - -} - diff --git a/eval/src/vespa/eval/tensor/sparse/sparse_tensor_address_reducer.cpp b/eval/src/vespa/eval/tensor/sparse/sparse_tensor_address_reducer.cpp deleted file mode 100644 index fbd0034bc14..00000000000 --- a/eval/src/vespa/eval/tensor/sparse/sparse_tensor_address_reducer.cpp +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#include "sparse_tensor_address_reducer.h" -#include <vespa/eval/eval/value_type.h> -#include <vespa/vespalib/stllike/hash_set.hpp> - -namespace vespalib::tensor::sparse { - -TensorAddressReducer::TensorAddressReducer(const eval::ValueType &type, - const std::vector<vespalib::string> & removeDimensions) - : SparseTensorAddressBuilder(), - _ops() -{ - TensorDimensionsSet removeSet(removeDimensions.cbegin(), removeDimensions.cend()); - _ops.reserve(type.dimensions().size()); - for (const auto &dim : type.dimensions()) { - if (removeSet.find(dim.name) != removeSet.end()) { - _ops.push_back(AddressOp::REMOVE); - } else { - _ops.push_back(AddressOp::COPY); - } - } -} - -TensorAddressReducer::~TensorAddressReducer() = default; - -} - diff --git a/eval/src/vespa/eval/tensor/sparse/sparse_tensor_address_reducer.h b/eval/src/vespa/eval/tensor/sparse/sparse_tensor_address_reducer.h deleted file mode 100644 index a2034d3be49..00000000000 --- a/eval/src/vespa/eval/tensor/sparse/sparse_tensor_address_reducer.h +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#pragma once - -#include "sparse_tensor_address_builder.h" -#include <vespa/eval/tensor/types.h> -#include "sparse_tensor_address_decoder.h" -#include <cassert> - -namespace vespalib::eval { class ValueType; } -namespace vespalib::tensor::sparse { - -/** - * Reduce sparse tensor address by removing one or more dimensions. - */ -class TensorAddressReducer : public SparseTensorAddressBuilder -{ - enum AddressOp { REMOVE, COPY }; - - using AddressOps = std::vector<AddressOp>; - - AddressOps _ops; - -public: - TensorAddressReducer(const eval::ValueType &type, - const std::vector<vespalib::string> &removeDimensions); - - ~TensorAddressReducer(); - - void reduce(SparseTensorAddressRef ref) - { - clear(); - SparseTensorAddressDecoder decoder(ref); - for (auto op : _ops) { - switch (op) { - case AddressOp::REMOVE: - decoder.skipLabel(); - break; - case AddressOp::COPY: - add(decoder.decodeLabel()); - } - } - assert(!decoder.valid()); - } -}; - -} - diff --git a/eval/src/vespa/eval/tensor/sparse/sparse_tensor_address_ref.cpp b/eval/src/vespa/eval/tensor/sparse/sparse_tensor_address_ref.cpp deleted file mode 100644 index e2929269ce6..00000000000 --- a/eval/src/vespa/eval/tensor/sparse/sparse_tensor_address_ref.cpp +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright 2019 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#include "sparse_tensor_address_ref.h" -#include <xxhash.h> - -namespace vespalib::tensor { - -uint32_t -SparseTensorAddressRef::calcHash() const noexcept { - return XXH32(_start, _size, 0); -} - -} - diff --git a/eval/src/vespa/eval/tensor/sparse/sparse_tensor_address_ref.h b/eval/src/vespa/eval/tensor/sparse/sparse_tensor_address_ref.h deleted file mode 100644 index e8838b1acdb..00000000000 --- a/eval/src/vespa/eval/tensor/sparse/sparse_tensor_address_ref.h +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#pragma once - -#include <vespa/vespalib/util/stash.h> -#include <cstring> - -namespace vespalib::tensor { - -/** - * A reference to a compact sparse immutable address to a tensor cell. - */ -class SparseTensorAddressRef -{ - const void *_start; - uint32_t _size; - uint32_t _hash; - static void * copy(const SparseTensorAddressRef rhs, Stash &stash) { - void *res = stash.alloc(rhs._size); - memcpy(res, rhs._start, rhs._size); - return res; - } -public: - SparseTensorAddressRef() noexcept - : _start(nullptr), _size(0u), _hash(0u) - { - } - - SparseTensorAddressRef(const void *start_in, uint32_t size_in) noexcept - : _start(start_in), _size(size_in), - _hash(calcHash()) - { - } - - SparseTensorAddressRef(const SparseTensorAddressRef rhs, Stash &stash) - : _start(copy(rhs, stash)), - _size(rhs._size), - _hash(rhs._hash) - {} - - uint32_t hash() const noexcept { return _hash; } - - uint32_t calcHash() const noexcept; - - bool operator<(const SparseTensorAddressRef &rhs) const noexcept { - size_t minSize = std::min(_size, rhs._size); - int res = memcmp(_start, rhs._start, minSize); - if (res != 0) { - return res < 0; - } - return _size < rhs._size; - } - - bool operator==(const SparseTensorAddressRef &rhs) const noexcept - { - if (_size != rhs._size || _hash != rhs._hash) { - return false; - } - return memcmp(_start, rhs._start, _size) == 0; - } - - const void *start() const { return _start; } - uint32_t size() const { return _size; } -}; - -} - diff --git a/eval/src/vespa/eval/tensor/sparse/sparse_tensor_index.cpp b/eval/src/vespa/eval/tensor/sparse/sparse_tensor_index.cpp deleted file mode 100644 index 4d03a9673dd..00000000000 --- a/eval/src/vespa/eval/tensor/sparse/sparse_tensor_index.cpp +++ /dev/null @@ -1,294 +0,0 @@ -// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#include "sparse_tensor_index.h" -#include "sparse_tensor_address_builder.h" -#include "sparse_tensor_address_decoder.h" -#include <vespa/vespalib/stllike/hash_map.hpp> -#include <vespa/vespalib/stllike/hash_map_equal.hpp> - -namespace vespalib::tensor { - -using IndexMap = SparseTensorIndex::IndexMap; -using View = vespalib::eval::Value::Index::View; - -namespace { - -void copyMap(IndexMap &map, const IndexMap &map_in, Stash &to_stash) { - // copy the exact hashtable structure: - map = map_in; - // copy the actual contents of the addresses, - // and update the pointers inside the hashtable - // keys so they point to our copy: - for (auto & kv : map) { - SparseTensorAddressRef oldRef = kv.first; - SparseTensorAddressRef newRef(oldRef, to_stash); - kv.first = newRef; - } -} - -//----------------------------------------------------------------------------- - -class SparseTensorValueView : public View -{ -private: - const IndexMap ↦ - IndexMap::const_iterator iter; - const std::vector<size_t> lookup_dims; - std::vector<vespalib::stringref> lookup_refs; -public: - SparseTensorValueView(const IndexMap & map_in, - const std::vector<size_t> &dims) - : map(map_in), iter(map.end()), lookup_dims(dims), lookup_refs() {} - ~SparseTensorValueView(); - void lookup(ConstArrayRef<const vespalib::stringref*> addr) override; - bool next_result(ConstArrayRef<vespalib::stringref*> addr_out, size_t &idx_out) override; -}; - -SparseTensorValueView::~SparseTensorValueView() = default; - -void -SparseTensorValueView::lookup(ConstArrayRef<const vespalib::stringref*> addr) -{ - lookup_refs.clear(); - for (auto ptr : addr) { - lookup_refs.push_back(*ptr); - } - iter = map.begin(); - -} - -bool -SparseTensorValueView::next_result(ConstArrayRef<vespalib::stringref*> addr_out, size_t &idx_out) -{ - size_t total_dims = lookup_refs.size() + addr_out.size(); - while (iter != map.end()) { - const auto & ref = iter->first; - SparseTensorAddressDecoder decoder(ref); - idx_out = iter->second; - ++iter; - bool couldmatch = true; - size_t vd_idx = 0; - size_t ao_idx = 0; - for (size_t i = 0; i < total_dims; ++i) { - const auto label = decoder.decodeLabel(); - if (vd_idx < lookup_dims.size()) { - size_t next_view_dim = lookup_dims[vd_idx]; - if (i == next_view_dim) { - if (label == lookup_refs[vd_idx]) { - // match in this dimension - ++vd_idx; - continue; - } else { - // does not match - couldmatch = false; - break; - } - } - } - // not a view dimension: - *addr_out[ao_idx] = label; - ++ao_idx; - } - if (couldmatch) { - assert(vd_idx == lookup_dims.size()); - assert(ao_idx == addr_out.size()); - return true; - } - } - return false; -} - -//----------------------------------------------------------------------------- - -class SparseTensorValueLookup : public View -{ -private: - const IndexMap ↦ - IndexMap::const_iterator iter; -public: - SparseTensorValueLookup(const IndexMap & map_in) : map(map_in), iter(map.end()) {} - ~SparseTensorValueLookup(); - void lookup(ConstArrayRef<const vespalib::stringref*> addr) override; - bool next_result(ConstArrayRef<vespalib::stringref*> addr_out, size_t &idx_out) override; -}; - -SparseTensorValueLookup::~SparseTensorValueLookup() = default; - -void -SparseTensorValueLookup::lookup(ConstArrayRef<const vespalib::stringref*> addr) -{ - SparseTensorAddressBuilder builder; - for (const auto & label : addr) { - builder.add(*label); - } - auto ref = builder.getAddressRef(); - iter = map.find(ref); -} - -bool -SparseTensorValueLookup::next_result(ConstArrayRef<vespalib::stringref*>, size_t &idx_out) -{ - if (iter != map.end()) { - idx_out = iter->second; - iter = map.end(); - return true; - } - return false; -} - -//----------------------------------------------------------------------------- - -class SparseTensorValueAllMappings : public View -{ -private: - const IndexMap ↦ - IndexMap::const_iterator iter; -public: - SparseTensorValueAllMappings(const IndexMap & map_in) : map(map_in), iter(map.end()) {} - ~SparseTensorValueAllMappings(); - void lookup(ConstArrayRef<const vespalib::stringref*> addr) override; - bool next_result(ConstArrayRef<vespalib::stringref*> addr_out, size_t &idx_out) override; -}; - -SparseTensorValueAllMappings::~SparseTensorValueAllMappings() = default; - -void -SparseTensorValueAllMappings::lookup(ConstArrayRef<const vespalib::stringref*>) -{ - iter = map.begin(); -} - -bool -SparseTensorValueAllMappings::next_result(ConstArrayRef<vespalib::stringref*> addr_out, size_t &idx_out) -{ - if (iter != map.end()) { - const auto & ref = iter->first; - idx_out = iter->second; - ++iter; - SparseTensorAddressDecoder decoder(ref); - for (const auto ptr : addr_out) { - const auto label = decoder.decodeLabel(); - *ptr = label; - } - return true; - } - return false; -} - -} // namespace <unnamed> - -//----------------------------------------------------------------------------- - -size_t -SparseTensorIndex::wanted_chunk_size_for(const SparseTensorIndex &other) { - auto mem = other._stash.get_memory_usage(); - size_t mem_use = mem.usedBytes(); - if (mem_use == 0) { - return STASH_CHUNK_SIZE; - } - if (mem_use < (STASH_CHUNK_SIZE / 4)) { - size_t avg_per_addr = mem_use / other.size(); - mem_use = std::max(mem_use, (7 * avg_per_addr)); - size_t aligned_size = (mem_use + 63) & ~(sizeof(char *) - 1); - return aligned_size; - } - return STASH_CHUNK_SIZE; -} - -SparseTensorIndex::SparseTensorIndex(size_t num_mapped_in) - : _stash(STASH_CHUNK_SIZE), _map(), _num_mapped_dims(num_mapped_in) -{} - -SparseTensorIndex::SparseTensorIndex(size_t stash_size, const SparseTensorIndex &index_in) - : _stash(stash_size), _map(), _num_mapped_dims(index_in._num_mapped_dims) -{ - copyMap(_map, index_in._map, _stash); -} - -SparseTensorIndex -SparseTensorIndex::shrunk_copy() const -{ - size_t want_mem = wanted_chunk_size_for(*this); - return SparseTensorIndex(want_mem, *this); -} - -SparseTensorIndex -SparseTensorIndex::copy() const -{ - size_t want_mem = _stash.get_chunk_size(); - return SparseTensorIndex(want_mem, *this); -} - -void -SparseTensorIndex::reserve(size_t estimate) { - _map.resize(2*estimate); -} - -SparseTensorIndex::~SparseTensorIndex() = default; - -size_t SparseTensorIndex::size() const { - return _map.size(); -} - -std::unique_ptr<View> -SparseTensorIndex::create_view(const std::vector<size_t> &dims) const -{ - if (dims.size() == _num_mapped_dims) { - return std::make_unique<SparseTensorValueLookup>(_map); - } - if (dims.size() == 0) { - return std::make_unique<SparseTensorValueAllMappings>(_map); - } - return std::make_unique<SparseTensorValueView>(_map, dims); -} - -void -SparseTensorIndex::add_address(SparseTensorAddressRef tmp_ref) -{ - SparseTensorAddressRef ref(tmp_ref, _stash); - size_t idx = _map.size(); - auto insert_result = _map.insert({ref, idx}); - assert(insert_result.second); -} - -size_t -SparseTensorIndex::lookup_or_add(SparseTensorAddressRef tmp_ref) -{ - auto [map_iter, was_inserted] = _map.insert({tmp_ref, _map.size()}); - if (was_inserted) { - // we must copy the memory tmp_ref refers to into our own stash: - SparseTensorAddressRef ref(tmp_ref, _stash); - // and update the key in the map, just like copyMap() does. - map_iter->first = ref; - } - return map_iter->second; -} - -bool -SparseTensorIndex::lookup_address(SparseTensorAddressRef ref, size_t &idx) const -{ - auto iter = _map.find(ref); - if (iter != _map.end()) { - idx = iter->second; - return true; - } - idx = size_t(-1); - return false; -} - -MemoryUsage -SparseTensorIndex::get_memory_usage() const -{ - MemoryUsage mem = _stash.get_memory_usage(); - size_t plus = _map.getMemoryConsumption(); - mem.incUsedBytes(plus); - mem.incAllocatedBytes(plus); - return mem; -} - - -//----------------------------------------------------------------------------- - -} // namespace - -VESPALIB_HASH_MAP_INSTANTIATE(vespalib::tensor::SparseTensorAddressRef, uint32_t); diff --git a/eval/src/vespa/eval/tensor/sparse/sparse_tensor_index.h b/eval/src/vespa/eval/tensor/sparse/sparse_tensor_index.h deleted file mode 100644 index 089759452b5..00000000000 --- a/eval/src/vespa/eval/tensor/sparse/sparse_tensor_index.h +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#pragma once - -#include "sparse_tensor_address_ref.h" -#include <vespa/eval/eval/value.h> -#include <vespa/vespalib/stllike/hash_map.h> -#include <vespa/vespalib/util/stash.h> - -namespace vespalib::tensor { - -class SparseTensorIndex : public vespalib::eval::Value::Index -{ -public: - static constexpr size_t STASH_CHUNK_SIZE = 16384u; - // - using View = vespalib::eval::Value::Index::View; - using IndexMap = hash_map<SparseTensorAddressRef, uint32_t, hash<SparseTensorAddressRef>, - std::equal_to<>, hashtable_base::and_modulator>; - // construct - explicit SparseTensorIndex(size_t num_mapped_dims_in); - SparseTensorIndex copy() const; - SparseTensorIndex shrunk_copy() const; - SparseTensorIndex(const SparseTensorIndex &) = delete; - SparseTensorIndex(SparseTensorIndex && index_in) = default; - ~SparseTensorIndex(); - // Index API - size_t size() const override; - std::unique_ptr<View> create_view(const std::vector<size_t> &dims) const override; - // build API - void reserve(size_t estimate); - void add_address(SparseTensorAddressRef tmp_ref); - size_t lookup_or_add(SparseTensorAddressRef tmp_ref); - // lookup API - bool lookup_address(SparseTensorAddressRef ref, size_t &idx) const; - // traversal API - const IndexMap &get_map() const { return _map; } - // stats - MemoryUsage get_memory_usage() const; -private: - Stash _stash; - IndexMap _map; - size_t _num_mapped_dims; - static size_t wanted_chunk_size_for(const SparseTensorIndex &other); - SparseTensorIndex(size_t stash_size, const SparseTensorIndex &other); -}; - -} // namespace diff --git a/eval/src/vespa/eval/tensor/sparse/sparse_tensor_join.h b/eval/src/vespa/eval/tensor/sparse/sparse_tensor_join.h deleted file mode 100644 index 07695b66ccb..00000000000 --- a/eval/src/vespa/eval/tensor/sparse/sparse_tensor_join.h +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#pragma once - -namespace vespalib::tensor { - class Tensor; - class SparseTensor; -} - -namespace vespalib::tensor::sparse { - -/** - * Create new tensor using all combinations of input tensor cells with matching - * labels for common dimensions, using func to calculate new cell value - * based on the cell values in the input tensors. - */ -template <typename LCT, typename RCT, typename OCT, typename Function> -std::unique_ptr<Tensor> -join(const SparseTensor &lhs, const SparseTensor &rhs, eval::ValueType res_type, Function &&func); - -} - diff --git a/eval/src/vespa/eval/tensor/sparse/sparse_tensor_join.hpp b/eval/src/vespa/eval/tensor/sparse/sparse_tensor_join.hpp deleted file mode 100644 index ae54e42f5c2..00000000000 --- a/eval/src/vespa/eval/tensor/sparse/sparse_tensor_join.hpp +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#pragma once - -#include "sparse_tensor_join.h" -#include "sparse_tensor_t.h" -#include "sparse_tensor_address_combiner.h" -#include "direct_sparse_tensor_builder.h" - -namespace vespalib::tensor::sparse { - -template <typename LCT, typename RCT, typename OCT, typename Function> -std::unique_ptr<Tensor> -join(const SparseTensor &lhs_in, const SparseTensor &rhs_in, eval::ValueType res_type, Function &&func) -{ - auto & lhs = static_cast<const SparseTensorT<LCT> &>(lhs_in); - auto & rhs = static_cast<const SparseTensorT<RCT> &>(rhs_in); - DirectSparseTensorBuilder<OCT> builder(std::move(res_type)); - TensorAddressCombiner addressCombiner(lhs.fast_type(), rhs.fast_type()); - if (addressCombiner.numOverlappingDimensions() != 0) { - size_t estimatedCells = std::min(lhs.my_size(), rhs.my_size()); - builder.reserve(estimatedCells*2); - } else { - size_t estimatedCells = (lhs.my_size() * rhs.my_size()); - builder.reserve(estimatedCells); - } - for (const auto & lhs_kv : lhs.index().get_map()) { - for (const auto & rhs_kv : rhs.index().get_map()) { - bool combineSuccess = addressCombiner.combine(lhs_kv.first, rhs_kv.first); - if (combineSuccess) { - auto a = lhs.get_value(lhs_kv.second); - auto b = rhs.get_value(rhs_kv.second); - builder.insertCell(addressCombiner.getAddressRef(), func(a, b)); - } - } - } - return builder.build(); -} - -} diff --git a/eval/src/vespa/eval/tensor/sparse/sparse_tensor_match.cpp b/eval/src/vespa/eval/tensor/sparse/sparse_tensor_match.cpp deleted file mode 100644 index 74aa557d92b..00000000000 --- a/eval/src/vespa/eval/tensor/sparse/sparse_tensor_match.cpp +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#include "sparse_tensor_match.h" -#include "sparse_tensor_address_decoder.h" -#include <vespa/vespalib/stllike/hash_map.hpp> -#include <vespa/vespalib/util/overload.h> -#include <vespa/vespalib/util/visit_ranges.h> -#include <assert.h> - -namespace vespalib::tensor { - -template<typename LCT, typename RCT> -void -SparseTensorMatch<LCT,RCT>::fastMatch(const SparseTensorT<LCT> &lhs, const SparseTensorT<RCT> &rhs) -{ - const auto & lhs_map = lhs.index().get_map(); - const auto & rhs_map = rhs.index().get_map(); - _builder.reserve(lhs_map.size()); - const auto rhs_map_end = rhs_map.end(); - for (const auto & kv : lhs_map) { - auto rhsItr = rhs_map.find(kv.first); - if (rhsItr != rhs_map_end) { - LCT a = lhs.get_value(kv.second); - RCT b = rhs.get_value(rhsItr->second); - _builder.insertCell(kv.first, a * b); - } - } -} - -template<typename LCT, typename RCT> -SparseTensorMatch<LCT,RCT>::SparseTensorMatch(const SparseTensorT<LCT> &lhs, - const SparseTensorT<RCT> &rhs, - eval::ValueType res_type) - : _builder(std::move(res_type)) -{ - fastMatch(lhs, rhs); -} - -template class SparseTensorMatch<float,float>; -template class SparseTensorMatch<float,double>; -template class SparseTensorMatch<double,float>; -template class SparseTensorMatch<double,double>; - -} diff --git a/eval/src/vespa/eval/tensor/sparse/sparse_tensor_match.h b/eval/src/vespa/eval/tensor/sparse/sparse_tensor_match.h deleted file mode 100644 index 21223112329..00000000000 --- a/eval/src/vespa/eval/tensor/sparse/sparse_tensor_match.h +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#pragma once - -#include "sparse_tensor.h" -#include "sparse_tensor_t.h" -#include "direct_sparse_tensor_builder.h" - -namespace vespalib::tensor { - -/** - * Returns the match product of two tensors. - * This returns a tensor which contains the matching cells in the two tensors, - * with their values multiplied. - * - * Only used when two tensors have exactly the same dimensions, - * this is the Hadamard product. - */ -template<typename LCT, typename RCT> -class SparseTensorMatch -{ -public: - using OCT = typename eval::UnifyCellTypes<LCT,RCT>::type; - DirectSparseTensorBuilder<OCT> _builder; -private: - void fastMatch(const SparseTensorT<LCT> &lhs, const SparseTensorT<RCT> &rhs); -public: - SparseTensorMatch(const SparseTensorT<LCT> &lhs, const SparseTensorT<RCT> &rhs, eval::ValueType res_type); - Tensor::UP result() { - return _builder.build(); - } -}; - -} diff --git a/eval/src/vespa/eval/tensor/sparse/sparse_tensor_modify.cpp b/eval/src/vespa/eval/tensor/sparse/sparse_tensor_modify.cpp deleted file mode 100644 index f36e1c71c16..00000000000 --- a/eval/src/vespa/eval/tensor/sparse/sparse_tensor_modify.cpp +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#include "sparse_tensor_modify.h" -#include "sparse_tensor_t.h" -#include <vespa/eval/tensor/tensor_address_element_iterator.h> - -namespace vespalib::tensor { - -template<typename T> -SparseTensorModify<T>::SparseTensorModify(join_fun_t op, const SparseTensorT<T> &input) - : _op(op), - _type(input.fast_type()), - _index(input.index()), - _values(input.my_values()), - _addressBuilder() -{ -} - -template<typename T> -SparseTensorModify<T>::~SparseTensorModify() = default; - -template<typename T> -void -SparseTensorModify<T>::visit(const TensorAddress &address, double value) -{ - _addressBuilder.populate(_type, address); - auto addressRef = _addressBuilder.getAddressRef(); - size_t idx; - if (_index.lookup_address(addressRef, idx)) { - _values[idx] = _op(_values[idx], value); - } -} - -template<typename T> -std::unique_ptr<Tensor> -SparseTensorModify<T>::build() -{ - using tt = SparseTensorT<T>; - return std::make_unique<tt>(std::move(_type), _index.copy(), std::move(_values)); -} - -template class SparseTensorModify<float>; -template class SparseTensorModify<double>; - -} diff --git a/eval/src/vespa/eval/tensor/sparse/sparse_tensor_modify.h b/eval/src/vespa/eval/tensor/sparse/sparse_tensor_modify.h deleted file mode 100644 index 86f0c0a5c48..00000000000 --- a/eval/src/vespa/eval/tensor/sparse/sparse_tensor_modify.h +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#pragma once - -#include <vespa/eval/eval/operation.h> -#include <vespa/eval/tensor/tensor_visitor.h> -#include "sparse_tensor.h" -#include "sparse_tensor_t.h" -#include "sparse_tensor_address_builder.h" - -namespace vespalib::tensor { - -/* - * This class handles tensor modify update on a sparse tensor. - * For all cells visited, a join function is applied to determine - * the new cell value. - */ -template<typename T> -class SparseTensorModify : public TensorVisitor -{ - using join_fun_t = vespalib::eval::operation::op2_t; - join_fun_t _op; - eval::ValueType _type; - const SparseTensorIndex & _index; - std::vector<T> _values; - SparseTensorAddressBuilder _addressBuilder; - -public: - SparseTensorModify(join_fun_t op, const SparseTensorT<T> & input); - ~SparseTensorModify(); - void visit(const TensorAddress &address, double value) override; - std::unique_ptr<Tensor> build(); -}; - -} diff --git a/eval/src/vespa/eval/tensor/sparse/sparse_tensor_reduce.hpp b/eval/src/vespa/eval/tensor/sparse/sparse_tensor_reduce.hpp deleted file mode 100644 index 1ee13a2d8e1..00000000000 --- a/eval/src/vespa/eval/tensor/sparse/sparse_tensor_reduce.hpp +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#pragma once - -#include "sparse_tensor_address_reducer.h" -#include "direct_sparse_tensor_builder.h" - -namespace vespalib::tensor::sparse { - -template <typename T, typename Function> -std::unique_ptr<Tensor> -reduceAll(const SparseTensorT<T> &tensor, Function &&func) -{ - DirectSparseTensorBuilder<double> builder; - size_t sz = tensor.my_size(); - double result = 0.0; - if (sz != 0) { - result = tensor.get_value(0); - } - for (size_t i = 1; i < sz; ++i) { - result = func(result, tensor.get_value(i)); - } - builder.insertCell(SparseTensorAddressRef(), result); - return builder.build(); -} - -template <typename T, typename Function> -std::unique_ptr<Tensor> -reduce(const SparseTensorT<T> &tensor, - const std::vector<vespalib::string> &dimensions, Function &&func) -{ - auto tt = tensor.fast_type().reduce(dimensions); - if (tt.is_double()) { - return reduceAll(tensor, func); - } - DirectSparseTensorBuilder<T> builder(std::move(tt)); - builder.reserve(tensor.my_size()); - TensorAddressReducer addressReducer(tensor.fast_type(), dimensions); - for (const auto & kv : tensor.index().get_map()) { - addressReducer.reduce(kv.first); - auto v = tensor.get_value(kv.second); - builder.insertCell(addressReducer.getAddressRef(), v, func); - } - return builder.build(); -} - -} diff --git a/eval/src/vespa/eval/tensor/sparse/sparse_tensor_remove.cpp b/eval/src/vespa/eval/tensor/sparse/sparse_tensor_remove.cpp deleted file mode 100644 index eae09c0cb83..00000000000 --- a/eval/src/vespa/eval/tensor/sparse/sparse_tensor_remove.cpp +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#include "sparse_tensor_remove.h" -#include "sparse_tensor_t.h" -#include <vespa/eval/tensor/tensor_address_element_iterator.h> - -namespace vespalib::tensor { - -template<typename T> -SparseTensorRemove<T>::SparseTensorRemove(const SparseTensorT<T> &input) - : _input(input), - _map(input.index().get_map()), - _addressBuilder() -{ -} - -template<typename T> -SparseTensorRemove<T>::~SparseTensorRemove() = default; - -template<typename T> -void -SparseTensorRemove<T>::visit(const TensorAddress &address, double) -{ - _addressBuilder.populate(_input.fast_type(), address); - auto addressRef = _addressBuilder.getAddressRef(); - _map.erase(addressRef); -} - -template<typename T> -std::unique_ptr<Tensor> -SparseTensorRemove<T>::build() -{ - SparseTensorIndex new_index(_input.fast_type().count_mapped_dimensions()); - std::vector<T> new_values; - new_index.reserve(_map.size()); - new_values.reserve(_map.size()); - for (const auto & kv : _map) { - size_t idx = new_index.lookup_or_add(kv.first); - assert(idx == new_values.size()); - double v = _input.get_value(kv.second); - new_values.push_back(v); - } - using tt = SparseTensorT<T>; - return std::make_unique<tt>(_input.fast_type(), std::move(new_index), std::move(new_values)); -} - -template class SparseTensorRemove<float>; -template class SparseTensorRemove<double>; - -} diff --git a/eval/src/vespa/eval/tensor/sparse/sparse_tensor_remove.h b/eval/src/vespa/eval/tensor/sparse/sparse_tensor_remove.h deleted file mode 100644 index c52c38a9b0e..00000000000 --- a/eval/src/vespa/eval/tensor/sparse/sparse_tensor_remove.h +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#pragma once - -#include "sparse_tensor.h" -#include "sparse_tensor_t.h" -#include "sparse_tensor_address_builder.h" -#include <vespa/eval/tensor/tensor_visitor.h> - -namespace vespalib::tensor { - -/** - * This class handles a tensor remove operation on a sparse tensor. - * - * Creates a new tensor by removing the cells matching the cell addresses visited. - * The value associated with the address is ignored. - */ -template<typename T> -class SparseTensorRemove : public TensorVisitor { -private: - const SparseTensorT<T> & _input; - SparseTensorIndex::IndexMap _map; - SparseTensorAddressBuilder _addressBuilder; -public: - explicit SparseTensorRemove(const SparseTensorT<T> &input); - ~SparseTensorRemove(); - void visit(const TensorAddress &address, double value) override; - std::unique_ptr<Tensor> build(); -}; - -} diff --git a/eval/src/vespa/eval/tensor/sparse/sparse_tensor_t.cpp b/eval/src/vespa/eval/tensor/sparse/sparse_tensor_t.cpp deleted file mode 100644 index 164d9bc957f..00000000000 --- a/eval/src/vespa/eval/tensor/sparse/sparse_tensor_t.cpp +++ /dev/null @@ -1,259 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#include "sparse_tensor.h" -#include "sparse_tensor_add.h" -#include "sparse_tensor_address_builder.h" -#include "sparse_tensor_join.h" -#include "sparse_tensor_join.hpp" -#include "sparse_tensor_match.h" -#include "sparse_tensor_modify.h" -#include "sparse_tensor_reduce.hpp" -#include "sparse_tensor_remove.h" -#include "direct_sparse_tensor_builder.h" -#include <vespa/eval/eval/operation.h> -#include <vespa/eval/tensor/cell_values.h> -#include <vespa/eval/tensor/tensor_address_builder.h> -#include <vespa/eval/tensor/tensor_visitor.h> -#include <vespa/vespalib/stllike/hash_map.hpp> -#include <vespa/vespalib/stllike/hash_map_equal.hpp> -#include <vespa/vespalib/util/array_equal.hpp> - -#include <vespa/log/log.h> -LOG_SETUP(".eval.tensor.sparse.sparse_tensor"); - -namespace vespalib::tensor { - -namespace { - -template<typename LCT> -struct GenericSparseJoin { - template<typename RCT, typename OCT> - static Tensor::UP invoke(const SparseTensor & lhs_in, - const SparseTensor & rhs_in, - eval::ValueType res_type, - SparseTensor::join_fun_t func) - { - auto & lhs = static_cast<const SparseTensorT<LCT> &>(lhs_in); - auto & rhs = static_cast<const SparseTensorT<RCT> &>(rhs_in); - return sparse::join<LCT, RCT, OCT>(lhs, rhs, std::move(res_type), func); - } -}; - -template<typename LCT> -struct FastSparseJoin { - template<typename RCT> - static Tensor::UP invoke(const SparseTensor & lhs_in, - const SparseTensor & rhs_in, - eval::ValueType res_type) - { - auto & lhs = static_cast<const SparseTensorT<LCT> &>(lhs_in); - auto & rhs = static_cast<const SparseTensorT<RCT> &>(rhs_in); - // Ensure that first tensor to fastMatch has fewest cells. - if (rhs.my_size() < lhs.my_size()) { - return SparseTensorMatch<RCT,LCT>(rhs, lhs, std::move(res_type)).result(); - } else { - return SparseTensorMatch<LCT,RCT>(lhs, rhs, std::move(res_type)).result(); - } - } -}; - -struct GenericSparseMerge { - template<typename LCT, typename RCT> - static Tensor::UP invoke(const SparseTensor &lhs_in, - const SparseTensor &rhs_in, - SparseTensor::join_fun_t function) - { - using OCT = typename eval::UnifyCellTypes<LCT,RCT>::type; - auto & lhs= static_cast<const SparseTensorT<LCT> &>(lhs_in); - auto & rhs= static_cast<const SparseTensorT<RCT> &>(rhs_in); - DirectSparseTensorBuilder<OCT> builder(eval::ValueType::merge(lhs.fast_type(), rhs.fast_type())); - builder.reserve(lhs.my_size() + rhs.my_size()); - const auto &lhs_map = lhs.index().get_map(); - const auto &rhs_map = rhs.index().get_map(); - for (const auto & kv : lhs_map) { - auto pos = rhs_map.find(kv.first); - if (pos == rhs_map.end()) { - builder.insertCell(kv.first, lhs.get_value(kv.second)); - } else { - double a = lhs.get_value(kv.second); - double b = rhs.get_value(pos->second); - builder.insertCell(kv.first, function(a, b)); - } - } - for (const auto & kv : rhs_map) { - auto pos = lhs_map.find(kv.first); - if (pos == lhs_map.end()) { - double b = rhs.get_value(kv.second); - builder.insertCell(kv.first, b); - } - } - return builder.build(); - } -}; - -} // namespace <unnamed> - -template<typename T> -SparseTensorT<T>::SparseTensorT(eval::ValueType type_in, SparseTensorIndex index_in, std::vector<T> values_in) - : SparseTensor(std::move(type_in), std::move(index_in)), - _values(std::move(values_in)) -{ -} - -template<typename T> -SparseTensorT<T>::~SparseTensorT() = default; - -template<typename T> -eval::TypedCells -SparseTensorT<T>::cells() const -{ - return eval::TypedCells(_values); -} - -template<typename T> -double -SparseTensorT<T>::as_double() const -{ - double result = 0.0; - for (double v : _values) { - result += v; - } - return result; -} - -template<typename T> -void -SparseTensorT<T>::accept(TensorVisitor &visitor) const -{ - TensorAddressBuilder addrBuilder; - TensorAddress addr; - for (const auto & kv : index().get_map()) { - SparseTensorAddressDecoder decoder(kv.first); - addrBuilder.clear(); - for (const auto &dimension : fast_type().dimensions()) { - auto label = decoder.decodeLabel(); - if (label.size() != 0u) { - addrBuilder.add(dimension.name, label); - } - } - assert(!decoder.valid()); - addr = addrBuilder.build(); - visitor.visit(addr, get_value(kv.second)); - } -} - -template<typename T> -std::unique_ptr<Tensor> -SparseTensorT<T>::add(const Tensor &arg) const -{ - const SparseTensor *rhs = dynamic_cast<const SparseTensor *>(&arg); - if (!rhs) { - return Tensor::UP(); - } - SparseTensorAdd<T> adder(fast_type(), index().copy(), _values); - rhs->accept(adder); - return adder.build(); -} - -template<typename T> -Tensor::UP -SparseTensorT<T>::apply(const CellFunction &func) const -{ - std::vector<T> new_values; - new_values.reserve(_values.size()); - for (T v : _values) { - new_values.push_back(func.apply(v)); - } - return std::make_unique<SparseTensorT<T>>(fast_type(), index().copy(), std::move(new_values)); -} - -template<typename T> -Tensor::UP -SparseTensorT<T>::join(join_fun_t function, const Tensor &arg) const -{ - const SparseTensor *rhs = dynamic_cast<const SparseTensor *>(&arg); - if (!rhs) { - return Tensor::UP(); - } - const auto & lhs_type = fast_type(); - const auto & rhs_type = rhs->fast_type(); - auto rhs_ct = rhs_type.cell_type(); - auto res_type = eval::ValueType::join(lhs_type, rhs_type); - if (function == eval::operation::Mul::f) { - if (lhs_type.dimensions() == rhs_type.dimensions()) { - return typify_invoke<1,eval::TypifyCellType,FastSparseJoin<T>>(rhs_ct, - *this, *rhs, std::move(res_type)); - } - } - auto res_ct = res_type.cell_type(); - return typify_invoke<2,eval::TypifyCellType,GenericSparseJoin<T>>(rhs_ct, res_ct, - *this, *rhs, std::move(res_type), function); -} - -template<typename T> -Tensor::UP -SparseTensorT<T>::merge(join_fun_t function, const Tensor &arg) const -{ - const SparseTensor *rhs = dynamic_cast<const SparseTensor *>(&arg); - assert(rhs && (fast_type().dimensions() == rhs->fast_type().dimensions())); - return typify_invoke<2,eval::TypifyCellType,GenericSparseMerge>( - fast_type().cell_type(), rhs->fast_type().cell_type(), - *this, *rhs, function); -} - -template<typename T> -std::unique_ptr<Tensor> -SparseTensorT<T>::modify(join_fun_t op, const CellValues &cellValues) const -{ - SparseTensorModify modifier(op, *this);; - cellValues.accept(modifier); - return modifier.build(); -} - -template<typename T> -Tensor::UP -SparseTensorT<T>::reduce(join_fun_t op, const std::vector<vespalib::string> &dimensions) const -{ - return sparse::reduce(*this, dimensions, op); -} - -template<typename T> -std::unique_ptr<Tensor> -SparseTensorT<T>::remove(const CellValues &cellAddresses) const -{ - SparseTensorRemove<T> remover(*this); - cellAddresses.accept(remover); - return remover.build(); -} - -template<typename T> -MemoryUsage -SparseTensorT<T>::get_memory_usage() const -{ - MemoryUsage result = index().get_memory_usage(); - result.incUsedBytes(sizeof(SparseTensor)); - result.incUsedBytes(_values.size() * sizeof(T)); - result.incAllocatedBytes(sizeof(SparseTensor)); - result.incAllocatedBytes(_values.capacity() * sizeof(T)); - return result; -} - -template<typename T> -bool -SparseTensorT<T>::should_shrink() const -{ - auto mem_use = get_memory_usage(); - return (mem_use.usedBytes() * 3 < mem_use.allocatedBytes()); -} - -template<typename T> -Tensor::UP -SparseTensorT<T>::shrink() const -{ - return std::make_unique<SparseTensorT<T>>(fast_type(), index().shrunk_copy(), _values); -} - -template class SparseTensorT<float>; -template class SparseTensorT<double>; - -} diff --git a/eval/src/vespa/eval/tensor/sparse/sparse_tensor_t.h b/eval/src/vespa/eval/tensor/sparse/sparse_tensor_t.h deleted file mode 100644 index ed8c1f427f9..00000000000 --- a/eval/src/vespa/eval/tensor/sparse/sparse_tensor_t.h +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#pragma once - -#include "sparse_tensor_index.h" -#include <vespa/eval/tensor/cell_function.h> -#include <vespa/eval/tensor/tensor.h> -#include <vespa/eval/tensor/tensor_address.h> -#include <vespa/eval/tensor/types.h> -#include <vespa/vespalib/stllike/hash_map.h> -#include <vespa/vespalib/stllike/string.h> -#include <vespa/vespalib/util/stash.h> - -namespace vespalib::tensor { - -template<typename T> -class SparseTensorT : public SparseTensor -{ -private: - std::vector<T> _values; -public: - SparseTensorT(eval::ValueType type_in, SparseTensorIndex index_in, std::vector<T> cells_in); - ~SparseTensorT() override; - eval::TypedCells cells() const override; - T get_value(size_t idx) const { return _values[idx]; } - size_t my_size() const { return _values.size(); } - const std::vector<T> &my_values() const { return _values; } - double as_double() const override; - void accept(TensorVisitor &visitor) const override; - Tensor::UP add(const Tensor &arg) const override; - Tensor::UP apply(const CellFunction &func) const override; - Tensor::UP join(join_fun_t function, const Tensor &arg) const override; - Tensor::UP merge(join_fun_t function, const Tensor &arg) const override; - Tensor::UP modify(join_fun_t op, const CellValues &cellValues) const override; - Tensor::UP reduce(join_fun_t op, const std::vector<vespalib::string> &dimensions) const override; - Tensor::UP remove(const CellValues &cellAddresses) const override; - MemoryUsage get_memory_usage() const override; - bool should_shrink() const; - Tensor::UP shrink() const; -}; - -} diff --git a/eval/src/vespa/eval/tensor/sparse/sparse_tensor_value_builder.cpp b/eval/src/vespa/eval/tensor/sparse/sparse_tensor_value_builder.cpp deleted file mode 100644 index 2152a2c3b6e..00000000000 --- a/eval/src/vespa/eval/tensor/sparse/sparse_tensor_value_builder.cpp +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#include "sparse_tensor_value_builder.h" -#include "sparse_tensor_t.h" - -namespace vespalib::tensor { - -template <typename T> -ArrayRef<T> -SparseTensorValueBuilder<T>::add_subspace(ConstArrayRef<vespalib::stringref> addr) -{ - uint32_t idx = _cells.size(); - _addr_builder.clear(); - for (const auto & label : addr) { - _addr_builder.add(label); - } - auto tmp_ref = _addr_builder.getAddressRef(); - _index.add_address(tmp_ref); - _cells.push_back(0.0); - return ArrayRef<T>(&_cells[idx], 1); -} - -template <typename T> -std::unique_ptr<eval::Value> -SparseTensorValueBuilder<T>::build(std::unique_ptr<eval::ValueBuilder<T>>) -{ - return std::make_unique<SparseTensorT<T>>(std::move(_type), - std::move(_index), - std::move(_cells)); - -} - -template class SparseTensorValueBuilder<float>; -template class SparseTensorValueBuilder<double>; - -} // namespace diff --git a/eval/src/vespa/eval/tensor/sparse/sparse_tensor_value_builder.h b/eval/src/vespa/eval/tensor/sparse/sparse_tensor_value_builder.h deleted file mode 100644 index a48af150b15..00000000000 --- a/eval/src/vespa/eval/tensor/sparse/sparse_tensor_value_builder.h +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#pragma once - -#include "sparse_tensor.h" -#include "sparse_tensor_address_builder.h" - -namespace vespalib::tensor { - -/** - * A builder for SparseTensorValue objects - * appropriate for cell type T. - **/ -template <typename T> -class SparseTensorValueBuilder : public eval::ValueBuilder<T> -{ -private: - eval::ValueType _type; - SparseTensorIndex _index; - std::vector<T> _cells; - SparseTensorAddressBuilder _addr_builder; -public: - SparseTensorValueBuilder(const eval::ValueType &type, - size_t num_mapped_in, - size_t expected_subspaces) - : _type(type), - _index(num_mapped_in), - _cells() - { - assert(num_mapped_in > 0); - _index.reserve(expected_subspaces); - _cells.reserve(expected_subspaces); - } - - ~SparseTensorValueBuilder() override = default; - - ArrayRef<T> add_subspace(ConstArrayRef<vespalib::stringref> addr) override; - std::unique_ptr<eval::Value> build(std::unique_ptr<eval::ValueBuilder<T>> self) override; -}; - -} // namespace diff --git a/eval/src/vespa/eval/tensor/tensor.cpp b/eval/src/vespa/eval/tensor/tensor.cpp deleted file mode 100644 index 1b5671990a9..00000000000 --- a/eval/src/vespa/eval/tensor/tensor.cpp +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#include "tensor.h" -#include <sstream> - -namespace vespalib::tensor { - -Tensor::Tensor() : eval::Tensor() {} - -bool -Tensor::supported(TypeList types) -{ - bool sparse = false; - bool dense = false; - for (const eval::ValueType &type: types) { - dense = (dense || type.is_double()); - for (const auto &dim: type.dimensions()) { - dense = (dense || dim.is_indexed()); - sparse = (sparse || dim.is_mapped()); - } - } - return (dense != sparse); -} - -std::ostream & -operator<<(std::ostream &out, const Tensor &value) -{ - out << value.toSpec().to_string(); - return out; -} - -} diff --git a/eval/src/vespa/eval/tensor/tensor.h b/eval/src/vespa/eval/tensor/tensor.h deleted file mode 100644 index 01cf6e8e61d..00000000000 --- a/eval/src/vespa/eval/tensor/tensor.h +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#pragma once - -#include "cell_function.h" -#include "tensor_address.h" -#include <vespa/vespalib/stllike/string.h> -#include <vespa/eval/eval/operation.h> -#include <vespa/eval/eval/tensor.h> -#include <vespa/eval/eval/tensor_spec.h> -#include <vespa/eval/eval/value_type.h> - -namespace vespalib::eval { struct BinaryOperation; } -namespace vespalib::tensor { - -class TensorVisitor; -class CellValues; - -/** - * Interface for operations on a tensor (sparse multi-dimensional array). - * - * A sparse tensor is a set of cells containing scalar values. - * Each cell is identified by its address, which consists of a set of dimension -> label pairs, - * where both dimension and label is a string on the form of an identifier or integer. - */ -class Tensor : public eval::Tensor -{ -public: - typedef std::unique_ptr<Tensor> UP; - typedef std::reference_wrapper<const Tensor> CREF; - using join_fun_t = vespalib::eval::operation::op2_t; - - Tensor(); - virtual ~Tensor() {} - virtual Tensor::UP apply(const CellFunction &func) const = 0; - virtual Tensor::UP join(join_fun_t function, const Tensor &arg) const = 0; - virtual Tensor::UP merge(join_fun_t function, const Tensor &arg) const = 0; - virtual Tensor::UP reduce(join_fun_t op, const std::vector<vespalib::string> &dimensions) const = 0; - - /* - * Creates a new tensor by modifying the underlying cells matching - * the given cells applying a join function to determine the new - * cell value. - */ - virtual std::unique_ptr<Tensor> modify(join_fun_t op, const CellValues &cellValues) const = 0; - - /** - * Creates a new tensor by adding the cells of the argument tensor to this tensor. - * Existing cell values are overwritten. - */ - virtual std::unique_ptr<Tensor> add(const Tensor &arg) const = 0; - - /** - * Creates a new tensor by removing the cells matching the given cell addresses. - * The value associated with the address is ignored. - */ - virtual std::unique_ptr<Tensor> remove(const CellValues &cellAddresses) const = 0; - - virtual eval::TensorSpec toSpec() const = 0; - virtual void accept(TensorVisitor &visitor) const = 0; - - using TypeList = std::initializer_list<std::reference_wrapper<const eval::ValueType>>; - static bool supported(TypeList types); -}; - -std::ostream &operator<<(std::ostream &out, const Tensor &value); - -} diff --git a/eval/src/vespa/eval/tensor/tensor_address.cpp b/eval/src/vespa/eval/tensor/tensor_address.cpp deleted file mode 100644 index a68fc5d3353..00000000000 --- a/eval/src/vespa/eval/tensor/tensor_address.cpp +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#include "tensor_address.h" -#include <algorithm> -#include <ostream> - -namespace vespalib::tensor { - -const vespalib::string TensorAddress::Element::UNDEFINED_LABEL = "(undefined)"; - -TensorAddress::Element::~Element() = default; - -TensorAddress::TensorAddress() - : _elements() -{ -} - -TensorAddress::~TensorAddress() = default; - -TensorAddress::TensorAddress(const Elements &elements_in) - : _elements(elements_in) -{ - std::sort(_elements.begin(), _elements.end()); -} - -bool -TensorAddress::hasDimension(const vespalib::string &dimension) const -{ - for (const auto &elem : _elements) { - if (elem.dimension() == dimension) { - return true; - } - } - return false; -} - -bool -TensorAddress::operator<(const TensorAddress &rhs) const -{ - if (_elements.size() == rhs._elements.size()) { - for (size_t i = 0; i < _elements.size(); ++i) { - if (_elements[i] != rhs._elements[i]) { - return _elements[i] < rhs._elements[i]; - } - } - } - return _elements.size() < rhs._elements.size(); -} - -bool -TensorAddress::operator==(const TensorAddress &rhs) const -{ - return _elements == rhs._elements; -} - -size_t -TensorAddress::hash() const -{ - size_t hashCode = 1; - for (const auto &elem : _elements) { - hashCode = 31 * hashCode + elem.hash(); - } - return hashCode; -} - -std::ostream & -operator<<(std::ostream &out, const TensorAddress::Elements &elements) -{ - out << "{"; - bool first = true; - for (const auto &elem : elements) { - if (!first) { - out << ","; - } - out << elem.dimension() << ":" << elem.label(); - first = false; - } - out << "}"; - return out; -} - -std::ostream & -operator<<(std::ostream &out, const TensorAddress &value) -{ - out << value.elements(); - return out; -} - -} diff --git a/eval/src/vespa/eval/tensor/tensor_address.h b/eval/src/vespa/eval/tensor/tensor_address.h deleted file mode 100644 index b12a5ca2dbb..00000000000 --- a/eval/src/vespa/eval/tensor/tensor_address.h +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#pragma once - -#include <vespa/vespalib/stllike/hash_fun.h> -#include <vespa/vespalib/stllike/string.h> -#include <iosfwd> -#include <map> -#include <vector> - -namespace vespalib::tensor { - -/** - * A sparse immutable address to a tensor cell. - * - * Only dimensions which have a different label than "undefined" are explicitly included. - * Tensor addresses are ordered by increasing size primarily, - * and by the natural order of the elements in sorted order secondarily. - */ -class TensorAddress -{ -public: - typedef std::unique_ptr<TensorAddress> UP; - - class Element - { - private: - vespalib::string _dimension; - vespalib::string _label; - - public: - static const vespalib::string UNDEFINED_LABEL; - Element(const vespalib::string &dimension_in, const vespalib::string &label_in) noexcept - : _dimension(dimension_in), _label(label_in) - {} - Element(const Element &) noexcept = default; - Element & operator = (const Element &) noexcept = default; - Element(Element &&) noexcept = default; - Element & operator = (Element &&) noexcept = default; - ~Element(); - const vespalib::string &dimension() const { return _dimension; } - const vespalib::string &label() const { return _label; } - bool operator<(const Element &rhs) const { - if (_dimension == rhs._dimension) { - // Define sort order when dimension is the same to be able - // to do set operations over element vectors. - return _label < rhs._label; - } - return _dimension < rhs._dimension; - } - bool operator==(const Element &rhs) const { - return (_dimension == rhs._dimension) && (_label == rhs._label); - } - bool operator!=(const Element &rhs) const { - return !(*this == rhs); - } - size_t hash() const { - return hashValue(_dimension.c_str()) + hashValue(_label.c_str()); - } - }; - - typedef std::vector<Element> Elements; - -private: - Elements _elements; - -public: - TensorAddress(); - explicit TensorAddress(const Elements &elements_in); - explicit TensorAddress(Elements &&elements_in) - : _elements(std::move(elements_in)) - {} - TensorAddress(const TensorAddress &) = default; - TensorAddress & operator = (const TensorAddress &) = default; - TensorAddress(TensorAddress &&) = default; - TensorAddress & operator = (TensorAddress &&) = default; - - ~TensorAddress(); - const Elements &elements() const { return _elements; } - bool hasDimension(const vespalib::string &dimension) const; - bool operator<(const TensorAddress &rhs) const; - bool operator==(const TensorAddress &rhs) const; - size_t hash() const; -}; - -std::ostream &operator<<(std::ostream &out, const TensorAddress::Elements &elements); -std::ostream &operator<<(std::ostream &out, const TensorAddress &value); - -} diff --git a/eval/src/vespa/eval/tensor/tensor_address_builder.h b/eval/src/vespa/eval/tensor/tensor_address_builder.h deleted file mode 100644 index 47ea79fd985..00000000000 --- a/eval/src/vespa/eval/tensor/tensor_address_builder.h +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#pragma once - -#include "tensor_address.h" - -namespace vespalib::tensor { - - -/** - * A builder for tensor addresses. - */ -class TensorAddressBuilder -{ - TensorAddress::Elements _elements; -public: - TensorAddressBuilder() - : _elements() - { - } - void add(vespalib::stringref dimension, vespalib::stringref label) { - _elements.emplace_back(dimension, label); - } - TensorAddress build() { return TensorAddress(_elements); } - void clear(void) { _elements.clear(); } -}; - - -} diff --git a/eval/src/vespa/eval/tensor/tensor_address_element_iterator.h b/eval/src/vespa/eval/tensor/tensor_address_element_iterator.h deleted file mode 100644 index 01710105840..00000000000 --- a/eval/src/vespa/eval/tensor/tensor_address_element_iterator.h +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#pragma once - -#include <vespa/vespalib/stllike/string.h> - -namespace vespalib::tensor { - - -/** - * An iterator for tensor address elements used to simplify 3-way merge - * between two tensor addresses and a dimension vector. - */ -template <class Address> -class TensorAddressElementIterator { - using InnerIterator = typename Address::Elements::const_iterator; - InnerIterator _itr; - InnerIterator _itrEnd; -public: - TensorAddressElementIterator(const Address &address) - : _itr(address.elements().cbegin()), - _itrEnd(address.elements().cend()) - { - } - bool valid() const { return (_itr != _itrEnd); } - vespalib::stringref dimension() const { return _itr->dimension(); } - vespalib::stringref label() const { return _itr->label(); } - void next() { ++_itr; } - bool skipToDimension(vespalib::stringref rhsDimension) { - for (;;) { - if (!valid()) { - return false; - } - if (dimension() < rhsDimension) { - next(); - } else { - return (dimension() == rhsDimension); - } - } - } -}; - -} diff --git a/eval/src/vespa/eval/tensor/tensor_visitor.h b/eval/src/vespa/eval/tensor/tensor_visitor.h deleted file mode 100644 index 4cd9792afbd..00000000000 --- a/eval/src/vespa/eval/tensor/tensor_visitor.h +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#pragma once - -#include "tensor_address.h" -#include <vespa/vespalib/stllike/string.h> -#include "types.h" - -namespace vespalib::tensor { - -/** - * Class for visiting a tensor. First visit must specify dimensions, - * remaining visits must specify tensor addresses and values. - */ -class TensorVisitor -{ -public: - virtual ~TensorVisitor() {} - virtual void visit(const TensorAddress &address, double value) = 0; -}; - -}
\ No newline at end of file diff --git a/eval/src/vespa/eval/tensor/types.h b/eval/src/vespa/eval/tensor/types.h deleted file mode 100644 index d969bc0a2fb..00000000000 --- a/eval/src/vespa/eval/tensor/types.h +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#pragma once - -#include <vespa/vespalib/stllike/string.h> -#include <vespa/vespalib/stllike/hash_set.h> -#include <vector> -#include <map> - -namespace vespalib::tensor { - -using TensorCells = std::map<std::map<vespalib::string, vespalib::string>, double>; -using TensorDimensions = std::vector<vespalib::string>; -using TensorDimensionsSet = vespalib::hash_set<vespalib::string>; -using DenseTensorCells = std::map<std::map<vespalib::string, size_t>, double>; - -} diff --git a/searchcore/src/vespa/searchcore/proton/matching/match_master.cpp b/searchcore/src/vespa/searchcore/proton/matching/match_master.cpp index 6c86f6c2d1c..6e56d6365ec 100644 --- a/searchcore/src/vespa/searchcore/proton/matching/match_master.cpp +++ b/searchcore/src/vespa/searchcore/proton/matching/match_master.cpp @@ -10,7 +10,6 @@ #include <vespa/vespalib/data/slime/inserter.h> #include <vespa/vespalib/data/slime/inject.h> #include <vespa/vespalib/data/slime/cursor.h> -#include <vespa/eval/eval/tensor_engine.h> #include <vespa/vespalib/objects/nbostream.h> #include <vespa/log/log.h> diff --git a/searchlib/src/tests/attribute/searchable/attributeblueprint_test.cpp b/searchlib/src/tests/attribute/searchable/attributeblueprint_test.cpp index afeb89349c7..51b4f1d760d 100644 --- a/searchlib/src/tests/attribute/searchable/attributeblueprint_test.cpp +++ b/searchlib/src/tests/attribute/searchable/attributeblueprint_test.cpp @@ -3,7 +3,6 @@ #include <vespa/eval/eval/tensor_spec.h> #include <vespa/eval/eval/value.h> #include <vespa/eval/eval/value_codec.h> -#include <vespa/eval/tensor/dense/dense_tensor_view.h> #include <vespa/searchcommon/attribute/iattributecontext.h> #include <vespa/searchlib/attribute/attribute_blueprint_factory.h> #include <vespa/searchlib/attribute/attribute_read_guard.h> diff --git a/searchlib/src/vespa/searchlib/attribute/attribute_blueprint_factory.cpp b/searchlib/src/vespa/searchlib/attribute/attribute_blueprint_factory.cpp index 95fde42724b..dfcbfbbbe2b 100644 --- a/searchlib/src/vespa/searchlib/attribute/attribute_blueprint_factory.cpp +++ b/searchlib/src/vespa/searchlib/attribute/attribute_blueprint_factory.cpp @@ -8,7 +8,6 @@ #include "attribute_blueprint_params.h" #include "document_weight_or_filter_search.h" #include <vespa/eval/eval/value.h> -#include <vespa/eval/tensor/dense/dense_tensor_view.h> #include <vespa/searchlib/common/location.h> #include <vespa/searchlib/common/locationiterators.h> #include <vespa/searchlib/common/matching_elements_fields.h> diff --git a/searchlib/src/vespa/searchlib/features/onnx_feature.cpp b/searchlib/src/vespa/searchlib/features/onnx_feature.cpp index d207e34e991..c3655e8ed2a 100644 --- a/searchlib/src/vespa/searchlib/features/onnx_feature.cpp +++ b/searchlib/src/vespa/searchlib/features/onnx_feature.cpp @@ -4,8 +4,7 @@ #include <vespa/searchlib/fef/properties.h> #include <vespa/searchlib/fef/onnx_model.h> #include <vespa/searchlib/fef/featureexecutor.h> -#include <vespa/eval/tensor/dense/dense_tensor_view.h> -#include <vespa/eval/tensor/dense/mutable_dense_tensor_view.h> +#include <vespa/eval/eval/value.h> #include <vespa/vespalib/util/stringfmt.h> #include <vespa/vespalib/util/stash.h> diff --git a/searchlib/src/vespa/searchlib/tensor/dense_tensor_attribute.cpp b/searchlib/src/vespa/searchlib/tensor/dense_tensor_attribute.cpp index 434df7549f3..be127a8be3e 100644 --- a/searchlib/src/vespa/searchlib/tensor/dense_tensor_attribute.cpp +++ b/searchlib/src/vespa/searchlib/tensor/dense_tensor_attribute.cpp @@ -5,8 +5,7 @@ #include "nearest_neighbor_index.h" #include "nearest_neighbor_index_saver.h" #include "tensor_attribute.hpp" -#include <vespa/eval/tensor/dense/dense_tensor_view.h> -#include <vespa/eval/tensor/dense/mutable_dense_tensor_view.h> +#include <vespa/eval/eval/value.h> #include <vespa/fastlib/io/bufferedfile.h> #include <vespa/searchlib/attribute/load_utils.h> #include <vespa/searchlib/attribute/readerbase.h> diff --git a/searchlib/src/vespa/searchlib/tensor/dense_tensor_store.cpp b/searchlib/src/vespa/searchlib/tensor/dense_tensor_store.cpp index 0eb657a2a25..bc8362c2643 100644 --- a/searchlib/src/vespa/searchlib/tensor/dense_tensor_store.cpp +++ b/searchlib/src/vespa/searchlib/tensor/dense_tensor_store.cpp @@ -1,8 +1,7 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include "dense_tensor_store.h" -#include <vespa/eval/tensor/dense/dense_tensor_view.h> -#include <vespa/eval/tensor/dense/mutable_dense_tensor_view.h> +#include <vespa/eval/eval/value.h> #include <vespa/vespalib/datastore/datastore.hpp> using vespalib::datastore::Handle; |