aboutsummaryrefslogtreecommitdiffstats
path: root/eval/src/tests/tensor
diff options
context:
space:
mode:
authorArne H Juul <arnej27959@users.noreply.github.com>2020-12-09 20:21:04 +0100
committerGitHub <noreply@github.com>2020-12-09 20:21:04 +0100
commit80db966fd7477f1267613f469ff70787af95b54e (patch)
treebdb878f82fecdbd8c004204c3ca60fbd57ba2af5 /eval/src/tests/tensor
parentf3e2acd0df995ea17ddf016719d0f2ef33ef1427 (diff)
parentb66792587ac1c7164700db323dd7f2483062bbbd (diff)
Merge pull request #15764 from vespa-engine/arnej/move-dense-optimizers
Arnej/move dense optimizers
Diffstat (limited to 'eval/src/tests/tensor')
-rw-r--r--eval/src/tests/tensor/dense_add_dimension_optimizer/CMakeLists.txt8
-rw-r--r--eval/src/tests/tensor/dense_add_dimension_optimizer/dense_add_dimension_optimizer_test.cpp109
-rw-r--r--eval/src/tests/tensor/dense_dimension_combiner/CMakeLists.txt9
-rw-r--r--eval/src/tests/tensor/dense_dimension_combiner/dense_dimension_combiner_test.cpp185
-rw-r--r--eval/src/tests/tensor/dense_fast_rename_optimizer/CMakeLists.txt8
-rw-r--r--eval/src/tests/tensor/dense_fast_rename_optimizer/dense_fast_rename_optimizer_test.cpp75
-rw-r--r--eval/src/tests/tensor/dense_inplace_join_function/CMakeLists.txt8
-rw-r--r--eval/src/tests/tensor/dense_inplace_join_function/dense_inplace_join_function_test.cpp138
-rw-r--r--eval/src/tests/tensor/dense_pow_as_map_optimizer/CMakeLists.txt9
-rw-r--r--eval/src/tests/tensor/dense_pow_as_map_optimizer/dense_pow_as_map_optimizer_test.cpp92
-rw-r--r--eval/src/tests/tensor/dense_remove_dimension_optimizer/CMakeLists.txt8
-rw-r--r--eval/src/tests/tensor/dense_remove_dimension_optimizer/dense_remove_dimension_optimizer_test.cpp81
-rw-r--r--eval/src/tests/tensor/dense_replace_type_function/CMakeLists.txt8
-rw-r--r--eval/src/tests/tensor/dense_replace_type_function/dense_replace_type_function_test.cpp77
-rw-r--r--eval/src/tests/tensor/dense_simple_join_function/CMakeLists.txt8
-rw-r--r--eval/src/tests/tensor/dense_simple_join_function/dense_simple_join_function_test.cpp225
-rw-r--r--eval/src/tests/tensor/dense_simple_map_function/CMakeLists.txt9
-rw-r--r--eval/src/tests/tensor/dense_simple_map_function/dense_simple_map_function_test.cpp75
-rw-r--r--eval/src/tests/tensor/dense_single_reduce_function/CMakeLists.txt8
-rw-r--r--eval/src/tests/tensor/dense_single_reduce_function/dense_single_reduce_function_test.cpp170
-rw-r--r--eval/src/tests/tensor/dense_tensor_create_function/CMakeLists.txt8
-rw-r--r--eval/src/tests/tensor/dense_tensor_create_function/dense_tensor_create_function_test.cpp60
-rw-r--r--eval/src/tests/tensor/direct_sparse_tensor_builder/CMakeLists.txt8
-rw-r--r--eval/src/tests/tensor/direct_sparse_tensor_builder/direct_sparse_tensor_builder_test.cpp119
-rw-r--r--eval/src/tests/tensor/instruction_benchmark/instruction_benchmark.cpp1
-rw-r--r--eval/src/tests/tensor/onnx_wrapper/onnx_wrapper_test.cpp1
-rw-r--r--eval/src/tests/tensor/tensor_address/tensor_address_test.cpp2
-rw-r--r--eval/src/tests/tensor/typed_cells/CMakeLists.txt8
-rw-r--r--eval/src/tests/tensor/typed_cells/typed_cells_test.cpp622
-rw-r--r--eval/src/tests/tensor/vector_from_doubles_function/CMakeLists.txt8
-rw-r--r--eval/src/tests/tensor/vector_from_doubles_function/vector_from_doubles_function_test.cpp59
31 files changed, 0 insertions, 2206 deletions
diff --git a/eval/src/tests/tensor/dense_add_dimension_optimizer/CMakeLists.txt b/eval/src/tests/tensor/dense_add_dimension_optimizer/CMakeLists.txt
deleted file mode 100644
index 1bc9f93b1a2..00000000000
--- a/eval/src/tests/tensor/dense_add_dimension_optimizer/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_add_dimension_optimizer_test_app TEST
- SOURCES
- dense_add_dimension_optimizer_test.cpp
- DEPENDS
- vespaeval
-)
-vespa_add_test(NAME eval_dense_add_dimension_optimizer_test_app COMMAND eval_dense_add_dimension_optimizer_test_app)
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
deleted file mode 100644
index 0e8e50daae5..00000000000
--- a/eval/src/tests/tensor/dense_add_dimension_optimizer/dense_add_dimension_optimizer_test.cpp
+++ /dev/null
@@ -1,109 +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/fast_value.h>
-#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/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();
-
-EvalFixture::ParamRepo make_params() {
- return EvalFixture::ParamRepo()
- .add("x5", spec({x(5)}, N()))
- .add("x5f", spec(float_cells({x(5)}), N()))
- .add("x5y1", spec({x(5),y(1)}, N()))
- .add("y1z1", spec({y(1),z(1)}, N()))
- .add("x_m", spec({x({"a"})}, N()));
-}
-EvalFixture::ParamRepo param_repo = make_params();
-
-void verify_optimized(const vespalib::string &expr) {
- EvalFixture fixture(prod_factory, expr, param_repo, true);
- EXPECT_EQUAL(fixture.result(), EvalFixture::ref(expr, param_repo));
- auto info = fixture.find_all<DenseReplaceTypeFunction>();
- EXPECT_EQUAL(info.size(), 1u);
-}
-
-void verify_not_optimized(const vespalib::string &expr) {
- EvalFixture fixture(prod_factory, expr, param_repo, true);
- EXPECT_EQUAL(fixture.result(), EvalFixture::ref(expr, param_repo));
- auto info = fixture.find_all<DenseReplaceTypeFunction>();
- EXPECT_TRUE(info.empty());
-}
-
-TEST("require that dimension addition can be optimized") {
- TEST_DO(verify_optimized("join(x5,tensor(y[1])(1),f(a,b)(a*b))"));
- TEST_DO(verify_optimized("join(tensor(y[1])(1),x5,f(a,b)(a*b))"));
- TEST_DO(verify_optimized("x5*tensor(y[1])(1)"));
- TEST_DO(verify_optimized("tensor(y[1])(1)*x5"));
- TEST_DO(verify_optimized("x5y1*tensor(z[1])(1)"));
- TEST_DO(verify_optimized("tensor(z[1])(1)*x5y1"));
-}
-
-TEST("require that multi-dimension addition can be optimized") {
- TEST_DO(verify_optimized("x5*tensor(a[1],b[1],c[1])(1)"));
-}
-
-TEST("require that dimension addition can be chained (and compacted)") {
- TEST_DO(verify_optimized("tensor(z[1])(1)*x5*tensor(y[1])(1)"));
-}
-
-TEST("require that constant dimension addition is optimized") {
- TEST_DO(verify_optimized("tensor(x[1])(1)*tensor(y[1])(1)"));
- TEST_DO(verify_optimized("tensor(x[1])(1.1)*tensor(y[1])(1)"));
- TEST_DO(verify_optimized("tensor(x[1])(1)*tensor(y[1])(1.1)"));
- TEST_DO(verify_optimized("tensor(x[2])(1)*tensor(y[1])(1)"));
- TEST_DO(verify_optimized("tensor(x[1])(1)*tensor(y[2])(1)"));
-}
-
-TEST("require that non-canonical dimension addition is not optimized") {
- TEST_DO(verify_not_optimized("x5+tensor(y[1])(0)"));
- TEST_DO(verify_not_optimized("tensor(y[1])(0)+x5"));
- TEST_DO(verify_not_optimized("x5-tensor(y[1])(0)"));
- TEST_DO(verify_not_optimized("x5/tensor(y[1])(1)"));
- TEST_DO(verify_not_optimized("tensor(y[1])(1)/x5"));
-}
-
-TEST("require that dimension addition with overlapping dimensions is optimized") {
- TEST_DO(verify_optimized("x5y1*tensor(y[1],z[1])(1)"));
- TEST_DO(verify_optimized("tensor(y[1],z[1])(1)*x5y1"));
-}
-
-TEST("require that dimension addition with inappropriate dimensions is not optimized") {
- TEST_DO(verify_not_optimized("x_m*tensor(y[1])(1)"));
- TEST_DO(verify_not_optimized("tensor(y[1])(1)*x_m"));
-}
-
-TEST("require that dimension addition optimization requires unit constant tensor") {
- TEST_DO(verify_not_optimized("x5*tensor(y[1])(0.9)"));
- TEST_DO(verify_not_optimized("tensor(y[1])(1.1)*x5"));
- TEST_DO(verify_not_optimized("x5*tensor(y[1],z[2])(1)"));
- TEST_DO(verify_not_optimized("tensor(y[1],z[2])(1)*x5"));
- TEST_DO(verify_not_optimized("x5*y1z1"));
- TEST_DO(verify_not_optimized("y1z1*x5"));
- TEST_DO(verify_not_optimized("tensor(x[1])(1.1)*tensor(y[1])(1.1)"));
- TEST_DO(verify_not_optimized("tensor(x[2])(1)*tensor(y[2])(1)"));
-}
-
-TEST("require that optimization also works for float cells") {
- TEST_DO(verify_optimized("x5*tensor<float>(a[1],b[1],c[1])(1)"));
- TEST_DO(verify_optimized("x5f*tensor<float>(a[1],b[1],c[1])(1)"));
-}
-
-TEST("require that optimization is disabled if unit vector would promote tensor cell types") {
- TEST_DO(verify_not_optimized("x5f*tensor(a[1],b[1],c[1])(1)"));
-}
-
-TEST_MAIN() { TEST_RUN_ALL(); }
diff --git a/eval/src/tests/tensor/dense_dimension_combiner/CMakeLists.txt b/eval/src/tests/tensor/dense_dimension_combiner/CMakeLists.txt
deleted file mode 100644
index eaee8ebb4e4..00000000000
--- a/eval/src/tests/tensor/dense_dimension_combiner/CMakeLists.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-# Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-
-vespa_add_executable(eval_dense_dimension_combiner_test_app TEST
- SOURCES
- dense_dimension_combiner_test.cpp
- DEPENDS
- vespaeval
-)
-vespa_add_test(NAME eval_dense_dimension_combiner_test_app COMMAND eval_dense_dimension_combiner_test_app)
diff --git a/eval/src/tests/tensor/dense_dimension_combiner/dense_dimension_combiner_test.cpp b/eval/src/tests/tensor/dense_dimension_combiner/dense_dimension_combiner_test.cpp
deleted file mode 100644
index b8949e3a7e6..00000000000
--- a/eval/src/tests/tensor/dense_dimension_combiner/dense_dimension_combiner_test.cpp
+++ /dev/null
@@ -1,185 +0,0 @@
-// Copyright 2019 Oath Inc. 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/tensor/dense/dense_dimension_combiner.h>
-
-using namespace vespalib;
-using namespace vespalib::eval;
-using namespace vespalib::tensor;
-
-void verifyLeft(DenseDimensionCombiner &d, size_t last) {
- d.commonReset();
- d.leftReset();
- EXPECT_TRUE(d.leftInRange());
- EXPECT_EQUAL(d.leftIdx(), 0u);
- size_t expect = 0;
- while (d.leftInRange()) {
- d.stepLeft();
- EXPECT_GREATER(d.leftIdx(), expect);
- expect = d.leftIdx();
- }
- EXPECT_FALSE(d.leftInRange());
- EXPECT_EQUAL(expect, last);
- d.leftReset();
- EXPECT_TRUE(d.leftInRange());
- EXPECT_EQUAL(d.leftIdx(), 0u);
-}
-
-void verifyRight(DenseDimensionCombiner &d, size_t last) {
- d.commonReset();
- d.rightReset();
- EXPECT_TRUE(d.rightInRange());
- EXPECT_EQUAL(d.rightIdx(), 0u);
- size_t expect = 0;
- while (d.rightInRange()) {
- d.stepRight();
- EXPECT_GREATER(d.rightIdx(), expect);
- expect = d.rightIdx();
- }
- EXPECT_FALSE(d.rightInRange());
- EXPECT_EQUAL(expect, last);
- d.rightReset();
- EXPECT_TRUE(d.rightInRange());
- EXPECT_EQUAL(d.rightIdx(), 0u);
-}
-
-
-TEST("require that one left, one common, one right dimension works") {
- ValueType t12_lc = ValueType::tensor_type({{"d1_l", 3},{"d2_c", 4}});
- ValueType t23_cr = ValueType::tensor_type({{"d2_c", 4},{"d3_r", 5}});
-
- DenseDimensionCombiner d(t12_lc, t23_cr);
-
- EXPECT_TRUE(d.leftInRange());
- EXPECT_TRUE(d.rightInRange());
- EXPECT_TRUE(d.commonInRange());
- EXPECT_EQUAL(d.leftIdx(), 0u);
- EXPECT_EQUAL(d.rightIdx(), 0u);
- EXPECT_EQUAL(d.outputIdx(), 0u);
-
- d.stepCommon();
- EXPECT_TRUE(d.leftInRange());
- EXPECT_TRUE(d.rightInRange());
- EXPECT_TRUE(d.commonInRange());
- EXPECT_EQUAL(d.leftIdx(), 1u);
- EXPECT_EQUAL(d.rightIdx(), 5u);
- EXPECT_EQUAL(d.outputIdx(), 5u);
-
- d.stepRight();
- EXPECT_TRUE(d.leftInRange());
- EXPECT_TRUE(d.rightInRange());
- EXPECT_TRUE(d.commonInRange());
- EXPECT_EQUAL(d.leftIdx(), 1u);
- EXPECT_EQUAL(d.rightIdx(), 6u);
- EXPECT_EQUAL(d.outputIdx(), 6u);
-
- d.stepLeft();
- EXPECT_TRUE(d.leftInRange());
- EXPECT_TRUE(d.rightInRange());
- EXPECT_TRUE(d.commonInRange());
- EXPECT_EQUAL(d.leftIdx(), 5u);
- EXPECT_EQUAL(d.rightIdx(), 6u);
- EXPECT_EQUAL(d.outputIdx(), 26u);
-
- d.stepLeft();
- EXPECT_TRUE(d.leftInRange());
- EXPECT_TRUE(d.rightInRange());
- EXPECT_TRUE(d.commonInRange());
- EXPECT_EQUAL(d.leftIdx(), 9u);
- EXPECT_EQUAL(d.rightIdx(), 6u);
- EXPECT_EQUAL(d.outputIdx(), 46u);
-
- d.stepLeft();
- EXPECT_FALSE(d.leftInRange());
- EXPECT_TRUE(d.rightInRange());
- EXPECT_TRUE(d.commonInRange());
- EXPECT_EQUAL(d.leftIdx(), 13u);
- EXPECT_EQUAL(d.rightIdx(), 6u);
- EXPECT_EQUAL(d.outputIdx(), 6u);
-
- d.leftReset();
- EXPECT_TRUE(d.leftInRange());
- EXPECT_TRUE(d.rightInRange());
- EXPECT_TRUE(d.commonInRange());
- EXPECT_EQUAL(d.leftIdx(), 1u);
- EXPECT_EQUAL(d.rightIdx(), 6u);
- EXPECT_EQUAL(d.outputIdx(), 6u);
-
- d.stepCommon();
- EXPECT_TRUE(d.leftInRange());
- EXPECT_TRUE(d.rightInRange());
- EXPECT_TRUE(d.commonInRange());
- EXPECT_EQUAL(d.leftIdx(), 2u);
- EXPECT_EQUAL(d.rightIdx(), 11u);
- EXPECT_EQUAL(d.outputIdx(), 11u);
-
- d.stepRight();
- EXPECT_TRUE(d.leftInRange());
- EXPECT_TRUE(d.rightInRange());
- EXPECT_TRUE(d.commonInRange());
- EXPECT_EQUAL(d.leftIdx(), 2u);
- EXPECT_EQUAL(d.rightIdx(), 12u);
- EXPECT_EQUAL(d.outputIdx(), 12u);
-
- TEST_DO(verifyLeft(d, 12));
- TEST_DO(verifyRight(d, 20));
-}
-
-TEST("require that two left, no common, two right dimensions works") {
- ValueType t12_ll = ValueType::tensor_type({{"d1_l", 3},{"d2_l", 4}});
- ValueType t34_rr = ValueType::tensor_type({{"d3_r", 5},{"d4_r", 2}});
-
- DenseDimensionCombiner d(t12_ll, t34_rr);
-
- EXPECT_TRUE(d.leftInRange());
- EXPECT_TRUE(d.rightInRange());
- EXPECT_TRUE(d.commonInRange());
- EXPECT_EQUAL(d.leftIdx(), 0u);
- EXPECT_EQUAL(d.rightIdx(), 0u);
- EXPECT_EQUAL(d.outputIdx(), 0u);
-
- d.stepCommon();
- EXPECT_TRUE(d.leftInRange());
- EXPECT_TRUE(d.rightInRange());
- EXPECT_FALSE(d.commonInRange());
- EXPECT_EQUAL(d.leftIdx(), 0u);
- EXPECT_EQUAL(d.rightIdx(), 0u);
- EXPECT_EQUAL(d.outputIdx(), 120u);
-
- d.commonReset();
- d.stepRight();
- EXPECT_TRUE(d.leftInRange());
- EXPECT_TRUE(d.rightInRange());
- EXPECT_TRUE(d.commonInRange());
- EXPECT_EQUAL(d.leftIdx(), 0u);
- EXPECT_EQUAL(d.rightIdx(), 1u);
- EXPECT_EQUAL(d.outputIdx(), 1u);
-
- d.stepLeft();
- EXPECT_TRUE(d.leftInRange());
- EXPECT_TRUE(d.rightInRange());
- EXPECT_TRUE(d.commonInRange());
- EXPECT_EQUAL(d.leftIdx(), 1u);
- EXPECT_EQUAL(d.rightIdx(), 1u);
- EXPECT_EQUAL(d.outputIdx(), 11u);
-
- d.stepLeft();
- d.stepLeft();
- d.stepLeft();
- d.stepLeft();
- d.stepLeft();
- d.stepLeft();
- d.stepLeft();
-
- EXPECT_TRUE(d.leftInRange());
- EXPECT_TRUE(d.rightInRange());
- EXPECT_TRUE(d.commonInRange());
- EXPECT_EQUAL(d.leftIdx(), 8u);
- EXPECT_EQUAL(d.rightIdx(), 1u);
- EXPECT_EQUAL(d.outputIdx(), 81u);
-
- TEST_DO(verifyLeft(d, 12));
- TEST_DO(verifyRight(d, 10));
-}
-
-TEST_MAIN() { TEST_RUN_ALL(); }
diff --git a/eval/src/tests/tensor/dense_fast_rename_optimizer/CMakeLists.txt b/eval/src/tests/tensor/dense_fast_rename_optimizer/CMakeLists.txt
deleted file mode 100644
index 32cf6c45d1e..00000000000
--- a/eval/src/tests/tensor/dense_fast_rename_optimizer/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_fast_rename_optimizer_test_app TEST
- SOURCES
- dense_fast_rename_optimizer_test.cpp
- DEPENDS
- vespaeval
-)
-vespa_add_test(NAME eval_dense_fast_rename_optimizer_test_app COMMAND eval_dense_fast_rename_optimizer_test_app)
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
deleted file mode 100644
index 52afde0e92c..00000000000
--- a/eval/src/tests/tensor/dense_fast_rename_optimizer/dense_fast_rename_optimizer_test.cpp
+++ /dev/null
@@ -1,75 +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/dense_replace_type_function.h>
-#include <vespa/eval/tensor/dense/dense_fast_rename_optimizer.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();
-
-EvalFixture::ParamRepo make_params() {
- return EvalFixture::ParamRepo()
- .add("x5", spec({x(5)}, N()))
- .add("x5f", spec(float_cells({x(5)}), N()))
- .add("x_m", spec({x({"a", "b", "c"})}, N()))
- .add("x5y3", spec({x(5),y(3)}, N()));
-}
-EvalFixture::ParamRepo param_repo = make_params();
-
-void verify_optimized(const vespalib::string &expr) {
- EvalFixture fixture(prod_factory, expr, param_repo, true);
- EXPECT_EQUAL(fixture.result(), EvalFixture::ref(expr, param_repo));
- auto info = fixture.find_all<DenseReplaceTypeFunction>();
- EXPECT_EQUAL(info.size(), 1u);
-}
-
-void verify_not_optimized(const vespalib::string &expr) {
- EvalFixture fixture(prod_factory, expr, param_repo, true);
- EXPECT_EQUAL(fixture.result(), EvalFixture::ref(expr, param_repo));
- auto info = fixture.find_all<DenseReplaceTypeFunction>();
- EXPECT_TRUE(info.empty());
-}
-
-TEST("require that non-transposing dense renames are optimized") {
- TEST_DO(verify_optimized("rename(x5,x,y)"));
- TEST_DO(verify_optimized("rename(x5,x,a)"));
- TEST_DO(verify_optimized("rename(x5y3,y,z)"));
- TEST_DO(verify_optimized("rename(x5y3,x,a)"));
- TEST_DO(verify_optimized("rename(x5y3,(x,y),(a,b))"));
- TEST_DO(verify_optimized("rename(x5y3,(x,y),(z,zz))"));
- TEST_DO(verify_optimized("rename(x5y3,(x,y),(y,z))"));
- TEST_DO(verify_optimized("rename(x5y3,(y,x),(b,a))"));
-}
-
-TEST("require that transposing dense renames are not optimized") {
- TEST_DO(verify_not_optimized("rename(x5y3,x,z)"));
- TEST_DO(verify_not_optimized("rename(x5y3,y,a)"));
- TEST_DO(verify_not_optimized("rename(x5y3,(x,y),(y,x))"));
- TEST_DO(verify_not_optimized("rename(x5y3,(x,y),(b,a))"));
- TEST_DO(verify_not_optimized("rename(x5y3,(y,x),(a,b))"));
-}
-
-TEST("require that non-dense renames are not optimized") {
- TEST_DO(verify_not_optimized("rename(x_m,x,y)"));
-}
-
-TEST("require that chained optimized renames are compacted into a single operation") {
- TEST_DO(verify_optimized("rename(rename(x5,x,y),y,z)"));
-}
-
-TEST("require that optimization works for float cells") {
- TEST_DO(verify_optimized("rename(x5f,x,y)"));
-}
-
-TEST_MAIN() { TEST_RUN_ALL(); }
diff --git a/eval/src/tests/tensor/dense_inplace_join_function/CMakeLists.txt b/eval/src/tests/tensor/dense_inplace_join_function/CMakeLists.txt
deleted file mode 100644
index 2808675bc78..00000000000
--- a/eval/src/tests/tensor/dense_inplace_join_function/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_inplace_join_function_test_app TEST
- SOURCES
- dense_inplace_join_function_test.cpp
- DEPENDS
- vespaeval
-)
-vespa_add_test(NAME eval_dense_inplace_join_function_test_app COMMAND eval_dense_inplace_join_function_test_app)
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
deleted file mode 100644
index 853607ae76d..00000000000
--- a/eval/src/tests/tensor/dense_inplace_join_function/dense_inplace_join_function_test.cpp
+++ /dev/null
@@ -1,138 +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/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_x5_B", spec({x(5)}, seq))
- .add("con_x5_C", spec({x(5)}, seq))
- .add("con_x5y3_A", spec({x(5),y(3)}, seq))
- .add("con_x5y3_B", spec({x(5),y(3)}, seq))
- .add_mutable("mut_dbl_A", spec(1.5))
- .add_mutable("mut_dbl_B", spec(2.5))
- .add_mutable("mut_x5_A", spec({x(5)}, seq))
- .add_mutable("mut_x5_B", spec({x(5)}, seq))
- .add_mutable("mut_x5_C", spec({x(5)}, seq))
- .add_mutable("mut_x5f_D", spec(float_cells({x(5)}), seq))
- .add_mutable("mut_x5f_E", spec(float_cells({x(5)}), seq))
- .add_mutable("mut_x5y3_A", spec({x(5),y(3)}, seq))
- .add_mutable("mut_x5y3_B", spec({x(5),y(3)}, seq))
- .add_mutable("mut_x_sparse", spec({x({"a", "b", "c"})}, seq));
-}
-EvalFixture::ParamRepo param_repo = make_params();
-
-void verify_optimized(const vespalib::string &expr, size_t param_idx) {
- EvalFixture fixture(prod_factory, expr, param_repo, true, true);
- EXPECT_EQUAL(fixture.result(), EvalFixture::ref(expr, param_repo));
- for (size_t i = 0; i < fixture.num_params(); ++i) {
- TEST_STATE(vespalib::make_string("param %zu", i).c_str());
- if (i == param_idx) {
- EXPECT_EQUAL(fixture.get_param(i), fixture.result());
- } else {
- EXPECT_NOT_EQUAL(fixture.get_param(i), fixture.result());
- }
- }
-}
-
-void verify_p0_optimized(const vespalib::string &expr) {
- verify_optimized(expr, 0);
-}
-
-void verify_p1_optimized(const vespalib::string &expr) {
- verify_optimized(expr, 1);
-}
-
-void verify_p2_optimized(const vespalib::string &expr) {
- verify_optimized(expr, 2);
-}
-
-void verify_not_optimized(const vespalib::string &expr) {
- EvalFixture fixture(prod_factory, expr, param_repo, true, true);
- EXPECT_EQUAL(fixture.result(), EvalFixture::ref(expr, param_repo));
- for (size_t i = 0; i < fixture.num_params(); ++i) {
- EXPECT_NOT_EQUAL(fixture.get_param(i), fixture.result());
- }
-}
-
-TEST("require that mutable dense concrete tensors are optimized") {
- TEST_DO(verify_p1_optimized("mut_x5_A-mut_x5_B"));
- TEST_DO(verify_p0_optimized("mut_x5_A-con_x5_B"));
- TEST_DO(verify_p1_optimized("con_x5_A-mut_x5_B"));
- TEST_DO(verify_p1_optimized("mut_x5y3_A-mut_x5y3_B"));
- TEST_DO(verify_p0_optimized("mut_x5y3_A-con_x5y3_B"));
- TEST_DO(verify_p1_optimized("con_x5y3_A-mut_x5y3_B"));
-}
-
-TEST("require that self-join operations can be optimized") {
- TEST_DO(verify_p0_optimized("mut_x5_A+mut_x5_A"));
-}
-
-TEST("require that join(tensor,scalar) operations are optimized") {
- TEST_DO(verify_p0_optimized("mut_x5_A-mut_dbl_B"));
- TEST_DO(verify_p1_optimized("mut_dbl_A-mut_x5_B"));
-}
-
-TEST("require that join with different tensor shapes are optimized") {
- TEST_DO(verify_p1_optimized("mut_x5_A*mut_x5y3_B"));
-}
-
-TEST("require that inplace join operations can be chained") {
- TEST_DO(verify_p2_optimized("mut_x5_A+(mut_x5_B+mut_x5_C)"));
- TEST_DO(verify_p0_optimized("(mut_x5_A+con_x5_B)+con_x5_C"));
- TEST_DO(verify_p1_optimized("con_x5_A+(mut_x5_B+con_x5_C)"));
- TEST_DO(verify_p2_optimized("con_x5_A+(con_x5_B+mut_x5_C)"));
-}
-
-TEST("require that non-mutable tensors are not optimized") {
- TEST_DO(verify_not_optimized("con_x5_A+con_x5_B"));
-}
-
-TEST("require that scalar values are not optimized") {
- TEST_DO(verify_not_optimized("mut_dbl_A+mut_dbl_B"));
- TEST_DO(verify_not_optimized("mut_dbl_A+5"));
- TEST_DO(verify_not_optimized("5+mut_dbl_B"));
-}
-
-TEST("require that mapped tensors are not optimized") {
- TEST_DO(verify_not_optimized("mut_x_sparse+mut_x_sparse"));
-}
-
-TEST("require that optimization works with float cells") {
- TEST_DO(verify_p1_optimized("mut_x5f_D-mut_x5f_E"));
-}
-
-TEST("require that overwritten value must have same cell type as result") {
- TEST_DO(verify_p0_optimized("mut_x5_A-mut_x5f_D"));
- TEST_DO(verify_p1_optimized("mut_x5f_D-mut_x5_A"));
- TEST_DO(verify_not_optimized("con_x5_A-mut_x5f_D"));
- TEST_DO(verify_not_optimized("mut_x5f_D-con_x5_A"));
-}
-
-TEST_MAIN() { TEST_RUN_ALL(); }
diff --git a/eval/src/tests/tensor/dense_pow_as_map_optimizer/CMakeLists.txt b/eval/src/tests/tensor/dense_pow_as_map_optimizer/CMakeLists.txt
deleted file mode 100644
index d6ce9f1924c..00000000000
--- a/eval/src/tests/tensor/dense_pow_as_map_optimizer/CMakeLists.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-# Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-vespa_add_executable(eval_dense_pow_as_map_optimizer_test_app TEST
- SOURCES
- dense_pow_as_map_optimizer_test.cpp
- DEPENDS
- vespaeval
- GTest::GTest
-)
-vespa_add_test(NAME eval_dense_pow_as_map_optimizer_test_app COMMAND eval_dense_pow_as_map_optimizer_test_app)
diff --git a/eval/src/tests/tensor/dense_pow_as_map_optimizer/dense_pow_as_map_optimizer_test.cpp b/eval/src/tests/tensor/dense_pow_as_map_optimizer/dense_pow_as_map_optimizer_test.cpp
deleted file mode 100644
index d00744bcfaf..00000000000
--- a/eval/src/tests/tensor/dense_pow_as_map_optimizer/dense_pow_as_map_optimizer_test.cpp
+++ /dev/null
@@ -1,92 +0,0 @@
-// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-
-#include <vespa/eval/eval/fast_value.h>
-#include <vespa/eval/eval/tensor_function.h>
-#include <vespa/eval/tensor/dense/dense_simple_map_function.h>
-#include <vespa/eval/eval/test/eval_fixture.h>
-#include <vespa/eval/eval/test/tensor_model.hpp>
-#include <vespa/vespalib/gtest/gtest.h>
-
-using namespace vespalib::eval::operation;
-using namespace vespalib::eval::tensor_function;
-using namespace vespalib::eval::test;
-using namespace vespalib::eval;
-using namespace vespalib::tensor;
-//using namespace vespalib;
-
-const ValueBuilderFactory &prod_factory = FastValueBuilderFactory::get();
-
-EvalFixture::ParamRepo make_params() {
- return EvalFixture::ParamRepo()
- .add("a", spec(1.5))
- .add("b", spec(2.5))
- .add("sparse", spec({x({"a"})}, N()))
- .add("mixed", spec({x({"a"}),y(5)}, N()))
- .add_matrix("x", 5, "y", 3);
-}
-EvalFixture::ParamRepo param_repo = make_params();
-
-void verify_optimized(const vespalib::string &expr, op1_t op1, bool inplace = false) {
- EvalFixture slow_fixture(prod_factory, expr, param_repo, false);
- EvalFixture fixture(prod_factory, expr, param_repo, true, true);
- EXPECT_EQ(fixture.result(), EvalFixture::ref(expr, param_repo));
- EXPECT_EQ(fixture.result(), slow_fixture.result());
- auto info = fixture.find_all<DenseSimpleMapFunction>();
- ASSERT_EQ(info.size(), 1u);
- EXPECT_TRUE(info[0]->result_is_mutable());
- EXPECT_EQ(info[0]->function(), op1);
- EXPECT_EQ(info[0]->inplace(), inplace);
- ASSERT_EQ(fixture.num_params(), 1);
- if (inplace) {
- EXPECT_EQ(fixture.get_param(0), fixture.result());
- } else {
- EXPECT_TRUE(!(fixture.get_param(0) == fixture.result()));
- }
-}
-
-void verify_not_optimized(const vespalib::string &expr) {
- EvalFixture slow_fixture(prod_factory, expr, param_repo, false);
- EvalFixture fixture(prod_factory, expr, param_repo, true);
- EXPECT_EQ(fixture.result(), EvalFixture::ref(expr, param_repo));
- EXPECT_EQ(fixture.result(), slow_fixture.result());
- auto info = fixture.find_all<Map>();
- EXPECT_TRUE(info.empty());
-}
-
-TEST(PowAsMapTest, squared_dense_tensor_is_optimized) {
- verify_optimized("x5y3^2.0", Square::f);
- verify_optimized("pow(x5y3,2.0)", Square::f);
- verify_optimized("join(x5y3,2.0,f(x,y)(x^y))", Square::f);
- verify_optimized("join(x5y3,2.0,f(x,y)(pow(x,y)))", Square::f);
- verify_optimized("join(x5y3f,2.0,f(x,y)(pow(x,y)))", Square::f);
- verify_optimized("join(@x5y3,2.0,f(x,y)(pow(x,y)))", Square::f, true);
- verify_optimized("join(@x5y3f,2.0,f(x,y)(pow(x,y)))", Square::f, true);
-}
-
-TEST(PowAsMapTest, cubed_dense_tensor_is_optimized) {
- verify_optimized("x5y3^3.0", Cube::f);
- verify_optimized("pow(x5y3,3.0)", Cube::f);
- verify_optimized("join(x5y3,3.0,f(x,y)(x^y))", Cube::f);
- verify_optimized("join(x5y3,3.0,f(x,y)(pow(x,y)))", Cube::f);
- verify_optimized("join(x5y3f,3.0,f(x,y)(pow(x,y)))", Cube::f);
- verify_optimized("join(@x5y3,3.0,f(x,y)(pow(x,y)))", Cube::f, true);
- verify_optimized("join(@x5y3f,3.0,f(x,y)(pow(x,y)))", Cube::f, true);
-}
-
-TEST(PowAsMapTest, hypercubed_dense_tensor_is_not_optimized) {
- verify_not_optimized("join(x5y3,4.0,f(x,y)(pow(x,y)))");
-}
-
-TEST(PowAsMapTest, scalar_join_is_not_optimized) {
- verify_not_optimized("join(a,2.0,f(x,y)(pow(x,y)))");
-}
-
-TEST(PowAsMapTest, sparse_join_is_not_optimized) {
- verify_not_optimized("join(sparse,2.0,f(x,y)(pow(x,y)))");
-}
-
-TEST(PowAsMapTest, mixed_join_is_not_optimized) {
- verify_not_optimized("join(mixed,2.0,f(x,y)(pow(x,y)))");
-}
-
-GTEST_MAIN_RUN_ALL_TESTS()
diff --git a/eval/src/tests/tensor/dense_remove_dimension_optimizer/CMakeLists.txt b/eval/src/tests/tensor/dense_remove_dimension_optimizer/CMakeLists.txt
deleted file mode 100644
index c945bd31609..00000000000
--- a/eval/src/tests/tensor/dense_remove_dimension_optimizer/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_remove_dimension_optimizer_test_app TEST
- SOURCES
- dense_remove_dimension_optimizer_test.cpp
- DEPENDS
- vespaeval
-)
-vespa_add_test(NAME eval_dense_remove_dimension_optimizer_test_app COMMAND eval_dense_remove_dimension_optimizer_test_app)
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
deleted file mode 100644
index 69910e27b4b..00000000000
--- a/eval/src/tests/tensor/dense_remove_dimension_optimizer/dense_remove_dimension_optimizer_test.cpp
+++ /dev/null
@@ -1,81 +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/dense_replace_type_function.h>
-#include <vespa/eval/tensor/dense/dense_fast_rename_optimizer.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();
-
-EvalFixture::ParamRepo make_params() {
- return EvalFixture::ParamRepo()
- .add("x1y5z1", spec({x(1),y(5),z(1)}, N()))
- .add("x1y5z1f", spec(float_cells({x(1),y(5),z(1)}), N()))
- .add("x1y1z1", spec({x(1),y(1),z(1)}, N()))
- .add("x1y5z_m", spec({x(1),y(5),z({"a"})}, N()));
-}
-EvalFixture::ParamRepo param_repo = make_params();
-
-void verify_optimized(const vespalib::string &expr) {
- EvalFixture fixture(prod_factory, expr, param_repo, true);
- EXPECT_EQUAL(fixture.result(), EvalFixture::ref(expr, param_repo));
- auto info = fixture.find_all<DenseReplaceTypeFunction>();
- EXPECT_EQUAL(info.size(), 1u);
-}
-
-void verify_not_optimized(const vespalib::string &expr) {
- EvalFixture fixture(prod_factory, expr, param_repo, true);
- EXPECT_EQUAL(fixture.result(), EvalFixture::ref(expr, param_repo));
- auto info = fixture.find_all<DenseReplaceTypeFunction>();
- EXPECT_TRUE(info.empty());
-}
-
-TEST("require that dimension removal can be optimized for appropriate aggregators") {
- TEST_DO(verify_optimized("reduce(x1y5z1,avg,x)"));
- TEST_DO(verify_not_optimized("reduce(x1y5z1,count,x)")); // NB
- TEST_DO(verify_optimized("reduce(x1y5z1,prod,x)"));
- TEST_DO(verify_optimized("reduce(x1y5z1,sum,x)"));
- TEST_DO(verify_optimized("reduce(x1y5z1,max,x)"));
- TEST_DO(verify_optimized("reduce(x1y5z1,min,x)"));
-}
-
-TEST("require that multi-dimension removal can be optimized") {
- TEST_DO(verify_optimized("reduce(x1y5z1,sum,x,z)"));
-}
-
-TEST("require that chained dimension removal can be optimized (and compacted)") {
- TEST_DO(verify_optimized("reduce(reduce(x1y5z1,sum,x),sum,z)"));
-}
-
-TEST("require that reducing non-trivial dimension is not optimized") {
- TEST_DO(verify_not_optimized("reduce(x1y5z1,sum,y)"));
- TEST_DO(verify_not_optimized("reduce(x1y5z1,sum,x,y)"));
- TEST_DO(verify_not_optimized("reduce(x1y5z1,sum,y,z)"));
-}
-
-TEST("require that full reduce is not optimized") {
- TEST_DO(verify_not_optimized("reduce(x1y1z1,sum)"));
- TEST_DO(verify_not_optimized("reduce(x1y1z1,sum,x,y,z)"));
-}
-
-TEST("require that inappropriate tensor types cannot be optimized") {
- TEST_DO(verify_not_optimized("reduce(x1y5z_m,sum,x)"));
- TEST_DO(verify_not_optimized("reduce(x1y5z_m,sum,z)"));
-}
-
-TEST("require that optimization works for float cells") {
- TEST_DO(verify_optimized("reduce(x1y5z1f,avg,x)"));
-}
-
-TEST_MAIN() { TEST_RUN_ALL(); }
diff --git a/eval/src/tests/tensor/dense_replace_type_function/CMakeLists.txt b/eval/src/tests/tensor/dense_replace_type_function/CMakeLists.txt
deleted file mode 100644
index dd4a8a58082..00000000000
--- a/eval/src/tests/tensor/dense_replace_type_function/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_replace_type_function_test_app TEST
- SOURCES
- dense_replace_type_function_test.cpp
- DEPENDS
- vespaeval
-)
-vespa_add_test(NAME eval_dense_replace_type_function_test_app COMMAND eval_dense_replace_type_function_test_app)
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
deleted file mode 100644
index 2612869e72f..00000000000
--- a/eval/src/tests/tensor/dense_replace_type_function/dense_replace_type_function_test.cpp
+++ /dev/null
@@ -1,77 +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/fast_value.h>
-#include <vespa/eval/eval/value_codec.h>
-#include <vespa/eval/eval/interpreted_function.h>
-#include <vespa/eval/tensor/dense/dense_replace_type_function.h>
-#include <vespa/eval/eval/test/tensor_model.hpp>
-
-using namespace vespalib::eval::tensor_function;
-using namespace vespalib::eval::test;
-using namespace vespalib::eval;
-using namespace vespalib::tensor;
-using namespace vespalib;
-
-const ValueBuilderFactory &prod_factory = FastValueBuilderFactory::get();
-
-TypedCells getCellsRef(const eval::Value &value) {
- return value.cells();
-}
-
-struct ChildMock : Leaf {
- bool is_mutable;
- ChildMock(const ValueType &type) : Leaf(type), is_mutable(true) {}
- bool result_is_mutable() const override { return is_mutable; }
- InterpretedFunction::Instruction compile_self(const ValueBuilderFactory &, Stash &) const override { abort(); }
-};
-
-struct Fixture {
- Value::UP my_value;
- ValueType new_type;
- ChildMock mock_child;
- DenseReplaceTypeFunction my_fun;
- std::vector<TensorFunction::Child::CREF> children;
- InterpretedFunction::State state;
- Fixture()
- : my_value(value_from_spec(spec({x(10)}, N()), prod_factory)),
- new_type(ValueType::from_spec("tensor(x[5],y[2])")),
- mock_child(my_value->type()),
- my_fun(new_type, mock_child),
- children(),
- state(prod_factory)
- {
- my_fun.push_children(children);
- state.stack.push_back(*my_value);
- my_fun.compile_self(prod_factory, state.stash).perform(state);
- ASSERT_EQUAL(children.size(), 1u);
- ASSERT_EQUAL(state.stack.size(), 1u);
- ASSERT_TRUE(!new_type.is_error());
- }
-};
-
-TEST_F("require that DenseReplaceTypeFunction works as expected", Fixture()) {
- EXPECT_EQUAL(f1.my_fun.result_type(), f1.new_type);
- EXPECT_EQUAL(f1.my_fun.result_is_mutable(), true);
- f1.mock_child.is_mutable = false;
- EXPECT_EQUAL(f1.my_fun.result_is_mutable(), false);
- EXPECT_EQUAL(&f1.children[0].get().get(), &f1.mock_child);
- EXPECT_EQUAL(getCellsRef(f1.state.stack[0]).data, getCellsRef(*f1.my_value).data);
- EXPECT_EQUAL(getCellsRef(f1.state.stack[0]).size, getCellsRef(*f1.my_value).size);
- EXPECT_EQUAL(f1.state.stack[0].get().type(), f1.new_type);
- fprintf(stderr, "%s\n", f1.my_fun.as_string().c_str());
-}
-
-TEST("require that create_compact will collapse duplicate replace operations") {
- Stash stash;
- ValueType type = ValueType::double_type();
- ChildMock leaf(type);
- const DenseReplaceTypeFunction &a = DenseReplaceTypeFunction::create_compact(type, leaf, stash);
- const DenseReplaceTypeFunction &b = DenseReplaceTypeFunction::create_compact(type, a, stash);
- EXPECT_EQUAL(a.result_type(), type);
- EXPECT_EQUAL(&a.child(), &leaf);
- EXPECT_EQUAL(b.result_type(), type);
- EXPECT_EQUAL(&b.child(), &leaf);
-}
-
-TEST_MAIN() { TEST_RUN_ALL(); }
diff --git a/eval/src/tests/tensor/dense_simple_join_function/CMakeLists.txt b/eval/src/tests/tensor/dense_simple_join_function/CMakeLists.txt
deleted file mode 100644
index 8a2df392145..00000000000
--- a/eval/src/tests/tensor/dense_simple_join_function/CMakeLists.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-# Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-vespa_add_executable(eval_dense_simple_join_function_test_app TEST
- SOURCES
- dense_simple_join_function_test.cpp
- DEPENDS
- vespaeval
-)
-vespa_add_test(NAME eval_dense_simple_join_function_test_app COMMAND eval_dense_simple_join_function_test_app)
diff --git a/eval/src/tests/tensor/dense_simple_join_function/dense_simple_join_function_test.cpp b/eval/src/tests/tensor/dense_simple_join_function/dense_simple_join_function_test.cpp
deleted file mode 100644
index 6ad60d2e3f5..00000000000
--- a/eval/src/tests/tensor/dense_simple_join_function/dense_simple_join_function_test.cpp
+++ /dev/null
@@ -1,225 +0,0 @@
-// Copyright Verizon Media. 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/dense_simple_join_function.h>
-#include <vespa/eval/eval/test/eval_fixture.h>
-#include <vespa/eval/eval/test/tensor_model.hpp>
-
-#include <vespa/vespalib/util/stringfmt.h>
-
-using namespace vespalib;
-using namespace vespalib::eval;
-using namespace vespalib::eval::test;
-using namespace vespalib::tensor;
-using namespace vespalib::eval::tensor_function;
-
-using vespalib::make_string_short::fmt;
-
-using Primary = DenseSimpleJoinFunction::Primary;
-using Overlap = DenseSimpleJoinFunction::Overlap;
-
-namespace vespalib::tensor {
-
-std::ostream &operator<<(std::ostream &os, Primary primary)
-{
- switch(primary) {
- case Primary::LHS: return os << "LHS";
- case Primary::RHS: return os << "RHS";
- }
- abort();
-}
-
-std::ostream &operator<<(std::ostream &os, Overlap overlap)
-{
- switch(overlap) {
- case Overlap::FULL: return os << "FULL";
- case Overlap::INNER: return os << "INNER";
- case Overlap::OUTER: return os << "OUTER";
- }
- abort();
-}
-
-}
-
-const ValueBuilderFactory &prod_factory = FastValueBuilderFactory::get();
-
-EvalFixture::ParamRepo make_params() {
- return EvalFixture::ParamRepo()
- .add("a", spec(1.5))
- .add("b", spec(2.5))
- .add("sparse", spec({x({"a"})}, N()))
- .add("mixed", spec({x({"a"}),y(5)}, N()))
- .add_cube("a", 1, "b", 1, "c", 1)
- .add_cube("x", 1, "y", 1, "z", 1)
- .add_cube("x", 3, "y", 5, "z", 3)
- .add_vector("x", 5)
- .add_dense({{"c", 5}, {"d", 1}})
- .add_dense({{"b", 1}, {"c", 5}})
- .add_matrix("x", 3, "y", 5, [](size_t idx) noexcept { return double((idx * 2) + 3); })
- .add_matrix("x", 3, "y", 5, [](size_t idx) noexcept { return double((idx * 3) + 2); })
- .add_vector("y", 5, [](size_t idx) noexcept { return double((idx * 2) + 3); })
- .add_vector("y", 5, [](size_t idx) noexcept { return double((idx * 3) + 2); })
- .add_matrix("y", 5, "z", 3, [](size_t idx) noexcept { return double((idx * 2) + 3); })
- .add_matrix("y", 5, "z", 3, [](size_t idx) noexcept { return double((idx * 3) + 2); });
-}
-EvalFixture::ParamRepo param_repo = make_params();
-
-void verify_optimized(const vespalib::string &expr, Primary primary, Overlap overlap, bool pri_mut, size_t factor, int p_inplace = -1) {
- EvalFixture slow_fixture(prod_factory, expr, param_repo, false);
- EvalFixture fixture(prod_factory, expr, param_repo, true, true);
- EXPECT_EQUAL(fixture.result(), EvalFixture::ref(expr, param_repo));
- EXPECT_EQUAL(fixture.result(), slow_fixture.result());
- auto info = fixture.find_all<DenseSimpleJoinFunction>();
- ASSERT_EQUAL(info.size(), 1u);
- EXPECT_TRUE(info[0]->result_is_mutable());
- EXPECT_EQUAL(info[0]->primary(), primary);
- EXPECT_EQUAL(info[0]->overlap(), overlap);
- EXPECT_EQUAL(info[0]->primary_is_mutable(), pri_mut);
- EXPECT_EQUAL(info[0]->factor(), factor);
- EXPECT_TRUE((p_inplace == -1) || (fixture.num_params() > size_t(p_inplace)));
- for (size_t i = 0; i < fixture.num_params(); ++i) {
- if (i == size_t(p_inplace)) {
- EXPECT_EQUAL(fixture.get_param(i), fixture.result());
- } else {
- EXPECT_NOT_EQUAL(fixture.get_param(i), fixture.result());
- }
- }
-}
-
-void verify_not_optimized(const vespalib::string &expr) {
- EvalFixture slow_fixture(prod_factory, expr, param_repo, false);
- EvalFixture fixture(prod_factory, expr, param_repo, true);
- EXPECT_EQUAL(fixture.result(), EvalFixture::ref(expr, param_repo));
- EXPECT_EQUAL(fixture.result(), slow_fixture.result());
- auto info = fixture.find_all<DenseSimpleJoinFunction>();
- EXPECT_TRUE(info.empty());
-}
-
-TEST("require that basic join is optimized") {
- TEST_DO(verify_optimized("y5+y5$2", Primary::RHS, Overlap::FULL, false, 1));
-}
-
-TEST("require that unit join is optimized") {
- TEST_DO(verify_optimized("a1b1c1+x1y1z1", Primary::RHS, Overlap::FULL, false, 1));
-}
-
-TEST("require that trivial dimensions do not affect overlap calculation") {
- TEST_DO(verify_optimized("c5d1+b1c5", Primary::RHS, Overlap::FULL, false, 1));
-}
-
-TEST("require that outer nesting is preferred to inner nesting") {
- TEST_DO(verify_optimized("a1b1c1+y5", Primary::RHS, Overlap::OUTER, false, 5));
-}
-
-TEST("require that non-subset join is not optimized") {
- TEST_DO(verify_not_optimized("x5+y5"));
-}
-
-TEST("require that subset join with complex overlap is not optimized") {
- TEST_DO(verify_not_optimized("x3y5z3+y5"));
-}
-
-struct LhsRhs {
- vespalib::string lhs;
- vespalib::string rhs;
- size_t lhs_size;
- size_t rhs_size;
- Overlap overlap;
- size_t factor;
- LhsRhs(const vespalib::string &lhs_in, const vespalib::string &rhs_in,
- size_t lhs_size_in, size_t rhs_size_in, Overlap overlap_in) noexcept
- : lhs(lhs_in), rhs(rhs_in), lhs_size(lhs_size_in), rhs_size(rhs_size_in), overlap(overlap_in), factor(1)
- {
- if (lhs_size > rhs_size) {
- ASSERT_EQUAL(lhs_size % rhs_size, 0u);
- factor = (lhs_size / rhs_size);
- } else {
- ASSERT_EQUAL(rhs_size % lhs_size, 0u);
- factor = (rhs_size / lhs_size);
- }
- }
-};
-
-vespalib::string adjust_param(const vespalib::string &str, bool float_cells, bool mut_cells, bool is_rhs) {
- vespalib::string result = str;
- if (mut_cells) {
- result = "@" + result;
- }
- if (float_cells) {
- result += "f";
- }
- if (is_rhs) {
- result += "$2";
- }
- return result;
-}
-
-TEST("require that various parameter combinations work") {
- for (bool left_float: {false, true}) {
- for (bool right_float: {false, true}) {
- bool float_result = (left_float && right_float);
- for (bool left_mut: {false, true}) {
- for (bool right_mut: {false, true}) {
- for (const char *op_pattern: {"%s+%s", "%s-%s", "%s*%s"}) {
- for (const LhsRhs &params:
- { LhsRhs("y5", "y5", 5, 5, Overlap::FULL),
- LhsRhs("y5", "x3y5", 5, 15, Overlap::INNER),
- LhsRhs("y5", "y5z3", 5, 15, Overlap::OUTER),
- LhsRhs("x3y5", "y5", 15, 5, Overlap::INNER),
- LhsRhs("y5z3", "y5", 15, 5, Overlap::OUTER)})
- {
- vespalib::string left = adjust_param(params.lhs, left_float, left_mut, false);
- vespalib::string right = adjust_param(params.rhs, right_float, right_mut, true);
- vespalib::string expr = fmt(op_pattern, left.c_str(), right.c_str());
- TEST_STATE(expr.c_str());
- Primary primary = Primary::RHS;
- if (params.overlap == Overlap::FULL) {
- bool w_lhs = ((left_float == float_result) && left_mut);
- bool w_rhs = ((right_float == float_result) && right_mut);
- if (w_lhs && !w_rhs) {
- primary = Primary::LHS;
- }
- } else if (params.lhs_size > params.rhs_size) {
- primary = Primary::LHS;
- }
- bool pri_mut = (primary == Primary::LHS) ? left_mut : right_mut;
- bool pri_float = (primary == Primary::LHS) ? left_float : right_float;
- int p_inplace = -1;
- if (pri_mut && (pri_float == float_result)) {
- p_inplace = (primary == Primary::LHS) ? 0 : 1;
- }
- verify_optimized(expr, primary, params.overlap, pri_mut, params.factor, p_inplace);
- }
- }
- }
- }
- }
- }
-}
-
-TEST("require that scalar values are not optimized") {
- TEST_DO(verify_not_optimized("a+b"));
- TEST_DO(verify_not_optimized("a+y5"));
- TEST_DO(verify_not_optimized("y5+b"));
- TEST_DO(verify_not_optimized("a+sparse"));
- TEST_DO(verify_not_optimized("sparse+a"));
- TEST_DO(verify_not_optimized("a+mixed"));
- TEST_DO(verify_not_optimized("mixed+a"));
-}
-
-TEST("require that mapped tensors are not optimized") {
- TEST_DO(verify_not_optimized("sparse+sparse"));
- TEST_DO(verify_not_optimized("sparse+y5"));
- TEST_DO(verify_not_optimized("y5+sparse"));
- TEST_DO(verify_not_optimized("sparse+mixed"));
- TEST_DO(verify_not_optimized("mixed+sparse"));
-}
-
-TEST("require mixed tensors are not optimized") {
- TEST_DO(verify_not_optimized("mixed+mixed"));
- TEST_DO(verify_not_optimized("mixed+y5"));
- TEST_DO(verify_not_optimized("y5+mixed"));
-}
-
-TEST_MAIN() { TEST_RUN_ALL(); }
diff --git a/eval/src/tests/tensor/dense_simple_map_function/CMakeLists.txt b/eval/src/tests/tensor/dense_simple_map_function/CMakeLists.txt
deleted file mode 100644
index 8d3bb8c92aa..00000000000
--- a/eval/src/tests/tensor/dense_simple_map_function/CMakeLists.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-# Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-vespa_add_executable(eval_dense_simple_map_function_test_app TEST
- SOURCES
- dense_simple_map_function_test.cpp
- DEPENDS
- vespaeval
- GTest::GTest
-)
-vespa_add_test(NAME eval_dense_simple_map_function_test_app COMMAND eval_dense_simple_map_function_test_app)
diff --git a/eval/src/tests/tensor/dense_simple_map_function/dense_simple_map_function_test.cpp b/eval/src/tests/tensor/dense_simple_map_function/dense_simple_map_function_test.cpp
deleted file mode 100644
index 53164ad59c8..00000000000
--- a/eval/src/tests/tensor/dense_simple_map_function/dense_simple_map_function_test.cpp
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-
-#include <vespa/eval/eval/tensor_function.h>
-#include <vespa/eval/tensor/dense/dense_simple_map_function.h>
-#include <vespa/eval/eval/test/eval_fixture.h>
-#include <vespa/eval/eval/test/tensor_model.hpp>
-#include <vespa/vespalib/gtest/gtest.h>
-
-using namespace vespalib;
-using namespace vespalib::eval;
-using namespace vespalib::eval::test;
-using namespace vespalib::eval::tensor_function;
-using namespace vespalib::tensor;
-
-const ValueBuilderFactory &prod_factory = FastValueBuilderFactory::get();
-
-EvalFixture::ParamRepo make_params() {
- return EvalFixture::ParamRepo()
- .add("a", spec(1.5))
- .add("b", spec(2.5))
- .add("sparse", spec({x({"a"})}, N()))
- .add("mixed", spec({x({"a"}),y(5)}, N()))
- .add_matrix("x", 5, "y", 3);
-}
-EvalFixture::ParamRepo param_repo = make_params();
-
-void verify_optimized(const vespalib::string &expr, bool inplace) {
- EvalFixture slow_fixture(prod_factory, expr, param_repo, false);
- EvalFixture fixture(prod_factory, expr, param_repo, true, true);
- EXPECT_EQ(fixture.result(), EvalFixture::ref(expr, param_repo));
- EXPECT_EQ(fixture.result(), slow_fixture.result());
- auto info = fixture.find_all<DenseSimpleMapFunction>();
- ASSERT_EQ(info.size(), 1u);
- EXPECT_TRUE(info[0]->result_is_mutable());
- EXPECT_EQ(info[0]->inplace(), inplace);
- ASSERT_EQ(fixture.num_params(), 1);
- if (inplace) {
- EXPECT_EQ(fixture.get_param(0), fixture.result());
- } else {
- EXPECT_TRUE(!(fixture.get_param(0) == fixture.result()));
- }
-}
-
-void verify_not_optimized(const vespalib::string &expr) {
- EvalFixture slow_fixture(prod_factory, expr, param_repo, false);
- EvalFixture fixture(prod_factory, expr, param_repo, true);
- EXPECT_EQ(fixture.result(), EvalFixture::ref(expr, param_repo));
- EXPECT_EQ(fixture.result(), slow_fixture.result());
- auto info = fixture.find_all<DenseSimpleMapFunction>();
- EXPECT_TRUE(info.empty());
-}
-
-TEST(MapTest, dense_map_is_optimized) {
- verify_optimized("map(x5y3,f(x)(x+10))", false);
- verify_optimized("map(x5y3f,f(x)(x+10))", false);
-}
-
-TEST(MapTest, simple_dense_map_can_be_inplace) {
- verify_optimized("map(@x5y3,f(x)(x+10))", true);
- verify_optimized("map(@x5y3f,f(x)(x+10))", true);
-}
-
-TEST(MapTest, scalar_map_is_not_optimized) {
- verify_not_optimized("map(a,f(x)(x+10))");
-}
-
-TEST(MapTest, sparse_map_is_not_optimized) {
- verify_not_optimized("map(sparse,f(x)(x+10))");
-}
-
-TEST(MapTest, mixed_map_is_not_optimized) {
- verify_not_optimized("map(mixed,f(x)(x+10))");
-}
-
-GTEST_MAIN_RUN_ALL_TESTS()
diff --git a/eval/src/tests/tensor/dense_single_reduce_function/CMakeLists.txt b/eval/src/tests/tensor/dense_single_reduce_function/CMakeLists.txt
deleted file mode 100644
index 42b00699c31..00000000000
--- a/eval/src/tests/tensor/dense_single_reduce_function/CMakeLists.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-# Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-vespa_add_executable(eval_dense_single_reduce_function_test_app TEST
- SOURCES
- dense_single_reduce_function_test.cpp
- DEPENDS
- vespaeval
-)
-vespa_add_test(NAME eval_dense_single_reduce_function_test_app COMMAND eval_dense_single_reduce_function_test_app)
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
deleted file mode 100644
index 347228269cf..00000000000
--- a/eval/src/tests/tensor/dense_single_reduce_function/dense_single_reduce_function_test.cpp
+++ /dev/null
@@ -1,170 +0,0 @@
-// Copyright Verizon Media. 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/eval/operation.h>
-#include <vespa/eval/tensor/dense/dense_single_reduce_function.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();
-
-EvalFixture::ParamRepo make_params() {
- return EvalFixture::ParamRepo()
- .add_dense({{"a", 2}, {"b", 3}, {"c", 4}, {"d", 5}})
- .add_dense({{"a", 9}, {"b", 9}, {"c", 9}, {"d", 9}})
- .add_cube("a", 2, "b", 1, "c", 1)
- .add_cube("a", 1, "b", 2, "c", 1)
- .add_cube("a", 1, "b", 1, "c", 2)
- .add_cube("a", 1, "b", 1, "c", 1)
- .add_vector("a", 10)
- .add("xy_mapped", spec({x({"a", "b"}),y({"x", "y"})}, N()))
- .add("xyz_mixed", spec({x({"a", "b"}),y({"x", "y"}),z(3)}, N()));
-}
-EvalFixture::ParamRepo param_repo = make_params();
-
-struct ReduceSpec {
- size_t outer_size;
- size_t reduce_size;
- size_t inner_size;
- Aggr aggr;
-};
-
-void verify_optimized_impl(const vespalib::string &expr, const std::vector<ReduceSpec> &spec_list) {
- EvalFixture slow_fixture(prod_factory, expr, param_repo, false);
- EvalFixture fixture(prod_factory, expr, param_repo, true);
- EXPECT_EQUAL(fixture.result(), EvalFixture::ref(expr, param_repo));
- EXPECT_EQUAL(fixture.result(), slow_fixture.result());
- auto info = fixture.find_all<DenseSingleReduceFunction>();
- ASSERT_EQUAL(info.size(), spec_list.size());
- for (size_t i = 0; i < spec_list.size(); ++i) {
- EXPECT_TRUE(info[i]->result_is_mutable());
- EXPECT_EQUAL(info[i]->outer_size(), spec_list[i].outer_size);
- EXPECT_EQUAL(info[i]->reduce_size(), spec_list[i].reduce_size);
- EXPECT_EQUAL(info[i]->inner_size(), spec_list[i].inner_size);
- EXPECT_EQUAL(int(info[i]->aggr()), int(spec_list[i].aggr));
- }
-}
-
-void verify_optimized(const vespalib::string &expr, const ReduceSpec &spec) {
- verify_optimized_impl(expr, {spec});
-}
-
-void verify_optimized(const vespalib::string &expr, const ReduceSpec &spec1, const ReduceSpec &spec2) {
- verify_optimized_impl(expr, {spec1, spec2});
-}
-
-void verify_not_optimized(const vespalib::string &expr) {
- EvalFixture slow_fixture(prod_factory, expr, param_repo, false);
- EvalFixture fixture(prod_factory, expr, param_repo, true);
- EXPECT_EQUAL(fixture.result(), EvalFixture::ref(expr, param_repo));
- EXPECT_EQUAL(fixture.result(), slow_fixture.result());
- auto info = fixture.find_all<DenseSingleReduceFunction>();
- EXPECT_TRUE(info.empty());
-}
-
-TEST("require that reduce to scalar is not optimized") {
- TEST_DO(verify_not_optimized("reduce(a10,sum,a)"));
- TEST_DO(verify_not_optimized("reduce(a10,sum)"));
-}
-
-TEST("require that sparse reduce is not optimized") {
- TEST_DO(verify_not_optimized("reduce(xy_mapped,sum,x)"));
- TEST_DO(verify_not_optimized("reduce(xy_mapped,sum,y)"));
-}
-
-TEST("require that mixed reduce is not optimized") {
- TEST_DO(verify_not_optimized("reduce(xyz_mixed,sum,x)"));
- TEST_DO(verify_not_optimized("reduce(xyz_mixed,sum,y)"));
- TEST_DO(verify_not_optimized("reduce(xyz_mixed,sum,z)"));
-}
-
-TEST("require that reducing trivial dimensions is not optimized") {
- TEST_DO(verify_not_optimized("reduce(a1b1c1,avg,c)"));
- TEST_DO(verify_not_optimized("reduce(a1b1c1,count,c)"));
- TEST_DO(verify_not_optimized("reduce(a1b1c1,prod,c)"));
- TEST_DO(verify_not_optimized("reduce(a1b1c1,sum,c)"));
- TEST_DO(verify_not_optimized("reduce(a1b1c1,max,c)"));
- TEST_DO(verify_not_optimized("reduce(a1b1c1,median,c)"));
- TEST_DO(verify_not_optimized("reduce(a1b1c1,min,c)"));
-}
-
-TEST("require that atleast_8 dense single reduce works") {
- TEST_DO(verify_optimized("reduce(a9b9c9d9,avg,a)", {1, 9, 729, Aggr::AVG}));
- TEST_DO(verify_optimized("reduce(a9b9c9d9,avg,b)", {9, 9, 81, Aggr::AVG}));
- TEST_DO(verify_optimized("reduce(a9b9c9d9,avg,c)", {81, 9, 9, Aggr::AVG}));
- TEST_DO(verify_optimized("reduce(a9b9c9d9,avg,d)", {729, 9, 1, Aggr::AVG}));
- TEST_DO(verify_optimized("reduce(a9b9c9d9,sum,c,d)", {81, 81, 1, Aggr::SUM}));
-}
-
-TEST("require that simple aggregators can be decomposed into multiple reduce operations") {
- TEST_DO(verify_optimized("reduce(a2b3c4d5,sum,a,c)", {3, 4, 5, Aggr::SUM}, {1, 2, 60, Aggr::SUM}));
- TEST_DO(verify_optimized("reduce(a2b3c4d5,min,a,c)", {3, 4, 5, Aggr::MIN}, {1, 2, 60, Aggr::MIN}));
- TEST_DO(verify_optimized("reduce(a2b3c4d5,max,a,c)", {3, 4, 5, Aggr::MAX}, {1, 2, 60, Aggr::MAX}));
-}
-
-TEST("require that reduce dimensions can be listed in reverse order") {
- TEST_DO(verify_optimized("reduce(a2b3c4d5,sum,c,a)", {3, 4, 5, Aggr::SUM}, {1, 2, 60, Aggr::SUM}));
- TEST_DO(verify_optimized("reduce(a2b3c4d5,min,c,a)", {3, 4, 5, Aggr::MIN}, {1, 2, 60, Aggr::MIN}));
- TEST_DO(verify_optimized("reduce(a2b3c4d5,max,c,a)", {3, 4, 5, Aggr::MAX}, {1, 2, 60, Aggr::MAX}));
-}
-
-TEST("require that non-simple aggregators cannot be decomposed into multiple reduce operations") {
- TEST_DO(verify_not_optimized("reduce(a2b3c4d5,avg,a,c)"));
- TEST_DO(verify_not_optimized("reduce(a2b3c4d5,count,a,c)"));
- TEST_DO(verify_not_optimized("reduce(a2b3c4d5,median,a,c)"));
-}
-
-vespalib::string make_expr(const vespalib::string &arg, const vespalib::string &dim, bool float_cells, Aggr aggr) {
- return make_string("reduce(%s%s,%s,%s)", arg.c_str(), float_cells ? "f" : "", AggrNames::name_of(aggr)->c_str(), dim.c_str());
-}
-
-void verify_optimized_multi(const vespalib::string &arg, const vespalib::string &dim, size_t outer_size, size_t reduce_size, size_t inner_size) {
- for (bool float_cells: {false, true}) {
- for (Aggr aggr: Aggregator::list()) {
- if (aggr != Aggr::PROD) {
- auto expr = make_expr(arg, dim, float_cells, aggr);
- TEST_DO(verify_optimized(expr, {outer_size, reduce_size, inner_size, aggr}));
- }
- }
- }
-}
-
-TEST("require that normal dense single reduce works") {
- TEST_DO(verify_optimized_multi("a2b3c4d5", "a", 1, 2, 60));
- TEST_DO(verify_optimized_multi("a2b3c4d5", "b", 2, 3, 20));
- TEST_DO(verify_optimized_multi("a2b3c4d5", "c", 6, 4, 5));
- TEST_DO(verify_optimized_multi("a2b3c4d5", "d", 24, 5, 1));
-}
-
-TEST("require that dimension-combined dense single reduce works") {
- TEST_DO(verify_optimized_multi("a2b3c4d5", "a,b", 1, 6, 20));
- TEST_DO(verify_optimized_multi("a2b3c4d5", "b,c", 2, 12, 5));
- TEST_DO(verify_optimized_multi("a2b3c4d5", "c,d", 6, 20, 1));
-}
-
-TEST("require that minimal dense single reduce works") {
- TEST_DO(verify_optimized_multi("a2b1c1", "a", 1, 2, 1));
- TEST_DO(verify_optimized_multi("a1b2c1", "b", 1, 2, 1));
- TEST_DO(verify_optimized_multi("a1b1c2", "c", 1, 2, 1));
-}
-
-TEST("require that trivial dimensions can be trivially reduced") {
- TEST_DO(verify_optimized_multi("a2b1c1", "a,b", 1, 2, 1));
- TEST_DO(verify_optimized_multi("a2b1c1", "a,c", 1, 2, 1));
- TEST_DO(verify_optimized_multi("a1b2c1", "b,a", 1, 2, 1));
- TEST_DO(verify_optimized_multi("a1b2c1", "b,c", 1, 2, 1));
- TEST_DO(verify_optimized_multi("a1b1c2", "c,a", 1, 2, 1));
- TEST_DO(verify_optimized_multi("a1b1c2", "c,b", 1, 2, 1));
-}
-
-TEST_MAIN() { TEST_RUN_ALL(); }
diff --git a/eval/src/tests/tensor/dense_tensor_create_function/CMakeLists.txt b/eval/src/tests/tensor/dense_tensor_create_function/CMakeLists.txt
deleted file mode 100644
index 883f331bda8..00000000000
--- a/eval/src/tests/tensor/dense_tensor_create_function/CMakeLists.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-# Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-vespa_add_executable(eval_dense_tensor_create_function_test_app TEST
- SOURCES
- dense_tensor_create_function_test.cpp
- DEPENDS
- vespaeval
-)
-vespa_add_test(NAME eval_dense_tensor_create_function_test_app COMMAND eval_dense_tensor_create_function_test_app)
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
deleted file mode 100644
index edf999e97b3..00000000000
--- a/eval/src/tests/tensor/dense_tensor_create_function/dense_tensor_create_function_test.cpp
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright 2019 Oath Inc. 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/dense_tensor_create_function.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();
-
-EvalFixture::ParamRepo make_params() {
- return EvalFixture::ParamRepo()
- .add("a", spec(1.0))
- .add("b", spec(2.0))
- .add("c", spec(3.0));
-}
-EvalFixture::ParamRepo param_repo = make_params();
-
-void verify(const vespalib::string &expr, size_t expect_optimized_cnt, size_t expect_not_optimized_cnt) {
- EvalFixture fixture(prod_factory, expr, param_repo, true);
- EXPECT_EQUAL(fixture.result(), EvalFixture::ref(expr, param_repo));
- auto info = fixture.find_all<DenseTensorCreateFunction>();
- EXPECT_EQUAL(info.size(), expect_optimized_cnt);
- for (size_t i = 0; i < info.size(); ++i) {
- EXPECT_TRUE(info[i]->result_is_mutable());
- }
- EXPECT_EQUAL(fixture.find_all<Create>().size(), expect_not_optimized_cnt);
-}
-
-//-----------------------------------------------------------------------------
-
-TEST("require that tensor create can be optimized") {
- TEST_DO(verify("tensor(x[3]):{{x:0}:1,{x:1}:2,{x:2}:3}", 0, 0)); // NB: const value
- TEST_DO(verify("tensor(x[3]):{{x:0}:a,{x:1}:b,{x:2}:c}", 1, 0));
- TEST_DO(verify("tensor<float>(x[3]):{{x:0}:a,{x:1}:b,{x:2}:c}", 1, 0));
- TEST_DO(verify("tensor(x[3]):{{x:0}:a+b,{x:1}:b-c,{x:2}:c*a}", 1, 0));
-}
-
-TEST("require that tensor create can be optimized with missing cells (padded with 0.0)") {
- TEST_DO(verify("tensor(x[3],y[5]):{{x:0,y:1}:a,{x:1,y:3}:b,{x:2,y:4}:c}", 1, 0));
-}
-
-TEST("require that tensor create in not optimized for sparse tensor") {
- TEST_DO(verify("tensor(x{}):{{x:0}:a,{x:1}:b,{x:2}:c}", 0, 1));
-}
-
-TEST("require that tensor create in not optimized for mixed tensor") {
- TEST_DO(verify("tensor(x{},y[3]):{{x:a,y:0}:a,{x:a,y:1}:b,{x:a,y:2}:c}", 0, 1));
-}
-
-TEST_MAIN() { TEST_RUN_ALL(); }
diff --git a/eval/src/tests/tensor/direct_sparse_tensor_builder/CMakeLists.txt b/eval/src/tests/tensor/direct_sparse_tensor_builder/CMakeLists.txt
deleted file mode 100644
index 00ff230fadd..00000000000
--- a/eval/src/tests/tensor/direct_sparse_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_sparse_tensor_builder_test_app TEST
- SOURCES
- direct_sparse_tensor_builder_test.cpp
- DEPENDS
- vespaeval
-)
-vespa_add_test(NAME eval_direct_sparse_tensor_builder_test_app COMMAND eval_direct_sparse_tensor_builder_test_app)
diff --git a/eval/src/tests/tensor/direct_sparse_tensor_builder/direct_sparse_tensor_builder_test.cpp b/eval/src/tests/tensor/direct_sparse_tensor_builder/direct_sparse_tensor_builder_test.cpp
deleted file mode 100644
index bcee6471f76..00000000000
--- a/eval/src/tests/tensor/direct_sparse_tensor_builder/direct_sparse_tensor_builder_test.cpp
+++ /dev/null
@@ -1,119 +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/testkit/test_kit.h>
-#include <vespa/eval/tensor/sparse/direct_sparse_tensor_builder.h>
-#include <vespa/eval/tensor/sparse/sparse_tensor_address_combiner.h>
-#include <vespa/vespalib/test/insertion_operators.h>
-
-using namespace vespalib::tensor;
-using namespace vespalib::tensor::sparse;
-using vespalib::eval::TensorSpec;
-using vespalib::eval::CellType;
-using vespalib::eval::ValueType;
-
-void
-assertCellValue(double expValue, const TensorAddress &address,
- const ValueType &type,
- const SparseTensor &tensor)
-{
- SparseTensorAddressBuilder addressBuilder;
- auto dimsItr = type.dimensions().cbegin();
- auto dimsItrEnd = type.dimensions().cend();
- for (const auto &element : address.elements()) {
- while ((dimsItr < dimsItrEnd) && (dimsItr->name < element.dimension())) {
- addressBuilder.add("");
- ++dimsItr;
- }
- assert((dimsItr != dimsItrEnd) && (dimsItr->name == element.dimension()));
- addressBuilder.add(element.label());
- ++dimsItr;
- }
- while (dimsItr < dimsItrEnd) {
- addressBuilder.add("");
- ++dimsItr;
- }
- SparseTensorAddressRef addressRef(addressBuilder.getAddressRef());
- size_t idx;
- bool found = tensor.index().lookup_address(addressRef, idx);
- EXPECT_TRUE(found);
- auto cells = tensor.cells();
- if (EXPECT_TRUE(cells.type == CellType::DOUBLE)) {
- auto arr = cells.typify<double>();
- EXPECT_EQUAL(expValue, arr[idx]);
- }
-}
-
-Tensor::UP
-buildTensor()
-{
- DirectSparseTensorBuilder<double> builder(ValueType::from_spec("tensor(a{},b{},c{},d{})"));
- SparseTensorAddressBuilder address;
- address.set({"1", "2", "", ""});
- builder.insertCell(address, 10);
- address.set({"", "", "3", "4"});
- builder.insertCell(address, 20);
- return builder.build();
-}
-
-TEST("require that tensor can be constructed")
-{
- Tensor::UP tensor = buildTensor();
- const SparseTensor &sparseTensor = dynamic_cast<const SparseTensor &>(*tensor);
- const ValueType &type = sparseTensor.type();
- const auto & index = sparseTensor.index();
- EXPECT_EQUAL(2u, index.size());
- assertCellValue(10, TensorAddress({{"a","1"},{"b","2"}}), type, sparseTensor);
- assertCellValue(20, TensorAddress({{"c","3"},{"d","4"}}), type, sparseTensor);
-}
-
-TEST("require that tensor can be converted to tensor spec")
-{
- Tensor::UP tensor = buildTensor();
- TensorSpec expSpec("tensor(a{},b{},c{},d{})");
- expSpec.add({{"a", "1"}, {"b", "2"}, {"c", ""}, {"d", ""}}, 10).
- add({{"a", ""},{"b",""},{"c", "3"}, {"d", "4"}}, 20);
- TensorSpec actSpec = tensor->toSpec();
- EXPECT_EQUAL(expSpec, actSpec);
-}
-
-TEST("require that dimensions are extracted")
-{
- Tensor::UP tensor = buildTensor();
- const SparseTensor &sparseTensor = dynamic_cast<const SparseTensor &>(*tensor);
- const auto &dims = sparseTensor.type().dimensions();
- EXPECT_EQUAL(4u, dims.size());
- EXPECT_EQUAL("a", dims[0].name);
- EXPECT_EQUAL("b", dims[1].name);
- EXPECT_EQUAL("c", dims[2].name);
- EXPECT_EQUAL("d", dims[3].name);
- EXPECT_EQUAL("tensor(a{},b{},c{},d{})", sparseTensor.type().to_spec());
-}
-
-void verifyAddressCombiner(const ValueType & a, const ValueType & b, size_t numDim, size_t numOverlapping) {
- TensorAddressCombiner combiner(a, b);
- EXPECT_EQUAL(numDim, combiner.numDimensions());
- EXPECT_EQUAL(numOverlapping, combiner.numOverlappingDimensions());
-}
-TEST("Test sparse tensor address combiner") {
- verifyAddressCombiner(ValueType::tensor_type({{"a"}}), ValueType::tensor_type({{"b"}}), 2, 0);
- verifyAddressCombiner(ValueType::tensor_type({{"a"}, {"b"}}), ValueType::tensor_type({{"b"}}), 2, 1);
- verifyAddressCombiner(ValueType::tensor_type({{"a"}, {"b"}}), ValueType::tensor_type({{"b"}, {"c"}}), 3, 1);
-
-}
-
-TEST("Test essential object sizes") {
- EXPECT_EQUAL(16u, sizeof(SparseTensorAddressRef));
- EXPECT_EQUAL(24u, sizeof(std::pair<SparseTensorAddressRef, double>));
- EXPECT_EQUAL(32u, sizeof(vespalib::hash_node<std::pair<SparseTensorAddressRef, double>>));
- Tensor::UP tensor = buildTensor();
- size_t used = tensor->get_memory_usage().usedBytes();
- EXPECT_GREATER(used, sizeof(SparseTensor));
- EXPECT_LESS(used, 10000u);
- size_t allocated = tensor->get_memory_usage().allocatedBytes();
- EXPECT_GREATER(allocated, used);
- EXPECT_LESS(allocated, 50000u);
- fprintf(stderr, "tensor using %zu bytes of %zu allocated\n",
- used, allocated);
-}
-
-TEST_MAIN() { TEST_RUN_ALL(); }
diff --git a/eval/src/tests/tensor/instruction_benchmark/instruction_benchmark.cpp b/eval/src/tests/tensor/instruction_benchmark/instruction_benchmark.cpp
index 618715a885f..aa1da07bc91 100644
--- a/eval/src/tests/tensor/instruction_benchmark/instruction_benchmark.cpp
+++ b/eval/src/tests/tensor/instruction_benchmark/instruction_benchmark.cpp
@@ -48,7 +48,6 @@
using namespace vespalib;
using namespace vespalib::eval;
-using namespace vespalib::tensor;
using namespace vespalib::eval::instruction;
using vespalib::make_string_short::fmt;
diff --git a/eval/src/tests/tensor/onnx_wrapper/onnx_wrapper_test.cpp b/eval/src/tests/tensor/onnx_wrapper/onnx_wrapper_test.cpp
index 7e204f1ea06..b474d2458b9 100644
--- a/eval/src/tests/tensor/onnx_wrapper/onnx_wrapper_test.cpp
+++ b/eval/src/tests/tensor/onnx_wrapper/onnx_wrapper_test.cpp
@@ -6,7 +6,6 @@
#include <vespa/vespalib/gtest/gtest.h>
using namespace vespalib::eval;
-using namespace vespalib::tensor;
using vespalib::make_string_short::fmt;
using TensorInfo = Onnx::TensorInfo;
diff --git a/eval/src/tests/tensor/tensor_address/tensor_address_test.cpp b/eval/src/tests/tensor/tensor_address/tensor_address_test.cpp
index c12b7071d02..a0a062c4322 100644
--- a/eval/src/tests/tensor/tensor_address/tensor_address_test.cpp
+++ b/eval/src/tests/tensor/tensor_address/tensor_address_test.cpp
@@ -3,8 +3,6 @@
#include <vespa/vespalib/testkit/test_kit.h>
#include <vespa/eval/tensor/tensor_address.h>
-using namespace vespalib::tensor;
-
void
assertSortOrder(const TensorAddress::Elements &exp,
const TensorAddress::Elements &input)
diff --git a/eval/src/tests/tensor/typed_cells/CMakeLists.txt b/eval/src/tests/tensor/typed_cells/CMakeLists.txt
deleted file mode 100644
index d57ff33eda6..00000000000
--- a/eval/src/tests/tensor/typed_cells/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_typed_cells_test_app TEST
- SOURCES
- typed_cells_test.cpp
- DEPENDS
- vespaeval
-)
-vespa_add_test(NAME eval_typed_cells_test_app COMMAND eval_typed_cells_test_app)
diff --git a/eval/src/tests/tensor/typed_cells/typed_cells_test.cpp b/eval/src/tests/tensor/typed_cells/typed_cells_test.cpp
deleted file mode 100644
index ccb522fd496..00000000000
--- a/eval/src/tests/tensor/typed_cells/typed_cells_test.cpp
+++ /dev/null
@@ -1,622 +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/testkit/test_kit.h>
-#include <vespa/vespalib/util/arrayref.h>
-#include <memory>
-
-using namespace vespalib;
-
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-// Low-level typed cells reference
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-
-enum class CellType : char { DOUBLE, FLOAT, INT };
-template <typename T> bool check_type(CellType type);
-template <> bool check_type<double>(CellType type) { return (type == CellType::DOUBLE); }
-template <> bool check_type<float>(CellType type) { return (type == CellType::FLOAT); }
-template <> bool check_type<int>(CellType type) { return (type == CellType::INT); }
-
-struct TypedCells {
- const void *data;
- CellType type;
- size_t size:56;
- explicit TypedCells(ConstArrayRef<double> cells) : data(cells.begin()), type(CellType::DOUBLE), size(cells.size()) {}
- explicit TypedCells(ConstArrayRef<float> cells) : data(cells.begin()), type(CellType::FLOAT), size(cells.size()) {}
- explicit TypedCells(ConstArrayRef<int> cells) : data(cells.begin()), type(CellType::INT), size(cells.size()) {}
- template <typename T> bool check_type() const { return ::check_type<T>(type); }
- template <typename T> ConstArrayRef<T> typify() const {
- assert(check_type<T>());
- return ConstArrayRef<T>((const T *)data, size);
- }
- template <typename T> ConstArrayRef<T> unsafe_typify() const {
- return ConstArrayRef<T>((const T *)data, size);
- }
-};
-
-TEST("require that structures are of expected size") {
- EXPECT_EQUAL(sizeof(void*), 8u);
- EXPECT_EQUAL(sizeof(size_t), 8u);
- EXPECT_EQUAL(sizeof(CellType), 1u);
- EXPECT_EQUAL(sizeof(TypedCells), 16u);
-}
-
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-// CASE STUDY: Direct dispatch, minimal runtime type resolving
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-
-struct CellwiseAdd {
- template <typename A, typename B, typename C>
- static void call(const ConstArrayRef<A> &a, const ConstArrayRef<B> &b, const ConstArrayRef<C> &c, size_t cnt) __attribute__ ((noinline));
-};
-
-template <typename A, typename B, typename C>
-void CellwiseAdd::call(const ConstArrayRef<A> &a, const ConstArrayRef<B> &b, const ConstArrayRef<C> &c, size_t cnt) {
- auto dst = unconstify(c);
- for (size_t i = 0; i < cnt; ++i) {
- dst[i] = a[i] + b[i];
- }
-}
-
-//-----------------------------------------------------------------------------
-
-struct DotProduct {
- template <typename A, typename B>
- static double call(const ConstArrayRef<A> &a, const ConstArrayRef<B> &b, size_t cnt) __attribute__ ((noinline));
-};
-
-template <typename A, typename B>
-double DotProduct::call(const ConstArrayRef<A> &a, const ConstArrayRef<B> &b, size_t cnt) {
- double result = 0.0;
- for (size_t i = 0; i < cnt; ++i) {
- result += (a[i] * b[i]);
- }
- return result;
-}
-
-//-----------------------------------------------------------------------------
-
-struct Sum {
- template <typename A>
- static double call(const ConstArrayRef<A> &a) __attribute__ ((noinline));
-};
-
-template <typename A>
-double Sum::call(const ConstArrayRef<A> &a) {
- double result = 0.0;
- for (const auto &value: a) {
- result += value;
- }
- return result;
-}
-
-//-----------------------------------------------------------------------------
-
-template <typename T>
-struct Typify {
- template <typename... Args>
- static auto typify_1(const TypedCells &a, Args &&...args) {
- switch(a.type) {
- case CellType::DOUBLE: return T::call(a.unsafe_typify<double>(), std::forward<Args>(args)...);
- case CellType::FLOAT: return T::call(a.unsafe_typify<float>(), std::forward<Args>(args)...);
- case CellType::INT: return T::call(a.unsafe_typify<int>(), std::forward<Args>(args)...);
- }
- abort();
- }
- template <typename A, typename... Args>
- static auto typify_2(A &&a, const TypedCells &b, Args &&...args) {
- switch(b.type) {
- case CellType::DOUBLE: return T::call(std::forward<A>(a), b.unsafe_typify<double>(), std::forward<Args>(args)...);
- case CellType::FLOAT: return T::call(std::forward<A>(a), b.unsafe_typify<float>(), std::forward<Args>(args)...);
- case CellType::INT: return T::call(std::forward<A>(a), b.unsafe_typify<int>(), std::forward<Args>(args)...);
- }
- abort();
- }
- template <typename A, typename B, typename... Args>
- static auto typify_3(A &&a, B &&b, const TypedCells &c, Args &&...args) {
- switch(c.type) {
- case CellType::DOUBLE: return T::call(std::forward<A>(a), std::forward<B>(b), c.unsafe_typify<double>(), std::forward<Args>(args)...);
- case CellType::FLOAT: return T::call(std::forward<A>(a), std::forward<B>(b), c.unsafe_typify<float>(), std::forward<Args>(args)...);
- case CellType::INT: return T::call(std::forward<A>(a), std::forward<B>(b), c.unsafe_typify<int>(), std::forward<Args>(args)...);
- }
- abort();
- }
-};
-
-template <typename Fun>
-struct Dispatch3 {
- using Self = Dispatch3<Fun>;
- template <typename A, typename B, typename C, typename... Args>
- static auto call(const ConstArrayRef<A> &a, const ConstArrayRef<B> &b, const ConstArrayRef<C> &c, Args &&...args) {
- return Fun::call(a, b, c, std::forward<Args>(args)...);
- }
- template <typename A, typename B, typename... Args>
- static auto call(const ConstArrayRef<A> &a, const ConstArrayRef<B> &b, const TypedCells &c, Args &&...args) {
- return Typify<Self>::typify_3(a, b, c, std::forward<Args>(args)...);
- }
- template <typename A, typename... Args>
- static auto call(const ConstArrayRef<A> &a, const TypedCells &b, const TypedCells &c, Args &&...args) {
- return Typify<Self>::typify_2(a, b, c, std::forward<Args>(args)...);
- }
- template <typename A, typename C, typename... Args>
- static auto call(const ConstArrayRef<A> &a, const TypedCells &b, const ConstArrayRef<C> &c, Args &&...args) {
- return Typify<Self>::typify_2(a, b, c, std::forward<Args>(args)...);
- }
- template <typename... Args>
- static auto call(const TypedCells &a, const TypedCells &b, const TypedCells &c, Args &&...args) {
- return Typify<Self>::typify_1(a, b, c, std::forward<Args>(args)...);
- }
- template <typename B, typename... Args>
- static auto call(const TypedCells &a, const ConstArrayRef<B> &b, const TypedCells &c, Args &&...args) {
- return Typify<Self>::typify_1(a, b, c, std::forward<Args>(args)...);
- }
- template <typename C, typename... Args>
- static auto call(const TypedCells &a, const TypedCells &b, const ConstArrayRef<C> &c, Args &&...args) {
- return Typify<Self>::typify_1(a, b, c, std::forward<Args>(args)...);
- }
- template <typename B, typename C, typename... Args>
- static auto call(const TypedCells &a, const ConstArrayRef<B> &b, const ConstArrayRef<C> &c, Args &&...args) {
- return Typify<Self>::typify_1(a, b, c, std::forward<Args>(args)...);
- }
-};
-
-template <typename Fun>
-struct Dispatch2 {
- using Self = Dispatch2<Fun>;
- template <typename A, typename B, typename... Args>
- static auto call(const ConstArrayRef<A> &a, const ConstArrayRef<B> &b, Args &&...args) {
- return Fun::call(a, b, std::forward<Args>(args)...);
- }
- template <typename A, typename... Args>
- static auto call(const ConstArrayRef<A> &a, const TypedCells &b, Args &&...args) {
- return Typify<Self>::typify_2(a, b, std::forward<Args>(args)...);
- }
- template <typename... Args>
- static auto call(const TypedCells &a, const TypedCells &b, Args &&...args) {
- return Typify<Self>::typify_1(a, b, std::forward<Args>(args)...);
- }
- template <typename B, typename... Args>
- static auto call(const TypedCells &a, const ConstArrayRef<B> &b, Args &&...args) {
- return Typify<Self>::typify_1(a, b, std::forward<Args>(args)...);
- }
-};
-
-template <typename Fun>
-struct Dispatch1 {
- using Self = Dispatch1<Fun>;
- template <typename A, typename... Args>
- static auto call(const ConstArrayRef<A> &a, Args &&...args) {
- return Fun::call(a, std::forward<Args>(args)...);
- }
- template <typename... Args>
- static auto call(const TypedCells &a, Args &&...args) {
- return Typify<Self>::typify_1(a, std::forward<Args>(args)...);
- }
-};
-
-//-----------------------------------------------------------------------------
-
-TEST("require that direct dispatch 'a op b -> c' works") {
- std::vector<int> a({1,2,3});
- std::vector<float> b({1.5,2.5,3.5});
- std::vector<double> c(3, 0.0);
- ConstArrayRef<int> a_ref(a);
- ConstArrayRef<float> b_ref(b);
- ConstArrayRef<double> c_ref(c);
- TypedCells a_cells(a);
- TypedCells b_cells(b);
- TypedCells c_cells(c);
-
- Dispatch3<CellwiseAdd>::call(a_cells, b_cells, c_cells, 3);
- Dispatch3<CellwiseAdd>::call(a_cells, b_ref, c_cells, 3);
- Dispatch3<CellwiseAdd>::call(a_cells, b_cells, c_ref, 3);
- Dispatch3<CellwiseAdd>::call(a_cells, b_ref, c_ref, 3);
- Dispatch3<CellwiseAdd>::call(a_ref, b_cells, c_cells, 3);
- Dispatch3<CellwiseAdd>::call(a_ref, b_cells, c_ref, 3);
- Dispatch3<CellwiseAdd>::call(a_ref, b_ref, c_cells, 3);
- Dispatch3<CellwiseAdd>::call(a_ref, b_ref, c_ref, 3);
-
- EXPECT_EQUAL(c[0], 2.5);
- EXPECT_EQUAL(c[1], 4.5);
- EXPECT_EQUAL(c[2], 6.5);
-}
-
-TEST("require that direct dispatch 'dot product' with return value works") {
- std::vector<int> a({1,2,3});
- std::vector<float> b({1.5,2.5,3.5});
- ConstArrayRef<int> a_ref(a);
- ConstArrayRef<float> b_ref(b);
- TypedCells a_cells(a);
- TypedCells b_cells(b);
- double expect = 1.5 + (2 * 2.5) + (3 * 3.5);
-
- EXPECT_EQUAL(expect, Dispatch2<DotProduct>::call(a_cells, b_cells, 3));
- EXPECT_EQUAL(expect, Dispatch2<DotProduct>::call(a_cells, b_ref, 3));
- EXPECT_EQUAL(expect, Dispatch2<DotProduct>::call(a_ref, b_cells, 3));
- EXPECT_EQUAL(expect, Dispatch2<DotProduct>::call(a_ref, b_ref, 3));
-}
-
-TEST("require that direct dispatch 'sum' with return value works") {
- std::vector<int> a({1,2,3});
- ConstArrayRef<int> a_ref(a);
- TypedCells a_cells(a);
- double expect = (1 + 2 + 3);
-
- EXPECT_EQUAL(expect, Dispatch1<Sum>::call(a_cells));
- EXPECT_EQUAL(expect, Dispatch1<Sum>::call(a_ref));
-}
-
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-// CASE STUDY: Pre-resolved templated subclass
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-
-struct CellwiseAdd2 {
- virtual void call(const TypedCells &a, const TypedCells &b, const TypedCells &c, size_t cnt) const = 0;
- template <typename A, typename B, typename C>
- static std::unique_ptr<CellwiseAdd2> create();
- virtual ~CellwiseAdd2() {}
-};
-
-template <typename A, typename B, typename C>
-struct CellwiseAdd2Impl : CellwiseAdd2 {
- void call_impl(const ConstArrayRef<A> &a, const ConstArrayRef<B> &b, const ConstArrayRef<C> &c, size_t cnt) const {
- auto dst = unconstify(c);
- for (size_t i = 0; i < cnt; ++i) {
- dst[i] = a[i] + b[i];
- }
- }
- void call(const TypedCells &a, const TypedCells &b, const TypedCells &c, size_t cnt) const override {
- call_impl(a.unsafe_typify<A>(), b.unsafe_typify<B>(), c.unsafe_typify<C>(), cnt);
- }
-};
-
-template <typename A, typename B, typename C>
-std::unique_ptr<CellwiseAdd2> CellwiseAdd2::create() {
- return std::make_unique<CellwiseAdd2Impl<A, B, C> >();
-}
-
-//-----------------------------------------------------------------------------
-
-struct DotProduct2 {
- virtual double call(const TypedCells &a, const TypedCells &b, size_t cnt) const = 0;
- template <typename A, typename B>
- static std::unique_ptr<DotProduct2> create();
- virtual ~DotProduct2() {}
-};
-
-template <typename A, typename B>
-struct DotProduct2Impl : DotProduct2 {
- double call_impl(const ConstArrayRef<A> &a, const ConstArrayRef<B> &b, size_t cnt) const {
- double result = 0.0;
- for (size_t i = 0; i < cnt; ++i) {
- result += (a[i] * b[i]);
- }
- return result;
- }
- double call(const TypedCells &a, const TypedCells &b, size_t cnt) const override {
- return call_impl(a.unsafe_typify<A>(), b.unsafe_typify<B>(), cnt);
- }
-};
-
-template <typename A, typename B>
-std::unique_ptr<DotProduct2> DotProduct2::create() {
- return std::make_unique<DotProduct2Impl<A, B> >();
-}
-
-//-----------------------------------------------------------------------------
-
-struct Sum2 {
- virtual double call(const TypedCells &a) const = 0;
- template <typename A>
- static std::unique_ptr<Sum2> create();
- virtual ~Sum2() {}
-};
-
-template <typename A>
-struct Sum2Impl : Sum2 {
- double call_impl(const ConstArrayRef<A> &a) const {
- double result = 0.0;
- for (const auto &value: a) {
- result += value;
- }
- return result;
- }
- double call(const TypedCells &a) const override {
- return call_impl(a.unsafe_typify<A>());
- }
-};
-
-template <typename A>
-std::unique_ptr<Sum2> Sum2::create() {
- return std::make_unique<Sum2Impl<A> >();
-}
-
-//-----------------------------------------------------------------------------
-
-template <typename T, typename... Args>
-std::unique_ptr<T> create(CellType a_type) {
- switch(a_type) {
- case CellType::DOUBLE: return T::template create<double, Args...>();
- case CellType::FLOAT: return T::template create<float, Args...>();
- case CellType::INT: return T::template create<int, Args...>();
- }
- abort();
-}
-
-template <typename T, typename... Args>
-std::unique_ptr<T> create(CellType a_type, CellType b_type) {
- switch(b_type) {
- case CellType::DOUBLE: return create<T, double, Args...>(a_type);
- case CellType::FLOAT: return create<T, float, Args...>(a_type);
- case CellType::INT: return create<T, int, Args...>(a_type);
- }
- abort();
-}
-
-template <typename T>
-std::unique_ptr<T> create(CellType a_type, CellType b_type, CellType c_type) {
- switch(c_type) {
- case CellType::DOUBLE: return create<T, double>(a_type, b_type);
- case CellType::FLOAT: return create<T, float>(a_type, b_type);
- case CellType::INT: return create<T, int>(a_type, b_type);
- }
- abort();
-}
-
-//-----------------------------------------------------------------------------
-
-TEST("require that pre-resolved subclass 'a op b -> c' works") {
- std::vector<int> a({1,2,3});
- std::vector<float> b({1.5,2.5,3.5});
- std::vector<double> c(3, 0.0);
- TypedCells a_cells(a);
- TypedCells b_cells(b);
- TypedCells c_cells(c);
-
- auto op = create<CellwiseAdd2>(a_cells.type, b_cells.type, c_cells.type);
- op->call(a_cells, b_cells, c_cells, 3);
-
- EXPECT_EQUAL(c[0], 2.5);
- EXPECT_EQUAL(c[1], 4.5);
- EXPECT_EQUAL(c[2], 6.5);
-}
-
-TEST("require that pre-resolved subclass 'dot product' with return value works") {
- std::vector<int> a({1,2,3});
- std::vector<float> b({1.5,2.5,3.5});
- TypedCells a_cells(a);
- TypedCells b_cells(b);
- double expect = 1.5 + (2 * 2.5) + (3 * 3.5);
-
- auto op = create<DotProduct2>(a_cells.type, b_cells.type);
-
- EXPECT_EQUAL(expect, op->call(a_cells, b_cells, 3));
-}
-
-TEST("require that pre-resolved subclass 'sum' with return value works") {
- std::vector<int> a({1,2,3});
- TypedCells a_cells(a);
- double expect = (1 + 2 + 3);
-
- auto op = create<Sum2>(a_cells.type);
-
- EXPECT_EQUAL(expect, op->call(a_cells));
-}
-
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-// CASE STUDY: self-updating cached function pointer
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-
-template <typename T, typename... Args>
-auto get_fun(CellType a_type) {
- switch(a_type) {
- case CellType::DOUBLE: return T::template get_fun<double, Args...>();
- case CellType::FLOAT: return T::template get_fun<float, Args...>();
- case CellType::INT: return T::template get_fun<int, Args...>();
- }
- abort();
-}
-
-template <typename T, typename... Args>
-auto get_fun(CellType a_type, CellType b_type) {
- switch(b_type) {
- case CellType::DOUBLE: return get_fun<T, double, Args...>(a_type);
- case CellType::FLOAT: return get_fun<T, float, Args...>(a_type);
- case CellType::INT: return get_fun<T, int, Args...>(a_type);
- }
- abort();
-}
-
-template <typename T>
-auto get_fun(CellType a_type, CellType b_type, CellType c_type) {
- switch(c_type) {
- case CellType::DOUBLE: return get_fun<T, double>(a_type, b_type);
- case CellType::FLOAT: return get_fun<T, float>(a_type, b_type);
- case CellType::INT: return get_fun<T, int>(a_type, b_type);
- }
- abort();
-}
-
-//-----------------------------------------------------------------------------
-
-struct CellwiseAdd3 {
- struct Self;
- using fun_type = void (*)(const TypedCells &x, const TypedCells &y, const TypedCells &z, size_t cnt, Self &self);
- template <typename A, typename B, typename C>
- static fun_type get_fun();
- struct Self {
- fun_type my_fun;
- Self();
- };
- Self self;
- void call(const TypedCells &x, const TypedCells &y, const TypedCells &z, size_t cnt) {
- self.my_fun(x, y, z, cnt, self);
- }
-};
-
-template <typename A, typename B, typename C>
-void cellwise_add(const TypedCells &x, const TypedCells &y, const TypedCells &z, size_t cnt, CellwiseAdd3::Self &self) {
- if (!x.check_type<A>() || !y.check_type<B>() || !z.check_type<C>()) {
- auto new_fun = get_fun<CellwiseAdd3>(x.type, y.type, z.type);
- self.my_fun = new_fun;
- return new_fun(x, y, z, cnt, self);
- }
- auto a = x.unsafe_typify<A>();
- auto b = y.unsafe_typify<B>();
- auto c = z.unsafe_typify<C>();
- auto dst = unconstify(c);
- for (size_t i = 0; i < cnt; ++i) {
- dst[i] = a[i] + b[i];
- }
-};
-
-template <typename A, typename B, typename C>
-CellwiseAdd3::fun_type CellwiseAdd3::get_fun() {
- return cellwise_add<A, B, C>;
-}
-
-CellwiseAdd3::Self::Self()
- : my_fun(cellwise_add<double, double, double>)
-{
-}
-
-//-----------------------------------------------------------------------------
-
-struct DotProduct3 {
- struct Self;
- using fun_type = double (*)(const TypedCells &x, const TypedCells &y, size_t cnt, Self &self);
- template <typename A, typename B>
- static fun_type get_fun();
- struct Self {
- fun_type my_fun;
- Self();
- };
- Self self;
- double call(const TypedCells &x, const TypedCells &y, size_t cnt) {
- return self.my_fun(x, y, cnt, self);
- }
-};
-
-template <typename A, typename B>
-double dot_product(const TypedCells &x, const TypedCells &y, size_t cnt, DotProduct3::Self &self) {
- if (!x.check_type<A>() || !y.check_type<B>()) {
- auto new_fun = get_fun<DotProduct3>(x.type, y.type);
- self.my_fun = new_fun;
- return new_fun(x, y, cnt, self);
- }
- auto a = x.unsafe_typify<A>();
- auto b = y.unsafe_typify<B>();
- double result = 0.0;
- for (size_t i = 0; i < cnt; ++i) {
- result += (a[i] * b[i]);
- }
- return result;
-}
-
-template <typename A, typename B>
-DotProduct3::fun_type DotProduct3::get_fun() {
- return dot_product<A, B>;
-}
-
-DotProduct3::Self::Self()
- : my_fun(dot_product<double, double>)
-{
-}
-
-//-----------------------------------------------------------------------------
-
-struct Sum3 {
- struct Self;
- using fun_type = double (*)(const TypedCells &x, Self &self);
- template <typename A>
- static fun_type get_fun();
- struct Self {
- fun_type my_fun;
- Self();
- };
- Self self;
- double call(const TypedCells &x) {
- return self.my_fun(x, self);
- }
-};
-
-template <typename A>
-double sum(const TypedCells &x, Sum3::Self &self) {
- if (!x.check_type<A>()) {
- auto new_fun = get_fun<Sum3>(x.type);
- self.my_fun = new_fun;
- return new_fun(x, self);
- }
- auto a = x.unsafe_typify<A>();
- double result = 0.0;
- for (const auto &value: a) {
- result += value;
- }
- return result;
-}
-
-template <typename A>
-Sum3::fun_type Sum3::get_fun() {
- return sum<A>;
-}
-
-Sum3::Self::Self()
- : my_fun(sum<double>)
-{
-}
-
-//-----------------------------------------------------------------------------
-
-TEST("require that self-updating cached function pointer 'a op b -> c' works") {
- std::vector<int> a({1,2,3});
- std::vector<float> b({1.5,2.5,3.5});
- std::vector<double> c(3, 0.0);
- TypedCells a_cells(a);
- TypedCells b_cells(b);
- TypedCells c_cells(c);
-
- CellwiseAdd3 op;
- EXPECT_EQUAL(op.self.my_fun, (&cellwise_add<double,double,double>));
- op.call(a_cells, b_cells, c_cells, 3);
- EXPECT_EQUAL(op.self.my_fun, (&cellwise_add<int,float,double>));
- EXPECT_NOT_EQUAL(op.self.my_fun, (&cellwise_add<double,double,double>));
-
- EXPECT_EQUAL(c[0], 2.5);
- EXPECT_EQUAL(c[1], 4.5);
- EXPECT_EQUAL(c[2], 6.5);
-}
-
-TEST("require that self-updating cached function pointer 'dot product' with return value works") {
- std::vector<int> a({1,2,3});
- std::vector<float> b({1.5,2.5,3.5});
- TypedCells a_cells(a);
- TypedCells b_cells(b);
- double expect = 1.5 + (2 * 2.5) + (3 * 3.5);
-
- DotProduct3 op;
- EXPECT_EQUAL(op.self.my_fun, (&dot_product<double,double>));
- EXPECT_EQUAL(expect, op.call(a_cells, b_cells, 3));
- EXPECT_EQUAL(op.self.my_fun, (&dot_product<int,float>));
- EXPECT_NOT_EQUAL(op.self.my_fun, (&dot_product<double,double>));
-}
-
-TEST("require that self-updating cached function pointer 'sum' with return value works") {
- std::vector<int> a({1,2,3});
- TypedCells a_cells(a);
- double expect = (1 + 2 + 3);
-
- Sum3 op;
- EXPECT_EQUAL(op.self.my_fun, (&sum<double>));
- EXPECT_EQUAL(expect, op.call(a_cells));
- EXPECT_EQUAL(op.self.my_fun, (&sum<int>));
- EXPECT_NOT_EQUAL(op.self.my_fun, (&sum<double>));
-}
-
-TEST_MAIN() { TEST_RUN_ALL(); }
diff --git a/eval/src/tests/tensor/vector_from_doubles_function/CMakeLists.txt b/eval/src/tests/tensor/vector_from_doubles_function/CMakeLists.txt
deleted file mode 100644
index 5b2e47ec498..00000000000
--- a/eval/src/tests/tensor/vector_from_doubles_function/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_vector_from_doubles_function_test_app TEST
- SOURCES
- vector_from_doubles_function_test.cpp
- DEPENDS
- vespaeval
-)
-vespa_add_test(NAME eval_vector_from_doubles_function_test_app COMMAND eval_vector_from_doubles_function_test_app)
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
deleted file mode 100644
index c3e1f2f248e..00000000000
--- a/eval/src/tests/tensor/vector_from_doubles_function/vector_from_doubles_function_test.cpp
+++ /dev/null
@@ -1,59 +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/testkit/test_kit.h>
-#include <vespa/eval/eval/tensor_function.h>
-#include <vespa/eval/tensor/dense/vector_from_doubles_function.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();
-
-EvalFixture::ParamRepo make_params() {
- return EvalFixture::ParamRepo()
- .add("a", spec(1.0))
- .add("b", spec(2.0))
- .add("c", spec(3.0))
- .add("d", spec(4.0))
- .add("x5", spec({x(5)}, N()));
-}
-EvalFixture::ParamRepo param_repo = make_params();
-
-void verify(const vespalib::string &expr, size_t expect_optimized_cnt, size_t expect_not_optimized_cnt) {
- EvalFixture fixture(prod_factory, expr, param_repo, true);
- EXPECT_EQUAL(fixture.result(), EvalFixture::ref(expr, param_repo));
- auto info = fixture.find_all<VectorFromDoublesFunction>();
- EXPECT_EQUAL(info.size(), expect_optimized_cnt);
- for (size_t i = 0; i < info.size(); ++i) {
- EXPECT_TRUE(info[i]->result_is_mutable());
- }
- EXPECT_EQUAL(fixture.find_all<Concat>().size(), expect_not_optimized_cnt);
-}
-
-//-----------------------------------------------------------------------------
-
-TEST("require that multiple concats are optimized") {
- TEST_DO(verify("concat(a,b,x)", 1, 0));
- TEST_DO(verify("concat(a,concat(b,concat(c,d,x),x),x)", 1, 0));
- TEST_DO(verify("concat(concat(concat(a,b,x),c,x),d,x)", 1, 0));
- TEST_DO(verify("concat(concat(a,b,x),concat(c,d,x),x)", 1, 0));
-}
-
-TEST("require that concat along different dimension is not optimized") {
- TEST_DO(verify("concat(concat(a,b,x),concat(c,d,x),y)", 2, 1));
-}
-
-TEST("require that concat of vector and double is not optimized") {
- TEST_DO(verify("concat(a,x5,x)", 0, 1));
- TEST_DO(verify("concat(x5,b,x)", 0, 1));
-}
-
-TEST_MAIN() { TEST_RUN_ALL(); }