From 52be221f7e73ed6c01464b7c7d160be28466dde5 Mon Sep 17 00:00:00 2001 From: Arne Juul Date: Mon, 24 Jun 2019 12:16:56 +0000 Subject: add unit test --- eval/CMakeLists.txt | 1 + .../tensor/dense_dimension_combiner/CMakeLists.txt | 9 + .../dense_dimension_combiner_test.cpp | 185 +++++++++++++++++++++ .../eval/tensor/dense/dense_dimension_combiner.cpp | 2 + .../eval/tensor/dense/dense_dimension_combiner.h | 2 + 5 files changed, 199 insertions(+) create mode 100644 eval/src/tests/tensor/dense_dimension_combiner/CMakeLists.txt create mode 100644 eval/src/tests/tensor/dense_dimension_combiner/dense_dimension_combiner_test.cpp (limited to 'eval') diff --git a/eval/CMakeLists.txt b/eval/CMakeLists.txt index 26e046ec52a..92fdd2f9162 100644 --- a/eval/CMakeLists.txt +++ b/eval/CMakeLists.txt @@ -25,6 +25,7 @@ vespa_define_module( src/tests/eval/value_cache src/tests/eval/value_type src/tests/gp/ponder_nov2017 + src/tests/tensor/dense_dimension_combiner src/tests/tensor/dense_add_dimension_optimizer src/tests/tensor/dense_dot_product_function src/tests/tensor/dense_fast_rename_optimizer diff --git a/eval/src/tests/tensor/dense_dimension_combiner/CMakeLists.txt b/eval/src/tests/tensor/dense_dimension_combiner/CMakeLists.txt new file mode 100644 index 00000000000..eaee8ebb4e4 --- /dev/null +++ b/eval/src/tests/tensor/dense_dimension_combiner/CMakeLists.txt @@ -0,0 +1,9 @@ +# 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 new file mode 100644 index 00000000000..b8949e3a7e6 --- /dev/null +++ b/eval/src/tests/tensor/dense_dimension_combiner/dense_dimension_combiner_test.cpp @@ -0,0 +1,185 @@ +// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#include +#include + +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/vespa/eval/tensor/dense/dense_dimension_combiner.cpp b/eval/src/vespa/eval/tensor/dense/dense_dimension_combiner.cpp index 1d73eea6ddc..194f4d0eae3 100644 --- a/eval/src/vespa/eval/tensor/dense/dense_dimension_combiner.cpp +++ b/eval/src/vespa/eval/tensor/dense/dense_dimension_combiner.cpp @@ -5,6 +5,8 @@ namespace vespalib::tensor { +DenseDimensionCombiner::~DenseDimensionCombiner() = default; + DenseDimensionCombiner::DenseDimensionCombiner(const eval::ValueType &lhs, const eval::ValueType &rhs) : _leftDims(), _rightDims(), _commonDims(), diff --git a/eval/src/vespa/eval/tensor/dense/dense_dimension_combiner.h b/eval/src/vespa/eval/tensor/dense/dense_dimension_combiner.h index b0539b830db..91449f122cd 100644 --- a/eval/src/vespa/eval/tensor/dense/dense_dimension_combiner.h +++ b/eval/src/vespa/eval/tensor/dense/dense_dimension_combiner.h @@ -129,6 +129,8 @@ public: DenseDimensionCombiner(const eval::ValueType &lhs, const eval::ValueType &rhs); + ~DenseDimensionCombiner(); + void dump() const; }; -- cgit v1.2.3