From cf2b625dc1f310fc2d30d05ddb21fcf36ccda59f Mon Sep 17 00:00:00 2001 From: Haavard Date: Thu, 11 Aug 2016 13:29:55 +0000 Subject: adjust tensor engine API and update implementations accordingly --- .../eval/simple_tensor/simple_tensor_test.cpp | 6 +- .../vespa/vespalib/eval/interpreted_function.cpp | 2 +- .../vespa/vespalib/eval/simple_tensor_engine.cpp | 24 ++------ .../src/vespa/vespalib/eval/simple_tensor_engine.h | 9 +-- vespalib/src/vespa/vespalib/eval/tensor_engine.h | 8 +-- vespalib/src/vespa/vespalib/eval/value.cpp | 4 +- .../vespalib/tensor/default_tensor_engine.cpp | 70 +++++++++------------- .../vespa/vespalib/tensor/default_tensor_engine.h | 9 +-- 8 files changed, 55 insertions(+), 77 deletions(-) diff --git a/vespalib/src/tests/eval/simple_tensor/simple_tensor_test.cpp b/vespalib/src/tests/eval/simple_tensor/simple_tensor_test.cpp index 742c6181023..775c2b72e0a 100644 --- a/vespalib/src/tests/eval/simple_tensor/simple_tensor_test.cpp +++ b/vespalib/src/tests/eval/simple_tensor/simple_tensor_test.cpp @@ -127,7 +127,7 @@ TEST("require that simple tensors can have their values negated") { auto result = SimpleTensor::perform(operation::Neg(), *tensor); EXPECT_EQUAL(Check(*expect), Check(*result)); Stash stash; - const Value &result2 = SimpleTensorEngine::ref().perform(operation::Neg(), *tensor, stash); + const Value &result2 = SimpleTensorEngine::ref().map(operation::Neg(), *tensor, stash); EXPECT_EQUAL(Check(*expect), Check(unwrap(result2))); } @@ -152,7 +152,7 @@ TEST("require that simple tensors can be multiplied with each other") { auto result = SimpleTensor::perform(operation::Mul(), *lhs, *rhs); EXPECT_EQUAL(Check(*expect), Check(*result)); Stash stash; - const Value &result2 = SimpleTensorEngine::ref().perform(operation::Mul(), *lhs, *rhs, stash); + const Value &result2 = SimpleTensorEngine::ref().apply(operation::Mul(), *lhs, *rhs, stash); EXPECT_EQUAL(Check(*expect), Check(unwrap(result2))); } @@ -185,7 +185,7 @@ TEST("require that simple tensors support dimension reduction") { const Value &result_sum_y_2 = SimpleTensorEngine::ref().reduce(*tensor, operation::Add(), {"y"}, stash); const Value &result_sum_x_2 = SimpleTensorEngine::ref().reduce(*tensor, operation::Add(), {"x"}, stash); const Value &result_sum_all_2 = SimpleTensorEngine::ref().reduce(*tensor, operation::Add(), {"x", "y"}, stash); - const Value &result_sum_all_3 = SimpleTensorEngine::ref().reduce(*tensor, operation::Add(), stash); + const Value &result_sum_all_3 = SimpleTensorEngine::ref().reduce(*tensor, operation::Add(), {}, stash); EXPECT_EQUAL(Check(*expect_sum_y), Check(unwrap(result_sum_y_2))); EXPECT_EQUAL(Check(*expect_sum_x), Check(unwrap(result_sum_x_2))); EXPECT_TRUE(result_sum_all_2.is_double()); diff --git a/vespalib/src/vespa/vespalib/eval/interpreted_function.cpp b/vespalib/src/vespa/vespalib/eval/interpreted_function.cpp index bfa48683e57..8d93bf4b5e5 100644 --- a/vespalib/src/vespa/vespalib/eval/interpreted_function.cpp +++ b/vespalib/src/vespa/vespalib/eval/interpreted_function.cpp @@ -106,7 +106,7 @@ void op_not_member(State &state, uint64_t) { void op_tensor_sum(State &state, uint64_t) { const eval::Tensor *tensor = state.peek(0).as_tensor(); if (tensor != nullptr) { - state.replace(1, tensor->engine().reduce(*tensor, operation::Add(), state.stash)); + state.replace(1, tensor->engine().reduce(*tensor, operation::Add(), {}, state.stash)); } else { state.replace(1, state.stash.create()); } diff --git a/vespalib/src/vespa/vespalib/eval/simple_tensor_engine.cpp b/vespalib/src/vespa/vespalib/eval/simple_tensor_engine.cpp index 8d4b0cf8fb6..7a36f08b224 100644 --- a/vespalib/src/vespa/vespalib/eval/simple_tensor_engine.cpp +++ b/vespalib/src/vespa/vespalib/eval/simple_tensor_engine.cpp @@ -18,12 +18,6 @@ SimpleTensorEngine::type_of(const Tensor &tensor) const return simple_tensor.type(); } -std::unique_ptr -SimpleTensorEngine::create(const TensorSpec &spec) const -{ - return SimpleTensor::create(spec); -} - bool SimpleTensorEngine::equal(const Tensor &a, const Tensor &b) const { @@ -34,16 +28,10 @@ SimpleTensorEngine::equal(const Tensor &a, const Tensor &b) const return SimpleTensor::equal(simple_a, simple_b); } -const Value & -SimpleTensorEngine::reduce(const eval::Tensor &tensor, const BinaryOperation &op, Stash &stash) const +std::unique_ptr +SimpleTensorEngine::create(const TensorSpec &spec) const { - assert(&tensor.engine() == this); - const SimpleTensor &simple_tensor = static_cast(tensor); - std::vector dimensions = simple_tensor.type().dimension_names(); - auto result = simple_tensor.reduce(op, dimensions); - assert(result->type().is_double()); - assert(result->cells().size() == 1u); - return stash.create(result->cells()[0].value); + return SimpleTensor::create(spec); } const Value & @@ -51,7 +39,7 @@ SimpleTensorEngine::reduce(const eval::Tensor &tensor, const BinaryOperation &op { assert(&tensor.engine() == this); const SimpleTensor &simple_tensor = static_cast(tensor); - auto result = simple_tensor.reduce(op, dimensions); + auto result = simple_tensor.reduce(op, dimensions.empty() ? simple_tensor.type().dimension_names() : dimensions); if (result->type().is_double()) { assert(result->cells().size() == 1u); return stash.create(result->cells()[0].value); @@ -60,7 +48,7 @@ SimpleTensorEngine::reduce(const eval::Tensor &tensor, const BinaryOperation &op } const Value & -SimpleTensorEngine::perform(const UnaryOperation &op, const eval::Tensor &a, Stash &stash) const +SimpleTensorEngine::map(const UnaryOperation &op, const eval::Tensor &a, Stash &stash) const { assert(&a.engine() == this); const SimpleTensor &simple_a = static_cast(a); @@ -69,7 +57,7 @@ SimpleTensorEngine::perform(const UnaryOperation &op, const eval::Tensor &a, Sta } const Value & -SimpleTensorEngine::perform(const BinaryOperation &op, const eval::Tensor &a, const eval::Tensor &b, Stash &stash) const +SimpleTensorEngine::apply(const BinaryOperation &op, const eval::Tensor &a, const eval::Tensor &b, Stash &stash) const { assert(&a.engine() == this); assert(&b.engine() == this); diff --git a/vespalib/src/vespa/vespalib/eval/simple_tensor_engine.h b/vespalib/src/vespa/vespalib/eval/simple_tensor_engine.h index 03307e48833..4ea22f10759 100644 --- a/vespalib/src/vespa/vespalib/eval/simple_tensor_engine.h +++ b/vespalib/src/vespa/vespalib/eval/simple_tensor_engine.h @@ -18,13 +18,14 @@ private: static const SimpleTensorEngine _engine; public: static const TensorEngine &ref() { return _engine; }; + ValueType type_of(const Tensor &tensor) const override; - std::unique_ptr create(const TensorSpec &spec) const override; bool equal(const Tensor &a, const Tensor &b) const override; - const Value &reduce(const Tensor &tensor, const BinaryOperation &op, Stash &stash) const override; + + std::unique_ptr create(const TensorSpec &spec) const override; const Value &reduce(const Tensor &tensor, const BinaryOperation &op, const std::vector &dimensions, Stash &stash) const override; - const Value &perform(const UnaryOperation &op, const Tensor &a, Stash &stash) const override; - const Value &perform(const BinaryOperation &op, const Tensor &a, const Tensor &b, Stash &stash) const override; + const Value &map(const UnaryOperation &op, const Tensor &a, Stash &stash) const override; + const Value &apply(const BinaryOperation &op, const Tensor &a, const Tensor &b, Stash &stash) const override; }; } // namespace vespalib::eval diff --git a/vespalib/src/vespa/vespalib/eval/tensor_engine.h b/vespalib/src/vespa/vespalib/eval/tensor_engine.h index abc2e89f468..6a9306438c5 100644 --- a/vespalib/src/vespa/vespalib/eval/tensor_engine.h +++ b/vespalib/src/vespa/vespalib/eval/tensor_engine.h @@ -38,12 +38,12 @@ struct TensorEngine using UnaryOperation = eval::UnaryOperation; virtual ValueType type_of(const Tensor &tensor) const = 0; - virtual std::unique_ptr create(const TensorSpec &spec) const = 0; virtual bool equal(const Tensor &a, const Tensor &b) const = 0; - virtual const Value &reduce(const Tensor &tensor, const BinaryOperation &op, Stash &stash) const = 0; + + virtual std::unique_ptr create(const TensorSpec &spec) const = 0; virtual const Value &reduce(const Tensor &tensor, const BinaryOperation &op, const std::vector &dimensions, Stash &stash) const = 0; - virtual const Value &perform(const UnaryOperation &op, const Tensor &a, Stash &stash) const = 0; - virtual const Value &perform(const BinaryOperation &op, const Tensor &a, const Tensor &b, Stash &stash) const = 0; + virtual const Value &map(const UnaryOperation &op, const Tensor &a, Stash &stash) const = 0; + virtual const Value &apply(const BinaryOperation &op, const Tensor &a, const Tensor &b, Stash &stash) const = 0; virtual ~TensorEngine() {} }; diff --git a/vespalib/src/vespa/vespalib/eval/value.cpp b/vespalib/src/vespa/vespalib/eval/value.cpp index b228c642eae..ff72ac4c85c 100644 --- a/vespalib/src/vespa/vespalib/eval/value.cpp +++ b/vespalib/src/vespa/vespalib/eval/value.cpp @@ -29,7 +29,7 @@ TensorValue::equal(const Value &rhs) const const Value & TensorValue::apply(const UnaryOperation &op, Stash &stash) const { - return _value->engine().perform(op, *_value, stash); + return _value->engine().map(op, *_value, stash); } const Value & @@ -39,7 +39,7 @@ TensorValue::apply(const BinaryOperation &op, const Value &rhs, Stash &stash) co if ((other == nullptr) || (&other->engine() != &_value->engine())) { return stash.create(); } - return _value->engine().perform(op, *_value, *other, stash); + return _value->engine().apply(op, *_value, *other, stash); } } // namespace vespalib::eval diff --git a/vespalib/src/vespa/vespalib/tensor/default_tensor_engine.cpp b/vespalib/src/vespa/vespalib/tensor/default_tensor_engine.cpp index 40ca3930680..bf76a7bd9e3 100644 --- a/vespalib/src/vespa/vespalib/tensor/default_tensor_engine.cpp +++ b/vespalib/src/vespa/vespalib/tensor/default_tensor_engine.cpp @@ -26,6 +26,22 @@ DefaultTensorEngine::type_of(const Tensor &tensor) const return my_tensor.getType().as_value_type(); } +bool +DefaultTensorEngine::equal(const Tensor &a, const Tensor &b) const +{ + assert(&a.engine() == this); + assert(&b.engine() == this); + const tensor::Tensor &my_a = static_cast(a); + const tensor::Tensor &my_b = static_cast(b); + return my_a.equals(my_b); +} + +struct IsAddOperation : public eval::DefaultOperationVisitor { + bool result = false; + void visitDefault(const eval::Operation &) override {} + void visit(const eval::operation::Add &) override { result = true; } +}; + std::unique_ptr DefaultTensorEngine::create(const TensorSpec &spec) const { @@ -76,36 +92,6 @@ DefaultTensorEngine::create(const TensorSpec &spec) const } } -bool -DefaultTensorEngine::equal(const Tensor &a, const Tensor &b) const -{ - assert(&a.engine() == this); - assert(&b.engine() == this); - const tensor::Tensor &my_a = static_cast(a); - const tensor::Tensor &my_b = static_cast(b); - return my_a.equals(my_b); -} - -struct IsAddOperation : public eval::DefaultOperationVisitor { - bool result = false; - void visitDefault(const eval::Operation &) override {} - void visit(const eval::operation::Add &) override { result = true; } -}; - -const eval::Value & -DefaultTensorEngine::reduce(const Tensor &tensor, const BinaryOperation &op, Stash &stash) const -{ - assert(&tensor.engine() == this); - const tensor::Tensor &my_tensor = static_cast(tensor); - IsAddOperation check; - op.accept(check); - if (check.result) { - return stash.create(my_tensor.sum()); - } else { - return stash.create(); - } -} - const eval::Value & DefaultTensorEngine::reduce(const Tensor &tensor, const BinaryOperation &op, const std::vector &dimensions, Stash &stash) const { @@ -114,17 +100,19 @@ DefaultTensorEngine::reduce(const Tensor &tensor, const BinaryOperation &op, con IsAddOperation check; op.accept(check); if (check.result) { - tensor::Tensor::UP result; - for (const auto &dimension: dimensions) { - if (result) { - result = result->sum(dimension); - } else { - result = my_tensor.sum(dimension); + if (dimensions.empty()) { // sum + return stash.create(my_tensor.sum()); + } else { // dimension sum + tensor::Tensor::UP result; + for (const auto &dimension: dimensions) { + if (result) { + result = result->sum(dimension); + } else { + result = my_tensor.sum(dimension); + } } + return stash.create(std::move(result)); } - return stash.create(std::move(result)); - } else { - return stash.create(); } return stash.create(); } @@ -136,7 +124,7 @@ struct CellFunctionAdapter : tensor::CellFunction { }; const eval::Value & -DefaultTensorEngine::perform(const UnaryOperation &op, const Tensor &a, Stash &stash) const +DefaultTensorEngine::map(const UnaryOperation &op, const Tensor &a, Stash &stash) const { assert(&a.engine() == this); const tensor::Tensor &my_a = static_cast(a); @@ -176,7 +164,7 @@ struct TensorOperationOverride : eval::DefaultOperationVisitor { }; const eval::Value & -DefaultTensorEngine::perform(const BinaryOperation &op, const Tensor &a, const Tensor &b, Stash &stash) const +DefaultTensorEngine::apply(const BinaryOperation &op, const Tensor &a, const Tensor &b, Stash &stash) const { assert(&a.engine() == this); assert(&b.engine() == this); diff --git a/vespalib/src/vespa/vespalib/tensor/default_tensor_engine.h b/vespalib/src/vespa/vespalib/tensor/default_tensor_engine.h index 32e9d787925..d42c8d1cee1 100644 --- a/vespalib/src/vespa/vespalib/tensor/default_tensor_engine.h +++ b/vespalib/src/vespa/vespalib/tensor/default_tensor_engine.h @@ -18,13 +18,14 @@ private: static const DefaultTensorEngine _engine; public: static const TensorEngine &ref() { return _engine; }; + ValueType type_of(const Tensor &tensor) const override; - std::unique_ptr create(const TensorSpec &spec) const override; bool equal(const Tensor &a, const Tensor &b) const override; - const Value &reduce(const Tensor &tensor, const BinaryOperation &op, Stash &stash) const override; + + std::unique_ptr create(const TensorSpec &spec) const override; const Value &reduce(const Tensor &tensor, const BinaryOperation &op, const std::vector &dimensions, Stash &stash) const override; - const Value &perform(const UnaryOperation &op, const Tensor &a, Stash &stash) const override; - const Value &perform(const BinaryOperation &op, const Tensor &a, const Tensor &b, Stash &stash) const override; + const Value &map(const UnaryOperation &op, const Tensor &a, Stash &stash) const override; + const Value &apply(const BinaryOperation &op, const Tensor &a, const Tensor &b, Stash &stash) const override; }; } // namespace vespalib::tensor -- cgit v1.2.3