diff options
author | Arne Juul <arnej@yahoo-inc.com> | 2019-06-27 08:48:33 +0000 |
---|---|---|
committer | Arne Juul <arnej@yahoo-inc.com> | 2019-07-04 11:49:32 +0000 |
commit | 5a993bc1a9272281e41ca220ee117d0f8d3081d8 (patch) | |
tree | f466bc6ec9e203a12973cfcb66cef49171f0fb75 /eval/src/tests | |
parent | eb95248e0f4e89e59e8af64efdcfc0388529b832 (diff) |
add TypedCells and related functionality
* templated DenseTensor
* templated DenseTensorModify
* add templated TypedDenseTensorBuilder
* remove DirectDenseTensorBuilder
* remove unused TensorMapper
* add dispatch structs
* add unit test for generic dense join
* add special handling of reducing all dimensions
Diffstat (limited to 'eval/src/tests')
7 files changed, 176 insertions, 236 deletions
diff --git a/eval/src/tests/tensor/dense_generic_join/CMakeLists.txt b/eval/src/tests/tensor/dense_generic_join/CMakeLists.txt new file mode 100644 index 00000000000..1fbb35cb2b8 --- /dev/null +++ b/eval/src/tests/tensor/dense_generic_join/CMakeLists.txt @@ -0,0 +1,8 @@ +# Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +vespa_add_executable(eval_dense_generic_join_test_app TEST + SOURCES + dense_generic_join_test.cpp + DEPENDS + vespaeval +) +vespa_add_test(NAME eval_dense_generic_join_test_app COMMAND eval_dense_generic_join_test_app) diff --git a/eval/src/tests/tensor/dense_generic_join/dense_generic_join_test.cpp b/eval/src/tests/tensor/dense_generic_join/dense_generic_join_test.cpp new file mode 100644 index 00000000000..395437e13dd --- /dev/null +++ b/eval/src/tests/tensor/dense_generic_join/dense_generic_join_test.cpp @@ -0,0 +1,127 @@ +// 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/simple_tensor.h> +#include <vespa/eval/eval/simple_tensor_engine.h> +#include <vespa/eval/tensor/default_tensor_engine.h> +#include <vespa/eval/tensor/dense/typed_dense_tensor_builder.h> +#include <vespa/eval/tensor/dense/dense_tensor.h> +#include <vespa/eval/eval/test/tensor_model.hpp> +#include <vespa/eval/eval/test/eval_fixture.h> + +#include <vespa/vespalib/util/stringfmt.h> +#include <vespa/vespalib/util/stash.h> + +using namespace vespalib; +using namespace vespalib::eval; +using namespace vespalib::eval::test; +using namespace vespalib::tensor; +using namespace vespalib::eval::tensor_function; + +const TensorEngine &prod_engine = DefaultTensorEngine::ref(); + +double seq_value = 0.0; + +struct GlobalSequence : public Sequence { + GlobalSequence() {} + double operator[](size_t) const override { + seq_value += 1.0; + return seq_value; + } + ~GlobalSequence() {} +}; +GlobalSequence seq; + +EvalFixture::ParamRepo make_params() { + return EvalFixture::ParamRepo() + .add("con_x5_A", spec({x(5) }, seq)) + .add("con_x5y3_B", spec({x(5),y(3) }, seq)) + .add("con_x5z4_C", spec({x(5), z(4)}, seq)) + .add("con_x5y3z4_D", spec({x(5),y(3),z(4)}, seq)) + .add("con_y3_E", spec({ y(3) }, seq)) + .add("con_y3z4_F", spec({ y(3),z(4)}, seq)) + .add("con_z4_G", spec({ z(4)}, seq)) + .add("con_x5f_H", spec({x(5) }, seq), "tensor<float>(x[5])") + .add("con_x5y3_I", spec({x(5),y(3) }, seq), "tensor<float>(x[5],y[3])") + .add("con_x5z4_J", spec({x(5), z(4)}, seq), "tensor<float>(x[5],z[4])") + .add("con_x5y3z4_K", spec({x(5),y(3),z(4)}, seq), "tensor<float>(x[5],y[3],z[4])") + .add("con_y3_L", spec({ y(3) }, seq), "tensor<float>(y[3])") + .add("con_y3z4_M", spec({ y(3),z(4)}, seq), "tensor<float>(y[3],z[4])))") + .add("con_z4_N", spec({ z(4)}, seq), "tensor<float>(z[4]))") + .add("con_y2", spec({y(5)}, seq)) + .add("con_y2f", spec({y(5)}, seq), "tensor<float>(y[2]))"); +} +EvalFixture::ParamRepo param_repo = make_params(); + +void verify_equal(const vespalib::string &expr) { + EvalFixture fixture(prod_engine, expr, param_repo, true, true); + EXPECT_EQUAL(fixture.result(), EvalFixture::ref(expr, param_repo)); +} + + +TEST("require that non-overlapping dense join works") { + TEST_DO(verify_equal("con_x5_A-con_y3_E")); + TEST_DO(verify_equal("con_x5_A+con_y3_E")); + TEST_DO(verify_equal("con_x5_A*con_y3_E")); + + TEST_DO(verify_equal("con_x5_A-con_y3z4_F")); + TEST_DO(verify_equal("con_x5_A+con_y3z4_F")); + TEST_DO(verify_equal("con_x5_A*con_y3z4_F")); + + TEST_DO(verify_equal("con_x5_A-con_z4_G")); + TEST_DO(verify_equal("con_x5_A+con_z4_G")); + TEST_DO(verify_equal("con_x5_A*con_z4_G")); + + TEST_DO(verify_equal("con_x5y3_B-con_z4_G")); + TEST_DO(verify_equal("con_x5y3_B+con_z4_G")); + TEST_DO(verify_equal("con_x5y3_B*con_z4_G")); + + TEST_DO(verify_equal("con_y3_E-con_z4_G")); + TEST_DO(verify_equal("con_y3_E+con_z4_G")); + TEST_DO(verify_equal("con_y3_E*con_z4_G")); +} + +TEST("require that overlapping dense join works") { + TEST_DO(verify_equal("con_x5_A-con_x5y3_B")); + TEST_DO(verify_equal("con_x5_A+con_x5y3_B")); + TEST_DO(verify_equal("con_x5_A*con_x5y3_B")); + + TEST_DO(verify_equal("con_x5_A-con_x5z4_C")); + TEST_DO(verify_equal("con_x5_A+con_x5z4_C")); + TEST_DO(verify_equal("con_x5_A*con_x5z4_C")); + + TEST_DO(verify_equal("con_x5y3_B-con_y3_E")); + TEST_DO(verify_equal("con_x5y3_B+con_y3_E")); + TEST_DO(verify_equal("con_x5y3_B*con_y3_E")); + + TEST_DO(verify_equal("con_x5y3_B-con_y3z4_F")); + TEST_DO(verify_equal("con_x5y3_B+con_y3z4_F")); + TEST_DO(verify_equal("con_x5y3_B*con_y3z4_F")); + + TEST_DO(verify_equal("con_x5y3z4_D-con_x5y3_B")); + TEST_DO(verify_equal("con_x5y3z4_D+con_x5y3_B")); + TEST_DO(verify_equal("con_x5y3z4_D*con_x5y3_B")); + + TEST_DO(verify_equal("con_x5y3z4_D-con_x5z4_C")); + TEST_DO(verify_equal("con_x5y3z4_D+con_x5z4_C")); + TEST_DO(verify_equal("con_x5y3z4_D*con_x5z4_C")); + + TEST_DO(verify_equal("con_x5y3z4_D-con_y3z4_F")); + TEST_DO(verify_equal("con_x5y3z4_D+con_y3z4_F")); + TEST_DO(verify_equal("con_x5y3z4_D*con_y3z4_F")); + + TEST_DO(verify_equal("con_x5y3z4_D-con_y3z4_F")); + TEST_DO(verify_equal("con_x5y3z4_D+con_y3z4_F")); + TEST_DO(verify_equal("con_x5y3z4_D*con_y3z4_F")); + + TEST_DO(verify_equal("con_y3_E-con_y3z4_F")); + TEST_DO(verify_equal("con_y3_E+con_y3z4_F")); + TEST_DO(verify_equal("con_y3_E*con_y3z4_F")); + + TEST_DO(verify_equal("con_y3z4_F-con_z4_G")); + TEST_DO(verify_equal("con_y3z4_F+con_z4_G")); + TEST_DO(verify_equal("con_y3z4_F*con_z4_G")); +} + +TEST_MAIN() { TEST_RUN_ALL(); } diff --git a/eval/src/tests/tensor/dense_replace_type_function/dense_replace_type_function_test.cpp b/eval/src/tests/tensor/dense_replace_type_function/dense_replace_type_function_test.cpp index 7e6b933d7c6..0533b1c92b7 100644 --- a/eval/src/tests/tensor/dense_replace_type_function/dense_replace_type_function_test.cpp +++ b/eval/src/tests/tensor/dense_replace_type_function/dense_replace_type_function_test.cpp @@ -13,11 +13,9 @@ using namespace vespalib::eval; using namespace vespalib::tensor; using namespace vespalib; -using CellsRef = DenseTensorView::CellsRef; - const TensorEngine &engine = DefaultTensorEngine::ref(); -CellsRef getCellsRef(const eval::Value &value) { +TypedCells getCellsRef(const eval::Value &value) { return static_cast<const DenseTensorView &>(value).cellsRef(); } @@ -58,8 +56,8 @@ TEST_F("require that DenseReplaceTypeFunction works as expected", Fixture()) { 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]).begin(), getCellsRef(*f1.my_value).begin()); - EXPECT_EQUAL(getCellsRef(f1.state.stack[0]).end(), getCellsRef(*f1.my_value).end()); + 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()); } diff --git a/eval/src/tests/tensor/direct_dense_tensor_builder/direct_dense_tensor_builder_test.cpp b/eval/src/tests/tensor/direct_dense_tensor_builder/direct_dense_tensor_builder_test.cpp index a0b7b60e2da..3f4641ed2ee 100644 --- a/eval/src/tests/tensor/direct_dense_tensor_builder/direct_dense_tensor_builder_test.cpp +++ b/eval/src/tests/tensor/direct_dense_tensor_builder/direct_dense_tensor_builder_test.cpp @@ -2,31 +2,36 @@ #include <vespa/vespalib/test/insertion_operators.h> #include <vespa/vespalib/testkit/test_kit.h> -#include <vespa/eval/tensor/dense/direct_dense_tensor_builder.h> +#include <vespa/eval/tensor/dense/typed_dense_tensor_builder.h> #include <vespa/vespalib/util/exceptions.h> using namespace vespalib::tensor; using vespalib::IllegalArgumentException; -using Builder = DirectDenseTensorBuilder; +using BuilderDbl = TypedDenseTensorBuilder<double>; +using BuilderFlt = TypedDenseTensorBuilder<float>; using vespalib::eval::TensorSpec; using vespalib::eval::ValueType; using vespalib::ConstArrayRef; -template <typename T> std::vector<T> make_vector(const ConstArrayRef<T> &ref) { - std::vector<T> vec; - for (const T &t: ref) { - vec.push_back(t); +struct CallMakeVector { + template <typename T> + static std::vector<double> call(const ConstArrayRef<T> &ref) { + std::vector<double> result; + result.reserve(ref.size()); + for (T v : ref) { + result.push_back(v); + } + return result; } - return vec; -} +}; void assertTensor(const vespalib::string &type_spec, - const DenseTensor::Cells &expCells, + const std::vector<double> &expCells, const Tensor &tensor) { - const DenseTensor &realTensor = dynamic_cast<const DenseTensor &>(tensor); + const DenseTensorView &realTensor = dynamic_cast<const DenseTensorView &>(tensor); EXPECT_EQUAL(ValueType::from_spec(type_spec), realTensor.type()); - EXPECT_EQUAL(expCells, make_vector(realTensor.cellsRef())); + EXPECT_EQUAL(expCells, dispatch_1<CallMakeVector>(realTensor.cellsRef())); } void assertTensorSpec(const TensorSpec &expSpec, const Tensor &tensor) { @@ -35,7 +40,7 @@ void assertTensorSpec(const TensorSpec &expSpec, const Tensor &tensor) { } Tensor::UP build1DTensor() { - Builder builder(ValueType::from_spec("tensor(x[3])")); + BuilderDbl builder(ValueType::from_spec("tensor(x[3])")); builder.insertCell(0, 10); builder.insertCell(1, 11); builder.insertCell(2, 12); @@ -55,7 +60,7 @@ TEST("require that 1d tensor can be converted to tensor spec") { } Tensor::UP build2DTensor() { - Builder builder(ValueType::from_spec("tensor(x[3],y[2])")); + BuilderDbl builder(ValueType::from_spec("tensor(x[3],y[2])")); builder.insertCell({0, 0}, 10); builder.insertCell({0, 1}, 11); builder.insertCell({1, 0}, 12); @@ -81,7 +86,7 @@ TEST("require that 2d tensor can be converted to tensor spec") { } TEST("require that 3d tensor can be constructed") { - Builder builder(ValueType::from_spec("tensor(x[3],y[2],z[2])")); + BuilderDbl builder(ValueType::from_spec("tensor(x[3],y[2],z[2])")); builder.insertCell({0, 0, 0}, 10); builder.insertCell({0, 0, 1}, 11); builder.insertCell({0, 1, 0}, 12); @@ -99,16 +104,26 @@ TEST("require that 3d tensor can be constructed") { *builder.build()); } +TEST("require that 2d tensor with float cells can be constructed") { + BuilderFlt builder(ValueType::from_spec("tensor<float>(x[3],y[2])")); + builder.insertCell({0, 1}, 2.5); + builder.insertCell({1, 0}, 1.5); + builder.insertCell({2, 0}, -0.25); + builder.insertCell({2, 1}, 0.75); + assertTensor("tensor<float>(x[3],y[2])", {0,2.5,1.5,0,-0.25,0.75}, + *builder.build()); +} + TEST("require that cells get default value 0 if not specified") { - Builder builder(ValueType::from_spec("tensor(x[3])")); + BuilderDbl builder(ValueType::from_spec("tensor(x[3])")); builder.insertCell(1, 11); assertTensor("tensor(x[3])", {0,11,0}, *builder.build()); } -void assertTensorCell(const DenseTensor::Address &expAddress, +void assertTensorCell(const DenseTensorView::Address &expAddress, double expCell, - const DenseTensor::CellsIterator &itr) + const DenseTensorView::CellsIterator &itr) { EXPECT_TRUE(itr.valid()); EXPECT_EQUAL(expAddress, itr.address()); @@ -118,14 +133,14 @@ void assertTensorCell(const DenseTensor::Address &expAddress, TEST("require that dense tensor cells iterator works for 1d tensor") { Tensor::UP tensor; { - Builder builder(ValueType::from_spec("tensor(x[2])")); + BuilderDbl builder(ValueType::from_spec("tensor(x[2])")); builder.insertCell(0, 2); builder.insertCell(1, 3); tensor = builder.build(); } - const DenseTensor &denseTensor = dynamic_cast<const DenseTensor &>(*tensor); - DenseTensor::CellsIterator itr = denseTensor.cellsIterator(); + const DenseTensorView &denseTensor = dynamic_cast<const DenseTensorView &>(*tensor); + DenseTensorView::CellsIterator itr = denseTensor.cellsIterator(); assertTensorCell({0}, 2, itr); itr.next(); @@ -137,7 +152,7 @@ TEST("require that dense tensor cells iterator works for 1d tensor") { TEST("require that dense tensor cells iterator works for 2d tensor") { Tensor::UP tensor; { - Builder builder(ValueType::from_spec("tensor(x[2],y[2])")); + BuilderDbl builder(ValueType::from_spec("tensor(x[2],y[2])")); builder.insertCell({0, 0}, 2); builder.insertCell({0, 1}, 3); builder.insertCell({1, 0}, 5); @@ -145,8 +160,8 @@ TEST("require that dense tensor cells iterator works for 2d tensor") { tensor = builder.build(); } - const DenseTensor &denseTensor = dynamic_cast<const DenseTensor &>(*tensor); - DenseTensor::CellsIterator itr = denseTensor.cellsIterator(); + const DenseTensorView &denseTensor = dynamic_cast<const DenseTensorView &>(*tensor); + DenseTensorView::CellsIterator itr = denseTensor.cellsIterator(); assertTensorCell({0,0}, 2, itr); itr.next(); diff --git a/eval/src/tests/tensor/tensor_mapper/.gitignore b/eval/src/tests/tensor/tensor_mapper/.gitignore deleted file mode 100644 index 8a312ff3157..00000000000 --- a/eval/src/tests/tensor/tensor_mapper/.gitignore +++ /dev/null @@ -1 +0,0 @@ -vespalib_tensor_mapper_test_app diff --git a/eval/src/tests/tensor/tensor_mapper/CMakeLists.txt b/eval/src/tests/tensor/tensor_mapper/CMakeLists.txt deleted file mode 100644 index dfc35b4f018..00000000000 --- a/eval/src/tests/tensor/tensor_mapper/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_tensor_mapper_test_app TEST - SOURCES - tensor_mapper_test.cpp - DEPENDS - vespaeval -) -vespa_add_test(NAME eval_tensor_mapper_test_app COMMAND eval_tensor_mapper_test_app) diff --git a/eval/src/tests/tensor/tensor_mapper/tensor_mapper_test.cpp b/eval/src/tests/tensor/tensor_mapper/tensor_mapper_test.cpp deleted file mode 100644 index 60b17930f0b..00000000000 --- a/eval/src/tests/tensor/tensor_mapper/tensor_mapper_test.cpp +++ /dev/null @@ -1,199 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#include <vespa/eval/eval/simple_tensor.h> -#include <vespa/eval/eval/tensor_spec.h> -#include <vespa/eval/tensor/default_tensor_engine.h> -#include <vespa/eval/tensor/tensor_mapper.h> -#include <vespa/eval/tensor/test/test_utils.h> -#include <vespa/eval/tensor/wrapped_simple_tensor.h> -#include <vespa/vespalib/testkit/test_kit.h> -#include <vespa/vespalib/util/stringfmt.h> - -using vespalib::eval::ValueType; -using vespalib::eval::Value; -using vespalib::eval::TensorSpec; -using vespalib::eval::SimpleTensor; -using vespalib::tensor::test::makeTensor; -using namespace vespalib::tensor; - -void -verify_wrapped(const TensorSpec &source, const vespalib::string &type, const TensorSpec &expect) -{ - auto tensor = std::make_unique<WrappedSimpleTensor>(SimpleTensor::create(source)); - auto mapped = TensorMapper::mapToWrapped(*tensor, ValueType::from_spec(type)); - TensorSpec actual = mapped->toSpec(); - EXPECT_EQUAL(actual, expect); -} - -void -verify(const TensorSpec &source, const vespalib::string &type, const TensorSpec &expect) -{ - auto tensor = makeTensor<Tensor>(source); - TensorMapper mapper(ValueType::from_spec(type)); - auto mapped = mapper.map(*tensor); - TensorSpec actual = mapped->toSpec(); - EXPECT_EQUAL(actual, expect); - TEST_DO(verify_wrapped(source, type, expect)); -} - -TEST("require that sparse tensors can be mapped to sparse type") { - TEST_DO(verify(TensorSpec("tensor(x{},y{})") - .add({{"x","1"},{"y","1"}}, 1) - .add({{"x","2"},{"y","1"}}, 3) - .add({{"x","1"},{"y","2"}}, 5) - .add({{"x","2"},{"y","2"}}, 7), - "tensor(y{})", - TensorSpec("tensor(y{})") - .add({{"y","1"}}, 4) - .add({{"y","2"}}, 12))); - - TEST_DO(verify(TensorSpec("tensor(x{},y{})") - .add({{"x","1"},{"y","1"}}, 1) - .add({{"x","2"},{"y","1"}}, 3) - .add({{"x","1"},{"y","2"}}, 5) - .add({{"x","2"},{"y","2"}}, 7), - "tensor(x{})", - TensorSpec("tensor(x{})") - .add({{"x","1"}}, 6) - .add({{"x","2"}}, 10))); -} - -TEST("require that sparse tensors can be mapped to dense type") { - TEST_DO(verify(TensorSpec("tensor(x{},y{})") - .add({{"x","1"},{"y","0"}}, 1) - .add({{"x","2"},{"y","0"}}, 3) - .add({{"x","1"},{"y","1"}}, 5) - .add({{"x","2"},{"y","1"}}, 7), - "tensor(y[3])", - TensorSpec("tensor(y[3])") - .add({{"y",0}}, 4) - .add({{"y",1}}, 12) - .add({{"y",2}}, 0))); - - TEST_DO(verify(TensorSpec("tensor(x{},y{})") - .add({{"x","1"},{"y","0x"}}, 1) - .add({{"x","2"},{"y",""}}, 3) - .add({{"x","1"},{"y","1"}}, 5) - .add({{"x","2"},{"y","10"}}, 7), - "tensor(y[3])", - TensorSpec("tensor(y[3])") - .add({{"y",0}}, 3) - .add({{"y",1}}, 5) - .add({{"y",2}}, 0))); - - TEST_DO(verify(TensorSpec("tensor(x{},y{})") - .add({{"x","0"},{"y","0"}}, 1) - .add({{"x","1"},{"y","0"}}, 3) - .add({{"x","0"},{"y","1"}}, 5) - .add({{"x","10"},{"y","1"}}, 7), - "tensor(x[2],y[3])", - TensorSpec("tensor(x[2],y[3])") - .add({{"x",0},{"y",0}}, 1) - .add({{"x",0},{"y",1}}, 5) - .add({{"x",0},{"y",2}}, 0) - .add({{"x",1},{"y",0}}, 3) - .add({{"x",1},{"y",1}}, 0) - .add({{"x",1},{"y",2}}, 0))); -} - -TEST("require that dense tensors can be mapped to sparse type") { - TEST_DO(verify(TensorSpec("tensor(x[2],y[2])") - .add({{"x",0},{"y",0}}, 1) - .add({{"x",0},{"y",1}}, 3) - .add({{"x",1},{"y",0}}, 5) - .add({{"x",1},{"y",1}}, 7), - "tensor(x{})", - TensorSpec("tensor(x{})") - .add({{"x","0"}}, 4) - .add({{"x","1"}}, 12))); -} - -TEST("require that mixed tensors can be mapped to sparse type") { - TEST_DO(verify(TensorSpec("tensor(x[2],y{})") - .add({{"x",0},{"y","0"}}, 1) - .add({{"x",0},{"y","1"}}, 3) - .add({{"x",1},{"y","0"}}, 5) - .add({{"x",1},{"y","1"}}, 7), - "tensor(x{})", - TensorSpec("tensor(x{})") - .add({{"x","0"}}, 4) - .add({{"x","1"}}, 12))); -} - -TEST("require that mixed tensors can be mapped to dense type") { - TEST_DO(verify(TensorSpec("tensor(x[2],y{})") - .add({{"x",0},{"y","0"}}, 1) - .add({{"x",0},{"y","1"}}, 3) - .add({{"x",1},{"y","0"}}, 5) - .add({{"x",1},{"y","1"}}, 7), - "tensor(y[2])", - TensorSpec("tensor(y[2])") - .add({{"y",0}}, 6) - .add({{"y",1}}, 10))); -} - -TEST("require that mixed tensors can be mapped to mixed type") { - TEST_DO(verify(TensorSpec("tensor(x[2],y{})") - .add({{"x",0},{"y","0"}}, 1) - .add({{"x",0},{"y","1"}}, 3) - .add({{"x",1},{"y","0"}}, 5) - .add({{"x",1},{"y","1"}}, 7), - "tensor(x{},y[2])", - TensorSpec("tensor(x{},y[2])") - .add({{"x","0"},{"y",0}}, 1) - .add({{"x","0"},{"y",1}}, 3) - .add({{"x","1"},{"y",0}}, 5) - .add({{"x","1"},{"y",1}}, 7))); -} - -TEST("require that dense tensors can be mapped to mixed type") { - TEST_DO(verify(TensorSpec("tensor(x[2],y[2])") - .add({{"x",0},{"y",0}}, 1) - .add({{"x",0},{"y",1}}, 3) - .add({{"x",1},{"y",0}}, 5) - .add({{"x",1},{"y",1}}, 7), - "tensor(x{},y[2])", - TensorSpec("tensor(x{},y[2])") - .add({{"x","0"},{"y",0}}, 1) - .add({{"x","0"},{"y",1}}, 3) - .add({{"x","1"},{"y",0}}, 5) - .add({{"x","1"},{"y",1}}, 7))); -} - -TEST("require that sparse tensors can be mapped to mixed type") { - TEST_DO(verify(TensorSpec("tensor(x{},y{})") - .add({{"x","0"},{"y","0"}}, 1) - .add({{"x","0"},{"y","1"}}, 3) - .add({{"x","1"},{"y","0"}}, 5) - .add({{"x","1"},{"y","1"}}, 7), - "tensor(x[2],y{})", - TensorSpec("tensor(x[2],y{})") - .add({{"x",0},{"y","0"}}, 1) - .add({{"x",0},{"y","1"}}, 3) - .add({{"x",1},{"y","0"}}, 5) - .add({{"x",1},{"y","1"}}, 7))); -} - -TEST("require that missing dimensions are added appropriately") { - TEST_DO(verify(TensorSpec("tensor(x{})") - .add({{"x","foo"}}, 42), - "tensor(x{},y{})", - TensorSpec("tensor(x{},y{})") - .add({{"x","foo"},{"y",""}}, 42))); - - TEST_DO(verify(TensorSpec("tensor(x[1])") - .add({{"x",0}}, 42), - "tensor(x[1],y[1],z[2])", - TensorSpec("tensor(x[1],y[1],z[2])") - .add({{"x",0},{"y",0},{"z",0}}, 42) - .add({{"x",0},{"y",0},{"z",1}}, 0))); - - TEST_DO(verify(TensorSpec("tensor(a{})") - .add({{"a","foo"}}, 42), - "tensor(a{},b[1],c{},d[2])", - TensorSpec("tensor(a{},b[1],c{},d[2])") - .add({{"a","foo"},{"b",0},{"c",""},{"d",0}}, 42) - .add({{"a","foo"},{"b",0},{"c",""},{"d",1}}, 0))); -} - -TEST_MAIN() { TEST_RUN_ALL(); } |