summaryrefslogtreecommitdiffstats
path: root/searchlib
diff options
context:
space:
mode:
authorArne Juul <arnej@verizonmedia.com>2020-04-06 08:53:32 +0000
committerArne Juul <arnej@verizonmedia.com>2020-04-06 10:39:20 +0000
commitd25ae106304c454c0d5f7e074357aafdee109835 (patch)
tree89180625998fdc21e3e7360d5529f8d4edeae025 /searchlib
parentcb28efe6ea469089913e277d70d9ed16c55f00a3 (diff)
add histogram for links on level 0
* also add stats for current config
Diffstat (limited to 'searchlib')
-rw-r--r--searchlib/src/vespa/searchlib/tensor/hnsw_graph.cpp29
-rw-r--r--searchlib/src/vespa/searchlib/tensor/hnsw_graph.h6
-rw-r--r--searchlib/src/vespa/searchlib/tensor/hnsw_index.cpp21
3 files changed, 40 insertions, 16 deletions
diff --git a/searchlib/src/vespa/searchlib/tensor/hnsw_graph.cpp b/searchlib/src/vespa/searchlib/tensor/hnsw_graph.cpp
index 6f902a30861..b6b3e670f08 100644
--- a/searchlib/src/vespa/searchlib/tensor/hnsw_graph.cpp
+++ b/searchlib/src/vespa/searchlib/tensor/hnsw_graph.cpp
@@ -50,21 +50,32 @@ HnswGraph::set_link_array(uint32_t docid, uint32_t level, const LinkArrayRef& ne
links.remove(old_links_ref);
}
-std::vector<uint32_t>
-HnswGraph::level_histogram() const
+HnswGraph::Histograms
+HnswGraph::histograms() const
{
- std::vector<uint32_t> result;
+ Histograms result;
size_t num_nodes = node_refs.size();
for (size_t i = 0; i < num_nodes; ++i) {
- uint32_t levels = 0;
auto node_ref = node_refs[i].load_acquire();
if (node_ref.valid()) {
- levels = nodes.get(node_ref).size();
+ uint32_t levels = 0;
+ uint32_t l0links = 0;
+ auto level_array = nodes.get(node_ref);
+ levels = level_array.size();
+ if (levels > 0) {
+ auto links_ref = level_array[0].load_acquire();
+ auto link_array = links.get(links_ref);
+ l0links = link_array.size();
+ }
+ while (result.level_histogram.size() <= levels) {
+ result.level_histogram.push_back(0);
+ }
+ ++result.level_histogram[levels];
+ while (result.links_histogram.size() <= l0links) {
+ result.links_histogram.push_back(0);
+ }
+ ++result.links_histogram[l0links];
}
- while (result.size() <= levels) {
- result.push_back(0);
- }
- ++result[levels];
}
return result;
}
diff --git a/searchlib/src/vespa/searchlib/tensor/hnsw_graph.h b/searchlib/src/vespa/searchlib/tensor/hnsw_graph.h
index 233b9087af7..f38f5ca0baf 100644
--- a/searchlib/src/vespa/searchlib/tensor/hnsw_graph.h
+++ b/searchlib/src/vespa/searchlib/tensor/hnsw_graph.h
@@ -70,7 +70,11 @@ struct HnswGraph {
size_t size() const { return node_refs.size(); }
- std::vector<uint32_t> level_histogram() const;
+ struct Histograms {
+ std::vector<uint32_t> level_histogram;
+ std::vector<uint32_t> links_histogram;
+ };
+ Histograms histograms() const;
};
}
diff --git a/searchlib/src/vespa/searchlib/tensor/hnsw_index.cpp b/searchlib/src/vespa/searchlib/tensor/hnsw_index.cpp
index b08d862ae6d..c1f6589b025 100644
--- a/searchlib/src/vespa/searchlib/tensor/hnsw_index.cpp
+++ b/searchlib/src/vespa/searchlib/tensor/hnsw_index.cpp
@@ -383,18 +383,27 @@ HnswIndex::get_state(const vespalib::slime::Inserter& inserter) const
StateExplorerUtils::memory_usage_to_slime(memory_usage(), object.setObject("memory_usage"));
object.setLong("nodes", _graph.size());
auto& histogram_array = object.setArray("level_histogram");
- auto level_histogram = _graph.level_histogram();
- for (uint32_t hist_val : level_histogram) {
+ auto& links_hst_array = object.setArray("level_0_links_histogram");
+ auto histograms = _graph.histograms();
+ uint32_t valid_nodes = 0;
+ for (uint32_t hist_val : histograms.level_histogram) {
histogram_array.addLong(hist_val);
+ valid_nodes += hist_val;
}
- uint32_t reachable = count_reachable_nodes();
- uint32_t unreachable = _graph.size() - reachable;
- if (level_histogram.size() > 0) {
- unreachable -= level_histogram[0];
+ object.setLong("valid_nodes", valid_nodes);
+ for (uint32_t hist_val : histograms.links_histogram) {
+ links_hst_array.addLong(hist_val);
}
+ uint32_t reachable = count_reachable_nodes();
+ uint32_t unreachable = valid_nodes - reachable;
object.setLong("unreachable_nodes", unreachable);
object.setLong("entry_docid", _graph.entry_docid);
object.setLong("entry_level", _graph.entry_level);
+ auto& cfgObj = object.setObject("cfg");
+ cfgObj.setLong("max_links_at_level_0", _cfg.max_links_at_level_0());
+ cfgObj.setLong("max_links_on_inserts", _cfg.max_links_on_inserts());
+ cfgObj.setLong("neighbors_to_explore_at_construction",
+ _cfg.neighbors_to_explore_at_construction());
}
std::unique_ptr<NearestNeighborIndexSaver>