diff options
author | Geir Storli <geirst@verizonmedia.com> | 2020-02-18 13:09:59 +0000 |
---|---|---|
committer | Geir Storli <geirst@verizonmedia.com> | 2020-02-20 07:29:05 +0000 |
commit | 6e3070e67bd244a0d651051e6f71420c913fca78 (patch) | |
tree | 9afca0160043a792d5aa74477effe48289b9d1cc | |
parent | de87979afeea21a8a613f2e726be94e3bb2e860c (diff) |
Add hnsw index params to config for attribute vector.
5 files changed, 73 insertions, 6 deletions
diff --git a/searchcommon/src/vespa/searchcommon/attribute/config.cpp b/searchcommon/src/vespa/searchcommon/attribute/config.cpp index 53e57fd9c66..b4e05875820 100644 --- a/searchcommon/src/vespa/searchcommon/attribute/config.cpp +++ b/searchcommon/src/vespa/searchcommon/attribute/config.cpp @@ -17,7 +17,8 @@ Config::Config() : _growStrategy(), _compactionStrategy(), _predicateParams(), - _tensorType(vespalib::eval::ValueType::error_type()) + _tensorType(vespalib::eval::ValueType::error_type()), + _hnsw_index_params() { } @@ -34,7 +35,8 @@ Config::Config(BasicType bt, CollectionType ct, bool fastSearch_, bool huge_) _growStrategy(), _compactionStrategy(), _predicateParams(), - _tensorType(vespalib::eval::ValueType::error_type()) + _tensorType(vespalib::eval::ValueType::error_type()), + _hnsw_index_params() { } @@ -60,7 +62,8 @@ Config::operator==(const Config &b) const _compactionStrategy == b._compactionStrategy && _predicateParams == b._predicateParams && (_basicType.type() != BasicType::Type::TENSOR || - _tensorType == b._tensorType); + _tensorType == b._tensorType) && + _hnsw_index_params == b._hnsw_index_params; } } diff --git a/searchcommon/src/vespa/searchcommon/attribute/config.h b/searchcommon/src/vespa/searchcommon/attribute/config.h index 2f767061f7a..836fcfed84a 100644 --- a/searchcommon/src/vespa/searchcommon/attribute/config.h +++ b/searchcommon/src/vespa/searchcommon/attribute/config.h @@ -4,15 +4,21 @@ #include "basictype.h" #include "collectiontype.h" +#include "hnsw_index_params.h" #include "predicate_params.h" -#include <vespa/searchcommon/common/growstrategy.h> #include <vespa/searchcommon/common/compaction_strategy.h> +#include <vespa/searchcommon/common/growstrategy.h> #include <vespa/eval/eval/value_type.h> +#include <optional> namespace search::attribute { -class Config -{ +/** + * Configuration for an attribute vector. + * + * Used to determine which implementation to instantiate. + */ +class Config { public: Config(); Config(BasicType bt, CollectionType ct = CollectionType::SINGLE, @@ -29,6 +35,7 @@ public: bool huge() const { return _huge; } const PredicateParams &predicateParams() const { return _predicateParams; } vespalib::eval::ValueType tensorType() const { return _tensorType; } + const std::optional<HnswIndexParams>& hnsw_index_params() const { return _hnsw_index_params; } /** * Check if attribute posting list can consist of a bitvector in @@ -60,6 +67,10 @@ public: _tensorType = tensorType_in; return *this; } + Config& set_hnsw_index_params(const HnswIndexParams& params) { + _hnsw_index_params = params; + return *this; + } /** * Enable attribute posting list to consist of a bitvector in @@ -107,6 +118,7 @@ private: CompactionStrategy _compactionStrategy; PredicateParams _predicateParams; vespalib::eval::ValueType _tensorType; + std::optional<HnswIndexParams> _hnsw_index_params; }; } diff --git a/searchcommon/src/vespa/searchcommon/attribute/hnsw_index_params.h b/searchcommon/src/vespa/searchcommon/attribute/hnsw_index_params.h new file mode 100644 index 00000000000..9e98a8c5fb7 --- /dev/null +++ b/searchcommon/src/vespa/searchcommon/attribute/hnsw_index_params.h @@ -0,0 +1,32 @@ +// Copyright 2020 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#pragma once + +namespace search::attribute { + +/** + * Configuration parameters for a hnsw index used together with a 1-dimensional indexed tensor + * for approximate nearest neighbor search. + */ +class HnswIndexParams { +private: + uint32_t _max_links_per_node; + uint32_t _neighbors_to_explore_at_insert; + +public: + HnswIndexParams(uint32_t max_links_per_node_in, + uint32_t neighbors_to_explore_at_insert_in) + : _max_links_per_node(max_links_per_node_in), + _neighbors_to_explore_at_insert(neighbors_to_explore_at_insert_in) + {} + + uint32_t max_links_per_node() const { return _max_links_per_node; } + uint32_t neighbors_to_explore_at_insert() const { return _neighbors_to_explore_at_insert; } + + bool operator==(const HnswIndexParams& rhs) const { + return _max_links_per_node == rhs._max_links_per_node && + _neighbors_to_explore_at_insert == rhs._neighbors_to_explore_at_insert; + } +}; + +} diff --git a/searchlib/src/tests/attribute/attributemanager/attributemanager_test.cpp b/searchlib/src/tests/attribute/attributemanager/attributemanager_test.cpp index 7d09b2aa0b8..850a967ed3d 100644 --- a/searchlib/src/tests/attribute/attributemanager/attributemanager_test.cpp +++ b/searchlib/src/tests/attribute/attributemanager/attributemanager_test.cpp @@ -278,6 +278,22 @@ AttributeManagerTest::testConfigConvert() AttributeVector::Config out = ConfigConverter::convert(a); EXPECT_EQUAL("tensor(x[5])", out.tensorType().to_spec()); } + { // hnsw index params (enabled) + CACA a; + a.index.hnsw.enabled = true; + a.index.hnsw.maxlinkspernode = 32; + a.index.hnsw.neighborstoexploreatinsert = 300; + auto out = ConfigConverter::convert(a); + EXPECT_TRUE(out.hnsw_index_params().has_value()); + EXPECT_EQUAL(32u, out.hnsw_index_params().value().max_links_per_node()); + EXPECT_EQUAL(300u, out.hnsw_index_params().value().neighbors_to_explore_at_insert()); + } + { // hnsw index params (disabled) + CACA a; + a.index.hnsw.enabled = false; + auto out = ConfigConverter::convert(a); + EXPECT_FALSE(out.hnsw_index_params().has_value()); + } } bool gt_attribute(const attribute::IAttributeVector * a, const attribute::IAttributeVector * b) { diff --git a/searchlib/src/vespa/searchlib/attribute/configconverter.cpp b/searchlib/src/vespa/searchlib/attribute/configconverter.cpp index 535e81fc032..10e1a1edb52 100644 --- a/searchlib/src/vespa/searchlib/attribute/configconverter.cpp +++ b/searchlib/src/vespa/searchlib/attribute/configconverter.cpp @@ -73,6 +73,10 @@ ConfigConverter::convert(const AttributesConfig::Attribute & cfg) predicateParams.setBounds(cfg.lowerbound, cfg.upperbound); predicateParams.setDensePostingListThreshold(cfg.densepostinglistthreshold); retval.setPredicateParams(predicateParams); + if (cfg.index.hnsw.enabled) { + retval.set_hnsw_index_params(HnswIndexParams(cfg.index.hnsw.maxlinkspernode, + cfg.index.hnsw.neighborstoexploreatinsert)); + } if (retval.basicType().type() == BasicType::Type::TENSOR) { if (!cfg.tensortype.empty()) { retval.setTensorType(ValueType::from_spec(cfg.tensortype)); |