diff options
author | Henning Baldersheim <balder@yahoo-inc.com> | 2022-06-02 18:19:57 +0000 |
---|---|---|
committer | Henning Baldersheim <balder@yahoo-inc.com> | 2022-06-02 18:19:57 +0000 |
commit | 33e37e2df71770934beb06dcde8b30aa9048c053 (patch) | |
tree | ed345fd1622ffccbb1161c4560c32a1edb7eb42e /eval | |
parent | a51340034f1b4bc98096613af8f5736a2c974c96 (diff) |
Move the ValueBuilder stuff from value.h to value_builder_factory.h as that is required in far fewer places than value.h.
Diffstat (limited to 'eval')
21 files changed, 171 insertions, 149 deletions
diff --git a/eval/src/vespa/eval/eval/CMakeLists.txt b/eval/src/vespa/eval/eval/CMakeLists.txt index 09ca3b83353..0e4baac3006 100644 --- a/eval/src/vespa/eval/eval/CMakeLists.txt +++ b/eval/src/vespa/eval/eval/CMakeLists.txt @@ -34,6 +34,7 @@ vespa_add_library(eval_eval OBJECT tensor_spec.cpp typed_cells.cpp value.cpp + value_builder_factory.cpp value_codec.cpp value_type.cpp value_type_spec.cpp diff --git a/eval/src/vespa/eval/eval/double_value_builder.h b/eval/src/vespa/eval/eval/double_value_builder.h index f29482d97b0..db6e845a4b8 100644 --- a/eval/src/vespa/eval/eval/double_value_builder.h +++ b/eval/src/vespa/eval/eval/double_value_builder.h @@ -2,7 +2,7 @@ #pragma once -#include "value.h" +#include "value_builder_factory.h" namespace vespalib::eval { diff --git a/eval/src/vespa/eval/eval/fast_value.h b/eval/src/vespa/eval/eval/fast_value.h index 9f9d2e198f7..e774efbd32e 100644 --- a/eval/src/vespa/eval/eval/fast_value.h +++ b/eval/src/vespa/eval/eval/fast_value.h @@ -2,7 +2,7 @@ #pragma once -#include "value.h" +#include "value_builder_factory.h" namespace vespalib::eval { diff --git a/eval/src/vespa/eval/eval/fast_value.hpp b/eval/src/vespa/eval/eval/fast_value.hpp index 3ac6853f564..b897fb0eaf2 100644 --- a/eval/src/vespa/eval/eval/fast_value.hpp +++ b/eval/src/vespa/eval/eval/fast_value.hpp @@ -1,6 +1,6 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -#include "value.h" +#include "value_builder_factory.h" #include "fast_addr_map.h" #include "inline_operation.h" #include <vespa/eval/instruction/generic_join.h> diff --git a/eval/src/vespa/eval/eval/interpreted_function.h b/eval/src/vespa/eval/eval/interpreted_function.h index 57d7f79caf4..98699c77842 100644 --- a/eval/src/vespa/eval/eval/interpreted_function.h +++ b/eval/src/vespa/eval/eval/interpreted_function.h @@ -14,6 +14,7 @@ namespace nodes { struct Node; } struct TensorFunction; class TensorSpec; struct CTFMetaData; +class ValueBuilderFactory; /** * A Function that has been prepared for execution. This will diff --git a/eval/src/vespa/eval/eval/simple_value.h b/eval/src/vespa/eval/eval/simple_value.h index 32d244a156d..76819f338fc 100644 --- a/eval/src/vespa/eval/eval/simple_value.h +++ b/eval/src/vespa/eval/eval/simple_value.h @@ -2,7 +2,7 @@ #pragma once -#include "value.h" +#include "value_builder_factory.h" #include <vespa/vespalib/util/shared_string_repo.h> #include <vector> #include <map> diff --git a/eval/src/vespa/eval/eval/value.cpp b/eval/src/vespa/eval/eval/value.cpp index 589b19bcb16..b7acdef3fee 100644 --- a/eval/src/vespa/eval/eval/value.cpp +++ b/eval/src/vespa/eval/eval/value.cpp @@ -1,12 +1,10 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include "value.h" -#include "value_codec.h" #include <vespa/vespalib/util/typify.h> #include <vespa/vespalib/objects/nbostream.h> -namespace vespalib { -namespace eval { +namespace vespalib::eval { namespace { @@ -79,55 +77,4 @@ Value::as_double() const ValueType DoubleValue::_type = ValueType::double_type(); -namespace { - -struct CopyValue { - template <typename CT> - static std::unique_ptr<Value> invoke(const Value &value, - const ValueType &type, - const ValueBuilderFactory &factory) - { - size_t num_mapped = type.count_mapped_dimensions(); - size_t dense_size = type.dense_subspace_size(); - const auto & idx = value.index(); - auto input_cells = value.cells().typify<CT>(); - auto builder = factory.create_value_builder<CT>(type, num_mapped, dense_size, idx.size()); - std::vector<string_id> addr(num_mapped); - if (num_mapped == 0) { - assert(idx.size() == 1); - auto array_ref = builder->add_subspace(addr); - for (size_t i = 0; i < dense_size; ++i) { - array_ref[i] = input_cells[i]; - } - } else { - auto view = idx.create_view({}); - view->lookup({}); - std::vector<string_id*> addr_fetch; - addr_fetch.reserve(num_mapped); - for (auto & label : addr) { - addr_fetch.push_back(&label); - } - size_t subspace_idx; - while (view->next_result(addr_fetch, subspace_idx)) { - auto array_ref = builder->add_subspace(addr); - for (size_t i = 0; i < dense_size; ++i) { - array_ref[i] = input_cells[(dense_size * subspace_idx) + i]; - } - } - } - return builder->build(std::move(builder)); - } -}; - -} // namespace <unnamed> - -std::unique_ptr<Value> -ValueBuilderFactory::copy(const Value &value) const -{ - const auto & type = value.type(); - return typify_invoke<1,TypifyCellType,CopyValue>(type.cell_type(), - value, type, *this); } - -} // namespace vespalib::eval -} // namespace vespalib diff --git a/eval/src/vespa/eval/eval/value.h b/eval/src/vespa/eval/eval/value.h index 7cf2659c3fb..9195bf3b0bd 100644 --- a/eval/src/vespa/eval/eval/value.h +++ b/eval/src/vespa/eval/eval/value.h @@ -136,88 +136,6 @@ public: MemoryUsage get_memory_usage() const final override { return self_memory_usage<ValueView>(); } }; -/** - * Tagging interface used as return type from factories before - * downcasting to actual builder with specialized cell type. - **/ -struct ValueBuilderBase { - virtual ~ValueBuilderBase() {} -}; - -/** - * Interface used to build a value one dense subspace at a - * time. Enables decoupling of what the value should contain from how - * to store the value. - **/ -template <typename T> -struct ValueBuilder : ValueBuilderBase { - // add a dense subspace for the given address (label for all - // mapped dimensions in canonical order). Note that previously - // returned subspaces will be invalidated when new subspaces are - // added. Also note that adding the same subspace multiple times - // is not allowed. - virtual ArrayRef<T> add_subspace(ConstArrayRef<vespalib::stringref> addr) = 0; - - // add a dense subspace for the given address where labels are - // specified by shared string repo ids. Note that the caller is - // responsible for making sure the ids are valid 'long enough'. - virtual ArrayRef<T> add_subspace(ConstArrayRef<string_id> addr) = 0; - - // convenience function to add a subspace with an empty address - ArrayRef<T> add_subspace() { return add_subspace(ConstArrayRef<string_id>()); } - - // Given the ownership of the builder itself, produce the newly - // created value. This means that builders can only be used once, - // it also means values can build themselves. - virtual std::unique_ptr<Value> build(std::unique_ptr<ValueBuilder> self) = 0; -}; - -/** - * Factory able to create appropriate value builders. We do not really - * care about the full mathematical type here, but it needs to be - * passed since it is exposed in the value api. The expected number of - * subspaces is also passed since it enables the builder to pre-size - * internal structures appropriately. Note that since we are not able - * to have virtual templated functions we need to cast the created - * builder. With interoperability between all values. - **/ -struct ValueBuilderFactory { -private: - template <typename T> - std::unique_ptr<ValueBuilder<T>> create_value_builder(const ValueType &type, bool transient, - size_t num_mapped_dims_in, size_t subspace_size_in, size_t expected_subspaces) const - { - assert(check_cell_type<T>(type.cell_type())); - auto base = create_value_builder_base(type, transient, num_mapped_dims_in, subspace_size_in, expected_subspaces); - ValueBuilder<T> *builder = static_cast<ValueBuilder<T>*>(base.get()); - base.release(); - return std::unique_ptr<ValueBuilder<T>>(builder); - } -public: - template <typename T> - std::unique_ptr<ValueBuilder<T>> create_value_builder(const ValueType &type, - size_t num_mapped_dims_in, size_t subspace_size_in, size_t expected_subspaces) const - { - return create_value_builder<T>(type, false, num_mapped_dims_in, subspace_size_in, expected_subspaces); - } - template <typename T> - std::unique_ptr<ValueBuilder<T>> create_transient_value_builder(const ValueType &type, - size_t num_mapped_dims_in, size_t subspace_size_in, size_t expected_subspaces) const - { - return create_value_builder<T>(type, true, num_mapped_dims_in, subspace_size_in, expected_subspaces); - } - template <typename T> - std::unique_ptr<ValueBuilder<T>> create_value_builder(const ValueType &type) const - { - return create_value_builder<T>(type, false, type.count_mapped_dimensions(), type.dense_subspace_size(), 1); - } - std::unique_ptr<Value> copy(const Value &value) const; - virtual ~ValueBuilderFactory() {} -protected: - virtual std::unique_ptr<ValueBuilderBase> create_value_builder_base(const ValueType &type, bool transient, - size_t num_mapped_dims_in, size_t subspace_size_in, size_t expected_subspaces) const = 0; -}; - } VESPA_CAN_SKIP_DESTRUCTION(::vespalib::eval::DoubleValue); diff --git a/eval/src/vespa/eval/eval/value_builder_factory.cpp b/eval/src/vespa/eval/eval/value_builder_factory.cpp new file mode 100644 index 00000000000..650973e6a21 --- /dev/null +++ b/eval/src/vespa/eval/eval/value_builder_factory.cpp @@ -0,0 +1,57 @@ +// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#include "value_builder_factory.h" + +namespace vespalib::eval { + +namespace { + +struct CopyValue { + template <typename CT> + static std::unique_ptr<Value> invoke(const Value &value, + const ValueType &type, + const ValueBuilderFactory &factory) + { + size_t num_mapped = type.count_mapped_dimensions(); + size_t dense_size = type.dense_subspace_size(); + const auto & idx = value.index(); + auto input_cells = value.cells().typify<CT>(); + auto builder = factory.create_value_builder<CT>(type, num_mapped, dense_size, idx.size()); + std::vector<string_id> addr(num_mapped); + if (num_mapped == 0) { + assert(idx.size() == 1); + auto array_ref = builder->add_subspace(addr); + for (size_t i = 0; i < dense_size; ++i) { + array_ref[i] = input_cells[i]; + } + } else { + auto view = idx.create_view({}); + view->lookup({}); + std::vector<string_id*> addr_fetch; + addr_fetch.reserve(num_mapped); + for (auto & label : addr) { + addr_fetch.push_back(&label); + } + size_t subspace_idx; + while (view->next_result(addr_fetch, subspace_idx)) { + auto array_ref = builder->add_subspace(addr); + for (size_t i = 0; i < dense_size; ++i) { + array_ref[i] = input_cells[(dense_size * subspace_idx) + i]; + } + } + } + return builder->build(std::move(builder)); + } +}; + +} // namespace <unnamed> + +std::unique_ptr<Value> +ValueBuilderFactory::copy(const Value &value) const +{ + const auto & type = value.type(); + return typify_invoke<1,TypifyCellType,CopyValue>(type.cell_type(), + value, type, *this); +} + +} diff --git a/eval/src/vespa/eval/eval/value_builder_factory.h b/eval/src/vespa/eval/eval/value_builder_factory.h new file mode 100644 index 00000000000..dd8181fc4a8 --- /dev/null +++ b/eval/src/vespa/eval/eval/value_builder_factory.h @@ -0,0 +1,91 @@ +// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#pragma once + +#include "value.h" + +namespace vespalib::eval { + +/** + * Tagging interface used as return type from factories before + * downcasting to actual builder with specialized cell type. + **/ +struct ValueBuilderBase { + virtual ~ValueBuilderBase() {} +}; + +/** + * Interface used to build a value one dense subspace at a + * time. Enables decoupling of what the value should contain from how + * to store the value. + **/ +template <typename T> +struct ValueBuilder : ValueBuilderBase { + // add a dense subspace for the given address (label for all + // mapped dimensions in canonical order). Note that previously + // returned subspaces will be invalidated when new subspaces are + // added. Also note that adding the same subspace multiple times + // is not allowed. + virtual ArrayRef<T> add_subspace(ConstArrayRef<vespalib::stringref> addr) = 0; + + // add a dense subspace for the given address where labels are + // specified by shared string repo ids. Note that the caller is + // responsible for making sure the ids are valid 'long enough'. + virtual ArrayRef<T> add_subspace(ConstArrayRef<string_id> addr) = 0; + + // convenience function to add a subspace with an empty address + ArrayRef<T> add_subspace() { return add_subspace(ConstArrayRef<string_id>()); } + + // Given the ownership of the builder itself, produce the newly + // created value. This means that builders can only be used once, + // it also means values can build themselves. + virtual std::unique_ptr<Value> build(std::unique_ptr<ValueBuilder> self) = 0; +}; + +/** + * Factory able to create appropriate value builders. We do not really + * care about the full mathematical type here, but it needs to be + * passed since it is exposed in the value api. The expected number of + * subspaces is also passed since it enables the builder to pre-size + * internal structures appropriately. Note that since we are not able + * to have virtual templated functions we need to cast the created + * builder. With interoperability between all values. + **/ +struct ValueBuilderFactory { +private: + template <typename T> + std::unique_ptr<ValueBuilder<T>> create_value_builder(const ValueType &type, bool transient, + size_t num_mapped_dims_in, size_t subspace_size_in, size_t expected_subspaces) const + { + assert(check_cell_type<T>(type.cell_type())); + auto base = create_value_builder_base(type, transient, num_mapped_dims_in, subspace_size_in, expected_subspaces); + ValueBuilder<T> *builder = static_cast<ValueBuilder<T>*>(base.get()); + base.release(); + return std::unique_ptr<ValueBuilder<T>>(builder); + } +public: + template <typename T> + std::unique_ptr<ValueBuilder<T>> create_value_builder(const ValueType &type, + size_t num_mapped_dims_in, size_t subspace_size_in, size_t expected_subspaces) const + { + return create_value_builder<T>(type, false, num_mapped_dims_in, subspace_size_in, expected_subspaces); + } + template <typename T> + std::unique_ptr<ValueBuilder<T>> create_transient_value_builder(const ValueType &type, + size_t num_mapped_dims_in, size_t subspace_size_in, size_t expected_subspaces) const + { + return create_value_builder<T>(type, true, num_mapped_dims_in, subspace_size_in, expected_subspaces); + } + template <typename T> + std::unique_ptr<ValueBuilder<T>> create_value_builder(const ValueType &type) const + { + return create_value_builder<T>(type, false, type.count_mapped_dimensions(), type.dense_subspace_size(), 1); + } + std::unique_ptr<Value> copy(const Value &value) const; + virtual ~ValueBuilderFactory() {} +protected: + virtual std::unique_ptr<ValueBuilderBase> create_value_builder_base(const ValueType &type, bool transient, + size_t num_mapped_dims_in, size_t subspace_size_in, size_t expected_subspaces) const = 0; +}; + +} diff --git a/eval/src/vespa/eval/eval/value_cache/constant_tensor_loader.h b/eval/src/vespa/eval/eval/value_cache/constant_tensor_loader.h index c90ff611934..3cdbe2f68a1 100644 --- a/eval/src/vespa/eval/eval/value_cache/constant_tensor_loader.h +++ b/eval/src/vespa/eval/eval/value_cache/constant_tensor_loader.h @@ -5,8 +5,9 @@ #include "constant_value.h" #include <vespa/vespalib/stllike/string.h> -namespace vespalib { -namespace eval { +namespace vespalib::eval { + +class ValueBuilderFactory; /** * A ConstantValueFactory that will load constant tensor values from @@ -23,5 +24,4 @@ public: ConstantValue::UP create(const vespalib::string &path, const vespalib::string &type) const override; }; -} // namespace vespalib::eval -} // namespace vespalib +} diff --git a/eval/src/vespa/eval/eval/value_codec.cpp b/eval/src/vespa/eval/eval/value_codec.cpp index 369ffb85133..d5fc2eb7c16 100644 --- a/eval/src/vespa/eval/eval/value_codec.cpp +++ b/eval/src/vespa/eval/eval/value_codec.cpp @@ -3,6 +3,7 @@ #include "value_codec.h" #include "tensor_spec.h" #include "array_array_map.h" +#include "value_builder_factory.h" #include <vespa/vespalib/objects/nbostream.h> #include <vespa/vespalib/util/exceptions.h> #include <vespa/vespalib/util/typify.h> diff --git a/eval/src/vespa/eval/eval/value_codec.h b/eval/src/vespa/eval/eval/value_codec.h index 3495ef4ecdf..80d955853c4 100644 --- a/eval/src/vespa/eval/eval/value_codec.h +++ b/eval/src/vespa/eval/eval/value_codec.h @@ -13,6 +13,8 @@ namespace vespalib::eval { VESPA_DEFINE_EXCEPTION(DecodeValueException, Exception); +class ValueBuilderFactory; + /** * encode a value (which must support the new APIs) to binary format **/ diff --git a/eval/src/vespa/eval/instruction/generic_concat.cpp b/eval/src/vespa/eval/instruction/generic_concat.cpp index 1c91354e4cf..134bc1cb80b 100644 --- a/eval/src/vespa/eval/instruction/generic_concat.cpp +++ b/eval/src/vespa/eval/instruction/generic_concat.cpp @@ -2,7 +2,7 @@ #include "generic_concat.h" #include "generic_join.h" -#include <vespa/eval/eval/value.h> +#include <vespa/eval/eval/value_builder_factory.h> #include <vespa/eval/eval/wrap_param.h> #include <vespa/vespalib/util/overload.h> #include <vespa/vespalib/util/stash.h> diff --git a/eval/src/vespa/eval/instruction/generic_join.cpp b/eval/src/vespa/eval/instruction/generic_join.cpp index 60949a65b62..e1e02070466 100644 --- a/eval/src/vespa/eval/instruction/generic_join.cpp +++ b/eval/src/vespa/eval/instruction/generic_join.cpp @@ -3,6 +3,7 @@ #include "generic_join.h" #include <vespa/eval/eval/inline_operation.h> #include <vespa/eval/eval/wrap_param.h> +#include <vespa/eval/eval/value_builder_factory.h> #include <vespa/vespalib/util/overload.h> #include <vespa/vespalib/util/stash.h> #include <vespa/vespalib/util/typify.h> diff --git a/eval/src/vespa/eval/instruction/generic_merge.cpp b/eval/src/vespa/eval/instruction/generic_merge.cpp index 322935417ed..f6b4870be22 100644 --- a/eval/src/vespa/eval/instruction/generic_merge.cpp +++ b/eval/src/vespa/eval/instruction/generic_merge.cpp @@ -2,11 +2,11 @@ #include "generic_merge.h" #include <vespa/eval/eval/inline_operation.h> +#include <vespa/eval/eval/value_builder_factory.h> #include <vespa/eval/eval/wrap_param.h> #include <vespa/vespalib/util/stash.h> #include <vespa/vespalib/util/typify.h> #include <cassert> -#include <typeindex> using namespace vespalib::eval::tensor_function; diff --git a/eval/src/vespa/eval/instruction/generic_peek.cpp b/eval/src/vespa/eval/instruction/generic_peek.cpp index ea6e53e5505..426480dc976 100644 --- a/eval/src/vespa/eval/instruction/generic_peek.cpp +++ b/eval/src/vespa/eval/instruction/generic_peek.cpp @@ -1,6 +1,7 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include "generic_peek.h" +#include <vespa/eval/eval/value_builder_factory.h> #include <vespa/eval/eval/nested_loop.h> #include <vespa/eval/eval/wrap_param.h> #include <vespa/vespalib/util/stash.h> diff --git a/eval/src/vespa/eval/instruction/generic_reduce.cpp b/eval/src/vespa/eval/instruction/generic_reduce.cpp index db3b0e49222..71eb94f4118 100644 --- a/eval/src/vespa/eval/instruction/generic_reduce.cpp +++ b/eval/src/vespa/eval/instruction/generic_reduce.cpp @@ -1,7 +1,7 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include "generic_reduce.h" -#include <vespa/eval/eval/value.h> +#include <vespa/eval/eval/value_builder_factory.h> #include <vespa/eval/eval/wrap_param.h> #include <vespa/eval/eval/array_array_map.h> #include <vespa/vespalib/util/stash.h> diff --git a/eval/src/vespa/eval/instruction/generic_rename.cpp b/eval/src/vespa/eval/instruction/generic_rename.cpp index 06e1ece1e98..6bab1038e6d 100644 --- a/eval/src/vespa/eval/instruction/generic_rename.cpp +++ b/eval/src/vespa/eval/instruction/generic_rename.cpp @@ -1,7 +1,7 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include "generic_rename.h" -#include <vespa/eval/eval/value.h> +#include <vespa/eval/eval/value_builder_factory.h> #include <vespa/eval/eval/wrap_param.h> #include <vespa/vespalib/util/stash.h> #include <vespa/vespalib/util/typify.h> diff --git a/eval/src/vespa/eval/streamed/streamed_value_builder.h b/eval/src/vespa/eval/streamed/streamed_value_builder.h index f64dc74542c..506661b7cea 100644 --- a/eval/src/vespa/eval/streamed/streamed_value_builder.h +++ b/eval/src/vespa/eval/streamed/streamed_value_builder.h @@ -3,6 +3,7 @@ #pragma once #include "streamed_value.h" +#include <vespa/eval/eval/value_builder_factory.h> #include <vespa/vespalib/util/shared_string_repo.h> namespace vespalib::eval { diff --git a/eval/src/vespa/eval/streamed/streamed_value_builder_factory.h b/eval/src/vespa/eval/streamed/streamed_value_builder_factory.h index 540804affcc..ca11c5ed7af 100644 --- a/eval/src/vespa/eval/streamed/streamed_value_builder_factory.h +++ b/eval/src/vespa/eval/streamed/streamed_value_builder_factory.h @@ -3,6 +3,7 @@ #pragma once #include "streamed_value.h" +#include <vespa/eval/eval/value_builder_factory.h> namespace vespalib::eval { @@ -18,7 +19,7 @@ private: size_t subspace_size_in, size_t expected_subspaces) const override; public: static const StreamedValueBuilderFactory &get() { return _factory; } - ~StreamedValueBuilderFactory(); + ~StreamedValueBuilderFactory() override; }; } |