From 6c0d09b07f1ef9d5faccce302e0ca44db25be183 Mon Sep 17 00:00:00 2001 From: HÃ¥vard Pettersen Date: Thu, 15 Mar 2018 10:57:57 +0000 Subject: added generic DenseReplaceTypeFunction with test --- .../dense_replace_type_function/CMakeLists.txt | 8 +++ .../dense_replace_type_function_test.cpp | 67 ++++++++++++++++++++++ eval/src/vespa/eval/tensor/dense/CMakeLists.txt | 1 + .../tensor/dense/dense_replace_type_function.cpp | 45 +++++++++++++++ .../tensor/dense/dense_replace_type_function.h | 23 ++++++++ 5 files changed, 144 insertions(+) create mode 100644 eval/src/tests/tensor/dense_replace_type_function/CMakeLists.txt create mode 100644 eval/src/tests/tensor/dense_replace_type_function/dense_replace_type_function_test.cpp create mode 100644 eval/src/vespa/eval/tensor/dense/dense_replace_type_function.cpp create mode 100644 eval/src/vespa/eval/tensor/dense/dense_replace_type_function.h (limited to 'eval/src') diff --git a/eval/src/tests/tensor/dense_replace_type_function/CMakeLists.txt b/eval/src/tests/tensor/dense_replace_type_function/CMakeLists.txt new file mode 100644 index 00000000000..dd4a8a58082 --- /dev/null +++ b/eval/src/tests/tensor/dense_replace_type_function/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_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 new file mode 100644 index 00000000000..0e774be3dc3 --- /dev/null +++ b/eval/src/tests/tensor/dense_replace_type_function/dense_replace_type_function_test.cpp @@ -0,0 +1,67 @@ +// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#include +#include +#include +#include +#include +#include + +using namespace vespalib::eval::tensor_function; +using namespace vespalib::eval::test; +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) { + return static_cast(value).cellsRef(); +} + +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(Stash &) const override { abort(); } +}; + +struct Fixture { + Value::UP my_value; + ValueType new_type; + ChildMock mock_child; + DenseReplaceTypeFunction my_fun; + std::vector children; + InterpretedFunction::State state; + Fixture() + : my_value(engine.from_spec(spec({x(10)}, N()))), + new_type(ValueType::from_spec("tensor(x[5],y[2])")), + mock_child(my_value->type()), + my_fun(new_type, mock_child), + children(), + state(engine) + { + my_fun.push_children(children); + state.stack.push_back(*my_value); + my_fun.compile_self(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]).begin(), getCellsRef(*f1.my_value).begin()); + EXPECT_EQUAL(getCellsRef(f1.state.stack[0]).end(), getCellsRef(*f1.my_value).end()); + EXPECT_EQUAL(f1.state.stack[0].get().type(), f1.new_type); + fprintf(stderr, "%s\n", f1.my_fun.as_string().c_str()); +} + +TEST_MAIN() { TEST_RUN_ALL(); } diff --git a/eval/src/vespa/eval/tensor/dense/CMakeLists.txt b/eval/src/vespa/eval/tensor/dense/CMakeLists.txt index f78e49dc2f3..f3498d44a3d 100644 --- a/eval/src/vespa/eval/tensor/dense/CMakeLists.txt +++ b/eval/src/vespa/eval/tensor/dense/CMakeLists.txt @@ -5,6 +5,7 @@ vespa_add_library(eval_tensor_dense OBJECT dense_fast_rename_function.cpp dense_inplace_join_function.cpp dense_inplace_map_function.cpp + dense_replace_type_function.cpp dense_tensor.cpp dense_tensor_address_combiner.cpp dense_tensor_builder.cpp diff --git a/eval/src/vespa/eval/tensor/dense/dense_replace_type_function.cpp b/eval/src/vespa/eval/tensor/dense/dense_replace_type_function.cpp new file mode 100644 index 00000000000..dd6d5635ef9 --- /dev/null +++ b/eval/src/vespa/eval/tensor/dense/dense_replace_type_function.cpp @@ -0,0 +1,45 @@ +// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#include "dense_replace_type_function.h" +#include "dense_tensor_view.h" +#include + +namespace vespalib::tensor { + +using CellsRef = DenseTensorView::CellsRef; +using eval::Value; +using eval::ValueType; +using eval::TensorFunction; + +namespace { + +CellsRef getCellsRef(const eval::Value &value) { + const DenseTensorView &denseTensor = static_cast(value); + return denseTensor.cellsRef(); +} + +void my_replace_type_op(eval::InterpretedFunction::State &state, uint64_t param) { + const ValueType *type = (const ValueType *)(param); + CellsRef cells = getCellsRef(state.peek(0)); + state.pop_push(state.stash.create(*type, cells)); +} + +} // namespace vespalib::tensor:: + +DenseReplaceTypeFunction::DenseReplaceTypeFunction(const eval::ValueType &result_type, + const eval::TensorFunction &child) + : eval::tensor_function::Op1(result_type, child) +{ +} + +DenseReplaceTypeFunction::~DenseReplaceTypeFunction() +{ +} + +eval::InterpretedFunction::Instruction +DenseReplaceTypeFunction::compile_self(Stash &) const +{ + return eval::InterpretedFunction::Instruction(my_replace_type_op, (uint64_t)&(result_type())); +} + +} // namespace vespalib::tensor diff --git a/eval/src/vespa/eval/tensor/dense/dense_replace_type_function.h b/eval/src/vespa/eval/tensor/dense/dense_replace_type_function.h new file mode 100644 index 00000000000..67a221b101e --- /dev/null +++ b/eval/src/vespa/eval/tensor/dense/dense_replace_type_function.h @@ -0,0 +1,23 @@ +// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#pragma once + +#include + +namespace vespalib::tensor { + +/** + * Tensor function for efficient type-only modification of dense + * tensor. + **/ +class DenseReplaceTypeFunction : public eval::tensor_function::Op1 +{ +public: + DenseReplaceTypeFunction(const eval::ValueType &result_type, + const eval::TensorFunction &child); + ~DenseReplaceTypeFunction(); + eval::InterpretedFunction::Instruction compile_self(Stash &stash) const override; + bool result_is_mutable() const override { return child().result_is_mutable(); } +}; + +} // namespace vespalib::tensor -- cgit v1.2.3