From 52d1d4020073889962b4b73aebb13c3fc001dbaf Mon Sep 17 00:00:00 2001 From: "Corey J. Nolet" Date: Wed, 6 May 2026 23:59:11 -0400 Subject: [PATCH 001/129] Convert docs to Fern --- .github/CODEOWNERS | 1 + .github/workflows/check-c-abi.yaml | 2 +- .github/workflows/pr.yaml | 6 + build.sh | 18 +- ci/build_docs.sh | 37 +- ci/release/update-version.sh | 4 +- .../all_cuda-129_arch-aarch64.yaml | 12 +- .../all_cuda-129_arch-x86_64.yaml | 12 +- .../all_cuda-131_arch-aarch64.yaml | 12 +- .../all_cuda-131_arch-x86_64.yaml | 12 +- dependencies.yaml | 12 +- docs/Makefile | 20 - docs/README.md | 35 +- docs/make.bat | 36 - docs/source/_static/collapse_overloads.js | 67 - docs/source/_static/references.css | 36 - docs/source/advanced_topics.rst | 22 - docs/source/api_basics.rst | 90 - docs/source/api_docs.rst | 13 - docs/source/api_interoperability.rst | 106 - docs/source/build.rst | 285 -- docs/source/c_api.rst | 14 - docs/source/c_api/cluster.rst | 12 - docs/source/c_api/cluster_kmeans_c.rst | 27 - docs/source/c_api/core_c_api.rst | 32 - docs/source/c_api/distance.rst | 26 - docs/source/c_api/neighbors.rst | 19 - .../c_api/neighbors_all_neighbors_c.rst | 26 - docs/source/c_api/neighbors_bruteforce_c.rst | 42 - docs/source/c_api/neighbors_cagra_c.rst | 67 - docs/source/c_api/neighbors_hnsw_c.rst | 65 - docs/source/c_api/neighbors_ivf_flat_c.rst | 58 - docs/source/c_api/neighbors_ivf_pq_c.rst | 58 - docs/source/c_api/neighbors_mg.rst | 257 -- docs/source/c_api/neighbors_vamana_c.rst | 43 - docs/source/c_api/preprocessing.rst | 38 - docs/source/conf.py | 220 -- docs/source/cpp_api.rst | 15 - docs/source/cpp_api/cluster.rst | 14 - docs/source/cpp_api/cluster_agglomerative.rst | 31 - docs/source/cpp_api/cluster_kmeans.rst | 44 - docs/source/cpp_api/cluster_spectral.rst | 28 - docs/source/cpp_api/distance.rst | 32 - docs/source/cpp_api/neighbors.rst | 24 - .../cpp_api/neighbors_all_neighbors.rst | 29 - docs/source/cpp_api/neighbors_bruteforce.rst | 44 - docs/source/cpp_api/neighbors_cagra.rst | 84 - .../cpp_api/neighbors_dynamic_batching.rst | 45 - .../neighbors_epsilon_neighborhood.rst | 20 - docs/source/cpp_api/neighbors_filter.rst | 18 - docs/source/cpp_api/neighbors_hnsw.rst | 67 - docs/source/cpp_api/neighbors_ivf_flat.rst | 68 - docs/source/cpp_api/neighbors_ivf_pq.rst | 80 - docs/source/cpp_api/neighbors_mg.rst | 76 - docs/source/cpp_api/neighbors_nn_descent.rst | 37 - docs/source/cpp_api/neighbors_refine.rst | 20 - docs/source/cpp_api/neighbors_vamana.rst | 44 - docs/source/cpp_api/preprocessing.rst | 14 - docs/source/cpp_api/preprocessing_pca.rst | 27 - .../source/cpp_api/preprocessing_quantize.rst | 45 - .../preprocessing_spectral_embedding.rst | 108 - docs/source/cpp_api/selection.rst | 19 - docs/source/cpp_api/stats.rst | 34 - docs/source/cuvs_bench/index.rst | 661 ---- docs/source/cuvs_bench/param_tuning.rst | 918 ------ docs/source/cuvs_bench/pluggable_backend.rst | 241 -- docs/source/filtering.rst | 116 - docs/source/getting_started.rst | 124 - docs/source/integrations.rst | 13 - docs/source/integrations/kinetica.rst | 6 - docs/source/neighbors/cagra.rst | 276 -- docs/source/neighbors/ivfflat.rst | 115 - docs/source/neighbors/ivfpq.rst | 135 - docs/source/neighbors/neighbors.rst | 21 - docs/source/neighbors/vamana.rst | 75 - docs/source/python_api.rst | 13 - docs/source/python_api/cluster.rst | 12 - docs/source/python_api/cluster_kmeans.rst | 27 - docs/source/python_api/distance.rst | 12 - docs/source/python_api/neighbors.rst | 19 - .../python_api/neighbors_all_neighbors.rst | 19 - .../python_api/neighbors_brute_force.rst | 32 - docs/source/python_api/neighbors_cagra.rst | 51 - docs/source/python_api/neighbors_hnsw.rst | 45 - docs/source/python_api/neighbors_ivf_flat.rst | 49 - docs/source/python_api/neighbors_ivf_pq.rst | 49 - docs/source/python_api/neighbors_mg_cagra.rst | 55 - .../python_api/neighbors_mg_ivf_flat.rst | 60 - .../source/python_api/neighbors_mg_ivf_pq.rst | 60 - .../source/python_api/neighbors_multi_gpu.rst | 118 - .../source/python_api/neighbors_nn_decent.rst | 24 - docs/source/python_api/preprocessing.rst | 55 - docs/source/rust_api/index.rst | 15 - docs/source/sphinxext/github_link.py | 154 - docs/source/working_with_ann_indexes.rst | 11 - docs/source/working_with_ann_indexes_c.rst | 62 - docs/source/working_with_ann_indexes_cpp.rst | 43 - .../working_with_ann_indexes_python.rst | 33 - docs/source/working_with_ann_indexes_rust.rst | 62 - fern/README.md | 37 + fern/assets/rapids_logo.png | Bin 0 -> 113880 bytes fern/build_docs.sh | 90 + fern/docs.yml | 395 +++ fern/fern.config.json | 4 + fern/pages/advanced_topics.md | 14 + fern/pages/api_basics.md | 80 + fern/pages/api_docs.md | 8 + fern/pages/api_interoperability.md | 105 + fern/pages/build.md | 242 ++ fern/pages/c_api/c-api-cluster-kmeans.md | 216 ++ fern/pages/c_api/c-api-core-c-api.md | 577 ++++ .../c_api/c-api-distance-pairwise-distance.md | 43 + .../c_api/c-api-neighbors-all-neighbors.md | 132 + .../c_api/c-api-neighbors-brute-force.md | 181 ++ fern/pages/c_api/c-api-neighbors-cagra.md | 867 ++++++ fern/pages/c_api/c-api-neighbors-common.md | 50 + fern/pages/c_api/c-api-neighbors-hnsw.md | 515 +++ fern/pages/c_api/c-api-neighbors-ivf-flat.md | 413 +++ fern/pages/c_api/c-api-neighbors-ivf-pq.md | 789 +++++ fern/pages/c_api/c-api-neighbors-mg-cagra.md | 381 +++ fern/pages/c_api/c-api-neighbors-mg-common.md | 55 + .../c_api/c-api-neighbors-mg-ivf-flat.md | 381 +++ fern/pages/c_api/c-api-neighbors-mg-ivf-pq.md | 381 +++ .../pages/c_api/c-api-neighbors-nn-descent.md | 162 + fern/pages/c_api/c-api-neighbors-refine.md | 45 + .../c_api/c-api-neighbors-tiered-index.md | 259 ++ fern/pages/c_api/c-api-neighbors-vamana.md | 220 ++ fern/pages/c_api/c-api-preprocessing-pca.md | 251 ++ .../c-api-preprocessing-quantize-binary.md | 216 ++ .../c_api/c-api-preprocessing-quantize-pq.md | 338 ++ .../c-api-preprocessing-quantize-scalar.md | 195 ++ fern/pages/c_api/index.md | 26 + .../pages/choosing_and_configuring_indexes.md | 77 +- .../pages/comparing_indexes.md | 38 +- {docs/source => fern/pages}/contributing.md | 3 - .../cpp_api/cpp-api-cluster-agglomerative.md | 218 ++ fern/pages/cpp_api/cpp-api-cluster-kmeans.md | 1150 +++++++ .../pages/cpp_api/cpp-api-cluster-spectral.md | 120 + .../cpp_api/cpp-api-distance-distance.md | 273 ++ .../cpp-api-neighbors-all-neighbors.md | 118 + .../cpp_api/cpp-api-neighbors-ball-cover.md | 34 + .../cpp_api/cpp-api-neighbors-brute-force.md | 812 +++++ fern/pages/cpp_api/cpp-api-neighbors-cagra.md | 1827 +++++++++++ .../pages/cpp_api/cpp-api-neighbors-common.md | 235 ++ .../cpp-api-neighbors-dynamic-batching.md | 321 ++ .../cpp-api-neighbors-epsilon-neighborhood.md | 54 + fern/pages/cpp_api/cpp-api-neighbors-hnsw.md | 896 ++++++ .../cpp_api/cpp-api-neighbors-ivf-flat.md | 2337 ++++++++++++++ .../pages/cpp_api/cpp-api-neighbors-ivf-pq.md | 2547 +++++++++++++++ .../cpp_api/cpp-api-neighbors-nn-descent.md | 494 +++ .../pages/cpp_api/cpp-api-neighbors-refine.md | 351 +++ fern/pages/cpp_api/cpp-api-neighbors-scann.md | 168 + .../pages/cpp_api/cpp-api-neighbors-vamana.md | 600 ++++ .../cpp_api/cpp-api-preprocessing-pca.md | 161 + .../cpp-api-preprocessing-quantize-binary.md | 554 ++++ .../cpp-api-preprocessing-quantize-pq.md | 230 ++ .../cpp-api-preprocessing-quantize-scalar.md | 531 ++++ ...pp-api-preprocessing-spectral-embedding.md | 67 + .../cpp_api/cpp-api-selection-select-k.md | 128 + .../cpp_api/cpp-api-stats-silhouette-score.md | 155 + .../cpp-api-stats-trustworthiness-score.md | 46 + fern/pages/cpp_api/index.md | 30 + .../pages/cuvs_bench/build.md | 34 +- .../pages/cuvs_bench/datasets.md | 61 +- fern/pages/cuvs_bench/index.md | 512 +++ fern/pages/cuvs_bench/param_tuning.md | 251 ++ fern/pages/cuvs_bench/pluggable_backend.md | 224 ++ .../pages/cuvs_bench/wiki_all_dataset.md | 78 +- .../source => fern/pages}/developer_guide.md | 71 +- fern/pages/filtering.md | 108 + fern/pages/getting_started.md | 100 + fern/pages/go_api/go-api-brute-force.md | 79 + fern/pages/go_api/go-api-cagra.md | 529 ++++ fern/pages/go_api/go-api-cuvs.md | 339 ++ fern/pages/go_api/go-api-ivf-flat.md | 238 ++ fern/pages/go_api/go-api-ivf-pq.md | 346 +++ fern/pages/go_api/index.md | 9 + .../pages}/images/build_benchmarks.png | Bin .../pages}/images/index_recalls.png | Bin .../pages}/images/recall_buckets.png | Bin fern/pages/img/tech_stack.png | Bin 0 -> 189873 bytes docs/source/index.rst => fern/pages/index.md | 70 +- fern/pages/integrations.md | 10 + .../pages/integrations/faiss.md | 5 +- fern/pages/integrations/kinetica.md | 5 + .../pages/integrations/lucene.md | 5 +- .../pages/integrations/milvus.md | 7 +- fern/pages/java_api/index.md | 44 + ...ava-api-com-nvidia-cuvs-bruteforceindex.md | 203 ++ ...i-com-nvidia-cuvs-bruteforceindexparams.md | 61 + ...ava-api-com-nvidia-cuvs-bruteforcequery.md | 237 ++ ...-com-nvidia-cuvs-cagracompressionparams.md | 273 ++ .../java-api-com-nvidia-cuvs-cagraindex.md | 409 +++ ...va-api-com-nvidia-cuvs-cagraindexparams.md | 608 ++++ ...va-api-com-nvidia-cuvs-cagramergeparams.md | 114 + .../java-api-com-nvidia-cuvs-cagraquery.md | 273 ++ ...a-api-com-nvidia-cuvs-cagrasearchparams.md | 591 ++++ .../java-api-com-nvidia-cuvs-cuvsaceparams.md | 246 ++ ...va-api-com-nvidia-cuvs-cuvsdevicematrix.md | 29 + ...java-api-com-nvidia-cuvs-cuvshostmatrix.md | 15 + ...pi-com-nvidia-cuvs-cuvsivfpqindexparams.md | 439 +++ ...ava-api-com-nvidia-cuvs-cuvsivfpqparams.md | 133 + ...i-com-nvidia-cuvs-cuvsivfpqsearchparams.md | 168 + .../java-api-com-nvidia-cuvs-cuvsmatrix.md | 366 +++ .../java-api-com-nvidia-cuvs-cuvsresources.md | 115 + ...a-api-com-nvidia-cuvs-cuvsresourcesinfo.md | 24 + ...-com-nvidia-cuvs-delegatingscopedaccess.md | 13 + .../java-api-com-nvidia-cuvs-gpuinfo.md | 27 + ...ava-api-com-nvidia-cuvs-gpuinfoprovider.md | 64 + .../java-api-com-nvidia-cuvs-hnswaceparams.md | 236 ++ .../java-api-com-nvidia-cuvs-hnswindex.md | 189 ++ ...ava-api-com-nvidia-cuvs-hnswindexparams.md | 294 ++ .../java-api-com-nvidia-cuvs-hnswquery.md | 223 ++ ...va-api-com-nvidia-cuvs-hnswsearchparams.md | 89 + ...va-api-com-nvidia-cuvs-libraryexception.md | 13 + .../java-api-com-nvidia-cuvs-rowview.md | 119 + .../java-api-com-nvidia-cuvs-searchresults.md | 49 + ...va-api-com-nvidia-cuvs-spi-cuvsprovider.md | 415 +++ ...com-nvidia-cuvs-spi-cuvsserviceprovider.md | 37 + ...m-nvidia-cuvs-synchronizedcuvsresources.md | 15 + .../java-api-com-nvidia-cuvs-tieredindex.md | 312 ++ ...a-api-com-nvidia-cuvs-tieredindexparams.md | 233 ++ ...va-api-com-nvidia-cuvs-tieredindexquery.md | 315 ++ {docs/source => fern/pages}/jit_lto_guide.md | 2 +- .../pages/neighbors/all_neighbors.md | 19 +- .../pages/neighbors/bruteforce.md | 37 +- fern/pages/neighbors/cagra.md | 224 ++ fern/pages/neighbors/ivfflat.md | 77 + fern/pages/neighbors/ivfpq.md | 85 + fern/pages/neighbors/neighbors.md | 10 + fern/pages/neighbors/vamana.md | 49 + fern/pages/python_api/index.md | 42 + .../python_api/python-api-cluster-kmeans.md | 334 ++ fern/pages/python_api/python-api-common.md | 215 ++ fern/pages/python_api/python-api-distance.md | 89 + .../python-api-neighbors-all-neighbors.md | 129 + .../python-api-neighbors-brute-force.md | 248 ++ .../python_api/python-api-neighbors-cagra.md | 806 +++++ .../python-api-neighbors-filters.md | 107 + .../python_api/python-api-neighbors-hnsw.md | 593 ++++ .../python-api-neighbors-ivf-flat.md | 441 +++ .../python_api/python-api-neighbors-ivf-pq.md | 809 +++++ .../python-api-neighbors-mg-cagra.md | 418 +++ .../python-api-neighbors-mg-ivf-flat.md | 416 +++ .../python-api-neighbors-mg-ivf-pq.md | 415 +++ .../python-api-neighbors-nn-descent.md | 192 ++ .../python-api-neighbors-tiered-index.md | 249 ++ .../python_api/python-api-neighbors-vamana.md | 239 ++ fern/pages/python_api/python-api-neighbors.md | 69 + .../python-api-preprocessing-pca.md | 264 ++ ...ython-api-preprocessing-quantize-binary.md | 56 + .../python-api-preprocessing-quantize-pq.md | 330 ++ ...ython-api-preprocessing-quantize-scalar.md | 192 ++ fern/pages/rust_api/index.md | 40 + .../rust_api/rust-api-cuvs-brute-force.md | 85 + .../rust-api-cuvs-cagra-index-params.md | 197 ++ .../rust_api/rust-api-cuvs-cagra-index.md | 179 ++ .../rust-api-cuvs-cagra-search-params.md | 185 ++ fern/pages/rust_api/rust-api-cuvs-cagra.md | 119 + .../rust-api-cuvs-cluster-kmeans-params.md | 141 + .../rust_api/rust-api-cuvs-cluster-kmeans.md | 117 + fern/pages/rust_api/rust-api-cuvs-cluster.md | 17 + .../rust_api/rust-api-cuvs-distance-type.md | 17 + fern/pages/rust_api/rust-api-cuvs-distance.md | 35 + fern/pages/rust_api/rust-api-cuvs-dlpack.md | 74 + fern/pages/rust_api/rust-api-cuvs-error.md | 53 + .../rust-api-cuvs-ivf-flat-index-params.md | 104 + .../rust_api/rust-api-cuvs-ivf-flat-index.md | 83 + .../rust-api-cuvs-ivf-flat-search-params.md | 46 + fern/pages/rust_api/rust-api-cuvs-ivf-flat.md | 97 + .../rust-api-cuvs-ivf-pq-index-params.md | 209 ++ .../rust_api/rust-api-cuvs-ivf-pq-index.md | 83 + .../rust-api-cuvs-ivf-pq-search-params.md | 84 + fern/pages/rust_api/rust-api-cuvs-ivf-pq.md | 95 + .../pages/rust_api/rust-api-cuvs-resources.md | 71 + .../rust-api-cuvs-vamana-index-params.md | 135 + .../rust_api/rust-api-cuvs-vamana-index.md | 85 + fern/pages/rust_api/rust-api-cuvs-vamana.md | 27 + fern/pages/rust_api/rust-api-cuvs.md | 102 + .../pages/tuning_guide.md | 45 +- .../vector_databases_vs_vector_search.md | 24 +- fern/pages/working_with_ann_indexes.md | 8 + fern/pages/working_with_ann_indexes_c.md | 58 + fern/pages/working_with_ann_indexes_cpp.md | 39 + fern/pages/working_with_ann_indexes_python.md | 29 + fern/pages/working_with_ann_indexes_rust.md | 60 + fern/scripts/generate_api_reference.py | 2755 +++++++++++++++++ 287 files changed, 44716 insertions(+), 6943 deletions(-) delete mode 100644 docs/Makefile delete mode 100644 docs/make.bat delete mode 100644 docs/source/_static/collapse_overloads.js delete mode 100644 docs/source/_static/references.css delete mode 100644 docs/source/advanced_topics.rst delete mode 100644 docs/source/api_basics.rst delete mode 100644 docs/source/api_docs.rst delete mode 100644 docs/source/api_interoperability.rst delete mode 100644 docs/source/build.rst delete mode 100644 docs/source/c_api.rst delete mode 100644 docs/source/c_api/cluster.rst delete mode 100644 docs/source/c_api/cluster_kmeans_c.rst delete mode 100644 docs/source/c_api/core_c_api.rst delete mode 100644 docs/source/c_api/distance.rst delete mode 100644 docs/source/c_api/neighbors.rst delete mode 100644 docs/source/c_api/neighbors_all_neighbors_c.rst delete mode 100644 docs/source/c_api/neighbors_bruteforce_c.rst delete mode 100644 docs/source/c_api/neighbors_cagra_c.rst delete mode 100644 docs/source/c_api/neighbors_hnsw_c.rst delete mode 100644 docs/source/c_api/neighbors_ivf_flat_c.rst delete mode 100644 docs/source/c_api/neighbors_ivf_pq_c.rst delete mode 100644 docs/source/c_api/neighbors_mg.rst delete mode 100644 docs/source/c_api/neighbors_vamana_c.rst delete mode 100644 docs/source/c_api/preprocessing.rst delete mode 100644 docs/source/conf.py delete mode 100644 docs/source/cpp_api.rst delete mode 100644 docs/source/cpp_api/cluster.rst delete mode 100644 docs/source/cpp_api/cluster_agglomerative.rst delete mode 100644 docs/source/cpp_api/cluster_kmeans.rst delete mode 100644 docs/source/cpp_api/cluster_spectral.rst delete mode 100644 docs/source/cpp_api/distance.rst delete mode 100644 docs/source/cpp_api/neighbors.rst delete mode 100644 docs/source/cpp_api/neighbors_all_neighbors.rst delete mode 100644 docs/source/cpp_api/neighbors_bruteforce.rst delete mode 100644 docs/source/cpp_api/neighbors_cagra.rst delete mode 100644 docs/source/cpp_api/neighbors_dynamic_batching.rst delete mode 100644 docs/source/cpp_api/neighbors_epsilon_neighborhood.rst delete mode 100644 docs/source/cpp_api/neighbors_filter.rst delete mode 100644 docs/source/cpp_api/neighbors_hnsw.rst delete mode 100644 docs/source/cpp_api/neighbors_ivf_flat.rst delete mode 100644 docs/source/cpp_api/neighbors_ivf_pq.rst delete mode 100644 docs/source/cpp_api/neighbors_mg.rst delete mode 100644 docs/source/cpp_api/neighbors_nn_descent.rst delete mode 100644 docs/source/cpp_api/neighbors_refine.rst delete mode 100644 docs/source/cpp_api/neighbors_vamana.rst delete mode 100644 docs/source/cpp_api/preprocessing.rst delete mode 100644 docs/source/cpp_api/preprocessing_pca.rst delete mode 100644 docs/source/cpp_api/preprocessing_quantize.rst delete mode 100644 docs/source/cpp_api/preprocessing_spectral_embedding.rst delete mode 100644 docs/source/cpp_api/selection.rst delete mode 100644 docs/source/cpp_api/stats.rst delete mode 100644 docs/source/cuvs_bench/index.rst delete mode 100644 docs/source/cuvs_bench/param_tuning.rst delete mode 100644 docs/source/cuvs_bench/pluggable_backend.rst delete mode 100644 docs/source/filtering.rst delete mode 100644 docs/source/getting_started.rst delete mode 100644 docs/source/integrations.rst delete mode 100644 docs/source/integrations/kinetica.rst delete mode 100644 docs/source/neighbors/cagra.rst delete mode 100644 docs/source/neighbors/ivfflat.rst delete mode 100644 docs/source/neighbors/ivfpq.rst delete mode 100644 docs/source/neighbors/neighbors.rst delete mode 100644 docs/source/neighbors/vamana.rst delete mode 100644 docs/source/python_api.rst delete mode 100644 docs/source/python_api/cluster.rst delete mode 100644 docs/source/python_api/cluster_kmeans.rst delete mode 100644 docs/source/python_api/distance.rst delete mode 100644 docs/source/python_api/neighbors.rst delete mode 100644 docs/source/python_api/neighbors_all_neighbors.rst delete mode 100644 docs/source/python_api/neighbors_brute_force.rst delete mode 100644 docs/source/python_api/neighbors_cagra.rst delete mode 100644 docs/source/python_api/neighbors_hnsw.rst delete mode 100644 docs/source/python_api/neighbors_ivf_flat.rst delete mode 100644 docs/source/python_api/neighbors_ivf_pq.rst delete mode 100644 docs/source/python_api/neighbors_mg_cagra.rst delete mode 100644 docs/source/python_api/neighbors_mg_ivf_flat.rst delete mode 100644 docs/source/python_api/neighbors_mg_ivf_pq.rst delete mode 100644 docs/source/python_api/neighbors_multi_gpu.rst delete mode 100644 docs/source/python_api/neighbors_nn_decent.rst delete mode 100644 docs/source/python_api/preprocessing.rst delete mode 100644 docs/source/rust_api/index.rst delete mode 100644 docs/source/sphinxext/github_link.py delete mode 100644 docs/source/working_with_ann_indexes.rst delete mode 100644 docs/source/working_with_ann_indexes_c.rst delete mode 100644 docs/source/working_with_ann_indexes_cpp.rst delete mode 100644 docs/source/working_with_ann_indexes_python.rst delete mode 100644 docs/source/working_with_ann_indexes_rust.rst create mode 100644 fern/README.md create mode 100644 fern/assets/rapids_logo.png create mode 100755 fern/build_docs.sh create mode 100644 fern/docs.yml create mode 100644 fern/fern.config.json create mode 100644 fern/pages/advanced_topics.md create mode 100644 fern/pages/api_basics.md create mode 100644 fern/pages/api_docs.md create mode 100644 fern/pages/api_interoperability.md create mode 100644 fern/pages/build.md create mode 100644 fern/pages/c_api/c-api-cluster-kmeans.md create mode 100644 fern/pages/c_api/c-api-core-c-api.md create mode 100644 fern/pages/c_api/c-api-distance-pairwise-distance.md create mode 100644 fern/pages/c_api/c-api-neighbors-all-neighbors.md create mode 100644 fern/pages/c_api/c-api-neighbors-brute-force.md create mode 100644 fern/pages/c_api/c-api-neighbors-cagra.md create mode 100644 fern/pages/c_api/c-api-neighbors-common.md create mode 100644 fern/pages/c_api/c-api-neighbors-hnsw.md create mode 100644 fern/pages/c_api/c-api-neighbors-ivf-flat.md create mode 100644 fern/pages/c_api/c-api-neighbors-ivf-pq.md create mode 100644 fern/pages/c_api/c-api-neighbors-mg-cagra.md create mode 100644 fern/pages/c_api/c-api-neighbors-mg-common.md create mode 100644 fern/pages/c_api/c-api-neighbors-mg-ivf-flat.md create mode 100644 fern/pages/c_api/c-api-neighbors-mg-ivf-pq.md create mode 100644 fern/pages/c_api/c-api-neighbors-nn-descent.md create mode 100644 fern/pages/c_api/c-api-neighbors-refine.md create mode 100644 fern/pages/c_api/c-api-neighbors-tiered-index.md create mode 100644 fern/pages/c_api/c-api-neighbors-vamana.md create mode 100644 fern/pages/c_api/c-api-preprocessing-pca.md create mode 100644 fern/pages/c_api/c-api-preprocessing-quantize-binary.md create mode 100644 fern/pages/c_api/c-api-preprocessing-quantize-pq.md create mode 100644 fern/pages/c_api/c-api-preprocessing-quantize-scalar.md create mode 100644 fern/pages/c_api/index.md rename docs/source/choosing_and_configuring_indexes.rst => fern/pages/choosing_and_configuring_indexes.md (68%) rename docs/source/comparing_indexes.rst => fern/pages/comparing_indexes.md (84%) rename {docs/source => fern/pages}/contributing.md (99%) create mode 100644 fern/pages/cpp_api/cpp-api-cluster-agglomerative.md create mode 100644 fern/pages/cpp_api/cpp-api-cluster-kmeans.md create mode 100644 fern/pages/cpp_api/cpp-api-cluster-spectral.md create mode 100644 fern/pages/cpp_api/cpp-api-distance-distance.md create mode 100644 fern/pages/cpp_api/cpp-api-neighbors-all-neighbors.md create mode 100644 fern/pages/cpp_api/cpp-api-neighbors-ball-cover.md create mode 100644 fern/pages/cpp_api/cpp-api-neighbors-brute-force.md create mode 100644 fern/pages/cpp_api/cpp-api-neighbors-cagra.md create mode 100644 fern/pages/cpp_api/cpp-api-neighbors-common.md create mode 100644 fern/pages/cpp_api/cpp-api-neighbors-dynamic-batching.md create mode 100644 fern/pages/cpp_api/cpp-api-neighbors-epsilon-neighborhood.md create mode 100644 fern/pages/cpp_api/cpp-api-neighbors-hnsw.md create mode 100644 fern/pages/cpp_api/cpp-api-neighbors-ivf-flat.md create mode 100644 fern/pages/cpp_api/cpp-api-neighbors-ivf-pq.md create mode 100644 fern/pages/cpp_api/cpp-api-neighbors-nn-descent.md create mode 100644 fern/pages/cpp_api/cpp-api-neighbors-refine.md create mode 100644 fern/pages/cpp_api/cpp-api-neighbors-scann.md create mode 100644 fern/pages/cpp_api/cpp-api-neighbors-vamana.md create mode 100644 fern/pages/cpp_api/cpp-api-preprocessing-pca.md create mode 100644 fern/pages/cpp_api/cpp-api-preprocessing-quantize-binary.md create mode 100644 fern/pages/cpp_api/cpp-api-preprocessing-quantize-pq.md create mode 100644 fern/pages/cpp_api/cpp-api-preprocessing-quantize-scalar.md create mode 100644 fern/pages/cpp_api/cpp-api-preprocessing-spectral-embedding.md create mode 100644 fern/pages/cpp_api/cpp-api-selection-select-k.md create mode 100644 fern/pages/cpp_api/cpp-api-stats-silhouette-score.md create mode 100644 fern/pages/cpp_api/cpp-api-stats-trustworthiness-score.md create mode 100644 fern/pages/cpp_api/index.md rename docs/source/cuvs_bench/build.rst => fern/pages/cuvs_bench/build.md (70%) rename docs/source/cuvs_bench/datasets.rst => fern/pages/cuvs_bench/datasets.md (57%) create mode 100644 fern/pages/cuvs_bench/index.md create mode 100644 fern/pages/cuvs_bench/param_tuning.md create mode 100644 fern/pages/cuvs_bench/pluggable_backend.md rename docs/source/cuvs_bench/wiki_all_dataset.rst => fern/pages/cuvs_bench/wiki_all_dataset.md (54%) rename {docs/source => fern/pages}/developer_guide.md (94%) create mode 100644 fern/pages/filtering.md create mode 100644 fern/pages/getting_started.md create mode 100644 fern/pages/go_api/go-api-brute-force.md create mode 100644 fern/pages/go_api/go-api-cagra.md create mode 100644 fern/pages/go_api/go-api-cuvs.md create mode 100644 fern/pages/go_api/go-api-ivf-flat.md create mode 100644 fern/pages/go_api/go-api-ivf-pq.md create mode 100644 fern/pages/go_api/index.md rename {docs/source => fern/pages}/images/build_benchmarks.png (100%) rename {docs/source => fern/pages}/images/index_recalls.png (100%) rename {docs/source => fern/pages}/images/recall_buckets.png (100%) create mode 100644 fern/pages/img/tech_stack.png rename docs/source/index.rst => fern/pages/index.md (60%) create mode 100644 fern/pages/integrations.md rename docs/source/integrations/faiss.rst => fern/pages/integrations/faiss.md (73%) create mode 100644 fern/pages/integrations/kinetica.md rename docs/source/integrations/lucene.rst => fern/pages/integrations/lucene.md (74%) rename docs/source/integrations/milvus.rst => fern/pages/integrations/milvus.md (59%) create mode 100644 fern/pages/java_api/index.md create mode 100644 fern/pages/java_api/java-api-com-nvidia-cuvs-bruteforceindex.md create mode 100644 fern/pages/java_api/java-api-com-nvidia-cuvs-bruteforceindexparams.md create mode 100644 fern/pages/java_api/java-api-com-nvidia-cuvs-bruteforcequery.md create mode 100644 fern/pages/java_api/java-api-com-nvidia-cuvs-cagracompressionparams.md create mode 100644 fern/pages/java_api/java-api-com-nvidia-cuvs-cagraindex.md create mode 100644 fern/pages/java_api/java-api-com-nvidia-cuvs-cagraindexparams.md create mode 100644 fern/pages/java_api/java-api-com-nvidia-cuvs-cagramergeparams.md create mode 100644 fern/pages/java_api/java-api-com-nvidia-cuvs-cagraquery.md create mode 100644 fern/pages/java_api/java-api-com-nvidia-cuvs-cagrasearchparams.md create mode 100644 fern/pages/java_api/java-api-com-nvidia-cuvs-cuvsaceparams.md create mode 100644 fern/pages/java_api/java-api-com-nvidia-cuvs-cuvsdevicematrix.md create mode 100644 fern/pages/java_api/java-api-com-nvidia-cuvs-cuvshostmatrix.md create mode 100644 fern/pages/java_api/java-api-com-nvidia-cuvs-cuvsivfpqindexparams.md create mode 100644 fern/pages/java_api/java-api-com-nvidia-cuvs-cuvsivfpqparams.md create mode 100644 fern/pages/java_api/java-api-com-nvidia-cuvs-cuvsivfpqsearchparams.md create mode 100644 fern/pages/java_api/java-api-com-nvidia-cuvs-cuvsmatrix.md create mode 100644 fern/pages/java_api/java-api-com-nvidia-cuvs-cuvsresources.md create mode 100644 fern/pages/java_api/java-api-com-nvidia-cuvs-cuvsresourcesinfo.md create mode 100644 fern/pages/java_api/java-api-com-nvidia-cuvs-delegatingscopedaccess.md create mode 100644 fern/pages/java_api/java-api-com-nvidia-cuvs-gpuinfo.md create mode 100644 fern/pages/java_api/java-api-com-nvidia-cuvs-gpuinfoprovider.md create mode 100644 fern/pages/java_api/java-api-com-nvidia-cuvs-hnswaceparams.md create mode 100644 fern/pages/java_api/java-api-com-nvidia-cuvs-hnswindex.md create mode 100644 fern/pages/java_api/java-api-com-nvidia-cuvs-hnswindexparams.md create mode 100644 fern/pages/java_api/java-api-com-nvidia-cuvs-hnswquery.md create mode 100644 fern/pages/java_api/java-api-com-nvidia-cuvs-hnswsearchparams.md create mode 100644 fern/pages/java_api/java-api-com-nvidia-cuvs-libraryexception.md create mode 100644 fern/pages/java_api/java-api-com-nvidia-cuvs-rowview.md create mode 100644 fern/pages/java_api/java-api-com-nvidia-cuvs-searchresults.md create mode 100644 fern/pages/java_api/java-api-com-nvidia-cuvs-spi-cuvsprovider.md create mode 100644 fern/pages/java_api/java-api-com-nvidia-cuvs-spi-cuvsserviceprovider.md create mode 100644 fern/pages/java_api/java-api-com-nvidia-cuvs-synchronizedcuvsresources.md create mode 100644 fern/pages/java_api/java-api-com-nvidia-cuvs-tieredindex.md create mode 100644 fern/pages/java_api/java-api-com-nvidia-cuvs-tieredindexparams.md create mode 100644 fern/pages/java_api/java-api-com-nvidia-cuvs-tieredindexquery.md rename {docs/source => fern/pages}/jit_lto_guide.md (99%) rename docs/source/neighbors/all_neighbors.rst => fern/pages/neighbors/all_neighbors.md (89%) rename docs/source/neighbors/bruteforce.rst => fern/pages/neighbors/bruteforce.md (69%) create mode 100644 fern/pages/neighbors/cagra.md create mode 100644 fern/pages/neighbors/ivfflat.md create mode 100644 fern/pages/neighbors/ivfpq.md create mode 100644 fern/pages/neighbors/neighbors.md create mode 100644 fern/pages/neighbors/vamana.md create mode 100644 fern/pages/python_api/index.md create mode 100644 fern/pages/python_api/python-api-cluster-kmeans.md create mode 100644 fern/pages/python_api/python-api-common.md create mode 100644 fern/pages/python_api/python-api-distance.md create mode 100644 fern/pages/python_api/python-api-neighbors-all-neighbors.md create mode 100644 fern/pages/python_api/python-api-neighbors-brute-force.md create mode 100644 fern/pages/python_api/python-api-neighbors-cagra.md create mode 100644 fern/pages/python_api/python-api-neighbors-filters.md create mode 100644 fern/pages/python_api/python-api-neighbors-hnsw.md create mode 100644 fern/pages/python_api/python-api-neighbors-ivf-flat.md create mode 100644 fern/pages/python_api/python-api-neighbors-ivf-pq.md create mode 100644 fern/pages/python_api/python-api-neighbors-mg-cagra.md create mode 100644 fern/pages/python_api/python-api-neighbors-mg-ivf-flat.md create mode 100644 fern/pages/python_api/python-api-neighbors-mg-ivf-pq.md create mode 100644 fern/pages/python_api/python-api-neighbors-nn-descent.md create mode 100644 fern/pages/python_api/python-api-neighbors-tiered-index.md create mode 100644 fern/pages/python_api/python-api-neighbors-vamana.md create mode 100644 fern/pages/python_api/python-api-neighbors.md create mode 100644 fern/pages/python_api/python-api-preprocessing-pca.md create mode 100644 fern/pages/python_api/python-api-preprocessing-quantize-binary.md create mode 100644 fern/pages/python_api/python-api-preprocessing-quantize-pq.md create mode 100644 fern/pages/python_api/python-api-preprocessing-quantize-scalar.md create mode 100644 fern/pages/rust_api/index.md create mode 100644 fern/pages/rust_api/rust-api-cuvs-brute-force.md create mode 100644 fern/pages/rust_api/rust-api-cuvs-cagra-index-params.md create mode 100644 fern/pages/rust_api/rust-api-cuvs-cagra-index.md create mode 100644 fern/pages/rust_api/rust-api-cuvs-cagra-search-params.md create mode 100644 fern/pages/rust_api/rust-api-cuvs-cagra.md create mode 100644 fern/pages/rust_api/rust-api-cuvs-cluster-kmeans-params.md create mode 100644 fern/pages/rust_api/rust-api-cuvs-cluster-kmeans.md create mode 100644 fern/pages/rust_api/rust-api-cuvs-cluster.md create mode 100644 fern/pages/rust_api/rust-api-cuvs-distance-type.md create mode 100644 fern/pages/rust_api/rust-api-cuvs-distance.md create mode 100644 fern/pages/rust_api/rust-api-cuvs-dlpack.md create mode 100644 fern/pages/rust_api/rust-api-cuvs-error.md create mode 100644 fern/pages/rust_api/rust-api-cuvs-ivf-flat-index-params.md create mode 100644 fern/pages/rust_api/rust-api-cuvs-ivf-flat-index.md create mode 100644 fern/pages/rust_api/rust-api-cuvs-ivf-flat-search-params.md create mode 100644 fern/pages/rust_api/rust-api-cuvs-ivf-flat.md create mode 100644 fern/pages/rust_api/rust-api-cuvs-ivf-pq-index-params.md create mode 100644 fern/pages/rust_api/rust-api-cuvs-ivf-pq-index.md create mode 100644 fern/pages/rust_api/rust-api-cuvs-ivf-pq-search-params.md create mode 100644 fern/pages/rust_api/rust-api-cuvs-ivf-pq.md create mode 100644 fern/pages/rust_api/rust-api-cuvs-resources.md create mode 100644 fern/pages/rust_api/rust-api-cuvs-vamana-index-params.md create mode 100644 fern/pages/rust_api/rust-api-cuvs-vamana-index.md create mode 100644 fern/pages/rust_api/rust-api-cuvs-vamana.md create mode 100644 fern/pages/rust_api/rust-api-cuvs.md rename docs/source/tuning_guide.rst => fern/pages/tuning_guide.md (70%) rename docs/source/vector_databases_vs_vector_search.rst => fern/pages/vector_databases_vs_vector_search.md (90%) create mode 100644 fern/pages/working_with_ann_indexes.md create mode 100644 fern/pages/working_with_ann_indexes_c.md create mode 100644 fern/pages/working_with_ann_indexes_cpp.md create mode 100644 fern/pages/working_with_ann_indexes_python.md create mode 100644 fern/pages/working_with_ann_indexes_rust.md create mode 100755 fern/scripts/generate_api_reference.py diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index a9c9d7a26e..e7e6221806 100755 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -20,6 +20,7 @@ examples/rust/ @rapidsai/cuvs-rust-codeowners #docs code owners docs/ @rapidsai/cuvs-docs-codeowners +fern/ @rapidsai/cuvs-docs-codeowners #cmake code owners CMakeLists.txt @rapidsai/cuvs-cmake-codeowners diff --git a/.github/workflows/check-c-abi.yaml b/.github/workflows/check-c-abi.yaml index 3e1afa52c9..c76f16a64f 100644 --- a/.github/workflows/check-c-abi.yaml +++ b/.github/workflows/check-c-abi.yaml @@ -127,5 +127,5 @@ jobs: - The changes are documented in the changelog - Migration guide is provided for users - For more information, see the [C ABI documentation](../docs/source/c_developer_guide.md).` + For more information, see the [C API documentation](../fern/pages/c_api/index.md).` }); diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml index 972be1a437..f417de6f26 100644 --- a/.github/workflows/pr.yaml +++ b/.github/workflows/pr.yaml @@ -124,6 +124,7 @@ jobs: - '!ci/test_wheel_cuvs.sh' - '!ci/validate_wheel.sh' - '!docs/**' + - '!fern/**' - '!go/**' - '!img/**' - '!java/**' @@ -160,6 +161,7 @@ jobs: - '!ci/validate_wheel.sh' - '!Dockerfile' - '!docs/**' + - '!fern/**' - '!img/**' - '!notebooks/**' - '!python/**' @@ -199,6 +201,7 @@ jobs: - '!Dockerfile' - '!README.md' - '!docs/**' + - '!fern/**' - '!go/**' - '!img/**' - '!java/**' @@ -243,6 +246,7 @@ jobs: - '!cpp/.clang-tidy' - '!cpp/doxygen/**' - '!docs/**' + - '!fern/**' - '!java/**' - '!go/**' - '!img/**' @@ -282,6 +286,7 @@ jobs: - '!ci/test_wheel_cuvs.sh' - '!ci/validate_wheel.sh' - '!docs/**' + - '!fern/**' - '!go/**' - '!img/**' - '!java/**' @@ -322,6 +327,7 @@ jobs: - '!ci/test_wheel_cuvs.sh' - '!ci/validate_wheel.sh' - '!docs/**' + - '!fern/**' - '!img/**' - '!java/**' - '!notebooks/**' diff --git a/build.sh b/build.sh index e39f5be5e2..f5260ecd59 100755 --- a/build.sh +++ b/build.sh @@ -67,8 +67,7 @@ HELP="$0 [ ...] [ ...] [--cmake-args=\"\"] [--cache-tool=/dev/null || nproc) +fi BUILD_ABI=${BUILD_ABI:=ON} # Default to Ninja if generator is not specified @@ -371,7 +372,7 @@ fi ################################################################################ # Configure for building all C++ targets -if (( NUMARGS == 0 )) || hasArg libcuvs || hasArg docs || hasArg tests || hasArg bench-prims || hasArg bench-ann || hasArg examples; then +if (( NUMARGS == 0 )) || hasArg libcuvs || hasArg tests || hasArg bench-prims || hasArg bench-ann || hasArg examples; then COMPILE_LIBRARY=ON if [[ "${BUILD_SHARED_LIBS}" != "OFF" ]]; then CMAKE_TARGET+=("cuvs") @@ -535,13 +536,8 @@ export RAPIDS_VERSION_MAJOR_MINOR if hasArg docs; then set -x - cd "${DOXYGEN_BUILD_DIR}" - doxygen Doxyfile - cd "${SPHINX_BUILD_DIR}" - make html - cd "${REPODIR}"/rust - cargo doc -p cuvs --no-deps - rsync -av "${RUST_BUILD_DIR}"/doc/ "${SPHINX_BUILD_DIR}"/build/html/_static/rust + cd "${REPODIR}" + "${FERN_DOCS_DIR}/build_docs.sh" "${FERN_DOCS_MODE:-check}" fi ################################################################################ diff --git a/ci/build_docs.sh b/ci/build_docs.sh index 65c8f29f8a..49e6ae7f44 100755 --- a/ci/build_docs.sh +++ b/ci/build_docs.sh @@ -4,25 +4,16 @@ set -euo pipefail -rapids-logger "Downloading artifacts from previous jobs" -CPP_CHANNEL=$(rapids-download-conda-from-github cpp) -PYTHON_CHANNEL=$(rapids-download-from-github "$(rapids-package-name "conda_python" cuvs --stable --cuda "$RAPIDS_CUDA_VERSION")") - -rapids-logger "Create test conda environment" +rapids-logger "Create docs conda environment" . /opt/conda/etc/profile.d/conda.sh rapids-logger "Configuring conda strict channel priority" conda config --set channel_priority strict -RAPIDS_VERSION_MAJOR_MINOR="$(rapids-version-major-minor)" -export RAPIDS_VERSION_MAJOR_MINOR - rapids-dependency-file-generator \ --output conda \ --file-key docs \ --matrix "cuda=${RAPIDS_CUDA_VERSION%.*};arch=$(arch);py=${RAPIDS_PY_VERSION}" \ - --prepend-channel "${CPP_CHANNEL}" \ - --prepend-channel "${PYTHON_CHANNEL}" \ | tee env.yaml rapids-mamba-retry env create --yes -f env.yaml -n docs @@ -35,27 +26,5 @@ set -eu rapids-print-env -RAPIDS_DOCS_DIR="$(mktemp -d)" -export RAPIDS_DOCS_DIR - -rapids-logger "Build CPP docs" -pushd cpp/doxygen -doxygen Doxyfile -popd - -rapids-logger "Build Rust docs" -pushd rust -LIBCLANG_PATH=$(dirname "$(find "$CONDA_PREFIX" -name libclang.so | head -n 1)") -export LIBCLANG_PATH -cargo doc -p cuvs --no-deps -popd - -rapids-logger "Build Python docs" -pushd docs -make dirhtml -mv ../rust/target/doc ./build/dirhtml/_static/rust -mkdir -p "${RAPIDS_DOCS_DIR}/cuvs/"html -mv build/dirhtml/* "${RAPIDS_DOCS_DIR}/cuvs/html" -popd - -RAPIDS_VERSION_NUMBER="${RAPIDS_VERSION_MAJOR_MINOR}" rapids-upload-docs +rapids-logger "Validate Fern docs" +fern/build_docs.sh "${FERN_DOCS_MODE:-check}" diff --git a/ci/release/update-version.sh b/ci/release/update-version.sh index 49da9abe83..25d3ffc4ef 100755 --- a/ci/release/update-version.sh +++ b/ci/release/update-version.sh @@ -139,14 +139,14 @@ if [[ "${RUN_CONTEXT}" == "main" ]]; then : elif [[ "${RUN_CONTEXT}" == "release" ]]; then # In release context, use release branch for documentation links (word boundaries to avoid partial matches) - sed_runner "/rapidsai\\/cuvs/ s|\\bmain\\b|release/${NEXT_SHORT_TAG}|g" docs/source/developer_guide.md + sed_runner "/rapidsai\\/cuvs/ s|\\bmain\\b|release/${NEXT_SHORT_TAG}|g" fern/pages/developer_guide.md sed_runner "s|\\bmain\\b|release/${NEXT_SHORT_TAG}|g" README.md # Only update the GitHub URL, not the main() function sed_runner "s|/cuvs/blob/\\bmain\\b/|/cuvs/blob/release/${NEXT_SHORT_TAG}/|g" python/cuvs_bench/cuvs_bench/plot/__main__.py fi # Update cuvs-bench Docker image references (version-only, not branch-related) -sed_runner "s|rapidsai/cuvs-bench:[0-9][0-9].[0-9][0-9]|rapidsai/cuvs-bench:${NEXT_SHORT_TAG}|g" docs/source/cuvs_bench/index.rst +sed_runner "s|rapidsai/cuvs-bench:[0-9][0-9].[0-9][0-9]|rapidsai/cuvs-bench:${NEXT_SHORT_TAG}|g" fern/pages/cuvs_bench/index.md # Version references (not branch-related) sed_runner "s|=[0-9][0-9].[0-9][0-9]|=${NEXT_SHORT_TAG}|g" README.md diff --git a/conda/environments/all_cuda-129_arch-aarch64.yaml b/conda/environments/all_cuda-129_arch-aarch64.yaml index 0a473a210f..7e9edd4f55 100644 --- a/conda/environments/all_cuda-129_arch-aarch64.yaml +++ b/conda/environments/all_cuda-129_arch-aarch64.yaml @@ -6,7 +6,6 @@ channels: - conda-forge dependencies: - _go_select *=cgo -- breathe>=4.35.0 - c-compiler - clang-tools==20.1.8 - clang==20.1.8 @@ -21,11 +20,8 @@ dependencies: - cxx-compiler - cython>=3.2.2 - dlpack>=0.8,<1.0 -- doxygen>=1.8.20 - gcc_linux-aarch64=14.* - go -- graphviz -- ipython - libclang==20.1.8 - libcublas-dev - libcurand-dev @@ -37,22 +33,16 @@ dependencies: - make - nccl>=2.19 - ninja +- nodejs - numpy>=1.23,<3.0 -- numpydoc - openblas - pre-commit - pylibraft==26.6.*,>=0.0.0a0 - pytest - pytest-cov - rapids-build-backend>=0.4.0,<0.5.0 -- recommonmark - rust - scikit-build-core>=0.11.0 - scikit-learn>=1.5 -- sphinx-copybutton -- sphinx-markdown-tables -- sphinx>=8.0.0 - sysroot_linux-aarch64==2.28 -- pip: - - nvidia-sphinx-theme name: all_cuda-129_arch-aarch64 diff --git a/conda/environments/all_cuda-129_arch-x86_64.yaml b/conda/environments/all_cuda-129_arch-x86_64.yaml index 08e3c3f4e5..43751d8ff5 100644 --- a/conda/environments/all_cuda-129_arch-x86_64.yaml +++ b/conda/environments/all_cuda-129_arch-x86_64.yaml @@ -6,7 +6,6 @@ channels: - conda-forge dependencies: - _go_select *=cgo -- breathe>=4.35.0 - c-compiler - clang-tools==20.1.8 - clang==20.1.8 @@ -21,11 +20,8 @@ dependencies: - cxx-compiler - cython>=3.2.2 - dlpack>=0.8,<1.0 -- doxygen>=1.8.20 - gcc_linux-64=14.* - go -- graphviz -- ipython - libclang==20.1.8 - libcublas-dev - libcurand-dev @@ -36,22 +32,16 @@ dependencies: - make - nccl>=2.19 - ninja +- nodejs - numpy>=1.23,<3.0 -- numpydoc - openblas - pre-commit - pylibraft==26.6.*,>=0.0.0a0 - pytest - pytest-cov - rapids-build-backend>=0.4.0,<0.5.0 -- recommonmark - rust - scikit-build-core>=0.11.0 - scikit-learn>=1.5 -- sphinx-copybutton -- sphinx-markdown-tables -- sphinx>=8.0.0 - sysroot_linux-64==2.28 -- pip: - - nvidia-sphinx-theme name: all_cuda-129_arch-x86_64 diff --git a/conda/environments/all_cuda-131_arch-aarch64.yaml b/conda/environments/all_cuda-131_arch-aarch64.yaml index 9fb879b06f..e608e201ce 100644 --- a/conda/environments/all_cuda-131_arch-aarch64.yaml +++ b/conda/environments/all_cuda-131_arch-aarch64.yaml @@ -6,7 +6,6 @@ channels: - conda-forge dependencies: - _go_select *=cgo -- breathe>=4.35.0 - c-compiler - clang-tools==20.1.8 - clang==20.1.8 @@ -21,11 +20,8 @@ dependencies: - cxx-compiler - cython>=3.2.2 - dlpack>=0.8,<1.0 -- doxygen>=1.8.20 - gcc_linux-aarch64=14.* - go -- graphviz -- ipython - libclang==20.1.8 - libcublas-dev - libcurand-dev @@ -37,22 +33,16 @@ dependencies: - make - nccl>=2.19 - ninja +- nodejs - numpy>=1.23,<3.0 -- numpydoc - openblas - pre-commit - pylibraft==26.6.*,>=0.0.0a0 - pytest - pytest-cov - rapids-build-backend>=0.4.0,<0.5.0 -- recommonmark - rust - scikit-build-core>=0.11.0 - scikit-learn>=1.5 -- sphinx-copybutton -- sphinx-markdown-tables -- sphinx>=8.0.0 - sysroot_linux-aarch64==2.28 -- pip: - - nvidia-sphinx-theme name: all_cuda-131_arch-aarch64 diff --git a/conda/environments/all_cuda-131_arch-x86_64.yaml b/conda/environments/all_cuda-131_arch-x86_64.yaml index 105e7a8d9c..a71351e7a6 100644 --- a/conda/environments/all_cuda-131_arch-x86_64.yaml +++ b/conda/environments/all_cuda-131_arch-x86_64.yaml @@ -6,7 +6,6 @@ channels: - conda-forge dependencies: - _go_select *=cgo -- breathe>=4.35.0 - c-compiler - clang-tools==20.1.8 - clang==20.1.8 @@ -21,11 +20,8 @@ dependencies: - cxx-compiler - cython>=3.2.2 - dlpack>=0.8,<1.0 -- doxygen>=1.8.20 - gcc_linux-64=14.* - go -- graphviz -- ipython - libclang==20.1.8 - libcublas-dev - libcurand-dev @@ -36,22 +32,16 @@ dependencies: - make - nccl>=2.19 - ninja +- nodejs - numpy>=1.23,<3.0 -- numpydoc - openblas - pre-commit - pylibraft==26.6.*,>=0.0.0a0 - pytest - pytest-cov - rapids-build-backend>=0.4.0,<0.5.0 -- recommonmark - rust - scikit-build-core>=0.11.0 - scikit-learn>=1.5 -- sphinx-copybutton -- sphinx-markdown-tables -- sphinx>=8.0.0 - sysroot_linux-64==2.28 -- pip: - - nvidia-sphinx-theme name: all_cuda-131_arch-x86_64 diff --git a/dependencies.yaml b/dependencies.yaml index 2aae054862..63b707e9a0 100644 --- a/dependencies.yaml +++ b/dependencies.yaml @@ -446,17 +446,7 @@ dependencies: common: - output_types: [conda] packages: - - breathe>=4.35.0 - - doxygen>=1.8.20 - - graphviz - - ipython - - numpydoc - - recommonmark - - sphinx>=8.0.0 - - sphinx-copybutton - - sphinx-markdown-tables - - pip: - - nvidia-sphinx-theme + - nodejs rust: common: - output_types: [conda] diff --git a/docs/Makefile b/docs/Makefile deleted file mode 100644 index 86a635a54d..0000000000 --- a/docs/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# Minimal makefile for Sphinx documentation -# - -# You can set these variables from the command line. -SPHINXOPTS = -W -SPHINXBUILD = sphinx-build -SPHINXPROJ = cuvs -SOURCEDIR = source -BUILDDIR = build - -# Put it first so that "make" without argument is like "make help". -help: - @$(SPHINXBUILD) -M help -v "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) - -.PHONY: help Makefile - -# Catch-all target: route all unknown targets to Sphinx using the new -# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). -%: Makefile - @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/README.md b/docs/README.md index 639961ea37..eb9089be2f 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,14 +1,33 @@ # Building Documentation -## Building locally: -#### [Build and install cuVS](source/build.md) +The cuVS documentation is a Fern project in [../fern](../fern). -#### Generate the docs -```shell script -bash build.sh docs +## Preview locally + +```bash +fern/build_docs.sh dev +``` + +Fern serves the preview at [http://localhost:3000](http://localhost:3000) by default. + +## Validate + +```bash +fern/build_docs.sh check ``` -#### Once the process finishes, documentation can be found in build/html -```shell script -xdg-open build/html/index.html` +The Fern build refreshes the C, C++, Python, Java, Rust, and Go API reference pages from the source tree before validating. + +## Publish + +Create a Fern preview deployment: + +```bash +fern/build_docs.sh preview +``` + +Publish the production docs site: + +```bash +fern/build_docs.sh publish ``` diff --git a/docs/make.bat b/docs/make.bat deleted file mode 100644 index ec3fa36436..0000000000 --- a/docs/make.bat +++ /dev/null @@ -1,36 +0,0 @@ -@ECHO OFF - -pushd %~dp0 - -REM Command file for Sphinx documentation - -if "%SPHINXBUILD%" == "" ( - set SPHINXBUILD=sphinx-build -) -set SOURCEDIR=source -set BUILDDIR=build -set SPHINXPROJ=cuvs - -if "%1" == "" goto help - -%SPHINXBUILD% >NUL 2>NUL -if errorlevel 9009 ( - echo. - echo.The 'sphinx-build' command was not found. Make sure you have Sphinx - echo.installed, then set the SPHINXBUILD environment variable to point - echo.to the full path of the 'sphinx-build' executable. Alternatively you - echo.may add the Sphinx directory to PATH. - echo. - echo.If you don't have Sphinx installed, grab it from - echo.http://sphinx-doc.org/ - exit /b 1 -) - -%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% -goto end - -:help -%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% - -:end -popd diff --git a/docs/source/_static/collapse_overloads.js b/docs/source/_static/collapse_overloads.js deleted file mode 100644 index 2ec2e710fb..0000000000 --- a/docs/source/_static/collapse_overloads.js +++ /dev/null @@ -1,67 +0,0 @@ -document.addEventListener("DOMContentLoaded", () => { - const toc = document.querySelector(".bd-toc-nav"); - if (!toc) return; - - // Get all TOC links - const links = toc.querySelectorAll("a"); - - const seen = new Set(); - links.forEach(link => { - let text = link.textContent.trim(); - let norm = text.replace(/\(\)$/, ""); // strip trailing () - - if (seen.has(norm)) { - // hide duplicate - link.parentElement.style.display = "none"; - } else { - seen.add(norm); - } - }); - }); - -document.addEventListener("DOMContentLoaded", () => { - const toc = document.querySelector(".toctree-wrapper"); - if (!toc) return; - - const leaf_traversal_fn = (leaf) => { - try { - const links = leaf.querySelectorAll("a"); - if (!links) return; - const seen = new Set(); - links.forEach(link => { - let text = link.textContent.trim(); - let norm = text.replace(/\(\)$/, ""); // strip trailing () - - if (seen.has(norm)) { - // hide duplicate - link.parentElement.style.display = "none"; - } else { - seen.add(norm); - } - }); - } catch (error) { - console.error(error); - } - }; - queue = [toc.querySelector("li")]; - while (queue.length > 0) { - const tree = queue.shift(); - try { - if (tree.childElementCount > 1 && - tree.firstChild.hasAttribute("href") && - tree.firstChild.attributes["href"].value.includes("#")) { - leaf_traversal_fn(tree.childNodes[1]); - } else { - const child = tree.querySelector("li"); - if (child) { - queue.push(child); - } - } - } catch (error) { - console.error(error); - } - if (tree.nextElementSibling) { - queue.push(tree.nextElementSibling); - } - } - }); diff --git a/docs/source/_static/references.css b/docs/source/_static/references.css deleted file mode 100644 index b8e1c631b8..0000000000 --- a/docs/source/_static/references.css +++ /dev/null @@ -1,36 +0,0 @@ - -/* Fix references to not look like parameters */ -dl.citation > dt.label { - display: unset !important; - float: left !important; - border: unset !important; - background: unset !important; - padding: unset !important; - margin: unset !important; - font-size: unset !important; - line-height: unset !important; - padding-right: 0.5rem !important; -} - -/* Add opening bracket */ -dl.citation > dt.label > span::before { - content: "["; -} - -/* Add closing bracket */ -dl.citation > dt.label > span::after { - content: "]"; -} - -/* Highlight math formulas in a box */ -div.math { - background-color: #f8f9fa !important; - border-top: 1px solid #e9ecef !important; - border-bottom: 1px solid #e9ecef !important; - border-left: none !important; - border-right: none !important; - border-radius: 0 !important; - padding: 1rem 1.25rem !important; - margin: 1rem 0 !important; - overflow-x: auto !important; -} diff --git a/docs/source/advanced_topics.rst b/docs/source/advanced_topics.rst deleted file mode 100644 index 4171845af5..0000000000 --- a/docs/source/advanced_topics.rst +++ /dev/null @@ -1,22 +0,0 @@ -Advanced Topics -=============== - -- `Just-in-Time Compilation`_ - -Just-in-Time Compilation ------------------------- -cuVS uses the Just-in-Time (JIT) `Link-Time Optimization (LTO) `_ compilation technology to compile certain kernels. When a JIT compilation is triggered, cuVS will compile the kernel for your architecture and automatically cache it in-memory and on-disk. The validity of the cache is as follows: - -1. In-memory cache is valid for the lifetime of the process. -2. On-disk cache is valid until a CUDA driver upgrade is performed. The cache can be portably shared between machines in network or cloud storage and we strongly recommend that you store the cache in a persistent location. For more details on how to configure the on-disk cache, look at CUDA documentation on `JIT Compilation `_. Specifically, the environment variables of interest are: `CUDA_CACHE_PATH` and `CUDA_CACHE_MAX_SIZE`. - - -Thus, the JIT compilation is a one-time cost and you can expect no loss in real performance after the first compilation. We recommend that you run a "warmup" to trigger the JIT compilation before the actual usage. - -Currently, the following capabilities will trigger a JIT compilation: -- IVF Flat search APIs: :doc:`cuvs::neighbors::ivf_flat::search() ` - -.. toctree:: - :maxdepth: 2 - - jit_lto_guide diff --git a/docs/source/api_basics.rst b/docs/source/api_basics.rst deleted file mode 100644 index 5ffb1da630..0000000000 --- a/docs/source/api_basics.rst +++ /dev/null @@ -1,90 +0,0 @@ -cuVS API Basics -=============== - -- `Memory management`_ -- `Resource management`_ - -Memory management ------------------ - -Centralized memory management allows flexible configuration of allocation strategies, such as sharing the same CUDA memory pool across library boundaries. cuVS uses the `RMM `_ library, which eases the burden of configuring different allocation strategies globally across GPU-accelerated libraries. - -RMM currently has APIs for C++ and Python. - -C++ -^^^ - -Here's an example of configuring RMM to use a pool allocator in C++ (derived from the RMM example `here `__): - -.. code-block:: c++ - - rmm::mr::cuda_memory_resource cuda_mr; - // Construct a resource that uses a coalescing best-fit pool allocator - // With the pool initially half of available device memory - auto initial_size = rmm::percent_of_free_device_memory(50); - rmm::mr::pool_memory_resource pool_mr{cuda_mr, initial_size}; - rmm::mr::set_current_device_resource(pool_mr); - auto mr = rmm::mr::get_current_device_resource_ref(); - -Python -^^^^^^ - -And the corresponding code in Python (derived from the RMM example `here `__): - -.. code-block:: python - - import rmm - pool = rmm.mr.PoolMemoryResource( - rmm.mr.CudaMemoryResource(), - initial_pool_size=2**30, - maximum_pool_size=2**32) - rmm.mr.set_current_device_resource(pool) - - -Resource management -------------------- - -cuVS uses an API from the `RAFT `_ library of ML and data mining primitives to centralize and reuse expensive resources, such as memory management. The below code examples demonstrate how to create these resources for use throughout this guide. - -See RAFT's `resource API documentation `_ for more information. - -C -^ - -.. code-block:: c - - #include - #include - - cuvsResources_t res; - cuvsResourcesCreate(&res); - - // ... do some processing ... - - cuvsResourcesDestroy(res); - -C++ -^^^ - -.. code-block:: c++ - - #include - - raft::device_resources res; - -Python -^^^^^^ - -.. code-block:: python - - import pylibraft - - res = pylibraft.common.DeviceResources() - - -Rust -^^^^ - -.. code-block:: rust - - let res = cuvs::Resources::new()?; diff --git a/docs/source/api_docs.rst b/docs/source/api_docs.rst deleted file mode 100644 index 68d184c72c..0000000000 --- a/docs/source/api_docs.rst +++ /dev/null @@ -1,13 +0,0 @@ -API Reference -============= - -.. toctree:: - :maxdepth: 3 - - c_api.rst - cpp_api.rst - python_api.rst - rust_api/index.rst - -* :ref:`genindex` -* :ref:`search` diff --git a/docs/source/api_interoperability.rst b/docs/source/api_interoperability.rst deleted file mode 100644 index 097025aee7..0000000000 --- a/docs/source/api_interoperability.rst +++ /dev/null @@ -1,106 +0,0 @@ -Interoperability -================ - -DLPack (C) -^^^^^^^^^^ - -Approximate nearest neighbor (ANN) indexes provide an interface to build and search an index via a C API. `DLPack v0.8 `_, a tensor interface framework, is used as the standard to interact with our C API. - -Representing a tensor with DLPack is simple, as it is a POD struct that stores information about the tensor at runtime. At the moment, `DLManagedTensor` from DLPack v0.8 is compatible with out C API however we will soon upgrade to `DLManagedTensorVersioned` from DLPack v1.0 as it will help us maintain ABI and API compatibility. - -Here's an example on how to represent device memory using `DLManagedTensor`: - -.. code-block:: c - - #include - - // Create data representation in host memory - float dataset[2][1] = {{0.2, 0.1}}; - // copy data to device memory - float *dataset_dev; - cuvsRMMAlloc(&dataset_dev, sizeof(float) * 2 * 1); - cudaMemcpy(dataset_dev, dataset, sizeof(float) * 2 * 1, cudaMemcpyDefault); - - // Use DLPack for representing the data as a tensor - DLManagedTensor dataset_tensor; - dataset_tensor.dl_tensor.data = dataset; - dataset_tensor.dl_tensor.device.device_type = kDLCUDA; - dataset_tensor.dl_tensor.ndim = 2; - dataset_tensor.dl_tensor.dtype.code = kDLFloat; - dataset_tensor.dl_tensor.dtype.bits = 32; - dataset_tensor.dl_tensor.dtype.lanes = 1; - int64_t dataset_shape[2] = {2, 1}; - dataset_tensor.dl_tensor.shape = dataset_shape; - dataset_tensor.dl_tensor.strides = nullptr; - - // free memory after use - cuvsRMMFree(dataset_dev); - -Please refer to `cuVS C API documentation `_ to learn more. - -Multi-dimensional span (C++) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -cuVS is built on top of the GPU-accelerated machine learning and data mining primitives in the `RAFT `_ library. Most of the C++ APIs in cuVS accept `mdspan `_ multi-dimensional array view for representing data in higher dimensions similar to the `ndarray` in the Numpy Python library. RAFT also contains the corresponding owning `mdarray` structure, which simplifies the allocation and management of multi-dimensional data in both host and device (GPU) memory. - -The `mdarray` is an owning object that forms a convenience layer over RMM and can be constructed in RAFT using a number of different helper functions: - -.. code-block:: c++ - - #include - - int n_rows = 10; - int n_cols = 10; - - auto scalar = raft::make_device_scalar(handle, 1.0); - auto vector = raft::make_device_vector(handle, n_cols); - auto matrix = raft::make_device_matrix(handle, n_rows, n_cols); - -The `mdspan` is a lightweight non-owning view that can wrap around any pointer, maintaining shape, layout, and indexing information for accessing elements. - -We can construct `mdspan` instances directly from the above `mdarray` instances: - -.. code-block:: c++ - - // Scalar mdspan on device - auto scalar_view = scalar.view(); - - // Vector mdspan on device - auto vector_view = vector.view(); - - // Matrix mdspan on device - auto matrix_view = matrix.view(); - -Since the `mdspan` is just a lightweight wrapper, we can also construct it from the underlying data handles in the `mdarray` instances above. We use the extent to get information about the `mdarray` or `mdspan`'s shape. - -.. code-block:: c++ - - #include - - auto scalar_view = raft::make_device_scalar_view(scalar.data_handle()); - auto vector_view = raft::make_device_vector_view(vector.data_handle(), vector.extent(0)); - auto matrix_view = raft::make_device_matrix_view(matrix.data_handle(), matrix.extent(0), matrix.extent(1)); - -Of course, RAFT's `mdspan`/`mdarray` APIs aren't just limited to the `device`. You can also create `host` variants: - -.. code-block:: c++ - - #include - #include - - int n_rows = 10; - int n_cols = 10; - - auto scalar = raft::make_host_scalar(handle, 1.0); - auto vector = raft::make_host_vector(handle, n_cols); - auto matrix = raft::make_host_matrix(handle, n_rows, n_cols); - - auto scalar_view = raft::make_host_scalar_view(scalar.data_handle()); - auto vector_view = raft::make_host_vector_view(vector.data_handle(), vector.extent(0)); - auto matrix_view = raft::make_host_matrix_view(matrix.data_handle(), matrix.extent(0), matrix.extent(1)); - -Please refer to RAFT's `mdspan documentation `_ to learn more. - - -CUDA array interface (Python) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/docs/source/build.rst b/docs/source/build.rst deleted file mode 100644 index 5e863e40f4..0000000000 --- a/docs/source/build.rst +++ /dev/null @@ -1,285 +0,0 @@ -Installation -============ - -The cuVS software development kit provides APIs for C, C++, Python, and Rust languages. This guide outlines how to install the pre-compiled packages, build it from source, and use it in downstream applications. - -- `Installing pre-compiled packages`_ - - * `C, C++, and Python through Conda`_ - - * `Python through Pip`_ - - * `Tarball`_ - -- `Build from source`_ - - * `Prerequisites`_ - - * `Create a build environment`_ - - * `C and C++ Libraries`_ - - * `Building the Googletests`_ - - * `Python Library`_ - - * `Rust Library`_ - - * `Using CMake Directly`_ - -- `Build Documentation`_ - - -Installing Pre-compiled Packages --------------------------------- - -**Note:** The cuVS pre-compiled packages are available for **Linux** only (x86_64 and aarch64 architectures). Native Windows support is not available at this time. On Windows, use **WSL2** with GPU passthrough. See the `RAPIDS WSL2 guide `_. - -C, C++, and Python through Conda -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -The easiest way to install the pre-compiled C, C++, and Python packages is through conda. You can get a minimal conda installation with `miniforge `__. - -Use the following commands, depending on your CUDA version, to install cuVS packages (replace `rapidsai` with `rapidsai-nightly` to install more up-to-date but less stable nightly packages). `mamba` is preferred over the `conda` command and can be enabled using `this guide `_. - -C/C++ Package -~~~~~~~~~~~~~ - -.. code-block:: bash - - # CUDA 13 - conda install -c rapidsai -c conda-forge libcuvs cuda-version=13.1 - - # CUDA 12 - conda install -c rapidsai -c conda-forge libcuvs cuda-version=12.9 - -Python Package -~~~~~~~~~~~~~~ - -.. code-block:: bash - - # CUDA 13 - conda install -c rapidsai -c conda-forge cuvs cuda-version=13.1 - - # CUDA 12 - conda install -c rapidsai -c conda-forge cuvs cuda-version=12.9 - -Python through Pip -^^^^^^^^^^^^^^^^^^ - -The cuVS Python package can also be `installed through pip `_. - -.. code-block:: bash - - # CUDA 13 - pip install cuvs-cu13 --extra-index-url=https://pypi.nvidia.com - - # CUDA 12 - pip install cuvs-cu12 --extra-index-url=https://pypi.nvidia.com - -Note: these packages statically link the C and C++ libraries so the `libcuvs` and `libcuvs_c` shared libraries won't be readily available to use in your code. - -Tarball -^^^^^^^ - -Install Dependencies -~~~~~~~~~~~~~~~~~~~~ - -1. `NCCL `_ -2. `libopenmp` -3. CUDA Toolkit Runtime 12.2+ -4. Ampere architecture or better (compute capability >= 8.0) - -Download & Extract -~~~~~~~~~~~~~~~~~~ - -Download the pre-built tarball for your CPU architecture and CUDA version from -`https://developer.nvidia.com/cuvs-downloads `_ - -Untar the tarball into a directory. - -.. code-block:: bash - - tar -xzvf libcuvs-linux-sbsa-26.02.00.189485_cuda12-archive.tar.xz -C /path/to/folder - - -Add cuVS to your system library load path. This should be done in the appropriate profile configuration (for e.g. `.bashrc`, `.bash_profile`) to maintain the setting across sessions. - -.. code-block:: bash - - export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/path/to/folder - - -Build from source ------------------ - -The core cuVS source code is written in C++ and wrapped through a C API. The C API is wrapped around the C++ APIs and the other supported languages are built around the C API. - -Prerequisites -^^^^^^^^^^^^^ - -- CMake 3.26.4+ -- GCC 9.3+ (11.4+ recommended) -- CUDA Toolkit 12.2+ -- Ampere architecture or better (compute capability >= 8.0) - -Create a build environment -^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Conda environment scripts are provided for installing the necessary dependencies to build cuVS from source. It is preferred to use `mamba`, as it provides significant speedup over `conda`: - -.. code-block:: bash - - conda env create --name cuvs -f conda/environments/all_cuda-131_arch-$(uname -m).yaml - conda activate cuvs - -The recommended way to build and install cuVS from source is to use the `build.sh` script in the root of the repository. This script can build both the C++ and Python artifacts and provides CMake options for building and installing the headers, tests, benchmarks, and the pre-compiled shared library. - - -C and C++ libraries -^^^^^^^^^^^^^^^^^^^ - -The C and C++ shared libraries are built together using the following arguments to `build.sh`: - -.. code-block:: bash - - ./build.sh libcuvs - -In above example the `libcuvs.so` and `libcuvs_c.so` shared libraries are installed by default into `$INSTALL_PREFIX/lib`. To disable this, pass `-n` flag. - -Once installed, the shared libraries, headers (and any dependencies downloaded and installed via `rapids-cmake`) can be uninstalled using `build.sh`: - -.. code-block:: bash - - ./build.sh libcuvs --uninstall - - -Multi-GPU features -^^^^^^^^^^^^^^^^^^ - -To disable the multi-gpu features run : - -.. code-block:: bash - - ./build.sh libcuvs --no-mg - - -Building the Googletests -~~~~~~~~~~~~~~~~~~~~~~~~ - -Compile the C and C++ Googletests using the `tests` target in `build.sh`. - -.. code-block:: bash - - ./build.sh libcuvs tests - -The tests will be written to the build directory, which is `cpp/build/` by default, and they will be named `*_TEST`. - -It can take some time to compile all of the tests. You can build individual tests by providing a semicolon-separated list to the `--limit-tests` option in `build.sh`. Make sure to pass the `-n` flag so the tests are not installed. - -.. code-block:: bash - - ./build.sh libcuvs tests -n --limit-tests=NEIGHBORS_TEST;CAGRA_C_TEST - -Python library -^^^^^^^^^^^^^^ - -The Python library should be built and installed using the `build.sh` script: - -.. code-block:: bash - - ./build.sh python - -The Python packages can also be uninstalled using the `build.sh` script: - -.. code-block:: bash - - ./build.sh python --uninstall - -Go library -^^^^^^^^^^ - -After building the C and C++ libraries, the Golang library can be built with the following command: - -.. code-block:: bash - - export CUDA_HOME="/usr/local/cuda" # or wherever your CUDA installation is. - export CGO_CFLAGS="-I${CONDA_PREFIX}/include -I${CUDA_HOME}/include" - export CGO_LDFLAGS="-L${CONDA_PREFIX}/lib -lcuvs -lcuvs_c" - export LD_LIBRARY_PATH="$CONDA_PREFIX/lib:$LD_LIBRARY_PATH" - export CC=clang - - ./build.sh go - -Rust library -^^^^^^^^^^^^ - -The Rust bindings can be built with - -.. code-block:: bash - - ./build.sh rust - -Using CMake directly -^^^^^^^^^^^^^^^^^^^^ - -When building cuVS from source, the `build.sh` script offers a nice wrapper around the `cmake` commands to ease the burdens of manually configuring the various available cmake options. When more fine-grained control over the CMake configuration is desired, the `cmake` command can be invoked directly as the below example demonstrates. - -The `CMAKE_INSTALL_PREFIX` installs cuVS into a specific location. The example below installs cuVS into the current Conda environment: - -.. code-block:: bash - - cd cpp - mkdir build - cd build - cmake -D BUILD_TESTS=ON -DCMAKE_INSTALL_PREFIX=$CONDA_PREFIX ../ - make -j install - -cuVS has the following configurable cmake flags available: - -.. list-table:: CMake Flags - - * - Flag - - Possible Values - - Default Value - - Behavior - - * - BUILD_TESTS - - ON, OFF - - ON - - Compile Googletests - - * - CUDA_ENABLE_KERNELINFO - - ON, OFF - - OFF - - Enables `kernelinfo` in nvcc. This is useful for `compute-sanitizer` - - * - CUDA_ENABLE_LINEINFO - - ON, OFF - - OFF - - Enable the `-lineinfo` option for nvcc - - * - CUDA_STATIC_MATH_LIBRARIES - - ON, OFF - - OFF - - Statically link the CUDA math libraries - - * - DETECT_CONDA_ENV - - ON, OFF - - ON - - Enable detection of conda environment for dependencies - - * - CUVS_NVTX - - ON, OFF - - OFF - - Enable NVTX markers - - -Build documentation -^^^^^^^^^^^^^^^^^^^ - -The documentation requires that the C, C++ and Python libraries have been built and installed. The following will build the docs along with the necessary libraries: - -.. code-block:: bash - - ./build.sh libcuvs python docs diff --git a/docs/source/c_api.rst b/docs/source/c_api.rst deleted file mode 100644 index c65eee06ef..0000000000 --- a/docs/source/c_api.rst +++ /dev/null @@ -1,14 +0,0 @@ -~~~~~~~~~~~~~~~~~~~ -C API Documentation -~~~~~~~~~~~~~~~~~~~ - -.. _api: - -.. toctree:: - :maxdepth: 4 - - c_api/core_c_api.rst - c_api/distance.rst - c_api/cluster.rst - c_api/neighbors.rst - c_api/preprocessing.rst diff --git a/docs/source/c_api/cluster.rst b/docs/source/c_api/cluster.rst deleted file mode 100644 index 34795e45bf..0000000000 --- a/docs/source/c_api/cluster.rst +++ /dev/null @@ -1,12 +0,0 @@ -Clustering -========== - -.. role:: py(code) - :language: c - :class: highlight - -.. toctree:: - :maxdepth: 2 - :caption: Contents: - - cluster_kmeans_c.rst diff --git a/docs/source/c_api/cluster_kmeans_c.rst b/docs/source/c_api/cluster_kmeans_c.rst deleted file mode 100644 index b22003bc27..0000000000 --- a/docs/source/c_api/cluster_kmeans_c.rst +++ /dev/null @@ -1,27 +0,0 @@ -K-Means -======= - -.. role:: py(code) - :language: c - :class: highlight - -Parameters ----------- - -``#include `` - -.. doxygengroup:: kmeans_c_params - :project: cuvs - :members: - :content-only: - - -Functions ---------- - -``#include `` - -.. doxygengroup:: kmeans_c - :project: cuvs - :members: - :content-only: diff --git a/docs/source/c_api/core_c_api.rst b/docs/source/c_api/core_c_api.rst deleted file mode 100644 index e228394733..0000000000 --- a/docs/source/c_api/core_c_api.rst +++ /dev/null @@ -1,32 +0,0 @@ -Core Routines -============= - -.. role:: py(code) - :language: c - :class: highlight - -``#include `` - -Resources Handle ----------------- - -.. doxygengroup:: resources_c - :project: cuvs - :members: - :content-only: - -Error Handling --------------- - -.. doxygengroup:: error_c - :project: cuvs - :members: - :content-only: - -Logging -------- - -.. doxygengroup:: log_c - :project: cuvs - :members: - :content-only: diff --git a/docs/source/c_api/distance.rst b/docs/source/c_api/distance.rst deleted file mode 100644 index 8635ddf8bc..0000000000 --- a/docs/source/c_api/distance.rst +++ /dev/null @@ -1,26 +0,0 @@ -Distance -======== - -.. role:: py(code) - :language: c - :class: highlight - - -Distance types --------------- - -``#include `` - -.. doxygenenum:: cuvsDistanceType - :project: cuvs - - -Pairwise distance ------------------ - -``#include `` - -.. doxygengroup:: pairwise_distance_c - :project: cuvs - :members: - :content-only: diff --git a/docs/source/c_api/neighbors.rst b/docs/source/c_api/neighbors.rst deleted file mode 100644 index 305364bb2a..0000000000 --- a/docs/source/c_api/neighbors.rst +++ /dev/null @@ -1,19 +0,0 @@ -Nearest Neighbors -================= - -.. role:: py(code) - :language: c - :class: highlight - -.. toctree:: - :maxdepth: 2 - :caption: Contents: - - neighbors_all_neighbors_c.rst - neighbors_bruteforce_c.rst - neighbors_cagra_c.rst - neighbors_hnsw_c.rst - neighbors_ivf_flat_c.rst - neighbors_ivf_pq_c.rst - neighbors_mg.rst - neighbors_vamana_c.rst diff --git a/docs/source/c_api/neighbors_all_neighbors_c.rst b/docs/source/c_api/neighbors_all_neighbors_c.rst deleted file mode 100644 index 7c6559979e..0000000000 --- a/docs/source/c_api/neighbors_all_neighbors_c.rst +++ /dev/null @@ -1,26 +0,0 @@ -All-Neighbors -============= - -The all-neighbors method constructs a k-NN graph for all vectors in a dataset. It supports multiple algorithms including brute force, IVF-PQ (approximate), and NN-Descent (approximate) for building local k-NN subgraphs. The API automatically detects whether the dataset is host-resident or device-resident and applies appropriate optimizations. - -.. role:: py(code) - :language: c - :class: highlight - -``#include `` - -Build parameters ----------------- - -.. doxygengroup:: all_neighbors_c_params - :project: cuvs - :members: - :content-only: - -Build ------ - -.. doxygengroup:: all_neighbors_c_build - :project: cuvs - :members: - :content-only: diff --git a/docs/source/c_api/neighbors_bruteforce_c.rst b/docs/source/c_api/neighbors_bruteforce_c.rst deleted file mode 100644 index 36ba96f424..0000000000 --- a/docs/source/c_api/neighbors_bruteforce_c.rst +++ /dev/null @@ -1,42 +0,0 @@ -Bruteforce -========== - -The bruteforce method is running the KNN algorithm. It performs an extensive search, and in contrast to ANN methods produces an exact result. - -.. role:: py(code) - :language: c - :class: highlight - -``#include `` - -Index ------ - -.. doxygengroup:: bruteforce_c_index - :project: cuvs - :members: - :content-only: - -Index build ------------ - -.. doxygengroup:: bruteforce_c_index_build - :project: cuvs - :members: - :content-only: - -Index search ------------- - -.. doxygengroup:: bruteforce_c_index_search - :project: cuvs - :members: - :content-only: - -Index serialize ---------------- - -.. doxygengroup:: bruteforce_c_index_serialize - :project: cuvs - :members: - :content-only: diff --git a/docs/source/c_api/neighbors_cagra_c.rst b/docs/source/c_api/neighbors_cagra_c.rst deleted file mode 100644 index 9d9f1b7ea9..0000000000 --- a/docs/source/c_api/neighbors_cagra_c.rst +++ /dev/null @@ -1,67 +0,0 @@ -CAGRA -===== - -CAGRA is a graph-based nearest neighbors algorithm that was built from the ground up for GPU acceleration. CAGRA demonstrates state-of-the art index build and query performance for both small- and large-batch sized search. - - -.. role:: py(code) - :language: c - :class: highlight - -``#include `` - -Index build parameters ----------------------- - -.. doxygengroup:: cagra_c_index_params - :project: cuvs - :members: - :content-only: - -Index search parameters ------------------------ - -.. doxygengroup:: cagra_c_search_params - :project: cuvs - :members: - :content-only: - -Index ------ - -.. doxygengroup:: cagra_c_index - :project: cuvs - :members: - :content-only: - -Index build ------------ - -.. doxygengroup:: cagra_c_index_build - :project: cuvs - :members: - :content-only: - -Index search ------------- - -.. doxygengroup:: cagra_c_index_search - :project: cuvs - :members: - :content-only: - -Index merge ------------ - -.. doxygengroup:: cagra_c_index_merge - :project: cuvs - :members: - :content-only: - -Index serialize ---------------- - -.. doxygengroup:: cagra_c_index_serialize - :project: cuvs - :members: - :content-only: diff --git a/docs/source/c_api/neighbors_hnsw_c.rst b/docs/source/c_api/neighbors_hnsw_c.rst deleted file mode 100644 index 3f10eea33b..0000000000 --- a/docs/source/c_api/neighbors_hnsw_c.rst +++ /dev/null @@ -1,65 +0,0 @@ -HNSW -==== - -This is a wrapper for hnswlib, to load a CAGRA index as an immutable HNSW index. The loaded HNSW index is only compatible in cuVS, and can be searched using wrapper functions. - - -.. role:: py(code) - :language: c - :class: highlight - -``#include `` - -Index search parameters ------------------------ - -.. doxygengroup:: hnsw_c_search_params - :project: cuvs - :members: - :content-only: - -Index ------ - -.. doxygengroup:: hnsw_c_index - :project: cuvs - :members: - :content-only: - -Index extend parameters ------------------------ - -.. doxygengroup:: hnsw_c_extend_params - :project: cuvs - :members: - :content-only: - -Index extend ------------- -.. doxygengroup:: hnsw_c_index_extend - :project: cuvs - :members: - :content-only: - -Index load ----------- -.. doxygengroup:: hnsw_c_index_load - :project: cuvs - :members: - :content-only: - -Index search ------------- - -.. doxygengroup:: hnsw_c_index_search - :project: cuvs - :members: - :content-only: - -Index serialize ---------------- - -.. doxygengroup:: hnsw_c_index_serialize - :project: cuvs - :members: - :content-only: diff --git a/docs/source/c_api/neighbors_ivf_flat_c.rst b/docs/source/c_api/neighbors_ivf_flat_c.rst deleted file mode 100644 index a37b153bed..0000000000 --- a/docs/source/c_api/neighbors_ivf_flat_c.rst +++ /dev/null @@ -1,58 +0,0 @@ -IVF-Flat -======== - -The IVF-Flat method is an ANN algorithm. It uses an inverted file index (IVF) with unmodified (that is, flat) vectors. This algorithm provides simple knobs to reduce the overall search space and to trade-off accuracy for speed. - -.. role:: py(code) - :language: c - :class: highlight - -``#include `` - -Index build parameters ----------------------- - -.. doxygengroup:: ivf_flat_c_index_params - :project: cuvs - :members: - :content-only: - -Index search parameters ------------------------ - -.. doxygengroup:: ivf_flat_c_search_params - :project: cuvs - :members: - :content-only: - -Index ------ - -.. doxygengroup:: ivf_flat_c_index - :project: cuvs - :members: - :content-only: - -Index build ------------ - -.. doxygengroup:: ivf_flat_c_index_build - :project: cuvs - :members: - :content-only: - -Index search ------------- - -.. doxygengroup:: ivf_flat_c_index_search - :project: cuvs - :members: - :content-only: - -Index serialize ---------------- - -.. doxygengroup:: ivf_flat_c_index_serialize - :project: cuvs - :members: - :content-only: diff --git a/docs/source/c_api/neighbors_ivf_pq_c.rst b/docs/source/c_api/neighbors_ivf_pq_c.rst deleted file mode 100644 index ae985870b4..0000000000 --- a/docs/source/c_api/neighbors_ivf_pq_c.rst +++ /dev/null @@ -1,58 +0,0 @@ -IVF-PQ -====== - -The IVF-PQ method is an ANN algorithm. Like IVF-Flat, IVF-PQ splits the points into a number of clusters (also specified by a parameter called n_lists) and searches the closest clusters to compute the nearest neighbors (also specified by a parameter called n_probes), but it shrinks the sizes of the vectors using a technique called product quantization. - -.. role:: py(code) - :language: c - :class: highlight - -``#include `` - -Index build parameters ----------------------- - -.. doxygengroup:: ivf_pq_c_index_params - :project: cuvs - :members: - :content-only: - -Index search parameters ------------------------ - -.. doxygengroup:: ivf_pq_c_search_params - :project: cuvs - :members: - :content-only: - -Index ------ - -.. doxygengroup:: ivf_pq_c_index - :project: cuvs - :members: - :content-only: - -Index build ------------ - -.. doxygengroup:: ivf_pq_c_index_build - :project: cuvs - :members: - :content-only: - -Index search ------------- - -.. doxygengroup:: ivf_pq_c_index_search - :project: cuvs - :members: - :content-only: - -Index serialize ---------------- - -.. doxygengroup:: ivf_pq_c_index_serialize - :project: cuvs - :members: - :content-only: diff --git a/docs/source/c_api/neighbors_mg.rst b/docs/source/c_api/neighbors_mg.rst deleted file mode 100644 index bffe3fc4c5..0000000000 --- a/docs/source/c_api/neighbors_mg.rst +++ /dev/null @@ -1,257 +0,0 @@ -Multi-GPU Nearest Neighbors -=========================== - -The Multi-GPU (SNMG - single-node multi-GPUs) C API provides a set of functions to deploy ANN indexes across multiple GPUs for improved performance and scalability. - -.. role:: py(code) - :language: c - :class: highlight - -Common Types and Enums -====================== - -Common types and enums used across multi-GPU ANN algorithms. - -``#include `` - -.. doxygengroup:: mg_c_common_types - :project: cuvs - :members: - :content-only: - -Multi-GPU IVF-Flat -================== - -The Multi-GPU IVF-Flat method extends the IVF-Flat ANN algorithm to work across multiple GPUs. It provides two distribution modes: replicated (for higher throughput) and sharded (for handling larger datasets). - -``#include `` - -IVF-Flat Index Build Parameters -------------------------------- - -.. doxygengroup:: mg_ivf_flat_c_index_params - :project: cuvs - :members: - :content-only: - -IVF-Flat Index Search Parameters --------------------------------- - -.. doxygengroup:: mg_ivf_flat_c_search_params - :project: cuvs - :members: - :content-only: - -IVF-Flat Index --------------- - -.. doxygengroup:: mg_ivf_flat_c_index - :project: cuvs - :members: - :content-only: - -IVF-Flat Index Build --------------------- - -.. doxygengroup:: mg_ivf_flat_c_index_build - :project: cuvs - :members: - :content-only: - -IVF-Flat Index Search ---------------------- - -.. doxygengroup:: mg_ivf_flat_c_index_search - :project: cuvs - :members: - :content-only: - -IVF-Flat Index Extend ---------------------- - -.. doxygengroup:: mg_ivf_flat_c_index_extend - :project: cuvs - :members: - :content-only: - -IVF-Flat Index Serialize ------------------------- - -.. doxygengroup:: mg_ivf_flat_c_index_serialize - :project: cuvs - :members: - :content-only: - -IVF-Flat Index Deserialize ---------------------------- - -.. doxygengroup:: mg_ivf_flat_c_index_deserialize - :project: cuvs - :members: - :content-only: - -IVF-Flat Index Distribute --------------------------- - -.. doxygengroup:: mg_ivf_flat_c_index_distribute - :project: cuvs - :members: - :content-only: - -Multi-GPU IVF-PQ -================= - -The Multi-GPU IVF-PQ method extends the IVF-PQ ANN algorithm to work across multiple GPUs. It provides two distribution modes: replicated (for higher throughput) and sharded (for handling larger datasets). - -``#include `` - -IVF-PQ Index Build Parameters ------------------------------ - -.. doxygengroup:: mg_ivf_pq_c_index_params - :project: cuvs - :members: - :content-only: - -IVF-PQ Index Search Parameters ------------------------------- - -.. doxygengroup:: mg_ivf_pq_c_search_params - :project: cuvs - :members: - :content-only: - -IVF-PQ Index ------------- - -.. doxygengroup:: mg_ivf_pq_c_index - :project: cuvs - :members: - :content-only: - -IVF-PQ Index Build ------------------- - -.. doxygengroup:: mg_ivf_pq_c_index_build - :project: cuvs - :members: - :content-only: - -IVF-PQ Index Search -------------------- - -.. doxygengroup:: mg_ivf_pq_c_index_search - :project: cuvs - :members: - :content-only: - -IVF-PQ Index Extend -------------------- - -.. doxygengroup:: mg_ivf_pq_c_index_extend - :project: cuvs - :members: - :content-only: - -IVF-PQ Index Serialize ----------------------- - -.. doxygengroup:: mg_ivf_pq_c_index_serialize - :project: cuvs - :members: - :content-only: - -IVF-PQ Index Deserialize ------------------------- - -.. doxygengroup:: mg_ivf_pq_c_index_deserialize - :project: cuvs - :members: - :content-only: - -IVF-PQ Index Distribute ------------------------ - -.. doxygengroup:: mg_ivf_pq_c_index_distribute - :project: cuvs - :members: - :content-only: - -Multi-GPU CAGRA -================ - -The Multi-GPU CAGRA method extends the CAGRA graph-based ANN algorithm to work across multiple GPUs. It provides two distribution modes: replicated (for higher throughput) and sharded (for handling larger datasets). - -``#include `` - -CAGRA Index Build Parameters ----------------------------- - -.. doxygengroup:: mg_cagra_c_index_params - :project: cuvs - :members: - :content-only: - -CAGRA Index Search Parameters ------------------------------ - -.. doxygengroup:: mg_cagra_c_search_params - :project: cuvs - :members: - :content-only: - -CAGRA Index ------------ - -.. doxygengroup:: mg_cagra_c_index - :project: cuvs - :members: - :content-only: - -CAGRA Index Build ------------------ - -.. doxygengroup:: mg_cagra_c_index_build - :project: cuvs - :members: - :content-only: - -CAGRA Index Search ------------------- - -.. doxygengroup:: mg_cagra_c_index_search - :project: cuvs - :members: - :content-only: - -CAGRA Index Extend ------------------- - -.. doxygengroup:: mg_cagra_c_index_extend - :project: cuvs - :members: - :content-only: - -CAGRA Index Serialize ---------------------- - -.. doxygengroup:: mg_cagra_c_index_serialize - :project: cuvs - :members: - :content-only: - -CAGRA Index Deserialize ------------------------ - -.. doxygengroup:: mg_cagra_c_index_deserialize - :project: cuvs - :members: - :content-only: - -CAGRA Index Distribute ----------------------- - -.. doxygengroup:: mg_cagra_c_index_distribute - :project: cuvs - :members: - :content-only: diff --git a/docs/source/c_api/neighbors_vamana_c.rst b/docs/source/c_api/neighbors_vamana_c.rst deleted file mode 100644 index 90e47f1f6e..0000000000 --- a/docs/source/c_api/neighbors_vamana_c.rst +++ /dev/null @@ -1,43 +0,0 @@ -Vamana -====== - -Vamana is the graph construction algorithm behind the well-known DiskANN vector search solution. The cuVS implementation of Vamana/DiskANN is a custom GPU-acceleration version of the algorithm that aims to reduce index construction time using NVIDIA GPUs. - - -.. role:: py(code) - :language: c - :class: highlight - -``#include `` - -Index build parameters ----------------------- - -.. doxygengroup:: vamana_c_index_params - :project: cuvs - :members: - :content-only: - -Index ------ - -.. doxygengroup:: vamana_c_index - :project: cuvs - :members: - :content-only: - -Index build ------------ - -.. doxygengroup:: vamana_c_index_build - :project: cuvs - :members: - :content-only: - -Index serialize ---------------- - -.. doxygengroup:: vamana_c_index_serialize - :project: cuvs - :members: - :content-only: diff --git a/docs/source/c_api/preprocessing.rst b/docs/source/c_api/preprocessing.rst deleted file mode 100644 index 1c65455de0..0000000000 --- a/docs/source/c_api/preprocessing.rst +++ /dev/null @@ -1,38 +0,0 @@ -Preprocessing -============= - -.. role:: py(code) - :language: c - :class: highlight - -Binary Quantizer ----------------- - -.. doxygengroup:: preprocessing_c_binary - :project: cuvs - :members: - :content-only: - -Product Quantizer ------------------ - -.. doxygengroup:: preprocessing_c_pq - :project: cuvs - :members: - :content-only: - -PCA (Principal Component Analysis) ------------------------------------ - -.. doxygengroup:: preprocessing_c_pca - :project: cuvs - :members: - :content-only: - -Scalar Quantizer ----------------- - -.. doxygengroup:: preprocessing_c_scalar - :project: cuvs - :members: - :content-only: diff --git a/docs/source/conf.py b/docs/source/conf.py deleted file mode 100644 index ffec63ded9..0000000000 --- a/docs/source/conf.py +++ /dev/null @@ -1,220 +0,0 @@ -# SPDX-FileCopyrightText: Copyright (c) 2018-2026, NVIDIA CORPORATION. -# SPDX-License-Identifier: Apache-2.0 - -import os -import sys -from packaging.version import Version - -import cuvs - -# If extensions (or modules to document with autodoc) are in another -# directory, add these directories to sys.path here. If the directory -# is relative to the documentation root, use os.path.abspath to make it -# absolute, like shown here. -sys.path.insert(0, os.path.abspath("sphinxext")) - -from github_link import make_linkcode_resolve # noqa - - -# -- General configuration ------------------------------------------------ - -# If your documentation needs a minimal Sphinx version, state it here. -# -# needs_sphinx = '1.0' - -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom -# ones. -extensions = [ - "numpydoc", - "sphinx.ext.linkcode", - "sphinx.ext.autodoc", - "sphinx.ext.autosummary", - "sphinx.ext.doctest", - "sphinx.ext.intersphinx", - "IPython.sphinxext.ipython_console_highlighting", - "IPython.sphinxext.ipython_directive", - "breathe", - "recommonmark", - "sphinx_markdown_tables", - "sphinx_copybutton", -] - -breathe_default_project = "cuvs" -breathe_projects = { - "cuvs": "../../cpp/doxygen/_xml/", -} -ipython_mplbackend = "str" - -# Add any paths that contain templates here, relative to this directory. -templates_path = ["_templates"] - -# generate autosummary even if no references -# autosummary_generate = True - -# The suffix(es) of source filenames. -# You can specify multiple suffix as a list of string: -# -# source_suffix = ['.rst', '.md'] -source_suffix = {".rst": "restructuredtext", ".md": "markdown"} - -# The master toctree document. -master_doc = "index" - -# General information about the project. -project = "cuvs" -copyright = "2024 - 2026, NVIDIA Corporation" -author = "NVIDIA Corporation" - -# The version info for the project you're documenting, acts as replacement for -# |version| and |release|, also used in various other places throughout the -# built documents. -# -CUVS_VERSION = Version(cuvs.__version__) -# The short X.Y version. -version = f"{CUVS_VERSION.major:02}.{CUVS_VERSION.minor:02}" -# The full version, including alpha/beta/rc tags. -release = ( - f"{CUVS_VERSION.major:02}.{CUVS_VERSION.minor:02}.{CUVS_VERSION.micro:02}" -) - -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -# -# This is also used if you do content translation via gettext catalogs. -# Usually you set "language" from the command line for these cases. -language = "en" - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -# This patterns also effect to html_static_path and html_extra_path -exclude_patterns = [] - -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = "sphinx" - -# If true, `todo` and `todoList` produce output, else they produce nothing. -todo_include_todos = False - -# -- Options for HTML output ---------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -# - -html_theme = "nvidia_sphinx_theme" - - -# Theme options are theme-specific and customize the look and feel of a theme -# further. For a list of options available for each theme, see the -# documentation. -# -html_theme_options = { - "external_links": [], - # https://github.com/pydata/pydata-sphinx-theme/issues/1220 - "icon_links": [], - "github_url": "https://github.com/rapidsai/cuvs", - "twitter_url": "https://twitter.com/rapidsai", - "show_toc_level": 1, - "navbar_align": "right", -} - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ["_static"] - -html_js_files = [] - -# -- Options for HTMLHelp output ------------------------------------------ - -# Output file base name for HTML help builder. -htmlhelp_basename = "cuvsdoc" - -# -- Options for LaTeX output --------------------------------------------- - -latex_elements = { - # The paper size ('letterpaper' or 'a4paper'). - # - # 'papersize': 'letterpaper', - # The font size ('10pt', '11pt' or '12pt'). - # - # 'pointsize': '10pt', - # Additional stuff for the LaTeX preamble. - # - # 'preamble': '', - # Latex figure (float) alignment - # - # 'figure_align': 'htbp', -} - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, -# author, documentclass [howto, manual, or own class]). -latex_documents = [ - ( - master_doc, - "cuvs.tex", - "cuVS Documentation", - "NVIDIA Corporation", - "manual", - ), -] - -# -- Options for manual page output --------------------------------------- - -# One entry per manual page. List of tuples -# (source start file, name, description, authors, manual section). -man_pages = [(master_doc, "cuvs", "cuVS Documentation", [author], 1)] - -# -- Options for Texinfo output ------------------------------------------- - -# Grouping the document tree into Texinfo files. List of tuples -# (source start file, target name, title, author, -# dir menu entry, description, category) -texinfo_documents = [ - ( - master_doc, - "cuvs", - "cuVS Documentation", - author, - "cuvs", - "One line description of project.", - "Miscellaneous", - ), -] - -# Example configuration for intersphinx: refer to the Python standard library. -intersphinx_mapping = { - "python": ("https://docs.python.org/", None), - "scipy": ("https://docs.scipy.org/doc/scipy/", None), -} - -# Config numpydoc -numpydoc_show_inherited_class_members = False -numpydoc_class_members_toctree = False - - -def setup(app): - app.add_css_file("references.css") - app.add_css_file("https://docs.rapids.ai/assets/css/custom.css") - app.add_js_file( - "https://docs.rapids.ai/assets/js/custom.js", loading_method="defer" - ) - app.add_js_file("collapse_overloads.js") - - -# The following is used by sphinx.ext.linkcode to provide links to github -linkcode_resolve = make_linkcode_resolve( - "cuvs", - "https://github.com/rapidsai/cuvs/" - "blob/{revision}/python/cuvs/" - "{package}/{path}#L{lineno}", -) - -# Set the default role for interpreted code (anything surrounded in `single -# backticks`) to be a python object. See -# https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-default_role -default_role = "py:obj" - -suppress_warnings = ["duplicate_declaration.cpp"] diff --git a/docs/source/cpp_api.rst b/docs/source/cpp_api.rst deleted file mode 100644 index 34f48a88f6..0000000000 --- a/docs/source/cpp_api.rst +++ /dev/null @@ -1,15 +0,0 @@ -~~~~~~~~~~~~~~~~~~~~~ -C++ API Documentation -~~~~~~~~~~~~~~~~~~~~~ - -.. _api: - -.. toctree:: - :maxdepth: 4 - - cpp_api/cluster.rst - cpp_api/distance.rst - cpp_api/neighbors.rst - cpp_api/preprocessing.rst - cpp_api/selection.rst - cpp_api/stats.rst diff --git a/docs/source/cpp_api/cluster.rst b/docs/source/cpp_api/cluster.rst deleted file mode 100644 index 8165a7d115..0000000000 --- a/docs/source/cpp_api/cluster.rst +++ /dev/null @@ -1,14 +0,0 @@ -Cluster -======= - -.. role:: py(code) - :language: c++ - :class: highlight - -.. toctree:: - :maxdepth: 2 - :caption: Contents: - - cluster_agglomerative.rst - cluster_kmeans.rst - cluster_spectral.rst diff --git a/docs/source/cpp_api/cluster_agglomerative.rst b/docs/source/cpp_api/cluster_agglomerative.rst deleted file mode 100644 index 57a46504c4..0000000000 --- a/docs/source/cpp_api/cluster_agglomerative.rst +++ /dev/null @@ -1,31 +0,0 @@ -Agglomerative -============= - -.. role:: py(code) - :language: c++ - :class: highlight - -Parameters ----------- - -``#include `` - -namespace *cuvs::cluster::agglomerative* - -.. doxygengroup:: agglomerative_params - :project: cuvs - :members: - :content-only: - - -Agglomerative -------------- - -``#include `` - -namespace *cuvs::cluster::agglomerative* - -.. doxygengroup:: single_linkage - :project: cuvs - :members: - :content-only: diff --git a/docs/source/cpp_api/cluster_kmeans.rst b/docs/source/cpp_api/cluster_kmeans.rst deleted file mode 100644 index 70ab57bcbd..0000000000 --- a/docs/source/cpp_api/cluster_kmeans.rst +++ /dev/null @@ -1,44 +0,0 @@ -K-Means -======= - -.. role:: py(code) - :language: c++ - :class: highlight - -Parameters ----------- - -``#include `` - -namespace *cuvs::cluster::kmeans* - -.. doxygengroup:: kmeans_params - :project: cuvs - :members: - :content-only: - - -K-means -------- - -``#include `` - -namespace *cuvs::cluster::kmeans* - -.. doxygengroup:: kmeans - :project: cuvs - :members: - :content-only: - - -K-means Helpers ---------------- - -``#include `` - -namespace *cuvs::cluster::kmeans::helpers* - -.. doxygengroup:: kmeans_helpers - :project: cuvs - :members: - :content-only: diff --git a/docs/source/cpp_api/cluster_spectral.rst b/docs/source/cpp_api/cluster_spectral.rst deleted file mode 100644 index 19dedeef19..0000000000 --- a/docs/source/cpp_api/cluster_spectral.rst +++ /dev/null @@ -1,28 +0,0 @@ -Spectral Clustering -=================== - -Spectral clustering is a graph-based clustering technique that uses the eigenvalues of similarity matrices to identify clusters with complex, non-convex shapes. - -.. role:: py(code) - :language: c++ - :class: highlight - -``#include `` - -namespace *cuvs::cluster::spectral* - -Parameters ----------- - -.. doxygengroup:: spectral_params - :project: cuvs - :members: - :content-only: - -Spectral Clustering -------------------- - -.. doxygengroup:: spectral - :project: cuvs - :members: - :content-only: diff --git a/docs/source/cpp_api/distance.rst b/docs/source/cpp_api/distance.rst deleted file mode 100644 index 994fbdaff5..0000000000 --- a/docs/source/cpp_api/distance.rst +++ /dev/null @@ -1,32 +0,0 @@ -Distance -======== - -This page provides C++ class references for the publicly-exposed elements of the `cuvs/distance` package. cuVS's -distances have been highly optimized and support a wide assortment of different distance measures. - -.. role:: py(code) - :language: c++ - :class: highlight - -Distance Types --------------- - -``#include `` - -namespace *cuvs::distance* - -.. doxygenenum:: cuvsDistanceType - :project: cuvs - - -Pairwise Distances ------------------- - -``#include `` - -namespace *cuvs::distance* - -.. doxygengroup:: pairwise_distance - :project: cuvs - :members: - :content-only: diff --git a/docs/source/cpp_api/neighbors.rst b/docs/source/cpp_api/neighbors.rst deleted file mode 100644 index 66b4e0c4aa..0000000000 --- a/docs/source/cpp_api/neighbors.rst +++ /dev/null @@ -1,24 +0,0 @@ -Nearest Neighbors -================= - -.. role:: py(code) - :language: c++ - :class: highlight - -.. toctree:: - :maxdepth: 2 - :caption: Contents: - - neighbors_all_neighbors.rst - neighbors_bruteforce.rst - neighbors_cagra.rst - neighbors_dynamic_batching.rst - neighbors_epsilon_neighborhood.rst - neighbors_filter.rst - neighbors_hnsw.rst - neighbors_ivf_flat.rst - neighbors_ivf_pq.rst - neighbors_mg.rst - neighbors_nn_descent.rst - neighbors_refine.rst - neighbors_vamana.rst diff --git a/docs/source/cpp_api/neighbors_all_neighbors.rst b/docs/source/cpp_api/neighbors_all_neighbors.rst deleted file mode 100644 index 3a7eaee61f..0000000000 --- a/docs/source/cpp_api/neighbors_all_neighbors.rst +++ /dev/null @@ -1,29 +0,0 @@ -All-Neighbors -============= - -All-Neighbors allows building an approximate all-neighbors knn graph. Given a full dataset, it finds nearest neighbors for all the training vectors in the dataset. - -.. role:: py(code) - :language: c++ - :class: highlight - -``#include `` - -namespace *cuvs::neighbors::all_neighbors* - -Build Parameters ----------------- - -.. doxygengroup:: all_neighbors_cpp_params - :project: cuvs - :members: - :content-only: - - -Build ------ - -.. doxygengroup:: all_neighbors_cpp_build - :project: cuvs - :members: - :content-only: diff --git a/docs/source/cpp_api/neighbors_bruteforce.rst b/docs/source/cpp_api/neighbors_bruteforce.rst deleted file mode 100644 index 1a3f2f7154..0000000000 --- a/docs/source/cpp_api/neighbors_bruteforce.rst +++ /dev/null @@ -1,44 +0,0 @@ -Bruteforce -========== - -The bruteforce method is running the KNN algorithm. It performs an extensive search, and in contrast to ANN methods produces an exact result. - -.. role:: py(code) - :language: c++ - :class: highlight - -``#include `` - -namespace *cuvs::neighbors::bruteforce* - -Index ------ - -.. doxygengroup:: bruteforce_cpp_index - :project: cuvs - :members: - :content-only: - -Index build ------------ - -.. doxygengroup:: bruteforce_cpp_index_build - :project: cuvs - :members: - :content-only: - -Index search ------------- - -.. doxygengroup:: bruteforce_cpp_index_search - :project: cuvs - :members: - :content-only: - -Index serialize ---------------- - -.. doxygengroup:: bruteforce_cpp_index_serialize - :project: cuvs - :members: - :content-only: diff --git a/docs/source/cpp_api/neighbors_cagra.rst b/docs/source/cpp_api/neighbors_cagra.rst deleted file mode 100644 index aa1e6ed117..0000000000 --- a/docs/source/cpp_api/neighbors_cagra.rst +++ /dev/null @@ -1,84 +0,0 @@ -CAGRA -===== - -CAGRA is a graph-based nearest neighbors algorithm that was built from the ground up for GPU acceleration. CAGRA demonstrates state-of-the art index build and query performance for both small- and large-batch sized search. - -.. role:: py(code) - :language: c++ - :class: highlight - -``#include `` - -namespace *cuvs::neighbors::cagra* - -Index build parameters ----------------------- - -.. doxygengroup:: cagra_cpp_index_params - :project: cuvs - :members: - :content-only: - -Index search parameters ------------------------ - -.. doxygengroup:: cagra_cpp_search_params - :project: cuvs - :members: - :content-only: - -Index extend parameters ------------------------ - -.. doxygengroup:: cagra_cpp_extend_params - :project: cuvs - :members: - :content-only: - -Index ------ - -.. doxygengroup:: cagra_cpp_index - :project: cuvs - :members: - :content-only: - -Index build ------------ - -.. doxygengroup:: cagra_cpp_index_build - :project: cuvs - :members: - :content-only: - -Index search ------------- - -.. doxygengroup:: cagra_cpp_index_search - :project: cuvs - :members: - :content-only: - -Index extend ------------- - -.. doxygengroup:: cagra_cpp_index_extend - :project: cuvs - :members: - :content-only: - -Index merge ------------ - -.. doxygengroup:: cagra_cpp_index_merge - :project: cuvs - :members: - :content-only: - -Index serialize ---------------- - -.. doxygengroup:: cagra_cpp_serialize - :project: cuvs - :members: - :content-only: diff --git a/docs/source/cpp_api/neighbors_dynamic_batching.rst b/docs/source/cpp_api/neighbors_dynamic_batching.rst deleted file mode 100644 index adc5cb56aa..0000000000 --- a/docs/source/cpp_api/neighbors_dynamic_batching.rst +++ /dev/null @@ -1,45 +0,0 @@ -Dynamic Batching -================ - -Dynamic Batching allows grouping small search requests into batches to increase the device occupancy and throughput while keeping the latency within limits. - -.. role:: py(code) - :language: c++ - :class: highlight - -``#include `` - -namespace *cuvs::neighbors::dynamic_batching* - -Index build parameters ----------------------- - -.. doxygengroup:: dynamic_batching_cpp_index_params - :project: cuvs - :members: - :content-only: - -Index search parameters ------------------------ - -.. doxygengroup:: dynamic_batching_cpp_search_params - :project: cuvs - :members: - :content-only: - -Index ------ - -.. doxygengroup:: dynamic_batching_cpp_index - :project: cuvs - :members: - :content-only: - - -Index search ------------- - -.. doxygengroup:: dynamic_batching_cpp_search - :project: cuvs - :members: - :content-only: diff --git a/docs/source/cpp_api/neighbors_epsilon_neighborhood.rst b/docs/source/cpp_api/neighbors_epsilon_neighborhood.rst deleted file mode 100644 index 1ca957bfed..0000000000 --- a/docs/source/cpp_api/neighbors_epsilon_neighborhood.rst +++ /dev/null @@ -1,20 +0,0 @@ -Epsilon Neighborhood -==================== - -Epsilon neighborhood finds all neighbors within a given radius (epsilon) for each point in a dataset. Unlike k-nearest neighbors which finds a fixed number of neighbors, epsilon neighborhood finds all points within a specified distance threshold, making it particularly useful for density-based algorithms and graph construction. - -.. role:: py(code) - :language: c++ - :class: highlight - -``#include `` - -namespace *cuvs::neighbors::epsilon_neighborhood* - -L2-Squared Distance Operations ------------------------------- - -.. doxygengroup:: epsilon_neighborhood_cpp_l2 - :project: cuvs - :members: - :content-only: diff --git a/docs/source/cpp_api/neighbors_filter.rst b/docs/source/cpp_api/neighbors_filter.rst deleted file mode 100644 index aba1d348fe..0000000000 --- a/docs/source/cpp_api/neighbors_filter.rst +++ /dev/null @@ -1,18 +0,0 @@ -Filtering -========== - -All nearest neighbors search methods support filtering. Filtering is a method to reduce the number -of candidates that are considered for the nearest neighbors search. - -.. role:: py(code) - :language: c++ - :class: highlight - -``#include `` - -namespace *cuvs::neighbors* - -.. doxygengroup:: neighbors_filtering - :project: cuvs - :members: - :content-only: diff --git a/docs/source/cpp_api/neighbors_hnsw.rst b/docs/source/cpp_api/neighbors_hnsw.rst deleted file mode 100644 index 00dd3a213c..0000000000 --- a/docs/source/cpp_api/neighbors_hnsw.rst +++ /dev/null @@ -1,67 +0,0 @@ -HNSW -==== - -This is a wrapper for hnswlib, to load a CAGRA index as an immutable HNSW index. The loaded HNSW index is only compatible in cuVS, and can be searched using wrapper functions. - -.. role:: py(code) - :language: c++ - :class: highlight - -``#include `` - -namespace *cuvs::neighbors::hnsw* - -Index search parameters ------------------------ - -.. doxygengroup:: hnsw_cpp_search_params - :project: cuvs - :members: - :content-only: - -Index ------ - -.. doxygengroup:: hnsw_cpp_index - :project: cuvs - :members: - :content-only: - -Index extend parameters ------------------------ - -.. doxygengroup:: hnsw_cpp_extend_params - :project: cuvs - :members: - :content-only: - -Index extend ------------- -.. doxygengroup:: hnsw_cpp_index_extend - :project: cuvs - :members: - :content-only: - -Index load ----------- - -.. doxygengroup:: hnsw_cpp_index_load - :project: cuvs - :members: - :content-only: - -Index search ------------- - -.. doxygengroup:: hnsw_cpp_index_search - :project: cuvs - :members: - :content-only: - -Index serialize ---------------- - -.. doxygengroup:: hnsw_cpp_index_serialize - :project: cuvs - :members: - :content-only: diff --git a/docs/source/cpp_api/neighbors_ivf_flat.rst b/docs/source/cpp_api/neighbors_ivf_flat.rst deleted file mode 100644 index 3836223e10..0000000000 --- a/docs/source/cpp_api/neighbors_ivf_flat.rst +++ /dev/null @@ -1,68 +0,0 @@ -IVF-Flat -======== - -The IVF-Flat method is an ANN algorithm. It uses an inverted file index (IVF) with unmodified (that is, flat) vectors. This algorithm provides simple knobs to reduce the overall search space and to trade-off accuracy for speed. - -.. role:: py(code) - :language: c++ - :class: highlight - -``#include `` - -namespace *cuvs::neighbors::ivf_flat* - -Index build parameters ----------------------- - -.. doxygengroup:: ivf_flat_cpp_index_params - :project: cuvs - :members: - :content-only: - -Index search parameters ------------------------ - -.. doxygengroup:: ivf_flat_cpp_search_params - :project: cuvs - :members: - :content-only: - -Index ------ - -.. doxygengroup:: ivf_flat_cpp_index - :project: cuvs - :members: - :content-only: - -Index build ------------ - -.. doxygengroup:: ivf_flat_cpp_index_build - :project: cuvs - :members: - :content-only: - -Index extend ------------- - -.. doxygengroup:: ivf_flat_cpp_index_extend - :project: cuvs - :members: - :content-only: - -Index search ------------- - -.. doxygengroup:: ivf_flat_cpp_index_search - :project: cuvs - :members: - :content-only: - -Index serialize ---------------- - -.. doxygengroup:: ivf_flat_cpp_serialize - :project: cuvs - :members: - :content-only: diff --git a/docs/source/cpp_api/neighbors_ivf_pq.rst b/docs/source/cpp_api/neighbors_ivf_pq.rst deleted file mode 100644 index cc515682b9..0000000000 --- a/docs/source/cpp_api/neighbors_ivf_pq.rst +++ /dev/null @@ -1,80 +0,0 @@ -IVF-PQ -====== - -The IVF-PQ method is an ANN algorithm. Like IVF-Flat, IVF-PQ splits the points into a number of clusters (also specified by a parameter called n_lists) and searches the closest clusters to compute the nearest neighbors (also specified by a parameter called n_probes), but it shrinks the sizes of the vectors using a technique called product quantization. - -.. role:: py(code) - :language: c++ - :class: highlight - -``#include `` - -namespace *cuvs::neighbors::ivf_pq* - -Index build parameters ----------------------- - -.. doxygengroup:: ivf_pq_cpp_index_params - :project: cuvs - :members: - :content-only: - -Index search parameters ------------------------ - -.. doxygengroup:: ivf_pq_cpp_search_params - :project: cuvs - :members: - :content-only: - -Index ------ - -.. doxygengroup:: ivf_pq_cpp_index - :project: cuvs - :members: - :content-only: - -Index build ------------ - -.. doxygengroup:: ivf_pq_cpp_index_build - :project: cuvs - :members: - :content-only: - -Index extend ------------- - -.. doxygengroup:: ivf_pq_cpp_index_extend - :project: cuvs - :members: - :content-only: - -Index search ------------- - -.. doxygengroup:: ivf_pq_cpp_index_search - :project: cuvs - :members: - :content-only: - -Index serialize ---------------- - -.. doxygengroup:: ivf_pq_cpp_serialize - :project: cuvs - :members: - :content-only: - -Helper Methods ---------------- - -Additional helper functions for manipulating the underlying data of an IVF-PQ index, unpacking records, and writing PQ codes into an existing IVF list. - -namespace *cuvs::neighbors::ivf_pq::helpers* - -.. doxygengroup:: ivf_pq_cpp_helpers - :project: cuvs - :members: - :content-only: diff --git a/docs/source/cpp_api/neighbors_mg.rst b/docs/source/cpp_api/neighbors_mg.rst deleted file mode 100644 index a03490a157..0000000000 --- a/docs/source/cpp_api/neighbors_mg.rst +++ /dev/null @@ -1,76 +0,0 @@ -Multi-GPU Nearest Neighbors -=========================== - -The Multi-GPU (SNMG - single-node multi-GPUs) nearest neighbors API provides a set of functions to deploy ANN indexes across multiple GPUs for improved performance and scalability. - -.. role:: py(code) - :language: c++ - :class: highlight - -``#include `` - -namespace *cuvs::neighbors* - -Index build parameters ----------------------- - -.. doxygengroup:: mg_cpp_index_params - :project: cuvs - :members: - :content-only: - -Search parameters ------------------ - -.. doxygengroup:: mg_cpp_search_params - :project: cuvs - :members: - :content-only: - -Index build ------------ - -.. doxygengroup:: mg_cpp_index_build - :project: cuvs - :members: - :content-only: - -Index extend ------------- - -.. doxygengroup:: mg_cpp_index_extend - :project: cuvs - :members: - :content-only: - -Index search ------------- - -.. doxygengroup:: mg_cpp_index_search - :project: cuvs - :members: - :content-only: - -Index serialize ---------------- - -.. doxygengroup:: mg_cpp_serialize - :project: cuvs - :members: - :content-only: - -Index deserialize ------------------ - -.. doxygengroup:: mg_cpp_deserialize - :project: cuvs - :members: - :content-only: - -Distribute pre-built local index --------------------------------- - -.. doxygengroup:: mg_cpp_distribute - :project: cuvs - :members: - :content-only: diff --git a/docs/source/cpp_api/neighbors_nn_descent.rst b/docs/source/cpp_api/neighbors_nn_descent.rst deleted file mode 100644 index c21a1003db..0000000000 --- a/docs/source/cpp_api/neighbors_nn_descent.rst +++ /dev/null @@ -1,37 +0,0 @@ -NN-Descent -========== - -The NN-descent method is an ANN algorithm that directly approximates a k-nearest neighbors graph by randomly sampling points to compute distances and using neighbors of neighbors distances to reduce distance computations. - -.. role:: py(code) - :language: c++ - :class: highlight - -``#include `` - -namespace *cuvs::neighbors::nn_descent* - -Index build parameters ----------------------- - -.. doxygengroup:: nn_descent_cpp_index_params - :project: cuvs - :members: - :content-only: - - -Index ------ - -.. doxygengroup:: nn_descent_cpp_index - :project: cuvs - :members: - :content-only: - -Index build ------------ - -.. doxygengroup:: nn_descent_cpp_index_build - :project: cuvs - :members: - :content-only: diff --git a/docs/source/cpp_api/neighbors_refine.rst b/docs/source/cpp_api/neighbors_refine.rst deleted file mode 100644 index 4a90ee9959..0000000000 --- a/docs/source/cpp_api/neighbors_refine.rst +++ /dev/null @@ -1,20 +0,0 @@ -Refinement -========== - -Candidate refinement methods for nearest neighbors search - -.. role:: py(code) - :language: c++ - :class: highlight - -``#include `` - -namespace *cuvs::neighbors* - -Index ------ - -.. doxygengroup:: ann_refine - :project: cuvs - :members: - :content-only: diff --git a/docs/source/cpp_api/neighbors_vamana.rst b/docs/source/cpp_api/neighbors_vamana.rst deleted file mode 100644 index 25447efce1..0000000000 --- a/docs/source/cpp_api/neighbors_vamana.rst +++ /dev/null @@ -1,44 +0,0 @@ -Vamana -====== - -Vamana is the graph construction algorithm behind the well-known DiskANN vector search solution. The cuVS implementation of Vamana/DiskANN is a custom GPU-acceleration version of the algorithm that aims to reduce index construction time using NVIDIA GPUs. - -.. role:: py(code) - :language: c++ - :class: highlight - -``#include `` - -namespace *cuvs::neighbors::vamana* - -Index build parameters ----------------------- - -.. doxygengroup:: vamana_cpp_index_params - :project: cuvs - :members: - :content-only: - -Index ------ - -.. doxygengroup:: vamana_cpp_index - :project: cuvs - :members: - :content-only: - -Index build ------------ - -.. doxygengroup:: vamana_cpp_index_build - :project: cuvs - :members: - :content-only: - -Index serialize ---------------- - -.. doxygengroup:: vamana_cpp_serialize - :project: cuvs - :members: - :content-only: diff --git a/docs/source/cpp_api/preprocessing.rst b/docs/source/cpp_api/preprocessing.rst deleted file mode 100644 index 417c8faf7e..0000000000 --- a/docs/source/cpp_api/preprocessing.rst +++ /dev/null @@ -1,14 +0,0 @@ -Preprocessing -============= - -.. role:: py(code) - :language: c++ - :class: highlight - -.. toctree:: - :maxdepth: 2 - :caption: Contents: - - preprocessing_pca.rst - preprocessing_quantize.rst - preprocessing_spectral_embedding.rst diff --git a/docs/source/cpp_api/preprocessing_pca.rst b/docs/source/cpp_api/preprocessing_pca.rst deleted file mode 100644 index 3083f42daf..0000000000 --- a/docs/source/cpp_api/preprocessing_pca.rst +++ /dev/null @@ -1,27 +0,0 @@ -PCA -=== - -Principal Component Analysis (PCA) is a linear dimensionality reduction technique that projects data onto orthogonal directions of maximum variance. - -.. role:: py(code) - :language: c++ - :class: highlight - -``#include `` - -namespace *cuvs::preprocessing::pca* - -Parameters ----------- - -.. doxygenstruct:: cuvs::preprocessing::pca::params - :project: cuvs - :members: - -PCA ---------- - -.. doxygengroup:: pca - :project: cuvs - :members: - :content-only: diff --git a/docs/source/cpp_api/preprocessing_quantize.rst b/docs/source/cpp_api/preprocessing_quantize.rst deleted file mode 100644 index fe8bf1ed8e..0000000000 --- a/docs/source/cpp_api/preprocessing_quantize.rst +++ /dev/null @@ -1,45 +0,0 @@ -Quantize -======== - -This page provides C++ class references for the publicly-exposed elements of the -`cuvs/preprocessing/quantize` package. - -.. role:: py(code) - :language: c++ - :class: highlight - -Binary Quantizer ----------------- - -``#include `` - -namespace *cuvs::preprocessing::quantize::binary* - -.. doxygengroup:: binary - :project: cuvs - :members: - :content-only: - -Product Quantizer ------------------ - -``#include `` - -namespace *cuvs::preprocessing::quantize::pq* - -.. doxygengroup:: pq - :project: cuvs - :members: - :content-only: - -Scalar Quantizer ----------------- - -``#include `` - -namespace *cuvs::preprocessing::quantize::scalar* - -.. doxygengroup:: scalar - :project: cuvs - :members: - :content-only: diff --git a/docs/source/cpp_api/preprocessing_spectral_embedding.rst b/docs/source/cpp_api/preprocessing_spectral_embedding.rst deleted file mode 100644 index bfae68f9de..0000000000 --- a/docs/source/cpp_api/preprocessing_spectral_embedding.rst +++ /dev/null @@ -1,108 +0,0 @@ -Spectral Embedding -================== - -Spectral embedding is a powerful dimensionality reduction technique that uses the eigenvectors -of the graph Laplacian to embed high-dimensional data into a lower-dimensional space. This -method is particularly effective for discovering non-linear manifold structures in data and -is widely used in clustering, visualization, and feature extraction tasks. - -.. role:: py(code) - :language: c++ - :class: highlight - -Overview --------- - -The spectral embedding algorithm works by: - -1. **Graph Construction**: Building a k-nearest neighbors graph from the input data -2. **Laplacian Computation**: Computing the graph Laplacian matrix (normalized or unnormalized) -3. **Eigendecomposition**: Finding the eigenvectors corresponding to the smallest eigenvalues -4. **Embedding**: Using these eigenvectors as coordinates in the lower-dimensional space - -Parameters ----------- - -``#include `` - -namespace *cuvs::preprocessing::spectral_embedding* - -.. doxygenstruct:: cuvs::preprocessing::spectral_embedding::params - :project: cuvs - :members: - -Spectral Embedding ------------------- - -``#include `` - -namespace *cuvs::preprocessing::spectral_embedding* - -.. doxygengroup:: spectral_embedding - :project: cuvs - :content-only: - -Example Usage -------------- - -Basic Usage with Dataset -~~~~~~~~~~~~~~~~~~~~~~~~ - -.. code-block:: cpp - - #include - #include - - // Initialize RAFT resources - raft::resources handle; - - // Configure spectral embedding parameters - cuvs::preprocessing::spectral_embedding::params params; - params.n_components = 2; // Reduce to 2D for visualization - params.n_neighbors = 15; // Local neighborhood size - params.norm_laplacian = true; // Use normalized Laplacian - params.drop_first = true; // Drop constant eigenvector - params.seed = 42; // For reproducibility - - // Create input dataset (n_samples x n_features) - int n_samples = 1000; - int n_features = 50; - auto dataset = raft::make_device_matrix(handle, n_samples, n_features); - // ... populate dataset with your data ... - - // Allocate output embedding matrix (n_samples x n_components) - auto embedding = raft::make_device_matrix( - handle, n_samples, params.n_components); - - // Perform spectral embedding - cuvs::preprocessing::spectral_embedding::transform( - handle, params, dataset.view(), embedding.view()); - -Using Precomputed Graph -~~~~~~~~~~~~~~~~~~~~~~~ - -.. code-block:: cpp - - #include - #include - - raft::resources handle; - - // Configure parameters (n_neighbors is ignored with precomputed graph) - cuvs::preprocessing::spectral_embedding::params params; - params.n_components = 3; - params.norm_laplacian = true; - params.drop_first = true; - params.seed = 42; - - // Assume we have a precomputed connectivity graph - // This could be from custom similarity computation or k-NN search - raft::device_coo_matrix connectivity_graph(...); - - // Allocate output embedding - auto embedding = raft::make_device_matrix( - handle, n_samples, params.n_components); - - // Perform spectral embedding with precomputed graph - cuvs::preprocessing::spectral_embedding::transform( - handle, params, connectivity_graph.view(), embedding.view()); diff --git a/docs/source/cpp_api/selection.rst b/docs/source/cpp_api/selection.rst deleted file mode 100644 index 5abe81662f..0000000000 --- a/docs/source/cpp_api/selection.rst +++ /dev/null @@ -1,19 +0,0 @@ -Selection -========= - -This page provides C++ class references for the publicly-exposed elements of the `cuvs/selection` -package. - -.. role:: py(code) - :language: c++ - :class: highlight - -Select-K --------- - -``#include `` - -namespace *cuvs::selection* - -.. doxygengroup:: select_k - :project: cuvs diff --git a/docs/source/cpp_api/stats.rst b/docs/source/cpp_api/stats.rst deleted file mode 100644 index 988ba05dfc..0000000000 --- a/docs/source/cpp_api/stats.rst +++ /dev/null @@ -1,34 +0,0 @@ -Stats -===== - - -This page provides C++ class references for the publicly-exposed elements of the `cuvs/stats` -package. - -.. role:: py(code) - :language: c++ - :class: highlight - -Silhouette Score ----------------- - -``#include `` - -namespace *cuvs::stats* - -.. doxygengroup:: stats_silhouette_score - :project: cuvs - :members: - :content-only: - -Trustworthiness Score ---------------------- - -``#include `` - -namespace *cuvs::stats* - -.. doxygengroup:: stats_trustworthiness - :project: cuvs - :members: - :content-only: diff --git a/docs/source/cuvs_bench/index.rst b/docs/source/cuvs_bench/index.rst deleted file mode 100644 index 2efa9ff86b..0000000000 --- a/docs/source/cuvs_bench/index.rst +++ /dev/null @@ -1,661 +0,0 @@ -~~~~~~~~~~ -cuVS Bench -~~~~~~~~~~ - -cuVS bench provides a reproducible benchmarking tool for various ANN search implementations. It's especially suitable for comparing GPU implementations as well as comparing GPU against CPU. One of the primary goals of cuVS is to capture ideal index configurations for a variety of important usage patterns so the results can be reproduced easily on different hardware environments, such as on-prem and cloud. - -This tool offers several benefits, including - -#. Making fair comparisons of index build times - -#. Making fair comparisons of index search throughput and/or latency - -#. Finding the optimal parameter settings for a range of recall buckets - -#. Easily generating consistently styled plots for index build and search - -#. Profiling blind spots and potential for algorithm optimization - -#. Investigating the relationship between different parameter settings, index build times, and search performance. - -- `Installing the benchmarks`_ - - * `Conda`_ - - * `Docker`_ - -- `Running the benchmarks`_ - - * `End-to-end: smaller-scale benchmarks (<1M to 10M)`_ - - * `End-to-end: large-scale benchmarks (>10M vectors)`_ - - * `Running with Docker containers`_ - - * `End-to-end run on GPU`_ - - * `Manually run the scripts inside the container`_ - - * `Evaluating the results`_ - -- `Creating and customizing dataset configurations`_ - - * `Multi-GPU benchmarks`_ - -- `Adding a new index algorithm`_ - - * `Implementation and configuration`_ - - * `Adding a Cmake target`_ - -Installing the benchmarks -========================= - -There are two main ways pre-compiled benchmarks are distributed: - -- `Conda`_ For users not using containers but want an easy to install and use Python package. Pip wheels are planned to be added as an alternative for users that cannot use conda and prefer to not use containers. -- `Docker`_ Only needs docker and `NVIDIA docker `_ to use. Provides a single docker run command for basic dataset benchmarking, as well as all the functionality of the conda solution inside the containers. - -Conda ------ - -.. code-block:: bash - - conda create --name cuvs_benchmarks - conda activate cuvs_benchmarks - - # to install GPU package: - conda install -c rapidsai -c conda-forge cuvs-bench= cuda-version=13.1* - - # to install CPU package for usage in CPU-only systems: - conda install -c rapidsai -c conda-forge cuvs-bench-cpu - -The channel `rapidsai` can easily be substituted with `rapidsai-nightly` if nightly benchmarks are desired. The CPU package currently allows to run the HNSW benchmarks. - -Please see the :doc:`build instructions ` to build the benchmarks from source. - -Docker ------- - -We provide images for GPU enabled systems, as well as systems without a GPU. The following images are available: - -- `cuvs-bench`: Contains GPU and CPU benchmarks, can run all algorithms supported. Will download million-scale datasets as required. Best suited for users that prefer a smaller container size for GPU based systems. Requires the NVIDIA Container Toolkit to run GPU algorithms, can run CPU algorithms without it. -- `cuvs-bench-cpu`: Contains only CPU benchmarks with minimal size. Best suited for users that want the smallest containers to reproduce benchmarks on systems without a GPU. - -Nightly images are located in `dockerhub `_. - -The following command pulls the nightly container for Python version 3.13, CUDA version 12.9, and cuVS version 26.06: - -.. code-block:: bash - - docker pull rapidsai/cuvs-bench:26.06a-cuda12-py3.13 # substitute cuvs-bench for the exact desired container. - -The CUDA and python versions can be changed for the supported values: -- Supported CUDA versions: 12, 13 -- Supported Python versions: 3.11, 3.11, 3.13, and 3.14 - -You can see the exact versions as well in the dockerhub site: -- `cuVS bench images `_ -- `cuVS bench CPU only images `_ - -**Note:** GPU containers use the CUDA toolkit from inside the container, the only requirement is a driver installed on the host machine that supports that version. So, for example, CUDA 12 containers can run in systems with a CUDA 13.x capable driver. Please also note that the Nvidia-Docker runtime from the `Nvidia Container Toolkit `_ is required to use GPUs inside docker containers. - -Running the benchmarks -====================== - -End-to-end: smaller-scale benchmarks (<1M to 10M) -------------------------------------------------- - -The steps below demonstrate how to download, install, and run benchmarks on a subset of 10M vectors from the Yandex Deep-1B dataset. By default the datasets will be stored and used from the folder indicated by the `RAPIDS_DATASET_ROOT_DIR` environment variable if defined, otherwise a datasets sub-folder from where the script is being called. - -.. code-block:: bash - - # (1) Prepare dataset. - python -m cuvs_bench.get_dataset --dataset deep-image-96-angular --normalize - -.. code-block:: python - - # (2) Build and search index. - from cuvs_bench.orchestrator import BenchmarkOrchestrator - - orchestrator = BenchmarkOrchestrator(backend_type="cpp_gbench") - results = orchestrator.run_benchmark( - dataset="deep-image-96-inner", - algorithms="cuvs_cagra", - count=10, - batch_size=10, - build=True, - search=True, - ) - -.. code-block:: bash - - # (3) Export data. - python -m cuvs_bench.run --data-export --dataset deep-image-96-inner - - # (4) Plot results. - python -m cuvs_bench.plot --dataset deep-image-96-inner - -.. list-table:: - - * - Dataset name - - Train rows - - Columns - - Test rows - - Distance - - * - `deep-image-96-angular` - - 10M - - 96 - - 10K - - Angular - - * - `fashion-mnist-784-euclidean` - - 60K - - 784 - - 10K - - Euclidean - - * - `glove-50-angular` - - 1.1M - - 50 - - 10K - - Angular - - * - `glove-100-angular` - - 1.1M - - 100 - - 10K - - Angular - - * - `mnist-784-euclidean` - - 60K - - 784 - - 10K - - Euclidean - - * - `nytimes-256-angular` - - 290K - - 256 - - 10K - - Angular - - * - `sift-128-euclidean` - - 1M - - 128 - - 10K - - Euclidean - -All of the datasets above contain ground test datasets with 100 neighbors. Thus `k` for these datasets must be less than or equal to 100. - -End-to-end: large-scale benchmarks (>10M vectors) -------------------------------------------------- - -`cuvs_bench.get_dataset` cannot be used to download the billion-scale datasets due to their size. You should instead use our billion-scale datasets guide to download and prepare them. -All other python commands mentioned below work as intended once the billion-scale dataset has been downloaded. - -To download billion-scale datasets, visit `big-ann-benchmarks `_ - -We also provide a new dataset called `wiki-all` containing 88 million 768-dimensional vectors. This dataset is meant for benchmarking a realistic retrieval-augmented generation (RAG)/LLM embedding size at scale. It also contains 1M and 10M vector subsets for smaller-scale experiments. See our :doc:`Wiki-all Dataset Guide ` for more information and to download the dataset. - - -The steps below demonstrate how to download, install, and run benchmarks on a subset of 100M vectors from the Yandex Deep-1B dataset. Please note that datasets of this scale are recommended for GPUs with larger amounts of memory, such as the A100 or H100. - -.. code-block:: bash - - mkdir -p datasets/deep-1B - # (1) Prepare dataset. - # download manually "Ground Truth" file of "Yandex DEEP" - # suppose the file name is deep_new_groundtruth.public.10K.bin - python -m cuvs_bench.split_groundtruth --groundtruth datasets/deep-1B/deep_new_groundtruth.public.10K.bin - # two files 'groundtruth.neighbors.ibin' and 'groundtruth.distances.fbin' should be produced - -.. code-block:: python - - # (2) Build and search index. - from cuvs_bench.orchestrator import BenchmarkOrchestrator - - orchestrator = BenchmarkOrchestrator(backend_type="cpp_gbench") - results = orchestrator.run_benchmark( - dataset="deep-1B", - algorithms="cuvs_cagra", - count=10, - batch_size=10, - build=True, - search=True, - ) - -.. code-block:: bash - - # (3) Export data. - python -m cuvs_bench.run --data-export --dataset deep-1B - - # (4) Plot results. - python -m cuvs_bench.plot --dataset deep-1B - -The usage of `python -m cuvs_bench.split_groundtruth` is: - -.. code-block:: bash - - usage: split_groundtruth.py [-h] --groundtruth GROUNDTRUTH - - options: - -h, --help show this help message and exit - --groundtruth GROUNDTRUTH - Path to billion-scale dataset groundtruth file (default: None) - - -Testing on new datasets ------------------------ - -To run benchmark on a dataset, it is required have a descriptor that defines the file names and a few other properties of that dataset. -Descriptors for several popular datasets are already available in `datasets.yaml ``. - -Let's consider how to test on a new dataset. First we create a descriptor `mydataset.yaml` - -.. code-block: yaml - - name: mydata-1M - base_file: mydata-1M/base.100M.u8bin - subset_size: 1000000 - dims: 128 - query_file: mydata-10M/queries.u8bin - groundtruth_neighbors_file: mydata-1M/groundtruth.neighbors.ibin - distance: euclidean - -Here `name` can be chosen arbitrarily. We pass `name` as the `--dataset` argument for the benchmark. The file names are relative to the path given by `--dataset-path` argument. -The `subset_size`` field is optional. This argument defines how many vectors to use from the dataset file, the first `subset_size` vectors will be used. -This way you can define benchmarks on multiple subsets of the same dataset without duplicating the dataset vectors. -Note that the ground truth vectors have to be generated for each subset separately. - -To run the benchmark on the newly defined `mydata-1M` dataset, you can use the following command line: - -.. code-black: bash - python -m cuvs_bench.run --dataset mydata-1M --dataset-path=/path/to/data/folder --dataset-configuration=mydataset.yaml --algorithms=cuvs_cagra - -Running with Docker containers ------------------------------- - -Two methods are provided for running the benchmarks with the Docker containers. - -End-to-end run on GPU -~~~~~~~~~~~~~~~~~~~~~ - -When no other entrypoint is provided, an end-to-end script will run through all the steps in `Running the benchmarks`_ above. - -For GPU-enabled systems, the `DATA_FOLDER` variable should be a local folder where you want datasets stored in `$DATA_FOLDER/datasets` and results in `$DATA_FOLDER/result` (we highly recommend `$DATA_FOLDER` to be a dedicated folder for the datasets and results of the containers): - -.. code-block:: bash - - export DATA_FOLDER=path/to/store/datasets/and/results - docker run --gpus all --rm -it -u $(id -u) \ - -v $DATA_FOLDER:/data/benchmarks \ - rapidsai/cuvs-bench:26.06a-cuda12-py3.13 \ - "--dataset deep-image-96-angular" \ - "--normalize" \ - "--algorithms cuvs_cagra,cuvs_ivf_pq --batch-size 10 -k 10" \ - "" - -Usage of the above command is as follows: - -.. list-table:: - - * - Argument - - Description - - * - `rapidsai/cuvs-bench:26.06a-cuda12-py3.13` - - Image to use. See "Docker" section for links to lists of available tags. - - * - `"--dataset deep-image-96-angular"` - - Dataset name - - * - `"--normalize"` - - Whether to normalize the dataset - - * - `"--algorithms cuvs_cagra,hnswlib --batch-size 10 -k 10"` - - Arguments passed to the `run` script, such as the algorithms to benchmark, the batch size, and `k` - - * - `""` - - Additional (optional) arguments that will be passed to the `plot` script. - -***Note about user and file permissions:*** The flag `-u $(id -u)` allows the user inside the container to match the `uid` of the user outside the container, allowing the container to read and write to the mounted volume indicated by the `$DATA_FOLDER` variable. - -End-to-end run on CPU -~~~~~~~~~~~~~~~~~~~~~ - -The container arguments in the above section also be used for the CPU-only container, which can be used on systems that don't have a GPU installed. - -***Note:*** the image changes to `cuvs-bench-cpu` container and the `--gpus all` argument is no longer used: - -.. code-block:: bash - - export DATA_FOLDER=path/to/store/datasets/and/results - docker run --rm -it -u $(id -u) \ - -v $DATA_FOLDER:/data/benchmarks \ - rapidsai/cuvs-bench-cpu:26.06a-py3.13 \ - "--dataset deep-image-96-angular" \ - "--normalize" \ - "--algorithms hnswlib --batch-size 10 -k 10" \ - "" - -Manually run the scripts inside the container -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -All of the `cuvs-bench` images contain the Conda packages, so they can be used directly by logging directly into the container itself: - -.. code-block:: bash - - export DATA_FOLDER=path/to/store/datasets/and/results - docker run --gpus all --rm -it -u $(id -u) \ - --entrypoint /bin/bash \ - --workdir /data/benchmarks \ - -v $DATA_FOLDER:/data/benchmarks \ - rapidsai/cuvs-bench:26.06a-cuda12-py3.13 - -This will drop you into a command line in the container, with the `cuvs-bench` python package ready to use, as described in the `Running the benchmarks`_ section above: - -.. code-block:: bash - - (base) root@00b068fbb862:/data/benchmarks# python -m cuvs_bench.get_dataset --dataset deep-image-96-angular --normalize - -Additionally, the containers can be run in detached mode without any issue. - -Evaluating the results ----------------------- - -The benchmarks capture several different measurements. The table below describes each of the measurements for index build benchmarks: - -.. list-table:: - - * - Name - - Description - - * - Benchmark - - A name that uniquely identifies the benchmark instance - - * - Time - - Wall-time spent training the index - - * - CPU - - CPU time spent training the index - - * - Iterations - - Number of iterations (this is usually 1) - - * - GPU - - GU time spent building - - * - index_size - - Number of vectors used to train index - -The table below describes each of the measurements for the index search benchmarks. The most important measurements `Latency`, `items_per_second`, `end_to_end`. - -.. list-table:: - - * - Name - - Description - - * - Benchmark - - A name that uniquely identifies the benchmark instance - - * - Time - - The wall-clock time of a single iteration (batch) divided by the number of threads. - - * - CPU - - The average CPU time (user + sys time). This does not include idle time (which can also happen while waiting for GPU sync). - - * - Iterations - - Total number of batches. This is going to be `total_queries` / `n_queries`. - - * - GPU - - GPU latency of a single batch (seconds). In throughput mode this is averaged over multiple threads. - - * - Latency - - Latency of a single batch (seconds), calculated from wall-clock time. In throughput mode this is averaged over multiple threads. - - * - Recall - - Proportion of correct neighbors to ground truth neighbors. Note this column is only present if groundtruth file is specified in dataset configuration. - - * - items_per_second - - Total throughput, a.k.a Queries per second (QPS). This is approximately `total_queries` / `end_to_end`. - - * - k - - Number of neighbors being queried in each iteration - - * - end_to_end - - Total time taken to run all batches for all iterations - - * - n_queries - - Total number of query vectors in each batch - - * - total_queries - - Total number of vectors queries across all iterations ( = `iterations` * `n_queries`) - -Note the following: -- A slightly different method is used to measure `Time` and `end_to_end`. That is why `end_to_end` = `Time` * `Iterations` holds only approximately. -- The actual table displayed on the screen may differ slightly as the hyper-parameters will also be displayed for each different combination being benchmarked. -- Recall calculation: the number of queries processed per test depends on the number of iterations. Because of this, recall can show slight fluctuations if less neighbors are processed then it is available for the benchmark. - -Creating and customizing dataset configurations -=============================================== - -A single configuration will often define a set of algorithms, with associated index and search parameters, that can be generalize across datasets. We use YAML to define dataset specific and algorithm specific configurations. - -A default `datasets.yaml` is provided by CUVS in `${CUVS_HOME}/python/cuvs_bench/cuvs_bench/config/datasets/datasets.yaml` with configurations available for several datasets. Here's a simple example entry for the `sift-128-euclidean` dataset: - -.. code-block:: yaml - - - name: sift-128-euclidean - base_file: sift-128-euclidean/base.fbin - query_file: sift-128-euclidean/query.fbin - groundtruth_neighbors_file: sift-128-euclidean/groundtruth.neighbors.ibin - dims: 128 - distance: euclidean - -Configuration files for ANN algorithms supported by `cuvs-bench` are provided in `${CUVS_HOME}/python/cuvs_bench/cuvs_bench/config/algos`. `cuvs_cagra` algorithm configuration looks like: - -.. code-block:: yaml - - name: cuvs_cagra - constraints: - build: cuvs_bench.config.algos.constraints.cuvs_cagra_build - search: cuvs_bench.config.algos.constraints.cuvs_cagra_search - groups: - base: - build: - graph_degree: [32, 64] - intermediate_graph_degree: [64, 96] - graph_build_algo: ["NN_DESCENT"] - search: - itopk: [32, 64, 128] - - large: - build: - graph_degree: [32, 64] - search: - itopk: [32, 64, 128] - -The default parameters for which the benchmarks are run can be overridden by creating a custom YAML file for algorithms with a `base` group. - -The config above has 3 fields: - -1. `name` - The name of the algorithm for which the parameters are being specified. -2. `constraints` - Optional. Python import paths to functions that validate build and search parameter combinations (e.g. ``cuvs_bench.config.algos.constraints.cuvs_cagra_build``). Each function returns ``True`` if the parameters are valid, ``False`` otherwise; invalid combinations are skipped and not benchmarked. -3. `groups` - Run groups, each with a set of parameters. Each group defines a cross-product of all hyper-parameter fields for `build` and `search`. - -The table below contains all algorithms supported by cuVS. Each unique algorithm will have its own set of `build` and `search` settings. The :doc:`ANN Algorithm Parameter Tuning Guide ` contains detailed instructions on choosing build and search parameters for each supported algorithm. - -.. list-table:: - - * - Library - - Algorithms - - * - FAISS_GPU - - `faiss_gpu_flat`, `faiss_gpu_ivf_flat`, `faiss_gpu_ivf_pq`, `faiss_gpu_cagra` - - * - FAISS_CPU - - `faiss_cpu_flat`, `faiss_cpu_ivf_flat`, `faiss_cpu_ivf_pq`, `faiss_cpu_hnsw_flat` - - * - GGNN - - `ggnn` - - * - HNSWLIB - - `hnswlib` - - * - DiskANN - - `diskann_memory`, `diskann_ssd` - - * - cuVS - - `cuvs_brute_force`, `cuvs_cagra`, `cuvs_ivf_flat`, `cuvs_ivf_pq`, `cuvs_cagra_hnswlib`, `cuvs_vamana` - - -Multi-GPU benchmarks --------------------- - -cuVS implements single node multi-GPU versions of IVF-Flat, IVF-PQ and CAGRA indexes. - -.. list-table:: - - * - Index type - - Multi-GPU algo name - - * - IVF-Flat - - `cuvs_mg_ivf_flat` - - * - IVF-PQ - - `cuvs_mg_ivf_pq` - - * - CAGRA - - `cuvs_mg_cagra` - - -Adding a new index algorithm -============================ - -Implementation and configuration --------------------------------- - -Implementation of a new algorithm should be a C++ class that inherits `class ANN` (defined in `cpp/bench/ann/src/ann.h`) and implements all the pure virtual functions. - -In addition, it should define two `struct`s for building and searching parameters. The searching parameter class should inherit `struct ANN::AnnSearchParam`. Take `class HnswLib` as an example, its definition is: - -.. code-block:: c++ - - template - class HnswLib : public ANN { - public: - struct BuildParam { - int M; - int ef_construction; - int num_threads; - }; - - using typename ANN::AnnSearchParam; - struct SearchParam : public AnnSearchParam { - int ef; - int num_threads; - }; - - // ... - }; - - -The benchmark program uses JSON format natively in a configuration file to specify indexes to build, along with the build and search parameters. However the JSON config files are overly verbose and are not meant to be used directly. Instead, the Python scripts parse YAML and create these json files automatically. It's important to realize that these json objects align with the yaml objects for `build_param`, whose value is a JSON object, and `search_param`, whose value is an array of JSON objects. Take the json configuration for `HnswLib` as an example of the json after it's been parsed from yaml: - -.. code-block:: json - - { - "name" : "hnswlib.M12.ef500.th32", - "algo" : "hnswlib", - "build_param": {"M":12, "efConstruction":500, "numThreads":32}, - "file" : "/path/to/file", - "search_params" : [ - {"ef":10, "numThreads":1}, - {"ef":20, "numThreads":1}, - {"ef":40, "numThreads":1}, - ], - "search_result_file" : "/path/to/file" - }, - -The build and search params are ultimately passed to the C++ layer as json objects for each param configuration to benchmark. The code below shows how to parse these params for `Hnswlib`: - -1. First, add two functions for parsing JSON object to `struct BuildParam` and `struct SearchParam`, respectively: - -.. code-block:: c++ - - template - void parse_build_param(const nlohmann::json& conf, - typename cuann::HnswLib::BuildParam& param) { - param.ef_construction = conf.at("efConstruction"); - param.M = conf.at("M"); - if (conf.contains("numThreads")) { - param.num_threads = conf.at("numThreads"); - } - } - - template - void parse_search_param(const nlohmann::json& conf, - typename cuann::HnswLib::SearchParam& param) { - param.ef = conf.at("ef"); - if (conf.contains("numThreads")) { - param.num_threads = conf.at("numThreads"); - } - } - - - -2. Next, add corresponding `if` case to functions `create_algo()` (in `cpp/bench/ann/) and `create_search_param()` by calling parsing functions. The string literal in `if` condition statement must be the same as the value of `algo` in configuration file. For example, - -.. code-block:: c++ - - // JSON configuration file contains a line like: "algo" : "hnswlib" - if (algo == "hnswlib") { - // ... - } - -Adding a Cmake target ---------------------- - -In `cuvs/cpp/bench/ann/CMakeLists.txt`, we provide a `CMake` function to configure a new Benchmark target with the following signature: - - -.. code-block:: cmake - - ConfigureAnnBench( - NAME - PATH - INCLUDES - CXXFLAGS - LINKS - ) - -To add a target for `HNSWLIB`, we would call the function as: - -.. code-block:: cmake - - ConfigureAnnBench( - NAME HNSWLIB PATH bench/ann/src/hnswlib/hnswlib_benchmark.cpp INCLUDES - ${CMAKE_CURRENT_BINARY_DIR}/_deps/hnswlib-src/hnswlib CXXFLAGS "${HNSW_CXX_FLAGS}" - ) - -This will create an executable called `HNSWLIB_ANN_BENCH`, which can then be used to run `HNSWLIB` benchmarks. - -Add a new entry to `algos.yaml` to map the name of the algorithm to its binary executable and specify whether the algorithm requires GPU support. - -.. code-block:: yaml - - cuvs_ivf_pq: - executable: CUVS_IVF_PQ_ANN_BENCH - requires_gpu: true - -`executable` : specifies the name of the binary that will build/search the index. It is assumed to be available in `cuvs/cpp/build/`. -`requires_gpu` : denotes whether an algorithm requires GPU to run. - - -.. toctree:: - :maxdepth: 4 - - build.rst - datasets.rst - param_tuning.rst - pluggable_backend.rst - wiki_all_dataset.rst diff --git a/docs/source/cuvs_bench/param_tuning.rst b/docs/source/cuvs_bench/param_tuning.rst deleted file mode 100644 index 692fd7eb6a..0000000000 --- a/docs/source/cuvs_bench/param_tuning.rst +++ /dev/null @@ -1,918 +0,0 @@ -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -cuVS Bench Parameter Tuning Guide -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -This guide outlines the various parameter settings that can be specified in :doc:`cuVS Benchmarks ` yaml configuration files and explains the impact they have on corresponding algorithms to help inform their settings for benchmarking across desired levels of recall. - -Benchmark modes -=============== - -When you run benchmarks with ``BenchmarkOrchestrator.run_benchmark()``, you can choose how parameters are explored: - -**Sweep mode (default)** - -Pass ``mode="sweep"`` or omit ``mode``. The orchestrator builds the full Cartesian product of all build and search parameter lists defined in the algorithm YAML (see :doc:`Creating and customizing dataset configurations `). Every valid combination (after constraint filtering) is run. Use this for exhaustive comparison across the configured parameter grid. - -**Tune mode** - -Pass ``mode="tune"`` to perform hyperparameter optimization using Optuna instead of running every combination. You must pass: - -- **constraints** (dict): The optimization target and optional bounds. One metric must be ``"maximize"`` or ``"minimize"`` (the goal). Others can set hard limits with ``{"min": X}`` or ``{"max": X}``. Examples: ``{"recall": "maximize", "latency": {"max": 10}}`` or ``{"latency": "minimize", "recall": {"min": 0.95}}``. -- **n_trials** (int, optional): Maximum number of Optuna trials (default 100). Ignored in sweep mode. - -Example: - -.. code-block:: python - - results = orchestrator.run_benchmark( - mode="tune", - dataset="deep-image-96-inner", - algorithms="cuvs_cagra", - constraints={"recall": "maximize", "latency": {"max": 5.0}}, - n_trials=50, - count=10, - batch_size=10, - ) - -The parameter tables below describe the build and search knobs that sweep mode varies and that tune mode can optimize. - -cuVS Indexes -============ - -cuvs_brute_force ----------------- - -Use cuVS brute-force index for exact search. Brute-force has no further build or search parameters. - -cuvs_ivf_flat -------------- - -IVF-flat uses an inverted-file index, which partitions the vectors into a series of clusters, or lists, storing them in an interleaved format which is optimized for fast distance computation. The searching of an IVF-flat index reduces the total vectors in the index to those within some user-specified nearest clusters called probes. - -IVF-flat is a simple algorithm which won't save any space, but it provides competitive search times even at higher levels of recall. - -.. list-table:: - - * - Parameter - - Type - - Required - - Data Type - - Default - - Description - - * - `nlist` - - `build` - - Y - - Positive integer >0 - - 1024 - - Number of clusters to partition the vectors into. Larger values will put less points into each cluster but this will impact index build time as more clusters need to be trained. - - * - `niter` - - `build` - - N - - Positive integer >0 - - 20 - - Number of kmeans iterations to use when training the ivf clusters - - * - `ratio` - - `build` - - N - - Positive integer >0 - - 2 - - `1/ratio` is the number of training points which should be used to train the clusters. - - * - `dataset_memory_type` - - `build` - - N - - [`device`, `host`, `mmap`] - - `mmap` - - Where should the dataset reside? - - * - `query_memory_type` - - `search` - - N - - [`device`, `host`, `mmap`] - - `device` - - Where should the queries reside? - - * - `nprobe` - - `search` - - Y - - Positive integer >0 - - - - The closest number of clusters to search for each query vector. Larger values will improve recall but will search more points in the index. - - -cuvs_ivf_pq ------------ - -IVF-pq is an inverted-file index, which partitions the vectors into a series of clusters, or lists, in a similar way to IVF-flat above. The difference is that IVF-PQ uses product quantization to also compress the vectors, giving the index a smaller memory footprint. Unfortunately, higher levels of compression can also shrink recall, which a refinement step can improve when the original vectors are still available. - -.. list-table:: - - * - Parameter - - Type - - Required - - Data Type - - Default - - Description - - * - `nlist` - - `build` - - Y - - Positive integer >0 - - 1024 - - Number of clusters to partition the vectors into. Larger values will put less points into each cluster but this will impact index build time as more clusters need to be trained. - - * - `niter` - - `build` - - N - - Positive integer >0 - - 20 - - Number of kmeans iterations to use when training the ivf clusters - - * - `ratio` - - `build` - - N - - Positive integer >0 - - 2 - - `1/ratio` is the number of training points which should be used to train the clusters. - - * - `pq_dim` - - `build` - - N - - Positive integer. Multiple of 8. - - 0 - - Dimensionality of the vector after product quantization. When 0, a heuristic is used to select this value. - - * - `pq_bits` - - `build` - - N - - Positive integer [4-8] - - 8 - - Bit length of the vector element after quantization. - - * - `codebook_kind` - - `build` - - N - - [`cluster`, `subspace`] - - `subspace` - - Type of codebook. See :doc:`IVF-PQ index overview <../neighbors/ivfpq>` for more detail - - * - `dataset_memory_type` - - `build` - - N - - [`device`, `host`, `mmap`] - - `mmap` - - Where should the dataset reside? - - * - `query_memory_type` - - `search` - - N - - [`device`, `host`, `mmap`] - - `device` - - Where should the queries reside? - - * - `nprobe` - - `search` - - Y - - Positive integer >0 - - 20 - - The closest number of clusters to search for each query vector. Larger values will improve recall but will search more points in the index. - - * - `internalDistanceDtype` - - `search` - - N - - [`float`, `half`] - - `half` - - The precision to use for the distance computations. Lower precision can increase performance at the cost of accuracy. - - * - `smemLutDtype` - - `search` - - N - - [`float`, `half`, `fp8`] - - `half` - - The precision to use for the lookup table in shared memory. Lower precision can increase performance at the cost of accuracy. - - * - `refine_ratio` - - `search` - - N - - Positive integer >0 - - 1 - - `refine_ratio * k` nearest neighbors are queried from the index initially and an additional refinement step improves recall by selecting only the best `k` neighbors. - - -cuvs_cagra ----------- - -CAGRA uses a graph-based index, which creates an intermediate, approximate kNN graph using IVF-PQ and then further refining and optimizing to create a final kNN graph. This kNN graph is used by CAGRA as an index for search. - -.. list-table:: - - * - Parameter - - Type - - Required - - Data Type - - Default - - Description - - * - `graph_degree` - - `build` - - N - - Positive integer >0 - - 64 - - Degree of the final kNN graph index. - - * - `intermediate_graph_degree` - - `build` - - N - - Positive integer >0 - - 128 - - Degree of the intermediate kNN graph before the CAGRA graph is optimized - - * - `graph_build_algo` - - `build` - - `N` - - [`IVF_PQ`, `NN_DESCENT`, `ACE`] - - `IVF_PQ` - - Algorithm to use for building the initial kNN graph, from which CAGRA will optimize into the navigable CAGRA graph - - * - `dataset_memory_type` - - `build` - - N - - [`device`, `host`, `mmap`] - - `mmap` - - Where should the dataset reside? - - * - `npartitions` - - `build` - - N - - Positive integer >0 - - 1 - - The number of partitions to use for the ACE build. Small values might improve recall but potentially degrade performance and increase memory usage. Partitions should not be too small to prevent issues in KNN graph construction. The partition size is on average 2 * (n_rows / npartitions) * dim * sizeof(T). 2 is because of the core and augmented vectors. Please account for imbalance in the partition sizes (up to 3x in our tests). - - * - `build_dir` - - `build` - - N - - String - - "/tmp/ace_build" - - The directory to use for the ACE build. Must be specified when using ACE build. This should be the fastest disk in the system and hold enough space for twice the dataset, final graph, and label mapping. - - * - `ef_construction` - - `build` - - Y - - Positive integer >0 - - 120 - - Controls index time and accuracy when using ACE build. Bigger values increase the index quality. At some point, increasing this will no longer improve the quality. - - * - `use_disk` - - `build` - - N - - Boolean - - `false` - - Whether to use disk-based storage for ACE build. When true, forces ACE to use disk-based storage even if the graph fits in host and GPU memory. When false, ACE will use in-memory storage if the graph fits in host and GPU memory and disk-based storage otherwise. - - * - `query_memory_type` - - `search` - - N - - [`device`, `host`, `mmap`] - - `device` - - Where should the queries reside? - - * - `itopk` - - `search` - - N - - Positive integer >0 - - 64 - - Number of intermediate search results retained during the search. Higher values improve search accuracy at the cost of speed - - * - `search_width` - - `search` - - N - - Positive integer >0 - - 1 - - Number of graph nodes to select as the starting point for the search in each iteration. - - * - `max_iterations` - - `search` - - N - - Positive integer >=0 - - 0 - - Upper limit of search iterations. Auto select when 0 - - * - `algo` - - `search` - - N - - [`auto`, `single_cta`, `multi_cta`, `multi_kernel`] - - `auto` - - Algorithm to use for search. It's usually best to leave this to `auto`. - - * - `graph_memory_type` - - `search` - - N - - [`device`, `host_pinned`, `host_huge_page`] - - `device` - - Memory type to store graph - - * - `internal_dataset_memory_type` - - `search` - - N - - [`device`, `host_pinned`, `host_huge_page`] - - `device` - - Memory type to store dataset - -The `graph_memory_type` or `internal_dataset_memory_type` options can be useful for large datasets that do not fit the device memory. Setting `internal_dataset_memory_type` other than `device` has negative impact on search speed. Using `host_huge_page` option is only supported on systems with Heterogeneous Memory Management or on platforms that natively support GPU access to system allocated memory, for example Grace Hopper. - -To fine tune CAGRA index building we can customize IVF-PQ index builder options using the following settings. These take effect only if `graph_build_algo == "IVF_PQ"`. It is recommended to experiment using a separate IVF-PQ index to find the config that gives the largest QPS for large batch. Recall does not need to be very high, since CAGRA further optimizes the kNN neighbor graph. Some of the default values are derived from the dataset size which is assumed to be [n_vecs, dim]. - -.. list-table:: - - * - Parameter - - Type - - Required - - Data Type - - Default - - Description - - * - `ivf_pq_build_nlist` - - `build` - - N - - Positive integer >0 - - sqrt(n_vecs) - - Number of clusters to partition the vectors into. Larger values will put less points into each cluster but this will impact index build time as more clusters need to be trained. - - * - `ivf_pq_build_niter` - - `build` - - N - - Positive integer >0 - - 25 - - Number of k-means iterations to use when training the clusters. - - * - `ivf_pq_build_ratio` - - `build` - - N - - Positive integer >0 - - 10 - - `1/ratio` is the number of training points which should be used to train the clusters. - - * - `ivf_pq_pq_dim` - - `build` - - N - - Positive integer. Multiple of 8 - - dim/2 rounded up to 8 - - Dimensionality of the vector after product quantization. When 0, a heuristic is used to select this value. `pq_dim` * `pq_bits` must be a multiple of 8. - - * - `ivf_pq_build_pq_bits` - - `build` - - N - - Positive integer [4-8] - - 8 - - Bit length of the vector element after quantization. - - * - `ivf_pq_build_codebook_kind` - - `build` - - N - - [`cluster`, `subspace`] - - `subspace` - - Type of codebook. See :doc:`IVF-PQ index overview <../neighbors/ivfpq>` for more detail - - * - `ivf_pq_build_nprobe` - - `search` - - N - - Positive integer >0 - - min(2*dim, nlist) - - The closest number of clusters to search for each query vector. Larger values will improve recall but will search more points in the index. - - * - `ivf_pq_build_internalDistanceDtype` - - `search` - - N - - [`float`, `half`] - - `half` - - The precision to use for the distance computations. Lower precision can increase performance at the cost of accuracy. - - * - `ivf_pq_build_smemLutDtype` - - `search` - - N - - [`float`, `half`, `fp8`] - - `fp8` - - The precision to use for the lookup table in shared memory. Lower precision can increase performance at the cost of accuracy. - - * - `ivf_pq_build_refine_ratio` - - `search` - - N - - Positive integer >0 - - 2 - - `refine_ratio * k` nearest neighbors are queried from the index initially and an additional refinement step improves recall by selecting only the best `k` neighbors. - -Alternatively, if `graph_build_algo == "NN_DESCENT"`, then we can customize the following parameters - -.. list-table:: - - * - Parameter - - Type - - Required - - Data Type - - Default - - Description - - * - `nn_descent_niter` - - `build` - - N - - Positive integer >0 - - 20 - - Number of nn-descent iterations - - * - `nn_descent_intermediate_graph_degree` - - `build` - - N - - Positive integer >0 - - `cagra.intermediate_graph_degree` * 1.5 - - Intermadiate graph degree during nn-descent iterations - - * - nn_descent_termination_threshold - - `build` - - N - - Positive float >0 - - 1e-4 - - Early stopping threshold for nn-descent convergence - -cuvs_cagra_hnswlib ------------------- - -This is a benchmark that enables interoperability between `CAGRA` built `HNSW` search. It uses the `CAGRA` built graph as the base layer of an `hnswlib` index to search queries only within the base layer (this is enabled with a simple patch to `hnswlib`). - -`build` : Same as `build` of CAGRA - -`search` : Same as `search` of Hnswlib - -cuvs_vamana ------------ - -Benchmark for building an in-memory Vamana graph based index on the GPU and interoperability with DiskANN for search. - -.. list-table:: - - * - Parameter - - Type - - Required - - Data Type - - Default - - Description - - * - `graph_degree` - - `build` - - N - - Positive integer >0 - - 32 - - Maximum degree of the graph index - - * - `visited_size` - - `build` - - N - - Positive integer >0 - - 64 - - Maximum number of visited nodes per search corresponds to the L parameter in the Vamana literature - - * - `alpha` - - `build` - - N - - Positive float >0 - - 1.2 - - Alpha for pruning parameter - - * - `L_search` - - `search` - - Y - - Positive integer >0 - - - - Maximum number of visited nodes per search corresponds to the L parameter in the Vamana literature. Larger values improve recall at the cost of search time. - -FAISS Indexes -============= - -faiss_gpu_flat --------------- - -Use FAISS flat index on the GPU, which performs an exact search using brute-force and doesn't have any further build or search parameters. - -faiss_gpu_ivf_flat ------------------- - -IVF-flat uses an inverted-file index, which partitions the vectors into a series of clusters, or lists, storing them in an interleaved format which is optimized for fast distance computation. The searching of an IVF-flat index reduces the total vectors in the index to those within some user-specified nearest clusters called probes. - -IVF-flat is a simple algorithm which won't save any space, but it provides competitive search times even at higher levels of recall. - -.. list-table:: - - * - Parameter - - Type - - Required - - Data Type - - Default - - Description - - * - `nlists` - - `build` - - Y - - Positive integer >0 - - - - Number of clusters to partition the vectors into. Larger values will put less points into each cluster but this will impact index build time as more clusters need to be trained - - * - `ratio` - - `build` - - N - - Positive integer >0 - - 2 - - `1/ratio` is the number of training points which should be used to train the clusters. - - * - `nprobe` - - `search` - - Y - - Positive integer >0 - - 20 - - The closest number of clusters to search for each query vector. Larger values will improve recall but will search more points in the index. - -faiss_gpu_ivf_pq ----------------- - -IVF-pq is an inverted-file index, which partitions the vectors into a series of clusters, or lists, in a similar way to IVF-flat above. The difference is that IVF-PQ uses product quantization to also compress the vectors, giving the index a smaller memory footprint. Unfortunately, higher levels of compression can also shrink recall, which a refinement step can improve when the original vectors are still available. - -.. list-table:: - - * - Parameter - - Type - - Required - - Data Type - - Default - - Description - - * - `nlist` - - `build` - - Y - - Positive integer >0 - - - - Number of clusters to partition the vectors into. Larger values will put less points into each cluster but this will impact index build time as more clusters need to be trained. - - * - `ratio` - - `build` - - N - - Positive integer >0 - - 2 - - `1/ratio` is the number of training points which should be used to train the clusters. - - * - `M_ratio` - - `build` - - Y - - Positive integer. Power of 2 [8-64] - - - - Ratio of number of chunks or subquantizers for each vector. Computed by `dims` / `M_ratio` - - * - `usePrecomputed` - - `build` - - N - - Boolean - - `false` - - Use pre-computed lookup tables to speed up search at the cost of increased memory usage. - - * - `useFloat16` - - `build` - - N - - Boolean - - `false` - - Use half-precision floats for clustering step. - - * - `nprobe` - - `search` - - Y - - Positive integer >0 - - - - The closest number of clusters to search for each query vector. Larger values will improve recall but will search more points in the index. - - * - `refine_ratio` - - `search` - - N - - Positive number >=1 - - 1 - - `refine_ratio * k` nearest neighbors are queried from the index initially and an additional refinement step improves recall by selecting only the best `k` neighbors. - - -faiss_cpu_flat --------------- - -Use FAISS flat index on the CPU, which performs an exact search using brute-force and doesn't have any further build or search parameters. - -.. list-table:: - - * - Parameter - - Type - - Required - - Data Type - - Default - - Description - - * - `numThreads` - - `search` - - N - - Positive integer >0 - - 1 - - Number of threads to use for queries. - -faiss_cpu_ivf_flat ------------------- - -Use FAISS IVF-Flat index on CPU - -.. list-table:: - - * - Parameter - - Type - - Required - - Data Type - - Default - - Description - - * - `nlists` - - `build` - - Y - - Positive integer >0 - - - - Number of clusters to partition the vectors into. Larger values will put less points into each cluster but this will impact index build time as more clusters need to be trained - - * - `ratio` - - `build` - - N - - Positive integer >0 - - 2 - - `1/ratio` is the number of training points which should be used to train the clusters. - - * - `nprobe` - - `search` - - Y - - Positive integer >0 - - - - The closest number of clusters to search for each query vector. Larger values will improve recall but will search more points in the index. - - * - `numThreads` - - `search` - - N - - Positive integer >0 - - 1 - - Number of threads to use for queries. - -faiss_cpu_ivf_pq ----------------- - -Use FAISS IVF-PQ index on CPU - -.. list-table:: - - * - Parameter - - Type - - Required - - Data Type - - Default - - Description - - * - `nlist` - - `build` - - Y - - Positive integer >0 - - - - Number of clusters to partition the vectors into. Larger values will put less points into each cluster but this will impact index build time as more clusters need to be trained. - - * - `ratio` - - `build` - - N - - Positive integer >0 - - 2 - - `1/ratio` is the number of training points which should be used to train the clusters. - - * - `M` - - `build` - - Y - - Positive integer. Power of 2 [8-64] - - - - Ratio of number of chunks or subquantizers for each vector. Computed by `dims` / `M_ratio` - - * - `usePrecomputed` - - `build` - - N - - Boolean - - `false` - - Use pre-computed lookup tables to speed up search at the cost of increased memory usage. - - * - `bitsPerCode` - - `build` - - N - - Positive integer [4-8] - - 8 - - Number of bits for representing each quantized code. - - * - `nprobe` - - `search` - - Y - - Positive integer >0 - - - - The closest number of clusters to search for each query vector. Larger values will improve recall but will search more points in the index. - - * - `refine_ratio` - - `search` - - N - - Positive number >=1 - - 1 - - `refine_ratio * k` nearest neighbors are queried from the index initially and an additional refinement step improves recall by selecting only the best `k` neighbors. - - * - `numThreads` - - `search` - - N - - Positive integer >0 - - 1 - - Number of threads to use for queries. - -HNSW -==== - -cuvs_hnsw ---------- - -cuVS HNSW builds an HNSW index using the ACE (Augmented Core Extraction) algorithm, which enables GPU-accelerated HNSW index construction for datasets too large to fit in GPU memory. - -.. list-table:: - - * - Parameter - - Type - - Required - - Data Type - - Default - - Description - - * - `hierarchy` - - `build` - - N - - [`NONE`, `CPU`, `GPU`] - - `NONE` - - Type of HNSW hierarchy to build. `NONE` creates a base-layer-only index, `CPU` builds full hierarchy on CPU, `GPU` builds full hierarchy on GPU. - - * - `efConstruction` - - `build` - - Y - - Positive integer >0 - - - - Controls index time and accuracy. Bigger values increase the index quality. At some point, increasing this will no longer improve the quality. - - * - `M` - - `build` - - Y - - Positive integer. Often between 2-100 - - - - Number of bi-directional links create for every new element during construction. Higher values work for higher intrinsic dimensionality and/or high recall, low values can work for datasets with low intrinsic dimensionality and/or low recalls. Also affects the algorithm's memory consumption. - - * - `numThreads` - - `build` - - N - - Positive integer >0 - - 1 - - Number of threads to use to build the index. - - * - `npartitions` - - `build` - - N - - Positive integer >0 - - 1 - - Number of partitions to use for the ACE build. Small values might improve recall but potentially degrade performance and increase memory usage. The partition size is on average 2 * (n_rows / npartitions) * dim * sizeof(T). 2 is because of the core and augmented vectors. Please account for imbalance in the partition sizes (up to 3x in our tests). - - * - `ef_construction` - - `build` - - N - - Positive integer >0 - - 120 - - Controls index time and accuracy when using ACE build. Bigger values increase the index quality. At some point, increasing this will no longer improve the quality. - - * - `build_dir` - - `build` - - N - - String - - "/tmp/ace_build" - - The directory to use for the ACE build. This should be the fastest disk in the system and hold enough space for twice the dataset, final graph, and label mapping. - - * - `use_disk` - - `build` - - N - - Boolean - - `false` - - Whether to use disk-based storage for ACE build. When true, forces ACE to use disk-based storage even if the graph fits in host and GPU memory. When false, ACE will use in-memory storage if the graph fits in host and GPU memory and disk-based storage otherwise. - - * - `ef` - - `search` - - Y - - Positive integer >0 - - - - Size of the dynamic list for the nearest neighbors used for search. Higher value leads to more accurate but slower search. Cannot be lower than `k`. - - * - `numThreads` - - `search` - - N - - Positive integer >0 - - 1 - - Number of threads to use for queries. - -hnswlib -------- - -.. list-table:: - - * - Parameter - - Type - - Required - - Data Type - - Default - - Description - - * - `efConstruction` - - `build` - - Y - - Positive integer >0 - - - - Controls index time and accuracy. Bigger values increase the index quality. At some point, increasing this will no longer improve the quality. - - * - `M` - - `build` - - Y - - Positive integer. Often between 2-100 - - - - Number of bi-directional links create for every new element during construction. Higher values work for higher intrinsic dimensionality and/or high recall, low values can work for datasets with low intrinsic dimensionality and/or low recalls. Also affects the algorithm's memory consumption. - - * - `numThreads` - - `build` - - N - - Positive integer >0 - - 1 - - Number of threads to use to build the index. - - * - `ef` - - `search` - - Y - - Positive integer >0 - - - - Size of the dynamic list for the nearest neighbors used for search. Higher value leads to more accurate but slower search. Cannot be lower than `k`. - - * - `numThreads` - - `search` - - N - - Positive integer >0 - - 1 - - Number of threads to use for queries. - -Please refer to `HNSW algorithm parameters guide `_ from `hnswlib` to learn more about these arguments. - -DiskANN -======= - -diskann_memory --------------- - -Use DiskANN in-memory index for approximate search. - -.. list-table:: - - * - Parameter - - Type - - Required - - Data Type - - Default - - Description - - * - `R` - - `build` - - Y - - Positive integer >0 - - - - Maximum degree of the graph index - - * - `L_build` - - `build` - - Y - - Positive integer >0 - - - - number of visited nodes per greedy search during graph construction - - * - `alpha` - - `build` - - N - - Positive number >=1 - - 1.2 - - controls the pruning parameter of the graph construction - - * - `num_threads` - - `build` - - N - - Positive integer >0 - - omp_get_max_threads() - - Number of CPU threads to use to build the index. - - * - `L_search` - - `search` - - Y - - Positive integer >0 - - - - visited list size during search diff --git a/docs/source/cuvs_bench/pluggable_backend.rst b/docs/source/cuvs_bench/pluggable_backend.rst deleted file mode 100644 index 3655c1b0b6..0000000000 --- a/docs/source/cuvs_bench/pluggable_backend.rst +++ /dev/null @@ -1,241 +0,0 @@ -~~~~~~~~~~~~~~~~~~~~~~~~~ -Pluggable Backend -~~~~~~~~~~~~~~~~~~~~~~~~~ - -cuVS Bench uses a pluggable API so that benchmarks can be run through different execution paths. The default path runs C++ benchmark executables; other backends (e.g. Elasticsearch, Milvus) can be added by implementing the same interface and registering them. Two pieces work together: a **config loader** turns the user's arguments (dataset, algorithms, k, batch_size, and the like) into a structured configuration; a **backend** takes that configuration and runs build and search. Both are registered under a backend type name (e.g. ``cpp_gbench``). When ``BenchmarkOrchestrator(backend_type="cpp_gbench").run_benchmark(...)`` is called, the orchestrator uses the config loader for that type to produce the configuration, then passes it to the backend for that type. - -The following shows how the default backend is used: - -.. code-block:: python - - from cuvs_bench.orchestrator import BenchmarkOrchestrator - - orchestrator = BenchmarkOrchestrator(backend_type="cpp_gbench") - results = orchestrator.run_benchmark( - dataset="deep-image-96-inner", - algorithms="cuvs_cagra", - count=10, - batch_size=10, - build=True, - search=True, - ) - -How a run flows ---------------- - -1. The user calls ``orchestrator.run_benchmark(backend_type="...", dataset=..., algorithms=..., count=..., **kwargs)``. - -2. The orchestrator looks up the **config loader** for that ``backend_type`` and calls its **load()** method. The loader reads YAML (or other sources), expands parameter combinations, applies constraints, and returns a **DatasetConfig** and a list of **BenchmarkConfig** (each describing one or more index configs: algorithm, build params, search params). - -3. The orchestrator obtains the **backend** for that ``backend_type`` from the **BackendRegistry** (instantiating it with the config it needs, e.g. executable path, host/port). - -4. The orchestrator calls the backend's **build(dataset, indexes, ...)** then **search(dataset, indexes, k, batch_size, ...)**. The backend uses the same config shape that its loader produced. - -5. The backend returns **BuildResult** and **SearchResult**; the orchestrator aggregates and returns them. - -The config loader and the backend are thus a pair: the loader defines what to run (which algorithms and parameters); the backend defines how it runs (C++ subprocess, HTTP to a service, and so on). - -What the config loader produces -------------------------------- - -The orchestrator calls the config loader's **load()** method with the same arguments passed to ``run_benchmark()`` (e.g. ``dataset``, ``dataset_path``, ``algorithms``, ``count``, ``batch_size``, ``groups``, ``algo_groups``, and backend-specific options). The loader must return two things: - -- **DatasetConfig** – Dataset metadata: ``name``, ``base_file``, ``query_file``, ``groundtruth_neighbors_file``, ``distance`` (e.g. ``"euclidean"``), ``dims``, and optional ``subset_size``. These are used by the orchestrator to build the in-memory ``Dataset`` and by the backend if it needs file paths. - -- **List[BenchmarkConfig]** – Each **BenchmarkConfig** has: - - **indexes**: a list of **IndexConfig**. Each **IndexConfig** has ``name`` (e.g. ``"my_algo.param1value"``), ``algo`` (algorithm name), ``build_param`` (dict of build parameters), ``search_params`` (list of dicts, one per search parameter combination to benchmark), and ``file`` (path or identifier where the index is stored). - - **backend_config**: a dict passed to the backend constructor (e.g. ``executable_path`` for C++, or ``host``, ``port``, ``index_name`` for a network backend). The backend receives this as its ``config`` in ``__init__``. - -The following shows how to construct a minimal ``DatasetConfig`` and one ``BenchmarkConfig`` (one index, one search param set) so the backend runs a single build and search configuration: - -.. code-block:: python - - from cuvs_bench.orchestrator.config_loaders import ( - ConfigLoader, - DatasetConfig, - BenchmarkConfig, - IndexConfig, - ) - - class MyConfigLoader(ConfigLoader): - @property - def backend_type(self) -> str: - return "my_backend" - - def load(self, dataset, dataset_path, algorithms, count=10, batch_size=10000, **kwargs): - path_to_base = ... # path to base vectors file - path_to_queries = ... # path to query file - path_to_groundtruth = ... # path to groundtruth neighbors file - path_to_index = ... # path or id where the index is stored - dataset_config = DatasetConfig( - name=dataset, - base_file=path_to_base, - query_file=path_to_queries, - groundtruth_neighbors_file=path_to_groundtruth, - distance="euclidean", - dims=128, - ) - index = IndexConfig( - name=f"{algorithms}.default", - algo=algorithms, - build_param={"nlist": 1024}, - search_params=[{"nprobe": 10}], - file=path_to_index, - ) - benchmark_config = BenchmarkConfig( - indexes=[index], - backend_config={ - "host": ..., # backend host - "port": ..., # backend port - "index_name": ..., # name of the index on the backend - }, - ) - return dataset_config, [benchmark_config] - -Adding a new backend --------------------- - -To add a new execution path (e.g. Elasticsearch): - -1. Implement a **config loader**. Subclass **ConfigLoader** (from ``cuvs_bench.orchestrator.config_loaders``). Implement **load()** to accept the kwargs the orchestrator passes (dataset, dataset_path, algorithms, count, batch_size, and the like) and return ``(DatasetConfig, List[BenchmarkConfig])``. Populate **DatasetConfig** with dataset paths and metadata; for each run you want, add an **IndexConfig** (name, algo, build_param, search_params, file) and a **BenchmarkConfig** (indexes, backend_config). The **backend_config** dict is passed to your backend's constructor. Register the loader with **register_config_loader("my_backend", MyConfigLoader)**. - -2. Implement the **backend**. Subclass **BenchmarkBackend** (from ``cuvs_bench.backends.base``). In **__init__(self, config)**, store the config (this is the **backend_config** produced by the loader). Implement **build(dataset, indexes, force=False, dry_run=False)** to return a **BuildResult** (index_path, build_time_seconds, index_size_bytes, algorithm, build_params, metadata, success). Implement **search(dataset, indexes, k, batch_size, mode=..., ...)** to return a **SearchResult** (neighbors, distances, search_time_ms, queries_per_second, recall, algorithm, search_params, success). Implement the **algo** property (e.g. from ``self.config["algo"]``). Set **requires_gpu** or **requires_network** in config if the backend needs them. Register the class with **get_registry().register("my_backend", MyBackend)**. - -3. Use the new backend by calling ``BenchmarkOrchestrator(backend_type="my_backend").run_benchmark(dataset=..., dataset_path=..., algorithms=..., **kwargs)``. The orchestrator will use your loader to build the configuration and your backend to run build and search. - -After implementing your loader and backend, register them as follows: - -.. code-block:: python - - from cuvs_bench.orchestrator import register_config_loader - from cuvs_bench.backends import get_registry - - register_config_loader("my_backend", MyConfigLoader) - get_registry().register("my_backend", MyBackend) - -Example: adding an Elasticsearch backend ------------------------------------------ - -The following example shows a minimal Elasticsearch-style backend. The config loader builds one dataset config and one benchmark config with a single index; the backend stubs build and search and returns the result types the orchestrator expects. In practice you would replace the stub logic with real Elasticsearch API calls. - -Config loader: the **load()** method receives ``dataset``, ``dataset_path``, ``algorithms``, ``count``, ``batch_size``, and optional kwargs. It returns a **DatasetConfig** (filled from dataset path and name) and a list of one **BenchmarkConfig** containing one **IndexConfig** and a **backend_config** with ``host``, ``port``, and ``index_name`` for the backend to use. - -.. code-block:: python - - from cuvs_bench.orchestrator.config_loaders import ( - ConfigLoader, - DatasetConfig, - BenchmarkConfig, - IndexConfig, - ) - - class ElasticsearchConfigLoader(ConfigLoader): - @property - def backend_type(self) -> str: - return "elasticsearch" - - def load(self, dataset, dataset_path, algorithms, count=10, batch_size=10000, **kwargs): - path_to_base = ... # path to base vectors (e.g. from dataset_path/dataset) - path_to_queries = ... # path to query vectors - path_to_groundtruth = ... # path to groundtruth file - path_to_index = ... # path or id for the index - dataset_config = DatasetConfig( - name=dataset, - base_file=path_to_base, - query_file=path_to_queries, - groundtruth_neighbors_file=path_to_groundtruth, - distance="euclidean", - dims=kwargs.get("dims", 128), - ) - index = IndexConfig( - name=f"{algorithms}.es", - algo=algorithms, - build_param={}, - search_params=[{"ef_search": 100}], - file=path_to_index, - ) - benchmark_config = BenchmarkConfig( - indexes=[index], - backend_config={ - "host": ..., # Elasticsearch host - "port": ..., # Elasticsearch port - "index_name": ..., # name of the vector index - "algo": algorithms, - }, - ) - return dataset_config, [benchmark_config] - -Backend: the backend is constructed with **backend_config** (host, port, index_name, algo). **build()** and **search()** return **BuildResult** and **SearchResult** with the required fields; here they are stubbed with minimal values. Replace the stub body with actual Elasticsearch index creation and search calls. - -.. code-block:: python - - import numpy as np - from cuvs_bench.backends.base import ( - BenchmarkBackend, - Dataset, - BuildResult, - SearchResult, - ) - from cuvs_bench.orchestrator.config_loaders import IndexConfig - - class ElasticsearchBackend(BenchmarkBackend): - @property - def algo(self) -> str: - return self.config.get("algo", "elasticsearch") - - def build(self, dataset, indexes, force=False, dry_run=False): - # Stub: in practice, create ES index and bulk-index dataset.base_vectors - return BuildResult( - index_path=indexes[0].file if indexes else "", - build_time_seconds=0.0, - index_size_bytes=0, - algorithm=self.algo, - build_params=indexes[0].build_param if indexes else {}, - metadata={}, - success=True, - ) - - def search(self, dataset, indexes, k, batch_size=10000, mode="latency", force=False, search_threads=None, dry_run=False): - # Stub: in practice, run ES kNN search and compute recall - n_queries = dataset.n_queries - return SearchResult( - neighbors=np.zeros((n_queries, k), dtype=np.int64), - distances=np.zeros((n_queries, k), dtype=np.float32), - search_time_ms=0.0, - queries_per_second=0.0, - recall=0.0, - algorithm=self.algo, - search_params=indexes[0].search_params if indexes else [], - success=True, - ) - -Registration: - -.. code-block:: python - - from cuvs_bench.orchestrator import register_config_loader - from cuvs_bench.backends import get_registry - - register_config_loader("elasticsearch", ElasticsearchConfigLoader) - get_registry().register("elasticsearch", ElasticsearchBackend) - -The built-in **CppGoogleBenchmarkBackend** (``backend_type="cpp_gbench"``) is one such pair: **CppGBenchConfigLoader** reads the YAML under ``config/datasets`` and ``config/algos``, expands the Cartesian product, and validates with the constraint functions; the backend runs the C++ benchmark executables and merges results. Adding a new C++ algorithm (see :doc:`index`) only adds another executable and config for this backend; it does not add a new backend. - -Components at a glance ----------------------- - -.. list-table:: - :header-rows: 1 - :widths: 20 80 - - * - Component - - Description - - * - ConfigLoader - - Abstract. **load(**kwargs)** returns ``(DatasetConfig, List[BenchmarkConfig])``. Register with **register_config_loader(backend_type, loader_class)**. - - * - BenchmarkBackend - - Abstract. **build(dataset, indexes, force, dry_run)** returns ``BuildResult``; **search(dataset, indexes, k, batch_size, mode, ...)** returns ``SearchResult``. Optional **initialize()** and **cleanup()**. Properties: **algo**, **requires_gpu**, **requires_network** (from config). Register with **BackendRegistry.register(name, backend_class)**; get an instance with **get_backend(name, config)**. - - * - BackendRegistry - - **get_registry()** returns the singleton. **register(name, backend_class)** and **get_backend(name, config)** tie a backend type name to the class and to instances. diff --git a/docs/source/filtering.rst b/docs/source/filtering.rst deleted file mode 100644 index cb168f94c8..0000000000 --- a/docs/source/filtering.rst +++ /dev/null @@ -1,116 +0,0 @@ -.. _filtering: - -~~~~~~~~~~~~~~~~~~~~~~~~ -Filtering vector indexes -~~~~~~~~~~~~~~~~~~~~~~~~ - -cuVS supports different type of filtering depending on the vector index being used. The main method used in all of the vector indexes -is pre-filtering, which is a technique that will take into account the filtering of the vectors before computing its closest neighbors, saving -some computation from calculating distances. - -Bitset -====== - -A bitset is an array of bits where each bit can have two possible values: `0` and `1`, which signify in the context of filtering whether -a sample should be filtered or not. `0` means that the corresponding vector will be filtered, and will therefore not be present in the results of the search. -This mechanism is optimized to take as little memory space as possible, and is available through the RAFT library -(check out RAFT's `bitset API documentation `). When calling a search function of an ANN index, the -bitset length should match the number of vectors present in the database. - -Bitmap -====== - -A bitmap is based on the same principle as a bitset, but in two dimensions. This allows users to provide a different bitset for each query -being searched. Check out RAFT's `bitmap API documentation `. - -Examples -======== - -Using a Bitset filter on a CAGRA index --------------------------------------- - -.. code-block:: c++ - - #include - #include - - using namespace cuvs::neighbors; - cagra::index index; - - // ... build index ... - - cagra::search_params search_params; - raft::device_resources res; - raft::device_matrix_view queries = load_queries(); - raft::device_matrix_view neighbors = make_device_matrix_view(n_queries, k); - raft::device_matrix_view distances = make_device_matrix_view(n_queries, k); - - // Load a list of all the samples that will get filtered - std::vector removed_indices_host = get_invalid_indices(); - auto removed_indices_device = - raft::make_device_vector(res, removed_indices_host.size()); - // Copy this list to device - raft::copy(removed_indices_device.data_handle(), removed_indices_host.data(), - removed_indices_host.size(), raft::resource::get_cuda_stream(res)); - - // Create a bitset with the list of samples to filter. - cuvs::core::bitset removed_indices_bitset( - res, removed_indices_device.view(), index.size()); - // Use a `bitset_filter` in the `cagra::search` function call. - auto bitset_filter = - cuvs::neighbors::filtering::bitset_filter(removed_indices_bitset.view()); - cagra::search(res, - search_params, - index, - queries, - neighbors, - distances, - bitset_filter); - - -Using a Bitmap filter on a Brute-force index --------------------------------------------- - -.. code-block:: c++ - - #include - #include - - using namespace cuvs::neighbors; - using indexing_dtype = int64_t; - - // ... build index ... - brute_force::index_params index_params; - brute_force::search_params search_params; - raft::device_resources res; - raft::device_matrix_view dataset = load_dataset(n_vectors, dim); - raft::device_matrix_view queries = load_queries(n_queries, dim); - auto index = brute_force::build(res, index_params, raft::make_const_mdspan(dataset.view())); - - // Load a list of all the samples that will get filtered - std::vector removed_indices_host = get_invalid_indices(); - auto removed_indices_device = - raft::make_device_vector(res, removed_indices_host.size()); - // Copy this list to device - raft::copy(removed_indices_device.data_handle(), removed_indices_host.data(), - removed_indices_host.size(), raft::resource::get_cuda_stream(res)); - - // Create a bitmap with the list of samples to filter. - cuvs::core::bitset removed_indices_bitset( - res, removed_indices_device.view(), n_queries * n_vectors); - cuvs::core::bitmap_view removed_indices_bitmap( - removed_indices_bitset.data(), n_queries, n_vectors); - - // Use a `bitmap_filter` in the `brute_force::search` function call. - auto bitmap_filter = - cuvs::neighbors::filtering::bitmap_filter(removed_indices_bitmap); - - auto neighbors = raft::make_device_matrix_view(n_queries, k); - auto distances = raft::make_device_matrix_view(n_queries, k); - brute_force::search(res, - search_params, - index, - raft::make_const_mdspan(queries.view()), - neighbors.view(), - distances.view(), - bitmap_filter); diff --git a/docs/source/getting_started.rst b/docs/source/getting_started.rst deleted file mode 100644 index 656bdf32e4..0000000000 --- a/docs/source/getting_started.rst +++ /dev/null @@ -1,124 +0,0 @@ -~~~~~~~~~~~~~~~ -Getting Started -~~~~~~~~~~~~~~~ - -- `New to vector search?`_ - - * :doc:`Primer on vector search ` - - * :doc:`Vector search indexes vs vector databases ` - - * :doc:`Index tuning guide ` - - * :doc:`Comparing vector search index performance ` - -- `Supported indexes`_ - - * :doc:`Vector search index guide ` - -- `Using cuVS APIs`_ - - * :doc:`C API Docs ` - - * :doc:`C++ API Docs ` - - * :doc:`Python API Docs ` - - * :doc:`Rust API Docs ` - - * :doc:`API basics ` - - * :doc:`API interoperability ` - -- `Where to next?`_ - - * `Social media`_ - - * `Blogs`_ - - * `Research`_ - - * `Get involved`_ - -New to vector search? -===================== - -If you are unfamiliar with the basics of vector search or how vector search differs from vector databases, then :doc:`this primer on vector search guide ` should provide some good insight. Another good resource for the uninitiated is our :doc:`vector databases vs vector search ` guide. As outlined in the primer, vector search as used in vector databases is often closer to machine learning than to traditional databases. This means that while traditional databases can often be slow without any performance tuning, they will usually still yield the correct results. Unfortunately, vector search indexes, like other machine learning models, can yield garbage results if not tuned correctly. - -Fortunately, this opens up the whole world of hyperparameter optimization to improve vector search performance and quality. Please see our :doc:`index tuning guide ` for more information. - -When comparing the performance of vector search indexes, it is important that considerations are made with respect to three main dimensions: - -#. Build time -#. Search quality -#. Search performance - -Please see the :doc:`primer on comparing vector search index performance ` for more information on methodologies and how to make a fair apples-to-apples comparison during your evaluations. - -Supported indexes -================= - -cuVS supports many of the standard index types with the list continuing to grow and stay current with the state-of-the-art. Please refer to our :doc:`vector search index guide ` to learn more about each individual index type, when they can be useful on the GPU, the tuning knobs they offer to trade off performance and quality. - -The primary goal of cuVS is to enable speed, scale, and flexibility (in that order)- and one of the important value propositions is to enhance existing software deployments with extensible GPU capabilities to improve pain points while not interrupting parts of the system that work well today with CPU. - - -Using cuVS APIs -=============== - -cuVS is a C++ library at its core, which is wrapped with a C library and exposed further through various different languages. cuVS currently provides APIs and documentation for :doc:`C `, :doc:`C++ `, :doc:`Python `, and :doc:`Rust ` with more languages in the works. our :doc:`API basics ` provides some background and context about the important paradigms and vocabulary types you'll encounter when working with cuVS types. - -Please refer to the :doc:`guide on API interoperability ` for more information on how cuVS can work seamlessly with other libraries like numpy, cupy, tensorflow, and pytorch, even without having to copy device memory. - - -Where to next? -============== - -cuVS is free and open source software, licensed under Apache 2.0 Once you are familiar with and/or have used cuVS, you can access the developer community most easily through `Github `_. Please open Github issues for any bugs, questions or feature requests. - -Social media ------------- - -You can access the RAPIDS community through `Slack `_ , `Stack Overflow `_ and `X `_ - -Blogs ------ - -We frequently publish blogs on GPU-enabled vector search, which can provide great deep dives into various important topics and breakthroughs: - -#. `See all cuVS blogs `_ -#. `Accelerated Vector Search: Approximating with cuVS IVF-Flat `_ -#. Accelerating Vector Search with cuVS IVF-PQ (`Part 1 `_, `Part 2 `_) - -Research --------- - -For the interested reader, many of the accelerated implementations in cuVS are also based on research papers which can provide a lot more background. We also ask you to please cite the corresponding algorithms by referencing them in your own research. - -#. `CAGRA: Highly Parallel Graph Construction and Approximate Nearest Neighbor Search `_ -#. `Top-K Algorithms on GPU: A Comprehensive Study and New Methods `_ -#. `Fast K-NN Graph Construction by GPU Based NN-Descent `_ -#. `cuSLINK: Single-linkage Agglomerative Clustering on the GPU `_ -#. `GPU Semiring Primitives for Sparse Neighborhood Methods `_ -#. `VecFlow: A High-Performance Vector Data Management System for Filtered-Search on GPUs `_ - - -Get involved ------------- - -We always welcome patches for new features and bug fixes. Please read our `contributing guide `_ for more information on contributing patches to cuVS. - - - -.. toctree:: - :hidden: - - choosing_and_configuring_indexes.rst - vector_databases_vs_vector_search.rst - tuning_guide.rst - comparing_indexes.rst - neighbors/neighbors.rst - api_basics.rst - api_interoperability.rst - working_with_ann_indexes.rst - filtering.rst diff --git a/docs/source/integrations.rst b/docs/source/integrations.rst deleted file mode 100644 index 760892a98a..0000000000 --- a/docs/source/integrations.rst +++ /dev/null @@ -1,13 +0,0 @@ -============ -Integrations -============ - -Aside from using cuVS standalone, it can be consumed through a number of sdk and vector database integrations. - -.. toctree:: - :maxdepth: 4 - - integrations/faiss.rst - integrations/milvus.rst - integrations/lucene.rst - integrations/kinetica.rst diff --git a/docs/source/integrations/kinetica.rst b/docs/source/integrations/kinetica.rst deleted file mode 100644 index e74cfe82fd..0000000000 --- a/docs/source/integrations/kinetica.rst +++ /dev/null @@ -1,6 +0,0 @@ -Kinetica --------- - -Starting with release 7.2, Kinetica supports the graph-based the CAGRA algorithm from RAFT. Kinetica will continue to improve its support over coming versions, while also migrating to cuVS as we work to move the vector search algorithms out of RAFT and into cuVS. - -Kinetica currently offers the ability to create a CAGRA index in a SQL `CREATE_TABLE` statement, as outlined in their `vector search indexing docs `_. Kinetica is not open source, but the RAFT indexes can be enabled in the developer edition, which can be installed `here `_. diff --git a/docs/source/neighbors/cagra.rst b/docs/source/neighbors/cagra.rst deleted file mode 100644 index 471f3a915a..0000000000 --- a/docs/source/neighbors/cagra.rst +++ /dev/null @@ -1,276 +0,0 @@ -CAGRA -===== - -CAGRA, or (C)UDA (A)NN (GRA)ph-based, is a graph-based index that is based loosely on the popular navigable small-world graph (NSG) algorithm, but which has been -built from the ground-up specifically for the GPU. CAGRA constructs a flat graph representation by first building a kNN graph -of the training points and then removing redundant paths between neighbors. - -The CAGRA algorithm has two basic steps- -* 1. Construct a kNN graph -* 2. Prune redundant routes from the kNN graph. - -I-force could be used to construct the initial kNN graph. This would yield the most accurate graph but would be very slow and -we find that in practice the kNN graph does not need to be very accurate since the pruning step helps to boost the overall recall of -the index. cuVS provides IVF-PQ and NN-Descent strategies for building the initial kNN graph and these can be selected in index params object during index construction. - -[ :doc:`C API <../c_api/neighbors_cagra_c>` | :doc:`C++ API <../cpp_api/neighbors_cagra>` | :doc:`Python API <../python_api/neighbors_cagra>` | :doc:`Rust API <../rust_api/index>` ] - -Interoperability with HNSW --------------------------- - -cuVS provides the capability to convert a CAGRA graph to an HNSW graph, which enables the GPU to be used only for building the index -while the CPU can be leveraged for search. - -Filtering considerations ------------------------- - -CAGRA supports filtered search and has improved multi-CTA algorithm in branch-25.02 to provide reasonable recall and performance for filtering rate as high as 90% or more. - -To obtain an appropriate recall in filtered search, it is necessary to set search parameters according to the filtering rate, but since it is difficult for users to do this, CAGRA automatically adjusts `itopk_size` internally according to the filtering rate on a heuristic basis. If you want to disable this automatic adjustment, set `filtering_rate`, one of the search parameters, to `0.0`, and `itopk_size` will not be adjusted automatically. - -Configuration parameters ------------------------- - -Build parameters -~~~~~~~~~~~~~~~~ - -.. list-table:: - :widths: 25 25 50 - :header-rows: 1 - - * - Name - - Default - - Description - * - compression - - None - - For large datasets, the raw vectors can be compressed using product quantization so they can be placed on device. This comes at the cost of lowering recall, though a refinement reranking step can be used to make up the lost recall after search. - * - graph_build_algo - - 'IVF_PQ' - - The graph build algorithm to use for building - * - graph_build_params - - None - - Specify explicit build parameters for the corresponding graph build algorithms - * - graph_degree - - 32 - - The degree of the final CAGRA graph. All vertices in the graph will have this degree. During search, a larger graph degree allows for more exploration of the search space and improves recall but at the expense of searching more vertices. - * - intermediate_graph_degree - - 64 - - The degree of the initial knn graph before it is optimized into the final CAGRA graph. A larger value increases connectivity of the initial graph so that it performs better once pruned. Larger values come at the cost of increased device memory usage and increases the time of initial knn graph construction. - * - guarantee_connectivity - - False - - Uses a degree-constrained minimum spanning tree to guarantee the initial knn graph is connected. This can improve recall on some datasets. - * - attach_data_on_build - - True - - Should the dataset be attached to the index after the index is built? Setting this to `False` can improve memory usage and performance, for example if the graph is being serialized to disk or converted to HNSW right after building it. - -Search parameters -~~~~~~~~~~~~~~~~~ - -.. list-table:: - :widths: 25 25 50 - :header-rows: 1 - - * - Name - - Default - - Description - * - itopk_size - - 64 - - Number of intermediate search results retained during search. This value needs to be >=k. This is the main knob to tweak search performance. - * - max_iterations - - 0 - - The maximum number of iterations during search. Default is to auto-select. - * - max_queries - - 0 - - Max number of search queries to perform concurrently (batch size). Default is to auto-select. - * - team_size - - 0 - - Number of CUDA threads for calculating each distance. Can be 4, 8, 16, or 32. Default is to auto-select. - * - search_width - - 1 - - Number of vertices to select as the starting point for the search in each iteration. - * - min_iterations - - 0 - - Minimum number of search iterations to perform - -Tuning Considerations ---------------------- - -The 3 hyper-parameters that are most often tuned are `graph_degree`, `intermediate_graph_degree`, and `itopk_size`. - -Memory footprint -================ - -CAGRA builds a nearest-neighbor graph (stored on host) while keeping the original dataset vectors around. During index build, the dataset must reside in device (GPU) memory. After building, the dataset can optionally be detached from the index — for example, when immediately converting the CAGRA graph to a CPU-based format like HNSW for search. - -Baseline Memory Footprint -------------------------- - -The baseline memory footprint after index construction: - -.. math:: - - \text{dataset_size (device)} - \;=\; - \text{number_vectors} \times \text{vector_dimension} \times \text{bytes_per_dimension} - -.. math:: - - \text{graph_size (host)} - \;=\; - \text{number_vectors} \times \text{graph_degree} \times \operatorname{sizeof}\!\big(\mathrm{IdxT}\big) - -Note: The dataset must be in GPU memory during index build, but can be detached afterward if not needed for search. - -**Example** (1,000,000 vectors, dim = 1024, fp32, graph\_degree = 64, IdxT = int32): - -- dataset\_size = 4,096,000,000 B = 3906.25 MB -- graph\_size = 256,000,000 B = 244.14 MB - -Build peak memory usage ------------------------ - -Index build has two phases: (1) construct a knn graph, then (2) optimize it to remove redundant and unnecessary paths. -The initial knn graph can be built with IVF-PQ or nn-descent. IVF-PQ has the additional benefit that it supports out-of-core construction, allowing CAGRA to be trained on datasets larger than available GPU memory. -The steps below are sequential with distinct peak memory consumption. The overall peak memory utilization depends on the configured RMM memory resource. - -knn graph build phase using IVF-PQ -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The knn graph can be constructed using the IVF-PQ algorithm, which works in two stages: first, an IVF-PQ index is trained on a subset of vectors to learn cluster centroids; then, the full dataset is queried against this index in batches to find approximate nearest neighbors for each vector. - -**IVF-PQ Build (centroid training)** — uses a training subset to compute cluster centroids and PQ codebooks. - -.. math:: - - \text{IVFPQ_build_peak} - \;=\; - \frac{n_{\text{vectors}}}{\text{train_set_ratio}} \times \text{dim} \times 4 - \;+\; - n_{\text{clusters}} \times \text{dim} \times 4 - \;+\; - \frac{n_{\text{vectors}}}{\text{train_set_ratio}} \times \operatorname{sizeof}(\mathrm{uint32\_t}) - -**Example** (n = 1e6; dim = 1024; n\_clusters = 1024; train\_set\_ratio = 10): 395.01 MB - -**IVF-PQ Search (forms the intermediate graph)** — Constructs the knn graph in batches by querying the IVF-PQ index for the nearest neighbors of all training points. - -.. math:: - - \text{IVFPQ_search_peak} - \;=\; - \text{batch_size} \times \text{dim} \times 4 - \;+\; - \text{batch_size} \times \text{intermediate_degree} \times \operatorname{sizeof}(\mathrm{uint32\_t}) - \;+\; - \text{batch_size} \times \text{intermediate_degree} \times 4 - -**Example** (batch = 1024, dim = 1024, intermediate\_degree = 128): 5.00 MB - -knn graph build phase using NN-DESCENT -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -**Peak device memory:** - -.. math:: - - \text{NND_device_peak} - \;=\; - n_\text{vectors} \times (n_\text{dims} \times 2 + 276) - -- Data vectors (transferred to device and stored as fp16): :math:`n_\text{dims} \times 2` bytes per vector -- Small working graph, locks, edge counters: 276 bytes per vector (fixed) -- Additional :math:`4` bytes per vector when using L2 metric (for precomputed norms) - -**Peak host memory:** - -.. math:: - - \text{NND_host_peak} - \;=\; - n_\text{vectors} \times (13 \times \text{intermediate_graph_degree} + 912) - -- Full graph with distances (~1.3x overallocation): :math:`1.3 \times 8 \times \text{intermediate_graph_degree}` bytes per vector -- Bloom filter for sampling: :math:`1.3 \times 2 \times \text{intermediate_graph_degree}` bytes per vector -- 5 sample buffers (degree 32 each): 640 bytes per vector -- Graph update buffer (degree 32): 256 bytes per vector -- Edge counters: 16 bytes per vector - - -Optimize phase -~~~~~~~~~~~~~~ - -Pruning/reordering the intermediate graph; peak scales linearly with intermediate degree. - -.. math:: - - \text{optimize_peak} - \;=\; - n_{\text{vectors}} \times - \Big( 4 + \big(\operatorname{sizeof}(\mathrm{IdxT}) + 1\big)\times \text{intermediate_degree} \Big) - -**Example** (n = 1e6, intermediate\_degree = 128, IdxT = int32): 614.17 MB -Out-of-core CAGRA build consists of IVF-PQ build, IVF-PQ search, CAGRA optimization. Note that these steps are performed sequentially, so they are not additive. - -Overall Build Peak Memory Usage -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The overall peak memory footprint on the device is the maximum allocation across each sequential step, since RMM's ``device_memory_resource`` releases memory between steps. - -**Using IVF-PQ:** - -.. math:: - - \text{build_peak} - \;=\; - \text{dataset_size} - \;+\; - \max\!\big(\text{IVFPQ_build_peak},\ \text{IVFPQ_search_peak},\ \text{optimize_peak}\big) - -**Example:** 3906.25 + max(395.01, 5.00, 614.17) = 4520.42 MB - -**Using NN-Descent:** - -.. math:: - - \text{build_peak} - \;=\; - \text{dataset_size}^{*} - \;+\; - \max\!\big(\text{NND_device_peak},\ \text{optimize_peak}\big) - -:math:`\text{dataset_size}^{*}` applies only when the user passes data residing in device memory; NN-Descent internally copies the dataset to the device as fp16, so host-memory inputs do not add this term. - -Search peak memory usage ------------------------- - -CAGRA search requires the dataset and graph to already be resident in GPU memory. When using CAGRA-Q (compressed/quantized), the original dataset can reside in host memory instead. Additionally, temporary workspace memory is needed to store the search results for a batch of queries. -If multiple batches are to be launched concurrently or overlapped, separate results buffers will be needed for each. -The below memory estimate assumes just one batch of queries being run at a time and reusing the buffers. - -.. math:: - - \text{search_memory} - \;=\; - \text{dataset_size} + \text{graph_size} + \text{workspace_size} - -Where ``workspace_size`` is the temporary memory used for query vectors and result storage: - -.. math:: - - \text{query_size} - \;=\; - \text{batch_size} \times \text{dim} \times \operatorname{sizeof}(\mathrm{float}) - -.. math:: - - \text{result_size} - \;=\; - \text{batch_size} \times \text{topk} \times - \big(\operatorname{sizeof}(\mathrm{IdxT}) + \operatorname{sizeof}(\mathrm{float})\big) - -**Example** (dim = 1024, batch\_size = 100, topk = 10, IdxT = int32): - -- query\_size = 409,600 B = 0.39 MB -- result\_size = 8,000 B = 0.0076 MB -- workspace\_size = query\_size + result\_size = 0.40 MB -- Total search memory ≈ 3906.25 + 244.14 + 0.40 = 4150.79 MB diff --git a/docs/source/neighbors/ivfflat.rst b/docs/source/neighbors/ivfflat.rst deleted file mode 100644 index d4c8f03c18..0000000000 --- a/docs/source/neighbors/ivfflat.rst +++ /dev/null @@ -1,115 +0,0 @@ -IVF-Flat -======== - -IVF-Flat is an inverted file index (IVF) algorithm, which in the context of nearest neighbors means that data points are -partitioned into clusters. At search time, brute-force is performed only in a (user-defined) subset of the closest clusters. -In practice, this algorithm can search the index much faster than brute-force and often still maintain an acceptable -recall, though this comes with the drawback that the index itself copies the original training vectors into a memory layout -that is optimized for fast memory reads and adds some additional memory storage overheads. Once the index is trained, -this algorithm no longer requires the original raw training vectors. - -IVF-Flat tends to be a great choice when - -1. like brute-force, there is enough device memory available to fit all of the vectors -in the index, and -2. exact recall is not needed. as with the other index types, the tuning parameters are used to trade-off recall for search latency / throughput. - -[ :doc:`C API <../c_api/neighbors_ivf_flat_c>` | :doc:`C++ API <../cpp_api/neighbors_ivf_flat>` | :doc:`Python API <../python_api/neighbors_ivf_flat>` | :doc:`Rust API <../rust_api/index>` ] - -Filtering considerations ------------------------- - -IVF methods only apply filters to the lists which are probed for each query point. As a result, the results of a filtered query will likely differ significantly from the results of a filtering applid to an exact method like brute-force. For example. imagine you have 3 IVF lists each containing 2 vectors and you perform a query against only the closest 2 lists but you filter out all but 1 element. If that remaining element happens to be in one of the lists which was not proved, it will not be considered at all in the search results. It's important to consider this when using any of the IVF methods in your applications. - - -Configuration parameters ------------------------- - -Build parameters -~~~~~~~~~~~~~~~~ - -.. list-table:: - :widths: 25 25 50 - :header-rows: 1 - - * - Name - - Default - - Description - * - n_lists - - sqrt(n) - - Number of coarse clusters used to partition the index. A good heuristic for this value is sqrt(n_vectors_in_index) - * - add_data_on_build - - True - - Should the training points be added to the index after the index is built? - * - kmeans_train_iters - - 20 - - Max number of iterations for k-means training before convergence is assumed. Note that convergence could happen before this number of iterations. - * - kmeans_trainset_fraction - - 0.5 - - Fraction of points that should be subsampled from the original dataset to train the k-means clusters. Default is 1/2 the training dataset. This can often be reduced for very large datasets to improve both cluster quality and the build time. - * - adaptive_centers - - false - - Should the existing trained centroids adapt to new points that are added to the index? This provides a trade-off between improving recall at the expense of having to compute new centroids for clusters when new points are added. When points are added in large batches, the performance cost may not be noticeable. - * - conservative_memory_allocation - - false - - To support dynamic indexes, where points are expected to be added later, the individual IVF lists can be imtentionally overallocated up front to reduce the amount and impact of increasing list sizes, which requires allocating more memory and copying the old list to the new, larger, list. - - -Search parameters -~~~~~~~~~~~~~~~~~ - -.. list-table:: - :widths: 25 25 50 - :header-rows: 1 - - * - Name - - Default - - Description - * - n_probes - - 20 - - Number of closest IVF lists to scan for each query point. - -Tuning Considerations ---------------------- - -Since IVF methods use clustering to establish spatial locality and partition data points into individual lists, there's an inherent -assumption that the number of lists, and thus the max size of the data in the index is known up front. For some use-cases, this -might not matter. For example, most vector databases build many smaller physical approximate nearest neighbors indexes, each from -fixed-size or maximum-sized immutable segments and so the number of lists can be tuned based on the number of vectors in the indexes. - -Empirically, we've found :math:`\sqrt{n\_index\_vectors}` to be a good starting point for the :math:`n\_lists` hyper-parameter. Remember, having more -lists means less points to search within each list, but it could also mean more :math:`n\_probes` are needed at search time to reach an acceptable -recall. - - -Memory footprint ----------------- - -Each cluster is padded to at least 32 vectors (but potentially up to 1024). Assuming uniform random distribution of vectors/list, we would have -:math:`cluster\_overhead = (conservative\_memory\_allocation ? 16 : 512 ) * dim * sizeof_{float}` - -Note that each cluster is allocated as a separate allocation. If we use a `cuda_memory_resource`, that would grab memory in 1 MiB chunks, so on average we might have 0.5 MiB overhead per cluster. If we us 10s of thousands of clusters, it becomes essential to use pool allocator to avoid this overhead. - -:math:`cluster\_overhead = 0.5 MiB` // if we do not use pool allocator - - -Index (device memory): -~~~~~~~~~~~~~~~~~~~~~~ - -.. math:: - - n\_vectors * n\_dimensions * sizeof(T) + - - n\_vectors * sizeof(int_type) + - - n\_clusters * n\_dimensions * sizeof(T) + - - n\_clusters * cluster_overhead` - - -Peak device memory usage for index build: -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -:math:`workspace = min(1GB, n\_queries * [(n\_lists + 1 + n\_probes * (k + 1)) * sizeof_{float} + n\_probes * k * sizeof_{idx}])` - -:math:`index\_size + workspace` diff --git a/docs/source/neighbors/ivfpq.rst b/docs/source/neighbors/ivfpq.rst deleted file mode 100644 index e243a5b562..0000000000 --- a/docs/source/neighbors/ivfpq.rst +++ /dev/null @@ -1,135 +0,0 @@ -IVF-PQ -====== - -IVF-PQ is an inverted file index (IVF) algorithm, which is an extension to the IVF-Flat algorithm (e.g. data points are first -partitioned into clusters) where product quantization is performed within each cluster in order to shrink the memory footprint -of the index. Product quantization is a lossy compression method and it is capable of storing larger number of vectors -on the GPU by offloading the original vectors to main memory, however higher compression levels often lead to reduced recall. -Often a strategy called refinement reranking is employed to make up for the lost recall by querying the IVF-PQ index for a larger -`k` than desired and performing a reordering and reduction to `k` based on the distances from the unquantized vectors. Unfortunately, -this does mean that the unquantized raw vectors need to be available and often this can be done efficiently using multiple CPU threads. - -[ :doc:`C API <../c_api/neighbors_ivf_pq_c>` | :doc:`C++ API <../cpp_api/neighbors_ivf_pq>` | :doc:`Python API <../python_api/neighbors_ivf_pq>` | :doc:`Rust API <../rust_api/index>` ] - - -Configuration parameters ------------------------- - -Build parameters -~~~~~~~~~~~~~~~~ - -.. list-table:: - :widths: 25 25 50 - :header-rows: 1 - - * - Name - - Default - - Description - * - n_lists - - sqrt(n) - - Number of coarse clusters used to partition the index. A good heuristic for this value is sqrt(n_vectors_in_index) - * - kmeans_n_iters - - 20 - - The number of iterations when searching for k-means centers - * - kmeans_trainset_fraction - - 0.5 - - The fraction of training data to use for iterative k-means building - * - pq_bits - - 8 - - The bit length of each vector element after compressing with PQ. Possible values are any integer between 4 and 8. - * - pq_dim - - 0 - - The dimensionality of each vector after compressing with PQ. When 0, the dim is set heuristically. - * - codebook_kind - - per_subspace - - How codebooks are created. `per_subspace` trains kmeans on some number of sub-dimensions while `per_cluster` - * - force_random_rotation - - false - - Apply a random rotation matrix on the input data and queries even if `dim % pq_dim == 0` - * - conservative_memory_allocation - - false - - To support dynamic indexes, where points are expected to be added later, the individual IVF lists can be imtentionally overallocated up front to reduce the amount and impact of increasing list sizes, which requires allocating more memory and copying the old list to the new, larger, list. - * - add_data_on_build - - True - - Should the training points be added to the index after the index is built? - * - max_train_points_per_pq_code - - 256 - - The max number of data points to use per PQ code during PQ codebook training. - - -Search parameters -~~~~~~~~~~~~~~~~~ - -.. list-table:: - :widths: 25 25 50 - :header-rows: 1 - - * - Name - - Default - - Description - * - n_probes - - 20 - - Number of closest IVF lists to scan for each query point. - * - lut_dtype - - cuda_r_32f - - Datatype to store the pq lookup tables. Can also use cuda_r_16f for half-precision and cuda_r_8u for 8-bit precision. Smaller lookup tables can fit into shared memory and significantly improve search times. - * - internal_distance_dtype - - cuda_r_32f - - Storage data type for distance/similarity computed at search time. Can also use cuda_r_16f for half-precision. - * - preferred_smem_carveout - - 1.0 - - Preferred fraction of SM's unified memory / L1 cache to be used as shared memory. Default is 100% - -Tuning Considerations ---------------------- - -IVF-PQ has similar tuning considerations to IVF-flat, though the PQ compression ratio adds an additional variable to trade-off index size for search quality. - -It's important to note that IVF-PQ becomes very lossy very quickly, and so refinement reranking is often needed to get a reasonable recall. This step usually consists of searching initially for more k-neighbors than needed and then reducing the resulting neighborhoods down to k by computing exact distances. This step can be performed efficiently on CPU or GPU and generally has only a marginal impact on search latency. - -Memory footprint ----------------- - -Index (device memory): -~~~~~~~~~~~~~~~~~~~~~~ - -Simple approximate formula: :math:`n\_vectors * (pq\_dim * \frac{pq\_bits}{8} + sizeof_{idx}) + n\_clusters` - -The IVF lists end up being represented by a sparse data structure that stores the pointers to each list, an indices array that contains the indexes of each vector in each list, and an array with the encoded (and interleaved) data for each list. - -IVF list pointers: :math:`n\_clusters * sizeof_{uint32\_t}` - -Indices: :math:`n\_vectors * sizeof_{idx}` - -Encoded data (interleaved): :math:`n\_vectors * pq\_dim * \frac{pq\_bits}{8}` - -Per subspace method: :math:`4 * pq\_dim * pq\_len * 2^{pq\_bits}` - -Per cluster method: :math:`4 * n\_clusters * pq\_len * 2^{pq\_bits}` - -Extras: :math:`n\_clusters * (20 + 8 * dim)` - -Index (host memory): -~~~~~~~~~~~~~~~~~~~~ - -When refinement is used with the dataset on host, the original raw vectors are needed: :math:`n\_vectors * dims * sizeof_{float}` - -Search peak memory usage (device); -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Total usage: :math:`index + queries + output\_indices + output\_distances + workspace` - -Workspace size is not trivial, a heuristic controls the batch size to make sure the workspace fits the `raft::resource::get_workspace_free_bytes(res)``. - -Build peak memory usage (device): -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. math:: - - \frac{n\_vectors}{trainset\_ratio * dims * sizeof_{float}} - - + \frac{n\_vectors}{trainset\_ratio * sizeof_{uint32\_t}} - - + n\_clusters * dim * sizeof_{float} - -Note, if there’s not enough space left in the workspace memory resource, IVF-PQ build automatically switches to the managed memory for the training set and labels. diff --git a/docs/source/neighbors/neighbors.rst b/docs/source/neighbors/neighbors.rst deleted file mode 100644 index f66b73f867..0000000000 --- a/docs/source/neighbors/neighbors.rst +++ /dev/null @@ -1,21 +0,0 @@ -Nearest Neighbor -================ - -.. toctree:: - :maxdepth: 3 - :caption: Contents: - - bruteforce.rst - cagra.rst - ivfflat.rst - ivfpq.rst - vamana.rst - all_neighbors.rst - - -Indices and tables -================== - -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` diff --git a/docs/source/neighbors/vamana.rst b/docs/source/neighbors/vamana.rst deleted file mode 100644 index 4f5c2eb5f0..0000000000 --- a/docs/source/neighbors/vamana.rst +++ /dev/null @@ -1,75 +0,0 @@ -Vamana -====== - -VAMANA is the underlying graph construction algorithm used to construct indexes for the DiskANN vector search solution. DiskANN and the Vamana algorithm are described in detail in the `published paper `, and a highly optimized `open-source repository ` includes many features for index construction and search. In cuVS, we provide a version of the Vamana algorithm optimized for GPU architectures to accelreate graph construction to build DiskANN idnexes. At a high level, the Vamana algorithm operates as follows: - -* 1. Starting with an empty graph, select a medoid vector from the D-dimension vector dataset and insert it into the graph. -* 2. Iteratively insert batches of dataset vectors into the graph, connecting each inserted vector to neighbors based on a graph traversal. -* 3. For each batch, create reverse edges and prune unnecessary edges. - -There are many algorithmic details that are outlined in the `paper `, and many GPU-specific optimizations are included in this implementation. - -The current implementation of DiskANN in cuVS only includes the 'in-memory' graph construction and a serialization step that writes the index to a file. This index file can be then used by the `open-source DiskANN ` library to perform efficient search. Additional DiskANN functionality, including GPU-accelerated search and 'ssd' index build are planned for future cuVS releases. - -[ :doc:`C++ API <../cpp_api/neighbors_vamana>` ] - -Interoperability with CPU DiskANN ---------------------------------- - -The 'vamana::serialize' API calls writes the index to a file with a format that is compatible with the `open-source DiskANN repositoriy `. This allows cuVS to be used to accelerate index construction while leveraging the efficient CPU-based search currently available. - -Configuration parameters ------------------------- - -Build parameters -~~~~~~~~~~~~~~~~ - -.. list-table:: - :widths: 25 25 50 - :header-rows: 1 - - * - Name - - Default - - Description - * - graph_degree - - 32 - - The maximum degre of the final Vamana graph. The internal representation of the graph includes this many edges for every node, but serialize will compress the graph into a 'CSR' format with, potentially, fewer edges. - * - visited_size - - 64 - - Maximum number of visited nodes saved during each traversal to insert a new node. This corresponds to the 'L' parameter in the paper. - * - vamana_iters - - 1 - - Number of iterations ran to improve the graph. Each iteration involves inserting every vector in the dataset. - * - alpha - - 1.2 - - Alpha parameter that defines how aggressively to prune edges. - * - max_fraction - - 0.06 - - Maximum fraction of the dataset that will be inserted as a single batch. Larger max batch size decreases graph quality but improves speed. - * - batch_base - - 2 - - Base of growth rate of batch sizes. Insertion batch sizes increase exponentially based on this parameter until max_fraction is reached. - * - queue_size - - 127 - - Size of the candidate queue structure used during graph traversal. Must be (2^x)-1 for some x, and must be > visited_size. - -Tuning Considerations ---------------------- - -The 2 hyper-parameters that are most often tuned are `graph_degree` and `visited_size`. The time needed to create a graph increases dramatically when increasing `graph_degree`, in particular. However, larger graphs may be needed to achieve very high recall search, especially for large datasets. - -Memory footprint ----------------- - -Vamana builds a graph that is stored in device memory. However, in order to serialize the index and write it to a file for later use, it must be moved into host memory. If the `include_dataset` parameter is also set, then the dataset must be resident in host memory when calling serialize as well. - -Device memory usage -~~~~~~~~~~~~~~~~~~~ - -The built index represents the graph as fixed degree, storing a total of :math:`graph\_degree * n\_index\_vectors` edges. Graph construction also requires the dataset be in device memory (or it copies it to device during build). In addition, device memory is used during construction to sort and create the reverse edges. Thus, the amount of device memory needed depends on the dataset itself, but it is bounded by a maximum sum of: - -- vector dataset: :math:`n\_index\_vectors * n\_dims * sizeof(T)` -- output graph: :math:`graph\_degree * n\_index\_vectors * sizeof(IdxT)` -- scratch memory: :math:`n\_index\_vectors * max\_fraction * (2 + graph\_degree) * sizeof(IdxT)` - -Reduction in scratch device memory requirements are planned for upcoming releases of cuVS. diff --git a/docs/source/python_api.rst b/docs/source/python_api.rst deleted file mode 100644 index 4c8fc47820..0000000000 --- a/docs/source/python_api.rst +++ /dev/null @@ -1,13 +0,0 @@ -~~~~~~~~~~~~~~~~~~~~~~~~ -Python API Documentation -~~~~~~~~~~~~~~~~~~~~~~~~ - -.. _api: - -.. toctree:: - :maxdepth: 4 - - python_api/cluster.rst - python_api/distance.rst - python_api/neighbors.rst - python_api/preprocessing.rst diff --git a/docs/source/python_api/cluster.rst b/docs/source/python_api/cluster.rst deleted file mode 100644 index b5c0ab957c..0000000000 --- a/docs/source/python_api/cluster.rst +++ /dev/null @@ -1,12 +0,0 @@ -Cluster -======== - -.. role:: py(code) - :language: python - :class: highlight - -.. toctree:: - :maxdepth: 1 - :caption: Contents: - - cluster_kmeans.rst diff --git a/docs/source/python_api/cluster_kmeans.rst b/docs/source/python_api/cluster_kmeans.rst deleted file mode 100644 index 8fda17f80d..0000000000 --- a/docs/source/python_api/cluster_kmeans.rst +++ /dev/null @@ -1,27 +0,0 @@ -K-Means -======= - -.. role:: py(code) - :language: python - :class: highlight - -K-Means Parameters -################## - -.. autoclass:: cuvs.cluster.kmeans.KMeansParams - :members: - -K-Means Fit -########### - -.. autofunction:: cuvs.cluster.kmeans.fit - -K-Means Predict -############### - -.. autofunction:: cuvs.cluster.kmeans.predict - -K-Means Cluster Cost -#################### - -.. autofunction:: cuvs.cluster.kmeans.cluster_cost diff --git a/docs/source/python_api/distance.rst b/docs/source/python_api/distance.rst deleted file mode 100644 index debd82953c..0000000000 --- a/docs/source/python_api/distance.rst +++ /dev/null @@ -1,12 +0,0 @@ -Distance -======== - -.. role:: py(code) - :language: python - :class: highlight - - -Pairwise Distance -################# - -.. autofunction:: cuvs.distance.pairwise_distance diff --git a/docs/source/python_api/neighbors.rst b/docs/source/python_api/neighbors.rst deleted file mode 100644 index a9914fa44f..0000000000 --- a/docs/source/python_api/neighbors.rst +++ /dev/null @@ -1,19 +0,0 @@ -Nearest Neighbors -================= - -.. role:: py(code) - :language: python - :class: highlight - -.. toctree:: - :maxdepth: 2 - :caption: Contents: - - neighbors_all_neighbors.rst - neighbors_brute_force.rst - neighbors_cagra.rst - neighbors_hnsw.rst - neighbors_ivf_flat.rst - neighbors_ivf_pq.rst - neighbors_multi_gpu.rst - neighbors_nn_decent.rst diff --git a/docs/source/python_api/neighbors_all_neighbors.rst b/docs/source/python_api/neighbors_all_neighbors.rst deleted file mode 100644 index 89ba0f8020..0000000000 --- a/docs/source/python_api/neighbors_all_neighbors.rst +++ /dev/null @@ -1,19 +0,0 @@ -All-Neighbors -============= - -.. role:: py(code) - :language: python - :class: highlight - -All-Neighbors allows building an approximate all-neighbors knn graph. Given a full dataset, it finds nearest neighbors for all the training vectors in the dataset. - -Build Parameters -################ - -.. autoclass:: cuvs.neighbors.all_neighbors.AllNeighborsParams - :members: - -Build -##### - -.. autofunction:: cuvs.neighbors.all_neighbors.build diff --git a/docs/source/python_api/neighbors_brute_force.rst b/docs/source/python_api/neighbors_brute_force.rst deleted file mode 100644 index d756a6c802..0000000000 --- a/docs/source/python_api/neighbors_brute_force.rst +++ /dev/null @@ -1,32 +0,0 @@ -Brute Force KNN -=============== - -.. role:: py(code) - :language: python - :class: highlight - -Index -##### - -.. autoclass:: cuvs.neighbors.brute_force.Index - :members: - -Index build -########### - -.. autofunction:: cuvs.neighbors.brute_force.build - -Index search -############ - -.. autofunction:: cuvs.neighbors.brute_force.search - -Index save -########## - -.. autofunction:: cuvs.neighbors.brute_force.save - -Index load -########## - -.. autofunction:: cuvs.neighbors.brute_force.load diff --git a/docs/source/python_api/neighbors_cagra.rst b/docs/source/python_api/neighbors_cagra.rst deleted file mode 100644 index 42647914f2..0000000000 --- a/docs/source/python_api/neighbors_cagra.rst +++ /dev/null @@ -1,51 +0,0 @@ -CAGRA -===== - -CAGRA is a graph-based nearest neighbors algorithm that was built from the ground up for GPU acceleration. CAGRA demonstrates state-of-the art index build and query performance for both small- and large-batch sized search. - -.. role:: py(code) - :language: python - :class: highlight - -Index build parameters -###################### - -.. autoclass:: cuvs.neighbors.cagra.IndexParams - :members: - -Index search parameters -####################### - -.. autoclass:: cuvs.neighbors.cagra.SearchParams - :members: - -Index -##### - -.. autoclass:: cuvs.neighbors.cagra.Index - :members: - -Index build -########### - -.. autofunction:: cuvs.neighbors.cagra.build - -Index search -############ - -.. autofunction:: cuvs.neighbors.cagra.search - -Index save -########## - -.. autofunction:: cuvs.neighbors.cagra.save - -Index load -########## - -.. autofunction:: cuvs.neighbors.cagra.load - -Index extend -############ - -.. autofunction:: cuvs.neighbors.cagra.extend diff --git a/docs/source/python_api/neighbors_hnsw.rst b/docs/source/python_api/neighbors_hnsw.rst deleted file mode 100644 index 40f3a1de7e..0000000000 --- a/docs/source/python_api/neighbors_hnsw.rst +++ /dev/null @@ -1,45 +0,0 @@ -HNSW -==== - -This is a wrapper for hnswlib, to load a CAGRA index as an immutable HNSW index. The loaded HNSW index is only compatible in cuVS, and can be searched using wrapper functions. - -.. role:: py(code) - :language: python - :class: highlight - -Index search parameters -####################### - -.. autoclass:: cuvs.neighbors.hnsw.SearchParams - :members: - -Index -##### - -.. autoclass:: cuvs.neighbors.hnsw.Index - :members: - -Index Conversion -################ - -.. autofunction:: cuvs.neighbors.hnsw.from_cagra - -Index search -############ - -.. autofunction:: cuvs.neighbors.hnsw.search - -Index save -########## - -.. autofunction:: cuvs.neighbors.hnsw.save - -Index load -########## - -.. autofunction:: cuvs.neighbors.hnsw.load - -Index extend -############ - -.. autofunction:: cuvs.neighbors.hnsw.extend diff --git a/docs/source/python_api/neighbors_ivf_flat.rst b/docs/source/python_api/neighbors_ivf_flat.rst deleted file mode 100644 index d0846b0d67..0000000000 --- a/docs/source/python_api/neighbors_ivf_flat.rst +++ /dev/null @@ -1,49 +0,0 @@ -IVF-Flat -======== - -.. role:: py(code) - :language: python - :class: highlight - -Index build parameters -###################### - -.. autoclass:: cuvs.neighbors.ivf_flat.IndexParams - :members: - -Index search parameters -####################### - -.. autoclass:: cuvs.neighbors.ivf_flat.SearchParams - :members: - -Index -##### - -.. autoclass:: cuvs.neighbors.ivf_flat.Index - :members: - -Index build -########### - -.. autofunction:: cuvs.neighbors.ivf_flat.build - -Index search -############ - -.. autofunction:: cuvs.neighbors.ivf_flat.search - -Index save -########## - -.. autofunction:: cuvs.neighbors.ivf_flat.save - -Index load -########## - -.. autofunction:: cuvs.neighbors.ivf_flat.load - -Index extend -############ - -.. autofunction:: cuvs.neighbors.ivf_flat.extend diff --git a/docs/source/python_api/neighbors_ivf_pq.rst b/docs/source/python_api/neighbors_ivf_pq.rst deleted file mode 100644 index ec4cfdff6a..0000000000 --- a/docs/source/python_api/neighbors_ivf_pq.rst +++ /dev/null @@ -1,49 +0,0 @@ -IVF-PQ -====== - -.. role:: py(code) - :language: python - :class: highlight - -Index build parameters -###################### - -.. autoclass:: cuvs.neighbors.ivf_pq.IndexParams - :members: - -Index search parameters -####################### - -.. autoclass:: cuvs.neighbors.ivf_pq.SearchParams - :members: - -Index -##### - -.. autoclass:: cuvs.neighbors.ivf_pq.Index - :members: - -Index build -########### - -.. autofunction:: cuvs.neighbors.ivf_pq.build - -Index search -############ - -.. autofunction:: cuvs.neighbors.ivf_pq.search - -Index save -########## - -.. autofunction:: cuvs.neighbors.ivf_pq.save - -Index load -########## - -.. autofunction:: cuvs.neighbors.ivf_pq.load - -Index extend -############ - -.. autofunction:: cuvs.neighbors.ivf_pq.extend diff --git a/docs/source/python_api/neighbors_mg_cagra.rst b/docs/source/python_api/neighbors_mg_cagra.rst deleted file mode 100644 index 763e0e2157..0000000000 --- a/docs/source/python_api/neighbors_mg_cagra.rst +++ /dev/null @@ -1,55 +0,0 @@ -Multi-GPU CAGRA -=============== - -Multi-GPU CAGRA extends the graph-based CAGRA algorithm to work across multiple GPUs, providing improved scalability and performance for large-scale vector search. It supports both replicated and sharded distribution modes. - -.. role:: py(code) - :language: python - :class: highlight - -.. note:: - **IMPORTANT**: Multi-GPU CAGRA requires all data (datasets, queries, output arrays) to be in host memory (CPU). - If using CuPy/device arrays, transfer to host with ``array.get()`` or ``cp.asnumpy(array)`` before use. - -Index build parameters -###################### - -.. autoclass:: cuvs.neighbors.mg.cagra.IndexParams - :members: - -Index search parameters -####################### - -.. autoclass:: cuvs.neighbors.mg.cagra.SearchParams - :members: - -Index -##### - -.. autoclass:: cuvs.neighbors.mg.cagra.Index - :members: - -Index build -########### - -.. autofunction:: cuvs.neighbors.mg.cagra.build - -Index search -############ - -.. autofunction:: cuvs.neighbors.mg.cagra.search - -Index save -########## - -.. autofunction:: cuvs.neighbors.mg.cagra.save - -Index load -########## - -.. autofunction:: cuvs.neighbors.mg.cagra.load - -Index distribute -################ - -.. autofunction:: cuvs.neighbors.mg.cagra.distribute diff --git a/docs/source/python_api/neighbors_mg_ivf_flat.rst b/docs/source/python_api/neighbors_mg_ivf_flat.rst deleted file mode 100644 index 68eea86fec..0000000000 --- a/docs/source/python_api/neighbors_mg_ivf_flat.rst +++ /dev/null @@ -1,60 +0,0 @@ -Multi-GPU IVF-Flat -================== - -Multi-GPU IVF-Flat extends the IVF-Flat algorithm to work across multiple GPUs, providing improved scalability and performance for large-scale vector search. It supports both replicated and sharded distribution modes. - -.. role:: py(code) - :language: python - :class: highlight - -.. note:: - **IMPORTANT**: Multi-GPU IVF-Flat requires all data (datasets, queries, output arrays) to be in host memory (CPU). - If using CuPy/device arrays, transfer to host with ``array.get()`` or ``cp.asnumpy(array)`` before use. - -Index build parameters -###################### - -.. autoclass:: cuvs.neighbors.mg.ivf_flat.IndexParams - :members: - -Index search parameters -####################### - -.. autoclass:: cuvs.neighbors.mg.ivf_flat.SearchParams - :members: - -Index -##### - -.. autoclass:: cuvs.neighbors.mg.ivf_flat.Index - :members: - -Index build -########### - -.. autofunction:: cuvs.neighbors.mg.ivf_flat.build - -Index search -############ - -.. autofunction:: cuvs.neighbors.mg.ivf_flat.search - -Index extend -############ - -.. autofunction:: cuvs.neighbors.mg.ivf_flat.extend - -Index save -########## - -.. autofunction:: cuvs.neighbors.mg.ivf_flat.save - -Index load -########## - -.. autofunction:: cuvs.neighbors.mg.ivf_flat.load - -Index distribute -################ - -.. autofunction:: cuvs.neighbors.mg.ivf_flat.distribute diff --git a/docs/source/python_api/neighbors_mg_ivf_pq.rst b/docs/source/python_api/neighbors_mg_ivf_pq.rst deleted file mode 100644 index 8343d59753..0000000000 --- a/docs/source/python_api/neighbors_mg_ivf_pq.rst +++ /dev/null @@ -1,60 +0,0 @@ -Multi-GPU IVF-PQ -================ - -Multi-GPU IVF-PQ extends the IVF-PQ (Inverted File with Product Quantization) algorithm to work across multiple GPUs, providing improved scalability and performance for large-scale vector search. It supports both replicated and sharded distribution modes. - -.. role:: py(code) - :language: python - :class: highlight - -.. note:: - **IMPORTANT**: Multi-GPU IVF-PQ requires all data (datasets, queries, output arrays) to be in host memory (CPU). - If using CuPy/device arrays, transfer to host with ``array.get()`` or ``cp.asnumpy(array)`` before use. - -Index build parameters -###################### - -.. autoclass:: cuvs.neighbors.mg.ivf_pq.IndexParams - :members: - -Index search parameters -####################### - -.. autoclass:: cuvs.neighbors.mg.ivf_pq.SearchParams - :members: - -Index -##### - -.. autoclass:: cuvs.neighbors.mg.ivf_pq.Index - :members: - -Index build -########### - -.. autofunction:: cuvs.neighbors.mg.ivf_pq.build - -Index search -############ - -.. autofunction:: cuvs.neighbors.mg.ivf_pq.search - -Index extend -############ - -.. autofunction:: cuvs.neighbors.mg.ivf_pq.extend - -Index save -########## - -.. autofunction:: cuvs.neighbors.mg.ivf_pq.save - -Index load -########## - -.. autofunction:: cuvs.neighbors.mg.ivf_pq.load - -Index distribute -################ - -.. autofunction:: cuvs.neighbors.mg.ivf_pq.distribute diff --git a/docs/source/python_api/neighbors_multi_gpu.rst b/docs/source/python_api/neighbors_multi_gpu.rst deleted file mode 100644 index bb3a5a07ed..0000000000 --- a/docs/source/python_api/neighbors_multi_gpu.rst +++ /dev/null @@ -1,118 +0,0 @@ -Multi-GPU Nearest Neighbors -=========================== - -Multi-GPU support in cuVS enables scaling ANN (Approximate Nearest Neighbors) algorithms across multiple GPUs on a single node, providing improved performance and the ability to handle larger datasets. - -.. role:: py(code) - :language: python - :class: highlight - -Overview --------- - -The multi-GPU implementations extend the single-GPU algorithms to work across multiple GPUs using two main distribution strategies: - -- **Replicated Mode**: The entire index is replicated across all GPUs. This mode provides higher query throughput by distributing queries across GPUs while maintaining the full index on each GPU. - -- **Sharded Mode**: The index is partitioned (sharded) across GPUs. This mode allows handling larger datasets that don't fit on a single GPU by distributing the data across multiple GPUs. - -Important Notes ---------------- - -.. warning:: - **Memory Requirements**: Multi-GPU algorithms require all data to be in host memory (CPU). This is different from single-GPU algorithms that typically work with device memory. - -.. note:: - **Supported Algorithms**: Currently, multi-GPU support is available for: - - - CAGRA (Graph-based ANN) - - IVF-Flat (Inverted File with Flat storage) - - IVF-PQ (Inverted File with Product Quantization) - - All-neighbors (multi-GPU is built into its unified API via ``MultiGpuResources``) - -Configuration Options ---------------------- - -Distribution Modes -^^^^^^^^^^^^^^^^^^ - -- **Replicated Mode** - - In replicated mode, the complete index is stored on each GPU. This approach: - - - Maximizes query throughput by processing queries in parallel across all GPUs - - Requires each GPU to have enough memory to store the entire index - - Is ideal for scenarios where query throughput is more important than index size limitations - -- **Sharded Mode** - - In sharded mode, the index is distributed across GPUs. This approach: - - - Enables handling of larger datasets by partitioning across GPUs - - Requires coordination between GPUs during search operations - - Is ideal for scenarios where the dataset is too large for a single GPU - -Search Modes -^^^^^^^^^^^^ - -- **Load Balancer** - - Divides each query across multiple GPUs, distributing workload efficiently to maximize performance and throughput. - -- **Round Robin** - - Distributes queries evenly across GPUs in a rotating sequence, ensuring balanced workload allocation. This mode is best suited for frequent, small-scale search operations. - -Merge Modes -^^^^^^^^^^^ - -- **Merge on Root Rank** - - Results from all GPUs are collected and merged on the root rank (typically GPU 0). - -- **Tree Merge** - - Results are merged in a tree-like fashion across GPUs to reduce communication overhead. - -Usage Examples --------------- - -Basic Multi-GPU Usage -^^^^^^^^^^^^^^^^^^^^^^ - -.. code-block:: python - - import numpy as np - from cuvs.neighbors import mg_cagra - - # Create dataset in host memory - n_samples = 100000 - n_features = 128 - dataset = np.random.random_sample((n_samples, n_features), dtype=np.float32) - - # Build multi-GPU index - build_params = mg_cagra.IndexParams( - distribution_mode="sharded", - metric="sqeuclidean" - ) - index = mg_cagra.build(build_params, dataset) - - # Search with multi-GPU - queries = np.random.random_sample((1000, n_features), dtype=np.float32) - search_params = mg_cagra.SearchParams( - search_mode="load_balancer", - merge_mode="merge_on_root_rank" - ) - distances, neighbors = mg_cagra.search(search_params, index, queries, k=10) - -Algorithm-Specific Documentation --------------------------------- - -.. toctree:: - :maxdepth: 2 - :caption: Multi-GPU Algorithms: - - neighbors_all_neighbors.rst - neighbors_mg_cagra.rst - neighbors_mg_ivf_flat.rst - neighbors_mg_ivf_pq.rst diff --git a/docs/source/python_api/neighbors_nn_decent.rst b/docs/source/python_api/neighbors_nn_decent.rst deleted file mode 100644 index 01e9e196c9..0000000000 --- a/docs/source/python_api/neighbors_nn_decent.rst +++ /dev/null @@ -1,24 +0,0 @@ -NN-Descent -========== - -.. role:: py(code) - :language: python - :class: highlight - -Index build parameters -###################### - -.. autoclass:: cuvs.neighbors.nn_descent.IndexParams - :members: - - -Index -##### - -.. autoclass:: cuvs.neighbors.nn_descent.Index - :members: - -Index build -########### - -.. autofunction:: cuvs.neighbors.nn_descent.build diff --git a/docs/source/python_api/preprocessing.rst b/docs/source/python_api/preprocessing.rst deleted file mode 100644 index bbf1337710..0000000000 --- a/docs/source/python_api/preprocessing.rst +++ /dev/null @@ -1,55 +0,0 @@ -Preprocessing -============= - -.. role:: py(code) - :language: python - :class: highlight - -PCA (Principal Component Analysis) -################################### - -.. autoclass:: cuvs.preprocessing.pca.Params - :members: - -.. autofunction:: cuvs.preprocessing.pca.fit - -.. autofunction:: cuvs.preprocessing.pca.fit_transform - -.. autofunction:: cuvs.preprocessing.pca.transform - -.. autofunction:: cuvs.preprocessing.pca.inverse_transform - -Binary Quantizer -################ - -.. autofunction:: cuvs.preprocessing.quantize.binary.transform - -Product Quantizer -################# - -.. autoclass:: cuvs.preprocessing.quantize.pq.Quantizer - :members: - -.. autoclass:: cuvs.preprocessing.quantize.pq.QuantizerParams - :members: - -.. autofunction:: cuvs.preprocessing.quantize.pq.build - -.. autofunction:: cuvs.preprocessing.quantize.pq.transform - -.. autofunction:: cuvs.preprocessing.quantize.pq.inverse_transform - -Scalar Quantizer -################ - -.. autoclass:: cuvs.preprocessing.quantize.scalar.Quantizer - :members: - -.. autoclass:: cuvs.preprocessing.quantize.scalar.QuantizerParams - :members: - -.. autofunction:: cuvs.preprocessing.quantize.scalar.train - -.. autofunction:: cuvs.preprocessing.quantize.scalar.transform - -.. autofunction:: cuvs.preprocessing.quantize.scalar.inverse_transform diff --git a/docs/source/rust_api/index.rst b/docs/source/rust_api/index.rst deleted file mode 100644 index f79d04fdf8..0000000000 --- a/docs/source/rust_api/index.rst +++ /dev/null @@ -1,15 +0,0 @@ -~~~~~~~~~~~~~~~~~~~~~~ -Rust API Documentation -~~~~~~~~~~~~~~~~~~~~~~ - -.. raw:: html - - - - - diff --git a/docs/source/sphinxext/github_link.py b/docs/source/sphinxext/github_link.py deleted file mode 100644 index 1ee5f610b5..0000000000 --- a/docs/source/sphinxext/github_link.py +++ /dev/null @@ -1,154 +0,0 @@ -# This contains code with copyright by the scikit-learn project, subject to the -# license in /thirdparty/LICENSES/LICENSE.scikit_learn -# -# SPDX-FileCopyrightText: Copyright (c) 2024-2025, NVIDIA CORPORATION. -# SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause -# - -import inspect -import os -import re -import subprocess -import sys -from operator import attrgetter - -orig = inspect.isfunction - - -# See https://opendreamkit.org/2017/06/09/CythonSphinx/ -def isfunction(obj): - orig_val = orig(obj) - - new_val = hasattr(type(obj), "__code__") - - if orig_val != new_val: - return new_val - - return orig_val - - -inspect.isfunction = isfunction - -REVISION_CMD = "git rev-parse --short HEAD" - -source_regex = re.compile( - r"^File: (.*?) \(starting at line ([0-9]*?)\)$", re.MULTILINE -) - - -def _get_git_revision(): - try: - revision = subprocess.check_output(REVISION_CMD.split()).strip() - except (subprocess.CalledProcessError, OSError): - print("Failed to execute git to get revision") - return None - return revision.decode("utf-8") - - -def _linkcode_resolve(domain, info, package, url_fmt, revision): - """Determine a link to online source for a class/method/function - - This is called by sphinx.ext.linkcode - - An example with a long-untouched module that everyone has - >>> _linkcode_resolve('py', {'module': 'tty', - ... 'fullname': 'setraw'}, - ... package='tty', - ... url_fmt='http://hg.python.org/cpython/file/' - ... '{revision}/Lib/{package}/{path}#L{lineno}', - ... revision='xxxx') - 'http://hg.python.org/cpython/file/xxxx/Lib/tty/tty.py#L18' - """ - - if revision is None: - return - if domain not in ("py", "pyx"): - return - if not info.get("module") or not info.get("fullname"): - return - - class_name = info["fullname"].split(".")[0] - module = __import__(info["module"], fromlist=[class_name]) - obj = attrgetter(info["fullname"])(module) - - # Unwrap the object to get the correct source - # file in case that is wrapped by a decorator - obj = inspect.unwrap(obj) - - fn: str = None - lineno: str = None - - try: - fn = inspect.getsourcefile(obj) - except Exception: - fn = None - if not fn: - try: - fn = inspect.getsourcefile(sys.modules[obj.__module__]) - except Exception: - fn = None - - if not fn: - # Possibly Cython code. Search docstring for source - m = source_regex.search(obj.__doc__) - - if m is not None: - source_file = m.group(1) - lineno = m.group(2) - - # fn is expected to be the absolute path. - fn = os.path.relpath(source_file, start=package) - print( - "{}:{}".format( - os.path.abspath(os.path.join("..", "python", "cuvs", fn)), - lineno, - ) - ) - else: - return - else: - if fn.endswith(".pyx"): - sp_path = next( - x for x in sys.path if re.match(".*site-packages$", x) - ) - fn = fn.replace("/opt/conda/conda-bld/work/python/cuvs", sp_path) - - # Convert to relative from module root - fn = os.path.relpath( - fn, start=os.path.dirname(__import__(package).__file__) - ) - - # Get the line number if we need it. (Can work without it) - if lineno is None: - try: - lineno = inspect.getsourcelines(obj)[1] - except Exception: - # Can happen if its a cyfunction. See if it has `__code__` - if hasattr(obj, "__code__"): - lineno = obj.__code__.co_firstlineno - else: - lineno = "" - return url_fmt.format( - revision=revision, package=package, path=fn, lineno=lineno - ) - - -def make_linkcode_resolve(package, url_fmt): - """Returns a linkcode_resolve function for the given URL format - - revision is a git commit reference (hash or name) - - package is the name of the root module of the package - - url_fmt is along the lines of ('https://github.com/USER/PROJECT/' - 'blob/{revision}/{package}/' - '{path}#L{lineno}') - """ - revision = _get_git_revision() - - def linkcode_resolve(domain, info): - return _linkcode_resolve( - domain, info, revision=revision, package=package, url_fmt=url_fmt - ) - - return linkcode_resolve diff --git a/docs/source/working_with_ann_indexes.rst b/docs/source/working_with_ann_indexes.rst deleted file mode 100644 index 8e91fb4acd..0000000000 --- a/docs/source/working_with_ann_indexes.rst +++ /dev/null @@ -1,11 +0,0 @@ -Working with ANN Indexes -======================== - -.. toctree:: - :maxdepth: 1 - :caption: Contents: - - working_with_ann_indexes_c.rst - working_with_ann_indexes_cpp.rst - working_with_ann_indexes_python.rst - working_with_ann_indexes_rust.rst diff --git a/docs/source/working_with_ann_indexes_c.rst b/docs/source/working_with_ann_indexes_c.rst deleted file mode 100644 index 1e84141a86..0000000000 --- a/docs/source/working_with_ann_indexes_c.rst +++ /dev/null @@ -1,62 +0,0 @@ -Working with ANN Indexes in C -============================= - -- `Building an index`_ -- `Searching an index`_ - -Building an index ------------------ - -.. code-block:: c - - #include - - cuvsResources_t res; - cuvsCagraIndexParams_t index_params; - cuvsCagraIndex_t index; - - DLManagedTensor *dataset; - - // populate tensor with data - load_dataset(dataset); - - cuvsResourcesCreate(&res); - cuvsCagraIndexParamsCreate(&index_params); - cuvsCagraIndexCreate(&index); - - cuvsCagraBuild(res, index_params, dataset, index); - - cuvsCagraIndexDestroy(index); - cuvsCagraIndexParamsDestroy(index_params); - cuvsResourcesDestroy(res); - - -Searching an index ------------------- - -.. code-block:: c - - #include - - cuvsResources_t res; - cuvsCagraSearchParams_t search_params; - cuvsCagraIndex_t index; - - // ... build index ... - - DLManagedTensor *queries; - - DLManagedTensor *neighbors; - DLManagedTensor *distances; - - // populate tensor with data - load_queries(queries); - - cuvsResourcesCreate(&res); - cuvsCagraSearchParamsCreate(&index_params); - - cuvsCagraSearch(res, search_params, index, queries, neighbors, distances); - - cuvsCagraIndexDestroy(index); - cuvsCagraIndexParamsDestroy(index_params); - cuvsResourcesDestroy(res); diff --git a/docs/source/working_with_ann_indexes_cpp.rst b/docs/source/working_with_ann_indexes_cpp.rst deleted file mode 100644 index 68578bf848..0000000000 --- a/docs/source/working_with_ann_indexes_cpp.rst +++ /dev/null @@ -1,43 +0,0 @@ -Working with ANN Indexes in C++ -=============================== - -- `Building an index`_ -- `Searching an index`_ - -Building an index ------------------ - -.. code-block:: c++ - - #include - - using namespace cuvs::neighbors; - - raft::device_matrix_view dataset = load_dataset(); - raft::device_resources res; - - cagra::index_params index_params; - - auto index = cagra::build(res, index_params, dataset); - - -Searching an index ------------------- - -.. code-block:: c++ - - #include - - using namespace cuvs::neighbors; - cagra::index index; - - // ... build index ... - - raft::device_matrix_view queries = load_queries(); - raft::device_matrix_view neighbors = make_device_matrix_view(n_queries, k); - raft::device_matrix_view distances = make_device_matrix_view(n_queries, k); - raft::device_resources res; - - cagra::search_params search_params; - - cagra::search(res, search_params, index, queries, neighbors, distances); diff --git a/docs/source/working_with_ann_indexes_python.rst b/docs/source/working_with_ann_indexes_python.rst deleted file mode 100644 index 0419c47beb..0000000000 --- a/docs/source/working_with_ann_indexes_python.rst +++ /dev/null @@ -1,33 +0,0 @@ -Working with ANN Indexes in Python -================================== - -- `Building an index`_ -- `Searching an index`_ - -Building an index ------------------ - -.. code-block:: python - - from cuvs.neighbors import cagra - - dataset = load_data() - index_params = cagra.IndexParams() - - index = cagra.build(build_params, dataset) - - -Searching an index ------------------- - -.. code-block:: python - - from cuvs.neighbors import cagra - - queries = load_queries() - - search_params = cagra.SearchParams() - - index = // ... build index ... - - neighbors, distances = cagra.search(search_params, index, queries, k) diff --git a/docs/source/working_with_ann_indexes_rust.rst b/docs/source/working_with_ann_indexes_rust.rst deleted file mode 100644 index 487ad0964b..0000000000 --- a/docs/source/working_with_ann_indexes_rust.rst +++ /dev/null @@ -1,62 +0,0 @@ -Working with ANN Indexes in Rust -================================ - -- `Building and Searching an index`_ - -Building and Searching an index -------------------------------- - -.. code-block:: rust - - use cuvs::cagra::{Index, IndexParams}; - use cuvs::{Resources, Result}; - - use ndarray_rand::rand_distr::Uniform; - use ndarray_rand::RandomExt; - - /// Example showing how to index and search data with CAGRA - fn cagra_example() -> Result<()> { - let res = Resources::new()?; - - // Create a new random dataset to index - let n_datapoints = 65536; - let n_features = 512; - let dataset = - ndarray::Array::::random((n_datapoints, n_features), Uniform::new(0., 1.0)); - - // build the cagra index - let build_params = IndexParams::new()?; - let index = Index::build(&res, &build_params, &dataset)?; - - // use the first 4 points from the dataset as queries : will test that we get them back - // as their own nearest neighbor - let n_queries = 4; - let queries = dataset.slice(s![0..n_queries, ..]); - - let k = 10; - - // CAGRA search API requires queries and outputs to be on device memory - // copy query data over, and allocate new device memory for the distances/ neighbors - // outputs - let queries = ManagedTensor::from(&queries).to_device(&res)?; - let mut neighbors_host = ndarray::Array::::zeros((n_queries, k)); - let neighbors = ManagedTensor::from(&neighbors_host).to_device(&res)?; - - let mut distances_host = ndarray::Array::::zeros((n_queries, k)); - let distances = ManagedTensor::from(&distances_host).to_device(&res)?; - - let search_params = SearchParams::new()?; - - index.search(&res, &search_params, &queries, &neighbors, &distances)?; - - // Copy back to host memory - distances.to_host(&res, &mut distances_host)?; - neighbors.to_host(&res, &mut neighbors_host)?; - - // nearest neighbors should be themselves, since queries are from the - // dataset - println!("Neighbors {:?}", neighbors_host); - println!("Distances {:?}", distances_host); - - Ok(()) - } diff --git a/fern/README.md b/fern/README.md new file mode 100644 index 0000000000..b52918b79f --- /dev/null +++ b/fern/README.md @@ -0,0 +1,37 @@ +# cuVS Fern documentation + +The cuVS documentation lives in this Fern project. Pages are in `fern/pages`, and the sidebar navigation is configured in `fern/docs.yml`. + +The C, C++, Python, Java, Rust, and Go API reference pages are generated from the source tree by `fern/scripts/generate_api_reference.py`. `fern/build_docs.sh` refreshes those pages before validation, preview, and publish runs. + +## Preview locally + +Start the local preview server from the repository root: + +```bash +fern/build_docs.sh dev +``` + +Fern serves the local preview at `http://localhost:3000` by default. + +## Validate + +Run Fern's checks before publishing changes: + +```bash +fern/build_docs.sh check +``` + +## Publish + +Create a Fern preview deployment: + +```bash +fern/build_docs.sh preview +``` + +Publish to the instance configured in `fern/docs.yml` with: + +```bash +fern/build_docs.sh publish +``` diff --git a/fern/assets/rapids_logo.png b/fern/assets/rapids_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..405040836a038441f435499f8fbb2d63a80e1105 GIT binary patch literal 113880 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

ku7-Itg_2b3uwgKN- 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/dev/null 2>&1; then + FERN_CMD=("fern") +else + FERN_CMD=("npx" "--yes" "fern-api") +fi + +run_fern() { + "${FERN_CMD[@]}" "$@" +} + +generate_api_reference() { + python3 "${SCRIPT_DIR}/scripts/generate_api_reference.py" +} + +run_checks() { + pushd "${REPO_DIR}" >/dev/null + run_fern check --warnings + run_fern docs md check + popd >/dev/null +} + +case "${MODE}" in + check) + generate_api_reference + run_checks + ;; + preview) + generate_api_reference + run_checks + pushd "${REPO_DIR}" >/dev/null + run_fern generate --docs --preview "$@" + popd >/dev/null + ;; + publish) + generate_api_reference + run_checks + pushd "${REPO_DIR}" >/dev/null + run_fern generate --docs "$@" + popd >/dev/null + ;; + dev) + generate_api_reference + pushd "${REPO_DIR}" >/dev/null + run_fern docs dev "$@" + popd >/dev/null + ;; + -h|--help|help) + usage + ;; + *) + echo "Unknown mode: ${MODE}" >&2 + echo >&2 + usage >&2 + exit 2 + ;; +esac diff --git a/fern/docs.yml b/fern/docs.yml new file mode 100644 index 0000000000..1de259647c --- /dev/null +++ b/fern/docs.yml @@ -0,0 +1,395 @@ +# yaml-language-server: $schema=https://schema.buildwithfern.dev/docs-yml.json + +title: "cuVS" +instances: + - url: "rapids-cuvs.docs.buildwithfern.com" +logo: + light: "./assets/rapids_logo.png" + dark: "./assets/rapids_logo.png" + href: "https://rapids.ai/" +colors: + accent-primary: + light: "#76B900" + dark: "#A4E600" +check: + rules: + broken-links: "error" +layout: + content-width: "760px" +navbar-links: + - type: "secondary" + text: "GitHub" + url: "https://github.com/rapidsai/cuvs" + - type: "secondary" + text: "RAPIDS" + url: "https://rapids.ai/" +navigation: + - page: "Home" + path: "./pages/index.md" + - page: "Installation" + path: "./pages/build.md" + - section: "Getting Started" + path: "./pages/getting_started.md" + contents: + - page: "Primer on vector search indexes" + path: "./pages/choosing_and_configuring_indexes.md" + - page: "Vector search indexes vs vector databases" + path: "./pages/vector_databases_vs_vector_search.md" + - page: "Automated tuning Guide" + path: "./pages/tuning_guide.md" + - page: "Comparing performance of vector indexes" + path: "./pages/comparing_indexes.md" + - section: "Nearest Neighbor" + path: "./pages/neighbors/neighbors.md" + contents: + - page: "Brute-force" + path: "./pages/neighbors/bruteforce.md" + - page: "CAGRA" + path: "./pages/neighbors/cagra.md" + - page: "IVF-Flat" + path: "./pages/neighbors/ivfflat.md" + - page: "IVF-PQ" + path: "./pages/neighbors/ivfpq.md" + - page: "Vamana" + path: "./pages/neighbors/vamana.md" + - page: "All-neighbors" + path: "./pages/neighbors/all_neighbors.md" + - page: "cuVS API Basics" + path: "./pages/api_basics.md" + - page: "Interoperability" + path: "./pages/api_interoperability.md" + - section: "Working with ANN Indexes" + path: "./pages/working_with_ann_indexes.md" + contents: + - page: "Working with ANN Indexes in C" + path: "./pages/working_with_ann_indexes_c.md" + - page: "Working with ANN Indexes in C++" + path: "./pages/working_with_ann_indexes_cpp.md" + - page: "Working with ANN Indexes in Python" + path: "./pages/working_with_ann_indexes_python.md" + - page: "Working with ANN Indexes in Rust" + path: "./pages/working_with_ann_indexes_rust.md" + - page: "Filtering vector indexes" + path: "./pages/filtering.md" + - section: "Integrations" + path: "./pages/integrations.md" + contents: + - page: "Faiss" + path: "./pages/integrations/faiss.md" + - page: "Milvus" + path: "./pages/integrations/milvus.md" + - page: "Lucene" + path: "./pages/integrations/lucene.md" + - page: "Kinetica" + path: "./pages/integrations/kinetica.md" + - section: "cuVS Bench" + path: "./pages/cuvs_bench/index.md" + contents: + - page: "Build cuVS Bench From Source" + path: "./pages/cuvs_bench/build.md" + - page: "cuVS Bench Datasets" + path: "./pages/cuvs_bench/datasets.md" + - page: "cuVS Bench Parameter Tuning Guide" + path: "./pages/cuvs_bench/param_tuning.md" + - page: "Pluggable Backend" + path: "./pages/cuvs_bench/pluggable_backend.md" + - page: "Wiki-all Dataset" + path: "./pages/cuvs_bench/wiki_all_dataset.md" + - section: "API Reference" + path: "./pages/api_docs.md" + contents: + - section: "C API Documentation" + path: "./pages/c_api/index.md" + contents: + - page: "Cluster Kmeans" + path: "./pages/c_api/c-api-cluster-kmeans.md" + - page: "Core C API" + path: "./pages/c_api/c-api-core-c-api.md" + - page: "Distance Pairwise Distance" + path: "./pages/c_api/c-api-distance-pairwise-distance.md" + - page: "Neighbors All Neighbors" + path: "./pages/c_api/c-api-neighbors-all-neighbors.md" + - page: "Neighbors Brute Force" + path: "./pages/c_api/c-api-neighbors-brute-force.md" + - page: "Neighbors Cagra" + path: "./pages/c_api/c-api-neighbors-cagra.md" + - page: "Neighbors Common" + path: "./pages/c_api/c-api-neighbors-common.md" + - page: "Neighbors HNSW" + path: "./pages/c_api/c-api-neighbors-hnsw.md" + - page: "Neighbors IVF Flat" + path: "./pages/c_api/c-api-neighbors-ivf-flat.md" + - page: "Neighbors IVF PQ" + path: "./pages/c_api/c-api-neighbors-ivf-pq.md" + - page: "Neighbors Multi GPU Cagra" + path: "./pages/c_api/c-api-neighbors-mg-cagra.md" + - page: "Neighbors Multi GPU Common" + path: "./pages/c_api/c-api-neighbors-mg-common.md" + - page: "Neighbors Multi GPU IVF Flat" + path: "./pages/c_api/c-api-neighbors-mg-ivf-flat.md" + - page: "Neighbors Multi GPU IVF PQ" + path: "./pages/c_api/c-api-neighbors-mg-ivf-pq.md" + - page: "Neighbors NN Descent" + path: "./pages/c_api/c-api-neighbors-nn-descent.md" + - page: "Neighbors Refine" + path: "./pages/c_api/c-api-neighbors-refine.md" + - page: "Neighbors Tiered Index" + path: "./pages/c_api/c-api-neighbors-tiered-index.md" + - page: "Neighbors Vamana" + path: "./pages/c_api/c-api-neighbors-vamana.md" + - page: "Preprocessing PCA" + path: "./pages/c_api/c-api-preprocessing-pca.md" + - page: "Preprocessing Quantize Binary" + path: "./pages/c_api/c-api-preprocessing-quantize-binary.md" + - page: "Preprocessing Quantize PQ" + path: "./pages/c_api/c-api-preprocessing-quantize-pq.md" + - page: "Preprocessing Quantize Scalar" + path: "./pages/c_api/c-api-preprocessing-quantize-scalar.md" + - section: "Cpp API Documentation" + path: "./pages/cpp_api/index.md" + contents: + - page: "Cluster Agglomerative" + path: "./pages/cpp_api/cpp-api-cluster-agglomerative.md" + - page: "Cluster Kmeans" + path: "./pages/cpp_api/cpp-api-cluster-kmeans.md" + - page: "Cluster Spectral" + path: "./pages/cpp_api/cpp-api-cluster-spectral.md" + - page: "Distance Distance" + path: "./pages/cpp_api/cpp-api-distance-distance.md" + - page: "Neighbors All Neighbors" + path: "./pages/cpp_api/cpp-api-neighbors-all-neighbors.md" + - page: "Neighbors Ball Cover" + path: "./pages/cpp_api/cpp-api-neighbors-ball-cover.md" + - page: "Neighbors Brute Force" + path: "./pages/cpp_api/cpp-api-neighbors-brute-force.md" + - page: "Neighbors Cagra" + path: "./pages/cpp_api/cpp-api-neighbors-cagra.md" + - page: "Neighbors Common" + path: "./pages/cpp_api/cpp-api-neighbors-common.md" + - page: "Neighbors Dynamic Batching" + path: "./pages/cpp_api/cpp-api-neighbors-dynamic-batching.md" + - page: "Neighbors Epsilon Neighborhood" + path: "./pages/cpp_api/cpp-api-neighbors-epsilon-neighborhood.md" + - page: "Neighbors HNSW" + path: "./pages/cpp_api/cpp-api-neighbors-hnsw.md" + - page: "Neighbors IVF Flat" + path: "./pages/cpp_api/cpp-api-neighbors-ivf-flat.md" + - page: "Neighbors IVF PQ" + path: "./pages/cpp_api/cpp-api-neighbors-ivf-pq.md" + - page: "Neighbors NN Descent" + path: "./pages/cpp_api/cpp-api-neighbors-nn-descent.md" + - page: "Neighbors Refine" + path: "./pages/cpp_api/cpp-api-neighbors-refine.md" + - page: "Neighbors Scann" + path: "./pages/cpp_api/cpp-api-neighbors-scann.md" + - page: "Neighbors Vamana" + path: "./pages/cpp_api/cpp-api-neighbors-vamana.md" + - page: "Preprocessing PCA" + path: "./pages/cpp_api/cpp-api-preprocessing-pca.md" + - page: "Preprocessing Quantize Binary" + path: "./pages/cpp_api/cpp-api-preprocessing-quantize-binary.md" + - page: "Preprocessing Quantize PQ" + path: "./pages/cpp_api/cpp-api-preprocessing-quantize-pq.md" + - page: "Preprocessing Quantize Scalar" + path: "./pages/cpp_api/cpp-api-preprocessing-quantize-scalar.md" + - page: "Preprocessing Spectral Embedding" + path: "./pages/cpp_api/cpp-api-preprocessing-spectral-embedding.md" + - page: "Selection Select K" + path: "./pages/cpp_api/cpp-api-selection-select-k.md" + - page: "Stats Silhouette Score" + path: "./pages/cpp_api/cpp-api-stats-silhouette-score.md" + - page: "Stats Trustworthiness Score" + path: "./pages/cpp_api/cpp-api-stats-trustworthiness-score.md" + - section: "Python API Documentation" + path: "./pages/python_api/index.md" + contents: + - page: "Cluster Kmeans" + path: "./pages/python_api/python-api-cluster-kmeans.md" + - page: "Common" + path: "./pages/python_api/python-api-common.md" + - page: "Distance" + path: "./pages/python_api/python-api-distance.md" + - page: "Neighbors Multi GPU Cagra" + path: "./pages/python_api/python-api-neighbors-mg-cagra.md" + - page: "Neighbors Multi GPU IVF Flat" + path: "./pages/python_api/python-api-neighbors-mg-ivf-flat.md" + - page: "Neighbors Multi GPU IVF PQ" + path: "./pages/python_api/python-api-neighbors-mg-ivf-pq.md" + - page: "Neighbors All Neighbors" + path: "./pages/python_api/python-api-neighbors-all-neighbors.md" + - page: "Neighbors Brute Force" + path: "./pages/python_api/python-api-neighbors-brute-force.md" + - page: "Neighbors Cagra" + path: "./pages/python_api/python-api-neighbors-cagra.md" + - page: "Neighbors Filters" + path: "./pages/python_api/python-api-neighbors-filters.md" + - page: "Neighbors HNSW" + path: "./pages/python_api/python-api-neighbors-hnsw.md" + - page: "Neighbors IVF Flat" + path: "./pages/python_api/python-api-neighbors-ivf-flat.md" + - page: "Neighbors IVF PQ" + path: "./pages/python_api/python-api-neighbors-ivf-pq.md" + - page: "Neighbors NN Descent" + path: "./pages/python_api/python-api-neighbors-nn-descent.md" + - page: "Neighbors" + path: "./pages/python_api/python-api-neighbors.md" + - page: "Neighbors Tiered Index" + path: "./pages/python_api/python-api-neighbors-tiered-index.md" + - page: "Neighbors Vamana" + path: "./pages/python_api/python-api-neighbors-vamana.md" + - page: "Preprocessing Quantize Binary" + path: "./pages/python_api/python-api-preprocessing-quantize-binary.md" + - page: "Preprocessing PCA" + path: "./pages/python_api/python-api-preprocessing-pca.md" + - page: "Preprocessing Quantize PQ" + path: "./pages/python_api/python-api-preprocessing-quantize-pq.md" + - page: "Preprocessing Quantize Scalar" + path: "./pages/python_api/python-api-preprocessing-quantize-scalar.md" + - section: "Java API Documentation" + path: "./pages/java_api/index.md" + contents: + - page: "Com Nvidia cuVS Bruteforceindex" + path: "./pages/java_api/java-api-com-nvidia-cuvs-bruteforceindex.md" + - page: "Com Nvidia cuVS Bruteforceindexparams" + path: "./pages/java_api/java-api-com-nvidia-cuvs-bruteforceindexparams.md" + - page: "Com Nvidia cuVS Bruteforcequery" + path: "./pages/java_api/java-api-com-nvidia-cuvs-bruteforcequery.md" + - page: "Com Nvidia cuVS Cagracompressionparams" + path: "./pages/java_api/java-api-com-nvidia-cuvs-cagracompressionparams.md" + - page: "Com Nvidia cuVS Cagraindex" + path: "./pages/java_api/java-api-com-nvidia-cuvs-cagraindex.md" + - page: "Com Nvidia cuVS Cagraindexparams" + path: "./pages/java_api/java-api-com-nvidia-cuvs-cagraindexparams.md" + - page: "Com Nvidia cuVS Cagramergeparams" + path: "./pages/java_api/java-api-com-nvidia-cuvs-cagramergeparams.md" + - page: "Com Nvidia cuVS Cagraquery" + path: "./pages/java_api/java-api-com-nvidia-cuvs-cagraquery.md" + - page: "Com Nvidia cuVS Cagrasearchparams" + path: "./pages/java_api/java-api-com-nvidia-cuvs-cagrasearchparams.md" + - page: "Com Nvidia cuVS Cuvsaceparams" + path: "./pages/java_api/java-api-com-nvidia-cuvs-cuvsaceparams.md" + - page: "Com Nvidia cuVS Cuvsdevicematrix" + path: "./pages/java_api/java-api-com-nvidia-cuvs-cuvsdevicematrix.md" + - page: "Com Nvidia cuVS Cuvshostmatrix" + path: "./pages/java_api/java-api-com-nvidia-cuvs-cuvshostmatrix.md" + - page: "Com Nvidia cuVS Cuvsivfpqindexparams" + path: "./pages/java_api/java-api-com-nvidia-cuvs-cuvsivfpqindexparams.md" + - page: "Com Nvidia cuVS Cuvsivfpqparams" + path: "./pages/java_api/java-api-com-nvidia-cuvs-cuvsivfpqparams.md" + - page: "Com Nvidia cuVS Cuvsivfpqsearchparams" + path: "./pages/java_api/java-api-com-nvidia-cuvs-cuvsivfpqsearchparams.md" + - page: "Com Nvidia cuVS Cuvsmatrix" + path: "./pages/java_api/java-api-com-nvidia-cuvs-cuvsmatrix.md" + - page: "Com Nvidia cuVS Cuvsresources" + path: "./pages/java_api/java-api-com-nvidia-cuvs-cuvsresources.md" + - page: "Com Nvidia cuVS Cuvsresourcesinfo" + path: "./pages/java_api/java-api-com-nvidia-cuvs-cuvsresourcesinfo.md" + - page: "Com Nvidia cuVS Delegatingscopedaccess" + path: "./pages/java_api/java-api-com-nvidia-cuvs-delegatingscopedaccess.md" + - page: "Com Nvidia cuVS Gpuinfo" + path: "./pages/java_api/java-api-com-nvidia-cuvs-gpuinfo.md" + - page: "Com Nvidia cuVS Gpuinfoprovider" + path: "./pages/java_api/java-api-com-nvidia-cuvs-gpuinfoprovider.md" + - page: "Com Nvidia cuVS Hnswaceparams" + path: "./pages/java_api/java-api-com-nvidia-cuvs-hnswaceparams.md" + - page: "Com Nvidia cuVS Hnswindex" + path: "./pages/java_api/java-api-com-nvidia-cuvs-hnswindex.md" + - page: "Com Nvidia cuVS Hnswindexparams" + path: "./pages/java_api/java-api-com-nvidia-cuvs-hnswindexparams.md" + - page: "Com Nvidia cuVS Hnswquery" + path: "./pages/java_api/java-api-com-nvidia-cuvs-hnswquery.md" + - page: "Com Nvidia cuVS Hnswsearchparams" + path: "./pages/java_api/java-api-com-nvidia-cuvs-hnswsearchparams.md" + - page: "Com Nvidia cuVS Libraryexception" + path: "./pages/java_api/java-api-com-nvidia-cuvs-libraryexception.md" + - page: "Com Nvidia cuVS Rowview" + path: "./pages/java_api/java-api-com-nvidia-cuvs-rowview.md" + - page: "Com Nvidia cuVS Searchresults" + path: "./pages/java_api/java-api-com-nvidia-cuvs-searchresults.md" + - page: "Com Nvidia cuVS Synchronizedcuvsresources" + path: "./pages/java_api/java-api-com-nvidia-cuvs-synchronizedcuvsresources.md" + - page: "Com Nvidia cuVS Tieredindex" + path: "./pages/java_api/java-api-com-nvidia-cuvs-tieredindex.md" + - page: "Com Nvidia cuVS Tieredindexparams" + path: "./pages/java_api/java-api-com-nvidia-cuvs-tieredindexparams.md" + - page: "Com Nvidia cuVS Tieredindexquery" + path: "./pages/java_api/java-api-com-nvidia-cuvs-tieredindexquery.md" + - page: "Com Nvidia cuVS Spi Cuvsprovider" + path: "./pages/java_api/java-api-com-nvidia-cuvs-spi-cuvsprovider.md" + - page: "Com Nvidia cuVS Spi Cuvsserviceprovider" + path: "./pages/java_api/java-api-com-nvidia-cuvs-spi-cuvsserviceprovider.md" + - section: "Rust API Documentation" + path: "./pages/rust_api/index.md" + contents: + - page: "cuVS Cluster" + path: "./pages/rust_api/rust-api-cuvs-cluster.md" + - page: "cuVS Cluster Kmeans" + path: "./pages/rust_api/rust-api-cuvs-cluster-kmeans.md" + - page: "cuVS Cluster Kmeans Params" + path: "./pages/rust_api/rust-api-cuvs-cluster-kmeans-params.md" + - page: "cuVS" + path: "./pages/rust_api/rust-api-cuvs.md" + - page: "cuVS Dlpack" + path: "./pages/rust_api/rust-api-cuvs-dlpack.md" + - page: "cuVS Error" + path: "./pages/rust_api/rust-api-cuvs-error.md" + - page: "cuVS Resources" + path: "./pages/rust_api/rust-api-cuvs-resources.md" + - page: "cuVS Distance" + path: "./pages/rust_api/rust-api-cuvs-distance.md" + - page: "cuVS Distance Type" + path: "./pages/rust_api/rust-api-cuvs-distance-type.md" + - page: "cuVS Brute Force" + path: "./pages/rust_api/rust-api-cuvs-brute-force.md" + - page: "cuVS Cagra" + path: "./pages/rust_api/rust-api-cuvs-cagra.md" + - page: "cuVS Cagra Index" + path: "./pages/rust_api/rust-api-cuvs-cagra-index.md" + - page: "cuVS Cagra Index Params" + path: "./pages/rust_api/rust-api-cuvs-cagra-index-params.md" + - page: "cuVS Cagra Search Params" + path: "./pages/rust_api/rust-api-cuvs-cagra-search-params.md" + - page: "cuVS IVF Flat" + path: "./pages/rust_api/rust-api-cuvs-ivf-flat.md" + - page: "cuVS IVF Flat Index" + path: "./pages/rust_api/rust-api-cuvs-ivf-flat-index.md" + - page: "cuVS IVF Flat Index Params" + path: "./pages/rust_api/rust-api-cuvs-ivf-flat-index-params.md" + - page: "cuVS IVF Flat Search Params" + path: "./pages/rust_api/rust-api-cuvs-ivf-flat-search-params.md" + - page: "cuVS IVF PQ" + path: "./pages/rust_api/rust-api-cuvs-ivf-pq.md" + - page: "cuVS IVF PQ Index" + path: "./pages/rust_api/rust-api-cuvs-ivf-pq-index.md" + - page: "cuVS IVF PQ Index Params" + path: "./pages/rust_api/rust-api-cuvs-ivf-pq-index-params.md" + - page: "cuVS IVF PQ Search Params" + path: "./pages/rust_api/rust-api-cuvs-ivf-pq-search-params.md" + - page: "cuVS Vamana" + path: "./pages/rust_api/rust-api-cuvs-vamana.md" + - page: "cuVS Vamana Index" + path: "./pages/rust_api/rust-api-cuvs-vamana-index.md" + - page: "cuVS Vamana Index Params" + path: "./pages/rust_api/rust-api-cuvs-vamana-index-params.md" + - section: "Go API Documentation" + path: "./pages/go_api/index.md" + contents: + - page: "Brute Force" + path: "./pages/go_api/go-api-brute-force.md" + - page: "Cagra" + path: "./pages/go_api/go-api-cagra.md" + - page: "cuVS" + path: "./pages/go_api/go-api-cuvs.md" + - page: "IVF Flat" + path: "./pages/go_api/go-api-ivf-flat.md" + - page: "IVF PQ" + path: "./pages/go_api/go-api-ivf-pq.md" + - section: "Advanced Topics" + path: "./pages/advanced_topics.md" + contents: + - page: "JIT LTO (Just-In-Time Link-Time Optimization) Guide" + path: "./pages/jit_lto_guide.md" + - page: "Contributing" + path: "./pages/contributing.md" + - page: "Developer Guide" + path: "./pages/developer_guide.md" diff --git a/fern/fern.config.json b/fern/fern.config.json new file mode 100644 index 0000000000..e9ed9b60c1 --- /dev/null +++ b/fern/fern.config.json @@ -0,0 +1,4 @@ +{ + "organization": "rapidsai", + "version": "*" +} diff --git a/fern/pages/advanced_topics.md b/fern/pages/advanced_topics.md new file mode 100644 index 0000000000..80df165891 --- /dev/null +++ b/fern/pages/advanced_topics.md @@ -0,0 +1,14 @@ +# Advanced Topics + +- [Just-in-Time Compilation](#just-in-time-compilation) + +## Just-in-Time Compilation +cuVS uses the Just-in-Time (JIT) [Link-Time Optimization (LTO)](https://developer.nvidia.com/blog/cuda-12-0-compiler-support-for-runtime-lto-using-nvjitlink-library/) compilation technology to compile certain kernels. When a JIT compilation is triggered, cuVS will compile the kernel for your architecture and automatically cache it in-memory and on-disk. The validity of the cache is as follows: + +1. In-memory cache is valid for the lifetime of the process. +2. On-disk cache is valid until a CUDA driver upgrade is performed. The cache can be portably shared between machines in network or cloud storage and we strongly recommend that you store the cache in a persistent location. For more details on how to configure the on-disk cache, look at CUDA documentation on [JIT Compilation](https://docs.nvidia.com/cuda/cuda-programming-guide/05-appendices/environment-variables.html#jit-compilation). Specifically, the environment variables of interest are: `CUDA_CACHE_PATH` and `CUDA_CACHE_MAX_SIZE`. + +Thus, the JIT compilation is a one-time cost and you can expect no loss in real performance after the first compilation. We recommend that you run a "warmup" to trigger the JIT compilation before the actual usage. + +Currently, the following capabilities will trigger a JIT compilation: +- IVF Flat search APIs: [cuvs::neighbors::ivf_flat::search()](/api-reference/cpp-api-neighbors-ivf-flat) diff --git a/fern/pages/api_basics.md b/fern/pages/api_basics.md new file mode 100644 index 0000000000..9350f65fc0 --- /dev/null +++ b/fern/pages/api_basics.md @@ -0,0 +1,80 @@ +# cuVS API Basics + +- [Memory management](#memory-management) +- [Resource management](#resource-management) + +## Memory management + +Centralized memory management allows flexible configuration of allocation strategies, such as sharing the same CUDA memory pool across library boundaries. cuVS uses the [RMM](https://github.com/rapidsai/rmm) library, which eases the burden of configuring different allocation strategies globally across GPU-accelerated libraries. + +RMM currently has APIs for C++ and Python. + +### C++ + +Here's an example of configuring RMM to use a pool allocator in C++ (derived from the RMM example [here](https://github.com/rapidsai/rmm?tab=readme-ov-file#example)): + +```c++ +rmm::mr::cuda_memory_resource cuda_mr; +// Construct a resource that uses a coalescing best-fit pool allocator +// With the pool initially half of available device memory +auto initial_size = rmm::percent_of_free_device_memory(50); +rmm::mr::pool_memory_resource pool_mr{cuda_mr, initial_size}; +rmm::mr::set_current_device_resource(pool_mr); +auto mr = rmm::mr::get_current_device_resource_ref(); +``` + +### Python + +And the corresponding code in Python (derived from the RMM example [here](https://github.com/rapidsai/rmm?tab=readme-ov-file#memoryresource-objects)): + +```python +import rmm +pool = rmm.mr.PoolMemoryResource( + rmm.mr.CudaMemoryResource(), + initial_pool_size=2**30, + maximum_pool_size=2**32) +rmm.mr.set_current_device_resource(pool) +``` + +## Resource management + +cuVS uses an API from the [RAFT](https://github.com/rapidsai/raft) library of ML and data mining primitives to centralize and reuse expensive resources, such as memory management. The below code examples demonstrate how to create these resources for use throughout this guide. + +See RAFT's [resource API documentation](https://docs.rapids.ai/api/raft/nightly/cpp_api/core_resources/) for more information. + +C +^ + +```c +#include +#include + +cuvsResources_t res; +cuvsResourcesCreate(&res); + +// ... do some processing ... + +cuvsResourcesDestroy(res); +``` + +### C++ + +```c++ +#include + +raft::device_resources res; +``` + +### Python + +```python +import pylibraft + +res = pylibraft.common.DeviceResources() +``` + +### Rust + +```rust +let res = cuvs::Resources::new()?; +``` diff --git a/fern/pages/api_docs.md b/fern/pages/api_docs.md new file mode 100644 index 0000000000..2657f41cf0 --- /dev/null +++ b/fern/pages/api_docs.md @@ -0,0 +1,8 @@ +# API Reference + +- [C API Documentation](/api-reference/c-api-documentation) +- [C++ API Documentation](/api-reference/cpp-api-documentation) +- [Python API Documentation](/api-reference/python-api-documentation) +- [Java API Documentation](/api-reference/java-api-documentation) +- [Rust API Documentation](/api-reference/rust-api-documentation) +- [Go API Documentation](/api-reference/go-api-documentation) diff --git a/fern/pages/api_interoperability.md b/fern/pages/api_interoperability.md new file mode 100644 index 0000000000..ee57f24c93 --- /dev/null +++ b/fern/pages/api_interoperability.md @@ -0,0 +1,105 @@ +# Interoperability + +## DLPack (C) + +Approximate nearest neighbor (ANN) indexes provide an interface to build and search an index via a C API. [DLPack v0.8](https://github.com/dmlc/dlpack/blob/main/README.md), a tensor interface framework, is used as the standard to interact with our C API. + +Representing a tensor with DLPack is simple, as it is a POD struct that stores information about the tensor at runtime. At the moment, `DLManagedTensor` from DLPack v0.8 is compatible with out C API however we will soon upgrade to `DLManagedTensorVersioned` from DLPack v1.0 as it will help us maintain ABI and API compatibility. + +Here's an example on how to represent device memory using `DLManagedTensor`: + +```c +#include + +// Create data representation in host memory +float dataset[2][1] = {{0.2, 0.1}}; +// copy data to device memory +float *dataset_dev; +cuvsRMMAlloc(&dataset_dev, sizeof(float) * 2 * 1); +cudaMemcpy(dataset_dev, dataset, sizeof(float) * 2 * 1, cudaMemcpyDefault); + +// Use DLPack for representing the data as a tensor +DLManagedTensor dataset_tensor; +dataset_tensor.dl_tensor.data = dataset; +dataset_tensor.dl_tensor.device.device_type = kDLCUDA; +dataset_tensor.dl_tensor.ndim = 2; +dataset_tensor.dl_tensor.dtype.code = kDLFloat; +dataset_tensor.dl_tensor.dtype.bits = 32; +dataset_tensor.dl_tensor.dtype.lanes = 1; +int64_t dataset_shape[2] = {2, 1}; +dataset_tensor.dl_tensor.shape = dataset_shape; +dataset_tensor.dl_tensor.strides = nullptr; + +// free memory after use +cuvsRMMFree(dataset_dev); +``` + +Please refer to [cuVS C API documentation](/api-reference/c-api-documentation) to learn more. + +## Multi-dimensional span (C++) + +cuVS is built on top of the GPU-accelerated machine learning and data mining primitives in the [RAFT](https://github.com/rapidsai/raft) library. Most of the C++ APIs in cuVS accept [mdspan](https://arxiv.org/abs/2010.06474) multi-dimensional array view for representing data in higher dimensions similar to the `ndarray` in the Numpy Python library. RAFT also contains the corresponding owning `mdarray` structure, which simplifies the allocation and management of multi-dimensional data in both host and device (GPU) memory. + +The `mdarray` is an owning object that forms a convenience layer over RMM and can be constructed in RAFT using a number of different helper functions: + +```c++ +#include + +int n_rows = 10; +int n_cols = 10; + +auto scalar = raft::make_device_scalar(handle, 1.0); +auto vector = raft::make_device_vector(handle, n_cols); +auto matrix = raft::make_device_matrix(handle, n_rows, n_cols); +``` + +The `mdspan` is a lightweight non-owning view that can wrap around any pointer, maintaining shape, layout, and indexing information for accessing elements. + +We can construct `mdspan` instances directly from the above `mdarray` instances: + +```c++ +// Scalar mdspan on device +auto scalar_view = scalar.view(); + +// Vector mdspan on device +auto vector_view = vector.view(); + +// Matrix mdspan on device +auto matrix_view = matrix.view(); +``` + +Since the `mdspan` is just a lightweight wrapper, we can also construct it from the underlying data handles in the `mdarray` instances above. We use the extent to get information about the `mdarray` or `mdspan`'s shape. + +```c++ +#include + +auto scalar_view = raft::make_device_scalar_view(scalar.data_handle()); +auto vector_view = raft::make_device_vector_view(vector.data_handle(), vector.extent(0)); +auto matrix_view = raft::make_device_matrix_view(matrix.data_handle(), matrix.extent(0), matrix.extent(1)); +``` + +Of course, RAFT's `mdspan`/`mdarray` APIs aren't just limited to the `device`. You can also create `host` variants: + +```c++ +#include +#include + +int n_rows = 10; +int n_cols = 10; + +auto scalar = raft::make_host_scalar(handle, 1.0); +auto vector = raft::make_host_vector(handle, n_cols); +auto matrix = raft::make_host_matrix(handle, n_rows, n_cols); + +auto scalar_view = raft::make_host_scalar_view(scalar.data_handle()); +auto vector_view = raft::make_host_vector_view(vector.data_handle(), vector.extent(0)); +auto matrix_view = raft::make_host_matrix_view(matrix.data_handle(), matrix.extent(0), matrix.extent(1)); +``` + +Please refer to RAFT's [mdspan documentation](https://docs.rapids.ai/api/raft/stable/cpp_api/mdspan/) to learn more. + +## CUDA array interface (Python) + +The Python APIs accept objects that expose the CUDA Array Interface, which enables interoperability with GPU array libraries such as CuPy, Numba, PyTorch, and TensorFlow without copying device memory when compatible layouts are used. + +See [Working with ANN Indexes in Python](working_with_ann_indexes_python.md) for examples of building and searching cuVS indexes from Python arrays. diff --git a/fern/pages/build.md b/fern/pages/build.md new file mode 100644 index 0000000000..a5ae9af3fa --- /dev/null +++ b/fern/pages/build.md @@ -0,0 +1,242 @@ +# Installation + +The cuVS software development kit provides APIs for C, C++, Python, and Rust languages. This guide outlines how to install the pre-compiled packages, build it from source, and use it in downstream applications. + +- [Installing pre-compiled packages](#installing-pre-compiled-packages) + + * [C, C++, and Python through Conda](#c-c-and-python-through-conda) + + * [Python through Pip](#python-through-pip) + + * [Tarball](#tarball) + +- [Build from source](#build-from-source) + + * [Prerequisites](#prerequisites) + + * [Create a build environment](#create-a-build-environment) + + * [C and C++ Libraries](#c-and-c-libraries) + + * [Building the Googletests](#building-the-googletests) + + * [Python Library](#python-library) + + * [Rust Library](#rust-library) + + * [Using CMake Directly](#using-cmake-directly) + +- [Build Documentation](#build-documentation) + +## Installing Pre-compiled Packages + +**Note:** The cuVS pre-compiled packages are available for **Linux** only (x86_64 and aarch64 architectures). Native Windows support is not available at this time. On Windows, use **WSL2** with GPU passthrough. See the [RAPIDS WSL2 guide](https://rapids.ai/start.html#wsl2). + +### C, C++, and Python through Conda + +The easiest way to install the pre-compiled C, C++, and Python packages is through conda. You can get a minimal conda installation with [miniforge](https://github.com/conda-forge/miniforge). + +Use the following commands, depending on your CUDA version, to install cuVS packages (replace `rapidsai` with `rapidsai-nightly` to install more up-to-date but less stable nightly packages). `mamba` is preferred over the `conda` command and can be enabled using [this guide](https://conda.github.io/conda-libmamba-solver/user-guide/). + +#### C/C++ Package + +```bash +# CUDA 13 +conda install -c rapidsai -c conda-forge libcuvs cuda-version=13.1 + +# CUDA 12 +conda install -c rapidsai -c conda-forge libcuvs cuda-version=12.9 +``` + +#### Python Package + +```bash +# CUDA 13 +conda install -c rapidsai -c conda-forge cuvs cuda-version=13.1 + +# CUDA 12 +conda install -c rapidsai -c conda-forge cuvs cuda-version=12.9 +``` + +### Python through Pip + +The cuVS Python package can also be [installed through pip](https://docs.rapids.ai/install#pip). + +```bash +# CUDA 13 +pip install cuvs-cu13 --extra-index-url=https://pypi.nvidia.com + +# CUDA 12 +pip install cuvs-cu12 --extra-index-url=https://pypi.nvidia.com +``` + +Note: these packages statically link the C and C++ libraries so the `libcuvs` and `libcuvs_c` shared libraries won't be readily available to use in your code. + +### Tarball + +#### Install Dependencies + +1. [NCCL](https://docs.nvidia.com/deeplearning/nccl/install-guide/index.html) +2. `libopenmp` +3. CUDA Toolkit Runtime 12.2+ +4. Ampere architecture or better (compute capability >= 8.0) + +#### Download & Extract + +Download the pre-built tarball for your CPU architecture and CUDA version from +[https://developer.nvidia.com/cuvs-downloads](https://developer.nvidia.com/cuvs-downloads) + +Untar the tarball into a directory. + +```bash +tar -xzvf libcuvs-linux-sbsa-26.02.00.189485_cuda12-archive.tar.xz -C /path/to/folder +``` + +Add cuVS to your system library load path. This should be done in the appropriate profile configuration (for e.g. `.bashrc`, `.bash_profile`) to maintain the setting across sessions. + +```bash +export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/path/to/folder +``` + +## Build from source + +The core cuVS source code is written in C++ and wrapped through a C API. The C API is wrapped around the C++ APIs and the other supported languages are built around the C API. + +### Prerequisites + +- CMake 3.26.4+ +- GCC 9.3+ (11.4+ recommended) +- CUDA Toolkit 12.2+ +- Ampere architecture or better (compute capability >= 8.0) + +### Create a build environment + +Conda environment scripts are provided for installing the necessary dependencies to build cuVS from source. It is preferred to use `mamba`, as it provides significant speedup over `conda`: + +```bash +conda env create --name cuvs -f conda/environments/all_cuda-131_arch-$(uname -m).yaml +conda activate cuvs +``` + +The recommended way to build and install cuVS from source is to use the `build.sh` script in the root of the repository. This script can build both the C++ and Python artifacts and provides CMake options for building and installing the headers, tests, benchmarks, and the pre-compiled shared library. + +### C and C++ libraries + +The C and C++ shared libraries are built together using the following arguments to `build.sh`: + +```bash +./build.sh libcuvs +``` + +In above example the `libcuvs.so` and `libcuvs_c.so` shared libraries are installed by default into `$INSTALL_PREFIX/lib`. To disable this, pass `-n` flag. + +Once installed, the shared libraries, headers (and any dependencies downloaded and installed via `rapids-cmake`) can be uninstalled using `build.sh`: + +```bash +./build.sh libcuvs --uninstall +``` + +### Multi-GPU features + +To disable the multi-gpu features run : + +```bash +./build.sh libcuvs --no-mg +``` + +#### Building the Googletests + +Compile the C and C++ Googletests using the `tests` target in `build.sh`. + +```bash +./build.sh libcuvs tests +``` + +The tests will be written to the build directory, which is `cpp/build/` by default, and they will be named `*_TEST`. + +It can take some time to compile all of the tests. You can build individual tests by providing a semicolon-separated list to the `--limit-tests` option in `build.sh`. Make sure to pass the `-n` flag so the tests are not installed. + +```bash +./build.sh libcuvs tests -n --limit-tests=NEIGHBORS_TEST;CAGRA_C_TEST +``` + +### Python library + +The Python library should be built and installed using the `build.sh` script: + +```bash +./build.sh python +``` + +The Python packages can also be uninstalled using the `build.sh` script: + +```bash +./build.sh python --uninstall +``` + +### Go library + +After building the C and C++ libraries, the Golang library can be built with the following command: + +```bash +export CUDA_HOME="/usr/local/cuda" # or wherever your CUDA installation is. +export CGO_CFLAGS="-I${CONDA_PREFIX}/include -I${CUDA_HOME}/include" +export CGO_LDFLAGS="-L${CONDA_PREFIX}/lib -lcuvs -lcuvs_c" +export LD_LIBRARY_PATH="$CONDA_PREFIX/lib:$LD_LIBRARY_PATH" +export CC=clang + +./build.sh go +``` + +### Rust library + +The Rust bindings can be built with + +```bash +./build.sh rust +``` + +### Using CMake directly + +When building cuVS from source, the `build.sh` script offers a nice wrapper around the `cmake` commands to ease the burdens of manually configuring the various available cmake options. When more fine-grained control over the CMake configuration is desired, the `cmake` command can be invoked directly as the below example demonstrates. + +The `CMAKE_INSTALL_PREFIX` installs cuVS into a specific location. The example below installs cuVS into the current Conda environment: + +```bash +cd cpp +mkdir build +cd build +cmake -D BUILD_TESTS=ON -DCMAKE_INSTALL_PREFIX=$CONDA_PREFIX ../ +make -j install +``` + +cuVS has the following configurable cmake flags available: + +**CMake Flags** + +| Flag | Possible Values | Default Value | Behavior | +| --- | --- | --- | --- | +| BUILD_TESTS | ON, OFF | ON | Compile Googletests | +| CUDA_ENABLE_KERNELINFO | ON, OFF | OFF | Enables `kernelinfo` in nvcc. This is useful for `compute-sanitizer` | +| CUDA_ENABLE_LINEINFO | ON, OFF | OFF | Enable the `-lineinfo` option for nvcc | +| CUDA_STATIC_MATH_LIBRARIES | ON, OFF | OFF | Statically link the CUDA math libraries | +| DETECT_CONDA_ENV | ON, OFF | ON | Enable detection of conda environment for dependencies | +| CUVS_NVTX | ON, OFF | OFF | Enable NVTX markers | + +### Preview documentation + +The cuVS documentation is a Fern project in the repository's `fern` directory. Install the Fern CLI, then run the local preview from the repository root: + +```bash +npm install -g fern-api +fern docs dev +``` + +Fern serves the preview at [http://localhost:3000](http://localhost:3000) by default. + +Run the Fern checks before publishing documentation changes: + +```bash +fern check --warnings --strict-broken-links +fern docs md check +``` diff --git a/fern/pages/c_api/c-api-cluster-kmeans.md b/fern/pages/c_api/c-api-cluster-kmeans.md new file mode 100644 index 0000000000..e915e49df1 --- /dev/null +++ b/fern/pages/c_api/c-api-cluster-kmeans.md @@ -0,0 +1,216 @@ +--- +slug: api-reference/c-api-cluster-kmeans +--- + +# K-Means + +_Source header: `c/include/cuvs/cluster/kmeans.h`_ + +## k-means hyperparameters + +_Doxygen group: `kmeans_c_params`_ + +### cuvsKMeansInitMethod + +k-means hyperparameters + +```c +typedef enum { ... } cuvsKMeansInitMethod; +``` + +**Values** + +| Name | Value | +| --- | --- | +| `KMeansPlusPlus` | `0` | +| `Random` | `1` | +| `Array` | `2` | + +_Source: `c/include/cuvs/cluster/kmeans.h:22`_ + +### cuvsKMeansParams + +Hyper-parameters for the kmeans algorithm + +```c +struct cuvsKMeansParams { ... } ; +``` + +**Fields** + +| Name | Type | Description | +| --- | --- | --- | +| `n_clusters` | `int` | The number of clusters to form as well as the number of centroids to generate (default:8). | +| `init` | `cuvsKMeansInitMethod` | Method for initialization, defaults to k-means++: | +| `max_iter` | `int` | Maximum number of iterations of the k-means algorithm for a single run. | +| `tol` | `double` | Relative tolerance with regards to inertia to declare convergence. | +| `n_init` | `int` | Number of instance k-means algorithm will be run with different seeds. | +| `oversampling_factor` | `double` | Oversampling factor for use in the k-means\|\| algorithm | +| `batch_samples` | `int` | batch_samples and batch_centroids are used to tile 1NN computation which is | +| `batch_centroids` | `int` | if 0 then batch_centroids = n_clusters | +| `inertia_check` | `bool` | Check inertia during iterations for early convergence. | +| `hierarchical` | `bool` | Whether to use hierarchical (balanced) kmeans or not | +| `hierarchical_n_iters` | `int` | For hierarchical k-means , defines the number of training iterations | +| `streaming_batch_size` | `int64_t` | Number of samples to process per GPU batch for the batched (host-data) API. | +| `metric` | `cuvsDistanceType` | | + +_Source: `c/include/cuvs/cluster/kmeans.h:43`_ + +### cuvsKMeansParamsCreate + +Allocate KMeans params, and populate with default values + +```c +cuvsError_t cuvsKMeansParamsCreate(cuvsKMeansParams_t* params); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `params` | in | `cuvsKMeansParams_t*` | cuvsKMeansParams_t to allocate | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/cluster/kmeans.h:122`_ + +### cuvsKMeansParamsDestroy + +De-allocate KMeans params + +```c +cuvsError_t cuvsKMeansParamsDestroy(cuvsKMeansParams_t params); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `params` | in | `cuvsKMeansParams_t` | | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/cluster/kmeans.h:130`_ + +### cuvsKMeansType + +Type of k-means algorithm. + +```c +typedef enum { ... } cuvsKMeansType; +``` + +**Values** + +| Name | Value | +| --- | --- | +| `CUVS_KMEANS_TYPE_KMEANS` | `0` | +| `CUVS_KMEANS_TYPE_KMEANS_BALANCED` | `1` | + +_Source: `c/include/cuvs/cluster/kmeans.h:135`_ + +## k-means clustering APIs + +_Doxygen group: `kmeans_c`_ + +### cuvsKMeansFit + +Find clusters with k-means algorithm. + +```c +cuvsError_t cuvsKMeansFit(cuvsResources_t res, +cuvsKMeansParams_t params, +DLManagedTensor* X, +DLManagedTensor* sample_weight, +DLManagedTensor* centroids, +double* inertia, +int* n_iter); +``` + +Initial centroids are chosen with k-means++ algorithm. Empty clusters are reinitialized by choosing new centroids with k-means++ algorithm. X may reside on either host (CPU) or device (GPU) memory. When X is on the host the data is streamed to the GPU in batches controlled by params->streaming_batch_size. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | opaque C handle | +| `params` | in | `cuvsKMeansParams_t` | Parameters for KMeans model. | +| `X` | in | `DLManagedTensor*` | Training instances to cluster. The data must be in row-major format. May be on host or device memory. [dim = n_samples x n_features] | +| `sample_weight` | in | `DLManagedTensor*` | Optional weights for each observation in X. Must be on the same memory space as X. [len = n_samples] | +| `centroids` | inout | `DLManagedTensor*` | [in] When init is InitMethod::Array, use centroids as the initial cluster centers. [out] The generated centroids from the kmeans algorithm are stored at the address pointed by 'centroids'. Must be on device. [dim = n_clusters x n_features] | +| `inertia` | out | `double*` | Sum of squared distances of samples to their closest cluster center. | +| `n_iter` | out | `int*` | Number of iterations run. | + +**Returns** + +`cuvsError_t` + +_Source: `c/include/cuvs/cluster/kmeans.h:176`_ + +### cuvsKMeansPredict + +Predict the closest cluster each sample in X belongs to. + +```c +cuvsError_t cuvsKMeansPredict(cuvsResources_t res, +cuvsKMeansParams_t params, +DLManagedTensor* X, +DLManagedTensor* sample_weight, +DLManagedTensor* centroids, +DLManagedTensor* labels, +bool normalize_weight, +double* inertia); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | opaque C handle | +| `params` | in | `cuvsKMeansParams_t` | Parameters for KMeans model. | +| `X` | in | `DLManagedTensor*` | New data to predict. [dim = n_samples x n_features] | +| `sample_weight` | in | `DLManagedTensor*` | Optional weights for each observation in X. [len = n_samples] | +| `centroids` | in | `DLManagedTensor*` | Cluster centroids. The data must be in row-major format. [dim = n_clusters x n_features] | +| `labels` | out | `DLManagedTensor*` | Index of the cluster each sample in X belongs to. [len = n_samples] | +| `normalize_weight` | in | `bool` | True if the weights should be normalized | +| `inertia` | out | `double*` | Sum of squared distances of samples to their closest cluster center. | + +**Returns** + +`cuvsError_t` + +_Source: `c/include/cuvs/cluster/kmeans.h:203`_ + +### cuvsKMeansClusterCost + +Compute cluster cost + +```c +cuvsError_t cuvsKMeansClusterCost(cuvsResources_t res, +DLManagedTensor* X, +DLManagedTensor* centroids, +double* cost); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | opaque C handle | +| `X` | in | `DLManagedTensor*` | Training instances to cluster. The data must be in row-major format. [dim = n_samples x n_features] | +| `centroids` | in | `DLManagedTensor*` | Cluster centroids. The data must be in row-major format. [dim = n_clusters x n_features] | +| `cost` | out | `double*` | Resulting cluster cost | + +**Returns** + +`cuvsError_t` + +_Source: `c/include/cuvs/cluster/kmeans.h:225`_ diff --git a/fern/pages/c_api/c-api-core-c-api.md b/fern/pages/c_api/c-api-core-c-api.md new file mode 100644 index 0000000000..ce8274fee9 --- /dev/null +++ b/fern/pages/c_api/c-api-core-c-api.md @@ -0,0 +1,577 @@ +--- +slug: api-reference/c-api-core-c-api +--- + +# C API + +_Source header: `c/include/cuvs/core/c_api.h`_ + +## cuVS Error Messages + +_Doxygen group: `error_c`_ + +### cuvsError_t + +An enum denoting error statuses for function calls + +```c +typedef enum { ... } cuvsError_t; +``` + +**Values** + +| Name | Value | +| --- | --- | +| `CUVS_ERROR` | `0` | +| `CUVS_SUCCESS` | `1` | + +_Source: `c/include/cuvs/core/c_api.h:25`_ + +### cuvsGetLastErrorText + +Returns a string describing the last seen error on this thread, or + +```c +const char* cuvsGetLastErrorText(); +``` + +NULL if the last function succeeded. + +**Returns** + +`const char*` + +_Source: `c/include/cuvs/core/c_api.h:30`_ + +### cuvsSetLastErrorText + +Sets a string describing an error seen on the thread. Passing NULL + +```c +void cuvsSetLastErrorText(const char* error); +``` + +clears any previously seen error message. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `error` | | `const char*` | | + +**Returns** + +`void` + +_Source: `c/include/cuvs/core/c_api.h:36`_ + +## cuVS Logging + +_Doxygen group: `log_c`_ + +### cuvsLogLevel_t + +An enum denoting log levels + +```c +typedef enum { ... } cuvsLogLevel_t; +``` + +**Values** + +| Name | Value | +| --- | --- | +| `CUVS_LOG_LEVEL_TRACE` | `0` | +| `CUVS_LOG_LEVEL_DEBUG` | `1` | +| `CUVS_LOG_LEVEL_INFO` | `2` | +| `CUVS_LOG_LEVEL_WARN` | `3` | +| `CUVS_LOG_LEVEL_ERROR` | `4` | +| `CUVS_LOG_LEVEL_CRITICAL` | `5` | +| `CUVS_LOG_LEVEL_OFF` | `6` | + +_Source: `c/include/cuvs/core/c_api.h:49`_ + +### cuvsGetLogLevel + +Returns the current log level + +```c +cuvsLogLevel_t cuvsGetLogLevel(); +``` + +**Returns** + +`cuvsLogLevel_t` + +_Source: `c/include/cuvs/core/c_api.h:61`_ + +### cuvsSetLogLevel + +Sets the log level + +```c +void cuvsSetLogLevel(cuvsLogLevel_t); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `arg1` | | `cuvsLogLevel_t` | | + +**Returns** + +`void` + +_Source: `c/include/cuvs/core/c_api.h:65`_ + +## cuVS Resources Handle + +_Doxygen group: `resources_c`_ + +### cuvsResourcesCreate + +Create an Initialized opaque C handle for C++ type `raft::resources` + +```c +cuvsError_t cuvsResourcesCreate(cuvsResources_t* res); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t*` | cuvsResources_t opaque C handle | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/core/c_api.h:86`_ + +### cuvsResourcesDestroy + +Destroy and de-allocate opaque C handle for C++ type `raft::resources` + +```c +cuvsError_t cuvsResourcesDestroy(cuvsResources_t res); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/core/c_api.h:94`_ + +### cuvsStreamSet + +Set cudaStream_t on cuvsResources_t to queue CUDA kernels on APIs + +```c +cuvsError_t cuvsStreamSet(cuvsResources_t res, cudaStream_t stream); +``` + +that accept a cuvsResources_t handle + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `stream` | in | `cudaStream_t` | cudaStream_t stream to queue CUDA kernels | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/core/c_api.h:104`_ + +### cuvsStreamGet + +Get the cudaStream_t from a cuvsResources_t + +```c +cuvsError_t cuvsStreamGet(cuvsResources_t res, cudaStream_t* stream); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `stream` | out | `cudaStream_t*` | cudaStream_t stream to queue CUDA kernels | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/core/c_api.h:113`_ + +### cuvsStreamSync + +Syncs the current CUDA stream on the resources object + +```c +cuvsError_t cuvsStreamSync(cuvsResources_t res); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/core/c_api.h:121`_ + +### cuvsDeviceIdGet + +Get the id of the device associated with this cuvsResources_t + +```c +cuvsError_t cuvsDeviceIdGet(cuvsResources_t res, int* device_id); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `device_id` | out | `int*` | int the id of the device associated with res | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/core/c_api.h:130`_ + +### cuvsMultiGpuResourcesCreate + +Create an Initialized opaque C handle for C++ type `raft::device_resources_snmg` + +```c +cuvsError_t cuvsMultiGpuResourcesCreate(cuvsResources_t* res); +``` + +for multi-GPU operations + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t*` | cuvsResources_t opaque C handle | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/core/c_api.h:139`_ + +### cuvsMultiGpuResourcesCreateWithDeviceIds + +Create an Initialized opaque C handle for C++ type `raft::device_resources_snmg` + +```c +cuvsError_t cuvsMultiGpuResourcesCreateWithDeviceIds(cuvsResources_t* res, +DLManagedTensor* device_ids); +``` + +for multi-GPU operations with specific device IDs + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t*` | cuvsResources_t opaque C handle | +| `device_ids` | in | `DLManagedTensor*` | DLManagedTensor* containing device IDs to use | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/core/c_api.h:149`_ + +### cuvsMultiGpuResourcesDestroy + +Destroy and de-allocate opaque C handle for C++ type `raft::device_resources_snmg` + +```c +cuvsError_t cuvsMultiGpuResourcesDestroy(cuvsResources_t res); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/core/c_api.h:158`_ + +### cuvsMultiGpuResourcesSetMemoryPool + +Set a memory pool on all devices managed by the multi-GPU resources + +```c +cuvsError_t cuvsMultiGpuResourcesSetMemoryPool(cuvsResources_t res, int percent_of_free_memory); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle for multi-GPU resources | +| `percent_of_free_memory` | in | `int` | Percent of free memory to allocate for the pool | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/core/c_api.h:167`_ + +## cuVS Memory Allocation + +_Doxygen group: `memory_c`_ + +### cuvsRMMAlloc + +Allocates device memory using RMM + +```c +cuvsError_t cuvsRMMAlloc(cuvsResources_t res, void** ptr, size_t bytes); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `ptr` | out | `void**` | Pointer to allocated device memory | +| `bytes` | in | `size_t` | Size in bytes to allocate | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/core/c_api.h:184`_ + +### cuvsRMMFree + +Deallocates device memory using RMM + +```c +cuvsError_t cuvsRMMFree(cuvsResources_t res, void* ptr, size_t bytes); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `ptr` | in | `void*` | Pointer to allocated device memory to free | +| `bytes` | in | `size_t` | Size in bytes to allocate | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/core/c_api.h:194`_ + +### cuvsRMMPoolMemoryResourceEnable + +Switches the working memory resource to use the RMM pool memory resource, which will + +```c +cuvsError_t cuvsRMMPoolMemoryResourceEnable(int initial_pool_size_percent, +int max_pool_size_percent, +bool managed); +``` + +bypass unnecessary synchronizations by allocating a chunk of device memory up front and carving that up for temporary memory allocations within algorithms. Be aware that this function will change the memory resource for the whole process and the new memory resource will be used until explicitly changed. available memory available memory + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `initial_pool_size_percent` | in | `int` | The initial pool size as a percentage of the total | +| `max_pool_size_percent` | in | `int` | The maximum pool size as a percentage of the total | +| `managed` | in | `bool` | Whether to use a managed memory resource as upstream resource or not | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/core/c_api.h:210`_ + +### cuvsRMMMemoryResourceReset + +Resets the memory resource to use the default memory resource (cuda_memory_resource) + +```c +cuvsError_t cuvsRMMMemoryResourceReset(); +``` + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/core/c_api.h:217`_ + +### cuvsRMMHostAlloc + +Allocates pinned memory on the host using RMM + +```c +cuvsError_t cuvsRMMHostAlloc(void** ptr, size_t bytes); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `ptr` | out | `void**` | Pointer to allocated host memory | +| `bytes` | in | `size_t` | Size in bytes to allocate | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/core/c_api.h:225`_ + +### cuvsRMMHostFree + +Deallocates pinned memory on the host using RMM + +```c +cuvsError_t cuvsRMMHostFree(void* ptr, size_t bytes); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `ptr` | in | `void*` | Pointer to allocated host memory to free | +| `bytes` | in | `size_t` | Size in bytes to deallocate | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/core/c_api.h:233`_ + +### cuvsVersionGet + +Get the version of the cuVS library + +```c +cuvsError_t cuvsVersionGet(uint16_t* major, uint16_t* minor, uint16_t* patch); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `major` | out | `uint16_t*` | Major version | +| `minor` | out | `uint16_t*` | Minor version | +| `patch` | out | `uint16_t*` | Patch version | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/core/c_api.h:242`_ + +### cuvsMatrixCopy + +Copy a matrix + +```c +cuvsError_t cuvsMatrixCopy(cuvsResources_t res, DLManagedTensor* src, DLManagedTensor* dst); +``` + +This function copies a matrix from dst to src. This lets you copy a matrix from device memory to host memory (or vice versa), while accounting for differences in strides. Both src and dst must have the same shape and dtype, but can have different strides and device type. The memory for the output dst tensor must already be allocated and the tensor initialized. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `src` | in | `DLManagedTensor*` | Pointer to DLManagedTensor to copy | +| `dst` | out | `DLManagedTensor*` | Pointer to DLManagedTensor to receive copy of data | + +**Returns** + +`cuvsError_t` + +_Source: `c/include/cuvs/core/c_api.h:259`_ + +### cuvsMatrixSliceRows + +Slices rows from a matrix + +```c +cuvsError_t cuvsMatrixSliceRows( +cuvsResources_t res, DLManagedTensor* src, int64_t start, int64_t end, DLManagedTensor* dst); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `src` | in | `DLManagedTensor*` | Pointer to DLManagedTensor to copy | +| `start` | in | `int64_t` | First row index to include in the output | +| `end` | in | `int64_t` | Last row index to include in the output | +| `dst` | out | `DLManagedTensor*` | Pointer to DLManagedTensor to receive slice from matrix | + +**Returns** + +`cuvsError_t` + +_Source: `c/include/cuvs/core/c_api.h:270`_ diff --git a/fern/pages/c_api/c-api-distance-pairwise-distance.md b/fern/pages/c_api/c-api-distance-pairwise-distance.md new file mode 100644 index 0000000000..7cf5a0d060 --- /dev/null +++ b/fern/pages/c_api/c-api-distance-pairwise-distance.md @@ -0,0 +1,43 @@ +--- +slug: api-reference/c-api-distance-pairwise-distance +--- + +# Pairwise Distance + +_Source header: `c/include/cuvs/distance/pairwise_distance.h`_ + +## C pairwise distance + +_Doxygen group: `pairwise_distance_c`_ + +### cuvsPairwiseDistance + +Compute pairwise distances for two matrices + +```c +cuvsError_t cuvsPairwiseDistance(cuvsResources_t res, +DLManagedTensor* x, +DLManagedTensor* y, +DLManagedTensor* dist, +cuvsDistanceType metric, +float metric_arg); +``` + +Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | cuvs resources object for managing expensive resources | +| `x` | in | `DLManagedTensor*` | first set of points (size n*k) | +| `y` | in | `DLManagedTensor*` | second set of points (size m*k) | +| `dist` | out | `DLManagedTensor*` | output distance matrix (size n*m) | +| `metric` | in | `cuvsDistanceType` | distance to evaluate | +| `metric_arg` | in | `float` | metric argument (used for Minkowski distance) | + +**Returns** + +`cuvsError_t` + +_Source: `c/include/cuvs/distance/pairwise_distance.h:48`_ diff --git a/fern/pages/c_api/c-api-neighbors-all-neighbors.md b/fern/pages/c_api/c-api-neighbors-all-neighbors.md new file mode 100644 index 0000000000..c6c2fa7b66 --- /dev/null +++ b/fern/pages/c_api/c-api-neighbors-all-neighbors.md @@ -0,0 +1,132 @@ +--- +slug: api-reference/c-api-neighbors-all-neighbors +--- + +# All Neighbors + +_Source header: `c/include/cuvs/neighbors/all_neighbors.h`_ + +## All-neighbors C-API build parameters + +_Doxygen group: `all_neighbors_c_params`_ + +### cuvsAllNeighborsAlgo + +Graph build algorithm selection. + +```c +typedef enum { ... } cuvsAllNeighborsAlgo; +``` + +**Values** + +| Name | Value | +| --- | --- | +| `CUVS_ALL_NEIGHBORS_ALGO_BRUTE_FORCE` | `0` | +| `CUVS_ALL_NEIGHBORS_ALGO_IVF_PQ` | `1` | +| `CUVS_ALL_NEIGHBORS_ALGO_NN_DESCENT` | `2` | + +_Source: `c/include/cuvs/neighbors/all_neighbors.h:38`_ + +### cuvsAllNeighborsIndexParams + +Parameters controlling SNMG all-neighbors build. + +```c +struct cuvsAllNeighborsIndexParams { ... } ; +``` + +**Fields** + +| Name | Type | Description | +| --- | --- | --- | +| `algo` | `cuvsAllNeighborsAlgo` | | +| `overlap_factor` | `size_t` | | +| `n_clusters` | `size_t` | | +| `metric` | `cuvsDistanceType` | | +| `ivf_pq_params` | `cuvsIvfPqIndexParams_t` | | +| `nn_descent_params` | `cuvsNNDescentIndexParams_t` | | + +_Source: `c/include/cuvs/neighbors/all_neighbors.h:47`_ + +### cuvsAllNeighborsIndexParamsCreate + +Create a default all-neighbors index parameters struct. + +```c +cuvsError_t cuvsAllNeighborsIndexParamsCreate(cuvsAllNeighborsIndexParams_t* index_params); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `index_params` | out | `cuvsAllNeighborsIndexParams_t*` | Pointer to allocated index_params struct | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/all_neighbors.h:70`_ + +### cuvsAllNeighborsIndexParamsDestroy + +Destroy an all-neighbors index parameters struct. + +```c +cuvsError_t cuvsAllNeighborsIndexParamsDestroy(cuvsAllNeighborsIndexParams_t index_params); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `index_params` | in | `cuvsAllNeighborsIndexParams_t` | Index parameters struct to destroy | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/all_neighbors.h:79`_ + +## All-neighbors C-API build + +_Doxygen group: `all_neighbors_c_build`_ + +### cuvsAllNeighborsBuild + +Build an all-neighbors k-NN graph automatically detecting host vs device dataset. + +```c +cuvsError_t cuvsAllNeighborsBuild(cuvsResources_t res, +cuvsAllNeighborsIndexParams_t params, +DLManagedTensor* dataset, +DLManagedTensor* indices, +DLManagedTensor* distances, +DLManagedTensor* core_distances, +float alpha); +``` + +resources The function automatically detects whether the dataset is host-resident or device-resident and calls the appropriate implementation. For host datasets, it partitions data into `n_clusters` clusters and assigns each row to `overlap_factor` nearest clusters. For device datasets, `n_clusters` must be 1 (no batching); `overlap_factor` is ignored. Outputs always reside in device memory. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | Can be a SNMG multi-GPU resources (`cuvsResources_t`) or single-GPU | +| `params` | in | `cuvsAllNeighborsIndexParams_t` | Build parameters (see cuvsAllNeighborsIndexParams) | +| `dataset` | in | `DLManagedTensor*` | 2D tensor [num_rows x dim] on host or device (auto-detected) | +| `indices` | out | `DLManagedTensor*` | 2D tensor [num_rows x k] on device (int64) | +| `distances` | out | `DLManagedTensor*` | Optional 2D tensor [num_rows x k] on device (float32); can be NULL | +| `core_distances` | out | `DLManagedTensor*` | Optional 1D tensor [num_rows] on device (float32); can be NULL | +| `alpha` | in | `float` | Mutual-reachability scaling; used only when core_distances is provided | + +**Returns** + +`cuvsError_t` + +_Source: `c/include/cuvs/neighbors/all_neighbors.h:106`_ diff --git a/fern/pages/c_api/c-api-neighbors-brute-force.md b/fern/pages/c_api/c-api-neighbors-brute-force.md new file mode 100644 index 0000000000..a1f948ed2f --- /dev/null +++ b/fern/pages/c_api/c-api-neighbors-brute-force.md @@ -0,0 +1,181 @@ +--- +slug: api-reference/c-api-neighbors-brute-force +--- + +# Brute Force + +_Source header: `c/include/cuvs/neighbors/brute_force.h`_ + +## Bruteforce index + +_Doxygen group: `bruteforce_c_index`_ + +### cuvsBruteForceIndexCreate + +Allocate BRUTEFORCE index + +```c +cuvsError_t cuvsBruteForceIndexCreate(cuvsBruteForceIndex_t* index); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `index` | in | `cuvsBruteForceIndex_t*` | cuvsBruteForceIndex_t to allocate | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/brute_force.h:39`_ + +### cuvsBruteForceIndexDestroy + +De-allocate BRUTEFORCE index + +```c +cuvsError_t cuvsBruteForceIndexDestroy(cuvsBruteForceIndex_t index); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `index` | in | `cuvsBruteForceIndex_t` | cuvsBruteForceIndex_t to de-allocate | + +**Returns** + +`cuvsError_t` + +_Source: `c/include/cuvs/neighbors/brute_force.h:46`_ + +## Bruteforce index build + +_Doxygen group: `bruteforce_c_index_build`_ + +### cuvsBruteForceBuild + +Build a BRUTEFORCE index with a `DLManagedTensor` which has underlying + +```c +cuvsError_t cuvsBruteForceBuild(cuvsResources_t res, +DLManagedTensor* dataset, +cuvsDistanceType metric, +float metric_arg, +cuvsBruteForceIndex_t index); +``` + +`DLDeviceType` equal to `kDLCUDA`, `kDLCUDAHost`, `kDLCUDAManaged`, or `kDLCPU`. Also, acceptable underlying types are: 1. `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 32` 2. `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 16` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `dataset` | in | `DLManagedTensor*` | DLManagedTensor* training dataset | +| `metric` | in | `cuvsDistanceType` | metric | +| `metric_arg` | in | `float` | metric_arg | +| `index` | out | `cuvsBruteForceIndex_t` | cuvsBruteForceIndex_t Newly built BRUTEFORCE index | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/brute_force.h:92`_ + +## Bruteforce index search + +_Doxygen group: `bruteforce_c_index_search`_ + +### cuvsBruteForceSearch + +Search a BRUTEFORCE index with a `DLManagedTensor` which has underlying + +```c +cuvsError_t cuvsBruteForceSearch(cuvsResources_t res, +cuvsBruteForceIndex_t index, +DLManagedTensor* queries, +DLManagedTensor* neighbors, +DLManagedTensor* distances, +cuvsFilter prefilter); +``` + +`DLDeviceType` equal to `kDLCUDA`, `kDLCUDAHost`, `kDLCUDAManaged`. It is also important to note that the BRUTEFORCE index must have been built with the same type of `queries`, such that `index.dtype.code == queries.dl_tensor.dtype.code` Types for input are: 1. `queries`: `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 32` or `kDLDataType.bits = 16` 2. `neighbors`: `kDLDataType.code == kDLUInt` and `kDLDataType.bits = 32` 3. `distances`: `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 32` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `index` | in | `cuvsBruteForceIndex_t` | cuvsBruteForceIndex which has been returned by `cuvsBruteForceBuild` | +| `queries` | in | `DLManagedTensor*` | DLManagedTensor* queries dataset to search | +| `neighbors` | out | `DLManagedTensor*` | DLManagedTensor* output `k` neighbors for queries | +| `distances` | out | `DLManagedTensor*` | DLManagedTensor* output `k` distances for queries | +| `prefilter` | in | `cuvsFilter` | cuvsFilter input prefilter that can be used to filter queries and neighbors based on the given bitmap. | + +**Returns** + +`cuvsError_t` + +_Source: `c/include/cuvs/neighbors/brute_force.h:148`_ + +## BRUTEFORCE C-API serialize functions + +_Doxygen group: `bruteforce_c_index_serialize`_ + +### cuvsBruteForceSerialize + +Save the index to file. + +```c +cuvsError_t cuvsBruteForceSerialize(cuvsResources_t res, +const char* filename, +cuvsBruteForceIndex_t index); +``` + +The serialization format can be subject to changes, therefore loading an index saved with a previous version of cuvs is not guaranteed to work. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `filename` | in | `const char*` | the file name for saving the index | +| `index` | in | `cuvsBruteForceIndex_t` | BRUTEFORCE index | + +**Returns** + +`cuvsError_t` + +_Source: `c/include/cuvs/neighbors/brute_force.h:184`_ + +### cuvsBruteForceDeserialize + +Load index from file. + +```c +cuvsError_t cuvsBruteForceDeserialize(cuvsResources_t res, +const char* filename, +cuvsBruteForceIndex_t index); +``` + +The serialization format can be subject to changes, therefore loading an index saved with a previous version of cuvs is not guaranteed to work. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `filename` | in | `const char*` | the name of the file that stores the index | +| `index` | out | `cuvsBruteForceIndex_t` | BRUTEFORCE index loaded disk | + +**Returns** + +`cuvsError_t` + +_Source: `c/include/cuvs/neighbors/brute_force.h:211`_ diff --git a/fern/pages/c_api/c-api-neighbors-cagra.md b/fern/pages/c_api/c-api-neighbors-cagra.md new file mode 100644 index 0000000000..38a2cb8882 --- /dev/null +++ b/fern/pages/c_api/c-api-neighbors-cagra.md @@ -0,0 +1,867 @@ +--- +slug: api-reference/c-api-neighbors-cagra +--- + +# Cagra + +_Source header: `c/include/cuvs/neighbors/cagra.h`_ + +## C API for CUDA ANN Graph-based nearest neighbor search + +_Doxygen group: `cagra_c_index_params`_ + +### cuvsCagraGraphBuildAlgo + +Enum to denote which ANN algorithm is used to build CAGRA graph + +```c +enum cuvsCagraGraphBuildAlgo { ... } ; +``` + +**Values** + +| Name | Value | +| --- | --- | +| `AUTO_SELECT` | `0` | +| `IVF_PQ` | `1` | + +_Source: `c/include/cuvs/neighbors/cagra.h:29`_ + +### cuvsCagraHnswHeuristicType + +A strategy for selecting the graph build parameters based on similar HNSW index + +parameters. Define how cuvsCagraIndexParamsFromHnswParams should construct a graph to construct a graph that is to be converted to (used by) a CPU HNSW index. + +```c +enum cuvsCagraHnswHeuristicType { ... } ; +``` + +_Source: `c/include/cuvs/neighbors/cagra.h:54`_ + +### cuvsCagraCompressionParams + +Parameters for VPQ compression. + +```c +struct cuvsCagraCompressionParams { ... } ; +``` + +**Fields** + +| Name | Type | Description | +| --- | --- | --- | +| `pq_bits` | `uint32_t` | The bit length of the vector element after compression by PQ. | +| `pq_dim` | `uint32_t` | The dimensionality of the vector after compression by PQ. | +| `vq_n_centers` | `uint32_t` | Vector Quantization (VQ) codebook size - number of "coarse cluster centers". | +| `kmeans_n_iters` | `uint32_t` | The number of iterations searching for kmeans centers (both VQ & PQ phases). | +| `vq_kmeans_trainset_fraction` | `double` | The fraction of data to use during iterative kmeans building (VQ phase). | +| `pq_kmeans_trainset_fraction` | `double` | The fraction of data to use during iterative kmeans building (PQ phase). | + +_Source: `c/include/cuvs/neighbors/cagra.h:82`_ + +### cuvsAceParams + +Parameters for ACE (Augmented Core Extraction) graph build. + +ACE enables building indexes for datasets too large to fit in GPU memory by: 1. Partitioning the dataset in core (closest) and augmented (second-closest) partitions using balanced k-means. 2. Building sub-indexes for each partition independently 3. Concatenating sub-graphs into a final unified index + +```c +struct cuvsAceParams { ... } ; +``` + +**Fields** + +| Name | Type | Description | +| --- | --- | --- | +| `npartitions` | `size_t` | Number of partitions for ACE (Augmented Core Extraction) partitioned build. | +| `ef_construction` | `size_t` | The index quality for the ACE build. | +| `build_dir` | `const char*` | Directory to store ACE build artifacts (e.g., KNN graph, optimized graph). | +| `use_disk` | `bool` | Whether to use disk-based storage for ACE build. | +| `max_host_memory_gb` | `double` | Maximum host memory to use for ACE build in GiB. | +| `max_gpu_memory_gb` | `double` | Maximum GPU memory to use for ACE build in GiB. | + +_Source: `c/include/cuvs/neighbors/cagra.h:136`_ + +### cuvsCagraIndexParams + +Supplemental parameters to build CAGRA Index + +```c +struct cuvsCagraIndexParams { ... } ; +``` + +**Fields** + +| Name | Type | Description | +| --- | --- | --- | +| `metric` | `cuvsDistanceType` | Distance type. | +| `intermediate_graph_degree` | `size_t` | Degree of input graph for pruning. | +| `graph_degree` | `size_t` | Degree of output graph. | +| `build_algo` | `enum cuvsCagraGraphBuildAlgo` | ANN algorithm to build knn graph. | +| `nn_descent_niter` | `size_t` | Number of Iterations to run if building with NN_DESCENT | +| `compression` | `cuvsCagraCompressionParams_t` | Optional: specify compression parameters if compression is desired. | +| `graph_build_params` | `void*` | Optional: specify graph build params based on build_algo | + +_Source: `c/include/cuvs/neighbors/cagra.h:201`_ + +### cuvsCagraIndexParamsCreate + +Allocate CAGRA Index params, and populate with default values + +```c +cuvsError_t cuvsCagraIndexParamsCreate(cuvsCagraIndexParams_t* params); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `params` | in | `cuvsCagraIndexParams_t*` | cuvsCagraIndexParams_t to allocate | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/cagra.h:235`_ + +### cuvsCagraIndexParamsDestroy + +De-allocate CAGRA Index params + +```c +cuvsError_t cuvsCagraIndexParamsDestroy(cuvsCagraIndexParams_t params); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `params` | in | `cuvsCagraIndexParams_t` | | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/cagra.h:243`_ + +### cuvsCagraCompressionParamsCreate + +Allocate CAGRA Compression params, and populate with default values + +```c +cuvsError_t cuvsCagraCompressionParamsCreate(cuvsCagraCompressionParams_t* params); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `params` | in | `cuvsCagraCompressionParams_t*` | cuvsCagraCompressionParams_t to allocate | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/cagra.h:251`_ + +### cuvsCagraCompressionParamsDestroy + +De-allocate CAGRA Compression params + +```c +cuvsError_t cuvsCagraCompressionParamsDestroy(cuvsCagraCompressionParams_t params); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `params` | in | `cuvsCagraCompressionParams_t` | | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/cagra.h:259`_ + +### cuvsAceParamsCreate + +Allocate ACE params, and populate with default values + +```c +cuvsError_t cuvsAceParamsCreate(cuvsAceParams_t* params); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `params` | in | `cuvsAceParams_t*` | cuvsAceParams_t to allocate | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/cagra.h:267`_ + +### cuvsAceParamsDestroy + +De-allocate ACE params + +```c +cuvsError_t cuvsAceParamsDestroy(cuvsAceParams_t params); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `params` | in | `cuvsAceParams_t` | | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/cagra.h:275`_ + +### cuvsCagraIndexParamsFromHnswParams + +Create CAGRA index parameters similar to an HNSW index + +```c +cuvsError_t cuvsCagraIndexParamsFromHnswParams(cuvsCagraIndexParams_t params, +int64_t n_rows, +int64_t dim, +int M, +int ef_construction, +enum cuvsCagraHnswHeuristicType heuristic, +cuvsDistanceType metric); +``` + +This factory function creates CAGRA parameters that yield a graph compatible with an HNSW graph with the given parameters. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `params` | out | `cuvsCagraIndexParams_t` | The CAGRA index params to populate | +| `n_rows` | in | `int64_t` | Number of rows in the dataset | +| `dim` | in | `int64_t` | Number of dimensions in the dataset | +| `M` | in | `int` | HNSW index parameter M | +| `ef_construction` | in | `int` | HNSW index parameter ef_construction | +| `heuristic` | in | `enum cuvsCagraHnswHeuristicType` | Strategy for parameter selection | +| `metric` | in | `cuvsDistanceType` | Distance metric to use | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/cagra.h:292`_ + +## C API for CUDA ANN Graph-based nearest neighbor search + +_Doxygen group: `cagra_c_extend_params`_ + +### cuvsCagraExtendParams + +Supplemental parameters to extend CAGRA Index + +```c +struct cuvsCagraExtendParams { ... } ; +``` + +**Fields** + +| Name | Type | Description | +| --- | --- | --- | +| `max_chunk_size` | `uint32_t` | The additional dataset is divided into chunks and added to the graph. This is the knob to | + +_Source: `c/include/cuvs/neighbors/cagra.h:312`_ + +### cuvsCagraExtendParamsCreate + +Allocate CAGRA Extend params, and populate with default values + +```c +cuvsError_t cuvsCagraExtendParamsCreate(cuvsCagraExtendParams_t* params); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `params` | in | `cuvsCagraExtendParams_t*` | cuvsCagraExtendParams_t to allocate | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/cagra.h:329`_ + +### cuvsCagraExtendParamsDestroy + +De-allocate CAGRA Extend params + +```c +cuvsError_t cuvsCagraExtendParamsDestroy(cuvsCagraExtendParams_t params); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `params` | in | `cuvsCagraExtendParams_t` | | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/cagra.h:337`_ + +### cuvsCagraExtend + +Extend a CAGRA index with a `DLManagedTensor` which has underlying + +```c +cuvsError_t cuvsCagraExtend(cuvsResources_t res, +cuvsCagraExtendParams_t params, +DLManagedTensor* additional_dataset, +cuvsCagraIndex_t index); +``` + +`DLDeviceType` equal to `kDLCUDA`, `kDLCUDAHost`, `kDLCUDAManaged`, or `kDLCPU`. Also, acceptable underlying types are: 1. `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 32` 2. `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 16` 3. `kDLDataType.code == kDLInt` and `kDLDataType.bits = 8` 4. `kDLDataType.code == kDLUInt` and `kDLDataType.bits = 8` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `params` | in | `cuvsCagraExtendParams_t` | cuvsCagraExtendParams_t used to extend CAGRA index | +| `additional_dataset` | in | `DLManagedTensor*` | DLManagedTensor* additional dataset | +| `index` | in,out | `cuvsCagraIndex_t` | cuvsCagraIndex_t CAGRA index | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/cagra.h:644`_ + +## C API for CUDA ANN Graph-based nearest neighbor search + +_Doxygen group: `cagra_c_search_params`_ + +### cuvsCagraSearchAlgo + +Enum to denote algorithm used to search CAGRA Index + +```c +enum cuvsCagraSearchAlgo { ... } ; +``` + +**Values** + +| Name | Value | +| --- | --- | +| `SINGLE_CTA` | `0` | +| `MULTI_CTA` | `1` | +| `MULTI_KERNEL` | `2` | +| `AUTO` | `100` | + +_Source: `c/include/cuvs/neighbors/cagra.h:352`_ + +### cuvsCagraHashMode + +Enum to denote Hash Mode used while searching CAGRA index + +```c +enum cuvsCagraHashMode { ... } ; +``` + +**Values** + +| Name | Value | +| --- | --- | +| `HASH` | `0` | +| `SMALL` | `1` | +| `AUTO_HASH` | `100` | + +_Source: `c/include/cuvs/neighbors/cagra.h:365`_ + +### cuvsCagraSearchParams + +Supplemental parameters to search CAGRA index + +```c +struct cuvsCagraSearchParams { ... } ; +``` + +**Fields** + +| Name | Type | Description | +| --- | --- | --- | +| `max_queries` | `size_t` | Maximum number of queries to search at the same time (batch size). Auto select when 0. | +| `itopk_size` | `size_t` | Number of intermediate search results retained during the search. | +| `max_iterations` | `size_t` | Upper limit of search iterations. Auto select when 0. | +| `algo` | `enum cuvsCagraSearchAlgo` | Which search implementation to use. | +| `team_size` | `size_t` | Number of threads used to calculate a single distance. 4, 8, 16, or 32. | +| `search_width` | `size_t` | Number of graph nodes to select as the starting point for the search in each iteration. aka | +| `min_iterations` | `size_t` | Lower limit of search iterations. | +| `thread_block_size` | `size_t` | Thread block size. 0, 64, 128, 256, 512, 1024. Auto selection when 0. | +| `hashmap_mode` | `enum cuvsCagraHashMode` | Hashmap type. Auto selection when AUTO. | +| `hashmap_min_bitlen` | `size_t` | Lower limit of hashmap bit length. More than 8. | +| `hashmap_max_fill_rate` | `float` | Upper limit of hashmap fill rate. More than 0.1, less than 0.9. | +| `num_random_samplings` | `uint32_t` | Number of iterations of initial random seed node selection. 1 or more. | +| `rand_xor_mask` | `uint64_t` | Bit mask used for initial random seed node selection. | +| `persistent` | `bool` | Whether to use the persistent version of the kernel (only SINGLE_CTA is supported a.t.m.) | +| `persistent_lifetime` | `float` | Persistent kernel: time in seconds before the kernel stops if no requests received. | +| `persistent_device_usage` | `float` | Set the fraction of maximum grid size used by persistent kernel. | + +_Source: `c/include/cuvs/neighbors/cagra.h:371`_ + +### cuvsCagraSearchParamsCreate + +Allocate CAGRA search params, and populate with default values + +```c +cuvsError_t cuvsCagraSearchParamsCreate(cuvsCagraSearchParams_t* params); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `params` | in | `cuvsCagraSearchParams_t*` | cuvsCagraSearchParams_t to allocate | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/cagra.h:447`_ + +### cuvsCagraSearchParamsDestroy + +De-allocate CAGRA search params + +```c +cuvsError_t cuvsCagraSearchParamsDestroy(cuvsCagraSearchParams_t params); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `params` | in | `cuvsCagraSearchParams_t` | | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/cagra.h:455`_ + +## C API for CUDA ANN Graph-based nearest neighbor search + +_Doxygen group: `cagra_c_index`_ + +### cuvsCagraIndexCreate + +Allocate CAGRA index + +```c +cuvsError_t cuvsCagraIndexCreate(cuvsCagraIndex_t* index); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `index` | in | `cuvsCagraIndex_t*` | cuvsCagraIndex_t to allocate | + +**Returns** + +`cuvsError_t` + +cagraError_t + +_Source: `c/include/cuvs/neighbors/cagra.h:484`_ + +### cuvsCagraIndexDestroy + +De-allocate CAGRA index + +```c +cuvsError_t cuvsCagraIndexDestroy(cuvsCagraIndex_t index); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `index` | in | `cuvsCagraIndex_t` | cuvsCagraIndex_t to de-allocate | + +**Returns** + +`cuvsError_t` + +_Source: `c/include/cuvs/neighbors/cagra.h:491`_ + +### cuvsCagraIndexGetDims + +Get dimension of the CAGRA index + +```c +cuvsError_t cuvsCagraIndexGetDims(cuvsCagraIndex_t index, int64_t* dim); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `index` | in | `cuvsCagraIndex_t` | CAGRA index | +| `dim` | out | `int64_t*` | return dimension of the index | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/cagra.h:500`_ + +### cuvsCagraIndexGetSize + +Get size of the CAGRA index + +```c +cuvsError_t cuvsCagraIndexGetSize(cuvsCagraIndex_t index, int64_t* size); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `index` | in | `cuvsCagraIndex_t` | CAGRA index | +| `size` | out | `int64_t*` | return number of vectors in the index | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/cagra.h:509`_ + +### cuvsCagraIndexGetGraphDegree + +Get graph degree of the CAGRA index + +```c +cuvsError_t cuvsCagraIndexGetGraphDegree(cuvsCagraIndex_t index, int64_t* graph_degree); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `index` | in | `cuvsCagraIndex_t` | CAGRA index | +| `graph_degree` | out | `int64_t*` | return graph degree | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/cagra.h:518`_ + +### cuvsCagraIndexGetDataset + +Returns a view of the CAGRA dataset + +```c +cuvsError_t cuvsCagraIndexGetDataset(cuvsCagraIndex_t index, DLManagedTensor* dataset); +``` + +This function returns a non-owning view of the CAGRA dataset. The output will be referencing device memory that is directly used in CAGRA, without copying the dataset at all. This means that the output is only valid as long as the CAGRA index is alive, and once cuvsCagraIndexDestroy is called on the cagra index - the returned dataset view will be invalid. Note that the DLManagedTensor dataset returned will have an associated 'deleter' function that must be called when the dataset is no longer needed. This will free up host memory that stores the shape of the dataset view. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `index` | in | `cuvsCagraIndex_t` | CAGRA index | +| `dataset` | out | `DLManagedTensor*` | the dataset used in cagra | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/cagra.h:539`_ + +### cuvsCagraIndexGetGraph + +Returns a view of the CAGRA graph + +```c +cuvsError_t cuvsCagraIndexGetGraph(cuvsCagraIndex_t index, DLManagedTensor* graph); +``` + +This function returns a non-owning view of the CAGRA graph. The output will be referencing device memory that is directly used in CAGRA, without copying the graph at all. This means that the output is only valid as long as the CAGRA index is alive, and once cuvsCagraIndexDestroy is called on the cagra index - the returned graph view will be invalid. Note that the DLManagedTensor graph returned will have an associated 'deleter' function that must be called when the graph is no longer needed. This will free up host memory that stores the metadata for the graph view. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `index` | in | `cuvsCagraIndex_t` | CAGRA index | +| `graph` | out | `DLManagedTensor*` | the output knn graph. | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/cagra.h:560`_ + +## C API for CUDA ANN Graph-based nearest neighbor search + +_Doxygen group: `cagra_c_index_build`_ + +### cuvsCagraBuild + +Build a CAGRA index with a `DLManagedTensor` which has underlying + +```c +cuvsError_t cuvsCagraBuild(cuvsResources_t res, +cuvsCagraIndexParams_t params, +DLManagedTensor* dataset, +cuvsCagraIndex_t index); +``` + +`DLDeviceType` equal to `kDLCUDA`, `kDLCUDAHost`, `kDLCUDAManaged`, or `kDLCPU`. Also, acceptable underlying types are: 1. `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 32` 2. `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 16` 3. `kDLDataType.code == kDLInt` and `kDLDataType.bits = 8` 4. `kDLDataType.code == kDLUInt` and `kDLDataType.bits = 8` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `params` | in | `cuvsCagraIndexParams_t` | cuvsCagraIndexParams_t used to build CAGRA index | +| `dataset` | in | `DLManagedTensor*` | DLManagedTensor* training dataset | +| `index` | inout | `cuvsCagraIndex_t` | cuvsCagraIndex_t Newly built CAGRA index. This index needs to be already created with cuvsCagraIndexCreate. | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/cagra.h:615`_ + +## C API for CUDA ANN Graph-based nearest neighbor search + +_Doxygen group: `cagra_c_index_search`_ + +### cuvsCagraSearch + +Search a CAGRA index with a `DLManagedTensor` which has underlying + +```c +cuvsError_t cuvsCagraSearch(cuvsResources_t res, +cuvsCagraSearchParams_t params, +cuvsCagraIndex_t index, +DLManagedTensor* queries, +DLManagedTensor* neighbors, +DLManagedTensor* distances, +cuvsFilter filter); +``` + +`DLDeviceType` equal to `kDLCUDA`, `kDLCUDAHost`, `kDLCUDAManaged`. It is also important to note that the CAGRA Index must have been built with the same type of `queries`, such that `index.dtype.code == queries.dl_tensor.dtype.code` Types for input are: 1. `queries`: a. `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 32` b. `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 16` c. `kDLDataType.code == kDLInt` and `kDLDataType.bits = 8` d. `kDLDataType.code == kDLUInt` and `kDLDataType.bits = 8` 2. `neighbors`: `kDLDataType.code == kDLUInt` and `kDLDataType.bits = 32` or `kDLDataType.code == kDLInt` and `kDLDataType.bits = 64` 3. `distances`: `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 32` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `params` | in | `cuvsCagraSearchParams_t` | cuvsCagraSearchParams_t used to search CAGRA index | +| `index` | in | `cuvsCagraIndex_t` | cuvsCagraIndex which has been returned by `cuvsCagraBuild` | +| `queries` | in | `DLManagedTensor*` | DLManagedTensor* queries dataset to search | +| `neighbors` | out | `DLManagedTensor*` | DLManagedTensor* output `k` neighbors for queries | +| `distances` | out | `DLManagedTensor*` | DLManagedTensor* output `k` distances for queries | +| `filter` | in | `cuvsFilter` | cuvsFilter input filter that can be used to filter queries and neighbors based on the given bitset. | + +**Returns** + +`cuvsError_t` + +_Source: `c/include/cuvs/neighbors/cagra.h:707`_ + +## CAGRA C-API serialize functions + +_Doxygen group: `cagra_c_index_serialize`_ + +### cuvsCagraSerialize + +Save the index to file. + +```c +cuvsError_t cuvsCagraSerialize(cuvsResources_t res, +const char* filename, +cuvsCagraIndex_t index, +bool include_dataset); +``` + +Experimental, both the API and the serialization format are subject to change. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `filename` | in | `const char*` | the file name for saving the index | +| `index` | in | `cuvsCagraIndex_t` | CAGRA index | +| `include_dataset` | in | `bool` | Whether or not to write out the dataset to the file. | + +**Returns** + +`cuvsError_t` + +_Source: `c/include/cuvs/neighbors/cagra.h:745`_ + +### cuvsCagraSerializeToHnswlib + +Save the CAGRA index to file in hnswlib format. + +```c +cuvsError_t cuvsCagraSerializeToHnswlib(cuvsResources_t res, +const char* filename, +cuvsCagraIndex_t index); +``` + +NOTE: The saved index can only be read by the hnswlib wrapper in cuVS, as the serialization format is not compatible with the original hnswlib. Experimental, both the API and the serialization format are subject to change. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `filename` | in | `const char*` | the file name for saving the index | +| `index` | in | `cuvsCagraIndex_t` | CAGRA index | + +**Returns** + +`cuvsError_t` + +_Source: `c/include/cuvs/neighbors/cagra.h:774`_ + +### cuvsCagraDeserialize + +Load index from file. + +```c +cuvsError_t cuvsCagraDeserialize(cuvsResources_t res, const char* filename, cuvsCagraIndex_t index); +``` + +Experimental, both the API and the serialization format are subject to change. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `filename` | in | `const char*` | the name of the file that stores the index | +| `index` | inout | `cuvsCagraIndex_t` | cuvsCagraIndex_t CAGRA index loaded from disk. This index needs to be already created with cuvsCagraIndexCreate. | + +**Returns** + +`cuvsError_t` + +_Source: `c/include/cuvs/neighbors/cagra.h:788`_ + +### cuvsCagraIndexFromArgs + +Load index from a dataset and graph + +```c +cuvsError_t cuvsCagraIndexFromArgs(cuvsResources_t res, +cuvsDistanceType metric, +DLManagedTensor* graph, +DLManagedTensor* dataset, +cuvsCagraIndex_t index); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `metric` | in | `cuvsDistanceType` | cuvsDistanceType to use in the index | +| `graph` | in | `DLManagedTensor*` | the knn graph to use, shape (size, graph_degree) | +| `dataset` | in | `DLManagedTensor*` | the dataset to use, shape (size, dim) | +| `index` | inout | `cuvsCagraIndex_t` | cuvsCagraIndex_t CAGRA index populated with the graph and dataset. This index needs to be already created with cuvsCagraIndexCreate. | + +**Returns** + +`cuvsError_t` + +_Source: `c/include/cuvs/neighbors/cagra.h:824`_ + +## CAGRA C-API merge functions + +_Doxygen group: `cagra_c_index_merge`_ + +### cuvsCagraMerge + +Merge multiple CAGRA indices into a single CAGRA index. + +```c +cuvsError_t cuvsCagraMerge(cuvsResources_t res, +cuvsCagraIndexParams_t params, +cuvsCagraIndex_t* indices, +size_t num_indices, +cuvsFilter filter, +cuvsCagraIndex_t output_index); +``` + +All input indices must have been built with the same data type (`index.dtype`) and have the same dimensionality (`index.dims`). The merged index uses the output parameters specified in `cuvsCagraIndexParams`. Input indices must have: - `index.dtype.code` and `index.dtype.bits` matching across all indices. - Supported data types for indices: a. `kDLFloat` with `bits = 32` b. `kDLFloat` with `bits = 16` c. `kDLInt` with `bits = 8` d. `kDLUInt` with `bits = 8` The resulting output index will have the same data type as the input indices. Example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `params` | in | `cuvsCagraIndexParams_t` | cuvsCagraIndexParams_t parameters controlling merge behavior | +| `indices` | in | `cuvsCagraIndex_t*` | Array of input cuvsCagraIndex_t handles to merge | +| `num_indices` | in | `size_t` | Number of input indices | +| `filter` | in | `cuvsFilter` | Filter that can be used to filter out vectors from the merged index | +| `output_index` | out | `cuvsCagraIndex_t` | Output handle that will store the merged index. Must be initialized using `cuvsCagraIndexCreate` before use. | + +**Returns** + +`cuvsError_t` + +_Source: `c/include/cuvs/neighbors/cagra.h:891`_ diff --git a/fern/pages/c_api/c-api-neighbors-common.md b/fern/pages/c_api/c-api-neighbors-common.md new file mode 100644 index 0000000000..bf50bbfb1d --- /dev/null +++ b/fern/pages/c_api/c-api-neighbors-common.md @@ -0,0 +1,50 @@ +--- +slug: api-reference/c-api-neighbors-common +--- + +# Common + +_Source header: `c/include/cuvs/neighbors/common.h`_ + +## Filters APIs + +_Doxygen group: `filters`_ + +### cuvsFilterType + +Enum to denote filter type. + +```c +enum cuvsFilterType { ... } ; +``` + +**Values** + +| Name | Value | +| --- | --- | +| `NO_FILTER` | `0` | +| `BITSET` | `1` | +| `BITMAP` | `2` | + +_Source: `c/include/cuvs/neighbors/common.h:23`_ + +## Index Merge + +_Doxygen group: `index_merge`_ + +### cuvsMergeStrategy + +Strategy for merging indices. + +```c +typedef enum { ... } cuvsMergeStrategy; +``` + +**Values** + +| Name | Value | +| --- | --- | +| `MERGE_STRATEGY_PHYSICAL` | `0` | +| `MERGE_STRATEGY_LOGICAL` | `1` | + +_Source: `c/include/cuvs/neighbors/common.h:54`_ diff --git a/fern/pages/c_api/c-api-neighbors-hnsw.md b/fern/pages/c_api/c-api-neighbors-hnsw.md new file mode 100644 index 0000000000..3c3f472546 --- /dev/null +++ b/fern/pages/c_api/c-api-neighbors-hnsw.md @@ -0,0 +1,515 @@ +--- +slug: api-reference/c-api-neighbors-hnsw +--- + +# HNSW + +_Source header: `c/include/cuvs/neighbors/hnsw.h`_ + +## C API for HNSW index params + +_Doxygen group: `hnsw_c_index_params`_ + +### cuvsHnswHierarchy + +Hierarchy for HNSW index when converting from CAGRA index + +NOTE: When the value is `NONE`, the HNSW index is built as a base-layer-only index. + +```c +enum cuvsHnswHierarchy { ... } ; +``` + +**Values** + +| Name | Value | +| --- | --- | +| `CPU` | `1` | +| `GPU` | `2` | + +_Source: `c/include/cuvs/neighbors/hnsw.h:30`_ + +### cuvsHnswAceParams + +Parameters for ACE (Augmented Core Extraction) graph build for HNSW. + +ACE enables building indexes for datasets too large to fit in GPU memory by: 1. Partitioning the dataset in core and augmented partitions using balanced k-means 2. Building sub-indexes for each partition independently 3. Concatenating sub-graphs into a final unified index + +```c +struct cuvsHnswAceParams { ... } ; +``` + +**Fields** + +| Name | Type | Description | +| --- | --- | --- | +| `npartitions` | `size_t` | Number of partitions for ACE partitioned build. | +| `build_dir` | `const char*` | Directory to store ACE build artifacts (e.g., KNN graph, optimized graph). | +| `use_disk` | `bool` | Whether to use disk-based storage for ACE build. | +| `max_host_memory_gb` | `double` | Maximum host memory to use for ACE build in GiB. | +| `max_gpu_memory_gb` | `double` | Maximum GPU memory to use for ACE build in GiB. | + +_Source: `c/include/cuvs/neighbors/hnsw.h:46`_ + +### cuvsHnswAceParamsCreate + +Allocate HNSW ACE params, and populate with default values + +```c +cuvsError_t cuvsHnswAceParamsCreate(cuvsHnswAceParams_t* params); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `params` | in | `cuvsHnswAceParams_t*` | cuvsHnswAceParams_t to allocate | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/hnsw.h:97`_ + +### cuvsHnswAceParamsDestroy + +De-allocate HNSW ACE params + +```c +cuvsError_t cuvsHnswAceParamsDestroy(cuvsHnswAceParams_t params); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `params` | in | `cuvsHnswAceParams_t` | | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/hnsw.h:105`_ + +### cuvsHnswIndexParamsCreate + +Allocate HNSW Index params, and populate with default values + +```c +cuvsError_t cuvsHnswIndexParamsCreate(cuvsHnswIndexParams_t* params); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `params` | in | `cuvsHnswIndexParams_t*` | cuvsHnswIndexParams_t to allocate | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/hnsw.h:141`_ + +### cuvsHnswIndexParamsDestroy + +De-allocate HNSW Index params + +```c +cuvsError_t cuvsHnswIndexParamsDestroy(cuvsHnswIndexParams_t params); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `params` | in | `cuvsHnswIndexParams_t` | | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/hnsw.h:149`_ + +## C API for hnswlib wrapper index + +_Doxygen group: `hnsw_c_index`_ + +### cuvsHnswIndexCreate + +Allocate HNSW index + +```c +cuvsError_t cuvsHnswIndexCreate(cuvsHnswIndex_t* index); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `index` | in | `cuvsHnswIndex_t*` | cuvsHnswIndex_t to allocate | + +**Returns** + +`cuvsError_t` + +HnswError_t + +_Source: `c/include/cuvs/neighbors/hnsw.h:178`_ + +### cuvsHnswIndexDestroy + +De-allocate HNSW index + +```c +cuvsError_t cuvsHnswIndexDestroy(cuvsHnswIndex_t index); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `index` | in | `cuvsHnswIndex_t` | cuvsHnswIndex_t to de-allocate | + +**Returns** + +`cuvsError_t` + +_Source: `c/include/cuvs/neighbors/hnsw.h:185`_ + +## Parameters for extending HNSW index + +_Doxygen group: `hnsw_c_extend_params`_ + +### cuvsHnswExtendParams + +Parameters for extending HNSW index + +```c +struct cuvsHnswExtendParams { ... } ; +``` + +**Fields** + +| Name | Type | Description | +| --- | --- | --- | +| `num_threads` | `int` | Number of CPU threads used to extend additional vectors | + +_Source: `c/include/cuvs/neighbors/hnsw.h:196`_ + +### cuvsHnswExtendParamsCreate + +Allocate HNSW extend params, and populate with default values + +```c +cuvsError_t cuvsHnswExtendParamsCreate(cuvsHnswExtendParams_t* params); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `params` | in | `cuvsHnswExtendParams_t*` | cuvsHnswExtendParams_t to allocate | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/hnsw.h:209`_ + +### cuvsHnswExtendParamsDestroy + +De-allocate HNSW extend params + +```c +cuvsError_t cuvsHnswExtendParamsDestroy(cuvsHnswExtendParams_t params); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `params` | in | `cuvsHnswExtendParams_t` | cuvsHnswExtendParams_t to de-allocate | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/hnsw.h:218`_ + +## Load CAGRA index as hnswlib index + +_Doxygen group: `hnsw_c_index_load`_ + +### cuvsHnswFromCagra + +Convert a CAGRA Index to an HNSW index. + +```c +cuvsError_t cuvsHnswFromCagra(cuvsResources_t res, +cuvsHnswIndexParams_t params, +cuvsCagraIndex_t cagra_index, +cuvsHnswIndex_t hnsw_index); +``` + +NOTE: When hierarchy is: 1. `NONE`: This method uses the filesystem to write the CAGRA index in `/tmp/<random_number>.bin` before reading it as an hnswlib index, then deleting the temporary file. The returned index is immutable and can only be searched by the hnswlib wrapper in cuVS, as the format is not compatible with the original hnswlib. 2. `CPU`: The returned index is mutable and can be extended with additional vectors. The serialized index is also compatible with the original hnswlib library. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `params` | in | `cuvsHnswIndexParams_t` | cuvsHnswIndexParams_t used to load Hnsw index | +| `cagra_index` | in | `cuvsCagraIndex_t` | cuvsCagraIndex_t to convert to HNSW index | +| `hnsw_index` | out | `cuvsHnswIndex_t` | cuvsHnswIndex_t to return the HNSW index | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/hnsw.h:270`_ + +## Build HNSW index using ACE algorithm + +_Doxygen group: `hnsw_c_index_build`_ + +### cuvsHnswBuild + +Build an HNSW index using ACE (Augmented Core Extraction) algorithm. + +```c +cuvsError_t cuvsHnswBuild(cuvsResources_t res, +cuvsHnswIndexParams_t params, +DLManagedTensor* dataset, +cuvsHnswIndex_t index); +``` + +ACE enables building HNSW indexes for datasets too large to fit in GPU memory by: 1. Partitioning the dataset using balanced k-means into core and augmented partitions 2. Building sub-indexes for each partition independently 3. Concatenating sub-graphs into a final unified index NOTE: This function requires CUDA to be available at runtime. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `params` | in | `cuvsHnswIndexParams_t` | cuvsHnswIndexParams_t with ACE parameters configured | +| `dataset` | in | `DLManagedTensor*` | DLManagedTensor* host dataset to build index from | +| `index` | out | `cuvsHnswIndex_t` | cuvsHnswIndex_t to return the built HNSW index | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/hnsw.h:347`_ + +## Extend HNSW index with additional vectors + +_Doxygen group: `hnsw_c_index_extend`_ + +### cuvsHnswExtend + +Add new vectors to an HNSW index + +```c +cuvsError_t cuvsHnswExtend(cuvsResources_t res, +cuvsHnswExtendParams_t params, +DLManagedTensor* additional_dataset, +cuvsHnswIndex_t index); +``` + +NOTE: The HNSW index can only be extended when the hierarchy is `CPU` when converting from a CAGRA index. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `params` | in | `cuvsHnswExtendParams_t` | cuvsHnswExtendParams_t used to extend Hnsw index | +| `additional_dataset` | in | `DLManagedTensor*` | DLManagedTensor* additional dataset to extend the index | +| `index` | inout | `cuvsHnswIndex_t` | cuvsHnswIndex_t to extend | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/hnsw.h:405`_ + +## C API for hnswlib wrapper search params + +_Doxygen group: `hnsw_c_search_params`_ + +### cuvsHnswSearchParams + +C API for hnswlib wrapper search params + +```c +struct cuvsHnswSearchParams { ... } ; +``` + +**Fields** + +| Name | Type | Description | +| --- | --- | --- | +| `ef` | `int32_t` | | +| `num_threads` | `int32_t` | | + +_Source: `c/include/cuvs/neighbors/hnsw.h:419`_ + +### cuvsHnswSearchParamsCreate + +Allocate HNSW search params, and populate with default values + +```c +cuvsError_t cuvsHnswSearchParamsCreate(cuvsHnswSearchParams_t* params); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `params` | in | `cuvsHnswSearchParams_t*` | cuvsHnswSearchParams_t to allocate | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/hnsw.h:432`_ + +### cuvsHnswSearchParamsDestroy + +De-allocate HNSW search params + +```c +cuvsError_t cuvsHnswSearchParamsDestroy(cuvsHnswSearchParams_t params); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `params` | in | `cuvsHnswSearchParams_t` | cuvsHnswSearchParams_t to de-allocate | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/hnsw.h:440`_ + +## C API for CUDA ANN Graph-based nearest neighbor search + +_Doxygen group: `hnsw_c_index_search`_ + +### cuvsHnswSearch + +Search a HNSW index with a `DLManagedTensor` which has underlying + +```c +cuvsError_t cuvsHnswSearch(cuvsResources_t res, +cuvsHnswSearchParams_t params, +cuvsHnswIndex_t index, +DLManagedTensor* queries, +DLManagedTensor* neighbors, +DLManagedTensor* distances); +``` + +`DLDeviceType` equal to `kDLCPU`, `kDLCUDAHost`, or `kDLCUDAManaged`. It is also important to note that the HNSW Index must have been built with the same type of `queries`, such that `index.dtype.code == queries.dl_tensor.dtype.code` Supported types for input are: 1. `queries`: a. `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 32` b. `kDLDataType.code == kDLInt` and `kDLDataType.bits = 8` c. `kDLDataType.code == kDLUInt` and `kDLDataType.bits = 8` 2. `neighbors`: `kDLDataType.code == kDLUInt` and `kDLDataType.bits = 64` 3. `distances`: `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 32` NOTE: When hierarchy is `NONE`, the HNSW index can only be searched by the hnswlib wrapper in cuVS, as the format is not compatible with the original hnswlib. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `params` | in | `cuvsHnswSearchParams_t` | cuvsHnswSearchParams_t used to search Hnsw index | +| `index` | in | `cuvsHnswIndex_t` | cuvsHnswIndex which has been returned by `cuvsHnswFromCagra` | +| `queries` | in | `DLManagedTensor*` | DLManagedTensor* queries dataset to search | +| `neighbors` | out | `DLManagedTensor*` | DLManagedTensor* output `k` neighbors for queries | +| `distances` | out | `DLManagedTensor*` | DLManagedTensor* output `k` distances for queries | + +**Returns** + +`cuvsError_t` + +_Source: `c/include/cuvs/neighbors/hnsw.h:499`_ + +## HNSW C-API serialize functions + +_Doxygen group: `hnsw_c_index_serialize`_ + +### cuvsHnswSerialize + +Serialize a CAGRA index to a file as an hnswlib index + +```c +cuvsError_t cuvsHnswSerialize(cuvsResources_t res, const char* filename, cuvsHnswIndex_t index); +``` + +NOTE: When hierarchy is `NONE`, the saved hnswlib index is immutable and can only be read by the hnswlib wrapper in cuVS, as the serialization format is not compatible with the original hnswlib. However, when hierarchy is `CPU`, the saved hnswlib index is compatible with the original hnswlib library. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `filename` | in | `const char*` | the name of the file to save the index | +| `index` | in | `cuvsHnswIndex_t` | cuvsHnswIndex_t to serialize | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/hnsw.h:554`_ + +### cuvsHnswDeserialize + +Load hnswlib index from file which was serialized from a HNSW index. + +```c +cuvsError_t cuvsHnswDeserialize(cuvsResources_t res, +cuvsHnswIndexParams_t params, +const char* filename, +int dim, +cuvsDistanceType metric, +cuvsHnswIndex_t index); +``` + +NOTE: When hierarchy is `NONE`, the loaded hnswlib index is immutable, and only be read by the hnswlib wrapper in cuVS, as the serialization format is not compatible with the original hnswlib. Experimental, both the API and the serialization format are subject to change. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `params` | in | `cuvsHnswIndexParams_t` | cuvsHnswIndexParams_t used to load Hnsw index | +| `filename` | in | `const char*` | the name of the file that stores the index | +| `dim` | in | `int` | the dimension of the vectors in the index | +| `metric` | in | `cuvsDistanceType` | the distance metric used to build the index | +| `index` | out | `cuvsHnswIndex_t` | HNSW index loaded disk | + +**Returns** + +`cuvsError_t` + +_Source: `c/include/cuvs/neighbors/hnsw.h:592`_ diff --git a/fern/pages/c_api/c-api-neighbors-ivf-flat.md b/fern/pages/c_api/c-api-neighbors-ivf-flat.md new file mode 100644 index 0000000000..128e99d146 --- /dev/null +++ b/fern/pages/c_api/c-api-neighbors-ivf-flat.md @@ -0,0 +1,413 @@ +--- +slug: api-reference/c-api-neighbors-ivf-flat +--- + +# IVF Flat + +_Source header: `c/include/cuvs/neighbors/ivf_flat.h`_ + +## IVF-Flat index build parameters + +_Doxygen group: `ivf_flat_c_index_params`_ + +### cuvsIvfFlatIndexParams + +Supplemental parameters to build IVF-Flat Index + +```c +struct cuvsIvfFlatIndexParams { ... } ; +``` + +**Fields** + +| Name | Type | Description | +| --- | --- | --- | +| `metric` | `cuvsDistanceType` | Distance type. | +| `metric_arg` | `float` | The argument used by some distance metrics. | +| `add_data_on_build` | `bool` | Whether to add the dataset content to the index, i.e.: | +| `n_lists` | `uint32_t` | The number of inverted lists (clusters) | +| `kmeans_n_iters` | `uint32_t` | The number of iterations searching for kmeans centers (index building). | +| `kmeans_trainset_fraction` | `double` | The fraction of data to use during iterative kmeans building. | +| `adaptive_centers` | `bool` | By default (adaptive_centers = false), the cluster centers are trained in `ivf_flat::build`, | +| `conservative_memory_allocation` | `bool` | By default, the algorithm allocates more space than necessary for individual clusters | + +_Source: `c/include/cuvs/neighbors/ivf_flat.h:27`_ + +### cuvsIvfFlatIndexParamsCreate + +Allocate IVF-Flat Index params, and populate with default values + +```c +cuvsError_t cuvsIvfFlatIndexParamsCreate(cuvsIvfFlatIndexParams_t* index_params); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `index_params` | in | `cuvsIvfFlatIndexParams_t*` | cuvsIvfFlatIndexParams_t to allocate | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/ivf_flat.h:80`_ + +### cuvsIvfFlatIndexParamsDestroy + +De-allocate IVF-Flat Index params + +```c +cuvsError_t cuvsIvfFlatIndexParamsDestroy(cuvsIvfFlatIndexParams_t index_params); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `index_params` | in | `cuvsIvfFlatIndexParams_t` | | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/ivf_flat.h:88`_ + +## IVF-Flat index search parameters + +_Doxygen group: `ivf_flat_c_search_params`_ + +### cuvsIvfFlatSearchParams + +Supplemental parameters to search IVF-Flat index + +```c +struct cuvsIvfFlatSearchParams { ... } ; +``` + +**Fields** + +| Name | Type | Description | +| --- | --- | --- | +| `n_probes` | `uint32_t` | The number of clusters to search. | + +_Source: `c/include/cuvs/neighbors/ivf_flat.h:101`_ + +### cuvsIvfFlatSearchParamsCreate + +Allocate IVF-Flat search params, and populate with default values + +```c +cuvsError_t cuvsIvfFlatSearchParamsCreate(cuvsIvfFlatSearchParams_t* params); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `params` | in | `cuvsIvfFlatSearchParams_t*` | cuvsIvfFlatSearchParams_t to allocate | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/ivf_flat.h:114`_ + +### cuvsIvfFlatSearchParamsDestroy + +De-allocate IVF-Flat search params + +```c +cuvsError_t cuvsIvfFlatSearchParamsDestroy(cuvsIvfFlatSearchParams_t params); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `params` | in | `cuvsIvfFlatSearchParams_t` | | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/ivf_flat.h:122`_ + +## IVF-Flat index + +_Doxygen group: `ivf_flat_c_index`_ + +### cuvsIvfFlatIndexCreate + +Allocate IVF-Flat index + +```c +cuvsError_t cuvsIvfFlatIndexCreate(cuvsIvfFlatIndex_t* index); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `index` | in | `cuvsIvfFlatIndex_t*` | cuvsIvfFlatIndex_t to allocate | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/ivf_flat.h:148`_ + +### cuvsIvfFlatIndexDestroy + +De-allocate IVF-Flat index + +```c +cuvsError_t cuvsIvfFlatIndexDestroy(cuvsIvfFlatIndex_t index); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `index` | in | `cuvsIvfFlatIndex_t` | cuvsIvfFlatIndex_t to de-allocate | + +**Returns** + +`cuvsError_t` + +_Source: `c/include/cuvs/neighbors/ivf_flat.h:155`_ + +### cuvsIvfFlatIndexGetNLists + +Get the number of clusters/inverted lists + +```c +cuvsError_t cuvsIvfFlatIndexGetNLists(cuvsIvfFlatIndex_t index, int64_t* n_lists); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `index` | | `cuvsIvfFlatIndex_t` | | +| `n_lists` | | `int64_t*` | | + +**Returns** + +`cuvsError_t` + +_Source: `c/include/cuvs/neighbors/ivf_flat.h:158`_ + +### cuvsIvfFlatIndexGetDim + +Get the dimensionality of the data + +```c +cuvsError_t cuvsIvfFlatIndexGetDim(cuvsIvfFlatIndex_t index, int64_t* dim); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `index` | | `cuvsIvfFlatIndex_t` | | +| `dim` | | `int64_t*` | | + +**Returns** + +`cuvsError_t` + +_Source: `c/include/cuvs/neighbors/ivf_flat.h:161`_ + +### cuvsIvfFlatIndexGetCenters + +Get the cluster centers corresponding to the lists [n_lists, dim] + +```c +cuvsError_t cuvsIvfFlatIndexGetCenters(cuvsIvfFlatIndex_t index, DLManagedTensor* centers); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `index` | in | `cuvsIvfFlatIndex_t` | cuvsIvfFlatIndex_t Built Ivf-Flat Index | +| `centers` | out | `DLManagedTensor*` | Preallocated array on host or device memory to store output, [n_lists, dim] | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/ivf_flat.h:170`_ + +## IVF-Flat index build + +_Doxygen group: `ivf_flat_c_index_build`_ + +### cuvsIvfFlatBuild + +Build a IVF-Flat index with a `DLManagedTensor` which has underlying + +```c +cuvsError_t cuvsIvfFlatBuild(cuvsResources_t res, +cuvsIvfFlatIndexParams_t index_params, +DLManagedTensor* dataset, +cuvsIvfFlatIndex_t index); +``` + +`DLDeviceType` equal to `kDLCUDA`, `kDLCUDAHost`, `kDLCUDAManaged`, or `kDLCPU`. Also, acceptable underlying types are: 1. `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 32` 2. `kDLDataType.code == kDLInt` and `kDLDataType.bits = 8` 3. `kDLDataType.code == kDLUInt` and `kDLDataType.bits = 8` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `index_params` | in | `cuvsIvfFlatIndexParams_t` | cuvsIvfFlatIndexParams_t used to build IVF-Flat index | +| `dataset` | in | `DLManagedTensor*` | DLManagedTensor* training dataset | +| `index` | out | `cuvsIvfFlatIndex_t` | cuvsIvfFlatIndex_t Newly built IVF-Flat index | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/ivf_flat.h:222`_ + +## IVF-Flat index search + +_Doxygen group: `ivf_flat_c_index_search`_ + +### cuvsIvfFlatSearch + +Search a IVF-Flat index with a `DLManagedTensor` which has underlying + +```c +cuvsError_t cuvsIvfFlatSearch(cuvsResources_t res, +cuvsIvfFlatSearchParams_t search_params, +cuvsIvfFlatIndex_t index, +DLManagedTensor* queries, +DLManagedTensor* neighbors, +DLManagedTensor* distances, +cuvsFilter filter); +``` + +`DLDeviceType` equal to `kDLCUDA`, `kDLCUDAHost`, `kDLCUDAManaged`. It is also important to note that the IVF-Flat Index must have been built with the same type of `queries`, such that `index.dtype.code == queries.dl_tensor.dtype.code` Types for input are: 1. `queries`: `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 32` 2. `neighbors`: `kDLDataType.code == kDLUInt` and `kDLDataType.bits = 32` 3. `distances`: `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 32` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `search_params` | in | `cuvsIvfFlatSearchParams_t` | cuvsIvfFlatSearchParams_t used to search IVF-Flat index | +| `index` | in | `cuvsIvfFlatIndex_t` | ivfFlatIndex which has been returned by `ivfFlatBuild` | +| `queries` | in | `DLManagedTensor*` | DLManagedTensor* queries dataset to search | +| `neighbors` | out | `DLManagedTensor*` | DLManagedTensor* output `k` neighbors for queries | +| `distances` | out | `DLManagedTensor*` | DLManagedTensor* output `k` distances for queries | +| `filter` | in | `cuvsFilter` | cuvsFilter input filter that can be used to filter queries and neighbors based on the given bitset. | + +**Returns** + +`cuvsError_t` + +_Source: `c/include/cuvs/neighbors/ivf_flat.h:279`_ + +## IVF-Flat C-API serialize functions + +_Doxygen group: `ivf_flat_c_index_serialize`_ + +### cuvsIvfFlatSerialize + +Save the index to file. + +```c +cuvsError_t cuvsIvfFlatSerialize(cuvsResources_t res, +const char* filename, +cuvsIvfFlatIndex_t index); +``` + +Experimental, both the API and the serialization format are subject to change. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `filename` | in | `const char*` | the file name for saving the index | +| `index` | in | `cuvsIvfFlatIndex_t` | IVF-Flat index | + +**Returns** + +`cuvsError_t` + +_Source: `c/include/cuvs/neighbors/ivf_flat.h:315`_ + +### cuvsIvfFlatDeserialize + +Load index from file. + +```c +cuvsError_t cuvsIvfFlatDeserialize(cuvsResources_t res, +const char* filename, +cuvsIvfFlatIndex_t index); +``` + +Experimental, both the API and the serialization format are subject to change. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `filename` | in | `const char*` | the name of the file that stores the index | +| `index` | out | `cuvsIvfFlatIndex_t` | IVF-Flat index loaded disk | + +**Returns** + +`cuvsError_t` + +_Source: `c/include/cuvs/neighbors/ivf_flat.h:328`_ + +## IVF-Flat index extend + +_Doxygen group: `ivf_flat_c_index_extend`_ + +### cuvsIvfFlatExtend + +Extend the index with the new data. + +```c +cuvsError_t cuvsIvfFlatExtend(cuvsResources_t res, +DLManagedTensor* new_vectors, +DLManagedTensor* new_indices, +cuvsIvfFlatIndex_t index); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `new_vectors` | in | `DLManagedTensor*` | DLManagedTensor* the new vectors to add to the index | +| `new_indices` | in | `DLManagedTensor*` | DLManagedTensor* vector of new indices for the new vectors | +| `index` | inout | `cuvsIvfFlatIndex_t` | IVF-Flat index to be extended | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/ivf_flat.h:348`_ diff --git a/fern/pages/c_api/c-api-neighbors-ivf-pq.md b/fern/pages/c_api/c-api-neighbors-ivf-pq.md new file mode 100644 index 0000000000..955b877334 --- /dev/null +++ b/fern/pages/c_api/c-api-neighbors-ivf-pq.md @@ -0,0 +1,789 @@ +--- +slug: api-reference/c-api-neighbors-ivf-pq +--- + +# IVF PQ + +_Source header: `c/include/cuvs/neighbors/ivf_pq.h`_ + +## IVF-PQ index build parameters + +_Doxygen group: `ivf_pq_c_index_params`_ + +### cuvsIvfPqCodebookGen + +A type for specifying how PQ codebooks are created + +```c +enum cuvsIvfPqCodebookGen { ... } ; +``` + +**Values** + +| Name | Value | +| --- | --- | +| `CUVS_IVF_PQ_CODEBOOK_GEN_PER_SUBSPACE` | `0` | +| `CUVS_IVF_PQ_CODEBOOK_GEN_PER_CLUSTER` | `1` | + +_Source: `c/include/cuvs/neighbors/ivf_pq.h:26`_ + +### cuvsIvfPqListLayout + +A type for specifying the memory layout of IVF-PQ list data + +```c +enum cuvsIvfPqListLayout { ... } ; +``` + +**Values** + +| Name | Value | +| --- | --- | +| `CUVS_IVF_PQ_LIST_LAYOUT_FLAT` | `0` | +| `CUVS_IVF_PQ_LIST_LAYOUT_INTERLEAVED` | `1` | + +_Source: `c/include/cuvs/neighbors/ivf_pq.h:35`_ + +### cuvsIvfPqIndexParams + +Supplemental parameters to build IVF-PQ Index + +```c +struct cuvsIvfPqIndexParams { ... } ; +``` + +**Fields** + +| Name | Type | Description | +| --- | --- | --- | +| `metric` | `cuvsDistanceType` | Distance type. | +| `metric_arg` | `float` | The argument used by some distance metrics. | +| `add_data_on_build` | `bool` | Whether to add the dataset content to the index, i.e.: | +| `n_lists` | `uint32_t` | The number of inverted lists (clusters) | +| `kmeans_n_iters` | `uint32_t` | The number of iterations searching for kmeans centers (index building). | +| `kmeans_trainset_fraction` | `double` | The fraction of data to use during iterative kmeans building. | +| `pq_bits` | `uint32_t` | The bit length of the vector element after compression by PQ. | +| `pq_dim` | `uint32_t` | The dimensionality of the vector after compression by PQ. When zero, an optimal value is | +| `codebook_kind` | `enum cuvsIvfPqCodebookGen` | How PQ codebooks are created. | +| `force_random_rotation` | `bool` | Apply a random rotation matrix on the input data and queries even if `dim % pq_dim == 0`. | +| `conservative_memory_allocation` | `bool` | By default, the algorithm allocates more space than necessary for individual clusters | +| `max_train_points_per_pq_code` | `uint32_t` | The max number of data points to use per PQ code during PQ codebook training. Using more data | +| `codes_layout` | `enum cuvsIvfPqListLayout` | Memory layout of the IVF-PQ list data. | + +_Source: `c/include/cuvs/neighbors/ivf_pq.h:44`_ + +### cuvsIvfPqIndexParamsCreate + +Allocate IVF-PQ Index params, and populate with default values + +```c +cuvsError_t cuvsIvfPqIndexParamsCreate(cuvsIvfPqIndexParams_t* index_params); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `index_params` | in | `cuvsIvfPqIndexParams_t*` | cuvsIvfPqIndexParams_t to allocate | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/ivf_pq.h:144`_ + +### cuvsIvfPqIndexParamsDestroy + +De-allocate IVF-PQ Index params + +```c +cuvsError_t cuvsIvfPqIndexParamsDestroy(cuvsIvfPqIndexParams_t index_params); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `index_params` | in | `cuvsIvfPqIndexParams_t` | | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/ivf_pq.h:152`_ + +## IVF-PQ index search parameters + +_Doxygen group: `ivf_pq_c_search_params`_ + +### cuvsIvfPqSearchParams + +Supplemental parameters to search IVF-PQ index + +```c +struct cuvsIvfPqSearchParams { ... } ; +``` + +**Fields** + +| Name | Type | Description | +| --- | --- | --- | +| `n_probes` | `uint32_t` | The number of clusters to search. | +| `lut_dtype` | `cudaDataType_t` | Data type of look up table to be created dynamically at search time. | +| `internal_distance_dtype` | `cudaDataType_t` | Storage data type for distance/similarity computed at search time. | +| `coarse_search_dtype` | `cudaDataType_t` | The data type to use as the GEMM element type when searching the clusters to probe. | +| `max_internal_batch_size` | `uint32_t` | Set the internal batch size to improve GPU utilization at the cost of larger memory footprint. | +| `preferred_shmem_carveout` | `double` | Preferred fraction of SM's unified memory / L1 cache to be used as shared memory. | + +_Source: `c/include/cuvs/neighbors/ivf_pq.h:165`_ + +### cuvsIvfPqSearchParamsCreate + +Allocate IVF-PQ search params, and populate with default values + +```c +cuvsError_t cuvsIvfPqSearchParamsCreate(cuvsIvfPqSearchParams_t* params); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `params` | in | `cuvsIvfPqSearchParams_t*` | cuvsIvfPqSearchParams_t to allocate | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/ivf_pq.h:227`_ + +### cuvsIvfPqSearchParamsDestroy + +De-allocate IVF-PQ search params + +```c +cuvsError_t cuvsIvfPqSearchParamsDestroy(cuvsIvfPqSearchParams_t params); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `params` | in | `cuvsIvfPqSearchParams_t` | | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/ivf_pq.h:235`_ + +## IVF-PQ index + +_Doxygen group: `ivf_pq_c_index`_ + +### cuvsIvfPqIndexCreate + +Allocate IVF-PQ index + +```c +cuvsError_t cuvsIvfPqIndexCreate(cuvsIvfPqIndex_t* index); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `index` | in | `cuvsIvfPqIndex_t*` | cuvsIvfPqIndex_t to allocate | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/ivf_pq.h:261`_ + +### cuvsIvfPqIndexDestroy + +De-allocate IVF-PQ index + +```c +cuvsError_t cuvsIvfPqIndexDestroy(cuvsIvfPqIndex_t index); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `index` | in | `cuvsIvfPqIndex_t` | cuvsIvfPqIndex_t to de-allocate | + +**Returns** + +`cuvsError_t` + +_Source: `c/include/cuvs/neighbors/ivf_pq.h:268`_ + +### cuvsIvfPqIndexGetNLists + +Get the number of clusters/inverted lists + +```c +cuvsError_t cuvsIvfPqIndexGetNLists(cuvsIvfPqIndex_t index, int64_t* n_lists); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `index` | | `cuvsIvfPqIndex_t` | | +| `n_lists` | | `int64_t*` | | + +**Returns** + +`cuvsError_t` + +_Source: `c/include/cuvs/neighbors/ivf_pq.h:271`_ + +### cuvsIvfPqIndexGetDim + +Get the dimensionality + +```c +cuvsError_t cuvsIvfPqIndexGetDim(cuvsIvfPqIndex_t index, int64_t* dim); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `index` | | `cuvsIvfPqIndex_t` | | +| `dim` | | `int64_t*` | | + +**Returns** + +`cuvsError_t` + +_Source: `c/include/cuvs/neighbors/ivf_pq.h:274`_ + +### cuvsIvfPqIndexGetSize + +Get the size of the index + +```c +cuvsError_t cuvsIvfPqIndexGetSize(cuvsIvfPqIndex_t index, int64_t* size); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `index` | | `cuvsIvfPqIndex_t` | | +| `size` | | `int64_t*` | | + +**Returns** + +`cuvsError_t` + +_Source: `c/include/cuvs/neighbors/ivf_pq.h:277`_ + +### cuvsIvfPqIndexGetPqDim + +Get the dimensionality of an encoded vector after compression by PQ. + +```c +cuvsError_t cuvsIvfPqIndexGetPqDim(cuvsIvfPqIndex_t index, int64_t* pq_dim); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `index` | | `cuvsIvfPqIndex_t` | | +| `pq_dim` | | `int64_t*` | | + +**Returns** + +`cuvsError_t` + +_Source: `c/include/cuvs/neighbors/ivf_pq.h:280`_ + +### cuvsIvfPqIndexGetPqBits + +Get the bit length of an encoded vector element after compression by PQ. + +```c +cuvsError_t cuvsIvfPqIndexGetPqBits(cuvsIvfPqIndex_t index, int64_t* pq_bits); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `index` | | `cuvsIvfPqIndex_t` | | +| `pq_bits` | | `int64_t*` | | + +**Returns** + +`cuvsError_t` + +_Source: `c/include/cuvs/neighbors/ivf_pq.h:283`_ + +### cuvsIvfPqIndexGetPqLen + +Get the Dimensionality of a subspace, i.e. the number of vector + +```c +cuvsError_t cuvsIvfPqIndexGetPqLen(cuvsIvfPqIndex_t index, int64_t* pq_len); +``` + +components mapped to a subspace + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `index` | | `cuvsIvfPqIndex_t` | | +| `pq_len` | | `int64_t*` | | + +**Returns** + +`cuvsError_t` + +_Source: `c/include/cuvs/neighbors/ivf_pq.h:287`_ + +### cuvsIvfPqIndexGetCenters + +Get the cluster centers corresponding to the lists in the original space + +```c +cuvsError_t cuvsIvfPqIndexGetCenters(cuvsIvfPqIndex_t index, DLManagedTensor* centers); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `index` | in | `cuvsIvfPqIndex_t` | cuvsIvfPqIndex_t Built Ivf-Pq index | +| `centers` | out | `DLManagedTensor*` | Output tensor that will be populated with a non-owning view of the data | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/ivf_pq.h:296`_ + +### cuvsIvfPqIndexGetCentersPadded + +Get the padded cluster centers [n_lists, dim_ext] + +```c +cuvsError_t cuvsIvfPqIndexGetCentersPadded(cuvsIvfPqIndex_t index, DLManagedTensor* centers); +``` + +where dim_ext = round_up(dim + 1, 8) This returns the full padded centers as a contiguous array, suitable for use with cuvsIvfPqBuildPrecomputed. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `index` | in | `cuvsIvfPqIndex_t` | cuvsIvfPqIndex_t Built Ivf-Pq index | +| `centers` | out | `DLManagedTensor*` | Output tensor that will be populated with a non-owning view of the data | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/ivf_pq.h:309`_ + +### cuvsIvfPqIndexGetPqCenters + +Get the PQ cluster centers + +```c +cuvsError_t cuvsIvfPqIndexGetPqCenters(cuvsIvfPqIndex_t index, DLManagedTensor* pq_centers); +``` + +- CUVS_IVF_PQ_CODEBOOK_GEN_PER_SUBSPACE: [pq_dim , pq_len, pq_book_size] - CUVS_IVF_PQ_CODEBOOK_GEN_PER_CLUSTER: [n_lists, pq_len, pq_book_size] + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `index` | in | `cuvsIvfPqIndex_t` | cuvsIvfPqIndex_t Built Ivf-Pq index | +| `pq_centers` | out | `DLManagedTensor*` | Output tensor that will be populated with a non-owning view of the data | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/ivf_pq.h:321`_ + +### cuvsIvfPqIndexGetCentersRot + +Get the rotated cluster centers [n_lists, rot_dim] + +```c +cuvsError_t cuvsIvfPqIndexGetCentersRot(cuvsIvfPqIndex_t index, DLManagedTensor* centers_rot); +``` + +where rot_dim = pq_len * pq_dim + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `index` | in | `cuvsIvfPqIndex_t` | cuvsIvfPqIndex_t Built Ivf-Pq index | +| `centers_rot` | out | `DLManagedTensor*` | Output tensor that will be populated with a non-owning view of the data | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/ivf_pq.h:331`_ + +### cuvsIvfPqIndexGetRotationMatrix + +Get the rotation matrix [rot_dim, dim] + +```c +cuvsError_t cuvsIvfPqIndexGetRotationMatrix(cuvsIvfPqIndex_t index, +DLManagedTensor* rotation_matrix); +``` + +Transform matrix (original space -> rotated padded space) data + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `index` | in | `cuvsIvfPqIndex_t` | cuvsIvfPqIndex_t Built Ivf-Pq index | +| `rotation_matrix` | out | `DLManagedTensor*` | Output tensor that will be populated with a non-owning view of the | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/ivf_pq.h:342`_ + +### cuvsIvfPqIndexGetListSizes + +Get the sizes of each list + +```c +cuvsError_t cuvsIvfPqIndexGetListSizes(cuvsIvfPqIndex_t index, DLManagedTensor* list_sizes); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `index` | in | `cuvsIvfPqIndex_t` | cuvsIvfPqIndex_t Built Ivf-Pq index | +| `list_sizes` | out | `DLManagedTensor*` | Output tensor that will be populated with a non-owning view of the data | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/ivf_pq.h:352`_ + +### cuvsIvfPqIndexUnpackContiguousListData + +Unpack `n_rows` consecutive PQ encoded vectors of a single list (cluster) in the + +```c +cuvsError_t cuvsIvfPqIndexUnpackContiguousListData(cuvsResources_t res, +cuvsIvfPqIndex_t index, +DLManagedTensor* out_codes, +uint32_t label, +uint32_t offset); +``` + +compressed index starting at given `offset`, not expanded to one code per byte. Each code in the output buffer occupies ceildiv(index.pq_dim() * index.pq_bits(), 8) bytes. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | raft resource | +| `index` | in | `cuvsIvfPqIndex_t` | cuvsIvfPqIndex_t Built Ivf-Pq index | +| `out_codes` | out | `DLManagedTensor*` | the destination buffer [n_rows, ceildiv(index.pq_dim() * index.pq_bits(), 8)]. The length `n_rows` defines how many records to unpack, offset + n_rows must be smaller than or equal to the list size. This DLManagedTensor must already point to allocated device memory | +| `label` | in | `uint32_t` | The id of the list (cluster) to decode. | +| `offset` | in | `uint32_t` | How many records in the list to skip. | + +**Returns** + +`cuvsError_t` + +_Source: `c/include/cuvs/neighbors/ivf_pq.h:371`_ + +### cuvsIvfPqIndexGetListIndices + +Get the indices of each vector in a ivf-pq list + +```c +cuvsError_t cuvsIvfPqIndexGetListIndices(cuvsIvfPqIndex_t index, +uint32_t label, +DLManagedTensor* out_labels); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `index` | in | `cuvsIvfPqIndex_t` | cuvsIvfPqIndex_t Built Ivf-Pq index | +| `label` | in | `uint32_t` | The id of the list (cluster) to decode. | +| `out_labels` | out | `DLManagedTensor*` | output tensor that will be populated with a non-owning view of the data | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/ivf_pq.h:386`_ + +## IVF-PQ index build + +_Doxygen group: `ivf_pq_c_index_build`_ + +### cuvsIvfPqBuild + +Build a IVF-PQ index with a `DLManagedTensor` which has underlying + +```c +cuvsError_t cuvsIvfPqBuild(cuvsResources_t res, +cuvsIvfPqIndexParams_t params, +DLManagedTensor* dataset, +cuvsIvfPqIndex_t index); +``` + +`DLDeviceType` equal to `kDLCUDA`, `kDLCUDAHost`, `kDLCUDAManaged`, or `kDLCPU`. Also, acceptable underlying types are: 1. `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 32` 2. `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 16` 3. `kDLDataType.code == kDLInt` and `kDLDataType.bits = 8` 4. `kDLDataType.code == kDLUInt` and `kDLDataType.bits = 8` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `params` | in | `cuvsIvfPqIndexParams_t` | cuvsIvfPqIndexParams_t used to build IVF-PQ index | +| `dataset` | in | `DLManagedTensor*` | DLManagedTensor* training dataset | +| `index` | out | `cuvsIvfPqIndex_t` | cuvsIvfPqIndex_t Newly built IVF-PQ index | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/ivf_pq.h:440`_ + +### cuvsIvfPqBuildPrecomputed + +Build a view-type IVF-PQ index from device memory precomputed centroids and codebook. + +```c +cuvsError_t cuvsIvfPqBuildPrecomputed(cuvsResources_t res, +cuvsIvfPqIndexParams_t params, +uint32_t dim, +DLManagedTensor* pq_centers, +DLManagedTensor* centers, +DLManagedTensor* centers_rot, +DLManagedTensor* rotation_matrix, +cuvsIvfPqIndex_t index); +``` + +This function creates a non-owning index that stores a reference to the provided device data. All parameters must be provided with correct extents. The caller is responsible for ensuring the lifetime of the input data exceeds the lifetime of the returned index. The index_params must be consistent with the provided matrices. Specifically: - index_params.codebook_kind determines the expected shape of pq_centers - index_params.metric will be stored in the index - index_params.conservative_memory_allocation will be stored in the index The function will verify consistency between index_params, dim, and the matrix extents. matrices) dim] + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `params` | in | `cuvsIvfPqIndexParams_t` | cuvsIvfPqIndexParams_t used to configure the index (must be consistent with | +| `dim` | in | `uint32_t` | dimensionality of the input data | +| `pq_centers` | in | `DLManagedTensor*` | PQ codebook on device memory with required shape: - codebook_kind CUVS_IVF_PQ_CODEBOOK_GEN_PER_SUBSPACE: [pq_dim, pq_len, pq_book_size] - codebook_kind CUVS_IVF_PQ_CODEBOOK_GEN_PER_CLUSTER: [n_lists, pq_len, pq_book_size] | +| `centers` | in | `DLManagedTensor*` | Cluster centers in the original space [n_lists, dim_ext] where dim_ext = round_up(dim + 1, 8) | +| `centers_rot` | in | `DLManagedTensor*` | Rotated cluster centers [n_lists, rot_dim] where rot_dim = pq_len * pq_dim | +| `rotation_matrix` | in | `DLManagedTensor*` | Transform matrix (original space -> rotated padded space) [rot_dim, | +| `index` | out | `cuvsIvfPqIndex_t` | cuvsIvfPqIndex_t Newly built view-type IVF-PQ index | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/ivf_pq.h:474`_ + +## IVF-PQ index search + +_Doxygen group: `ivf_pq_c_index_search`_ + +### cuvsIvfPqSearch + +Search a IVF-PQ index with a `DLManagedTensor` which has underlying + +```c +cuvsError_t cuvsIvfPqSearch(cuvsResources_t res, +cuvsIvfPqSearchParams_t search_params, +cuvsIvfPqIndex_t index, +DLManagedTensor* queries, +DLManagedTensor* neighbors, +DLManagedTensor* distances); +``` + +`DLDeviceType` equal to `kDLCUDA`, `kDLCUDAHost`, `kDLCUDAManaged`. It is also important to note that the IVF-PQ Index must have been built with the same type of `queries`, such that `index.dtype.code == queries.dl_tensor.dtype.code` Types for input are: 1. `queries`: `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 32` or `kDLDataType.bits = 16` 2. `neighbors`: `kDLDataType.code == kDLUInt` and `kDLDataType.bits = 32` 3. `distances`: `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 32` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `search_params` | in | `cuvsIvfPqSearchParams_t` | cuvsIvfPqSearchParams_t used to search IVF-PQ index | +| `index` | in | `cuvsIvfPqIndex_t` | cuvsIvfPqIndex which has been returned by `cuvsIvfPqBuild` | +| `queries` | in | `DLManagedTensor*` | DLManagedTensor* queries dataset to search | +| `neighbors` | out | `DLManagedTensor*` | DLManagedTensor* output `k` neighbors for queries | +| `distances` | out | `DLManagedTensor*` | DLManagedTensor* output `k` distances for queries | + +**Returns** + +`cuvsError_t` + +_Source: `c/include/cuvs/neighbors/ivf_pq.h:534`_ + +## IVF-PQ C-API serialize functions + +_Doxygen group: `ivf_pq_c_index_serialize`_ + +### cuvsIvfPqSerialize + +Save the index to file. + +```c +cuvsError_t cuvsIvfPqSerialize(cuvsResources_t res, const char* filename, cuvsIvfPqIndex_t index); +``` + +Experimental, both the API and the serialization format are subject to change. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `filename` | in | `const char*` | the file name for saving the index | +| `index` | in | `cuvsIvfPqIndex_t` | IVF-PQ index | + +**Returns** + +`cuvsError_t` + +_Source: `c/include/cuvs/neighbors/ivf_pq.h:568`_ + +### cuvsIvfPqDeserialize + +Load index from file. + +```c +cuvsError_t cuvsIvfPqDeserialize(cuvsResources_t res, const char* filename, cuvsIvfPqIndex_t index); +``` + +Experimental, both the API and the serialization format are subject to change. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `filename` | in | `const char*` | the name of the file that stores the index | +| `index` | out | `cuvsIvfPqIndex_t` | IVF-PQ index loaded disk | + +**Returns** + +`cuvsError_t` + +_Source: `c/include/cuvs/neighbors/ivf_pq.h:579`_ + +## IVF-PQ index extend + +_Doxygen group: `ivf_pq_c_index_extend`_ + +### cuvsIvfPqExtend + +Extend the index with the new data. + +```c +cuvsError_t cuvsIvfPqExtend(cuvsResources_t res, +DLManagedTensor* new_vectors, +DLManagedTensor* new_indices, +cuvsIvfPqIndex_t index); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `new_vectors` | in | `DLManagedTensor*` | DLManagedTensor* the new vectors to add to the index | +| `new_indices` | in | `DLManagedTensor*` | DLManagedTensor* vector of new indices for the new vectors | +| `index` | inout | `cuvsIvfPqIndex_t` | IVF-PQ index to be extended | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/ivf_pq.h:597`_ + +## IVF-PQ index transform + +_Doxygen group: `ivf_pq_c_index_transform`_ + +### cuvsIvfPqTransform + +Transform the input data by applying pq-encoding + +```c +cuvsError_t cuvsIvfPqTransform(cuvsResources_t res, +cuvsIvfPqIndex_t index, +DLManagedTensor* input_dataset, +DLManagedTensor* output_labels, +DLManagedTensor* output_dataset); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `index` | in | `cuvsIvfPqIndex_t` | IVF-PQ index | +| `input_dataset` | in | `DLManagedTensor*` | DLManagedTensor* vectors to transform | +| `output_labels` | out | `DLManagedTensor*` | DLManagedTensor* Vector of cluster labels for each vector in the input | +| `output_dataset` | out | `DLManagedTensor*` | DLManagedTensor* input vectors after pq-encoding | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/ivf_pq.h:619`_ diff --git a/fern/pages/c_api/c-api-neighbors-mg-cagra.md b/fern/pages/c_api/c-api-neighbors-mg-cagra.md new file mode 100644 index 0000000000..5105d54da6 --- /dev/null +++ b/fern/pages/c_api/c-api-neighbors-mg-cagra.md @@ -0,0 +1,381 @@ +--- +slug: api-reference/c-api-neighbors-mg-cagra +--- + +# Multi-GPU Cagra + +_Source header: `c/include/cuvs/neighbors/mg_cagra.h`_ + +## Multi-GPU CAGRA index build parameters + +_Doxygen group: `mg_cagra_c_index_params`_ + +### cuvsMultiGpuCagraIndexParams + +Multi-GPU parameters to build CAGRA Index + +This structure extends the base CAGRA index parameters with multi-GPU specific settings. + +```c +struct cuvsMultiGpuCagraIndexParams { ... } ; +``` + +**Fields** + +| Name | Type | Description | +| --- | --- | --- | +| `base_params` | `cuvsCagraIndexParams_t` | Base CAGRA index parameters | +| `mode` | `cuvsMultiGpuDistributionMode` | Distribution mode for multi-GPU setup | + +_Source: `c/include/cuvs/neighbors/mg_cagra.h:28`_ + +### cuvsMultiGpuCagraIndexParamsCreate + +Allocate Multi-GPU CAGRA Index params, and populate with default values + +```c +cuvsError_t cuvsMultiGpuCagraIndexParamsCreate(cuvsMultiGpuCagraIndexParams_t* index_params); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `index_params` | in | `cuvsMultiGpuCagraIndexParams_t*` | cuvsMultiGpuCagraIndexParams_t to allocate | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/mg_cagra.h:43`_ + +### cuvsMultiGpuCagraIndexParamsDestroy + +De-allocate Multi-GPU CAGRA Index params + +```c +cuvsError_t cuvsMultiGpuCagraIndexParamsDestroy(cuvsMultiGpuCagraIndexParams_t index_params); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `index_params` | in | `cuvsMultiGpuCagraIndexParams_t` | | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/mg_cagra.h:51`_ + +## Multi-GPU CAGRA index search parameters + +_Doxygen group: `mg_cagra_c_search_params`_ + +### cuvsMultiGpuCagraSearchParams + +Multi-GPU parameters to search CAGRA index + +This structure extends the base CAGRA search parameters with multi-GPU specific settings. + +```c +struct cuvsMultiGpuCagraSearchParams { ... } ; +``` + +**Fields** + +| Name | Type | Description | +| --- | --- | --- | +| `base_params` | `cuvsCagraSearchParams_t` | Base CAGRA search parameters | +| `search_mode` | `cuvsMultiGpuReplicatedSearchMode` | Replicated search mode | +| `merge_mode` | `cuvsMultiGpuShardedMergeMode` | Sharded merge mode | +| `n_rows_per_batch` | `int64_t` | Number of rows per batch | + +_Source: `c/include/cuvs/neighbors/mg_cagra.h:67`_ + +### cuvsMultiGpuCagraSearchParamsCreate + +Allocate Multi-GPU CAGRA search params, and populate with default values + +```c +cuvsError_t cuvsMultiGpuCagraSearchParamsCreate(cuvsMultiGpuCagraSearchParams_t* params); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `params` | in | `cuvsMultiGpuCagraSearchParams_t*` | cuvsMultiGpuCagraSearchParams_t to allocate | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/mg_cagra.h:86`_ + +### cuvsMultiGpuCagraSearchParamsDestroy + +De-allocate Multi-GPU CAGRA search params + +```c +cuvsError_t cuvsMultiGpuCagraSearchParamsDestroy(cuvsMultiGpuCagraSearchParams_t params); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `params` | in | `cuvsMultiGpuCagraSearchParams_t` | | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/mg_cagra.h:94`_ + +## Multi-GPU CAGRA index + +_Doxygen group: `mg_cagra_c_index`_ + +### cuvsMultiGpuCagraIndexCreate + +Allocate Multi-GPU CAGRA index + +```c +cuvsError_t cuvsMultiGpuCagraIndexCreate(cuvsMultiGpuCagraIndex_t* index); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `index` | in | `cuvsMultiGpuCagraIndex_t*` | cuvsMultiGpuCagraIndex_t to allocate | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/mg_cagra.h:122`_ + +### cuvsMultiGpuCagraIndexDestroy + +De-allocate Multi-GPU CAGRA index + +```c +cuvsError_t cuvsMultiGpuCagraIndexDestroy(cuvsMultiGpuCagraIndex_t index); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `index` | in | `cuvsMultiGpuCagraIndex_t` | cuvsMultiGpuCagraIndex_t to de-allocate | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/mg_cagra.h:130`_ + +## Multi-GPU CAGRA index build + +_Doxygen group: `mg_cagra_c_index_build`_ + +### cuvsMultiGpuCagraBuild + +Build a Multi-GPU CAGRA index + +```c +cuvsError_t cuvsMultiGpuCagraBuild(cuvsResources_t res, +cuvsMultiGpuCagraIndexParams_t params, +DLManagedTensor* dataset_tensor, +cuvsMultiGpuCagraIndex_t index); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `params` | in | `cuvsMultiGpuCagraIndexParams_t` | Multi-GPU CAGRA index parameters | +| `dataset_tensor` | in | `DLManagedTensor*` | DLManagedTensor* training dataset | +| `index` | out | `cuvsMultiGpuCagraIndex_t` | Multi-GPU CAGRA index | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/mg_cagra.h:150`_ + +## Multi-GPU CAGRA index search + +_Doxygen group: `mg_cagra_c_index_search`_ + +### cuvsMultiGpuCagraSearch + +Search a Multi-GPU CAGRA index + +```c +cuvsError_t cuvsMultiGpuCagraSearch(cuvsResources_t res, +cuvsMultiGpuCagraSearchParams_t params, +cuvsMultiGpuCagraIndex_t index, +DLManagedTensor* queries_tensor, +DLManagedTensor* neighbors_tensor, +DLManagedTensor* distances_tensor); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `params` | in | `cuvsMultiGpuCagraSearchParams_t` | Multi-GPU CAGRA search parameters | +| `index` | in | `cuvsMultiGpuCagraIndex_t` | Multi-GPU CAGRA index | +| `queries_tensor` | in | `DLManagedTensor*` | DLManagedTensor* queries dataset | +| `neighbors_tensor` | out | `DLManagedTensor*` | DLManagedTensor* output neighbors | +| `distances_tensor` | out | `DLManagedTensor*` | DLManagedTensor* output distances | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/mg_cagra.h:175`_ + +## Multi-GPU CAGRA index extend + +_Doxygen group: `mg_cagra_c_index_extend`_ + +### cuvsMultiGpuCagraExtend + +Extend a Multi-GPU CAGRA index + +```c +cuvsError_t cuvsMultiGpuCagraExtend(cuvsResources_t res, +cuvsMultiGpuCagraIndex_t index, +DLManagedTensor* new_vectors_tensor, +DLManagedTensor* new_indices_tensor); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `index` | in,out | `cuvsMultiGpuCagraIndex_t` | Multi-GPU CAGRA index to extend | +| `new_vectors_tensor` | in | `DLManagedTensor*` | DLManagedTensor* new vectors to add | +| `new_indices_tensor` | in | `DLManagedTensor*` | DLManagedTensor* new indices (optional, can be NULL) | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/mg_cagra.h:200`_ + +## Multi-GPU CAGRA index serialize + +_Doxygen group: `mg_cagra_c_index_serialize`_ + +### cuvsMultiGpuCagraSerialize + +Serialize a Multi-GPU CAGRA index to file + +```c +cuvsError_t cuvsMultiGpuCagraSerialize(cuvsResources_t res, +cuvsMultiGpuCagraIndex_t index, +const char* filename); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `index` | in | `cuvsMultiGpuCagraIndex_t` | Multi-GPU CAGRA index to serialize | +| `filename` | in | `const char*` | Path to the output file | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/mg_cagra.h:222`_ + +## Multi-GPU CAGRA index deserialize + +_Doxygen group: `mg_cagra_c_index_deserialize`_ + +### cuvsMultiGpuCagraDeserialize + +Deserialize a Multi-GPU CAGRA index from file + +```c +cuvsError_t cuvsMultiGpuCagraDeserialize(cuvsResources_t res, +const char* filename, +cuvsMultiGpuCagraIndex_t index); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `filename` | in | `const char*` | Path to the input file | +| `index` | out | `cuvsMultiGpuCagraIndex_t` | Multi-GPU CAGRA index | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/mg_cagra.h:243`_ + +## Multi-GPU CAGRA index distribute + +_Doxygen group: `mg_cagra_c_index_distribute`_ + +### cuvsMultiGpuCagraDistribute + +Distribute a local CAGRA index to create a Multi-GPU index + +```c +cuvsError_t cuvsMultiGpuCagraDistribute(cuvsResources_t res, +const char* filename, +cuvsMultiGpuCagraIndex_t index); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `filename` | in | `const char*` | Path to the local index file | +| `index` | out | `cuvsMultiGpuCagraIndex_t` | Multi-GPU CAGRA index | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/mg_cagra.h:264`_ diff --git a/fern/pages/c_api/c-api-neighbors-mg-common.md b/fern/pages/c_api/c-api-neighbors-mg-common.md new file mode 100644 index 0000000000..9cb6eecbfd --- /dev/null +++ b/fern/pages/c_api/c-api-neighbors-mg-common.md @@ -0,0 +1,55 @@ +--- +slug: api-reference/c-api-neighbors-mg-common +--- + +# Multi-GPU Common + +_Source header: `c/include/cuvs/neighbors/mg_common.h`_ + +## Multi-GPU common types and enums + +_Doxygen group: `mg_c_common_types`_ + +### cuvsMultiGpuDistributionMode + +Distribution mode for multi-GPU indexes + +```c +typedef enum { ... } cuvsMultiGpuDistributionMode; +``` + +_Source: `c/include/cuvs/neighbors/mg_common.h:22`_ + +### cuvsMultiGpuReplicatedSearchMode + +Search mode when using a replicated index + +```c +typedef enum { ... } cuvsMultiGpuReplicatedSearchMode; +``` + +**Values** + +| Name | Value | +| --- | --- | +| `CUVS_NEIGHBORS_MG_LOAD_BALANCER` | `0` | +| `CUVS_NEIGHBORS_MG_ROUND_ROBIN` | `1` | + +_Source: `c/include/cuvs/neighbors/mg_common.h:32`_ + +### cuvsMultiGpuShardedMergeMode + +Merge mode when using a sharded index + +```c +typedef enum { ... } cuvsMultiGpuShardedMergeMode; +``` + +**Values** + +| Name | Value | +| --- | --- | +| `CUVS_NEIGHBORS_MG_MERGE_ON_ROOT_RANK` | `0` | +| `CUVS_NEIGHBORS_MG_TREE_MERGE` | `1` | + +_Source: `c/include/cuvs/neighbors/mg_common.h:42`_ diff --git a/fern/pages/c_api/c-api-neighbors-mg-ivf-flat.md b/fern/pages/c_api/c-api-neighbors-mg-ivf-flat.md new file mode 100644 index 0000000000..de20351357 --- /dev/null +++ b/fern/pages/c_api/c-api-neighbors-mg-ivf-flat.md @@ -0,0 +1,381 @@ +--- +slug: api-reference/c-api-neighbors-mg-ivf-flat +--- + +# Multi-GPU IVF Flat + +_Source header: `c/include/cuvs/neighbors/mg_ivf_flat.h`_ + +## Multi-GPU IVF-Flat index build parameters + +_Doxygen group: `mg_ivf_flat_c_index_params`_ + +### cuvsMultiGpuIvfFlatIndexParams + +Multi-GPU parameters to build IVF-Flat Index + +This structure extends the base IVF-Flat index parameters with multi-GPU specific settings. + +```c +struct cuvsMultiGpuIvfFlatIndexParams { ... } ; +``` + +**Fields** + +| Name | Type | Description | +| --- | --- | --- | +| `base_params` | `cuvsIvfFlatIndexParams_t` | Base IVF-Flat index parameters | +| `mode` | `cuvsMultiGpuDistributionMode` | Distribution mode for multi-GPU setup | + +_Source: `c/include/cuvs/neighbors/mg_ivf_flat.h:28`_ + +### cuvsMultiGpuIvfFlatIndexParamsCreate + +Allocate Multi-GPU IVF-Flat Index params, and populate with default values + +```c +cuvsError_t cuvsMultiGpuIvfFlatIndexParamsCreate(cuvsMultiGpuIvfFlatIndexParams_t* index_params); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `index_params` | in | `cuvsMultiGpuIvfFlatIndexParams_t*` | cuvsMultiGpuIvfFlatIndexParams_t to allocate | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/mg_ivf_flat.h:43`_ + +### cuvsMultiGpuIvfFlatIndexParamsDestroy + +De-allocate Multi-GPU IVF-Flat Index params + +```c +cuvsError_t cuvsMultiGpuIvfFlatIndexParamsDestroy(cuvsMultiGpuIvfFlatIndexParams_t index_params); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `index_params` | in | `cuvsMultiGpuIvfFlatIndexParams_t` | | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/mg_ivf_flat.h:51`_ + +## Multi-GPU IVF-Flat index search parameters + +_Doxygen group: `mg_ivf_flat_c_search_params`_ + +### cuvsMultiGpuIvfFlatSearchParams + +Multi-GPU parameters to search IVF-Flat index + +This structure extends the base IVF-Flat search parameters with multi-GPU specific settings. + +```c +struct cuvsMultiGpuIvfFlatSearchParams { ... } ; +``` + +**Fields** + +| Name | Type | Description | +| --- | --- | --- | +| `base_params` | `cuvsIvfFlatSearchParams_t` | Base IVF-Flat search parameters | +| `search_mode` | `cuvsMultiGpuReplicatedSearchMode` | Replicated search mode | +| `merge_mode` | `cuvsMultiGpuShardedMergeMode` | Sharded merge mode | +| `n_rows_per_batch` | `int64_t` | Number of rows per batch | + +_Source: `c/include/cuvs/neighbors/mg_ivf_flat.h:67`_ + +### cuvsMultiGpuIvfFlatSearchParamsCreate + +Allocate Multi-GPU IVF-Flat search params, and populate with default values + +```c +cuvsError_t cuvsMultiGpuIvfFlatSearchParamsCreate(cuvsMultiGpuIvfFlatSearchParams_t* params); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `params` | in | `cuvsMultiGpuIvfFlatSearchParams_t*` | cuvsMultiGpuIvfFlatSearchParams_t to allocate | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/mg_ivf_flat.h:86`_ + +### cuvsMultiGpuIvfFlatSearchParamsDestroy + +De-allocate Multi-GPU IVF-Flat search params + +```c +cuvsError_t cuvsMultiGpuIvfFlatSearchParamsDestroy(cuvsMultiGpuIvfFlatSearchParams_t params); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `params` | in | `cuvsMultiGpuIvfFlatSearchParams_t` | | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/mg_ivf_flat.h:94`_ + +## Multi-GPU IVF-Flat index + +_Doxygen group: `mg_ivf_flat_c_index`_ + +### cuvsMultiGpuIvfFlatIndexCreate + +Allocate Multi-GPU IVF-Flat index + +```c +cuvsError_t cuvsMultiGpuIvfFlatIndexCreate(cuvsMultiGpuIvfFlatIndex_t* index); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `index` | in | `cuvsMultiGpuIvfFlatIndex_t*` | cuvsMultiGpuIvfFlatIndex_t to allocate | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/mg_ivf_flat.h:122`_ + +### cuvsMultiGpuIvfFlatIndexDestroy + +De-allocate Multi-GPU IVF-Flat index + +```c +cuvsError_t cuvsMultiGpuIvfFlatIndexDestroy(cuvsMultiGpuIvfFlatIndex_t index); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `index` | in | `cuvsMultiGpuIvfFlatIndex_t` | cuvsMultiGpuIvfFlatIndex_t to de-allocate | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/mg_ivf_flat.h:130`_ + +## Multi-GPU IVF-Flat index build + +_Doxygen group: `mg_ivf_flat_c_index_build`_ + +### cuvsMultiGpuIvfFlatBuild + +Build a Multi-GPU IVF-Flat index + +```c +cuvsError_t cuvsMultiGpuIvfFlatBuild(cuvsResources_t res, +cuvsMultiGpuIvfFlatIndexParams_t params, +DLManagedTensor* dataset_tensor, +cuvsMultiGpuIvfFlatIndex_t index); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `params` | in | `cuvsMultiGpuIvfFlatIndexParams_t` | Multi-GPU IVF-Flat index parameters | +| `dataset_tensor` | in | `DLManagedTensor*` | DLManagedTensor* training dataset | +| `index` | out | `cuvsMultiGpuIvfFlatIndex_t` | Multi-GPU IVF-Flat index | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/mg_ivf_flat.h:150`_ + +## Multi-GPU IVF-Flat index search + +_Doxygen group: `mg_ivf_flat_c_index_search`_ + +### cuvsMultiGpuIvfFlatSearch + +Search a Multi-GPU IVF-Flat index + +```c +cuvsError_t cuvsMultiGpuIvfFlatSearch(cuvsResources_t res, +cuvsMultiGpuIvfFlatSearchParams_t params, +cuvsMultiGpuIvfFlatIndex_t index, +DLManagedTensor* queries_tensor, +DLManagedTensor* neighbors_tensor, +DLManagedTensor* distances_tensor); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `params` | in | `cuvsMultiGpuIvfFlatSearchParams_t` | Multi-GPU IVF-Flat search parameters | +| `index` | in | `cuvsMultiGpuIvfFlatIndex_t` | Multi-GPU IVF-Flat index | +| `queries_tensor` | in | `DLManagedTensor*` | DLManagedTensor* queries dataset | +| `neighbors_tensor` | out | `DLManagedTensor*` | DLManagedTensor* output neighbors | +| `distances_tensor` | out | `DLManagedTensor*` | DLManagedTensor* output distances | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/mg_ivf_flat.h:175`_ + +## Multi-GPU IVF-Flat index extend + +_Doxygen group: `mg_ivf_flat_c_index_extend`_ + +### cuvsMultiGpuIvfFlatExtend + +Extend a Multi-GPU IVF-Flat index + +```c +cuvsError_t cuvsMultiGpuIvfFlatExtend(cuvsResources_t res, +cuvsMultiGpuIvfFlatIndex_t index, +DLManagedTensor* new_vectors_tensor, +DLManagedTensor* new_indices_tensor); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `index` | in,out | `cuvsMultiGpuIvfFlatIndex_t` | Multi-GPU IVF-Flat index to extend | +| `new_vectors_tensor` | in | `DLManagedTensor*` | DLManagedTensor* new vectors to add | +| `new_indices_tensor` | in | `DLManagedTensor*` | DLManagedTensor* new indices (optional, can be NULL) | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/mg_ivf_flat.h:200`_ + +## Multi-GPU IVF-Flat index serialize + +_Doxygen group: `mg_ivf_flat_c_index_serialize`_ + +### cuvsMultiGpuIvfFlatSerialize + +Serialize a Multi-GPU IVF-Flat index to file + +```c +cuvsError_t cuvsMultiGpuIvfFlatSerialize(cuvsResources_t res, +cuvsMultiGpuIvfFlatIndex_t index, +const char* filename); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `index` | in | `cuvsMultiGpuIvfFlatIndex_t` | Multi-GPU IVF-Flat index to serialize | +| `filename` | in | `const char*` | Path to the output file | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/mg_ivf_flat.h:222`_ + +## Multi-GPU IVF-Flat index deserialize + +_Doxygen group: `mg_ivf_flat_c_index_deserialize`_ + +### cuvsMultiGpuIvfFlatDeserialize + +Deserialize a Multi-GPU IVF-Flat index from file + +```c +cuvsError_t cuvsMultiGpuIvfFlatDeserialize(cuvsResources_t res, +const char* filename, +cuvsMultiGpuIvfFlatIndex_t index); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `filename` | in | `const char*` | Path to the input file | +| `index` | out | `cuvsMultiGpuIvfFlatIndex_t` | Multi-GPU IVF-Flat index | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/mg_ivf_flat.h:243`_ + +## Multi-GPU IVF-Flat index distribute + +_Doxygen group: `mg_ivf_flat_c_index_distribute`_ + +### cuvsMultiGpuIvfFlatDistribute + +Distribute a local IVF-Flat index to create a Multi-GPU index + +```c +cuvsError_t cuvsMultiGpuIvfFlatDistribute(cuvsResources_t res, +const char* filename, +cuvsMultiGpuIvfFlatIndex_t index); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `filename` | in | `const char*` | Path to the local index file | +| `index` | out | `cuvsMultiGpuIvfFlatIndex_t` | Multi-GPU IVF-Flat index | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/mg_ivf_flat.h:264`_ diff --git a/fern/pages/c_api/c-api-neighbors-mg-ivf-pq.md b/fern/pages/c_api/c-api-neighbors-mg-ivf-pq.md new file mode 100644 index 0000000000..bde7f3549f --- /dev/null +++ b/fern/pages/c_api/c-api-neighbors-mg-ivf-pq.md @@ -0,0 +1,381 @@ +--- +slug: api-reference/c-api-neighbors-mg-ivf-pq +--- + +# Multi-GPU IVF PQ + +_Source header: `c/include/cuvs/neighbors/mg_ivf_pq.h`_ + +## Multi-GPU IVF-PQ index build parameters + +_Doxygen group: `mg_ivf_pq_c_index_params`_ + +### cuvsMultiGpuIvfPqIndexParams + +Multi-GPU parameters to build IVF-PQ Index + +This structure extends the base IVF-PQ index parameters with multi-GPU specific settings. + +```c +struct cuvsMultiGpuIvfPqIndexParams { ... } ; +``` + +**Fields** + +| Name | Type | Description | +| --- | --- | --- | +| `base_params` | `cuvsIvfPqIndexParams_t` | Base IVF-PQ index parameters | +| `mode` | `cuvsMultiGpuDistributionMode` | Distribution mode for multi-GPU setup | + +_Source: `c/include/cuvs/neighbors/mg_ivf_pq.h:28`_ + +### cuvsMultiGpuIvfPqIndexParamsCreate + +Allocate Multi-GPU IVF-PQ Index params, and populate with default values + +```c +cuvsError_t cuvsMultiGpuIvfPqIndexParamsCreate(cuvsMultiGpuIvfPqIndexParams_t* index_params); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `index_params` | in | `cuvsMultiGpuIvfPqIndexParams_t*` | cuvsMultiGpuIvfPqIndexParams_t to allocate | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/mg_ivf_pq.h:43`_ + +### cuvsMultiGpuIvfPqIndexParamsDestroy + +De-allocate Multi-GPU IVF-PQ Index params + +```c +cuvsError_t cuvsMultiGpuIvfPqIndexParamsDestroy(cuvsMultiGpuIvfPqIndexParams_t index_params); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `index_params` | in | `cuvsMultiGpuIvfPqIndexParams_t` | | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/mg_ivf_pq.h:51`_ + +## Multi-GPU IVF-PQ index search parameters + +_Doxygen group: `mg_ivf_pq_c_search_params`_ + +### cuvsMultiGpuIvfPqSearchParams + +Multi-GPU parameters to search IVF-PQ index + +This structure extends the base IVF-PQ search parameters with multi-GPU specific settings. + +```c +struct cuvsMultiGpuIvfPqSearchParams { ... } ; +``` + +**Fields** + +| Name | Type | Description | +| --- | --- | --- | +| `base_params` | `cuvsIvfPqSearchParams_t` | Base IVF-PQ search parameters | +| `search_mode` | `cuvsMultiGpuReplicatedSearchMode` | Replicated search mode | +| `merge_mode` | `cuvsMultiGpuShardedMergeMode` | Sharded merge mode | +| `n_rows_per_batch` | `int64_t` | Number of rows per batch | + +_Source: `c/include/cuvs/neighbors/mg_ivf_pq.h:67`_ + +### cuvsMultiGpuIvfPqSearchParamsCreate + +Allocate Multi-GPU IVF-PQ search params, and populate with default values + +```c +cuvsError_t cuvsMultiGpuIvfPqSearchParamsCreate(cuvsMultiGpuIvfPqSearchParams_t* params); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `params` | in | `cuvsMultiGpuIvfPqSearchParams_t*` | cuvsMultiGpuIvfPqSearchParams_t to allocate | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/mg_ivf_pq.h:86`_ + +### cuvsMultiGpuIvfPqSearchParamsDestroy + +De-allocate Multi-GPU IVF-PQ search params + +```c +cuvsError_t cuvsMultiGpuIvfPqSearchParamsDestroy(cuvsMultiGpuIvfPqSearchParams_t params); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `params` | in | `cuvsMultiGpuIvfPqSearchParams_t` | | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/mg_ivf_pq.h:94`_ + +## Multi-GPU IVF-PQ index + +_Doxygen group: `mg_ivf_pq_c_index`_ + +### cuvsMultiGpuIvfPqIndexCreate + +Allocate Multi-GPU IVF-PQ index + +```c +cuvsError_t cuvsMultiGpuIvfPqIndexCreate(cuvsMultiGpuIvfPqIndex_t* index); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `index` | in | `cuvsMultiGpuIvfPqIndex_t*` | cuvsMultiGpuIvfPqIndex_t to allocate | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/mg_ivf_pq.h:122`_ + +### cuvsMultiGpuIvfPqIndexDestroy + +De-allocate Multi-GPU IVF-PQ index + +```c +cuvsError_t cuvsMultiGpuIvfPqIndexDestroy(cuvsMultiGpuIvfPqIndex_t index); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `index` | in | `cuvsMultiGpuIvfPqIndex_t` | cuvsMultiGpuIvfPqIndex_t to de-allocate | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/mg_ivf_pq.h:130`_ + +## Multi-GPU IVF-PQ index build + +_Doxygen group: `mg_ivf_pq_c_index_build`_ + +### cuvsMultiGpuIvfPqBuild + +Build a Multi-GPU IVF-PQ index + +```c +cuvsError_t cuvsMultiGpuIvfPqBuild(cuvsResources_t res, +cuvsMultiGpuIvfPqIndexParams_t params, +DLManagedTensor* dataset_tensor, +cuvsMultiGpuIvfPqIndex_t index); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `params` | in | `cuvsMultiGpuIvfPqIndexParams_t` | Multi-GPU IVF-PQ index parameters | +| `dataset_tensor` | in | `DLManagedTensor*` | DLManagedTensor* training dataset | +| `index` | out | `cuvsMultiGpuIvfPqIndex_t` | Multi-GPU IVF-PQ index | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/mg_ivf_pq.h:150`_ + +## Multi-GPU IVF-PQ index search + +_Doxygen group: `mg_ivf_pq_c_index_search`_ + +### cuvsMultiGpuIvfPqSearch + +Search a Multi-GPU IVF-PQ index + +```c +cuvsError_t cuvsMultiGpuIvfPqSearch(cuvsResources_t res, +cuvsMultiGpuIvfPqSearchParams_t params, +cuvsMultiGpuIvfPqIndex_t index, +DLManagedTensor* queries_tensor, +DLManagedTensor* neighbors_tensor, +DLManagedTensor* distances_tensor); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `params` | in | `cuvsMultiGpuIvfPqSearchParams_t` | Multi-GPU IVF-PQ search parameters | +| `index` | in | `cuvsMultiGpuIvfPqIndex_t` | Multi-GPU IVF-PQ index | +| `queries_tensor` | in | `DLManagedTensor*` | DLManagedTensor* queries dataset | +| `neighbors_tensor` | out | `DLManagedTensor*` | DLManagedTensor* output neighbors | +| `distances_tensor` | out | `DLManagedTensor*` | DLManagedTensor* output distances | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/mg_ivf_pq.h:175`_ + +## Multi-GPU IVF-PQ index extend + +_Doxygen group: `mg_ivf_pq_c_index_extend`_ + +### cuvsMultiGpuIvfPqExtend + +Extend a Multi-GPU IVF-PQ index + +```c +cuvsError_t cuvsMultiGpuIvfPqExtend(cuvsResources_t res, +cuvsMultiGpuIvfPqIndex_t index, +DLManagedTensor* new_vectors_tensor, +DLManagedTensor* new_indices_tensor); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `index` | in,out | `cuvsMultiGpuIvfPqIndex_t` | Multi-GPU IVF-PQ index to extend | +| `new_vectors_tensor` | in | `DLManagedTensor*` | DLManagedTensor* new vectors to add | +| `new_indices_tensor` | in | `DLManagedTensor*` | DLManagedTensor* new indices (optional, can be NULL) | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/mg_ivf_pq.h:200`_ + +## Multi-GPU IVF-PQ index serialize + +_Doxygen group: `mg_ivf_pq_c_index_serialize`_ + +### cuvsMultiGpuIvfPqSerialize + +Serialize a Multi-GPU IVF-PQ index to file + +```c +cuvsError_t cuvsMultiGpuIvfPqSerialize(cuvsResources_t res, +cuvsMultiGpuIvfPqIndex_t index, +const char* filename); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `index` | in | `cuvsMultiGpuIvfPqIndex_t` | Multi-GPU IVF-PQ index to serialize | +| `filename` | in | `const char*` | Path to the output file | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/mg_ivf_pq.h:222`_ + +## Multi-GPU IVF-PQ index deserialize + +_Doxygen group: `mg_ivf_pq_c_index_deserialize`_ + +### cuvsMultiGpuIvfPqDeserialize + +Deserialize a Multi-GPU IVF-PQ index from file + +```c +cuvsError_t cuvsMultiGpuIvfPqDeserialize(cuvsResources_t res, +const char* filename, +cuvsMultiGpuIvfPqIndex_t index); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `filename` | in | `const char*` | Path to the input file | +| `index` | out | `cuvsMultiGpuIvfPqIndex_t` | Multi-GPU IVF-PQ index | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/mg_ivf_pq.h:243`_ + +## Multi-GPU IVF-PQ index distribute + +_Doxygen group: `mg_ivf_pq_c_index_distribute`_ + +### cuvsMultiGpuIvfPqDistribute + +Distribute a local IVF-PQ index to create a Multi-GPU index + +```c +cuvsError_t cuvsMultiGpuIvfPqDistribute(cuvsResources_t res, +const char* filename, +cuvsMultiGpuIvfPqIndex_t index); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `filename` | in | `const char*` | Path to the local index file | +| `index` | out | `cuvsMultiGpuIvfPqIndex_t` | Multi-GPU IVF-PQ index | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/mg_ivf_pq.h:264`_ diff --git a/fern/pages/c_api/c-api-neighbors-nn-descent.md b/fern/pages/c_api/c-api-neighbors-nn-descent.md new file mode 100644 index 0000000000..4bd0c04822 --- /dev/null +++ b/fern/pages/c_api/c-api-neighbors-nn-descent.md @@ -0,0 +1,162 @@ +--- +slug: api-reference/c-api-neighbors-nn-descent +--- + +# NN Descent + +_Source header: `c/include/cuvs/neighbors/nn_descent.h`_ + +## The nn-descent algorithm parameters. + +_Doxygen group: `nn_descent_c_index_params`_ + +### cuvsNNDescentIndexParams + +Parameters used to build an nn-descent index + +`metric`: The distance metric to use `metric_arg`: The argument used by distance metrics like Minkowskidistance `graph_degree`: For an input dataset of dimensions (N, D), determines the final dimensions of the all-neighbors knn graph which turns out to be of dimensions (N, graph_degree) `intermediate_graph_degree`: Internally, nn-descent builds an all-neighbors knn graph of dimensions (N, intermediate_graph_degree) before selecting the final `graph_degree` neighbors. It's recommended that `intermediate_graph_degree` >= 1.5 * graph_degree `max_iterations`: The number of iterations that nn-descent will refine the graph for. More iterations produce a better quality graph at cost of performance `termination_threshold`: The delta at which nn-descent will terminate its iterations `return_distances`: Boolean to decide whether to return distances array `dist_comp_dtype`: dtype to use for distance computation. Defaults to `NND_DIST_COMP_AUTO` which automatically determines the best dtype for distance computation based on the dataset dimensions. Use `NND_DIST_COMP_FP32` for better precision at the cost of performance and memory usage. This option is only valid when data type is fp32. Use `NND_DIST_COMP_FP16` for better performance and memory usage at the cost of precision. + +```c +struct cuvsNNDescentIndexParams { ... } ; +``` + +**Fields** + +| Name | Type | Description | +| --- | --- | --- | +| `metric` | `cuvsDistanceType` | | +| `metric_arg` | `float` | | +| `graph_degree` | `size_t` | | +| `intermediate_graph_degree` | `size_t` | | +| `max_iterations` | `size_t` | | +| `termination_threshold` | `float` | | +| `return_distances` | `bool` | | +| `dist_comp_dtype` | `cuvsNNDescentDistCompDtype` | | + +_Source: `c/include/cuvs/neighbors/nn_descent.h:52`_ + +### cuvsNNDescentIndexParamsCreate + +Allocate NN-Descent Index params, and populate with default values + +```c +cuvsError_t cuvsNNDescentIndexParamsCreate(cuvsNNDescentIndexParams_t* index_params); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `index_params` | in | `cuvsNNDescentIndexParams_t*` | cuvsNNDescentIndexParams_t to allocate | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/nn_descent.h:71`_ + +### cuvsNNDescentIndexParamsDestroy + +De-allocate NN-Descent Index params + +```c +cuvsError_t cuvsNNDescentIndexParamsDestroy(cuvsNNDescentIndexParams_t index_params); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `index_params` | in | `cuvsNNDescentIndexParams_t` | | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/nn_descent.h:79`_ + +## NN-Descent index + +_Doxygen group: `nn_descent_c_index`_ + +### cuvsNNDescentIndexCreate + +Allocate NN-Descent index + +```c +cuvsError_t cuvsNNDescentIndexCreate(cuvsNNDescentIndex_t* index); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `index` | in | `cuvsNNDescentIndex_t*` | cuvsNNDescentIndex_t to allocate | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/nn_descent.h:105`_ + +### cuvsNNDescentIndexDestroy + +De-allocate NN-Descent index + +```c +cuvsError_t cuvsNNDescentIndexDestroy(cuvsNNDescentIndex_t index); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `index` | in | `cuvsNNDescentIndex_t` | cuvsNNDescentIndex_t to de-allocate | + +**Returns** + +`cuvsError_t` + +_Source: `c/include/cuvs/neighbors/nn_descent.h:112`_ + +## NN-Descent index build + +_Doxygen group: `nn_descent_c_index_build`_ + +### cuvsNNDescentBuild + +Build a NN-Descent index with a `DLManagedTensor` which has underlying + +```c +cuvsError_t cuvsNNDescentBuild(cuvsResources_t res, +cuvsNNDescentIndexParams_t index_params, +DLManagedTensor* dataset, +DLManagedTensor* graph, +cuvsNNDescentIndex_t index); +``` + +`DLDeviceType` equal to `kDLCUDA`, `kDLCUDAHost`, `kDLCUDAManaged`, or `kDLCPU`. Also, acceptable underlying types are: 1. `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 32` 2. `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 16` 3. `kDLDataType.code == kDLInt` and `kDLDataType.bits = 8` 4. `kDLDataType.code == kDLUInt` and `kDLDataType.bits = 8` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `index_params` | in | `cuvsNNDescentIndexParams_t` | cuvsNNDescentIndexParams_t used to build NN-Descent index | +| `dataset` | in | `DLManagedTensor*` | DLManagedTensor* training dataset on host or device memory | +| `graph` | inout | `DLManagedTensor*` | Optional preallocated graph on host memory to store output | +| `index` | out | `cuvsNNDescentIndex_t` | cuvsNNDescentIndex_t Newly built NN-Descent index | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/nn_descent.h:165`_ diff --git a/fern/pages/c_api/c-api-neighbors-refine.md b/fern/pages/c_api/c-api-neighbors-refine.md new file mode 100644 index 0000000000..70bd403fd0 --- /dev/null +++ b/fern/pages/c_api/c-api-neighbors-refine.md @@ -0,0 +1,45 @@ +--- +slug: api-reference/c-api-neighbors-refine +--- + +# Refine + +_Source header: `c/include/cuvs/neighbors/refine.h`_ + +## Approximate Nearest Neighbors Refinement C-API + +_Doxygen group: `ann_refine_c`_ + +### cuvsRefine + +Refine nearest neighbor search. + +```c +cuvsError_t cuvsRefine(cuvsResources_t res, +DLManagedTensor* dataset, +DLManagedTensor* queries, +DLManagedTensor* candidates, +cuvsDistanceType metric, +DLManagedTensor* indices, +DLManagedTensor* distances); +``` + +Refinement is an operation that follows an approximate NN search. The approximate search has already selected n_candidates neighbor candidates for each query. We narrow it down to k neighbors. For each query, we calculate the exact distance between the query and its n_candidates neighbor candidate, and select the k nearest ones. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `dataset` | in | `DLManagedTensor*` | device matrix that stores the dataset [n_rows, dims] | +| `queries` | in | `DLManagedTensor*` | device matrix of the queries [n_queris, dims] | +| `candidates` | in | `DLManagedTensor*` | indices of candidate vectors [n_queries, n_candidates], where n_candidates >= k | +| `metric` | in | `cuvsDistanceType` | distance metric to use. Euclidean (L2) is used by default | +| `indices` | out | `DLManagedTensor*` | device matrix that stores the refined indices [n_queries, k] | +| `distances` | out | `DLManagedTensor*` | device matrix that stores the refined distances [n_queries, k] | + +**Returns** + +`cuvsError_t` + +_Source: `c/include/cuvs/neighbors/refine.h:37`_ diff --git a/fern/pages/c_api/c-api-neighbors-tiered-index.md b/fern/pages/c_api/c-api-neighbors-tiered-index.md new file mode 100644 index 0000000000..1920a97856 --- /dev/null +++ b/fern/pages/c_api/c-api-neighbors-tiered-index.md @@ -0,0 +1,259 @@ +--- +slug: api-reference/c-api-neighbors-tiered-index +--- + +# Tiered Index + +_Source header: `c/include/cuvs/neighbors/tiered_index.h`_ + +## Tiered Index + +_Doxygen group: `tiered_index_c_index`_ + +### cuvsTieredIndexCreate + +Allocate Tiered Index + +```c +cuvsError_t cuvsTieredIndexCreate(cuvsTieredIndex_t* index); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `index` | in | `cuvsTieredIndex_t*` | cuvsTieredIndex_t to allocate | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/tiered_index.h:53`_ + +### cuvsTieredIndexDestroy + +De-allocate Tiered index + +```c +cuvsError_t cuvsTieredIndexDestroy(cuvsTieredIndex_t index); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `index` | in | `cuvsTieredIndex_t` | cuvsTieredIndex_t to de-allocate | + +**Returns** + +`cuvsError_t` + +_Source: `c/include/cuvs/neighbors/tiered_index.h:60`_ + +## Tiered Index build parameters + +_Doxygen group: `tiered_c_index_params`_ + +### cuvsTieredIndexParams + +Supplemental parameters to build a TieredIndex + +```c +struct cuvsTieredIndexParams { ... } ; +``` + +**Fields** + +| Name | Type | Description | +| --- | --- | --- | +| `metric` | `cuvsDistanceType` | Distance type. | +| `algo` | `cuvsTieredIndexANNAlgo` | The type of ANN algorithm we are using | +| `min_ann_rows` | `int64_t` | The minimum number of rows necessary in the index to create an | +| `create_ann_index_on_extend` | `bool` | Whether or not to create a new ann index on extend, if the number | +| `cagra_params` | `cuvsCagraIndexParams_t` | Optional parameters for building a cagra index | +| `ivf_flat_params` | `cuvsIvfFlatIndexParams_t` | Optional parameters for building a ivf_flat index | +| `ivf_pq_params` | `cuvsIvfPqIndexParams_t` | Optional parameters for building a ivf-pq index | + +_Source: `c/include/cuvs/neighbors/tiered_index.h:72`_ + +### cuvsTieredIndexParamsCreate + +Allocate Tiered Index Params and populate with default values + +```c +cuvsError_t cuvsTieredIndexParamsCreate(cuvsTieredIndexParams_t* index_params); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `index_params` | in | `cuvsTieredIndexParams_t*` | cuvsTieredIndexParams_t to allocate | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/tiered_index.h:105`_ + +### cuvsTieredIndexParamsDestroy + +De-allocate Tiered Index params + +```c +cuvsError_t cuvsTieredIndexParamsDestroy(cuvsTieredIndexParams_t index_params); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `index_params` | in | `cuvsTieredIndexParams_t` | | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/tiered_index.h:113`_ + +## Tiered index build + +_Doxygen group: `tieredindex_c_index_build`_ + +### cuvsTieredIndexBuild + +Build a TieredIndex index with a `DLManagedTensor` which has underlying + +```c +cuvsError_t cuvsTieredIndexBuild(cuvsResources_t res, +cuvsTieredIndexParams_t index_params, +DLManagedTensor* dataset, +cuvsTieredIndex_t index); +``` + +`DLDeviceType` equal to `kDLCUDA`, `kDLCUDAHost`, `kDLCUDAManaged`, or `kDLCPU`. Also, acceptable underlying types are: 1. `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 32` 2. `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 16` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `index_params` | in | `cuvsTieredIndexParams_t` | Index parameters to use when building the index | +| `dataset` | in | `DLManagedTensor*` | DLManagedTensor* training dataset | +| `index` | out | `cuvsTieredIndex_t` | cuvsTieredIndex_t Newly built TieredIndex index | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/tiered_index.h:162`_ + +## Tiered index search + +_Doxygen group: `tieredindex_c_index_search`_ + +### cuvsTieredIndexSearch + +Search a TieredIndex index with a `DLManagedTensor` + +```c +cuvsError_t cuvsTieredIndexSearch(cuvsResources_t res, +void* search_params, +cuvsTieredIndex_t index, +DLManagedTensor* queries, +DLManagedTensor* neighbors, +DLManagedTensor* distances, +cuvsFilter prefilter); +``` + +cuvsCagraSearchParams_t, cuvsIvfFlatSearchParams_t, cuvsIvfPqSearchParams_t depending on the type of the tiered index used + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `search_params` | in | `void*` | params used to the ANN index, should be one of | +| `index` | in | `cuvsTieredIndex_t` | cuvsTieredIndex which has been returned by `cuvsTieredIndexBuild` | +| `queries` | in | `DLManagedTensor*` | DLManagedTensor* queries dataset to search | +| `neighbors` | out | `DLManagedTensor*` | DLManagedTensor* output `k` neighbors for queries | +| `distances` | out | `DLManagedTensor*` | DLManagedTensor* output `k` distances for queries | +| `prefilter` | in | `cuvsFilter` | cuvsFilter input prefilter that can be used to filter queries and neighbors based on the given bitmap. | + +**Returns** + +`cuvsError_t` + +_Source: `c/include/cuvs/neighbors/tiered_index.h:212`_ + +## Tiered index extend + +_Doxygen group: `tiered_c_index_extend`_ + +### cuvsTieredIndexExtend + +Extend the index with the new data. + +```c +cuvsError_t cuvsTieredIndexExtend(cuvsResources_t res, +DLManagedTensor* new_vectors, +cuvsTieredIndex_t index); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `new_vectors` | in | `DLManagedTensor*` | DLManagedTensor* the new vectors to add to the index | +| `index` | inout | `cuvsTieredIndex_t` | Tiered index to be extended | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/tiered_index.h:235`_ + +## Tiered index merge + +_Doxygen group: `tiered_c_index_merge`_ + +### cuvsTieredIndexMerge + +Merge multiple indices together into a single index + +```c +cuvsError_t cuvsTieredIndexMerge(cuvsResources_t res, +cuvsTieredIndexParams_t index_params, +cuvsTieredIndex_t* indices, +size_t num_indices, +cuvsTieredIndex_t output_index); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `index_params` | in | `cuvsTieredIndexParams_t` | Index parameters to use when merging | +| `indices` | in | `cuvsTieredIndex_t*` | pointers to indices to merge together | +| `num_indices` | in | `size_t` | the number of indices to merge | +| `output_index` | out | `cuvsTieredIndex_t` | the merged index | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/tiered_index.h:256`_ diff --git a/fern/pages/c_api/c-api-neighbors-vamana.md b/fern/pages/c_api/c-api-neighbors-vamana.md new file mode 100644 index 0000000000..4749767725 --- /dev/null +++ b/fern/pages/c_api/c-api-neighbors-vamana.md @@ -0,0 +1,220 @@ +--- +slug: api-reference/c-api-neighbors-vamana +--- + +# Vamana + +_Source header: `c/include/cuvs/neighbors/vamana.h`_ + +## C API for Vamana index build + +_Doxygen group: `vamana_c_index_params`_ + +### cuvsVamanaIndexParams + +Supplemental parameters to build Vamana Index + +`graph_degree`: Maximum degree of graph; corresponds to the R parameter of Vamana algorithm in the literature. `visited_size`: Maximum number of visited nodes per search during Vamana algorithm. Loosely corresponds to the L parameter in the literature. `vamana_iters`: The number of times all vectors are inserted into the graph. If > 1, all vectors are re-inserted to improve graph quality. `max_fraction`: The maximum batch size is this fraction of the total dataset size. Larger gives faster build but lower graph quality. `alpha`: Used to determine how aggressive the pruning will be. + +```c +struct cuvsVamanaIndexParams { ... } ; +``` + +**Fields** + +| Name | Type | Description | +| --- | --- | --- | +| `metric` | `cuvsDistanceType` | Distance type. | +| `graph_degree` | `uint32_t` | Maximum degree of output graph corresponds to the R parameter in the original Vamana | +| `visited_size` | `uint32_t` | Maximum number of visited nodes per search corresponds to the L parameter in the Vamana | +| `vamana_iters` | `float` | Number of Vamana vector insertion iterations (each iteration inserts all vectors). | +| `alpha` | `float` | Alpha for pruning parameter | +| `max_fraction` | `float` | Maximum fraction of dataset inserted per batch. * | +| `batch_base` | `float` | Base of growth rate of batch sizes * | +| `queue_size` | `uint32_t` | Size of candidate queue structure - should be (2^x)-1 | +| `reverse_batchsize` | `uint32_t` | Max batchsize of reverse edge processing (reduces memory footprint) | + +_Source: `c/include/cuvs/neighbors/vamana.h:37`_ + +### cuvsVamanaIndexParamsCreate + +Allocate Vamana Index params, and populate with default values + +```c +cuvsError_t cuvsVamanaIndexParamsCreate(cuvsVamanaIndexParams_t* params); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `params` | in | `cuvsVamanaIndexParams_t*` | cuvsVamanaIndexParams_t to allocate | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/vamana.h:69`_ + +### cuvsVamanaIndexParamsDestroy + +De-allocate Vamana Index params + +```c +cuvsError_t cuvsVamanaIndexParamsDestroy(cuvsVamanaIndexParams_t params); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `params` | in | `cuvsVamanaIndexParams_t` | cuvsVamanaIndexParams_t to de-allocate | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/vamana.h:77`_ + +## Vamana index + +_Doxygen group: `vamana_c_index`_ + +### cuvsVamanaIndexCreate + +Allocate Vamana index + +```c +cuvsError_t cuvsVamanaIndexCreate(cuvsVamanaIndex_t* index); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `index` | in | `cuvsVamanaIndex_t*` | cuvsVamanaIndex_t to allocate | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/vamana.h:106`_ + +### cuvsVamanaIndexDestroy + +De-allocate Vamana index + +```c +cuvsError_t cuvsVamanaIndexDestroy(cuvsVamanaIndex_t index); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `index` | in | `cuvsVamanaIndex_t` | cuvsVamanaIndex_t to de-allocate | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/vamana.h:114`_ + +### cuvsVamanaIndexGetDims + +Get the dimension of the index + +```c +cuvsError_t cuvsVamanaIndexGetDims(cuvsVamanaIndex_t index, int* dim); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `index` | in | `cuvsVamanaIndex_t` | cuvsVamanaIndex_t to get dimension of | +| `dim` | out | `int*` | pointer to dimension to set | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/vamana.h:123`_ + +## Vamana index build + +_Doxygen group: `vamana_c_index_build`_ + +### cuvsVamanaBuild + +Build Vamana index + +```c +cuvsError_t cuvsVamanaBuild(cuvsResources_t res, +cuvsVamanaIndexParams_t params, +DLManagedTensor* dataset, +cuvsVamanaIndex_t index); +``` + +Build the index from the dataset for efficient DiskANN search. The build uses the Vamana insertion-based algorithm to create the graph. The algorithm starts with an empty graph and iteratively inserts batches of nodes. Each batch involves performing a greedy search for each vector to be inserted, and inserting it with edges to all nodes traversed during the search. Reverse edges are also inserted and robustPrune is applied to improve graph quality. The index_params struct controls the degree of the final graph. The following distance metrics are supported: - L2 Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `params` | in | `cuvsVamanaIndexParams_t` | cuvsVamanaIndexParams_t used to build Vamana index | +| `dataset` | in | `DLManagedTensor*` | DLManagedTensor* training dataset | +| `index` | out | `cuvsVamanaIndex_t` | cuvsVamanaIndex_t Vamana index | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/vamana.h:169`_ + +## Vamana index serialize + +_Doxygen group: `vamana_c_index_serialize`_ + +### cuvsVamanaSerialize + +Save Vamana index to file + +```c +cuvsError_t cuvsVamanaSerialize(cuvsResources_t res, +const char* filename, +cuvsVamanaIndex_t index, +bool include_dataset); +``` + +Matches the file format used by the DiskANN open-source repository, allowing cross-compatibility. Serialized Index is to be used by the DiskANN open-source repository for graph search. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `filename` | in | `const char*` | the file prefix for where the index is saved | +| `index` | in | `cuvsVamanaIndex_t` | cuvsVamanaIndex_t to serialize | +| `include_dataset` | in | `bool` | whether to include the dataset in the serialized index | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/neighbors/vamana.h:205`_ diff --git a/fern/pages/c_api/c-api-preprocessing-pca.md b/fern/pages/c_api/c-api-preprocessing-pca.md new file mode 100644 index 0000000000..773f207dde --- /dev/null +++ b/fern/pages/c_api/c-api-preprocessing-pca.md @@ -0,0 +1,251 @@ +--- +slug: api-reference/c-api-preprocessing-pca +--- + +# PCA + +_Source header: `c/include/cuvs/preprocessing/pca.h`_ + +## C API for PCA (Principal Component Analysis) + +_Doxygen group: `preprocessing_c_pca`_ + +### cuvsPcaSolver + +Solver algorithm for PCA eigen decomposition. + +```c +enum cuvsPcaSolver { ... } ; +``` + +**Values** + +| Name | Value | +| --- | --- | +| `CUVS_PCA_COV_EIG_DQ` | `0` | +| `CUVS_PCA_COV_EIG_JACOBI` | `1` | + +_Source: `c/include/cuvs/preprocessing/pca.h:25`_ + +### cuvsPcaParams + +Parameters for PCA decomposition. + +```c +struct cuvsPcaParams { ... } ; +``` + +**Fields** + +| Name | Type | Description | +| --- | --- | --- | +| `n_components` | `int` | Number of principal components to keep. | +| `copy` | `bool` | If false, data passed to fit are overwritten and running fit(X).transform(X) will | +| `whiten` | `bool` | When true the component vectors are multiplied by the square root of n_samples and then | +| `algorithm` | `enum cuvsPcaSolver` | Solver algorithm to use. | +| `tol` | `float` | Tolerance for singular values (used by Jacobi solver). | +| `n_iterations` | `int` | Number of iterations for the power method (Jacobi solver). | + +_Source: `c/include/cuvs/preprocessing/pca.h:35`_ + +### cuvsPcaParamsCreate + +Allocate PCA params and populate with default values. + +```c +cuvsError_t cuvsPcaParamsCreate(cuvsPcaParams_t* params); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `params` | out | `cuvsPcaParams_t*` | cuvsPcaParams_t to allocate | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/preprocessing/pca.h:70`_ + +### cuvsPcaParamsDestroy + +De-allocate PCA params. + +```c +cuvsError_t cuvsPcaParamsDestroy(cuvsPcaParams_t params); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `params` | in | `cuvsPcaParams_t` | cuvsPcaParams_t to de-allocate | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/preprocessing/pca.h:78`_ + +### cuvsPcaFit + +Perform PCA fit operation. + +```c +cuvsError_t cuvsPcaFit(cuvsResources_t res, +cuvsPcaParams_t params, +DLManagedTensor* input, +DLManagedTensor* components, +DLManagedTensor* explained_var, +DLManagedTensor* explained_var_ratio, +DLManagedTensor* singular_vals, +DLManagedTensor* mu, +DLManagedTensor* noise_vars, +bool flip_signs_based_on_U); +``` + +Computes the principal components, explained variances, singular values, and column means from the input data. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `params` | in | `cuvsPcaParams_t` | PCA parameters | +| `input` | inout | `DLManagedTensor*` | input data [n_rows x n_cols] (col-major, float32, device) | +| `components` | out | `DLManagedTensor*` | principal components [n_components x n_cols] (col-major, float32, device) | +| `explained_var` | out | `DLManagedTensor*` | explained variances [n_components] (float32, device) | +| `explained_var_ratio` | out | `DLManagedTensor*` | explained variance ratios [n_components] (float32, device) | +| `singular_vals` | out | `DLManagedTensor*` | singular values [n_components] (float32, device) | +| `mu` | out | `DLManagedTensor*` | column means [n_cols] (float32, device) | +| `noise_vars` | out | `DLManagedTensor*` | noise variance [1] (float32, device) | +| `flip_signs_based_on_U` | in | `bool` | whether to determine signs by U (true) or V.T (false) | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/preprocessing/pca.h:128`_ + +### cuvsPcaFitTransform + +Perform PCA fit and transform in a single operation. + +```c +cuvsError_t cuvsPcaFitTransform(cuvsResources_t res, +cuvsPcaParams_t params, +DLManagedTensor* input, +DLManagedTensor* trans_input, +DLManagedTensor* components, +DLManagedTensor* explained_var, +DLManagedTensor* explained_var_ratio, +DLManagedTensor* singular_vals, +DLManagedTensor* mu, +DLManagedTensor* noise_vars, +bool flip_signs_based_on_U); +``` + +Computes the principal components and transforms the input data into the eigenspace. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `params` | in | `cuvsPcaParams_t` | PCA parameters | +| `input` | inout | `DLManagedTensor*` | input data [n_rows x n_cols] (col-major, float32, device) | +| `trans_input` | out | `DLManagedTensor*` | transformed data [n_rows x n_components] (col-major, float32, device) | +| `components` | out | `DLManagedTensor*` | principal components [n_components x n_cols] (col-major, float32, device) | +| `explained_var` | out | `DLManagedTensor*` | explained variances [n_components] (float32, device) | +| `explained_var_ratio` | out | `DLManagedTensor*` | explained variance ratios [n_components] (float32, device) | +| `singular_vals` | out | `DLManagedTensor*` | singular values [n_components] (float32, device) | +| `mu` | out | `DLManagedTensor*` | column means [n_cols] (float32, device) | +| `noise_vars` | out | `DLManagedTensor*` | noise variance [1] (float32, device) | +| `flip_signs_based_on_U` | in | `bool` | whether to determine signs by U (true) or V.T (false) | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/preprocessing/pca.h:157`_ + +### cuvsPcaTransform + +Perform PCA transform operation. + +```c +cuvsError_t cuvsPcaTransform(cuvsResources_t res, +cuvsPcaParams_t params, +DLManagedTensor* input, +DLManagedTensor* components, +DLManagedTensor* singular_vals, +DLManagedTensor* mu, +DLManagedTensor* trans_input); +``` + +Transforms the input data into the eigenspace using previously computed principal components. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `params` | in | `cuvsPcaParams_t` | PCA parameters | +| `input` | inout | `DLManagedTensor*` | data to transform [n_rows x n_cols] (col-major, float32, device) | +| `components` | in | `DLManagedTensor*` | principal components [n_components x n_cols] (col-major, float32, device) | +| `singular_vals` | in | `DLManagedTensor*` | singular values [n_components] (float32, device) | +| `mu` | in | `DLManagedTensor*` | column means [n_cols] (float32, device) | +| `trans_input` | out | `DLManagedTensor*` | transformed data [n_rows x n_components] (col-major, float32, device) | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/preprocessing/pca.h:183`_ + +### cuvsPcaInverseTransform + +Perform PCA inverse transform operation. + +```c +cuvsError_t cuvsPcaInverseTransform(cuvsResources_t res, +cuvsPcaParams_t params, +DLManagedTensor* trans_input, +DLManagedTensor* components, +DLManagedTensor* singular_vals, +DLManagedTensor* mu, +DLManagedTensor* output); +``` + +Transforms data from the eigenspace back to the original space. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `params` | in | `cuvsPcaParams_t` | PCA parameters | +| `trans_input` | in | `DLManagedTensor*` | transformed data [n_rows x n_components] (col-major, float32, device) | +| `components` | in | `DLManagedTensor*` | principal components [n_components x n_cols] (col-major, float32, device) | +| `singular_vals` | in | `DLManagedTensor*` | singular values [n_components] (float32, device) | +| `mu` | in | `DLManagedTensor*` | column means [n_cols] (float32, device) | +| `output` | out | `DLManagedTensor*` | reconstructed data [n_rows x n_cols] (col-major, float32, device) | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/preprocessing/pca.h:205`_ diff --git a/fern/pages/c_api/c-api-preprocessing-quantize-binary.md b/fern/pages/c_api/c-api-preprocessing-quantize-binary.md new file mode 100644 index 0000000000..5e1655b031 --- /dev/null +++ b/fern/pages/c_api/c-api-preprocessing-quantize-binary.md @@ -0,0 +1,216 @@ +--- +slug: api-reference/c-api-preprocessing-quantize-binary +--- + +# Binary + +_Source header: `c/include/cuvs/preprocessing/quantize/binary.h`_ + +## C API for Binary Quantizer + +_Doxygen group: `preprocessing_c_binary`_ + +### cuvsBinaryQuantizerThreshold + +In the cuvsBinaryQuantizerTransform function, a bit is set if the corresponding element in + +the dataset vector is greater than the corresponding element in the threshold vector. The mean and sampling_median thresholds are calculated separately for each dimension. + +```c +enum cuvsBinaryQuantizerThreshold { ... } ; +``` + +**Values** + +| Name | Value | +| --- | --- | +| `ZERO` | `0` | +| `MEAN` | `1` | +| `SAMPLING_MEDIAN` | `2` | + +_Source: `c/include/cuvs/preprocessing/quantize/binary.h:26`_ + +### cuvsBinaryQuantizerParams + +Binary quantizer parameters. + +```c +struct cuvsBinaryQuantizerParams { ... } ; +``` + +**Fields** + +| Name | Type | Description | +| --- | --- | --- | +| `threshold` | `enum` | | +| `sampling_ratio` | `float` | | + +_Source: `c/include/cuvs/preprocessing/quantize/binary.h:35`_ + +### cuvsBinaryQuantizerParamsCreate + +Allocate Binary Quantizer params, and populate with default values + +```c +cuvsError_t cuvsBinaryQuantizerParamsCreate(cuvsBinaryQuantizerParams_t* params); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `params` | in | `cuvsBinaryQuantizerParams_t*` | cuvsBinaryQuantizerParams_t to allocate | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/preprocessing/quantize/binary.h:55`_ + +### cuvsBinaryQuantizerParamsDestroy + +De-allocate Binary Quantizer params + +```c +cuvsError_t cuvsBinaryQuantizerParamsDestroy(cuvsBinaryQuantizerParams_t params); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `params` | in | `cuvsBinaryQuantizerParams_t` | | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/preprocessing/quantize/binary.h:63`_ + +### cuvsBinaryQuantizerCreate + +Allocate Binary Quantizer and populate with default values + +```c +cuvsError_t cuvsBinaryQuantizerCreate(cuvsBinaryQuantizer_t* quantizer); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `quantizer` | in | `cuvsBinaryQuantizer_t*` | cuvsBinaryQuantizer_t to allocate | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/preprocessing/quantize/binary.h:84`_ + +### cuvsBinaryQuantizerDestroy + +De-allocate Binary Quantizer + +```c +cuvsError_t cuvsBinaryQuantizerDestroy(cuvsBinaryQuantizer_t quantizer); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `quantizer` | in | `cuvsBinaryQuantizer_t` | | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/preprocessing/quantize/binary.h:92`_ + +### cuvsBinaryQuantizerTrain + +Trains a binary quantizer to be used later for quantizing the dataset. + +```c +cuvsError_t cuvsBinaryQuantizerTrain(cuvsResources_t res, +cuvsBinaryQuantizerParams_t params, +DLManagedTensor* dataset, +cuvsBinaryQuantizer_t quantizer); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | raft resource | +| `params` | in | `cuvsBinaryQuantizerParams_t` | configure binary quantizer, e.g. threshold | +| `dataset` | in | `DLManagedTensor*` | a row-major host or device matrix | +| `quantizer` | out | `cuvsBinaryQuantizer_t` | trained binary quantizer | + +**Returns** + +`cuvsError_t` + +_Source: `c/include/cuvs/preprocessing/quantize/binary.h:102`_ + +### cuvsBinaryQuantizerTransform + +Applies binary quantization transform to the given dataset + +```c +cuvsError_t cuvsBinaryQuantizerTransform(cuvsResources_t res, +DLManagedTensor* dataset, +DLManagedTensor* out); +``` + +This applies binary quantization to a dataset, changing any positive values to a bitwise 1. This is useful for searching with the BitwiseHamming distance type. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | raft resource | +| `dataset` | in | `DLManagedTensor*` | a row-major host or device matrix to transform | +| `out` | out | `DLManagedTensor*` | a row-major host or device matrix to store transformed data | + +**Returns** + +`cuvsError_t` + +_Source: `c/include/cuvs/preprocessing/quantize/binary.h:118`_ + +### cuvsBinaryQuantizerTransformWithParams + +Applies binary quantization transform to the given dataset + +```c +cuvsError_t cuvsBinaryQuantizerTransformWithParams(cuvsResources_t res, +cuvsBinaryQuantizer_t quantizer, +DLManagedTensor* dataset, +DLManagedTensor* out); +``` + +This applies binary quantization to a dataset, changing any values that are larger than the threshold specified in the param to a bitwise 1. This is useful for searching with the BitwiseHamming distance type. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | raft resource | +| `quantizer` | in | `cuvsBinaryQuantizer_t` | binary quantizer | +| `dataset` | in | `DLManagedTensor*` | a row-major host or device matrix to transform | +| `out` | out | `DLManagedTensor*` | a row-major host or device matrix to store transformed data | + +**Returns** + +`cuvsError_t` + +_Source: `c/include/cuvs/preprocessing/quantize/binary.h:134`_ diff --git a/fern/pages/c_api/c-api-preprocessing-quantize-pq.md b/fern/pages/c_api/c-api-preprocessing-quantize-pq.md new file mode 100644 index 0000000000..791e7af240 --- /dev/null +++ b/fern/pages/c_api/c-api-preprocessing-quantize-pq.md @@ -0,0 +1,338 @@ +--- +slug: api-reference/c-api-preprocessing-quantize-pq +--- + +# PQ + +_Source header: `c/include/cuvs/preprocessing/quantize/pq.h`_ + +## C API for Product Quantizer + +_Doxygen group: `preprocessing_c_pq`_ + +### cuvsProductQuantizerParams + +Product quantizer parameters. + +```c +struct cuvsProductQuantizerParams { ... } ; +``` + +**Fields** + +| Name | Type | Description | +| --- | --- | --- | +| `pq_bits` | `uint32_t` | The bit length of the vector element after compression by PQ. | +| `pq_dim` | `uint32_t` | The dimensionality of the vector after compression by PQ. | +| `use_subspaces` | `bool` | Whether to use subspaces for product quantization (PQ). | +| `use_vq` | `bool` | Whether to use Vector Quantization (KMeans) before product quantization (PQ). | +| `vq_n_centers` | `uint32_t` | Vector Quantization (VQ) codebook size - number of "coarse cluster centers". | +| `kmeans_n_iters` | `uint32_t` | The number of iterations searching for kmeans centers (both VQ & PQ phases). | +| `pq_kmeans_type` | `cuvsKMeansType` | The type of kmeans algorithm to use for PQ training. | +| `max_train_points_per_pq_code` | `uint32_t` | The max number of data points to use per PQ code during PQ codebook training. Using more data | +| `max_train_points_per_vq_cluster` | `uint32_t` | The max number of data points to use per VQ cluster. | + +_Source: `c/include/cuvs/preprocessing/quantize/pq.h:24`_ + +### cuvsProductQuantizerParamsCreate + +Allocate Product Quantizer params, and populate with default values + +```c +cuvsError_t cuvsProductQuantizerParamsCreate(cuvsProductQuantizerParams_t* params); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `params` | in | `cuvsProductQuantizerParams_t*` | cuvsProductQuantizerParams_t to allocate | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/preprocessing/quantize/pq.h:85`_ + +### cuvsProductQuantizerParamsDestroy + +De-allocate Product Quantizer params + +```c +cuvsError_t cuvsProductQuantizerParamsDestroy(cuvsProductQuantizerParams_t params); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `params` | in | `cuvsProductQuantizerParams_t` | | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/preprocessing/quantize/pq.h:93`_ + +### cuvsProductQuantizerCreate + +Allocate Product Quantizer + +```c +cuvsError_t cuvsProductQuantizerCreate(cuvsProductQuantizer_t* quantizer); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `quantizer` | in | `cuvsProductQuantizer_t*` | cuvsProductQuantizer_t to allocate | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/preprocessing/quantize/pq.h:114`_ + +### cuvsProductQuantizerDestroy + +De-allocate Product Quantizer + +```c +cuvsError_t cuvsProductQuantizerDestroy(cuvsProductQuantizer_t quantizer); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `quantizer` | in | `cuvsProductQuantizer_t` | | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/preprocessing/quantize/pq.h:122`_ + +### cuvsProductQuantizerBuild + +Builds a product quantizer to be used later for quantizing the dataset. + +```c +cuvsError_t cuvsProductQuantizerBuild(cuvsResources_t res, +cuvsProductQuantizerParams_t params, +DLManagedTensor* dataset, +cuvsProductQuantizer_t quantizer); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | raft resource | +| `params` | in | `cuvsProductQuantizerParams_t` | Parameters for product quantizer training | +| `dataset` | in | `DLManagedTensor*` | a row-major host or device matrix | +| `quantizer` | out | `cuvsProductQuantizer_t` | trained product quantizer | + +**Returns** + +`cuvsError_t` + +_Source: `c/include/cuvs/preprocessing/quantize/pq.h:132`_ + +### cuvsProductQuantizerTransform + +Applies product quantization transform to the given dataset + +```c +cuvsError_t cuvsProductQuantizerTransform(cuvsResources_t res, +cuvsProductQuantizer_t quantizer, +DLManagedTensor* dataset, +DLManagedTensor* codes_out, +DLManagedTensor* vq_labels); +``` + +This applies product quantization to a dataset. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | raft resource | +| `quantizer` | in | `cuvsProductQuantizer_t` | product quantizer | +| `dataset` | in | `DLManagedTensor*` | a row-major host or device matrix to transform | +| `codes_out` | out | `DLManagedTensor*` | a row-major device matrix to store transformed data | +| `vq_labels` | out | `DLManagedTensor*` | a device vector to store VQ labels. Optional, can be NULL. | + +**Returns** + +`cuvsError_t` + +_Source: `c/include/cuvs/preprocessing/quantize/pq.h:149`_ + +### cuvsProductQuantizerInverseTransform + +Applies product quantization inverse transform to the given quantized codes + +```c +cuvsError_t cuvsProductQuantizerInverseTransform(cuvsResources_t res, +cuvsProductQuantizer_t quantizer, +DLManagedTensor* pq_codes, +DLManagedTensor* out, +DLManagedTensor* vq_labels); +``` + +This applies product quantization inverse transform to the given quantized codes. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | raft resource | +| `quantizer` | in | `cuvsProductQuantizer_t` | product quantizer | +| `pq_codes` | in | `DLManagedTensor*` | a row-major device matrix of quantized codes | +| `out` | out | `DLManagedTensor*` | a row-major device matrix to store the original data | +| `vq_labels` | out | `DLManagedTensor*` | a device vector containing the VQ labels when VQ is used. Optional, can be NULL. | + +**Returns** + +`cuvsError_t` + +_Source: `c/include/cuvs/preprocessing/quantize/pq.h:167`_ + +### cuvsProductQuantizerGetPqBits + +Get the bit length of the vector element after compression by PQ. + +```c +cuvsError_t cuvsProductQuantizerGetPqBits(cuvsProductQuantizer_t quantizer, uint32_t* pq_bits); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `quantizer` | in | `cuvsProductQuantizer_t` | product quantizer | +| `pq_bits` | out | `uint32_t*` | bit length of the vector element after compression by PQ | + +**Returns** + +`cuvsError_t` + +_Source: `c/include/cuvs/preprocessing/quantize/pq.h:179`_ + +### cuvsProductQuantizerGetPqDim + +Get the dimensionality of the vector after compression by PQ. + +```c +cuvsError_t cuvsProductQuantizerGetPqDim(cuvsProductQuantizer_t quantizer, uint32_t* pq_dim); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `quantizer` | in | `cuvsProductQuantizer_t` | product quantizer | +| `pq_dim` | out | `uint32_t*` | dimensionality of the vector after compression by PQ | + +**Returns** + +`cuvsError_t` + +_Source: `c/include/cuvs/preprocessing/quantize/pq.h:187`_ + +### cuvsProductQuantizerGetPqCodebook + +Get the PQ codebook. + +```c +cuvsError_t cuvsProductQuantizerGetPqCodebook(cuvsProductQuantizer_t quantizer, +DLManagedTensor* pq_codebook); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `quantizer` | in | `cuvsProductQuantizer_t` | product quantizer | +| `pq_codebook` | out | `DLManagedTensor*` | PQ codebook | + +**Returns** + +`cuvsError_t` + +_Source: `c/include/cuvs/preprocessing/quantize/pq.h:195`_ + +### cuvsProductQuantizerGetVqCodebook + +Get the VQ codebook. + +```c +cuvsError_t cuvsProductQuantizerGetVqCodebook(cuvsProductQuantizer_t quantizer, +DLManagedTensor* vq_codebook); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `quantizer` | in | `cuvsProductQuantizer_t` | product quantizer | +| `vq_codebook` | out | `DLManagedTensor*` | VQ codebook | + +**Returns** + +`cuvsError_t` + +_Source: `c/include/cuvs/preprocessing/quantize/pq.h:204`_ + +### cuvsProductQuantizerGetEncodedDim + +Get the encoded dimension of the quantized dataset. + +```c +cuvsError_t cuvsProductQuantizerGetEncodedDim(cuvsProductQuantizer_t quantizer, +uint32_t* encoded_dim); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `quantizer` | in | `cuvsProductQuantizer_t` | product quantizer | +| `encoded_dim` | out | `uint32_t*` | encoded dimension of the quantized dataset | + +**Returns** + +`cuvsError_t` + +_Source: `c/include/cuvs/preprocessing/quantize/pq.h:212`_ + +### cuvsProductQuantizerGetUseVq + +Get whether VQ is used. + +```c +cuvsError_t cuvsProductQuantizerGetUseVq(cuvsProductQuantizer_t quantizer, bool* use_vq); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `quantizer` | in | `cuvsProductQuantizer_t` | product quantizer | +| `use_vq` | out | `bool*` | whether VQ is used | + +**Returns** + +`cuvsError_t` + +_Source: `c/include/cuvs/preprocessing/quantize/pq.h:221`_ diff --git a/fern/pages/c_api/c-api-preprocessing-quantize-scalar.md b/fern/pages/c_api/c-api-preprocessing-quantize-scalar.md new file mode 100644 index 0000000000..2dae942b6c --- /dev/null +++ b/fern/pages/c_api/c-api-preprocessing-quantize-scalar.md @@ -0,0 +1,195 @@ +--- +slug: api-reference/c-api-preprocessing-quantize-scalar +--- + +# Scalar + +_Source header: `c/include/cuvs/preprocessing/quantize/scalar.h`_ + +## C API for Scalar Quantizer + +_Doxygen group: `preprocessing_c_scalar`_ + +### cuvsScalarQuantizerParams + +Scalar quantizer parameters. + +```c +struct cuvsScalarQuantizerParams { ... } ; +``` + +**Fields** + +| Name | Type | Description | +| --- | --- | --- | +| `quantile` | `float` | | + +_Source: `c/include/cuvs/preprocessing/quantize/scalar.h:23`_ + +### cuvsScalarQuantizerParamsCreate + +Allocate Scalar Quantizer params, and populate with default values + +```c +cuvsError_t cuvsScalarQuantizerParamsCreate(cuvsScalarQuantizerParams_t* params); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `params` | in | `cuvsScalarQuantizerParams_t*` | cuvsScalarQuantizerParams_t to allocate | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/preprocessing/quantize/scalar.h:39`_ + +### cuvsScalarQuantizerParamsDestroy + +De-allocate Scalar Quantizer params + +```c +cuvsError_t cuvsScalarQuantizerParamsDestroy(cuvsScalarQuantizerParams_t params); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `params` | in | `cuvsScalarQuantizerParams_t` | | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/preprocessing/quantize/scalar.h:47`_ + +### cuvsScalarQuantizerCreate + +Allocate Scalar Quantizer and populate with default values + +```c +cuvsError_t cuvsScalarQuantizerCreate(cuvsScalarQuantizer_t* quantizer); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `quantizer` | in | `cuvsScalarQuantizer_t*` | cuvsScalarQuantizer_t to allocate | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/preprocessing/quantize/scalar.h:68`_ + +### cuvsScalarQuantizerDestroy + +De-allocate Scalar Quantizer + +```c +cuvsError_t cuvsScalarQuantizerDestroy(cuvsScalarQuantizer_t quantizer); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `quantizer` | in | `cuvsScalarQuantizer_t` | | + +**Returns** + +`cuvsError_t` + +cuvsError_t + +_Source: `c/include/cuvs/preprocessing/quantize/scalar.h:76`_ + +### cuvsScalarQuantizerTrain + +Trains a scalar quantizer to be used later for quantizing the dataset. + +```c +cuvsError_t cuvsScalarQuantizerTrain(cuvsResources_t res, +cuvsScalarQuantizerParams_t params, +DLManagedTensor* dataset, +cuvsScalarQuantizer_t quantizer); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | raft resource | +| `params` | in | `cuvsScalarQuantizerParams_t` | configure scalar quantizer, e.g. quantile | +| `dataset` | in | `DLManagedTensor*` | a row-major host or device matrix | +| `quantizer` | out | `cuvsScalarQuantizer_t` | trained scalar quantizer | + +**Returns** + +`cuvsError_t` + +_Source: `c/include/cuvs/preprocessing/quantize/scalar.h:86`_ + +### cuvsScalarQuantizerTransform + +Applies quantization transform to given dataset + +```c +cuvsError_t cuvsScalarQuantizerTransform(cuvsResources_t res, +cuvsScalarQuantizer_t quantizer, +DLManagedTensor* dataset, +DLManagedTensor* out); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | raft resource | +| `quantizer` | in | `cuvsScalarQuantizer_t` | a scalar quantizer | +| `dataset` | in | `DLManagedTensor*` | a row-major host or device matrix to transform | +| `out` | out | `DLManagedTensor*` | a row-major host or device matrix to store transformed data | + +**Returns** + +`cuvsError_t` + +_Source: `c/include/cuvs/preprocessing/quantize/scalar.h:99`_ + +### cuvsScalarQuantizerInverseTransform + +Perform inverse quantization step on previously quantized dataset + +```c +cuvsError_t cuvsScalarQuantizerInverseTransform(cuvsResources_t res, +cuvsScalarQuantizer_t quantizer, +DLManagedTensor* dataset, +DLManagedTensor* out); +``` + +Note that depending on the chosen data types train dataset the conversion is not lossless. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `cuvsResources_t` | raft resource | +| `quantizer` | in | `cuvsScalarQuantizer_t` | a scalar quantizer | +| `dataset` | in | `DLManagedTensor*` | a row-major host or device matrix | +| `out` | out | `DLManagedTensor*` | a row-major host or device matrix | + +**Returns** + +`cuvsError_t` + +_Source: `c/include/cuvs/preprocessing/quantize/scalar.h:116`_ diff --git a/fern/pages/c_api/index.md b/fern/pages/c_api/index.md new file mode 100644 index 0000000000..047b165ebb --- /dev/null +++ b/fern/pages/c_api/index.md @@ -0,0 +1,26 @@ +# C API Documentation + +These pages are generated from the documented public headers in the cuVS source tree. + +- [K-Means](/api-reference/c-api-cluster-kmeans) +- [C API](/api-reference/c-api-core-c-api) +- [Pairwise Distance](/api-reference/c-api-distance-pairwise-distance) +- [All Neighbors](/api-reference/c-api-neighbors-all-neighbors) +- [Brute Force](/api-reference/c-api-neighbors-brute-force) +- [Cagra](/api-reference/c-api-neighbors-cagra) +- [Common](/api-reference/c-api-neighbors-common) +- [HNSW](/api-reference/c-api-neighbors-hnsw) +- [IVF Flat](/api-reference/c-api-neighbors-ivf-flat) +- [IVF PQ](/api-reference/c-api-neighbors-ivf-pq) +- [Multi-GPU Cagra](/api-reference/c-api-neighbors-mg-cagra) +- [Multi-GPU Common](/api-reference/c-api-neighbors-mg-common) +- [Multi-GPU IVF Flat](/api-reference/c-api-neighbors-mg-ivf-flat) +- [Multi-GPU IVF PQ](/api-reference/c-api-neighbors-mg-ivf-pq) +- [NN Descent](/api-reference/c-api-neighbors-nn-descent) +- [Refine](/api-reference/c-api-neighbors-refine) +- [Tiered Index](/api-reference/c-api-neighbors-tiered-index) +- [Vamana](/api-reference/c-api-neighbors-vamana) +- [PCA](/api-reference/c-api-preprocessing-pca) +- [Binary](/api-reference/c-api-preprocessing-quantize-binary) +- [PQ](/api-reference/c-api-preprocessing-quantize-pq) +- [Scalar](/api-reference/c-api-preprocessing-quantize-scalar) diff --git a/docs/source/choosing_and_configuring_indexes.rst b/fern/pages/choosing_and_configuring_indexes.md similarity index 68% rename from docs/source/choosing_and_configuring_indexes.rst rename to fern/pages/choosing_and_configuring_indexes.md index b4c140f295..1bb0710ef5 100644 --- a/docs/source/choosing_and_configuring_indexes.rst +++ b/fern/pages/choosing_and_configuring_indexes.md @@ -1,98 +1,67 @@ -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Primer on vector search indexes -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Primer on vector search indexes Vector search indexes often use approximations to trade-off accuracy of the results for speed, either through lowering latency (end-to-end single query speed) or by increasing throughput (the number of query vectors that can be satisfied in a short period of time). Vector search indexes, especially ones that use approximations, are very closely related to machine learning models but they are optimized for fast search and accuracy of results. When the number of vectors is very small, such as less than 100 thousand vectors, it could be fast enough to use a brute-force (also known as a flat index), which returns exact results but at the expense of exhaustively searching all possible neighbors -Objectives -========== +## Objectives This primer addresses the challenge of configuring vector search indexes, but its primary goal is to get a user up and running quickly with acceptable enough results for a good choice of index type and a small and manageable tuning knob, rather than providing a comprehensive guide to tuning each and every hyper-parameter. For this reason, we focus on 4 primary data sizes: -#. Tiny datasets where GPU is likely not needed (< 100 thousand vectors) -#. Small datasets where GPU might not be needed (< 1 million vectors) -#. Large datasets (> 1 million vectors), goal is fast index creation at the expense of search quality -#. Large datasets where high quality is preferred at the expense of fast index creation +1. Tiny datasets where GPU is likely not needed (< 100 thousand vectors) +1. Small datasets where GPU might not be needed (< 1 million vectors) +1. Large datasets (> 1 million vectors), goal is fast index creation at the expense of search quality +1. Large datasets where high quality is preferred at the expense of fast index creation Like other machine learning algorithms, vector search indexes generally have a training step – which means building the index – and an inference – or search step. The hyper-parameters also tend to be broken down into build and search parameters. While not always the case, a general trend is often observed where the search speed decreases as the quality increases. This also tends to be the case with the index build performance, though different algorithms have different relationships between build time, quality, and search time. It’s important to understand that there’s no free lunch so there will always be trade-offs for each index type. -Definition of quality -===================== +## Definition of quality What do we mean when we say quality of an index? In machine learning terminology, we measure this using recall, which is sometimes used interchangeably to mean accuracy, even though the two are slightly different measures. Recall, when used in vector search, essentially means “out of all of my results, which results would have been included in the exact results?” In vector search, the objective is to find some number of vectors that are closest to a given query vector so recall tends to be more relaxed than accuracy, discriminating only on set inclusion, rather than on exact ordered list matching, which would be closer to an accuracy measure. -Choosing vector search indexes -============================== +## Choosing vector search indexes Many vector search algorithms improve scalability while reducing the number of distances by partitioning the vector space into smaller pieces, often through the use of clustering, hashing, trees, and other techniques. Another popular technique is to reduce the width or dimensionality of the space in order to decrease the cost of computing each distance. -Tiny datasets (< 100 thousand vectors) --------------------------------------- +### Tiny datasets (< 100 thousand vectors) -These datasets are very small and it’s questionable whether or not the GPU would provide any value at all. If the dimensionality is also relatively small (< 1024), you could just use brute-force or HNSW on the CPU and get great performance. If the dimensionality is relatively large (1536, 2048, 4096), you should consider using HNSW. If build time performance is critical, you should consider using CAGRA to build the graph and convert it to an HNSW graph for search (this capability exists today in the standalone cuVS/RAFT libraries and will soon be added to Milvus). An IVF flat index can also be a great candidate here, as it can improve the search performance over brute-force by partitioning the vector space and thus reducing the search space. +These datasets are very small and it’s questionable whether or not the GPU would provide any value at all. If the dimensionality is also relatively small (< 1024), you could just use brute-force or HNSW on the CPU and get great performance. If the dimensionality is relatively large (1536, 2048, 4096), you should consider using HNSW. If build time performance is critical, you should consider using CAGRA to build the graph and convert it to an HNSW graph for search (this capability exists today in the standalone cuVS/RAFT libraries and will soon be added to Milvus). An IVF flat index can also be a great candidate here, as it can improve the search performance over brute-force by partitioning the vector space and thus reducing the search space. -Small datasets where GPU might not be needed (< 1 million vectors) ------------------------------------------------------------------- +### Small datasets where GPU might not be needed (< 1 million vectors) For smaller dimensionality, such as 1024 or below, you could consider using a brute-force (aka flat) index on GPU and get very good search performance with exact results. You could also use a graph-based index like HNSW on the CPU or CAGRA on the GPU. If build time is critical, you could even build a CAGRA graph on the GPU and convert it to HNSW graph on the CPU. For larger dimensionality (1536, 2048, 4096), you will start to see lower build-time performance with HNSW for higher quality search settings, and so it becomes more clear that building a CAGRA graph can be useful instead. -Large datasets (> 1 million vectors), goal is fast index creation at the expense of search quality --------------------------------------------------------------------------------------------------- +### Large datasets (> 1 million vectors), goal is fast index creation at the expense of search quality For fast ingest where slightly lower search quality is acceptable (85% recall and above), the IVF (inverted file index) methods can be very useful, as they can be very fast to build and still have acceptable search performance. IVF-flat index will partition the vectors into some number of clusters (specified by the user as n_lists) and at search time, some number of closest clusters (defined by n_probes) will be searched with brute-force for each query vector. IVF-PQ is similar to IVF-flat with the major difference that the vectors are compressed using a lossy product quantized compression so the index can have a much smaller footprint on the GPU. In general, it’s advised to set n_lists = sqrt(n_vectors) and set n_probes to some percentage of n_lists (e.g. 1%, 2%, 4%, 8%, 16%). Because IVF-PQ is a lossy compression, a refinement step can be performed by initially increasing the number of neighbors (by some multiple factor) and using the raw vectors to compute the exact distances, ultimately reducing the neighborhoods down to size k. Even a refinement of 2x (which would query initially for k*2) can be quite effective in making up for recall lost by the PQ compression, but it does come at the expense of having to keep the raw vectors around (keeping in mind many databases store the raw vectors anyways). -Large datasets (> 1 million vectors), goal is high quality search at the expense of fast index creation -------------------------------------------------------------------------------------------------------- +### Large datasets (> 1 million vectors), goal is high quality search at the expense of fast index creation By trading off index creation performance, an extremely high quality search model can be built. Generally, all of the vector search index types have hyperparameters that have a direct correlation with the search accuracy and so they can be cranked up to yield better recall. Unfortunately, this can also significantly increase the index build time and reduce the search throughput. The trick here is to find the fastest build time that can achieve the best recall with the lowest latency or highest throughput possible. As for suggested index types, graph-based algorithms like HNSW and CAGRA tend to scale very well to larger datasets while having superior search performance with respect to quality. The challenge is that graph-based indexes require learning a graph and so, as the subtitle of this section suggests, have a tendency to be slower to build than other options. Using the CAGRA algorithm on the GPU can reduce the build time significantly over HNSW, while also having a superior throughput (and lower latency) than searching on the CPU. Currently, the downside to using CAGRA on the GPU is that it requires both the graph and the raw vectors to fit into GPU memory. A middle-ground can be reached by building a CAGRA graph on the GPU and converting it to an HNSW for high quality (and moderately fast) search on the CPU. - -Tuning and hyperparameter optimization -====================================== +## Tuning and hyperparameter optimization Unfortunately, for large datasets, doing a hyper-parameter optimization on the whole dataset is not always feasible. It is possible, however, to perform a hyper-parameter optimization on the smaller subsets and find reasonably acceptable parameters that should generalize fairly well to the entire dataset. Generally this hyper-parameter optimization will require computing a ground truth on the subset with an exact method like brute-force and then using it to evaluate several searches on randomly sampled vectors. Full hyper-parameter optimization may also not always be necessary- for example, once you have built a ground truth dataset on a subset, many times you can start by building an index with the default build parameters and then playing around with different search parameters until you get the desired quality and search performance. For massive indexes that might be multiple terabytes, you could also take this subsampling of, say, 10M vectors, train an index and then tune the search parameters from there. While there might be a small margin of error, the chosen build/search parameters should generalize fairly well for the databases that build locally partitioned indexes. +## Summary of vector search index types -Summary of vector search index types -==================================== - -.. list-table:: - :widths: 25 25 50 - :header-rows: 1 - - * - Name - - Trade-offs - - Best to use with... - * - Brute-force (aka flat) - - Exact search but requires exhaustive distance computations - - Tiny datasets (< 100k vectors) - * - IVF-Flat - - Partitions the vector space to reduce distance computations for brute-force search at the expense of recall - - Small datasets (<1M vectors) or larger datasets (>1M vectors) where fast index build time is prioritized over quality. - * - IVF-PQ - - Adds product quantization to IVF-Flat to achieve scale at the expense of recall - - Large datasets (>>1M vectors) where fast index build is prioritized over quality - * - HNSW - - Significantly reduces distance computations at the expense of longer build times - - Small datasets (<1M vectors) or large datasets (>1M vectors) where quality and speed of search are prioritized over index build times - * - CAGRA - - Significantly reduces distance computations at the expense of longer build times (though build times improve over HNSW) - - Large datasets (>>1M vectors) where quality and speed of search are prioritized over index build times but index build times are still important. - * - CAGRA build +HNSW search - - (coming soon to Milvus) - - Significantly reduces distance computations and improves build times at the expense of higher search latency / lower throughput. - Large datasets (>>1M vectors) where index build times and quality of search is important but GPU resources are limited and latency of search is not. +| Name | Trade-offs | Best to use with... | +| --- | --- | --- | +| Brute-force (aka flat) | Exact search but requires exhaustive distance computations | Tiny datasets (< 100k vectors) | +| IVF-Flat | Partitions the vector space to reduce distance computations for brute-force search at the expense of recall | Small datasets (<1M vectors) or larger datasets (>1M vectors) where fast index build time is prioritized over quality. | +| IVF-PQ | Adds product quantization to IVF-Flat to achieve scale at the expense of recall | Large datasets (>>1M vectors) where fast index build is prioritized over quality | +| HNSW | Significantly reduces distance computations at the expense of longer build times | Small datasets (<1M vectors) or large datasets (>1M vectors) where quality and speed of search are prioritized over index build times | +| CAGRA | Significantly reduces distance computations at the expense of longer build times (though build times improve over HNSW) | Large datasets (>>1M vectors) where quality and speed of search are prioritized over index build times but index build times are still important. | +| CAGRA build +HNSW search | (coming soon to Milvus) | Significantly reduces distance computations and improves build times at the expense of higher search latency / lower throughput.
Large datasets (>>1M vectors) where index build times and quality of search is important but GPU resources are limited and latency of search is not. | diff --git a/docs/source/comparing_indexes.rst b/fern/pages/comparing_indexes.md similarity index 84% rename from docs/source/comparing_indexes.rst rename to fern/pages/comparing_indexes.md index 167aa2e072..544dce5dfb 100644 --- a/docs/source/comparing_indexes.rst +++ b/fern/pages/comparing_indexes.md @@ -1,28 +1,22 @@ -.. _comparing_indexes: +<a id="comparing_indexes"></a> -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Comparing performance of vector indexes -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Comparing performance of vector indexes -This document provides a brief overview methodology for comparing vector search indexes and models. For guidance on how to choose and configure an index type, please refer to :doc:`this ` guide. +This document provides a brief overview methodology for comparing vector search indexes and models. For guidance on how to choose and configure an index type, please refer to [this](vector_databases_vs_vector_search.md) guide. Unlike traditional database indexes, which will generally return correct results even without performance tuning, vector search indexes are more closely related to ML models and they can return absolutely garbage results if they have not been tuned. For this reason, it’s important to consider the parameters that an index is built upon, both for its potential quality and throughput/latency, when comparing two trained indexes. While easier to build an index on its default parameters than having to tune them, a well tuned index can have a significantly better search quality AND perform within search perf constraints like maximal throughput and minimal latency. - -What is recall? -=============== +## What is recall? Recall is a measure of model quality. Imagine for a particular vector, we know the exact nearest neighbors because we computed them already. The recall for a query result can be computed by taking the set intersection between the exact nearest neighbors and the actual nearest neighbors. The number of neighbors in that intersection list gets divided by k, the number of neighbors being requested. To really give a fair estimate of the recall of a model, we use several query vectors, all with ground truth computed, and we take the total neighbors across all intersected neighbor lists and divide by n_queries * k. Parameter settings dictate the quality of an index. The graph below shows eight indexes from the same data but with different tuning parameters. Generally speaking, the indexes with higher average recall took longer to build. Which index is fair to report? -.. image:: images/index_recalls.png - +![index recalls](images/index_recalls.png) -How do I compare models or indexing algorithms? -=============================================== +## How do I compare models or indexing algorithms? In order to fairly compare the performance (e.g. latency and throughput) of an indexing algorithm or model against another, we always need to do so with respect to its potential recall. This is important and draws from the ML roots of vector search, but is often confusing to newcomers who might be more familiar with the database world. @@ -32,29 +26,25 @@ Because recall levels can vary quite a bit across parameter settings, we tend to We suggest averaging performance within a range of recall. For general guidance, we tend to use the following buckets: -#. 85% - 89% -#. 90% - 94% -#. 95% - 99% -#. >99% - -.. image:: images/recall_buckets.png +1. 85% - 89% +1. 90% - 94% +1. 95% - 99% +1. >99% +![recall buckets](images/recall_buckets.png) This allows us to make observations such as “at 95% recall level, model A can be built 3x faster than model B, but model B has 2x lower latency than model A” -.. image:: images/build_benchmarks.png - +![build benchmarks](images/build_benchmarks.png) Another important detail is that we compare these models against their best-case search performance within each recall window. This means that we aim to find models that not only have great recall quality but also have either the highest throughput or lowest latency within the window of interest. These best-cases are most often computed by doing a parameter sweep in a grid search (or other types of search optimizers) and looking at the best cases for each level of recall. The resulting data points will construct a curve known as a Pareto optimum. Please note that this process is specifically for showing best-case across recall and throughput/latency, but when we care about finding the parameters that yield the best recall and search performance, we are essentially performing a hyperparameter optimization, which is common in machine learning. - -How do I do this on large vector databases? -=========================================== +## How do I do this on large vector databases? It turns out that most vector databases, like Milvus for example, make many smaller vector search indexing models for a single “index”, and the distribution of the vectors across the smaller index models are assumed to be completely uniform. This means we can use subsampling to our benefit, and tune on smaller sub-samples of the overall dataset. Please note, however, that there are often caps on the size of each of these smaller indexes, and that needs to be taken into consideration when choosing the size of the sub sample to tune. -Please see :doc:`this guide ` for more information on the steps one would take to do this subsampling and tuning process. +Please see [this guide](tuning_guide.md) for more information on the steps one would take to do this subsampling and tuning process. diff --git a/docs/source/contributing.md b/fern/pages/contributing.md similarity index 99% rename from docs/source/contributing.md rename to fern/pages/contributing.md index 1a58da4d75..91983b94f4 100755 --- a/docs/source/contributing.md +++ b/fern/pages/contributing.md @@ -18,7 +18,6 @@ into three categories: - If you need more context on a particular issue, please ask and we shall provide. - ## Code contributions ### Your first issue @@ -37,7 +36,6 @@ into three categories: Remember, if you are unsure about anything, don't hesitate to comment on issues and ask for clarifications! - ### Python / Pre-commit hooks CUVS uses [pre-commit](https://pre-commit.com/) to execute code linters and formatters such as @@ -73,7 +71,6 @@ Now code linters and formatters will be run each time you commit changes. You can skip these checks with `git commit --no-verify` or with the short version `git commit -n`. - ### Seasoned developers Once you have gotten your feet wet and are more comfortable with the code, you diff --git a/fern/pages/cpp_api/cpp-api-cluster-agglomerative.md b/fern/pages/cpp_api/cpp-api-cluster-agglomerative.md new file mode 100644 index 0000000000..58bc0cc11e --- /dev/null +++ b/fern/pages/cpp_api/cpp-api-cluster-agglomerative.md @@ -0,0 +1,218 @@ +--- +slug: api-reference/cpp-api-cluster-agglomerative +--- + +# Agglomerative + +_Source header: `cpp/include/cuvs/cluster/agglomerative.hpp`_ + +## agglomerative clustering hyperparameters + +_Doxygen group: `agglomerative_params`_ + +### cuvs::cluster::agglomerative::Linkage + +Determines the method for computing the minimum spanning tree (MST) + +```cpp +enum Linkage { ... } ; +``` + +**Values** + +| Name | Value | +| --- | --- | +| `PAIRWISE` | `0` | +| `KNN_GRAPH` | `1` | + +_Source: `cpp/include/cuvs/cluster/agglomerative.hpp:30`_ + +## single-linkage clustering APIs + +_Doxygen group: `single_linkage`_ + +### cuvs::cluster::agglomerative::single_linkage + +Single-linkage clustering, capable of constructing a KNN graph to + +```cpp +void single_linkage( +raft::resources const& handle, +raft::device_matrix_view X, +raft::device_matrix_view dendrogram, +raft::device_vector_view labels, +cuvs::distance::DistanceType metric, +size_t n_clusters, +cuvs::cluster::agglomerative::Linkage linkage = cuvs::cluster::agglomerative::Linkage::KNN_GRAPH, +std::optional c = std::make_optional(DEFAULT_CONST_C)); +``` + +scale the algorithm beyond the n^2 memory consumption of implementations that use the fully-connected graph of pairwise distances by connecting a knn graph when k is not large enough to connect it. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | raft handle | +| `X` | in | `raft::device_matrix_view` | dense input matrix in row-major layout | +| `dendrogram` | out | `raft::device_matrix_view` | output dendrogram (size [n_rows - 1] * 2) | +| `labels` | out | `raft::device_vector_view` | output labels vector (size n_rows) | +| `metric` | in | `cuvs::distance::DistanceType` | distance metric to use when constructing connectivities graph | +| `n_clusters` | in | `size_t` | number of clusters to assign data samples | +| `linkage` | in | `cuvs::cluster::agglomerative::Linkage` | strategy for constructing the linkage. PAIRWISE uses more memory but can be faster for smaller datasets. KNN_GRAPH allows the memory usage to be controlled (using parameter c) at the expense of potentially additional minimum spanning tree iterations. Default: `cuvs::cluster::agglomerative::Linkage::KNN_GRAPH`. | +| `c` | in | `std::optional` | a constant used when constructing linkage from knn graph. Allows the indirect control of k. The algorithm will set `k = log(n) + c` Default: `std::make_optional<int>(DEFAULT_CONST_C)`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/cluster/agglomerative.hpp:104`_ + +### linkage_graph_params::distance_params + +Specialized parameters to build the KNN graph with regular distances + +```cpp +struct distance_params { ... } ; +``` + +**Fields** + +| Name | Type | Description | +| --- | --- | --- | +| `c` | `int` | a constant used when constructing linkage from knn graph. Allows the indirect control of k. | +| `dist_type` | `cuvs::cluster::agglomerative::Linkage` | strategy for constructing the linkage. PAIRWISE uses more memory but can be faster for smaller | + +_Source: `cpp/include/cuvs/cluster/agglomerative.hpp:118`_ + +### linkage_graph_params::mutual_reachability_params + +Specialized parameters to build the Mutual Reachability graph + +```cpp +struct mutual_reachability_params { ... } ; +``` + +**Fields** + +| Name | Type | Description | +| --- | --- | --- | +| `min_samples` | `int` | this neighborhood will be selected for core distances. | +| `alpha` | `float` | weight applied when internal distance is chosen for mutual reachability (value of 1.0 disables | +| `cuvs::neighbors::all_neighbors::all_neighbors_params all_neighbors_params{ cuvs::neighbors::graph_build_params::brute_force_params{}}` | `cuvs::neighbors::all_neighbors::all_neighbors_params all_neighbors_params{ cuvs::neighbors::graph_build_params::brute_force_params{}}` | Parameters for building the mutual reachability graph using an underlying KNN algorithm. | + +_Source: `cpp/include/cuvs/cluster/agglomerative.hpp:130`_ + +### linkage_graph_params::build_linkage + +Given a dataset, builds the KNN graph, connects graph components and builds a linkage + +```cpp +void build_linkage( +raft::resources const& handle, +raft::device_matrix_view X, +std::variant linkage_graph_params, +cuvs::distance::DistanceType metric, +raft::device_coo_matrix_view out_mst, +raft::device_matrix_view dendrogram, +raft::device_vector_view out_distances, +raft::device_vector_view out_sizes, +std::optional> core_dists); +``` + +(dendrogram). Returns the Minimum Spanning Tree edges sorted by weight and the dendrogram. Reachability space + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | raft handle for resource reuse | +| `X` | in | `raft::device_matrix_view` | data points on device memory (size n_rows * d) | +| `linkage_graph_params` | in | `std::variant` | Parameters controlling how the KNN graph is built. This can be either: - distance_params: standard distance-based KNN graph construction for traditional agglomerative clustering. - mutual_reachability_params: parameters to compute a mutual reachability graph for density-aware hierarchical clustering (e.g. HDBSCAN). | +| `metric` | in | `cuvs::distance::DistanceType` | distance metric to use | +| `out_mst` | out | `raft::device_coo_matrix_view` | output MST sorted by edge weights (size n_rows - 1) | +| `dendrogram` | out | `raft::device_matrix_view` | output dendrogram (size [n_rows - 1] * 2) | +| `out_distances` | out | `raft::device_vector_view` | distances for output | +| `out_sizes` | out | `raft::device_vector_view` | cluster sizes of output | +| `core_dists` | out | `std::optional>` | (optional) core distances (size m). Must be supplied in the Mutual | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/cluster/agglomerative.hpp:188`_ + +### linkage_graph_params::build_linkage + +Given a dataset, builds the KNN graph, connects graph components and builds a linkage + +```cpp +void build_linkage( +raft::resources const& handle, +raft::host_matrix_view X, +std::variant linkage_graph_params, +cuvs::distance::DistanceType metric, +raft::device_coo_matrix_view out_mst, +raft::device_matrix_view dendrogram, +raft::device_vector_view out_distances, +raft::device_vector_view out_sizes, +std::optional> core_dists); +``` + +(dendrogram). Returns the Minimum Spanning Tree edges sorted by weight and the dendrogram. Reachability space + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | raft handle for resource reuse | +| `X` | in | `raft::host_matrix_view` | data points on host memory (size n_rows * d) | +| `linkage_graph_params` | in | `std::variant` | Parameters controlling how the KNN graph is built. This can be either: - distance_params: standard distance-based KNN graph construction for traditional agglomerative clustering. - mutual_reachability_params: parameters to compute a mutual reachability graph for density-aware hierarchical clustering (e.g. HDBSCAN). | +| `metric` | in | `cuvs::distance::DistanceType` | distance metric to use | +| `out_mst` | out | `raft::device_coo_matrix_view` | output MST sorted by edge weights (size n_rows - 1) | +| `dendrogram` | out | `raft::device_matrix_view` | output dendrogram (size [n_rows - 1] * 2) | +| `out_distances` | out | `raft::device_vector_view` | distances for output | +| `out_sizes` | out | `raft::device_vector_view` | cluster sizes of output | +| `core_dists` | out | `std::optional>` | (optional) core distances (size m). Must be supplied in the Mutual | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/cluster/agglomerative.hpp:219`_ + +### linkage_graph_params::build_dendrogram + +Build dendrogram from a Minimum Spanning Tree (MST). + +```cpp +void build_dendrogram(raft::resources const& handle, +raft::device_vector_view rows, +raft::device_vector_view cols, +raft::device_vector_view data, +raft::device_matrix_view children, +raft::device_vector_view out_delta, +raft::device_vector_view out_size); +``` + +This function takes a sorted MST (represented as edges with source, destination, and weights) and constructs a dendrogram (hierarchical clustering tree) on the host. nnz) + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | The raft resources handle | +| `rows` | in | `raft::device_vector_view` | Source nodes of the MST edges (device memory, size: nnz) | +| `cols` | in | `raft::device_vector_view` | Destination nodes of the MST edges (device memory, size: nnz) | +| `data` | in | `raft::device_vector_view` | Edge weights/distances of the MST (device memory, size: nnz) | +| `children` | out | `raft::device_matrix_view` | Output dendrogram children array (device memory, size: nnz * 2) Each pair of consecutive elements represents the two children merged at each step of the hierarchy | +| `out_delta` | out | `raft::device_vector_view` | Output distances/heights at which clusters are merged (device memory, size: | +| `out_size` | out | `raft::device_vector_view` | Output cluster sizes at each merge step (device memory, size: nnz) | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/cluster/agglomerative.hpp:248`_ diff --git a/fern/pages/cpp_api/cpp-api-cluster-kmeans.md b/fern/pages/cpp_api/cpp-api-cluster-kmeans.md new file mode 100644 index 0000000000..7bbb2a5187 --- /dev/null +++ b/fern/pages/cpp_api/cpp-api-cluster-kmeans.md @@ -0,0 +1,1150 @@ +--- +slug: api-reference/cpp-api-cluster-kmeans +--- + +# K-Means + +_Source header: `cpp/include/cuvs/cluster/kmeans.hpp`_ + +## k-means hyperparameters + +_Doxygen group: `kmeans_params`_ + +### cuvs::cluster::kmeans::params + +Simple object to specify hyper-parameters to the kmeans algorithm. + +```cpp +struct params : base_params { ... } ; +``` + +**Fields** + +| Name | Type | Description | +| --- | --- | --- | +| `KMeansPlusPlus,` | `KMeansPlusPlus,` | Sample the centroids using the kmeans++ strategy | +| `Random,` | `Random,` | Sample the centroids uniformly at random | +| `Array` | `Array` | User provides the array of initial centroids | +| `n_clusters` | `int` | The number of clusters to form as well as the number of centroids to generate (default:8). | +| `init` | `InitMethod` | Method for initialization, defaults to k-means++: | +| `max_iter` | `int` | Maximum number of iterations of the k-means algorithm for a single run. | +| `tol` | `double` | Relative tolerance with regards to inertia to declare convergence. | +| `verbosity` | `rapids_logger::level_enum` | verbosity level. | +| `raft::random::RngState rng_state{0}` | `raft::random::RngState rng_state{0}` | Seed to the random number generator. | +| `n_init` | `int` | Number of instance k-means algorithm will be run with different seeds. | +| `oversampling_factor` | `double` | Oversampling factor for use in the k-means\|\| algorithm | +| `batch_samples` | `int` | batch_samples and batch_centroids are used to tile 1NN computation which is | +| `batch_centroids` | `int` | if 0 then batch_centroids = n_clusters | +| `inertia_check` | `bool` | If true, check inertia during iterations for early convergence. | +| `streaming_batch_size` | `int64_t` | Number of samples to process per GPU batch when fitting with host data. | + +_Source: `cpp/include/cuvs/cluster/kmeans.hpp:34`_ + +### cuvs::cluster::kmeans::balanced_params + +Simple object to specify hyper-parameters to the balanced k-means algorithm. + +The following metrics are currently supported in k-means balanced: - CosineExpanded - InnerProduct - L2Expanded - L2SqrtExpanded + +```cpp +struct balanced_params : base_params { ... } ; +``` + +**Fields** + +| Name | Type | Description | +| --- | --- | --- | +| `n_iters` | `uint32_t` | Number of training iterations | + +_Source: `cpp/include/cuvs/cluster/kmeans.hpp:139`_ + +### cuvs::cluster::kmeans::kmeans_type + +Type of k-means algorithm. + +```cpp +enum class kmeans_type { ... } ; +``` + +**Values** + +| Name | Value | +| --- | --- | +| `KMeans` | `0` | +| `KMeansBalanced` | `1` | + +_Source: `cpp/include/cuvs/cluster/kmeans.hpp:149`_ + +## k-means clustering APIs + +_Doxygen group: `kmeans`_ + +### cuvs::cluster::kmeans::fit + +Find clusters with k-means algorithm using batched processing of host data. + +```cpp +void fit(raft::resources const& handle, +const cuvs::cluster::kmeans::params& params, +raft::host_matrix_view X, +std::optional> sample_weight, +raft::device_matrix_view centroids, +raft::host_scalar_view inertia, +raft::host_scalar_view n_iter); +``` + +TODO: Evaluate replacing the extent type with int64_t. Reference issue: https://github.com/rapidsai/cuvs/issues/1961 This overload supports out-of-core computation where the dataset resides on the host. Data is processed in GPU-sized batches, streaming from host to device. The batch size is controlled by params.streaming_batch_size. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | The raft handle. | +| `params` | in | `const cuvs::cluster::kmeans::params&` | Parameters for KMeans model. Batch size is read from params.streaming_batch_size. | +| `X` | in | `raft::host_matrix_view` | Training instances on HOST memory. The data must be in row-major format. [dim = n_samples x n_features] | +| `sample_weight` | in | `std::optional>` | Optional weights for each observation in X (on host). [len = n_samples] | +| `centroids` | inout | `raft::device_matrix_view` | [in] When init is InitMethod::Array, use centroids as the initial cluster centers. [out] The generated centroids from the kmeans algorithm are stored at the address pointed by 'centroids'. [dim = n_clusters x n_features] | +| `inertia` | out | `raft::host_scalar_view` | Sum of squared distances of samples to their closest cluster center. | +| `n_iter` | out | `raft::host_scalar_view` | Number of iterations run. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/cluster/kmeans.hpp:217`_ + +### cuvs::cluster::kmeans::fit + +Find clusters with k-means algorithm using batched processing of host data. + +```cpp +void fit(raft::resources const& handle, +const cuvs::cluster::kmeans::params& params, +raft::host_matrix_view X, +std::optional> sample_weight, +raft::device_matrix_view centroids, +raft::host_scalar_view inertia, +raft::host_scalar_view n_iter); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | | `raft::resources const&` | | +| `params` | | `const cuvs::cluster::kmeans::params&` | | +| `X` | | `raft::host_matrix_view` | | +| `sample_weight` | | `std::optional>` | | +| `centroids` | | `raft::device_matrix_view` | | +| `inertia` | | `raft::host_scalar_view` | | +| `n_iter` | | `raft::host_scalar_view` | | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/cluster/kmeans.hpp:228`_ + +### cuvs::cluster::kmeans::fit + +Find clusters with k-means algorithm. + +```cpp +void fit(raft::resources const& handle, +const cuvs::cluster::kmeans::params& params, +raft::device_matrix_view X, +std::optional> sample_weight, +raft::device_matrix_view centroids, +raft::host_scalar_view inertia, +raft::host_scalar_view n_iter); +``` + +Initial centroids are chosen with k-means++ algorithm. Empty clusters are reinitialized by choosing new centroids with k-means++ algorithm. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | The raft handle. | +| `params` | in | `const cuvs::cluster::kmeans::params&` | Parameters for KMeans model. | +| `X` | in | `raft::device_matrix_view` | Training instances to cluster. The data must be in row-major format. [dim = n_samples x n_features] | +| `sample_weight` | in | `std::optional>` | Optional weights for each observation in X. [len = n_samples] | +| `centroids` | inout | `raft::device_matrix_view` | [in] When init is InitMethod::Array, use centroids as the initial cluster centers. [out] The generated centroids from the kmeans algorithm are stored at the address pointed by 'centroids'. [dim = n_clusters x n_features] | +| `inertia` | out | `raft::host_scalar_view` | Sum of squared distances of samples to their closest cluster center. | +| `n_iter` | out | `raft::host_scalar_view` | Number of iterations run. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/cluster/kmeans.hpp:278`_ + +### cuvs::cluster::kmeans::fit + +Find clusters with k-means algorithm. + +```cpp +void fit(raft::resources const& handle, +const cuvs::cluster::kmeans::params& params, +raft::device_matrix_view X, +std::optional> sample_weight, +raft::device_matrix_view centroids, +raft::host_scalar_view inertia, +raft::host_scalar_view n_iter); +``` + +Initial centroids are chosen with k-means++ algorithm. Empty clusters are reinitialized by choosing new centroids with k-means++ algorithm. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | The raft handle. | +| `params` | in | `const cuvs::cluster::kmeans::params&` | Parameters for KMeans model. | +| `X` | in | `raft::device_matrix_view` | Training instances to cluster. The data must be in row-major format. [dim = n_samples x n_features] | +| `sample_weight` | in | `std::optional>` | Optional weights for each observation in X. [len = n_samples] | +| `centroids` | inout | `raft::device_matrix_view` | [in] When init is InitMethod::Array, use centroids as the initial cluster centers. [out] The generated centroids from the kmeans algorithm are stored at the address pointed by 'centroids'. [dim = n_clusters x n_features] | +| `inertia` | out | `raft::host_scalar_view` | Sum of squared distances of samples to their closest cluster center. | +| `n_iter` | out | `raft::host_scalar_view` | Number of iterations run. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/cluster/kmeans.hpp:329`_ + +### cuvs::cluster::kmeans::fit + +Find clusters with k-means algorithm. + +```cpp +void fit(raft::resources const& handle, +const cuvs::cluster::kmeans::params& params, +raft::device_matrix_view X, +std::optional> sample_weight, +raft::device_matrix_view centroids, +raft::host_scalar_view inertia, +raft::host_scalar_view n_iter); +``` + +Initial centroids are chosen with k-means++ algorithm. Empty clusters are reinitialized by choosing new centroids with k-means++ algorithm. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | The raft handle. | +| `params` | in | `const cuvs::cluster::kmeans::params&` | Parameters for KMeans model. | +| `X` | in | `raft::device_matrix_view` | Training instances to cluster. The data must be in row-major format. [dim = n_samples x n_features] | +| `sample_weight` | in | `std::optional>` | Optional weights for each observation in X. [len = n_samples] | +| `centroids` | inout | `raft::device_matrix_view` | [in] When init is InitMethod::Array, use centroids as the initial cluster centers. [out] The generated centroids from the kmeans algorithm are stored at the address pointed by 'centroids'. [dim = n_clusters x n_features] | +| `inertia` | out | `raft::host_scalar_view` | Sum of squared distances of samples to their closest cluster center. | +| `n_iter` | out | `raft::host_scalar_view` | Number of iterations run. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/cluster/kmeans.hpp:379`_ + +### cuvs::cluster::kmeans::fit + +Find clusters with k-means algorithm. + +```cpp +void fit(raft::resources const& handle, +const cuvs::cluster::kmeans::params& params, +raft::device_matrix_view X, +std::optional> sample_weight, +raft::device_matrix_view centroids, +raft::host_scalar_view inertia, +raft::host_scalar_view n_iter); +``` + +Initial centroids are chosen with k-means++ algorithm. Empty clusters are reinitialized by choosing new centroids with k-means++ algorithm. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | The raft handle. | +| `params` | in | `const cuvs::cluster::kmeans::params&` | Parameters for KMeans model. | +| `X` | in | `raft::device_matrix_view` | Training instances to cluster. The data must be in row-major format. [dim = n_samples x n_features] | +| `sample_weight` | in | `std::optional>` | Optional weights for each observation in X. [len = n_samples] | +| `centroids` | inout | `raft::device_matrix_view` | [in] When init is InitMethod::Array, use centroids as the initial cluster centers. [out] The generated centroids from the kmeans algorithm are stored at the address pointed by 'centroids'. [dim = n_clusters x n_features] | +| `inertia` | out | `raft::host_scalar_view` | Sum of squared distances of samples to their closest cluster center. | +| `n_iter` | out | `raft::host_scalar_view` | Number of iterations run. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/cluster/kmeans.hpp:430`_ + +### cuvs::cluster::kmeans::fit + +Find clusters with k-means algorithm. + +```cpp +void fit(raft::resources const& handle, +const cuvs::cluster::kmeans::params& params, +raft::device_matrix_view X, +std::optional> sample_weight, +raft::device_matrix_view centroids, +raft::host_scalar_view inertia, +raft::host_scalar_view n_iter); +``` + +Initial centroids are chosen with k-means++ algorithm. Empty clusters are reinitialized by choosing new centroids with k-means++ algorithm. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | The raft handle. | +| `params` | in | `const cuvs::cluster::kmeans::params&` | Parameters for KMeans model. | +| `X` | in | `raft::device_matrix_view` | Training instances to cluster. The data must be in row-major format. [dim = n_samples x n_features] | +| `sample_weight` | in | `std::optional>` | Optional weights for each observation in X. [len = n_samples] | +| `centroids` | inout | `raft::device_matrix_view` | [in] When init is InitMethod::Array, use centroids as the initial cluster centers. [out] The generated centroids from the kmeans algorithm are stored at the address pointed by 'centroids'. [dim = n_clusters x n_features] | +| `inertia` | out | `raft::host_scalar_view` | Sum of squared distances of samples to their closest cluster center. | +| `n_iter` | out | `raft::host_scalar_view` | Number of iterations run. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/cluster/kmeans.hpp:480`_ + +### cuvs::cluster::kmeans::fit + +Find balanced clusters with k-means algorithm. + +```cpp +void fit(const raft::resources& handle, +cuvs::cluster::kmeans::balanced_params const& params, +raft::device_matrix_view X, +raft::device_matrix_view centroids, +std::optional> inertia = std::nullopt); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `const raft::resources&` | The raft handle. | +| `params` | in | `cuvs::cluster::kmeans::balanced_params const&` | Parameters for KMeans model. | +| `X` | in | `raft::device_matrix_view` | Training instances to cluster. The data must be in row-major format. [dim = n_samples x n_features] | +| `centroids` | out | `raft::device_matrix_view` | [out] The generated centroids from the kmeans algorithm are stored at the address pointed by 'centroids'. [dim = n_clusters x n_features] | +| `inertia` | out | `std::optional>` | Sum of squared distances of samples to their closest cluster center. Default: `std::nullopt`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/cluster/kmeans.hpp:520`_ + +### cuvs::cluster::kmeans::fit + +Find balanced clusters with k-means algorithm. + +```cpp +void fit(const raft::resources& handle, +cuvs::cluster::kmeans::balanced_params const& params, +raft::device_matrix_view X, +raft::device_matrix_view centroids, +std::optional> inertia = std::nullopt); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `const raft::resources&` | The raft handle. | +| `params` | in | `cuvs::cluster::kmeans::balanced_params const&` | Parameters for KMeans model. | +| `X` | in | `raft::device_matrix_view` | Training instances to cluster. The data must be in row-major format. [dim = n_samples x n_features] | +| `centroids` | inout | `raft::device_matrix_view` | [out] The generated centroids from the kmeans algorithm are stored at the address pointed by 'centroids'. [dim = n_clusters x n_features] | +| `inertia` | out | `std::optional>` | Sum of squared distances of samples to their closest cluster center. Default: `std::nullopt`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/cluster/kmeans.hpp:557`_ + +### cuvs::cluster::kmeans::fit + +Find balanced clusters with k-means algorithm. + +```cpp +void fit(const raft::resources& handle, +cuvs::cluster::kmeans::balanced_params const& params, +raft::device_matrix_view X, +raft::device_matrix_view centroids, +std::optional> inertia = std::nullopt); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `const raft::resources&` | The raft handle. | +| `params` | in | `cuvs::cluster::kmeans::balanced_params const&` | Parameters for KMeans model. | +| `X` | in | `raft::device_matrix_view` | Training instances to cluster. The data must be in row-major format. [dim = n_samples x n_features] | +| `centroids` | inout | `raft::device_matrix_view` | [out] The generated centroids from the kmeans algorithm are stored at the address pointed by 'centroids'. [dim = n_clusters x n_features] | +| `inertia` | out | `std::optional>` | Sum of squared distances of samples to their closest cluster center. Default: `std::nullopt`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/cluster/kmeans.hpp:594`_ + +### cuvs::cluster::kmeans::fit + +Find balanced clusters with k-means algorithm. + +```cpp +void fit(const raft::resources& handle, +cuvs::cluster::kmeans::balanced_params const& params, +raft::device_matrix_view X, +raft::device_matrix_view centroids, +std::optional> inertia = std::nullopt); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `const raft::resources&` | The raft handle. | +| `params` | in | `cuvs::cluster::kmeans::balanced_params const&` | Parameters for KMeans model. | +| `X` | in | `raft::device_matrix_view` | Training instances to cluster. The data must be in row-major format. [dim = n_samples x n_features] | +| `centroids` | inout | `raft::device_matrix_view` | [out] The generated centroids from the kmeans algorithm are stored at the address pointed by 'centroids'. [dim = n_clusters x n_features] | +| `inertia` | out | `std::optional>` | Sum of squared distances of samples to their closest cluster center. Default: `std::nullopt`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/cluster/kmeans.hpp:631`_ + +### cuvs::cluster::kmeans::predict + +Predict the closest cluster each sample in X belongs to. + +```cpp +void predict(raft::resources const& handle, +const kmeans::params& params, +raft::device_matrix_view X, +std::optional> sample_weight, +raft::device_matrix_view centroids, +raft::device_vector_view labels, +bool normalize_weight, +raft::host_scalar_view inertia); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | The raft handle. | +| `params` | in | `const kmeans::params&` | Parameters for KMeans model. | +| `X` | in | `raft::device_matrix_view` | New data to predict. [dim = n_samples x n_features] | +| `sample_weight` | in | `std::optional>` | Optional weights for each observation in X. [len = n_samples] | +| `centroids` | in | `raft::device_matrix_view` | Cluster centroids. The data must be in row-major format. [dim = n_clusters x n_features] | +| `labels` | out | `raft::device_vector_view` | Index of the cluster each sample in X belongs to. [len = n_samples] | +| `normalize_weight` | in | `bool` | True if the weights should be normalized | +| `inertia` | out | `raft::host_scalar_view` | Sum of squared distances of samples to their closest cluster center. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/cluster/kmeans.hpp:686`_ + +### cuvs::cluster::kmeans::predict + +Predict the closest cluster each sample in X belongs to. + +```cpp +void predict(raft::resources const& handle, +const kmeans::params& params, +raft::device_matrix_view X, +std::optional> sample_weight, +raft::device_matrix_view centroids, +raft::device_vector_view labels, +bool normalize_weight, +raft::host_scalar_view inertia); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | The raft handle. | +| `params` | in | `const kmeans::params&` | Parameters for KMeans model. | +| `X` | in | `raft::device_matrix_view` | New data to predict. [dim = n_samples x n_features] | +| `sample_weight` | in | `std::optional>` | Optional weights for each observation in X. [len = n_samples] | +| `centroids` | in | `raft::device_matrix_view` | Cluster centroids. The data must be in row-major format. [dim = n_clusters x n_features] | +| `labels` | out | `raft::device_vector_view` | Index of the cluster each sample in X belongs to. [len = n_samples] | +| `normalize_weight` | in | `bool` | True if the weights should be normalized | +| `inertia` | out | `raft::host_scalar_view` | Sum of squared distances of samples to their closest cluster center. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/cluster/kmeans.hpp:753`_ + +### cuvs::cluster::kmeans::predict + +Predict the closest cluster each sample in X belongs to. + +```cpp +void predict(raft::resources const& handle, +const kmeans::params& params, +raft::device_matrix_view X, +std::optional> sample_weight, +raft::device_matrix_view centroids, +raft::device_vector_view labels, +bool normalize_weight, +raft::host_scalar_view inertia); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | The raft handle. | +| `params` | in | `const kmeans::params&` | Parameters for KMeans model. | +| `X` | in | `raft::device_matrix_view` | New data to predict. [dim = n_samples x n_features] | +| `sample_weight` | in | `std::optional>` | Optional weights for each observation in X. [len = n_samples] | +| `centroids` | in | `raft::device_matrix_view` | Cluster centroids. The data must be in row-major format. [dim = n_clusters x n_features] | +| `labels` | out | `raft::device_vector_view` | Index of the cluster each sample in X belongs to. [len = n_samples] | +| `normalize_weight` | in | `bool` | True if the weights should be normalized | +| `inertia` | out | `raft::host_scalar_view` | Sum of squared distances of samples to their closest cluster center. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/cluster/kmeans.hpp:811`_ + +### cuvs::cluster::kmeans::predict + +Predict the closest cluster each sample in X belongs to. + +```cpp +void predict(raft::resources const& handle, +const kmeans::params& params, +raft::device_matrix_view X, +std::optional> sample_weight, +raft::device_matrix_view centroids, +raft::device_vector_view labels, +bool normalize_weight, +raft::host_scalar_view inertia); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | The raft handle. | +| `params` | in | `const kmeans::params&` | Parameters for KMeans model. | +| `X` | in | `raft::device_matrix_view` | New data to predict. [dim = n_samples x n_features] | +| `sample_weight` | in | `std::optional>` | Optional weights for each observation in X. [len = n_samples] | +| `centroids` | in | `raft::device_matrix_view` | Cluster centroids. The data must be in row-major format. [dim = n_clusters x n_features] | +| `labels` | out | `raft::device_vector_view` | Index of the cluster each sample in X belongs to. [len = n_samples] | +| `normalize_weight` | in | `bool` | True if the weights should be normalized | +| `inertia` | out | `raft::host_scalar_view` | Sum of squared distances of samples to their closest cluster center. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/cluster/kmeans.hpp:869`_ + +### cuvs::cluster::kmeans::predict + +Predict the closest cluster each sample in X belongs to. + +```cpp +void predict(const raft::resources& handle, +cuvs::cluster::kmeans::balanced_params const& params, +raft::device_matrix_view X, +raft::device_matrix_view centroids, +raft::device_vector_view labels); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `const raft::resources&` | The raft handle. | +| `params` | in | `cuvs::cluster::kmeans::balanced_params const&` | Parameters for KMeans model. | +| `X` | in | `raft::device_matrix_view` | New data to predict. [dim = n_samples x n_features] | +| `centroids` | in | `raft::device_matrix_view` | Cluster centroids. The data must be in row-major format. [dim = n_clusters x n_features] | +| `labels` | out | `raft::device_vector_view` | Index of the cluster each sample in X belongs to. [len = n_samples] | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/cluster/kmeans.hpp:916`_ + +### cuvs::cluster::kmeans::predict + +Predict the closest cluster each sample in X belongs to. + +```cpp +void predict(const raft::resources& handle, +cuvs::cluster::kmeans::balanced_params const& params, +raft::device_matrix_view X, +raft::device_matrix_view centroids, +raft::device_vector_view labels); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `const raft::resources&` | The raft handle. | +| `params` | in | `cuvs::cluster::kmeans::balanced_params const&` | Parameters for KMeans model. | +| `X` | in | `raft::device_matrix_view` | New data to predict. [dim = n_samples x n_features] | +| `centroids` | in | `raft::device_matrix_view` | Cluster centroids. The data must be in row-major format. [dim = n_clusters x n_features] | +| `labels` | out | `raft::device_vector_view` | Index of the cluster each sample in X belongs to. [len = n_samples] | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/cluster/kmeans.hpp:960`_ + +### cuvs::cluster::kmeans::predict + +Predict the closest cluster each sample in X belongs to. + +```cpp +void predict(const raft::resources& handle, +cuvs::cluster::kmeans::balanced_params const& params, +raft::device_matrix_view X, +raft::device_matrix_view centroids, +raft::device_vector_view labels); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `const raft::resources&` | The raft handle. | +| `params` | in | `cuvs::cluster::kmeans::balanced_params const&` | Parameters for KMeans model. | +| `X` | in | `raft::device_matrix_view` | New data to predict. [dim = n_samples x n_features] | +| `centroids` | in | `raft::device_matrix_view` | Cluster centroids. The data must be in row-major format. [dim = n_clusters x n_features] | +| `labels` | out | `raft::device_vector_view` | Index of the cluster each sample in X belongs to. [len = n_samples] | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/cluster/kmeans.hpp:1004`_ + +### cuvs::cluster::kmeans::predict + +Predict the closest cluster each sample in X belongs to. + +```cpp +void predict(const raft::resources& handle, +cuvs::cluster::kmeans::balanced_params const& params, +raft::device_matrix_view X, +raft::device_matrix_view centroids, +raft::device_vector_view labels); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `const raft::resources&` | The raft handle. | +| `params` | in | `cuvs::cluster::kmeans::balanced_params const&` | Parameters for KMeans model. | +| `X` | in | `raft::device_matrix_view` | New data to predict. [dim = n_samples x n_features] | +| `centroids` | in | `raft::device_matrix_view` | Cluster centroids. The data must be in row-major format. [dim = n_clusters x n_features] | +| `labels` | out | `raft::device_vector_view` | Index of the cluster each sample in X belongs to. [len = n_samples] | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/cluster/kmeans.hpp:1048`_ + +### cuvs::cluster::kmeans::predict + +Predict the closest cluster each sample in X belongs to. + +```cpp +void predict(const raft::resources& handle, +cuvs::cluster::kmeans::balanced_params const& params, +raft::device_matrix_view X, +raft::device_matrix_view centroids, +raft::device_vector_view labels); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `const raft::resources&` | The raft handle. | +| `params` | in | `cuvs::cluster::kmeans::balanced_params const&` | Parameters for KMeans model. | +| `X` | in | `raft::device_matrix_view` | New data to predict. [dim = n_samples x n_features] | +| `centroids` | in | `raft::device_matrix_view` | Cluster centroids. The data must be in row-major format. [dim = n_clusters x n_features] | +| `labels` | out | `raft::device_vector_view` | Index of the cluster each sample in X belongs to. [len = n_samples] | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/cluster/kmeans.hpp:1092`_ + +### cuvs::cluster::kmeans::predict + +Predict the closest cluster each sample in X belongs to. + +```cpp +void predict(const raft::resources& handle, +cuvs::cluster::kmeans::balanced_params const& params, +raft::device_matrix_view X, +raft::device_matrix_view centroids, +raft::device_vector_view labels); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `const raft::resources&` | The raft handle. | +| `params` | in | `cuvs::cluster::kmeans::balanced_params const&` | Parameters for KMeans model. | +| `X` | in | `raft::device_matrix_view` | New data to predict. [dim = n_samples x n_features] | +| `centroids` | in | `raft::device_matrix_view` | Cluster centroids. The data must be in row-major format. [dim = n_clusters x n_features] | +| `labels` | out | `raft::device_vector_view` | Index of the cluster each sample in X belongs to. [len = n_samples] | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/cluster/kmeans.hpp:1136`_ + +### cuvs::cluster::kmeans::fit_predict + +Compute k-means clustering and predicts cluster index for each sample + +```cpp +void fit_predict(raft::resources const& handle, +const kmeans::params& params, +raft::device_matrix_view X, +std::optional> sample_weight, +std::optional> centroids, +raft::device_vector_view labels, +raft::host_scalar_view inertia, +raft::host_scalar_view n_iter); +``` + +in the input. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | The raft handle. | +| `params` | in | `const kmeans::params&` | Parameters for KMeans model. | +| `X` | in | `raft::device_matrix_view` | Training instances to cluster. The data must be in row-major format. [dim = n_samples x n_features] | +| `sample_weight` | in | `std::optional>` | Optional weights for each observation in X. [len = n_samples] | +| `centroids` | inout | `std::optional>` | Optional [in] When init is InitMethod::Array, use centroids as the initial cluster centers [out] The generated centroids from the kmeans algorithm are stored at the address pointed by 'centroids'. [dim = n_clusters x n_features] | +| `labels` | out | `raft::device_vector_view` | Index of the cluster each sample in X belongs to. [len = n_samples] | +| `inertia` | out | `raft::host_scalar_view` | Sum of squared distances of samples to their closest cluster center. | +| `n_iter` | out | `raft::host_scalar_view` | Number of iterations run. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/cluster/kmeans.hpp:1188`_ + +### cuvs::cluster::kmeans::fit_predict + +Compute k-means clustering and predicts cluster index for each sample + +```cpp +void fit_predict(raft::resources const& handle, +const kmeans::params& params, +raft::device_matrix_view X, +std::optional> sample_weight, +std::optional> centroids, +raft::device_vector_view labels, +raft::host_scalar_view inertia, +raft::host_scalar_view n_iter); +``` + +in the input. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | The raft handle. | +| `params` | in | `const kmeans::params&` | Parameters for KMeans model. | +| `X` | in | `raft::device_matrix_view` | Training instances to cluster. The data must be in row-major format. [dim = n_samples x n_features] | +| `sample_weight` | in | `std::optional>` | Optional weights for each observation in X. [len = n_samples] | +| `centroids` | inout | `std::optional>` | Optional [in] When init is InitMethod::Array, use centroids as the initial cluster centers [out] The generated centroids from the kmeans algorithm are stored at the address pointed by 'centroids'. [dim = n_clusters x n_features] | +| `labels` | out | `raft::device_vector_view` | Index of the cluster each sample in X belongs to. [len = n_samples] | +| `inertia` | out | `raft::host_scalar_view` | Sum of squared distances of samples to their closest cluster center. | +| `n_iter` | out | `raft::host_scalar_view` | Number of iterations run. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/cluster/kmeans.hpp:1243`_ + +### cuvs::cluster::kmeans::fit_predict + +Compute k-means clustering and predicts cluster index for each sample + +```cpp +void fit_predict(raft::resources const& handle, +const kmeans::params& params, +raft::device_matrix_view X, +std::optional> sample_weight, +std::optional> centroids, +raft::device_vector_view labels, +raft::host_scalar_view inertia, +raft::host_scalar_view n_iter); +``` + +in the input. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | The raft handle. | +| `params` | in | `const kmeans::params&` | Parameters for KMeans model. | +| `X` | in | `raft::device_matrix_view` | Training instances to cluster. The data must be in row-major format. [dim = n_samples x n_features] | +| `sample_weight` | in | `std::optional>` | Optional weights for each observation in X. [len = n_samples] | +| `centroids` | inout | `std::optional>` | Optional [in] When init is InitMethod::Array, use centroids as the initial cluster centers [out] The generated centroids from the kmeans algorithm are stored at the address pointed by 'centroids'. [dim = n_clusters x n_features] | +| `labels` | out | `raft::device_vector_view` | Index of the cluster each sample in X belongs to. [len = n_samples] | +| `inertia` | out | `raft::host_scalar_view` | Sum of squared distances of samples to their closest cluster center. | +| `n_iter` | out | `raft::host_scalar_view` | Number of iterations run. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/cluster/kmeans.hpp:1298`_ + +### cuvs::cluster::kmeans::fit_predict + +Compute k-means clustering and predicts cluster index for each sample + +```cpp +void fit_predict(raft::resources const& handle, +const kmeans::params& params, +raft::device_matrix_view X, +std::optional> sample_weight, +std::optional> centroids, +raft::device_vector_view labels, +raft::host_scalar_view inertia, +raft::host_scalar_view n_iter); +``` + +in the input. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | The raft handle. | +| `params` | in | `const kmeans::params&` | Parameters for KMeans model. | +| `X` | in | `raft::device_matrix_view` | Training instances to cluster. The data must be in row-major format. [dim = n_samples x n_features] | +| `sample_weight` | in | `std::optional>` | Optional weights for each observation in X. [len = n_samples] | +| `centroids` | inout | `std::optional>` | Optional [in] When init is InitMethod::Array, use centroids as the initial cluster centers [out] The generated centroids from the kmeans algorithm are stored at the address pointed by 'centroids'. [dim = n_clusters x n_features] | +| `labels` | out | `raft::device_vector_view` | Index of the cluster each sample in X belongs to. [len = n_samples] | +| `inertia` | out | `raft::host_scalar_view` | Sum of squared distances of samples to their closest cluster center. | +| `n_iter` | out | `raft::host_scalar_view` | Number of iterations run. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/cluster/kmeans.hpp:1353`_ + +### cuvs::cluster::kmeans::fit_predict + +Compute balanced k-means clustering and predicts cluster index for each sample + +```cpp +void fit_predict(const raft::resources& handle, +cuvs::cluster::kmeans::balanced_params const& params, +raft::device_matrix_view X, +raft::device_matrix_view centroids, +raft::device_vector_view labels); +``` + +in the input. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `const raft::resources&` | The raft handle. | +| `params` | in | `cuvs::cluster::kmeans::balanced_params const&` | Parameters for KMeans model. | +| `X` | in | `raft::device_matrix_view` | Training instances to cluster. The data must be in row-major format. [dim = n_samples x n_features] | +| `centroids` | inout | `raft::device_matrix_view` | Optional [in] When init is InitMethod::Array, use centroids as the initial cluster centers [out] The generated centroids from the kmeans algorithm are stored at the address pointed by 'centroids'. [dim = n_clusters x n_features] | +| `labels` | out | `raft::device_vector_view` | Index of the cluster each sample in X belongs to. [len = n_samples] | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/cluster/kmeans.hpp:1400`_ + +### cuvs::cluster::kmeans::fit_predict + +Compute balanced k-means clustering and predicts cluster index for each sample + +```cpp +void fit_predict(const raft::resources& handle, +cuvs::cluster::kmeans::balanced_params const& params, +raft::device_matrix_view X, +raft::device_matrix_view centroids, +raft::device_vector_view labels); +``` + +in the input. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `const raft::resources&` | The raft handle. | +| `params` | in | `cuvs::cluster::kmeans::balanced_params const&` | Parameters for KMeans model. | +| `X` | in | `raft::device_matrix_view` | Training instances to cluster. The data must be in row-major format. [dim = n_samples x n_features] | +| `centroids` | inout | `raft::device_matrix_view` | Optional [in] When init is InitMethod::Array, use centroids as the initial cluster centers [out] The generated centroids from the kmeans algorithm are stored at the address pointed by 'centroids'. [dim = n_clusters x n_features] | +| `labels` | out | `raft::device_vector_view` | Index of the cluster each sample in X belongs to. [len = n_samples] | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/cluster/kmeans.hpp:1444`_ + +### cuvs::cluster::kmeans::transform + +Transform X to a cluster-distance space. + +```cpp +void transform(raft::resources const& handle, +const kmeans::params& params, +raft::device_matrix_view X, +raft::device_matrix_view centroids, +raft::device_matrix_view X_new); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | The raft handle. | +| `params` | in | `const kmeans::params&` | Parameters for KMeans model. | +| `X` | in | `raft::device_matrix_view` | Training instances to cluster. The data must be in row-major format [dim = n_samples x n_features] | +| `centroids` | in | `raft::device_matrix_view` | Cluster centroids. The data must be in row-major format. [dim = n_clusters x n_features] | +| `X_new` | out | `raft::device_matrix_view` | X transformed in the new space. [dim = n_samples x n_features] | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/cluster/kmeans.hpp:1463`_ + +### cuvs::cluster::kmeans::transform + +Transform X to a cluster-distance space. + +```cpp +void transform(raft::resources const& handle, +const kmeans::params& params, +raft::device_matrix_view X, +raft::device_matrix_view centroids, +raft::device_matrix_view X_new); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | The raft handle. | +| `params` | in | `const kmeans::params&` | Parameters for KMeans model. | +| `X` | in | `raft::device_matrix_view` | Training instances to cluster. The data must be in row-major format [dim = n_samples x n_features] | +| `centroids` | in | `raft::device_matrix_view` | Cluster centroids. The data must be in row-major format. [dim = n_clusters x n_features] | +| `X_new` | out | `raft::device_matrix_view` | X transformed in the new space. [dim = n_samples x n_features] | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/cluster/kmeans.hpp:1482`_ + +### cuvs::cluster::kmeans::cluster_cost + +Compute (optionally weighted) cluster cost + +```cpp +void cluster_cost( +const raft::resources& handle, +raft::device_matrix_view X, +raft::device_matrix_view centroids, +raft::host_scalar_view cost, +std::optional> sample_weight = std::nullopt); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `const raft::resources&` | The raft handle | +| `X` | in | `raft::device_matrix_view` | Training instances to cluster. The data must be in row-major format. [dim = n_samples x n_features] | +| `centroids` | in | `raft::device_matrix_view` | Cluster centroids. The data must be in row-major format. [dim = n_clusters x n_features] | +| `cost` | out | `raft::host_scalar_view` | Resulting cluster cost | +| `sample_weight` | in | `std::optional>` | Optional per-sample weights. [len = n_samples] Default: `std::nullopt`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/cluster/kmeans.hpp:1503`_ + +### cuvs::cluster::kmeans::cluster_cost + +Compute cluster cost + +```cpp +void cluster_cost( +const raft::resources& handle, +raft::device_matrix_view X, +raft::device_matrix_view centroids, +raft::host_scalar_view cost, +std::optional> sample_weight = std::nullopt); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `const raft::resources&` | The raft handle | +| `X` | in | `raft::device_matrix_view` | Training instances to cluster. The data must be in row-major format. [dim = n_samples x n_features] | +| `centroids` | in | `raft::device_matrix_view` | Cluster centroids. The data must be in row-major format. [dim = n_clusters x n_features] | +| `cost` | out | `raft::host_scalar_view` | Resulting cluster cost | +| `sample_weight` | in | `std::optional>` | Optional per-sample weights. [len = n_samples] Default: `std::nullopt`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/cluster/kmeans.hpp:1524`_ + +### cuvs::cluster::kmeans::cluster_cost + +Compute (optionally weighted) cluster cost + +```cpp +void cluster_cost( +const raft::resources& handle, +raft::device_matrix_view X, +raft::device_matrix_view centroids, +raft::host_scalar_view cost, +std::optional> sample_weight = std::nullopt); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `const raft::resources&` | The raft handle | +| `X` | in | `raft::device_matrix_view` | Training instances to cluster. The data must be in row-major format. [dim = n_samples x n_features] | +| `centroids` | in | `raft::device_matrix_view` | Cluster centroids. The data must be in row-major format. [dim = n_clusters x n_features] | +| `cost` | out | `raft::host_scalar_view` | Resulting cluster cost | +| `sample_weight` | in | `std::optional>` | Optional per-sample weights. [len = n_samples] Default: `std::nullopt`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/cluster/kmeans.hpp:1545`_ + +### cuvs::cluster::kmeans::cluster_cost + +Compute (optionally weighted) cluster cost + +```cpp +void cluster_cost( +const raft::resources& handle, +raft::device_matrix_view X, +raft::device_matrix_view centroids, +raft::host_scalar_view cost, +std::optional> sample_weight = std::nullopt); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `const raft::resources&` | The raft handle | +| `X` | in | `raft::device_matrix_view` | Training instances to cluster. The data must be in row-major format. [dim = n_samples x n_features] | +| `centroids` | in | `raft::device_matrix_view` | Cluster centroids. The data must be in row-major format. [dim = n_clusters x n_features] | +| `cost` | out | `raft::host_scalar_view` | Resulting cluster cost | +| `sample_weight` | in | `std::optional>` | Optional per-sample weights. [len = n_samples] Default: `std::nullopt`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/cluster/kmeans.hpp:1566`_ + +## k-means API helpers + +_Doxygen group: `kmeans_helpers`_ + +### helpers::find_k + +Automatically find the optimal value of k using a binary search. + +```cpp +void find_k(raft::resources const& handle, +raft::device_matrix_view X, +raft::host_scalar_view best_k, +raft::host_scalar_view inertia, +raft::host_scalar_view n_iter, +int kmax, +int kmin = 1, +int maxiter = 100, +float tol = 1e-3); +``` + +This method maximizes the Calinski-Harabasz Index while minimizing the per-cluster inertia. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | | `raft::resources const&` | raft handle | +| `X` | | `raft::device_matrix_view` | input observations (shape n_samples, n_dims) | +| `best_k` | | `raft::host_scalar_view` | best k found from binary search | +| `inertia` | | `raft::host_scalar_view` | inertia of best k found | +| `n_iter` | | `raft::host_scalar_view` | number of iterations used to find best k | +| `kmax` | | `int` | maximum k to try in search | +| `kmin` | | `int` | minimum k to try in search (should be >= 1) Default: `1`. | +| `maxiter` | | `int` | maximum number of iterations to run Default: `100`. | +| `tol` | | `float` | tolerance for early stopping convergence Default: `1e-3`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/cluster/kmeans.hpp:1619`_ diff --git a/fern/pages/cpp_api/cpp-api-cluster-spectral.md b/fern/pages/cpp_api/cpp-api-cluster-spectral.md new file mode 100644 index 0000000000..873cdab131 --- /dev/null +++ b/fern/pages/cpp_api/cpp-api-cluster-spectral.md @@ -0,0 +1,120 @@ +--- +slug: api-reference/cpp-api-cluster-spectral +--- + +# Spectral + +_Source header: `cpp/include/cuvs/cluster/spectral.hpp`_ + +## Spectral Clustering Parameters + +_Doxygen group: `spectral_params`_ + +### cuvs::cluster::spectral::params + +Parameters for spectral clustering + +```cpp +struct params { ... } ; +``` + +**Fields** + +| Name | Type | Description | +| --- | --- | --- | +| `n_clusters` | `int` | Number of clusters to find | +| `n_components` | `int` | Number of eigenvectors to use for the spectral embedding (typically equal to n_clusters) | +| `n_init` | `int` | Number of k-means runs with different centroid seeds | +| `n_neighbors` | `int` | Number of nearest neighbors for constructing the connectivity graph | +| `tolerance` | `float` | Tolerance for the eigenvalue solver | +| `raft::random::RngState rng_state{0}` | `raft::random::RngState rng_state{0}` | Random number generator state for reproducibility | + +_Source: `cpp/include/cuvs/cluster/spectral.hpp:22`_ + +## Spectral Clustering + +_Doxygen group: `spectral`_ + +### cuvs::cluster::spectral::fit_predict + +Perform spectral clustering on a connectivity graph + +```cpp +void fit_predict(raft::resources const& handle, +params config, +raft::device_coo_matrix_view connectivity_graph, +raft::device_vector_view labels); +``` + +n_clusters-1) + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | RAFT resource handle | +| `config` | in | `params` | Spectral clustering parameters | +| `connectivity_graph` | in | `raft::device_coo_matrix_view` | Sparse COO matrix representing connectivity between data points | +| `labels` | out | `raft::device_vector_view` | Device vector of size n_samples to store cluster assignments (0 to | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/cluster/spectral.hpp:84`_ + +### cuvs::cluster::spectral::fit_predict + +Perform spectral clustering on a connectivity graph + +```cpp +void fit_predict(raft::resources const& handle, +params config, +raft::device_coo_matrix_view connectivity_graph, +raft::device_vector_view labels); +``` + +n_clusters-1) + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | RAFT resource handle | +| `config` | in | `params` | Spectral clustering parameters | +| `connectivity_graph` | in | `raft::device_coo_matrix_view` | Sparse COO matrix representing connectivity between data points | +| `labels` | out | `raft::device_vector_view` | Device vector of size n_samples to store cluster assignments (0 to | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/cluster/spectral.hpp:122`_ + +### cuvs::cluster::spectral::fit_predict + +Perform spectral clustering on a dense dataset + +```cpp +void fit_predict(raft::resources const& handle, +params config, +raft::device_matrix_view dataset, +raft::device_vector_view labels); +``` + +This overload automatically constructs the connectivity graph from the input dataset using k-nearest neighbors. n_clusters-1) + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | RAFT resource handle | +| `config` | in | `params` | Spectral clustering parameters | +| `dataset` | in | `raft::device_matrix_view` | Dense row-major matrix of shape (n_samples, n_features) | +| `labels` | out | `raft::device_vector_view` | Device vector of size n_samples to store cluster assignments (0 to | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/cluster/spectral.hpp:155`_ diff --git a/fern/pages/cpp_api/cpp-api-distance-distance.md b/fern/pages/cpp_api/cpp-api-distance-distance.md new file mode 100644 index 0000000000..79bd8c7e77 --- /dev/null +++ b/fern/pages/cpp_api/cpp-api-distance-distance.md @@ -0,0 +1,273 @@ +--- +slug: api-reference/cpp-api-distance-distance +--- + +# Distance + +_Source header: `cpp/include/cuvs/distance/distance.hpp`_ + +## Pairwise Distances API + +_Doxygen group: `pairwise_distance`_ + +### kernels::pairwise_distance + +Compute pairwise distances for two matrices + +```cpp +void pairwise_distance( +raft::resources const& handle, +raft::device_matrix_view const x, +raft::device_matrix_view const y, +raft::device_matrix_view dist, +cuvs::distance::DistanceType metric, +float metric_arg = 2.0f); +``` + +Note: Only contiguous row- or column-major layouts supported currently. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | raft handle for managing expensive resources | +| `x` | in | `raft::device_matrix_view const` | first set of points (size n*k) | +| `y` | in | `raft::device_matrix_view const` | second set of points (size m*k) | +| `dist` | out | `raft::device_matrix_view` | output distance matrix (size n*m) | +| `metric` | in | `cuvs::distance::DistanceType` | distance to evaluate | +| `metric_arg` | in | `float` | metric argument (used for Minkowski distance) Default: `2.0f`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/distance/distance.hpp:161`_ + +### kernels::pairwise_distance + +Compute pairwise distances for two matrices + +```cpp +void pairwise_distance( +raft::resources const& handle, +raft::device_matrix_view const x, +raft::device_matrix_view const y, +raft::device_matrix_view dist, +cuvs::distance::DistanceType metric, +double metric_arg = 2.0f); +``` + +Note: Only contiguous row- or column-major layouts supported currently. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | raft handle for managing expensive resources | +| `x` | in | `raft::device_matrix_view const` | first set of points (size n*k) | +| `y` | in | `raft::device_matrix_view const` | second set of points (size m*k) | +| `dist` | out | `raft::device_matrix_view` | output distance matrix (size n*m) | +| `metric` | in | `cuvs::distance::DistanceType` | distance to evaluate | +| `metric_arg` | in | `double` | metric argument (used for Minkowski distance) Default: `2.0f`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/distance/distance.hpp:205`_ + +### kernels::pairwise_distance + +Compute pairwise distances for two matrices + +```cpp +void pairwise_distance( +raft::resources const& handle, +raft::device_matrix_view const x, +raft::device_matrix_view const y, +raft::device_matrix_view dist, +cuvs::distance::DistanceType metric, +float metric_arg = 2.0f); +``` + +Note: Only contiguous row- or column-major layouts supported currently. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | raft handle for managing expensive resources | +| `x` | in | `raft::device_matrix_view const` | first set of points (size n*k) | +| `y` | in | `raft::device_matrix_view const` | second set of points (size m*k) | +| `dist` | out | `raft::device_matrix_view` | output distance matrix (size n*m) | +| `metric` | in | `cuvs::distance::DistanceType` | distance to evaluate | +| `metric_arg` | in | `float` | metric argument (used for Minkowski distance) Default: `2.0f`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/distance/distance.hpp:248`_ + +### kernels::pairwise_distance + +Compute pairwise distances for two matrices + +```cpp +void pairwise_distance( +raft::resources const& handle, +raft::device_matrix_view const x, +raft::device_matrix_view const y, +raft::device_matrix_view dist, +cuvs::distance::DistanceType metric, +float metric_arg = 2.0f); +``` + +Note: Only contiguous row- or column-major layouts supported currently. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | raft handle for managing expensive resources | +| `x` | in | `raft::device_matrix_view const` | first set of points (size n*k) | +| `y` | in | `raft::device_matrix_view const` | second set of points (size m*k) | +| `dist` | out | `raft::device_matrix_view` | output distance matrix (size n*m) | +| `metric` | in | `cuvs::distance::DistanceType` | distance to evaluate | +| `metric_arg` | in | `float` | metric argument (used for Minkowski distance) Default: `2.0f`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/distance/distance.hpp:292`_ + +### kernels::pairwise_distance + +Compute pairwise distances for two matrices + +```cpp +void pairwise_distance( +raft::resources const& handle, +raft::device_matrix_view const x, +raft::device_matrix_view const y, +raft::device_matrix_view dist, +cuvs::distance::DistanceType metric, +double metric_arg = 2.0f); +``` + +Note: Only contiguous row- or column-major layouts supported currently. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | raft handle for managing expensive resources | +| `x` | in | `raft::device_matrix_view const` | first set of points (size n*k) | +| `y` | in | `raft::device_matrix_view const` | second set of points (size m*k) | +| `dist` | out | `raft::device_matrix_view` | output distance matrix (size n*m) | +| `metric` | in | `cuvs::distance::DistanceType` | distance to evaluate | +| `metric_arg` | in | `double` | metric argument (used for Minkowski distance) Default: `2.0f`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/distance/distance.hpp:335`_ + +### kernels::pairwise_distance + +Compute pairwise distances for two matrices + +```cpp +void pairwise_distance( +raft::resources const& handle, +raft::device_matrix_view const x, +raft::device_matrix_view const y, +raft::device_matrix_view dist, +cuvs::distance::DistanceType metric, +float metric_arg = 2.0f); +``` + +Note: Only contiguous row- or column-major layouts supported currently. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | raft handle for managing expensive resources | +| `x` | in | `raft::device_matrix_view const` | first set of points (size n*k) | +| `y` | in | `raft::device_matrix_view const` | second set of points (size m*k) | +| `dist` | out | `raft::device_matrix_view` | output distance matrix (size n*m) | +| `metric` | in | `cuvs::distance::DistanceType` | distance to evaluate | +| `metric_arg` | in | `float` | metric argument (used for Minkowski distance) Default: `2.0f`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/distance/distance.hpp:378`_ + +### kernels::pairwise_distance + +Compute sparse pairwise distances between x and y, using the provided + +```cpp +void pairwise_distance(raft::resources const& handle, +raft::device_csr_matrix_view x, +raft::device_csr_matrix_view y, +raft::device_matrix_view dist, +cuvs::distance::DistanceType metric, +float metric_arg = 2.0f); +``` + +input configuration and distance function. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | raft::resources | +| `x` | in | `raft::device_csr_matrix_view` | raft::device_csr_matrix_view | +| `y` | in | `raft::device_csr_matrix_view` | raft::device_csr_matrix_view | +| `dist` | out | `raft::device_matrix_view` | raft::device_matrix_view dense matrix | +| `metric` | in | `cuvs::distance::DistanceType` | distance metric to use | +| `metric_arg` | in | `float` | metric argument (used for Minkowski distance) Default: `2.0f`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/distance/distance.hpp:419`_ + +### kernels::pairwise_distance + +Compute sparse pairwise distances between x and y, using the provided + +```cpp +void pairwise_distance(raft::resources const& handle, +raft::device_csr_matrix_view x, +raft::device_csr_matrix_view y, +raft::device_matrix_view dist, +cuvs::distance::DistanceType metric, +float metric_arg = 2.0f); +``` + +input configuration and distance function. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | raft::resources | +| `x` | in | `raft::device_csr_matrix_view` | raft::device_csr_matrix_view | +| `y` | in | `raft::device_csr_matrix_view` | raft::device_csr_matrix_view | +| `dist` | out | `raft::device_matrix_view` | raft::device_matrix_view dense matrix | +| `metric` | in | `cuvs::distance::DistanceType` | distance metric to use | +| `metric_arg` | in | `float` | metric argument (used for Minkowski distance) Default: `2.0f`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/distance/distance.hpp:459`_ diff --git a/fern/pages/cpp_api/cpp-api-neighbors-all-neighbors.md b/fern/pages/cpp_api/cpp-api-neighbors-all-neighbors.md new file mode 100644 index 0000000000..13879f0a16 --- /dev/null +++ b/fern/pages/cpp_api/cpp-api-neighbors-all-neighbors.md @@ -0,0 +1,118 @@ +--- +slug: api-reference/cpp-api-neighbors-all-neighbors +--- + +# All Neighbors + +_Source header: `cpp/include/cuvs/neighbors/all_neighbors.hpp`_ + +## The all-neighbors algorithm parameters. + +_Doxygen group: `all_neighbors_cpp_params`_ + +### GraphBuildParams + +The all-neighbors algorithm parameters. + +```cpp +using GraphBuildParams = std::variant; +``` + +_Source: `cpp/include/cuvs/neighbors/all_neighbors.hpp:22`_ + +### cuvs::neighbors::all_neighbors::all_neighbors_params + +Parameters used to build an all-neighbors graph (find nearest neighbors for all the + +training vectors). For scalability, the all-neighbors graph construction algorithm partitions a set of training vectors into overlapping clusters, computes a local knn graph on each cluster, and merges the local graphs into a single global graph. Device memory usage and accuracy can be configured by changing the `overlap_factor` and `n_clusters`. The algorithm used to build each local graph is also configurable. + +```cpp +struct all_neighbors_params { ... } ; +``` + +**Fields** + +| Name | Type | Description | +| --- | --- | --- | +| `graph_build_params` | `GraphBuildParams` | Parameters for knn graph building algorithm | +| `overlap_factor` | `size_t` | Number of nearest clusters each data point will be assigned to in the batching algorithm. | +| `n_clusters` | `size_t` | Number of total clusters (aka batches) to split the data into. If set to 1, algorithm creates | +| `metric` | `cuvs::distance::DistanceType` | Metric used. | + +_Source: `cpp/include/cuvs/neighbors/all_neighbors.hpp:37`_ + +## The all-neighbors knn graph build + +_Doxygen group: `all_neighbors_cpp_build`_ + +### cuvs::neighbors::all_neighbors::build + +Builds an approximate all-neighbors knn graph (find nearest neighbors for all the + +```cpp +void build( +const raft::resources& handle, +const all_neighbors_params& params, +raft::host_matrix_view dataset, +raft::device_matrix_view indices, +std::optional> distances = std::nullopt, +std::optional> core_distances = std::nullopt, +float alpha = 1.0); +``` + +training vectors) Usage example: compute core_distances. If core_distances is given, the resulting indices and distances will be mutual reachability space. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `const raft::resources&` | raft::resources is an object managing resources | +| `params` | in | `const all_neighbors_params&` | an instance of all_neighbors::all_neighbors_params that are parameters to build all-neighbors knn graph | +| `dataset` | in | `raft::host_matrix_view` | raft::host_matrix_view input dataset expected to be located in host memory | +| `indices` | out | `raft::device_matrix_view` | nearest neighbor indices of shape [n_row x k] | +| `distances` | out | `std::optional>` | nearest neighbor distances [n_row x k] Default: `std::nullopt`. | +| `core_distances` | out | `std::optional>` | array for core distances of size [n_row]. Requires distances matrix to Default: `std::nullopt`. | +| `alpha` | in | `float` | distance scaling parameter as used in robust single linkage. Default: `1.0`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/all_neighbors.hpp:126`_ + +### cuvs::neighbors::all_neighbors::build + +Builds an approximate all-neighbors knn graph (find nearest neighbors for all the training + +```cpp +void build( +const raft::resources& handle, +const all_neighbors_params& params, +raft::device_matrix_view dataset, +raft::device_matrix_view indices, +std::optional> distances = std::nullopt, +std::optional> core_distances = std::nullopt, +float alpha = 1.0); +``` + +vectors) params.n_clusters should be 1 for data on device. To use a larger params.n_clusters for efficient device memory usage, put data on host RAM. Usage example: compute core_distances. If core_distances is given, the resulting indices and distances will be mutual reachability space. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `const raft::resources&` | raft::resources is an object managing resources | +| `params` | in | `const all_neighbors_params&` | an instance of all_neighbors::all_neighbors_params that are parameters to build all-neighbors knn graph | +| `dataset` | in | `raft::device_matrix_view` | raft::device_matrix_view input dataset expected to be located in device memory | +| `indices` | out | `raft::device_matrix_view` | nearest neighbor indices of shape [n_row x k] | +| `distances` | out | `std::optional>` | nearest neighbor distances [n_row x k] Default: `std::nullopt`. | +| `core_distances` | out | `std::optional>` | array for core distances of size [n_row]. Requires distances matrix to Default: `std::nullopt`. | +| `alpha` | in | `float` | distance scaling parameter as used in robust single linkage. Default: `1.0`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/all_neighbors.hpp:162`_ diff --git a/fern/pages/cpp_api/cpp-api-neighbors-ball-cover.md b/fern/pages/cpp_api/cpp-api-neighbors-ball-cover.md new file mode 100644 index 0000000000..9bc53fa9b3 --- /dev/null +++ b/fern/pages/cpp_api/cpp-api-neighbors-ball-cover.md @@ -0,0 +1,34 @@ +--- +slug: api-reference/cpp-api-neighbors-ball-cover +--- + +# Ball Cover + +_Source header: `cpp/include/cuvs/neighbors/ball_cover.hpp`_ + +## Random Ball Cover algorithm + +_Doxygen group: `random_ball_cover`_ + +### cuvs::neighbors::ball_cover::build + +Builds and populates a previously unbuilt cuvs::neighbors::ball_cover::index + +```cpp +void build(raft::resources const& handle, index& index); +``` + +Usage example: cuvs::neighbors::ball_cover::index + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | library resource management handle | +| `index` | inout | `index&` | an empty (and not previous built) instance of | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ball_cover.hpp:170`_ diff --git a/fern/pages/cpp_api/cpp-api-neighbors-brute-force.md b/fern/pages/cpp_api/cpp-api-neighbors-brute-force.md new file mode 100644 index 0000000000..b1696bb251 --- /dev/null +++ b/fern/pages/cpp_api/cpp-api-neighbors-brute-force.md @@ -0,0 +1,812 @@ +--- +slug: api-reference/cpp-api-neighbors-brute-force +--- + +# Brute Force + +_Source header: `cpp/include/cuvs/neighbors/brute_force.hpp`_ + +## Bruteforce index + +_Doxygen group: `bruteforce_cpp_index`_ + +### cuvs::neighbors::brute_force::index + +Construct an empty index. + +```cpp +index(raft::resources const& handle); +``` + +Constructs an empty index. This index will either need to be trained with `build` or loaded from a saved copy with `deserialize` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | | `raft::resources const&` | | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/brute_force.hpp:54`_ + +### cuvs::neighbors::brute_force::index + +Construct a brute force index from dataset + +```cpp +index(raft::resources const& res, +raft::host_matrix_view dataset_view, +std::optional>&& norms, +cuvs::distance::DistanceType metric, +DistT metric_arg = 0.0); +``` + +Constructs a brute force index from a dataset. This lets us precompute norms for the dataset, providing a speed benefit over doing this at query time. This index will copy the host dataset onto the device, and take ownership of any precaculated norms. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | | `raft::resources const&` | | +| `dataset_view` | | `raft::host_matrix_view` | | +| `norms` | | `std::optional>&&` | | +| `metric` | | `cuvs::distance::DistanceType` | | +| `metric_arg` | | `DistT` | Default: `0.0`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/brute_force.hpp:63`_ + +### cuvs::neighbors::brute_force::index + +Construct a brute force index from dataset + +```cpp +index(raft::resources const& res, +raft::device_matrix_view dataset_view, +std::optional>&& norms, +cuvs::distance::DistanceType metric, +DistT metric_arg = 0.0); +``` + +Constructs a brute force index from a dataset. This lets us precompute norms for the dataset, providing a speed benefit over doing this at query time. This index will store a non-owning reference to the dataset, but will move any norms supplied. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | | `raft::resources const&` | | +| `dataset_view` | | `raft::device_matrix_view` | | +| `norms` | | `std::optional>&&` | | +| `metric` | | `cuvs::distance::DistanceType` | | +| `metric_arg` | | `DistT` | Default: `0.0`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/brute_force.hpp:76`_ + +### cuvs::neighbors::brute_force::index + +Construct a brute force index from dataset + +```cpp +index(raft::resources const& res, +raft::device_matrix_view dataset_view, +std::optional> norms_view, +cuvs::distance::DistanceType metric, +DistT metric_arg = 0.0); +``` + +This class stores a non-owning reference to the dataset and norms. Having precomputed norms gives us a performance advantage at query time. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | | `raft::resources const&` | | +| `dataset_view` | | `raft::device_matrix_view` | | +| `norms_view` | | `std::optional>` | | +| `metric` | | `cuvs::distance::DistanceType` | | +| `metric_arg` | | `DistT` | Default: `0.0`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/brute_force.hpp:87`_ + +### cuvs::neighbors::brute_force::index + +Construct a brute force index from dataset + +```cpp +index(raft::resources const& res, +raft::device_matrix_view dataset_view, +std::optional>&& norms, +cuvs::distance::DistanceType metric, +DistT metric_arg = 0.0); +``` + +Constructs a brute force index from a dataset. This lets us precompute norms for the dataset, providing a speed benefit over doing this at query time. This index will store a non-owning reference to the dataset, but will move any norms supplied. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | | `raft::resources const&` | | +| `dataset_view` | | `raft::device_matrix_view` | | +| `norms` | | `std::optional>&&` | | +| `metric` | | `cuvs::distance::DistanceType` | | +| `metric_arg` | | `DistT` | Default: `0.0`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/brute_force.hpp:100`_ + +### cuvs::neighbors::brute_force::index + +Construct a brute force index from dataset + +```cpp +index(raft::resources const& res, +raft::device_matrix_view dataset_view, +std::optional> norms_view, +cuvs::distance::DistanceType metric, +DistT metric_arg = 0.0); +``` + +This class stores a non-owning reference to the dataset and norms, with the dataset being supplied on device in a col_major format + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | | `raft::resources const&` | | +| `dataset_view` | | `raft::device_matrix_view` | | +| `norms_view` | | `std::optional>` | | +| `metric` | | `cuvs::distance::DistanceType` | | +| `metric_arg` | | `DistT` | Default: `0.0`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/brute_force.hpp:111`_ + +### cuvs::neighbors::brute_force::update_dataset + +Replace the dataset with a new dataset. + +```cpp +void update_dataset(raft::resources const& res, +raft::device_matrix_view dataset); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | | `raft::resources const&` | | +| `dataset` | | `raft::device_matrix_view` | | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/brute_force.hpp:120`_ + +### cuvs::neighbors::brute_force::update_dataset + +Replace the dataset with a new dataset. + +```cpp +void update_dataset(raft::resources const& res, +raft::host_matrix_view dataset); +``` + +We create a copy of the dataset on the device. The index manages the lifetime of this copy. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | | `raft::resources const&` | | +| `dataset` | | `raft::host_matrix_view` | | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/brute_force.hpp:128`_ + +### cuvs::neighbors::brute_force::metric + +Distance metric used for retrieval + +```cpp +cuvs::distance::DistanceType metric() const noexcept; +``` + +**Returns** + +`cuvs::distance::DistanceType` + +_Source: `cpp/include/cuvs/neighbors/brute_force.hpp:132`_ + +### cuvs::neighbors::brute_force::metric_arg + +Metric argument + +```cpp +DistT metric_arg() const noexcept; +``` + +**Returns** + +`DistT` + +_Source: `cpp/include/cuvs/neighbors/brute_force.hpp:135`_ + +### cuvs::neighbors::brute_force::size + +Total length of the index (number of vectors). + +```cpp +size_t size() const noexcept; +``` + +**Returns** + +`size_t` + +_Source: `cpp/include/cuvs/neighbors/brute_force.hpp:138`_ + +### cuvs::neighbors::brute_force::dim + +Dimensionality of the data. + +```cpp +size_t dim() const noexcept; +``` + +**Returns** + +`size_t` + +_Source: `cpp/include/cuvs/neighbors/brute_force.hpp:141`_ + +### cuvs::neighbors::brute_force::dataset + +Dataset [size, dim] + +```cpp +raft::device_matrix_view dataset() const noexcept; +``` + +**Returns** + +`raft::device_matrix_view` + +_Source: `cpp/include/cuvs/neighbors/brute_force.hpp:144`_ + +### cuvs::neighbors::brute_force::norms + +Dataset norms + +```cpp +raft::device_vector_view norms() const; +``` + +**Returns** + +`raft::device_vector_view` + +_Source: `cpp/include/cuvs/neighbors/brute_force.hpp:150`_ + +### cuvs::neighbors::brute_force::has_norms + +Whether ot not this index has dataset norms + +```cpp +inline bool has_norms() const noexcept; +``` + +**Returns** + +`inline bool` + +_Source: `cpp/include/cuvs/neighbors/brute_force.hpp:156`_ + +## Bruteforce index build + +_Doxygen group: `bruteforce_cpp_index_build`_ + +### cuvs::neighbors::brute_force::build + +Build the index from the dataset for efficient search. + +```cpp +auto build(raft::resources const& handle, +const cuvs::neighbors::brute_force::index_params& index_params, +raft::device_matrix_view dataset) +-> cuvs::neighbors::brute_force::index; +``` + +Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | | +| `index_params` | in | `const cuvs::neighbors::brute_force::index_params&` | parameters such as the distance metric to use | +| `dataset` | in | `raft::device_matrix_view` | a device pointer to a row-major matrix [n_rows, dim] | + +**Returns** + +`cuvs::neighbors::brute_force::index` + +the constructed brute-force index + +_Source: `cpp/include/cuvs/neighbors/brute_force.hpp:191`_ + +### cuvs::neighbors::brute_force::build + +Build the index from the dataset for efficient search. + +```cpp +auto build(raft::resources const& handle, +const cuvs::neighbors::brute_force::index_params& index_params, +raft::host_matrix_view dataset) +-> cuvs::neighbors::brute_force::index; +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | | +| `index_params` | in | `const cuvs::neighbors::brute_force::index_params&` | parameters such as the distance metric to use | +| `dataset` | in | `raft::host_matrix_view` | a host pointer to a row-major matrix [n_rows, dim] | + +**Returns** + +`cuvs::neighbors::brute_force::index` + +the constructed brute-force index + +_Source: `cpp/include/cuvs/neighbors/brute_force.hpp:205`_ + +### cuvs::neighbors::brute_force::build + +Build the index from the dataset for efficient search. + +```cpp +auto build(raft::resources const& handle, +const cuvs::neighbors::brute_force::index_params& index_params, +raft::device_matrix_view dataset) +-> cuvs::neighbors::brute_force::index; +``` + +Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | | +| `index_params` | in | `const cuvs::neighbors::brute_force::index_params&` | parameters such as the distance metric to use | +| `dataset` | in | `raft::device_matrix_view` | a device pointer to a row-major matrix [n_rows, dim] | + +**Returns** + +`cuvs::neighbors::brute_force::index` + +the constructed brute force index + +_Source: `cpp/include/cuvs/neighbors/brute_force.hpp:232`_ + +### cuvs::neighbors::brute_force::build + +Build the index from the dataset for efficient search. + +```cpp +auto build(raft::resources const& handle, +const cuvs::neighbors::brute_force::index_params& index_params, +raft::host_matrix_view dataset) +-> cuvs::neighbors::brute_force::index; +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | | +| `index_params` | in | `const cuvs::neighbors::brute_force::index_params&` | parameters such as the distance metric to use | +| `dataset` | in | `raft::host_matrix_view` | a host pointer to a row-major matrix [n_rows, dim] | + +**Returns** + +`cuvs::neighbors::brute_force::index` + +the constructed brute-force index + +_Source: `cpp/include/cuvs/neighbors/brute_force.hpp:246`_ + +### cuvs::neighbors::brute_force::build + +Build the index from the dataset for efficient search. + +```cpp +auto build(raft::resources const& handle, +const cuvs::neighbors::brute_force::index_params& index_params, +raft::device_matrix_view dataset) +-> cuvs::neighbors::brute_force::index; +``` + +Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | | +| `index_params` | in | `const cuvs::neighbors::brute_force::index_params&` | parameters such as the distance metric to use | +| `dataset` | in | `raft::device_matrix_view` | a device pointer to a col-major matrix [n_rows, dim] | + +**Returns** + +`cuvs::neighbors::brute_force::index` + +the constructed brute force index + +_Source: `cpp/include/cuvs/neighbors/brute_force.hpp:272`_ + +### cuvs::neighbors::brute_force::build + +Build the index from the dataset for efficient search. + +```cpp +auto build(raft::resources const& handle, +const cuvs::neighbors::brute_force::index_params& index_params, +raft::device_matrix_view dataset) +-> cuvs::neighbors::brute_force::index; +``` + +Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | | +| `index_params` | in | `const cuvs::neighbors::brute_force::index_params&` | parameters such as the distance metric to use | +| `dataset` | in | `raft::device_matrix_view` | a device pointer to a col-major matrix [n_rows, dim] | + +**Returns** + +`cuvs::neighbors::brute_force::index` + +the constructed brute force index + +_Source: `cpp/include/cuvs/neighbors/brute_force.hpp:298`_ + +## Sparse Brute Force index + +_Doxygen group: `sparse_bruteforce_cpp_index`_ + +### cuvs::neighbors::brute_force::sparse_index + +Construct a sparse brute force sparse_index from dataset + +```cpp +sparse_index(raft::resources const& res, +raft::device_csr_matrix_view dataset, +cuvs::distance::DistanceType metric, +T metric_arg); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | | `raft::resources const&` | | +| `dataset` | | `raft::device_csr_matrix_view` | | +| `metric` | | `cuvs::distance::DistanceType` | | +| `metric_arg` | | `T` | | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/brute_force.hpp:609`_ + +### cuvs::neighbors::brute_force::metric + +Distance metric used for retrieval + +```cpp +cuvs::distance::DistanceType metric() const noexcept; +``` + +**Returns** + +`cuvs::distance::DistanceType` + +_Source: `cpp/include/cuvs/neighbors/brute_force.hpp:615`_ + +### cuvs::neighbors::brute_force::metric_arg + +Metric argument + +```cpp +T metric_arg() const noexcept; +``` + +**Returns** + +`T` + +_Source: `cpp/include/cuvs/neighbors/brute_force.hpp:618`_ + +## Sparse Brute Force index search + +_Doxygen group: `sparse_bruteforce_cpp_index_search`_ + +### cuvs::neighbors::brute_force::sparse_search_params + +Sparse Brute Force index search + +```cpp +struct sparse_search_params { ... } ; +``` + +**Fields** + +| Name | Type | Description | +| --- | --- | --- | +| `batch_size_index` | `int` | | +| `batch_size_query` | `int` | | + +_Source: `cpp/include/cuvs/neighbors/brute_force.hpp:668`_ + +## Bruteforce index serialize functions + +_Doxygen group: `bruteforce_cpp_index_serialize`_ + +### cuvs::neighbors::brute_force::serialize + +Save the index to file. + +```cpp +void serialize(raft::resources const& handle, +const std::string& filename, +const cuvs::neighbors::brute_force::index& index, +bool include_dataset = true); +``` + +The serialization format can be subject to changes, therefore loading an index saved with a previous version of cuvs is not guaranteed to work. output + +**Template Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `T` | `` | data element type | + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | the raft handle | +| `filename` | in | `const std::string&` | the file name for saving the index | +| `index` | in | `const cuvs::neighbors::brute_force::index&` | brute force index | +| `include_dataset` | in | `bool` | whether to include the dataset in the serialized Default: `true`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/brute_force.hpp:724`_ + +### cuvs::neighbors::brute_force::serialize + +Save the index to file. + +```cpp +void serialize(raft::resources const& handle, +const std::string& filename, +const cuvs::neighbors::brute_force::index& index, +bool include_dataset = true); +``` + +The serialization format can be subject to changes, therefore loading an index saved with a previous version of cuvs is not guaranteed to work. output + +**Template Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `T` | `` | data element type | + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | the raft handle | +| `filename` | in | `const std::string&` | the file name for saving the index | +| `index` | in | `const cuvs::neighbors::brute_force::index&` | brute force index | +| `include_dataset` | in | `bool` | whether to include the dataset in the serialized Default: `true`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/brute_force.hpp:755`_ + +### cuvs::neighbors::brute_force::serialize + +Write the index to an output stream + +```cpp +void serialize(raft::resources const& handle, +std::ostream& os, +const cuvs::neighbors::brute_force::index& index, +bool include_dataset = true); +``` + +The serialization format can be subject to changes, therefore loading an index saved with a previous version of cuvs is not guaranteed to work. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | the raft handle | +| `os` | in | `std::ostream&` | output stream | +| `index` | in | `const cuvs::neighbors::brute_force::index&` | brute force index | +| `include_dataset` | in | `bool` | Whether or not to write out the dataset to the file. Default: `true`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/brute_force.hpp:783`_ + +### cuvs::neighbors::brute_force::serialize + +Write the index to an output stream + +```cpp +void serialize(raft::resources const& handle, +std::ostream& os, +const cuvs::neighbors::brute_force::index& index, +bool include_dataset = true); +``` + +The serialization format can be subject to changes, therefore loading an index saved with a previous version of cuvs is not guaranteed to work. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | the raft handle | +| `os` | in | `std::ostream&` | output stream | +| `index` | in | `const cuvs::neighbors::brute_force::index&` | brute force index | +| `include_dataset` | in | `bool` | Whether or not to write out the dataset to the file. Default: `true`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/brute_force.hpp:811`_ + +### cuvs::neighbors::brute_force::deserialize + +Load index from file. + +```cpp +void deserialize(raft::resources const& handle, +const std::string& filename, +cuvs::neighbors::brute_force::index* index); +``` + +The serialization format can be subject to changes, therefore loading an index saved with a previous version of cuvs is not guaranteed to work. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | the raft handle | +| `filename` | in | `const std::string&` | the name of the file that stores the index | +| `index` | out | `cuvs::neighbors::brute_force::index*` | brute force index | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/brute_force.hpp:840`_ + +### cuvs::neighbors::brute_force::deserialize + +Load index from file. + +```cpp +void deserialize(raft::resources const& handle, +const std::string& filename, +cuvs::neighbors::brute_force::index* index); +``` + +The serialization format can be subject to changes, therefore loading an index saved with a previous version of cuvs is not guaranteed to work. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | the raft handle | +| `filename` | in | `const std::string&` | the name of the file that stores the index | +| `index` | out | `cuvs::neighbors::brute_force::index*` | brute force index | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/brute_force.hpp:867`_ + +### cuvs::neighbors::brute_force::deserialize + +Load index from input stream + +```cpp +void deserialize(raft::resources const& handle, +std::istream& is, +cuvs::neighbors::brute_force::index* index); +``` + +The serialization format can be subject to changes, therefore loading an index saved with a previous version of cuvs is not guaranteed to work. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | the raft handle | +| `is` | in | `std::istream&` | input stream | +| `index` | out | `cuvs::neighbors::brute_force::index*` | brute force index | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/brute_force.hpp:894`_ + +### cuvs::neighbors::brute_force::deserialize + +Load index from input stream + +```cpp +void deserialize(raft::resources const& handle, +std::istream& is, +cuvs::neighbors::brute_force::index* index); +``` + +The serialization format can be subject to changes, therefore loading an index saved with a previous version of cuvs is not guaranteed to work. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | the raft handle | +| `is` | in | `std::istream&` | input stream | +| `index` | out | `cuvs::neighbors::brute_force::index*` | brute force index | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/brute_force.hpp:921`_ diff --git a/fern/pages/cpp_api/cpp-api-neighbors-cagra.md b/fern/pages/cpp_api/cpp-api-neighbors-cagra.md new file mode 100644 index 0000000000..af3f3e2c49 --- /dev/null +++ b/fern/pages/cpp_api/cpp-api-neighbors-cagra.md @@ -0,0 +1,1827 @@ +--- +slug: api-reference/cpp-api-neighbors-cagra +--- + +# Cagra + +_Source header: `cpp/include/cuvs/neighbors/cagra.hpp`_ + +## CAGRA index build parameters + +_Doxygen group: `cagra_cpp_index_params`_ + +### cuvs::neighbors::vpq_params + +Parameters for VPQ compression. + +```cpp +struct vpq_params { ... } ; +``` + +**Fields** + +| Name | Type | Description | +| --- | --- | --- | +| `pq_bits` | `uint32_t` | The bit length of the vector element after compression by PQ. | +| `pq_dim` | `uint32_t` | The dimensionality of the vector after compression by PQ. | +| `vq_n_centers` | `uint32_t` | Vector Quantization (VQ) codebook size - number of "coarse cluster centers". | +| `kmeans_n_iters` | `uint32_t` | The number of iterations searching for kmeans centers (both VQ & PQ phases). | +| `vq_kmeans_trainset_fraction` | `double` | The fraction of data to use during iterative kmeans building (VQ phase). | +| `pq_kmeans_trainset_fraction` | `double` | The fraction of data to use during iterative kmeans building (PQ phase). | +| `pq_kmeans_type` | `cuvs::cluster::kmeans::kmeans_type` | Type of k-means algorithm for PQ training. | +| `max_train_points_per_pq_code` | `uint32_t` | The max number of data points to use per PQ code during PQ codebook training. Using more data | +| `max_train_points_per_vq_cluster` | `uint32_t` | The max number of data points to use per VQ cluster during training. | + +_Source: `cpp/include/cuvs/neighbors/common.hpp:42`_ + +### cuvs::neighbors::cagra::hnsw_heuristic_type + +A strategy for selecting the graph build parameters based on similar HNSW index + +parameters. Define how `cagra::index_params::from_hnsw_params` should construct a graph to construct a graph that is to be converted to (used by) a CPU HNSW index. + +```cpp +enum class hnsw_heuristic_type : uint32_t { ... } ; +``` + +_Source: `cpp/include/cuvs/neighbors/cagra.hpp:115`_ + +### cuvs::neighbors::cagra::from_hnsw_params + +Create a CAGRA index parameters compatible with HNSW index + +```cpp +static cagra::index_params from_hnsw_params( +raft::matrix_extent dataset, +int M, +int ef_construction, +hnsw_heuristic_type heuristic = hnsw_heuristic_type::SIMILAR_SEARCH_PERFORMANCE, +cuvs::distance::DistanceType metric = cuvs::distance::DistanceType::L2Expanded); +``` + +* IMPORTANT NOTE * The reference HNSW index and the corresponding from-CAGRA generated HNSW index will NOT produce exactly the same recalls and QPS for the same parameter `ef`. The graphs are different internally. Depending on the selected heuristics, the CAGRA-produced graph's QPS-Recall curve may be shifted along the curve right or left. See the heuristics descriptions for more details. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `dataset` | | `raft::matrix_extent` | The shape of the input dataset | +| `M` | | `int` | HNSW index parameter M | +| `ef_construction` | | `int` | HNSW index parameter ef_construction | +| `heuristic` | | `hnsw_heuristic_type` | The heuristic to use for selecting the graph build parameters Default: `hnsw_heuristic_type::SIMILAR_SEARCH_PERFORMANCE`. | +| `metric` | | `cuvs::distance::DistanceType` | The distance metric to search Default: `cuvs::distance::DistanceType::L2Expanded`. | + +**Returns** + +`static cagra::index_params` + +_Source: `cpp/include/cuvs/neighbors/cagra.hpp:245`_ + +## CAGRA index search parameters + +_Doxygen group: `cagra_cpp_search_params`_ + +### cuvs::neighbors::cagra::search_algo + +CAGRA index search parameters + +```cpp +enum class search_algo { ... } ; +``` + +**Values** + +| Name | Value | +| --- | --- | +| `SINGLE_CTA` | `0` | +| `MULTI_CTA` | `1` | +| `MULTI_KERNEL` | `2` | +| `AUTO` | `100` | + +_Source: `cpp/include/cuvs/neighbors/cagra.hpp:262`_ + +## CAGRA index extend parameters + +_Doxygen group: `cagra_cpp_extend_params`_ + +### cuvs::neighbors::cagra::extend_params + +CAGRA index extend parameters + +```cpp +struct extend_params { ... } ; +``` + +**Fields** + +| Name | Type | Description | +| --- | --- | --- | +| `max_chunk_size` | `uint32_t` | The additional dataset is divided into chunks and added to the graph. This is the knob to | + +_Source: `cpp/include/cuvs/neighbors/cagra.hpp:357`_ + +## CAGRA index type + +_Doxygen group: `cagra_cpp_index`_ + +### cuvs::neighbors::cagra::metric + +Distance metric used for clustering. + +```cpp +[[nodiscard]] constexpr inline auto metric() const noexcept -> cuvs::distance::DistanceType; +``` + +**Returns** + +`cuvs::distance::DistanceType` + +_Source: `cpp/include/cuvs/neighbors/cagra.hpp:401`_ + +### cuvs::neighbors::cagra::size + +Total length of the index (number of vectors). + +```cpp +[[nodiscard]] constexpr inline auto size() const noexcept -> IdxT; +``` + +**Returns** + +`IdxT` + +_Source: `cpp/include/cuvs/neighbors/cagra.hpp:407`_ + +### cuvs::neighbors::cagra::dim + +Dimensionality of the data. + +```cpp +[[nodiscard]] constexpr inline auto dim() const noexcept -> uint32_t; +``` + +**Returns** + +`uint32_t` + +_Source: `cpp/include/cuvs/neighbors/cagra.hpp:415`_ + +### cuvs::neighbors::cagra::graph_degree + +Graph degree + +```cpp +[[nodiscard]] constexpr inline auto graph_degree() const noexcept -> uint32_t; +``` + +**Returns** + +`uint32_t` + +_Source: `cpp/include/cuvs/neighbors/cagra.hpp:420`_ + +### cuvs::neighbors::cagra::data + +Dataset [size, dim] + +```cpp +[[nodiscard]] inline auto data() const noexcept -> const cuvs::neighbors::dataset&; +``` + +**Returns** + +`const cuvs::neighbors::dataset&` + +_Source: `cpp/include/cuvs/neighbors/cagra.hpp:435`_ + +### cuvs::neighbors::cagra::graph + +neighborhood graph [size, graph-degree] + +```cpp +[[nodiscard]] inline auto graph() const noexcept +-> raft::device_matrix_view; +``` + +**Returns** + +`raft::device_matrix_view` + +_Source: `cpp/include/cuvs/neighbors/cagra.hpp:441`_ + +### cuvs::neighbors::cagra::source_indices + +Mapping from internal graph node indices to the original user-provided indices. + +```cpp +[[nodiscard]] inline auto source_indices() const noexcept +-> std::optional>; +``` + +**Returns** + +`std::optional>` + +_Source: `cpp/include/cuvs/neighbors/cagra.hpp:448`_ + +### cuvs::neighbors::cagra::dataset_fd + +Get the dataset file descriptor (for disk-backed index) + +```cpp +[[nodiscard]] inline auto dataset_fd() const noexcept +-> const std::optional&; +``` + +**Returns** + +`const std::optional&` + +_Source: `cpp/include/cuvs/neighbors/cagra.hpp:458`_ + +### cuvs::neighbors::cagra::graph_fd + +Get the graph file descriptor (for disk-backed index) + +```cpp +[[nodiscard]] inline auto graph_fd() const noexcept +-> const std::optional&; +``` + +**Returns** + +`const std::optional&` + +_Source: `cpp/include/cuvs/neighbors/cagra.hpp:465`_ + +### cuvs::neighbors::cagra::mapping_fd + +Get the mapping file descriptor (for disk-backed index) + +```cpp +[[nodiscard]] inline auto mapping_fd() const noexcept +-> const std::optional&; +``` + +**Returns** + +`const std::optional&` + +_Source: `cpp/include/cuvs/neighbors/cagra.hpp:472`_ + +### cuvs::neighbors::cagra::dataset_norms + +Dataset norms for cosine distance [size] + +```cpp +[[nodiscard]] inline auto dataset_norms() const noexcept +-> std::optional>; +``` + +**Returns** + +`std::optional>` + +_Source: `cpp/include/cuvs/neighbors/cagra.hpp:479`_ + +### cuvs::neighbors::cagra::index + +```cpp +index(const index&) = delete; +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `arg1` | | `const index&` | | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/cagra.hpp:488`_ + +### cuvs::neighbors::cagra::index + +Construct an empty index. + +```cpp +index(raft::resources const& res, +cuvs::distance::DistanceType metric = cuvs::distance::DistanceType::L2Expanded) +: cuvs::neighbors::index(), +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | | `raft::resources const&` | | +| `metric` | | `cuvs::distance::DistanceType` | Default: `cuvs::distance::DistanceType::L2Expanded`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/cagra.hpp:496`_ + +### cuvs::neighbors::cagra::index + +Construct an index from dataset and knn_graph arrays + +```cpp +template +index(raft::resources const& res, +cuvs::distance::DistanceType metric, +raft::mdspan, raft::row_major, data_accessor> dataset, +raft::mdspan, +raft::row_major, +graph_accessor> knn_graph) +: cuvs::neighbors::index(), +``` + +If the dataset and graph is already in GPU memory, then the index is just a thin wrapper around these that stores a non-owning a reference to the arrays. The constructor also accepts host arrays. In that case they are copied to the device, and the device arrays will be owned by the index. In case the dasates rows are not 16 bytes aligned, then we create a padded copy in device memory to ensure alignment for vectorized load. Usage examples: - Cagra index is normally created by the cagra::build In the above example, we have passed a host dataset to build. The returned index will own a device copy of the dataset and the knn_graph. In contrast, if we pass the dataset as a device_mdspan to build, then it will only store a reference to it. - Constructing index using existing knn-graph + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | | `raft::resources const&` | | +| `metric` | | `cuvs::distance::DistanceType` | | +| `dataset` | | `raft::mdspan, raft::row_major, data_accessor>` | | +| `knn_graph` | | `raft::mdspan, raft::row_major, graph_accessor>` | | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/cagra.hpp:559`_ + +### cuvs::neighbors::cagra::update_dataset + +Replace the dataset with a new dataset. + +```cpp +void update_dataset(raft::resources const& res, +raft::device_matrix_view dataset); +``` + +If the new dataset rows are aligned on 16 bytes, then only a reference is stored to the dataset. It is the caller's responsibility to ensure that dataset stays alive as long as the index. It is expected that the same set of vectors are used for update_dataset and index build. Note: This will clear any precomputed dataset norms. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | | `raft::resources const&` | | +| `dataset` | | `raft::device_matrix_view` | | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/cagra.hpp:597`_ + +### cuvs::neighbors::cagra::update_dataset + +Set the dataset reference explicitly to a device matrix view with padding. + +```cpp +void update_dataset(raft::resources const& res, +raft::device_matrix_view dataset); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | | `raft::resources const&` | | +| `dataset` | | `raft::device_matrix_view` | | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/cagra.hpp:609`_ + +### cuvs::neighbors::cagra::update_dataset + +Replace the dataset with a new dataset. + +```cpp +void update_dataset(raft::resources const& res, +raft::host_matrix_view dataset); +``` + +We create a copy of the dataset on the device. The index manages the lifetime of this copy. It is expected that the same set of vectors are used for update_dataset and index build. Note: This will clear any precomputed dataset norms. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | | `raft::resources const&` | | +| `dataset` | | `raft::host_matrix_view` | | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/cagra.hpp:628`_ + +### cuvs::neighbors::cagra::update_dataset + +Replace the dataset with a new dataset. It is expected that the same set of vectors are used + +```cpp +template +auto update_dataset(raft::resources const& res, DatasetT&& dataset) +-> std::enable_if_t, DatasetT>>; +``` + +for update_dataset and index build. Note: This will clear any precomputed dataset norms. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | | `raft::resources const&` | | +| `dataset` | | `DatasetT&&` | | + +**Returns** + +`std::enable_if_t, DatasetT>>` + +_Source: `cpp/include/cuvs/neighbors/cagra.hpp:644`_ + +### cuvs::neighbors::cagra::update_graph + +Replace the graph with a new graph. + +```cpp +void update_graph( +raft::resources const& res, +raft::device_matrix_view knn_graph); +``` + +Since the new graph is a device array, we store a reference to that, and it is the caller's responsibility to ensure that knn_graph stays alive as long as the index. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | | `raft::resources const&` | | +| `knn_graph` | | `raft::device_matrix_view` | | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/cagra.hpp:677`_ + +### cuvs::neighbors::cagra::update_graph + +Replace the graph with a new graph. + +```cpp +void update_graph( +raft::resources const& res, +raft::host_matrix_view knn_graph); +``` + +We create a copy of the graph on the device. The index manages the lifetime of this copy. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | | `raft::resources const&` | | +| `knn_graph` | | `raft::host_matrix_view` | | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/cagra.hpp:689`_ + +### cuvs::neighbors::cagra::update_source_indices + +Replace the source indices with a new source indices taking the ownership of the passed vector. + +```cpp +void update_source_indices(raft::device_vector&& source_indices); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `source_indices` | | `raft::device_vector&&` | | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/cagra.hpp:713`_ + +### cuvs::neighbors::cagra::update_source_indices + +Copy the provided source indices into the index. + +```cpp +template +void update_source_indices( +raft::resources const& res, +raft::mdspan, raft::row_major, Accessor> +source_indices); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | | `raft::resources const&` | | +| `source_indices` | | `raft::mdspan, raft::row_major, Accessor>` | | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/cagra.hpp:723`_ + +### cuvs::neighbors::cagra::update_dataset + +Update the dataset from a disk file using a file descriptor. + +```cpp +void update_dataset(raft::resources const& res, cuvs::util::file_descriptor&& fd); +``` + +This method configures the index to use a disk-based dataset. The dataset file should contain a numpy header followed by vectors in row-major format. The number of rows and dimensionality are read from the numpy header. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resources | +| `fd` | in | `cuvs::util::file_descriptor&&` | File descriptor (will be moved into the index for lifetime management) | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/cagra.hpp:759`_ + +### cuvs::neighbors::cagra::update_graph + +Update the graph from a disk file using a file descriptor. + +```cpp +void update_graph(raft::resources const& res, cuvs::util::file_descriptor&& fd); +``` + +This method configures the index to use a disk-based graph. The graph file should contain a numpy header followed by neighbor indices in row-major format. The number of rows and graph degree are read from the numpy header. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resources | +| `fd` | in | `cuvs::util::file_descriptor&&` | File descriptor (will be moved into the index for lifetime management) | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/cagra.hpp:794`_ + +### cuvs::neighbors::cagra::update_mapping + +Update the dataset mapping from a disk file using a file descriptor. + +```cpp +void update_mapping(raft::resources const& res, cuvs::util::file_descriptor&& fd); +``` + +This method configures the index to use a disk-based dataset mapping. The mapping file should contain a numpy header followed by index mappings. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resources | +| `fd` | in | `cuvs::util::file_descriptor&&` | File descriptor (will be moved into the index for lifetime management) | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/cagra.hpp:834`_ + +## CAGRA index build functions + +_Doxygen group: `cagra_cpp_index_build`_ + +### cuvs::neighbors::cagra::build + +Build the index from the dataset for efficient search. + +```cpp +auto build(raft::resources const& res, +const cuvs::neighbors::cagra::index_params& params, +raft::device_matrix_view dataset) +-> cuvs::neighbors::cagra::index; +``` + +The build consist of two steps: build an intermediate knn-graph, and optimize it to create the final graph. The index_params struct controls the node degree of these graphs. The following distance metrics are supported: - L2 - InnerProduct (currently only supported with IVF-PQ as the build algorithm) - CosineExpanded - L1 (currently only supported with NN-Descent and Iterative Search as the build algorithm) Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | | +| `params` | in | `const cuvs::neighbors::cagra::index_params&` | parameters for building the index | +| `dataset` | in | `raft::device_matrix_view` | a matrix view (device) to a row-major matrix [n_rows, dim] | + +**Returns** + +`cuvs::neighbors::cagra::index` + +the constructed cagra index + +_Source: `cpp/include/cuvs/neighbors/cagra.hpp:923`_ + +### cuvs::neighbors::cagra::build + +Build the index from the dataset for efficient search. + +```cpp +auto build(raft::resources const& res, +const cuvs::neighbors::cagra::index_params& params, +raft::host_matrix_view dataset) +-> cuvs::neighbors::cagra::index; +``` + +The build consist of two steps: build an intermediate knn-graph, and optimize it to create the final graph. The index_params struct controls the node degree of these graphs. The following distance metrics are supported: - L2 - InnerProduct (currently only supported with IVF-PQ as the build algorithm) - CosineExpanded - L1 (currently only supported with NN-Descent and Iterative Search as the build algorithm) Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | | +| `params` | in | `const cuvs::neighbors::cagra::index_params&` | parameters for building the index | +| `dataset` | in | `raft::host_matrix_view` | a matrix view (host) to a row-major matrix [n_rows, dim] | + +**Returns** + +`cuvs::neighbors::cagra::index` + +the constructed cagra index + +_Source: `cpp/include/cuvs/neighbors/cagra.hpp:962`_ + +### cuvs::neighbors::cagra::build + +Build the index from the dataset for efficient search. + +```cpp +auto build(raft::resources const& res, +const cuvs::neighbors::cagra::index_params& params, +raft::device_matrix_view dataset) +-> cuvs::neighbors::cagra::index; +``` + +The build consist of two steps: build an intermediate knn-graph, and optimize it to create the final graph. The index_params struct controls the node degree of these graphs. The following distance metrics are supported: - L2 - InnerProduct (currently only supported with IVF-PQ as the build algorithm) - CosineExpanded (dataset norms are computed as float regardless of input data type) - L1 (currently only supported with NN-Descent and Iterative Search as the build algorithm) Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | | +| `params` | in | `const cuvs::neighbors::cagra::index_params&` | parameters for building the index | +| `dataset` | in | `raft::device_matrix_view` | a matrix view (device) to a row-major matrix [n_rows, dim] | + +**Returns** + +`cuvs::neighbors::cagra::index` + +the constructed cagra index + +_Source: `cpp/include/cuvs/neighbors/cagra.hpp:1001`_ + +### cuvs::neighbors::cagra::build + +Build the index from the dataset for efficient search. + +```cpp +auto build(raft::resources const& res, +const cuvs::neighbors::cagra::index_params& params, +raft::host_matrix_view dataset) +-> cuvs::neighbors::cagra::index; +``` + +The build consist of two steps: build an intermediate knn-graph, and optimize it to create the final graph. The index_params struct controls the node degree of these graphs. The following distance metrics are supported: - L2 - CosineExpanded (dataset norms are computed as float regardless of input data type) - L1 (currently only supported with NN-Descent and Iterative Search as the build algorithm) Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | | +| `params` | in | `const cuvs::neighbors::cagra::index_params&` | parameters for building the index | +| `dataset` | in | `raft::host_matrix_view` | a matrix view (host) to a row-major matrix [n_rows, dim] | + +**Returns** + +`cuvs::neighbors::cagra::index` + +the constructed cagra index + +_Source: `cpp/include/cuvs/neighbors/cagra.hpp:1039`_ + +### cuvs::neighbors::cagra::build + +Build the index from the dataset for efficient search. + +```cpp +auto build(raft::resources const& res, +const cuvs::neighbors::cagra::index_params& params, +raft::device_matrix_view dataset) +-> cuvs::neighbors::cagra::index; +``` + +The build consist of two steps: build an intermediate knn-graph, and optimize it to create the final graph. The index_params struct controls the node degree of these graphs. The following distance metrics are supported: - L2 - CosineExpanded (dataset norms are computed as float regardless of input data type) - L1 (currently only supported with NN-Descent and Iterative Search as the build algorithm) - BitwiseHamming (currently only supported with NN-Descent and Iterative Search as the build algorithm, and only for int8_t and uint8_t data types) Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | | +| `params` | in | `const cuvs::neighbors::cagra::index_params&` | parameters for building the index | +| `dataset` | in | `raft::device_matrix_view` | a matrix view (device) to a row-major matrix [n_rows, dim] | + +**Returns** + +`cuvs::neighbors::cagra::index` + +the constructed cagra index + +_Source: `cpp/include/cuvs/neighbors/cagra.hpp:1079`_ + +### cuvs::neighbors::cagra::build + +Build the index from the dataset for efficient search. + +```cpp +auto build(raft::resources const& res, +const cuvs::neighbors::cagra::index_params& params, +raft::host_matrix_view dataset) +-> cuvs::neighbors::cagra::index; +``` + +The build consist of two steps: build an intermediate knn-graph, and optimize it to create the final graph. The index_params struct controls the node degree of these graphs. The following distance metrics are supported: - L2 - InnerProduct (currently only supported with IVF-PQ as the build algorithm) - CosineExpanded (dataset norms are computed as float regardless of input data type) - L1 (currently only supported with NN-Descent and Iterative Search as the build algorithm) - BitwiseHamming (currently only supported with NN-Descent and Iterative Search as the build algorithm, and only for int8_t and uint8_t data types) Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | | +| `params` | in | `const cuvs::neighbors::cagra::index_params&` | parameters for building the index | +| `dataset` | in | `raft::host_matrix_view` | a matrix view (host) to a row-major matrix [n_rows, dim] | + +**Returns** + +`cuvs::neighbors::cagra::index` + +the constructed cagra index + +_Source: `cpp/include/cuvs/neighbors/cagra.hpp:1120`_ + +### cuvs::neighbors::cagra::build + +Build the index from the dataset for efficient search. + +```cpp +auto build(raft::resources const& res, +const cuvs::neighbors::cagra::index_params& params, +raft::device_matrix_view dataset) +-> cuvs::neighbors::cagra::index; +``` + +The build consist of two steps: build an intermediate knn-graph, and optimize it to create the final graph. The index_params struct controls the node degree of these graphs. The following distance metrics are supported: - L2 - InnerProduct (currently only supported with IVF-PQ as the build algorithm) - CosineExpanded (dataset norms are computed as float regardless of input data type) - L1 (currently only supported with NN-Descent and Iterative Search as the build algorithm) - BitwiseHamming (currently only supported with NN-Descent and Iterative Search as the build algorithm, and only for int8_t and uint8_t data types) Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | | +| `params` | in | `const cuvs::neighbors::cagra::index_params&` | parameters for building the index | +| `dataset` | in | `raft::device_matrix_view` | a matrix view (device) to a row-major matrix [n_rows, dim] | + +**Returns** + +`cuvs::neighbors::cagra::index` + +the constructed cagra index + +_Source: `cpp/include/cuvs/neighbors/cagra.hpp:1161`_ + +### cuvs::neighbors::cagra::build + +Build the index from the dataset for efficient search. + +```cpp +auto build(raft::resources const& res, +const cuvs::neighbors::cagra::index_params& params, +raft::host_matrix_view dataset) +-> cuvs::neighbors::cagra::index; +``` + +The build consist of two steps: build an intermediate knn-graph, and optimize it to create the final graph. The index_params struct controls the node degree of these graphs. The following distance metrics are supported: - L2 - InnerProduct (currently only supported with IVF-PQ as the build algorithm) - CosineExpanded (dataset norms are computed as float regardless of input data type) - L1 (currently only supported with NN-Descent and Iterative Search as the build algorithm) - BitwiseHamming (currently only supported with NN-Descent and Iterative Search as the build algorithm, and only for int8_t and uint8_t data types) Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | | +| `params` | in | `const cuvs::neighbors::cagra::index_params&` | parameters for building the index | +| `dataset` | in | `raft::host_matrix_view` | a matrix view (host) to a row-major matrix [n_rows, dim] | + +**Returns** + +`cuvs::neighbors::cagra::index` + +the constructed cagra index + +_Source: `cpp/include/cuvs/neighbors/cagra.hpp:1202`_ + +## CAGRA extend functions + +_Doxygen group: `cagra_cpp_index_extend`_ + +### cuvs::neighbors::cagra::extend + +Add new vectors to a CAGRA index + +```cpp +void extend( +raft::resources const& handle, +const cagra::extend_params& params, +raft::device_matrix_view additional_dataset, +cuvs::neighbors::cagra::index& idx, +std::optional> +new_dataset_buffer_view = std::nullopt, +std::optional> new_graph_buffer_view = std::nullopt); +``` + +Usage example: part. The data will be copied from the current index in this function. The num rows must be the sum of the original and additional datasets, cols must be the dimension of the dataset, and the stride must be the same as the original index dataset. This view will be stored in the output index. It is the caller's responsibility to ensure that dataset stays alive as long as the index. This option is useful when users want to manage the memory space for the dataset themselves. The data will be copied from the current index in this function. The num rows must be the sum of the original and additional datasets and cols must be the graph degree. This view will be stored in the output index. It is the caller's responsibility to ensure that dataset stays alive as long as the index. This option is useful when users want to manage the memory space for the graph themselves. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | raft resources | +| `params` | in | `const cagra::extend_params&` | extend params | +| `additional_dataset` | in | `raft::device_matrix_view` | additional dataset on device memory | +| `idx` | in,out | `cuvs::neighbors::cagra::index&` | CAGRA index | +| `new_dataset_buffer_view` | out | `std::optional>` | memory buffer view for the dataset including the additional Default: `std::nullopt`. | +| `new_graph_buffer_view` | out | `std::optional>` | memory buffer view for the graph including the additional part. Default: `std::nullopt`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/cagra.hpp:1244`_ + +### cuvs::neighbors::cagra::extend + +Add new vectors to a CAGRA index + +```cpp +void extend( +raft::resources const& handle, +const cagra::extend_params& params, +raft::host_matrix_view additional_dataset, +cuvs::neighbors::cagra::index& idx, +std::optional> +new_dataset_buffer_view = std::nullopt, +std::optional> new_graph_buffer_view = std::nullopt); +``` + +Usage example: part. The data will be copied from the current index in this function. The num rows must be the sum of the original and additional datasets, cols must be the dimension of the dataset, and the stride must be the same as the original index dataset. This view will be stored in the output index. It is the caller's responsibility to ensure that dataset stays alive as long as the index. This option is useful when users want to manage the memory space for the dataset themselves. The data will be copied from the current index in this function. The num rows must be the sum of the original and additional datasets and cols must be the graph degree. This view will be stored in the output index. It is the caller's responsibility to ensure that dataset stays alive as long as the index. This option is useful when users want to manage the memory space for the graph themselves. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | raft resources | +| `params` | in | `const cagra::extend_params&` | extend params | +| `additional_dataset` | in | `raft::host_matrix_view` | additional dataset on host memory | +| `idx` | in,out | `cuvs::neighbors::cagra::index&` | CAGRA index | +| `new_dataset_buffer_view` | out | `std::optional>` | memory buffer view for the dataset including the additional Default: `std::nullopt`. | +| `new_graph_buffer_view` | out | `std::optional>` | memory buffer view for the graph including the additional part. Default: `std::nullopt`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/cagra.hpp:1282`_ + +### cuvs::neighbors::cagra::extend + +Add new vectors to a CAGRA index + +```cpp +void extend( +raft::resources const& handle, +const cagra::extend_params& params, +raft::device_matrix_view additional_dataset, +cuvs::neighbors::cagra::index& idx, +std::optional> +new_dataset_buffer_view = std::nullopt, +std::optional> new_graph_buffer_view = std::nullopt); +``` + +Usage example: part. The data will be copied from the current index in this function. The num rows must be the sum of the original and additional datasets, cols must be the dimension of the dataset, and the stride must be the same as the original index dataset. This view will be stored in the output index. It is the caller's responsibility to ensure that dataset stays alive as long as the index. This option is useful when users want to manage the memory space for the dataset themselves. The data will be copied from the current index in this function. The num rows must be the sum of the original and additional datasets and cols must be the graph degree. This view will be stored in the output index. It is the caller's responsibility to ensure that dataset stays alive as long as the index. This option is useful when users want to manage the memory space for the graph themselves. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | raft resources | +| `params` | in | `const cagra::extend_params&` | extend params | +| `additional_dataset` | in | `raft::device_matrix_view` | additional dataset on device memory | +| `idx` | in,out | `cuvs::neighbors::cagra::index&` | CAGRA index | +| `new_dataset_buffer_view` | out | `std::optional>` | memory buffer view for the dataset including the additional Default: `std::nullopt`. | +| `new_graph_buffer_view` | out | `std::optional>` | memory buffer view for the graph including the additional part. Default: `std::nullopt`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/cagra.hpp:1320`_ + +### cuvs::neighbors::cagra::extend + +Add new vectors to a CAGRA index + +```cpp +void extend( +raft::resources const& handle, +const cagra::extend_params& params, +raft::host_matrix_view additional_dataset, +cuvs::neighbors::cagra::index& idx, +std::optional> +new_dataset_buffer_view = std::nullopt, +std::optional> new_graph_buffer_view = std::nullopt); +``` + +Usage example: part. The data will be copied from the current index in this function. The num rows must be the sum of the original and additional datasets, cols must be the dimension of the dataset, and the stride must be the same as the original index dataset. This view will be stored in the output index. It is the caller's responsibility to ensure that dataset stays alive as long as the index. This option is useful when users want to manage the memory space for the dataset themselves. The data will be copied from the current index in this function. The num rows must be the sum of the original and additional datasets and cols must be the graph degree. This view will be stored in the output index. It is the caller's responsibility to ensure that dataset stays alive as long as the index. This option is useful when users want to manage the memory space for the graph themselves. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | raft resources | +| `params` | in | `const cagra::extend_params&` | extend params | +| `additional_dataset` | in | `raft::host_matrix_view` | additional dataset on host memory | +| `idx` | in,out | `cuvs::neighbors::cagra::index&` | CAGRA index | +| `new_dataset_buffer_view` | out | `std::optional>` | memory buffer view for the dataset including the additional Default: `std::nullopt`. | +| `new_graph_buffer_view` | out | `std::optional>` | memory buffer view for the graph including the additional part. Default: `std::nullopt`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/cagra.hpp:1358`_ + +### cuvs::neighbors::cagra::extend + +Add new vectors to a CAGRA index + +```cpp +void extend( +raft::resources const& handle, +const cagra::extend_params& params, +raft::device_matrix_view additional_dataset, +cuvs::neighbors::cagra::index& idx, +std::optional> +new_dataset_buffer_view = std::nullopt, +std::optional> new_graph_buffer_view = std::nullopt); +``` + +Usage example: part. The data will be copied from the current index in this function. The num rows must be the sum of the original and additional datasets, cols must be the dimension of the dataset, and the stride must be the same as the original index dataset. This view will be stored in the output index. It is the caller's responsibility to ensure that dataset stays alive as long as the index. This option is useful when users want to manage the memory space for the dataset themselves. The data will be copied from the current index in this function. The num rows must be the sum of the original and additional datasets and cols must be the graph degree. This view will be stored in the output index. It is the caller's responsibility to ensure that dataset stays alive as long as the index. This option is useful when users want to manage the memory space for the graph themselves. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | raft resources | +| `params` | in | `const cagra::extend_params&` | extend params | +| `additional_dataset` | in | `raft::device_matrix_view` | additional dataset on device memory | +| `idx` | in,out | `cuvs::neighbors::cagra::index&` | CAGRA index | +| `new_dataset_buffer_view` | out | `std::optional>` | memory buffer view for the dataset including the additional Default: `std::nullopt`. | +| `new_graph_buffer_view` | out | `std::optional>` | memory buffer view for the graph including the additional part. Default: `std::nullopt`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/cagra.hpp:1396`_ + +### cuvs::neighbors::cagra::extend + +Add new vectors to a CAGRA index + +```cpp +void extend( +raft::resources const& handle, +const cagra::extend_params& params, +raft::host_matrix_view additional_dataset, +cuvs::neighbors::cagra::index& idx, +std::optional> +new_dataset_buffer_view = std::nullopt, +std::optional> new_graph_buffer_view = std::nullopt); +``` + +Usage example: part. The data will be copied from the current index in this function. The num rows must be the sum of the original and additional datasets, cols must be the dimension of the dataset, and the stride must be the same as the original index dataset. This view will be stored in the output index. It is the caller's responsibility to ensure that dataset stays alive as long as the index. This option is useful when users want to manage the memory space for the dataset themselves. The data will be copied from the current index in this function. The num rows must be the sum of the original and additional datasets and cols must be the graph degree. This view will be stored in the output index. It is the caller's responsibility to ensure that dataset stays alive as long as the index. This option is useful when users want to manage the memory space for the graph themselves. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | raft resources | +| `params` | in | `const cagra::extend_params&` | extend params | +| `additional_dataset` | in | `raft::host_matrix_view` | additional dataset on host memory | +| `idx` | in,out | `cuvs::neighbors::cagra::index&` | CAGRA index | +| `new_dataset_buffer_view` | out | `std::optional>` | memory buffer view for the dataset including the additional Default: `std::nullopt`. | +| `new_graph_buffer_view` | out | `std::optional>` | memory buffer view for the graph including the additional part. Default: `std::nullopt`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/cagra.hpp:1434`_ + +### cuvs::neighbors::cagra::extend + +Add new vectors to a CAGRA index + +```cpp +void extend( +raft::resources const& handle, +const cagra::extend_params& params, +raft::device_matrix_view additional_dataset, +cuvs::neighbors::cagra::index& idx, +std::optional> +new_dataset_buffer_view = std::nullopt, +std::optional> new_graph_buffer_view = std::nullopt); +``` + +Usage example: part. The data will be copied from the current index in this function. The num rows must be the sum of the original and additional datasets, cols must be the dimension of the dataset, and the stride must be the same as the original index dataset. This view will be stored in the output index. It is the caller's responsibility to ensure that dataset stays alive as long as the index. This option is useful when users want to manage the memory space for the dataset themselves. The data will be copied from the current index in this function. The num rows must be the sum of the original and additional datasets and cols must be the graph degree. This view will be stored in the output index. It is the caller's responsibility to ensure that dataset stays alive as long as the index. This option is useful when users want to manage the memory space for the graph themselves. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | raft resources | +| `params` | in | `const cagra::extend_params&` | extend params | +| `additional_dataset` | in | `raft::device_matrix_view` | additional dataset on host memory | +| `idx` | in,out | `cuvs::neighbors::cagra::index&` | CAGRA index | +| `new_dataset_buffer_view` | out | `std::optional>` | memory buffer view for the dataset including the additional Default: `std::nullopt`. | +| `new_graph_buffer_view` | out | `std::optional>` | memory buffer view for the graph including the additional part. Default: `std::nullopt`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/cagra.hpp:1472`_ + +### cuvs::neighbors::cagra::extend + +Add new vectors to a CAGRA index + +```cpp +void extend( +raft::resources const& handle, +const cagra::extend_params& params, +raft::host_matrix_view additional_dataset, +cuvs::neighbors::cagra::index& idx, +std::optional> +new_dataset_buffer_view = std::nullopt, +std::optional> new_graph_buffer_view = std::nullopt); +``` + +Usage example: part. The data will be copied from the current index in this function. The num rows must be the sum of the original and additional datasets, cols must be the dimension of the dataset, and the stride must be the same as the original index dataset. This view will be stored in the output index. It is the caller's responsibility to ensure that dataset stays alive as long as the index. This option is useful when users want to manage the memory space for the dataset themselves. The data will be copied from the current index in this function. The num rows must be the sum of the original and additional datasets and cols must be the graph degree. This view will be stored in the output index. It is the caller's responsibility to ensure that dataset stays alive as long as the index. This option is useful when users want to manage the memory space for the graph themselves. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | raft resources | +| `params` | in | `const cagra::extend_params&` | extend params | +| `additional_dataset` | in | `raft::host_matrix_view` | additional dataset on host memory | +| `idx` | in,out | `cuvs::neighbors::cagra::index&` | CAGRA index | +| `new_dataset_buffer_view` | out | `std::optional>` | memory buffer view for the dataset including the additional Default: `std::nullopt`. | +| `new_graph_buffer_view` | out | `std::optional>` | memory buffer view for the graph including the additional part. Default: `std::nullopt`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/cagra.hpp:1510`_ + +## CAGRA search functions + +_Doxygen group: `cagra_cpp_index_search`_ + +### sample_filter + +Search ANN using the constructed index. + +```cpp +void search(raft::resources const& res, +cuvs::neighbors::cagra::search_params const& params, +const cuvs::neighbors::cagra::index& index, +raft::device_matrix_view queries, +raft::device_matrix_view neighbors, +raft::device_matrix_view distances, +const cuvs::neighbors::filtering::base_filter& sample_filter = +cuvs::neighbors::filtering::none_sample_filter{} +``` + +_Source: `cpp/include/cuvs/neighbors/cagra.hpp:1541`_ + +## CAGRA serialize functions + +_Doxygen group: `cagra_cpp_serialize`_ + +### cuvs::neighbors::cagra::serialize + +Save the index to file. + +```cpp +void serialize(raft::resources const& handle, +const std::string& filename, +const cuvs::neighbors::cagra::index& index, +bool include_dataset = true); +``` + +Experimental, both the API and the serialization format are subject to change. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | the raft handle | +| `filename` | in | `const std::string&` | the file name for saving the index | +| `index` | in | `const cuvs::neighbors::cagra::index&` | CAGRA index | +| `include_dataset` | in | `bool` | Whether or not to write out the dataset to the file. Default: `true`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/cagra.hpp:1758`_ + +### cuvs::neighbors::cagra::deserialize + +Load index from file. + +```cpp +void deserialize(raft::resources const& handle, +const std::string& filename, +cuvs::neighbors::cagra::index* index); +``` + +Experimental, both the API and the serialization format are subject to change. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | the raft handle | +| `filename` | in | `const std::string&` | the name of the file that stores the index | +| `index` | out | `cuvs::neighbors::cagra::index*` | the cagra index | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/cagra.hpp:1785`_ + +### cuvs::neighbors::cagra::serialize + +Write the index to an output stream + +```cpp +void serialize(raft::resources const& handle, +std::ostream& os, +const cuvs::neighbors::cagra::index& index, +bool include_dataset = true); +``` + +Experimental, both the API and the serialization format are subject to change. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | the raft handle | +| `os` | in | `std::ostream&` | output stream | +| `index` | in | `const cuvs::neighbors::cagra::index&` | CAGRA index | +| `include_dataset` | in | `bool` | Whether or not to write out the dataset to the file. Default: `true`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/cagra.hpp:1811`_ + +### cuvs::neighbors::cagra::deserialize + +Load index from input stream + +```cpp +void deserialize(raft::resources const& handle, +std::istream& is, +cuvs::neighbors::cagra::index* index); +``` + +Experimental, both the API and the serialization format are subject to change. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | the raft handle | +| `is` | in | `std::istream&` | input stream | +| `index` | out | `cuvs::neighbors::cagra::index*` | the cagra index | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/cagra.hpp:1837`_ + +### cuvs::neighbors::cagra::serialize + +Save the index to file. + +```cpp +void serialize(raft::resources const& handle, +const std::string& filename, +const cuvs::neighbors::cagra::index& index, +bool include_dataset = true); +``` + +Experimental, both the API and the serialization format are subject to change. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | the raft handle | +| `filename` | in | `const std::string&` | the file name for saving the index | +| `index` | in | `const cuvs::neighbors::cagra::index&` | CAGRA index | +| `include_dataset` | in | `bool` | Whether or not to write out the dataset to the file. Default: `true`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/cagra.hpp:1863`_ + +### cuvs::neighbors::cagra::deserialize + +Load index from file. + +```cpp +void deserialize(raft::resources const& handle, +const std::string& filename, +cuvs::neighbors::cagra::index* index); +``` + +Experimental, both the API and the serialization format are subject to change. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | the raft handle | +| `filename` | in | `const std::string&` | the name of the file that stores the index | +| `index` | out | `cuvs::neighbors::cagra::index*` | the cagra index | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/cagra.hpp:1890`_ + +### cuvs::neighbors::cagra::serialize + +Write the index to an output stream + +```cpp +void serialize(raft::resources const& handle, +std::ostream& os, +const cuvs::neighbors::cagra::index& index, +bool include_dataset = true); +``` + +Experimental, both the API and the serialization format are subject to change. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | the raft handle | +| `os` | in | `std::ostream&` | output stream | +| `index` | in | `const cuvs::neighbors::cagra::index&` | CAGRA index | +| `include_dataset` | in | `bool` | Whether or not to write out the dataset to the file. Default: `true`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/cagra.hpp:1916`_ + +### cuvs::neighbors::cagra::deserialize + +Load index from input stream + +```cpp +void deserialize(raft::resources const& handle, +std::istream& is, +cuvs::neighbors::cagra::index* index); +``` + +Experimental, both the API and the serialization format are subject to change. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | the raft handle | +| `is` | in | `std::istream&` | input stream | +| `index` | out | `cuvs::neighbors::cagra::index*` | the cagra index | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/cagra.hpp:1942`_ + +### cuvs::neighbors::cagra::serialize + +Save the index to file. + +```cpp +void serialize(raft::resources const& handle, +const std::string& filename, +const cuvs::neighbors::cagra::index& index, +bool include_dataset = true); +``` + +Experimental, both the API and the serialization format are subject to change. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | the raft handle | +| `filename` | in | `const std::string&` | the file name for saving the index | +| `index` | in | `const cuvs::neighbors::cagra::index&` | CAGRA index | +| `include_dataset` | in | `bool` | Whether or not to write out the dataset to the file. Default: `true`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/cagra.hpp:1968`_ + +### cuvs::neighbors::cagra::deserialize + +Load index from file. + +```cpp +void deserialize(raft::resources const& handle, +const std::string& filename, +cuvs::neighbors::cagra::index* index); +``` + +Experimental, both the API and the serialization format are subject to change. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | the raft handle | +| `filename` | in | `const std::string&` | the name of the file that stores the index | +| `index` | out | `cuvs::neighbors::cagra::index*` | the cagra index | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/cagra.hpp:1995`_ + +### cuvs::neighbors::cagra::serialize + +Write the index to an output stream + +```cpp +void serialize(raft::resources const& handle, +std::ostream& os, +const cuvs::neighbors::cagra::index& index, +bool include_dataset = true); +``` + +Experimental, both the API and the serialization format are subject to change. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | the raft handle | +| `os` | in | `std::ostream&` | output stream | +| `index` | in | `const cuvs::neighbors::cagra::index&` | CAGRA index | +| `include_dataset` | in | `bool` | Whether or not to write out the dataset to the file. Default: `true`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/cagra.hpp:2021`_ + +### cuvs::neighbors::cagra::deserialize + +Load index from input stream + +```cpp +void deserialize(raft::resources const& handle, +std::istream& is, +cuvs::neighbors::cagra::index* index); +``` + +Experimental, both the API and the serialization format are subject to change. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | the raft handle | +| `is` | in | `std::istream&` | input stream | +| `index` | out | `cuvs::neighbors::cagra::index*` | the cagra index | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/cagra.hpp:2047`_ + +### cuvs::neighbors::cagra::serialize + +Save the index to file. + +```cpp +void serialize(raft::resources const& handle, +const std::string& filename, +const cuvs::neighbors::cagra::index& index, +bool include_dataset = true); +``` + +Experimental, both the API and the serialization format are subject to change. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | the raft handle | +| `filename` | in | `const std::string&` | the file name for saving the index | +| `index` | in | `const cuvs::neighbors::cagra::index&` | CAGRA index | +| `include_dataset` | in | `bool` | Whether or not to write out the dataset to the file. Default: `true`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/cagra.hpp:2073`_ + +### cuvs::neighbors::cagra::deserialize + +Load index from file. + +```cpp +void deserialize(raft::resources const& handle, +const std::string& filename, +cuvs::neighbors::cagra::index* index); +``` + +Experimental, both the API and the serialization format are subject to change. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | the raft handle | +| `filename` | in | `const std::string&` | the name of the file that stores the index | +| `index` | out | `cuvs::neighbors::cagra::index*` | the cagra index | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/cagra.hpp:2100`_ + +### cuvs::neighbors::cagra::serialize + +Write the index to an output stream + +```cpp +void serialize(raft::resources const& handle, +std::ostream& os, +const cuvs::neighbors::cagra::index& index, +bool include_dataset = true); +``` + +Experimental, both the API and the serialization format are subject to change. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | the raft handle | +| `os` | in | `std::ostream&` | output stream | +| `index` | in | `const cuvs::neighbors::cagra::index&` | CAGRA index | +| `include_dataset` | in | `bool` | Whether or not to write out the dataset to the file. Default: `true`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/cagra.hpp:2126`_ + +### cuvs::neighbors::cagra::deserialize + +Load index from input stream + +```cpp +void deserialize(raft::resources const& handle, +std::istream& is, +cuvs::neighbors::cagra::index* index); +``` + +Experimental, both the API and the serialization format are subject to change. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | the raft handle | +| `is` | in | `std::istream&` | input stream | +| `index` | out | `cuvs::neighbors::cagra::index*` | the cagra index | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/cagra.hpp:2152`_ + +### cuvs::neighbors::cagra::serialize_to_hnswlib + +Write the CAGRA built index as a base layer HNSW index to an output stream + +```cpp +void serialize_to_hnswlib( +raft::resources const& handle, +std::ostream& os, +const cuvs::neighbors::cagra::index& index, +std::optional> dataset = +std::nullopt); +``` + +NOTE: The saved index can only be read by the hnswlib wrapper in cuVS, as the serialization format is not compatible with the original hnswlib. Experimental, both the API and the serialization format are subject to change. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | the raft handle | +| `os` | in | `std::ostream&` | output stream | +| `index` | in | `const cuvs::neighbors::cagra::index&` | CAGRA index | +| `dataset` | in | `std::optional>` | [optional] host array that stores the dataset, required if the index does not contain the dataset. Default: `std::nullopt`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/cagra.hpp:2182`_ + +### cuvs::neighbors::cagra::serialize_to_hnswlib + +Save a CAGRA build index in hnswlib base-layer-only serialized format + +```cpp +void serialize_to_hnswlib( +raft::resources const& handle, +const std::string& filename, +const cuvs::neighbors::cagra::index& index, +std::optional> dataset = +std::nullopt); +``` + +NOTE: The saved index can only be read by the hnswlib wrapper in cuVS, as the serialization format is not compatible with the original hnswlib. Experimental, both the API and the serialization format are subject to change. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | the raft handle | +| `filename` | in | `const std::string&` | the file name for saving the index | +| `index` | in | `const cuvs::neighbors::cagra::index&` | CAGRA index | +| `dataset` | in | `std::optional>` | [optional] host array that stores the dataset, required if the index does not contain the dataset. Default: `std::nullopt`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/cagra.hpp:2216`_ + +### cuvs::neighbors::cagra::serialize_to_hnswlib + +Write the CAGRA built index as a base layer HNSW index to an output stream + +```cpp +void serialize_to_hnswlib( +raft::resources const& handle, +std::ostream& os, +const cuvs::neighbors::cagra::index& index, +std::optional> dataset = +std::nullopt); +``` + +NOTE: The saved index can only be read by the hnswlib wrapper in cuVS, as the serialization format is not compatible with the original hnswlib. Experimental, both the API and the serialization format are subject to change. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | the raft handle | +| `os` | in | `std::ostream&` | output stream | +| `index` | in | `const cuvs::neighbors::cagra::index&` | CAGRA index | +| `dataset` | in | `std::optional>` | [optional] host array that stores the dataset, required if the index does not contain the dataset. Default: `std::nullopt`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/cagra.hpp:2249`_ + +### cuvs::neighbors::cagra::serialize_to_hnswlib + +Save a CAGRA build index in hnswlib base-layer-only serialized format + +```cpp +void serialize_to_hnswlib( +raft::resources const& handle, +const std::string& filename, +const cuvs::neighbors::cagra::index& index, +std::optional> dataset = +std::nullopt); +``` + +NOTE: The saved index can only be read by the hnswlib wrapper in cuVS, as the serialization format is not compatible with the original hnswlib. Experimental, both the API and the serialization format are subject to change. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | the raft handle | +| `filename` | in | `const std::string&` | the file name for saving the index | +| `index` | in | `const cuvs::neighbors::cagra::index&` | CAGRA index | +| `dataset` | in | `std::optional>` | [optional] host array that stores the dataset, required if the index does not contain the dataset. Default: `std::nullopt`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/cagra.hpp:2283`_ + +### cuvs::neighbors::cagra::serialize_to_hnswlib + +Write the CAGRA built index as a base layer HNSW index to an output stream + +```cpp +void serialize_to_hnswlib( +raft::resources const& handle, +std::ostream& os, +const cuvs::neighbors::cagra::index& index, +std::optional> dataset = +std::nullopt); +``` + +NOTE: The saved index can only be read by the hnswlib wrapper in cuVS, as the serialization format is not compatible with the original hnswlib. Experimental, both the API and the serialization format are subject to change. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | the raft handle | +| `os` | in | `std::ostream&` | output stream | +| `index` | in | `const cuvs::neighbors::cagra::index&` | CAGRA index | +| `dataset` | in | `std::optional>` | [optional] host array that stores the dataset, required if the index does not contain the dataset. Default: `std::nullopt`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/cagra.hpp:2316`_ + +### cuvs::neighbors::cagra::serialize_to_hnswlib + +Save a CAGRA build index in hnswlib base-layer-only serialized format + +```cpp +void serialize_to_hnswlib( +raft::resources const& handle, +const std::string& filename, +const cuvs::neighbors::cagra::index& index, +std::optional> dataset = +std::nullopt); +``` + +NOTE: The saved index can only be read by the hnswlib wrapper in cuVS, as the serialization format is not compatible with the original hnswlib. Experimental, both the API and the serialization format are subject to change. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | the raft handle | +| `filename` | in | `const std::string&` | the file name for saving the index | +| `index` | in | `const cuvs::neighbors::cagra::index&` | CAGRA index | +| `dataset` | in | `std::optional>` | [optional] host array that stores the dataset, required if the index does not contain the dataset. Default: `std::nullopt`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/cagra.hpp:2350`_ + +### cuvs::neighbors::cagra::serialize_to_hnswlib + +Write the CAGRA built index as a base layer HNSW index to an output stream + +```cpp +void serialize_to_hnswlib( +raft::resources const& handle, +std::ostream& os, +const cuvs::neighbors::cagra::index& index, +std::optional> dataset = +std::nullopt); +``` + +NOTE: The saved index can only be read by the hnswlib wrapper in cuVS, as the serialization format is not compatible with the original hnswlib. Experimental, both the API and the serialization format are subject to change. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | the raft handle | +| `os` | in | `std::ostream&` | output stream | +| `index` | in | `const cuvs::neighbors::cagra::index&` | CAGRA index | +| `dataset` | in | `std::optional>` | [optional] host array that stores the dataset, required if the index does not contain the dataset. Default: `std::nullopt`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/cagra.hpp:2383`_ + +### cuvs::neighbors::cagra::serialize_to_hnswlib + +Save a CAGRA build index in hnswlib base-layer-only serialized format + +```cpp +void serialize_to_hnswlib( +raft::resources const& handle, +const std::string& filename, +const cuvs::neighbors::cagra::index& index, +std::optional> dataset = +std::nullopt); +``` + +NOTE: The saved index can only be read by the hnswlib wrapper in cuVS, as the serialization format is not compatible with the original hnswlib. Experimental, both the API and the serialization format are subject to change. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | the raft handle | +| `filename` | in | `const std::string&` | the file name for saving the index | +| `index` | in | `const cuvs::neighbors::cagra::index&` | CAGRA index | +| `dataset` | in | `std::optional>` | [optional] host array that stores the dataset, required if the index does not contain the dataset. Default: `std::nullopt`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/cagra.hpp:2417`_ diff --git a/fern/pages/cpp_api/cpp-api-neighbors-common.md b/fern/pages/cpp_api/cpp-api-neighbors-common.md new file mode 100644 index 0000000000..3ccf52b309 --- /dev/null +++ b/fern/pages/cpp_api/cpp-api-neighbors-common.md @@ -0,0 +1,235 @@ +--- +slug: api-reference/cpp-api-neighbors-common +--- + +# Common + +_Source header: `cpp/include/cuvs/neighbors/common.hpp`_ + +## Approximate Nearest Neighbors Types + +_Doxygen group: `neighbors_index`_ + +### cuvs::neighbors::index + +The base for approximate KNN index structures. + +```cpp +struct index { ... } ; +``` + +_Source: `cpp/include/cuvs/neighbors/common.hpp:107`_ + +### cuvs::neighbors::index_params + +The base for KNN index parameters. + +```cpp +struct index_params { ... } ; +``` + +**Fields** + +| Name | Type | Description | +| --- | --- | --- | +| `metric` | `cuvs::distance::DistanceType` | Distance type. | +| `metric_arg` | `float` | The argument used by some distance metrics. | + +_Source: `cpp/include/cuvs/neighbors/common.hpp:110`_ + +### cuvs::neighbors::MergeStrategy + +Strategy for merging indices. + +This enum is declared separately to avoid namespace pollution when including common.hpp. It provides a generic merge strategy that can be used across different index types. + +```cpp +enum class MergeStrategy { ... } ; +``` + +**Values** + +| Name | Value | +| --- | --- | +| `MERGE_STRATEGY_PHYSICAL` | `0` | +| `MERGE_STRATEGY_LOGICAL` | `1` | + +_Source: `cpp/include/cuvs/neighbors/common.hpp:125`_ + +## Filtering for ANN Types + +_Doxygen group: `neighbors_filtering`_ + +### filtering::FilterType + +Filtering for ANN Types + +```cpp +enum class FilterType { ... } ; +``` + +**Values** + +| Name | Value | +| --- | --- | +| `None` | `` | +| `Bitmap` | `` | +| `Bitset` | `` | + +_Source: `cpp/include/cuvs/neighbors/common.hpp:496`_ + +### filtering::operator + +```cpp +constexpr __forceinline__ _RAFT_HOST_DEVICE bool operator()( +// query index +const uint32_t query_ix, +// the current inverted list index +const uint32_t cluster_ix, +// the index of the current sample inside the current inverted list +const uint32_t sample_ix) const; +``` + +**Returns** + +`constexpr __forceinline__ _RAFT_HOST_DEVICE bool` + +_Source: `cpp/include/cuvs/neighbors/common.hpp:506`_ + +### filtering::get_filter_type + +```cpp +FilterType get_filter_type() const override; +``` + +**Returns** + +`FilterType` + +_Source: `cpp/include/cuvs/neighbors/common.hpp:520`_ + +### filtering::operator + +If the original filter takes three arguments, then don't modify the arguments. + +```cpp +inline _RAFT_HOST_DEVICE bool operator()( +// query index +const uint32_t query_ix, +// the current inverted list index +const uint32_t cluster_ix, +// the index of the current sample inside the current inverted list +const uint32_t sample_ix) const; +``` + +If the original filter takes two arguments, then we are using `inds_ptr_` to obtain the sample index. + +**Returns** + +`inline _RAFT_HOST_DEVICE bool` + +_Source: `cpp/include/cuvs/neighbors/common.hpp:544`_ + +### filtering::operator + +```cpp +inline _RAFT_HOST_DEVICE bool operator()( +// query index +const uint32_t query_ix, +// the index of the current sample +const uint32_t sample_ix) const; +``` + +**Returns** + +`inline _RAFT_HOST_DEVICE bool` + +_Source: `cpp/include/cuvs/neighbors/common.hpp:571`_ + +### filtering::get_filter_type + +```cpp +FilterType get_filter_type() const override; +``` + +**Returns** + +`FilterType` + +_Source: `cpp/include/cuvs/neighbors/common.hpp:578`_ + +### filtering::bitset_filter + +```cpp +_RAFT_HOST_DEVICE bitset_filter(const view_t bitset_for_filtering); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `bitset_for_filtering` | | `const view_t` | | + +**Returns** + +`_RAFT_HOST_DEVICE` + +_Source: `cpp/include/cuvs/neighbors/common.hpp:600`_ + +### filtering::get_filter_type + +```cpp +FilterType get_filter_type() const override; +``` + +**Returns** + +`FilterType` + +_Source: `cpp/include/cuvs/neighbors/common.hpp:608`_ + +## ANN MG index build parameters + +_Doxygen group: `mg_cpp_index_params`_ + +### ivf::distribution_mode + +```cpp +enum distribution_mode { ... } ; +``` + +_Source: `cpp/include/cuvs/neighbors/common.hpp:904`_ + +## ANN MG search parameters + +_Doxygen group: `mg_cpp_search_params`_ + +### ivf::replicated_search_mode + +```cpp +enum replicated_search_mode { ... } ; +``` + +**Values** + +| Name | Value | +| --- | --- | +| `LOAD_BALANCER` | `` | +| `ROUND_ROBIN` | `` | + +_Source: `cpp/include/cuvs/neighbors/common.hpp:915`_ + +### ivf::sharded_merge_mode + +```cpp +enum sharded_merge_mode { ... } ; +``` + +**Values** + +| Name | Value | +| --- | --- | +| `MERGE_ON_ROOT_RANK` | `` | +| `TREE_MERGE` | `` | + +_Source: `cpp/include/cuvs/neighbors/common.hpp:924`_ diff --git a/fern/pages/cpp_api/cpp-api-neighbors-dynamic-batching.md b/fern/pages/cpp_api/cpp-api-neighbors-dynamic-batching.md new file mode 100644 index 0000000000..3cef4b847f --- /dev/null +++ b/fern/pages/cpp_api/cpp-api-neighbors-dynamic-batching.md @@ -0,0 +1,321 @@ +--- +slug: api-reference/cpp-api-neighbors-dynamic-batching +--- + +# Dynamic Batching + +_Source header: `cpp/include/cuvs/neighbors/dynamic_batching.hpp`_ + +## Dynamic Batching index parameters + +_Doxygen group: `dynamic_batching_cpp_index_params`_ + +### detail::index_params + +Dynamic Batching index parameters + +```cpp +struct index_params : cuvs::neighbors::index_params { ... } ; +``` + +**Fields** + +| Name | Type | Description | +| --- | --- | --- | +| `k` | `int64_t` | The number of neighbors to search is fixed at construction time. | +| `max_batch_size` | `int64_t` | Maximum size of the batch to submit to the upstream index. | +| `n_queues` | `size_t` | The number of independent request queues. | +| `conservative_dispatch` | `bool` | By default (`conservative_dispatch = false`) the first CPU thread to commit a query to a batch | + +_Source: `cpp/include/cuvs/neighbors/dynamic_batching.hpp:21`_ + +## Dynamic Batching search parameters + +_Doxygen group: `dynamic_batching_cpp_search_params`_ + +### detail::search_params + +Dynamic Batching search parameters + +```cpp +struct search_params : cuvs::neighbors::search_params { ... } ; +``` + +**Fields** + +| Name | Type | Description | +| --- | --- | --- | +| `dispatch_timeout_ms` | `double` | How long a request can stay in the queue (milliseconds). | + +_Source: `cpp/include/cuvs/neighbors/dynamic_batching.hpp:60`_ + +## Dynamic Batching index type + +_Doxygen group: `dynamic_batching_cpp_index`_ + +### detail::index + +Construct a dynamic batching index by wrapping the upstream index. + +```cpp +template +index(const raft::resources& res, +const cuvs::neighbors::dynamic_batching::index_params& params, +const Upstream& upstream_index, +const typename Upstream::search_params_type& upstream_params, +const cuvs::neighbors::filtering::base_filter* sample_filter = nullptr); +``` + +**Template Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `Upstream` | `` | the upstream index type | + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `const raft::resources&` | raft resources | +| `params` | in | `const cuvs::neighbors::dynamic_batching::index_params&` | dynamic batching parameters | +| `upstream_index` | in | `const Upstream&` | the original index to perform the search (the reference must be alive for the lifetime of the dynamic batching index) | +| `upstream_params` | in | `const typename Upstream::search_params_type&` | the original index search parameters for all queries in a batch (the parameters are captured by value for the lifetime of the dynamic batching index) | +| `sample_filter` | in | `const cuvs::neighbors::filtering::base_filter*` | filtering function, if any, must be the same for all requests in a batch (the pointer must be alive for the lifetime of the dynamic batching index) Default: `nullptr`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/dynamic_batching.hpp:174`_ + +## Dynamic Batching search + +_Doxygen group: `dynamic_batching_cpp_search`_ + +### detail::search + +Search ANN using a dynamic batching index. + +```cpp +void search(raft::resources const& res, +cuvs::neighbors::dynamic_batching::search_params const& params, +dynamic_batching::index const& index, +raft::device_matrix_view queries, +raft::device_matrix_view neighbors, +raft::device_matrix_view distances); +``` + +The search parameters of the upstream index and the optional filtering function are configured at the dynamic batching index construction time. Like with many other indexes, the dynamic batching search has the stream-ordered semantics: the host function may return the control before the results are ready. Synchronize with the main CUDA stream in the given resource object to wait for arrival of the search results. Dynamic batching search is thread-safe: call the search function with copies of the same index in multiple threads to increase the occupancy of the batches. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | | +| `params` | in | `cuvs::neighbors::dynamic_batching::search_params const&` | query-specific batching parameters, such as the maximum waiting time | +| `index` | in | `dynamic_batching::index const&` | a dynamic batching index | +| `queries` | in | `raft::device_matrix_view` | a device matrix view to a row-major matrix [n_queries, dim] | +| `neighbors` | out | `raft::device_matrix_view` | a device matrix view to the indices of the neighbors in the source dataset [n_queries, k] | +| `distances` | out | `raft::device_matrix_view` | a device matrix view to the distances to the selected neighbors [n_queries, k] | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/dynamic_batching.hpp:214`_ + +### detail::search + +```cpp +void search(raft::resources const& res, +cuvs::neighbors::dynamic_batching::search_params const& params, +dynamic_batching::index const& index, +raft::device_matrix_view queries, +raft::device_matrix_view neighbors, +raft::device_matrix_view distances); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | | `raft::resources const&` | | +| `params` | | `cuvs::neighbors::dynamic_batching::search_params const&` | | +| `index` | | `dynamic_batching::index const&` | | +| `queries` | | `raft::device_matrix_view` | | +| `neighbors` | | `raft::device_matrix_view` | | +| `distances` | | `raft::device_matrix_view` | | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/dynamic_batching.hpp:222`_ + +### detail::search + +```cpp +void search(raft::resources const& res, +cuvs::neighbors::dynamic_batching::search_params const& params, +dynamic_batching::index const& index, +raft::device_matrix_view queries, +raft::device_matrix_view neighbors, +raft::device_matrix_view distances); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | | `raft::resources const&` | | +| `params` | | `cuvs::neighbors::dynamic_batching::search_params const&` | | +| `index` | | `dynamic_batching::index const&` | | +| `queries` | | `raft::device_matrix_view` | | +| `neighbors` | | `raft::device_matrix_view` | | +| `distances` | | `raft::device_matrix_view` | | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/dynamic_batching.hpp:230`_ + +### detail::search + +```cpp +void search(raft::resources const& res, +cuvs::neighbors::dynamic_batching::search_params const& params, +dynamic_batching::index const& index, +raft::device_matrix_view queries, +raft::device_matrix_view neighbors, +raft::device_matrix_view distances); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | | `raft::resources const&` | | +| `params` | | `cuvs::neighbors::dynamic_batching::search_params const&` | | +| `index` | | `dynamic_batching::index const&` | | +| `queries` | | `raft::device_matrix_view` | | +| `neighbors` | | `raft::device_matrix_view` | | +| `distances` | | `raft::device_matrix_view` | | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/dynamic_batching.hpp:238`_ + +### detail::search + +```cpp +void search(raft::resources const& res, +cuvs::neighbors::dynamic_batching::search_params const& params, +dynamic_batching::index const& index, +raft::device_matrix_view queries, +raft::device_matrix_view neighbors, +raft::device_matrix_view distances); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | | `raft::resources const&` | | +| `params` | | `cuvs::neighbors::dynamic_batching::search_params const&` | | +| `index` | | `dynamic_batching::index const&` | | +| `queries` | | `raft::device_matrix_view` | | +| `neighbors` | | `raft::device_matrix_view` | | +| `distances` | | `raft::device_matrix_view` | | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/dynamic_batching.hpp:246`_ + +### detail::search + +```cpp +void search(raft::resources const& res, +cuvs::neighbors::dynamic_batching::search_params const& params, +dynamic_batching::index const& index, +raft::device_matrix_view queries, +raft::device_matrix_view neighbors, +raft::device_matrix_view distances); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | | `raft::resources const&` | | +| `params` | | `cuvs::neighbors::dynamic_batching::search_params const&` | | +| `index` | | `dynamic_batching::index const&` | | +| `queries` | | `raft::device_matrix_view` | | +| `neighbors` | | `raft::device_matrix_view` | | +| `distances` | | `raft::device_matrix_view` | | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/dynamic_batching.hpp:254`_ + +### detail::search + +```cpp +void search(raft::resources const& res, +cuvs::neighbors::dynamic_batching::search_params const& params, +dynamic_batching::index const& index, +raft::device_matrix_view queries, +raft::device_matrix_view neighbors, +raft::device_matrix_view distances); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | | `raft::resources const&` | | +| `params` | | `cuvs::neighbors::dynamic_batching::search_params const&` | | +| `index` | | `dynamic_batching::index const&` | | +| `queries` | | `raft::device_matrix_view` | | +| `neighbors` | | `raft::device_matrix_view` | | +| `distances` | | `raft::device_matrix_view` | | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/dynamic_batching.hpp:262`_ + +### detail::search + +```cpp +void search(raft::resources const& res, +cuvs::neighbors::dynamic_batching::search_params const& params, +dynamic_batching::index const& index, +raft::device_matrix_view queries, +raft::device_matrix_view neighbors, +raft::device_matrix_view distances); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | | `raft::resources const&` | | +| `params` | | `cuvs::neighbors::dynamic_batching::search_params const&` | | +| `index` | | `dynamic_batching::index const&` | | +| `queries` | | `raft::device_matrix_view` | | +| `neighbors` | | `raft::device_matrix_view` | | +| `distances` | | `raft::device_matrix_view` | | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/dynamic_batching.hpp:270`_ diff --git a/fern/pages/cpp_api/cpp-api-neighbors-epsilon-neighborhood.md b/fern/pages/cpp_api/cpp-api-neighbors-epsilon-neighborhood.md new file mode 100644 index 0000000000..bc7c5b8327 --- /dev/null +++ b/fern/pages/cpp_api/cpp-api-neighbors-epsilon-neighborhood.md @@ -0,0 +1,54 @@ +--- +slug: api-reference/cpp-api-neighbors-epsilon-neighborhood +--- + +# Epsilon Neighborhood + +_Source header: `cpp/include/cuvs/neighbors/epsilon_neighborhood.hpp`_ + +## Epsilon Neighborhood L2 Operations + +_Doxygen group: `epsilon_neighborhood_cpp_l2`_ + +### cuvs::neighbors::epsilon_neighborhood::compute + +Computes epsilon neighborhood for the given distance metric and ball size. + +```cpp +template +void compute(raft::resources const& handle, +raft::device_matrix_view x, +raft::device_matrix_view y, +raft::device_matrix_view adj, +raft::device_vector_view vd, +value_t eps, +cuvs::distance::DistanceType metric = cuvs::distance::DistanceType::L2Unexpanded); +``` + +The epsilon neighbors is represented by a dense boolean adjacency matrix of size m * n and an array of degrees for each vertex, which can be used as a compressed sparse row (CSR) indptr array. Currently, only L2Unexpanded (L2-squared) distance metric is supported. Other metrics will throw an exception. + +**Template Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `value_t` | `` | IO and math type | +| `idx_t` | `` | Index type | +| `matrix_idx_t` | `` | matrix indexing type | + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | raft handle to manage library resources | +| `x` | in | `raft::device_matrix_view` | first matrix [row-major] [on device] [dim = m x k] | +| `y` | in | `raft::device_matrix_view` | second matrix [row-major] [on device] [dim = n x k] | +| `adj` | out | `raft::device_matrix_view` | adjacency matrix [row-major] [on device] [dim = m x n] | +| `vd` | out | `raft::device_vector_view` | vertex degree array [on device] [len = m + 1] `vd + m` stores the total number of edges in the adjacency matrix. Pass a nullptr if you don't need this info. | +| `eps` | in | `value_t` | defines epsilon neighborhood radius (should be passed as squared when using L2Unexpanded metric) | +| `metric` | in | `cuvs::distance::DistanceType` | distance metric to use. Currently only L2Unexpanded is supported. Default: `cuvs::distance::DistanceType::L2Unexpanded`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/epsilon_neighborhood.hpp:58`_ diff --git a/fern/pages/cpp_api/cpp-api-neighbors-hnsw.md b/fern/pages/cpp_api/cpp-api-neighbors-hnsw.md new file mode 100644 index 0000000000..4deb5a274c --- /dev/null +++ b/fern/pages/cpp_api/cpp-api-neighbors-hnsw.md @@ -0,0 +1,896 @@ +--- +slug: api-reference/cpp-api-neighbors-hnsw +--- + +# HNSW + +_Source header: `cpp/include/cuvs/neighbors/hnsw.hpp`_ + +## hnswlib index wrapper params + +_Doxygen group: `hnsw_cpp_index_params`_ + +### cuvs::neighbors::hnsw::HnswHierarchy + +Hierarchy for HNSW index when converting from CAGRA index + +NOTE: When the value is `NONE`, the HNSW index is built as a base-layer-only index. + +```cpp +enum class HnswHierarchy { ... } ; +``` + +**Values** + +| Name | Value | +| --- | --- | +| `NONE` | `` | + +_Source: `cpp/include/cuvs/neighbors/hnsw.hpp:40`_ + +### cuvs::neighbors::hnsw::[[deprecated + +Create a CAGRA index parameters compatible with HNSW index + +```cpp +[[deprecated("Use cagra::index_params::from_hnsw_params instead")]] +cuvs::neighbors::cagra::index_params to_cagra_params( +raft::matrix_extent dataset, +int M, +int ef_construction, +cuvs::distance::DistanceType metric = cuvs::distance::DistanceType::L2Expanded); +``` + +* IMPORTANT NOTE * The reference HNSW index and the corresponding from-CAGRA generated HNSW index will NOT produce the same recalls and QPS for the same parameter `ef`. The graphs are different internally. For the same `ef`, the from-CAGRA index likely has a slightly higher recall and slightly lower QPS. However, the Recall-QPS curves should be similar (i.e. the points are just shifted along the curve). Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `arg1` | | `"Use cagra::index_params::from_hnsw_params instead"` | | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/hnsw.hpp:114`_ + +## hnswlib index wrapper + +_Doxygen group: `hnsw_cpp_index`_ + +### template <typename T> + +hnswlib index wrapper + +```cpp +template +``` + +_Source: `cpp/include/cuvs/neighbors/hnsw.hpp:130`_ + +### cuvs::neighbors::hnsw::index + +load a base-layer-only hnswlib index originally saved from a built CAGRA index. + +```cpp +index(int dim, cuvs::distance::DistanceType metric, HnswHierarchy hierarchy = HnswHierarchy::NONE) +: dim_; +``` + +This is a virtual class and it cannot be used directly. To create an index, use the factory function `cuvs::neighbors::hnsw::from_cagra` from the header `cuvs/neighbors/hnsw.hpp` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `dim` | in | `int` | dimensions of the training dataset | +| `metric` | in | `cuvs::distance::DistanceType` | distance metric to search. Supported metrics ("L2Expanded", "InnerProduct") | +| `hierarchy` | in | `HnswHierarchy` | hierarchy used for upper HNSW layers Default: `HnswHierarchy::NONE`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/hnsw.hpp:143`_ + +### cuvs::neighbors::hnsw::get_index + +Get underlying index + +```cpp +virtual void const* get_index() const = 0; +``` + +**Returns** + +`virtual void const*` + +_Source: `cpp/include/cuvs/neighbors/hnsw.hpp:153`_ + +### cuvs::neighbors::hnsw::set_ef + +Set ef for search + +```cpp +virtual void set_ef(int ef) const = 0; +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `ef` | | `int` | | + +**Returns** + +`virtual void` + +_Source: `cpp/include/cuvs/neighbors/hnsw.hpp:164`_ + +### cuvs::neighbors::hnsw::file_path + +Get file path for disk-backed index + +```cpp +virtual std::string file_path() const; +``` + +**Returns** + +`virtual std::string` + +_Source: `cpp/include/cuvs/neighbors/hnsw.hpp:169`_ + +## HNSW index extend parameters + +_Doxygen group: `hnsw_cpp_extend_params`_ + +### cuvs::neighbors::hnsw::extend_params + +HNSW index extend parameters + +```cpp +struct extend_params { ... } ; +``` + +**Fields** + +| Name | Type | Description | +| --- | --- | --- | +| `num_threads` | `int` | Number of host threads to use to add additional vectors to the index. | + +_Source: `cpp/include/cuvs/neighbors/hnsw.hpp:186`_ + +## Build HNSW index on the GPU + +_Doxygen group: `hnsw_cpp_index_build`_ + +### cuvs::neighbors::hnsw::build + +Build an HNSW index on the GPU + +```cpp +std::unique_ptr> build( +raft::resources const& res, +const index_params& params, +raft::host_matrix_view dataset); +``` + +The resulting graph is compatible for HNSW search, but is not an exact equivalent of the graph built by the HNSW. The HNSW index construction parameters `M` and `ef_construction` are the main parameters to control the graph degree and graph quality. We have additional options that can be used to fine tune graph building on the GPU (see `cuvs::neighbors::cagra::index_params`). In case the index does not fit the host or GPU memory, we would use disk as temporary storage. In such cases it is important to set `ace_params.build_dir` to a fast disk with sufficient storage size. NOTE: This function requires CUDA headers to be available at compile time. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resources | +| `params` | in | `const index_params&` | hnsw index parameters including ACE configuration | +| `dataset` | in | `raft::host_matrix_view` | a host matrix view to a row-major matrix [n_rows, dim] | + +**Returns** + +`std::unique_ptr>` + +_Source: `cpp/include/cuvs/neighbors/hnsw.hpp:254`_ + +### cuvs::neighbors::hnsw::build + +Build an HNSW index on the GPU + +```cpp +std::unique_ptr> build( +raft::resources const& res, +const index_params& params, +raft::host_matrix_view dataset); +``` + +The resulting graph is compatible for HNSW search, but is not an exact equivalent of the graph built by the HNSW. The HNSW index construction parameters `M` and `ef_construction` are the main parameters to control the graph degree and graph quality. We have additional options that can be used to fine tune graph building on the GPU (see `cuvs::neighbors::cagra::index_params`). In case the index does not fit the host or GPU memory, we would use disk as temporary storage. In such cases it is important to set `ace_params.build_dir` to a fast disk with sufficient storage size. NOTE: This function requires CUDA headers to be available at compile time. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resources | +| `params` | in | `const index_params&` | hnsw index parameters including ACE configuration | +| `dataset` | in | `raft::host_matrix_view` | a host matrix view to a row-major matrix [n_rows, dim] | + +**Returns** + +`std::unique_ptr>` + +_Source: `cpp/include/cuvs/neighbors/hnsw.hpp:312`_ + +### cuvs::neighbors::hnsw::build + +Build an HNSW index on the GPU + +```cpp +std::unique_ptr> build( +raft::resources const& res, +const index_params& params, +raft::host_matrix_view dataset); +``` + +The resulting graph is compatible for HNSW search, but is not an exact equivalent of the graph built by the HNSW. The HNSW index construction parameters `M` and `ef_construction` are the main parameters to control the graph degree and graph quality. We have additional options that can be used to fine tune graph building on the GPU (see `cuvs::neighbors::cagra::index_params`). In case the index does not fit the host or GPU memory, we would use disk as temporary storage. In such cases it is important to set `ace_params.build_dir` to a fast disk with sufficient storage size. NOTE: This function requires CUDA headers to be available at compile time. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resources | +| `params` | in | `const index_params&` | hnsw index parameters including ACE configuration | +| `dataset` | in | `raft::host_matrix_view` | a host matrix view to a row-major matrix [n_rows, dim] | + +**Returns** + +`std::unique_ptr>` + +_Source: `cpp/include/cuvs/neighbors/hnsw.hpp:370`_ + +### cuvs::neighbors::hnsw::build + +Build an HNSW index on the GPU + +```cpp +std::unique_ptr> build( +raft::resources const& res, +const index_params& params, +raft::host_matrix_view dataset); +``` + +The resulting graph is compatible for HNSW search, but is not an exact equivalent of the graph built by the HNSW. The HNSW index construction parameters `M` and `ef_construction` are the main parameters to control the graph degree and graph quality. We have additional options that can be used to fine tune graph building on the GPU (see `cuvs::neighbors::cagra::index_params`). In case the index does not fit the host or GPU memory, we would use disk as temporary storage. In such cases it is important to set `ace_params.build_dir` to a fast disk with sufficient storage size. NOTE: This function requires CUDA headers to be available at compile time. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resources | +| `params` | in | `const index_params&` | hnsw index parameters including ACE configuration | +| `dataset` | in | `raft::host_matrix_view` | a host matrix view to a row-major matrix [n_rows, dim] | + +**Returns** + +`std::unique_ptr>` + +_Source: `cpp/include/cuvs/neighbors/hnsw.hpp:428`_ + +## Load CAGRA index as hnswlib index + +_Doxygen group: `hnsw_cpp_index_load`_ + +### cuvs::neighbors::hnsw::from_cagra + +Construct an hnswlib index from a CAGRA index + +```cpp +std::unique_ptr> from_cagra( +raft::resources const& res, +const index_params& params, +const cuvs::neighbors::cagra::index& cagra_index, +std::optional> dataset = +std::nullopt); +``` + +NOTE: When `hnsw::index_params.hierarchy` is: 1. `NONE`: This method uses the filesystem to write the CAGRA index in `/tmp/<random_number>.bin` before reading it as an hnswlib index, then deleting the temporary file. The returned index is immutable and can only be searched by the hnswlib wrapper in cuVS, as the format is not compatible with the original hnswlib. 2. `CPU`: The returned index is mutable and can be extended with additional vectors. The serialized index is also compatible with the original hnswlib library. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resources | +| `params` | in | `const index_params&` | hnsw index parameters | +| `cagra_index` | in | `const cuvs::neighbors::cagra::index&` | cagra index | +| `dataset` | in | `std::optional>` | optional dataset to avoid extra memory copy when hierarchy is `CPU` Default: `std::nullopt`. | + +**Returns** + +`std::unique_ptr>` + +_Source: `cpp/include/cuvs/neighbors/hnsw.hpp:471`_ + +### cuvs::neighbors::hnsw::from_cagra + +Construct an hnswlib index from a CAGRA index + +```cpp +std::unique_ptr> from_cagra( +raft::resources const& res, +const index_params& params, +const cuvs::neighbors::cagra::index& cagra_index, +std::optional> dataset = +std::nullopt); +``` + +NOTE: When `hnsw::index_params.hierarchy` is: 1. `NONE`: This method uses the filesystem to write the CAGRA index in `/tmp/<random_number>.bin` before reading it as an hnswlib index, then deleting the temporary file. The returned index is immutable and can only be searched by the hnswlib wrapper in cuVS, as the format is not compatible with the original hnswlib. 2. `CPU`: The returned index is mutable and can be extended with additional vectors. The serialized index is also compatible with the original hnswlib library. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resources | +| `params` | in | `const index_params&` | hnsw index parameters | +| `cagra_index` | in | `const cuvs::neighbors::cagra::index&` | cagra index | +| `dataset` | in | `std::optional>` | optional dataset to avoid extra memory copy when hierarchy is `CPU` Default: `std::nullopt`. | + +**Returns** + +`std::unique_ptr>` + +_Source: `cpp/include/cuvs/neighbors/hnsw.hpp:507`_ + +### cuvs::neighbors::hnsw::from_cagra + +Construct an hnswlib index from a CAGRA index + +```cpp +std::unique_ptr> from_cagra( +raft::resources const& res, +const index_params& params, +const cuvs::neighbors::cagra::index& cagra_index, +std::optional> dataset = +std::nullopt); +``` + +NOTE: When `hnsw::index_params.hierarchy` is: 1. `NONE`: This method uses the filesystem to write the CAGRA index in `/tmp/<random_number>.bin` before reading it as an hnswlib index, then deleting the temporary file. The returned index is immutable and can only be searched by the hnswlib wrapper in cuVS, as the format is not compatible with the original hnswlib. 2. `CPU`: The returned index is mutable and can be extended with additional vectors. The serialized index is also compatible with the original hnswlib library. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resources | +| `params` | in | `const index_params&` | hnsw index parameters | +| `cagra_index` | in | `const cuvs::neighbors::cagra::index&` | cagra index | +| `dataset` | in | `std::optional>` | optional dataset to avoid extra memory copy when hierarchy is `CPU` Default: `std::nullopt`. | + +**Returns** + +`std::unique_ptr>` + +_Source: `cpp/include/cuvs/neighbors/hnsw.hpp:543`_ + +### cuvs::neighbors::hnsw::from_cagra + +Construct an hnswlib index from a CAGRA index + +```cpp +std::unique_ptr> from_cagra( +raft::resources const& res, +const index_params& params, +const cuvs::neighbors::cagra::index& cagra_index, +std::optional> dataset = +std::nullopt); +``` + +NOTE: When `hnsw::index_params.hierarchy` is: 1. `NONE`: This method uses the filesystem to write the CAGRA index in `/tmp/<random_number>.bin` before reading it as an hnswlib index, then deleting the temporary file. The returned index is immutable and can only be searched by the hnswlib wrapper in cuVS, as the format is not compatible with the original hnswlib. 2. `CPU`: The returned index is mutable and can be extended with additional vectors. The serialized index is also compatible with the original hnswlib library. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resources | +| `params` | in | `const index_params&` | hnsw index parameters | +| `cagra_index` | in | `const cuvs::neighbors::cagra::index&` | cagra index | +| `dataset` | in | `std::optional>` | optional dataset to avoid extra memory copy when hierarchy is `CPU` Default: `std::nullopt`. | + +**Returns** + +`std::unique_ptr>` + +_Source: `cpp/include/cuvs/neighbors/hnsw.hpp:579`_ + +## Extend HNSW index with additional vectors + +_Doxygen group: `hnsw_cpp_index_extend`_ + +### cuvs::neighbors::hnsw::extend + +Add new vectors to an HNSW index + +```cpp +void extend(raft::resources const& res, +const extend_params& params, +raft::host_matrix_view additional_dataset, +index& idx); +``` + +NOTE: The HNSW index can only be extended when the `hnsw::index_params.hierarchy` is `CPU` when converting from a CAGRA index. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resources | +| `params` | in | `const extend_params&` | configure the extend | +| `additional_dataset` | in | `raft::host_matrix_view` | a host matrix view to a row-major matrix [n_rows, index->dim()] | +| `idx` | inout | `index&` | HNSW index to extend | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/hnsw.hpp:624`_ + +### cuvs::neighbors::hnsw::extend + +Add new vectors to an HNSW index + +```cpp +void extend(raft::resources const& res, +const extend_params& params, +raft::host_matrix_view additional_dataset, +index& idx); +``` + +NOTE: The HNSW index can only be extended when the `hnsw::index_params.hierarchy` is `CPU` when converting from a CAGRA index. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resources | +| `params` | in | `const extend_params&` | configure the extend | +| `additional_dataset` | in | `raft::host_matrix_view` | a host matrix view to a row-major matrix [n_rows, index->dim()] | +| `idx` | inout | `index&` | HNSW index to extend | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/hnsw.hpp:658`_ + +### cuvs::neighbors::hnsw::extend + +Add new vectors to an HNSW index + +```cpp +void extend(raft::resources const& res, +const extend_params& params, +raft::host_matrix_view additional_dataset, +index& idx); +``` + +NOTE: The HNSW index can only be extended when the `hnsw::index_params.hierarchy` is `CPU` when converting from a CAGRA index. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resources | +| `params` | in | `const extend_params&` | configure the extend | +| `additional_dataset` | in | `raft::host_matrix_view` | a host matrix view to a row-major matrix [n_rows, index->dim()] | +| `idx` | inout | `index&` | HNSW index to extend | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/hnsw.hpp:692`_ + +### cuvs::neighbors::hnsw::extend + +Add new vectors to an HNSW index + +```cpp +void extend(raft::resources const& res, +const extend_params& params, +raft::host_matrix_view additional_dataset, +index& idx); +``` + +NOTE: The HNSW index can only be extended when the `hnsw::index_params.hierarchy` is `CPU` when converting from a CAGRA index. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resources | +| `params` | in | `const extend_params&` | configure the extend | +| `additional_dataset` | in | `raft::host_matrix_view` | a host matrix view to a row-major matrix [n_rows, index->dim()] | +| `idx` | inout | `index&` | HNSW index to extend | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/hnsw.hpp:726`_ + +## Build CAGRA index and search with hnswlib + +_Doxygen group: `hnsw_cpp_search_params`_ + +### cuvs::neighbors::hnsw::search_params + +Build CAGRA index and search with hnswlib + +```cpp +struct search_params : cuvs::neighbors::search_params { ... } ; +``` + +**Fields** + +| Name | Type | Description | +| --- | --- | --- | +| `ef` | `int` | size of the candidate list | +| `num_threads` | `int` | number of host threads to use for concurrent searches. Value of 0 | + +_Source: `cpp/include/cuvs/neighbors/hnsw.hpp:740`_ + +## Search hnswlib index + +_Doxygen group: `hnsw_cpp_index_search`_ + +### cuvs::neighbors::hnsw::search + +Search HNSW index constructed from a CAGRA index + +```cpp +void search(raft::resources const& res, +const search_params& params, +const index& idx, +raft::host_matrix_view queries, +raft::host_matrix_view neighbors, +raft::host_matrix_view distances); +``` + +NOTE: The HNSW index can only be searched by the hnswlib wrapper in cuVS when the hierarchy is `NONE`, as the format is not compatible with the original hnswlib. [n_queries, k] k] Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resources | +| `params` | in | `const search_params&` | configure the search | +| `idx` | in | `const index&` | cagra index | +| `queries` | in | `raft::host_matrix_view` | a host matrix view to a row-major matrix [n_queries, index->dim()] | +| `neighbors` | out | `raft::host_matrix_view` | a host matrix view to the indices of the neighbors in the source dataset | +| `distances` | out | `raft::host_matrix_view` | a host matrix view to the distances to the selected neighbors [n_queries, | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/hnsw.hpp:794`_ + +### cuvs::neighbors::hnsw::search + +Search HNSW index constructed from a CAGRA index + +```cpp +void search(raft::resources const& res, +const search_params& params, +const index& idx, +raft::host_matrix_view queries, +raft::host_matrix_view neighbors, +raft::host_matrix_view distances); +``` + +NOTE: The HNSW index can only be searched by the hnswlib wrapper in cuVS when the hierarchy is `NONE`, as the format is not compatible with the original hnswlib. [n_queries, k] k] Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resources | +| `params` | in | `const search_params&` | configure the search | +| `idx` | in | `const index&` | cagra index | +| `queries` | in | `raft::host_matrix_view` | a host matrix view to a row-major matrix [n_queries, index->dim()] | +| `neighbors` | out | `raft::host_matrix_view` | a host matrix view to the indices of the neighbors in the source dataset | +| `distances` | out | `raft::host_matrix_view` | a host matrix view to the distances to the selected neighbors [n_queries, | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/hnsw.hpp:838`_ + +### cuvs::neighbors::hnsw::search + +Search HNSWindex constructed from a CAGRA index + +```cpp +void search(raft::resources const& res, +const search_params& params, +const index& idx, +raft::host_matrix_view queries, +raft::host_matrix_view neighbors, +raft::host_matrix_view distances); +``` + +NOTE: The HNSW index can only be searched by the hnswlib wrapper in cuVS when the hierarchy is `NONE`, as the format is not compatible with the original hnswlib. [n_queries, k] k] Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resources | +| `params` | in | `const search_params&` | configure the search | +| `idx` | in | `const index&` | cagra index | +| `queries` | in | `raft::host_matrix_view` | a host matrix view to a row-major matrix [n_queries, index->dim()] | +| `neighbors` | out | `raft::host_matrix_view` | a host matrix view to the indices of the neighbors in the source dataset | +| `distances` | out | `raft::host_matrix_view` | a host matrix view to the distances to the selected neighbors [n_queries, | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/hnsw.hpp:882`_ + +### cuvs::neighbors::hnsw::search + +Search HNSW index constructed from a CAGRA index + +```cpp +void search(raft::resources const& res, +const search_params& params, +const index& idx, +raft::host_matrix_view queries, +raft::host_matrix_view neighbors, +raft::host_matrix_view distances); +``` + +NOTE: The HNSW index can only be searched by the hnswlib wrapper in cuVS when the hierarchy is `NONE`, as the format is not compatible with the original hnswlib. [n_queries, k] k] Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resources | +| `params` | in | `const search_params&` | configure the search | +| `idx` | in | `const index&` | cagra index | +| `queries` | in | `raft::host_matrix_view` | a host matrix view to a row-major matrix [n_queries, index->dim()] | +| `neighbors` | out | `raft::host_matrix_view` | a host matrix view to the indices of the neighbors in the source dataset | +| `distances` | out | `raft::host_matrix_view` | a host matrix view to the distances to the selected neighbors [n_queries, | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/hnsw.hpp:926`_ + +## Deserialize CAGRA index as hnswlib index + +_Doxygen group: `hnsw_cpp_index_serialize`_ + +### cuvs::neighbors::hnsw::serialize + +Serialize the HNSW index to file + +```cpp +void serialize(raft::resources const& res, const std::string& filename, const index& idx); +``` + +NOTE: When hierarchy is `NONE`, the saved hnswlib index is immutable and can only be read by the hnswlib wrapper in cuVS, as the serialization format is not compatible with the original hnswlib. However, when hierarchy is `CPU`, the saved hnswlib index is compatible with the original hnswlib library. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resources | +| `filename` | in | `const std::string&` | path to the file to save the serialized CAGRA index | +| `idx` | in | `const index&` | cagra index | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/hnsw.hpp:969`_ + +### cuvs::neighbors::hnsw::serialize + +Serialize the HNSW index to file + +```cpp +void serialize(raft::resources const& res, const std::string& filename, const index& idx); +``` + +NOTE: When hierarchy is `NONE`, the saved hnswlib index is immutable and can only be read by the hnswlib wrapper in cuVS, as the serialization format is not compatible with the original hnswlib. However, when hierarchy is `CPU`, the saved hnswlib index is compatible with the original hnswlib library. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resources | +| `filename` | in | `const std::string&` | path to the file to save the serialized CAGRA index | +| `idx` | in | `const index&` | cagra index | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/hnsw.hpp:998`_ + +### cuvs::neighbors::hnsw::serialize + +Serialize the HNSW index to file + +```cpp +void serialize(raft::resources const& res, const std::string& filename, const index& idx); +``` + +NOTE: When hierarchy is `NONE`, the saved hnswlib index is immutable and can only be read by the hnswlib wrapper in cuVS, as the serialization format is not compatible with the original hnswlib. However, when hierarchy is `CPU`, the saved hnswlib index is compatible with the original hnswlib library. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resources | +| `filename` | in | `const std::string&` | path to the file to save the serialized CAGRA index | +| `idx` | in | `const index&` | cagra index | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/hnsw.hpp:1027`_ + +### cuvs::neighbors::hnsw::serialize + +Serialize the HNSW index to file + +```cpp +void serialize(raft::resources const& res, const std::string& filename, const index& idx); +``` + +NOTE: When hierarchy is `NONE`, the saved hnswlib index is immutable and can only be read by the hnswlib wrapper in cuVS, as the serialization format is not compatible with the original hnswlib. However, when hierarchy is `CPU`, the saved hnswlib index is compatible with the original hnswlib library. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resources | +| `filename` | in | `const std::string&` | path to the file to save the serialized CAGRA index | +| `idx` | in | `const index&` | cagra index | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/hnsw.hpp:1056`_ + +### cuvs::neighbors::hnsw::deserialize + +De-serialize a CAGRA index saved to a file as an hnswlib index + +```cpp +void deserialize(raft::resources const& res, +const index_params& params, +const std::string& filename, +int dim, +cuvs::distance::DistanceType metric, +index** index); +``` + +NOTE: When hierarchy is `NONE`, the saved hnswlib index is immutable and can only be read by the hnswlib wrapper in cuVS, as the serialization format is not compatible with the original hnswlib. However, when hierarchy is `CPU`, the saved hnswlib index is compatible with the original hnswlib library. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resources | +| `params` | in | `const index_params&` | hnsw index parameters | +| `filename` | in | `const std::string&` | path to the file containing the serialized CAGRA index | +| `dim` | in | `int` | dimensions of the training dataset | +| `metric` | in | `cuvs::distance::DistanceType` | distance metric to search. Supported metrics ("L2Expanded", "InnerProduct") | +| `index` | out | `index**` | hnsw index | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/hnsw.hpp:1094`_ + +### cuvs::neighbors::hnsw::deserialize + +De-serialize a CAGRA index saved to a file as an hnswlib index + +```cpp +void deserialize(raft::resources const& res, +const index_params& params, +const std::string& filename, +int dim, +cuvs::distance::DistanceType metric, +index** index); +``` + +NOTE: When hierarchy is `NONE`, the saved hnswlib index is immutable and can only be read by the hnswlib wrapper in cuVS, as the serialization format is not compatible with the original hnswlib. However, when hierarchy is `CPU`, the saved hnswlib index is compatible with the original hnswlib library. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resources | +| `params` | in | `const index_params&` | hnsw index parameters | +| `filename` | in | `const std::string&` | path to the file containing the serialized CAGRA index | +| `dim` | in | `int` | dimensions of the training dataset | +| `metric` | in | `cuvs::distance::DistanceType` | distance metric to search. Supported metrics ("L2Expanded", "InnerProduct") | +| `index` | out | `index**` | hnsw index | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/hnsw.hpp:1137`_ + +### cuvs::neighbors::hnsw::deserialize + +De-serialize a CAGRA index saved to a file as an hnswlib index + +```cpp +void deserialize(raft::resources const& res, +const index_params& params, +const std::string& filename, +int dim, +cuvs::distance::DistanceType metric, +index** index); +``` + +NOTE: When hierarchy is `NONE`, the saved hnswlib index is immutable and can only be read by the hnswlib wrapper in cuVS, as the serialization format is not compatible with the original hnswlib. However, when hierarchy is `CPU`, the saved hnswlib index is compatible with the original hnswlib library. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resources | +| `params` | in | `const index_params&` | hnsw index parameters | +| `filename` | in | `const std::string&` | path to the file containing the serialized CAGRA index | +| `dim` | in | `int` | dimensions of the training dataset | +| `metric` | in | `cuvs::distance::DistanceType` | distance metric to search. Supported metrics ("L2Expanded", "InnerProduct") | +| `index` | out | `index**` | hnsw index | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/hnsw.hpp:1180`_ + +### cuvs::neighbors::hnsw::deserialize + +De-serialize a CAGRA index saved to a file as an hnswlib index + +```cpp +void deserialize(raft::resources const& res, +const index_params& params, +const std::string& filename, +int dim, +cuvs::distance::DistanceType metric, +index** index); +``` + +NOTE: When hierarchy is `NONE`, the saved hnswlib index is immutable and can only be read by the hnswlib wrapper in cuVS, as the serialization format is not compatible with the original hnswlib. However, when hierarchy is `CPU`, the saved hnswlib index is compatible with the original hnswlib library. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resources | +| `params` | in | `const index_params&` | hnsw index parameters | +| `filename` | in | `const std::string&` | path to the file containing the serialized CAGRA index | +| `dim` | in | `int` | dimensions of the training dataset | +| `metric` | in | `cuvs::distance::DistanceType` | distance metric to search. Supported metrics ("L2Expanded", "InnerProduct") | +| `index` | out | `index**` | hnsw index | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/hnsw.hpp:1223`_ diff --git a/fern/pages/cpp_api/cpp-api-neighbors-ivf-flat.md b/fern/pages/cpp_api/cpp-api-neighbors-ivf-flat.md new file mode 100644 index 0000000000..49e49528f7 --- /dev/null +++ b/fern/pages/cpp_api/cpp-api-neighbors-ivf-flat.md @@ -0,0 +1,2337 @@ +--- +slug: api-reference/cpp-api-neighbors-ivf-flat +--- + +# IVF Flat + +_Source header: `cpp/include/cuvs/neighbors/ivf_flat.hpp`_ + +## IVF-Flat index search parameters + +_Doxygen group: `ivf_flat_cpp_search_params`_ + +### cuvs::neighbors::ivf_flat::search_params + +IVF-Flat index search parameters + +```cpp +struct search_params : cuvs::neighbors::search_params { ... } ; +``` + +**Fields** + +| Name | Type | Description | +| --- | --- | --- | +| `n_probes` | `uint32_t` | The number of clusters to search. | +| `metric_udf` | `std::optional` | Custom metric UDF code. | + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:73`_ + +### cuvs::neighbors::ivf_flat::make_list_extents + +Determine the extents of an array enough to hold a given amount of data. + +```cpp +constexpr auto make_list_extents(SizeT n_rows) const -> list_extents; +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `n_rows` | | `SizeT` | | + +**Returns** + +`list_extents` + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:108`_ + +## IVF-Flat index + +_Doxygen group: `ivf_flat_cpp_index`_ + +### cuvs::neighbors::ivf_flat::index + +Construct an empty index. + +```cpp +index(raft::resources const& res); +``` + +Constructs an empty index. This index will either need to be trained with `build` or loaded from a saved copy with `deserialize` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | | `raft::resources const&` | | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:154`_ + +### cuvs::neighbors::ivf_flat::index + +Construct an empty index. It needs to be trained and then populated. + +```cpp +index(raft::resources const& res, const index_params& params, uint32_t dim); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | | `raft::resources const&` | | +| `params` | | `const index_params&` | | +| `dim` | | `uint32_t` | | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:157`_ + +### cuvs::neighbors::ivf_flat::index + +Construct an empty index. It needs to be trained and then populated. + +```cpp +index(raft::resources const& res, +cuvs::distance::DistanceType metric, +uint32_t n_lists, +bool adaptive_centers, +bool conservative_memory_allocation, +uint32_t dim); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | | `raft::resources const&` | | +| `metric` | | `cuvs::distance::DistanceType` | | +| `n_lists` | | `uint32_t` | | +| `adaptive_centers` | | `bool` | | +| `conservative_memory_allocation` | | `bool` | | +| `dim` | | `uint32_t` | | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:159`_ + +### cuvs::neighbors::ivf_flat::veclen + +Vectorized load/store size in elements, determines the size of interleaved data chunks. + +```cpp +uint32_t veclen() const noexcept; +``` + +**Returns** + +`uint32_t` + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:169`_ + +### cuvs::neighbors::ivf_flat::metric + +Distance metric used for clustering. + +```cpp +cuvs::distance::DistanceType metric() const noexcept; +``` + +**Returns** + +`cuvs::distance::DistanceType` + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:172`_ + +### cuvs::neighbors::ivf_flat::adaptive_centers + +Whether `centers()` change upon extending the index (ivf_flat::extend). + +```cpp +bool adaptive_centers() const noexcept; +``` + +**Returns** + +`bool` + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:175`_ + +### cuvs::neighbors::ivf_flat::list_sizes + +Sizes of the lists (clusters) [n_lists] + +```cpp +raft::device_vector_view list_sizes() noexcept; +``` + +NB: This may differ from the actual list size if the shared lists have been extended by another index + +**Returns** + +`raft::device_vector_view` + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:204`_ + +### cuvs::neighbors::ivf_flat::centers + +k-means cluster centers corresponding to the lists [n_lists, dim] + +```cpp +raft::device_matrix_view centers() noexcept; +``` + +**Returns** + +`raft::device_matrix_view` + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:208`_ + +### cuvs::neighbors::ivf_flat::center_norms + +(Optional) Precomputed norms of the `centers` w.r.t. the chosen distance metric [n_lists]. + +```cpp +std::optional> center_norms() noexcept; +``` + +NB: this may be empty if the index is empty or if the metric does not require the center norms calculation. + +**Returns** + +`std::optional>` + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:217`_ + +### cuvs::neighbors::ivf_flat::accum_sorted_sizes + +Accumulated list sizes, sorted in descending order [n_lists + 1]. + +```cpp +auto accum_sorted_sizes() noexcept -> raft::host_vector_view; +``` + +The last value contains the total length of the index. The value at index zero is always zero. That is, the content of this span is as if the `list_sizes` was sorted and then accumulated. This span is used during search to estimate the maximum size of the workspace. + +**Returns** + +`raft::host_vector_view` + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:229`_ + +### cuvs::neighbors::ivf_flat::size + +Total length of the index. + +```cpp +IdxT size() const noexcept; +``` + +**Returns** + +`IdxT` + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:234`_ + +### cuvs::neighbors::ivf_flat::dim + +Dimensionality of the data. + +```cpp +uint32_t dim() const noexcept; +``` + +**Returns** + +`uint32_t` + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:237`_ + +### cuvs::neighbors::ivf_flat::n_lists + +Number of clusters/inverted lists. + +```cpp +uint32_t n_lists() const noexcept; +``` + +**Returns** + +`uint32_t` + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:240`_ + +### cuvs::neighbors::ivf_flat::inds_ptrs + +Pointers to the inverted lists (clusters) indices [n_lists]. + +```cpp +raft::device_vector_view inds_ptrs() noexcept; +``` + +**Returns** + +`raft::device_vector_view` + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:245`_ + +### cuvs::neighbors::ivf_flat::conservative_memory_allocation + +Whether to use conservative memory allocation when extending the list (cluster) data + +```cpp +bool conservative_memory_allocation() const noexcept; +``` + +(see index_params.conservative_memory_allocation). + +**Returns** + +`bool` + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:252`_ + +### cuvs::neighbors::ivf_flat::lists + +Lists' data and indices. + +```cpp +std::vector>>& lists() noexcept; +``` + +**Returns** + +`std::vector>>&` + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:257`_ + +## IVF-Flat index build + +_Doxygen group: `ivf_flat_cpp_index_build`_ + +### cuvs::neighbors::ivf_flat::build + +Build the index from the dataset for efficient search. + +```cpp +auto build(raft::resources const& handle, +const cuvs::neighbors::ivf_flat::index_params& index_params, +raft::device_matrix_view dataset) +-> cuvs::neighbors::ivf_flat::index; +``` + +NB: Currently, the following distance metrics are supported: - L2Expanded - L2Unexpanded - InnerProduct - CosineExpanded Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | | +| `index_params` | in | `const cuvs::neighbors::ivf_flat::index_params&` | configure the index building | +| `dataset` | in | `raft::device_matrix_view` | a device pointer to a row-major matrix [n_rows, dim] | + +**Returns** + +`cuvs::neighbors::ivf_flat::index` + +the constructed ivf-flat index + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:325`_ + +### cuvs::neighbors::ivf_flat::build + +Build the index from the dataset for efficient search. + +```cpp +void build(raft::resources const& handle, +const cuvs::neighbors::ivf_flat::index_params& index_params, +raft::device_matrix_view dataset, +cuvs::neighbors::ivf_flat::index& idx); +``` + +NB: Currently, the following distance metrics are supported: - L2Expanded - L2Unexpanded - InnerProduct - CosineExpanded Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | | +| `index_params` | in | `const cuvs::neighbors::ivf_flat::index_params&` | configure the index building | +| `dataset` | in | `raft::device_matrix_view` | raft::device_matrix_view to a row-major matrix [n_rows, dim] | +| `idx` | out | `cuvs::neighbors::ivf_flat::index&` | reference to ivf_flat::index | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:355`_ + +### cuvs::neighbors::ivf_flat::build + +Build the index from the dataset for efficient search. + +```cpp +auto build(raft::resources const& handle, +const cuvs::neighbors::ivf_flat::index_params& index_params, +raft::device_matrix_view dataset) +-> cuvs::neighbors::ivf_flat::index; +``` + +NB: Currently, the following distance metrics are supported: - L2Expanded - L2Unexpanded - InnerProduct - CosineExpanded Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | | +| `index_params` | in | `const cuvs::neighbors::ivf_flat::index_params&` | configure the index building | +| `dataset` | in | `raft::device_matrix_view` | a device pointer to a row-major matrix [n_rows, dim] | + +**Returns** + +`cuvs::neighbors::ivf_flat::index` + +the constructed ivf-flat index + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:384`_ + +### cuvs::neighbors::ivf_flat::build + +Build the index from the dataset for efficient search. + +```cpp +void build(raft::resources const& handle, +const cuvs::neighbors::ivf_flat::index_params& index_params, +raft::device_matrix_view dataset, +cuvs::neighbors::ivf_flat::index& idx); +``` + +NB: Currently, the following distance metrics are supported: - L2Expanded - L2Unexpanded - InnerProduct - CosineExpanded Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | | +| `index_params` | in | `const cuvs::neighbors::ivf_flat::index_params&` | configure the index building | +| `dataset` | in | `raft::device_matrix_view` | raft::device_matrix_view to a row-major matrix [n_rows, dim] | +| `idx` | out | `cuvs::neighbors::ivf_flat::index&` | reference to ivf_flat::index | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:414`_ + +### cuvs::neighbors::ivf_flat::build + +Build the index from the dataset for efficient search. + +```cpp +auto build(raft::resources const& handle, +const cuvs::neighbors::ivf_flat::index_params& index_params, +raft::device_matrix_view dataset) +-> cuvs::neighbors::ivf_flat::index; +``` + +NB: Currently, the following distance metrics are supported: - L2Expanded - L2Unexpanded - InnerProduct - CosineExpanded Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | | +| `index_params` | in | `const cuvs::neighbors::ivf_flat::index_params&` | configure the index building | +| `dataset` | in | `raft::device_matrix_view` | a device pointer to a row-major matrix [n_rows, dim] | + +**Returns** + +`cuvs::neighbors::ivf_flat::index` + +the constructed ivf-flat index + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:443`_ + +### cuvs::neighbors::ivf_flat::build + +Build the index from the dataset for efficient search. + +```cpp +void build(raft::resources const& handle, +const cuvs::neighbors::ivf_flat::index_params& index_params, +raft::device_matrix_view dataset, +cuvs::neighbors::ivf_flat::index& idx); +``` + +NB: Currently, the following distance metrics are supported: - L2Expanded - L2Unexpanded - InnerProduct - CosineExpanded Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | | +| `index_params` | in | `const cuvs::neighbors::ivf_flat::index_params&` | configure the index building | +| `dataset` | in | `raft::device_matrix_view` | raft::device_matrix_view to a row-major matrix [n_rows, dim] | +| `idx` | out | `cuvs::neighbors::ivf_flat::index&` | reference to ivf_flat::index | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:473`_ + +### cuvs::neighbors::ivf_flat::build + +Build the index from the dataset for efficient search. + +```cpp +auto build(raft::resources const& handle, +const cuvs::neighbors::ivf_flat::index_params& index_params, +raft::device_matrix_view dataset) +-> cuvs::neighbors::ivf_flat::index; +``` + +NB: Currently, the following distance metrics are supported: - L2Expanded - L2Unexpanded - InnerProduct - CosineExpanded Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | | +| `index_params` | in | `const cuvs::neighbors::ivf_flat::index_params&` | configure the index building | +| `dataset` | in | `raft::device_matrix_view` | a device pointer to a row-major matrix [n_rows, dim] | + +**Returns** + +`cuvs::neighbors::ivf_flat::index` + +the constructed ivf-flat index + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:502`_ + +### cuvs::neighbors::ivf_flat::build + +Build the index from the dataset for efficient search. + +```cpp +void build(raft::resources const& handle, +const cuvs::neighbors::ivf_flat::index_params& index_params, +raft::device_matrix_view dataset, +cuvs::neighbors::ivf_flat::index& idx); +``` + +NB: Currently, the following distance metrics are supported: - L2Expanded - L2Unexpanded - InnerProduct - CosineExpanded Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | | +| `index_params` | in | `const cuvs::neighbors::ivf_flat::index_params&` | configure the index building | +| `dataset` | in | `raft::device_matrix_view` | raft::device_matrix_view to a row-major matrix [n_rows, dim] | +| `idx` | out | `cuvs::neighbors::ivf_flat::index&` | reference to ivf_flat::index | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:532`_ + +### cuvs::neighbors::ivf_flat::build + +Build the index from the dataset for efficient search. + +```cpp +auto build(raft::resources const& handle, +const cuvs::neighbors::ivf_flat::index_params& index_params, +raft::host_matrix_view dataset) +-> cuvs::neighbors::ivf_flat::index; +``` + +NB: Currently, the following distance metrics are supported: - L2Expanded - L2Unexpanded - InnerProduct - CosineExpanded Note, if index_params.add_data_on_build is set to true, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | | +| `index_params` | in | `const cuvs::neighbors::ivf_flat::index_params&` | configure the index building | +| `dataset` | in | `raft::host_matrix_view` | raft::host_matrix_view to a row-major matrix [n_rows, dim] | + +**Returns** + +`cuvs::neighbors::ivf_flat::index` + +the constructed ivf-flat index + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:568`_ + +### cuvs::neighbors::ivf_flat::build + +Build the index from the dataset for efficient search. + +```cpp +void build(raft::resources const& handle, +const cuvs::neighbors::ivf_flat::index_params& index_params, +raft::host_matrix_view dataset, +cuvs::neighbors::ivf_flat::index& idx); +``` + +NB: Currently, the following distance metrics are supported: - L2Expanded - L2Unexpanded - InnerProduct - CosineExpanded Note, if index_params.add_data_on_build is set to true, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | | +| `index_params` | in | `const cuvs::neighbors::ivf_flat::index_params&` | configure the index building | +| `dataset` | in | `raft::host_matrix_view` | raft::host_matrix_view to a row-major matrix [n_rows, dim] | +| `idx` | out | `cuvs::neighbors::ivf_flat::index&` | reference to ivf_flat::index | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:605`_ + +### cuvs::neighbors::ivf_flat::build + +Build the index from the dataset for efficient search. + +```cpp +auto build(raft::resources const& handle, +const cuvs::neighbors::ivf_flat::index_params& index_params, +raft::host_matrix_view dataset) +-> cuvs::neighbors::ivf_flat::index; +``` + +NB: Currently, the following distance metrics are supported: - L2Expanded - L2Unexpanded - InnerProduct - CosineExpanded Note, if index_params.add_data_on_build is set to true, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | | +| `index_params` | in | `const cuvs::neighbors::ivf_flat::index_params&` | configure the index building | +| `dataset` | in | `raft::host_matrix_view` | raft::host_matrix_view to a row-major matrix [n_rows, dim] | + +**Returns** + +`cuvs::neighbors::ivf_flat::index` + +the constructed ivf-flat index + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:641`_ + +### cuvs::neighbors::ivf_flat::build + +Build the index from the dataset for efficient search. + +```cpp +void build(raft::resources const& handle, +const cuvs::neighbors::ivf_flat::index_params& index_params, +raft::host_matrix_view dataset, +cuvs::neighbors::ivf_flat::index& idx); +``` + +NB: Currently, the following distance metrics are supported: - L2Expanded - L2Unexpanded - InnerProduct - CosineExpanded Note, if index_params.add_data_on_build is set to true, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | | +| `index_params` | in | `const cuvs::neighbors::ivf_flat::index_params&` | configure the index building | +| `dataset` | in | `raft::host_matrix_view` | raft::host_matrix_view to a row-major matrix [n_rows, dim] | +| `idx` | out | `cuvs::neighbors::ivf_flat::index&` | reference to ivf_flat::index | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:678`_ + +### cuvs::neighbors::ivf_flat::build + +Build the index from the dataset for efficient search. + +```cpp +auto build(raft::resources const& handle, +const cuvs::neighbors::ivf_flat::index_params& index_params, +raft::host_matrix_view dataset) +-> cuvs::neighbors::ivf_flat::index; +``` + +NB: Currently, the following distance metrics are supported: - L2Expanded - L2Unexpanded - InnerProduct - CosineExpanded Note, if index_params.add_data_on_build is set to true, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | | +| `index_params` | in | `const cuvs::neighbors::ivf_flat::index_params&` | configure the index building | +| `dataset` | in | `raft::host_matrix_view` | a host pointer to a row-major matrix [n_rows, dim] | + +**Returns** + +`cuvs::neighbors::ivf_flat::index` + +the constructed ivf-flat index + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:714`_ + +### cuvs::neighbors::ivf_flat::build + +Build the index from the dataset for efficient search. + +```cpp +void build(raft::resources const& handle, +const cuvs::neighbors::ivf_flat::index_params& index_params, +raft::host_matrix_view dataset, +cuvs::neighbors::ivf_flat::index& idx); +``` + +NB: Currently, the following distance metrics are supported: - L2Expanded - L2Unexpanded - InnerProduct - CosineExpanded Note, if index_params.add_data_on_build is set to true, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | | +| `index_params` | in | `const cuvs::neighbors::ivf_flat::index_params&` | configure the index building | +| `dataset` | in | `raft::host_matrix_view` | raft::host_matrix_view to a row-major matrix [n_rows, dim] | +| `idx` | out | `cuvs::neighbors::ivf_flat::index&` | reference to ivf_flat::index | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:751`_ + +### cuvs::neighbors::ivf_flat::build + +Build the index from the dataset for efficient search. + +```cpp +auto build(raft::resources const& handle, +const cuvs::neighbors::ivf_flat::index_params& index_params, +raft::host_matrix_view dataset) +-> cuvs::neighbors::ivf_flat::index; +``` + +NB: Currently, the following distance metrics are supported: - L2Expanded - L2Unexpanded - InnerProduct - CosineExpanded Note, if index_params.add_data_on_build is set to true, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | | +| `index_params` | in | `const cuvs::neighbors::ivf_flat::index_params&` | configure the index building | +| `dataset` | in | `raft::host_matrix_view` | a host pointer to a row-major matrix [n_rows, dim] | + +**Returns** + +`cuvs::neighbors::ivf_flat::index` + +the constructed ivf-flat index + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:787`_ + +### cuvs::neighbors::ivf_flat::build + +Build the index from the dataset for efficient search. + +```cpp +void build(raft::resources const& handle, +const cuvs::neighbors::ivf_flat::index_params& index_params, +raft::host_matrix_view dataset, +cuvs::neighbors::ivf_flat::index& idx); +``` + +NB: Currently, the following distance metrics are supported: - L2Expanded - L2Unexpanded - InnerProduct - CosineExpanded Note, if index_params.add_data_on_build is set to true, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | | +| `index_params` | in | `const cuvs::neighbors::ivf_flat::index_params&` | configure the index building | +| `dataset` | in | `raft::host_matrix_view` | raft::host_matrix_view to a row-major matrix [n_rows, dim] | +| `idx` | out | `cuvs::neighbors::ivf_flat::index&` | reference to ivf_flat::index | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:824`_ + +## IVF-Flat index extend + +_Doxygen group: `ivf_flat_cpp_index_extend`_ + +### cuvs::neighbors::ivf_flat::extend + +Build a new index containing the data of the original plus new extra vectors. + +```cpp +auto extend(raft::resources const& handle, +raft::device_matrix_view new_vectors, +std::optional> new_indices, +const cuvs::neighbors::ivf_flat::index& idx) +-> cuvs::neighbors::ivf_flat::index; +``` + +Implementation note: The new data is clustered according to existing kmeans clusters, then the cluster centers are adjusted to match the newly labeled data. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | | +| `new_vectors` | in | `raft::device_matrix_view` | raft::device_matrix_view to a row-major matrix [n_rows, index.dim()] | +| `new_indices` | in | `std::optional>` | optional raft::device_vector_view to a vector of indices [n_rows]. If the original index is empty (`orig_index.size() == 0`), you can pass `std::nullopt` here to imply a continuous range `[0...n_rows)`. | +| `idx` | in | `const cuvs::neighbors::ivf_flat::index&` | original index | + +**Returns** + +`cuvs::neighbors::ivf_flat::index` + +the constructed extended ivf-flat index + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:866`_ + +### cuvs::neighbors::ivf_flat::extend + +Extend the index in-place with the new data. + +```cpp +void extend(raft::resources const& handle, +raft::device_matrix_view new_vectors, +std::optional> new_indices, +cuvs::neighbors::ivf_flat::index* idx); +``` + +Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | | +| `new_vectors` | in | `raft::device_matrix_view` | raft::device_matrix_view to a row-major matrix [n_rows, index.dim()] | +| `new_indices` | in | `std::optional>` | optional raft::device_vector_view to a vector of indices [n_rows]. If the original index is empty (`orig_index.size() == 0`), you can pass `std::nullopt` here to imply a continuous range `[0...n_rows)`. | +| `idx` | inout | `cuvs::neighbors::ivf_flat::index*` | pointer to index, to be overwritten in-place | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:896`_ + +### cuvs::neighbors::ivf_flat::extend + +Build a new index containing the data of the original plus new extra vectors. + +```cpp +auto extend(raft::resources const& handle, +raft::device_matrix_view new_vectors, +std::optional> new_indices, +const cuvs::neighbors::ivf_flat::index& idx) +-> cuvs::neighbors::ivf_flat::index; +``` + +Implementation note: The new data is clustered according to existing kmeans clusters, then the cluster centers are adjusted to match the newly labeled data. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | | +| `new_vectors` | in | `raft::device_matrix_view` | raft::device_matrix_view to a row-major matrix [n_rows, index.dim()] | +| `new_indices` | in | `std::optional>` | optional raft::device_vector_view to a vector of indices [n_rows]. If the original index is empty (`orig_index.size() == 0`), you can pass `std::nullopt` here to imply a continuous range `[0...n_rows)`. | +| `idx` | in | `const cuvs::neighbors::ivf_flat::index&` | original index | + +**Returns** + +`cuvs::neighbors::ivf_flat::index` + +the constructed extended ivf-flat index + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:930`_ + +### cuvs::neighbors::ivf_flat::extend + +Extend the index in-place with the new data. + +```cpp +void extend(raft::resources const& handle, +raft::device_matrix_view new_vectors, +std::optional> new_indices, +cuvs::neighbors::ivf_flat::index* idx); +``` + +Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | | +| `new_vectors` | in | `raft::device_matrix_view` | raft::device_matrix_view to a row-major matrix [n_rows, index.dim()] | +| `new_indices` | in | `std::optional>` | optional raft::device_vector_view to a vector of indices [n_rows]. If the original index is empty (`orig_index.size() == 0`), you can pass `std::nullopt` here to imply a continuous range `[0...n_rows)`. | +| `idx` | inout | `cuvs::neighbors::ivf_flat::index*` | pointer to index, to be overwritten in-place | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:960`_ + +### cuvs::neighbors::ivf_flat::extend + +Build a new index containing the data of the original plus new extra vectors. + +```cpp +auto extend(raft::resources const& handle, +raft::device_matrix_view new_vectors, +std::optional> new_indices, +const cuvs::neighbors::ivf_flat::index& idx) +-> cuvs::neighbors::ivf_flat::index; +``` + +Implementation note: The new data is clustered according to existing kmeans clusters, then the cluster centers are adjusted to match the newly labeled data. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | | +| `new_vectors` | in | `raft::device_matrix_view` | raft::device_matrix_view to a row-major matrix [n_rows, index.dim()] | +| `new_indices` | in | `std::optional>` | optional raft::device_vector_view to a vector of indices [n_rows]. If the original index is empty (`orig_index.size() == 0`), you can pass `std::nullopt` here to imply a continuous range `[0...n_rows)`. | +| `idx` | in | `const cuvs::neighbors::ivf_flat::index&` | original index | + +**Returns** + +`cuvs::neighbors::ivf_flat::index` + +the constructed extended ivf-flat index + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:994`_ + +### cuvs::neighbors::ivf_flat::extend + +Extend the index in-place with the new data. + +```cpp +void extend(raft::resources const& handle, +raft::device_matrix_view new_vectors, +std::optional> new_indices, +cuvs::neighbors::ivf_flat::index* idx); +``` + +Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | | +| `new_vectors` | in | `raft::device_matrix_view` | raft::device_matrix_view to a row-major matrix [n_rows, index.dim()] | +| `new_indices` | in | `std::optional>` | optional raft::device_vector_view to a vector of indices [n_rows]. If the original index is empty (`orig_index.size() == 0`), you can pass `std::nullopt` here to imply a continuous range `[0...n_rows)`. | +| `idx` | inout | `cuvs::neighbors::ivf_flat::index*` | pointer to index, to be overwritten in-place | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:1025`_ + +### cuvs::neighbors::ivf_flat::extend + +Build a new index containing the data of the original plus new extra vectors. + +```cpp +auto extend(raft::resources const& handle, +raft::device_matrix_view new_vectors, +std::optional> new_indices, +const cuvs::neighbors::ivf_flat::index& idx) +-> cuvs::neighbors::ivf_flat::index; +``` + +Implementation note: The new data is clustered according to existing kmeans clusters, then the cluster centers are adjusted to match the newly labeled data. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | | +| `new_vectors` | in | `raft::device_matrix_view` | raft::device_matrix_view to a row-major matrix [n_rows, index.dim()] | +| `new_indices` | in | `std::optional>` | optional raft::device_vector_view to a vector of indices [n_rows]. If the original index is empty (`orig_index.size() == 0`), you can pass `std::nullopt` here to imply a continuous range `[0...n_rows)`. | +| `idx` | in | `const cuvs::neighbors::ivf_flat::index&` | original index | + +**Returns** + +`cuvs::neighbors::ivf_flat::index` + +the constructed extended ivf-flat index + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:1059`_ + +### cuvs::neighbors::ivf_flat::extend + +Extend the index in-place with the new data. + +```cpp +void extend(raft::resources const& handle, +raft::device_matrix_view new_vectors, +std::optional> new_indices, +cuvs::neighbors::ivf_flat::index* idx); +``` + +Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | | +| `new_vectors` | in | `raft::device_matrix_view` | raft::device_matrix_view to a row-major matrix [n_rows, index.dim()] | +| `new_indices` | in | `std::optional>` | optional raft::device_vector_view to a vector of indices [n_rows]. If the original index is empty (`orig_index.size() == 0`), you can pass `std::nullopt` here to imply a continuous range `[0...n_rows)`. | +| `idx` | inout | `cuvs::neighbors::ivf_flat::index*` | pointer to index, to be overwritten in-place | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:1089`_ + +### cuvs::neighbors::ivf_flat::extend + +Build a new index containing the data of the original plus new extra vectors. + +```cpp +auto extend(raft::resources const& handle, +raft::host_matrix_view new_vectors, +std::optional> new_indices, +const cuvs::neighbors::ivf_flat::index& idx) +-> cuvs::neighbors::ivf_flat::index; +``` + +Note, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. Implementation note: The new data is clustered according to existing kmeans clusters, then the cluster centers are adjusted to match the newly labeled data. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | | +| `new_vectors` | in | `raft::host_matrix_view` | raft::host_matrix_view to a row-major matrix [n_rows, index.dim()] | +| `new_indices` | in | `std::optional>` | optional raft::host_vector_view to a vector of indices [n_rows]. If the original index is empty (`orig_index.size() == 0`), you can pass `std::nullopt` here to imply a continuous range `[0...n_rows)`. | +| `idx` | in | `const cuvs::neighbors::ivf_flat::index&` | original index | + +**Returns** + +`cuvs::neighbors::ivf_flat::index` + +the constructed extended ivf-flat index + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:1129`_ + +### cuvs::neighbors::ivf_flat::extend + +Extend the index in-place with the new data. + +```cpp +void extend(raft::resources const& handle, +raft::host_matrix_view new_vectors, +std::optional> new_indices, +cuvs::neighbors::ivf_flat::index* idx); +``` + +Note, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | | +| `new_vectors` | in | `raft::host_matrix_view` | raft::host_matrix_view to a row-major matrix [n_rows, index.dim()] | +| `new_indices` | in | `std::optional>` | optional raft::host_vector_view to a vector of indices [n_rows]. If the original index is empty (`orig_index.size() == 0`), you can pass `std::nullopt` here to imply a continuous range `[0...n_rows)`. | +| `idx` | inout | `cuvs::neighbors::ivf_flat::index*` | pointer to index, to be overwritten in-place | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:1165`_ + +### cuvs::neighbors::ivf_flat::extend + +Build a new index containing the data of the original plus new extra vectors. + +```cpp +auto extend(raft::resources const& handle, +raft::host_matrix_view new_vectors, +std::optional> new_indices, +const cuvs::neighbors::ivf_flat::index& idx) +-> cuvs::neighbors::ivf_flat::index; +``` + +Note, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. Implementation note: The new data is clustered according to existing kmeans clusters, then the cluster centers are adjusted to match the newly labeled data. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | | +| `new_vectors` | in | `raft::host_matrix_view` | raft::host_matrix_view to a row-major matrix [n_rows, index.dim()] | +| `new_indices` | in | `std::optional>` | optional raft::host_vector_view to a vector of indices [n_rows]. If the original index is empty (`orig_index.size() == 0`), you can pass `std::nullopt` here to imply a continuous range `[0...n_rows)`. | +| `idx` | in | `const cuvs::neighbors::ivf_flat::index&` | original index | + +**Returns** + +`cuvs::neighbors::ivf_flat::index` + +the constructed extended ivf-flat index + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:1205`_ + +### cuvs::neighbors::ivf_flat::extend + +Extend the index in-place with the new data. + +```cpp +void extend(raft::resources const& handle, +raft::host_matrix_view new_vectors, +std::optional> new_indices, +cuvs::neighbors::ivf_flat::index* idx); +``` + +Note, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | | +| `new_vectors` | in | `raft::host_matrix_view` | raft::host_matrix_view to a row-major matrix [n_rows, index.dim()] | +| `new_indices` | in | `std::optional>` | optional raft::host_vector_view to a vector of indices [n_rows]. If the original index is empty (`orig_index.size() == 0`), you can pass `std::nullopt` here to imply a continuous range `[0...n_rows)`. | +| `idx` | inout | `cuvs::neighbors::ivf_flat::index*` | pointer to index, to be overwritten in-place | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:1241`_ + +### cuvs::neighbors::ivf_flat::extend + +Build a new index containing the data of the original plus new extra vectors. + +```cpp +auto extend(raft::resources const& handle, +raft::host_matrix_view new_vectors, +std::optional> new_indices, +const cuvs::neighbors::ivf_flat::index& idx) +-> cuvs::neighbors::ivf_flat::index; +``` + +Note, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. Implementation note: The new data is clustered according to existing kmeans clusters, then the cluster centers are adjusted to match the newly labeled data. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | | +| `new_vectors` | in | `raft::host_matrix_view` | raft::host_matrix_view to a row-major matrix [n_rows, index.dim()] | +| `new_indices` | in | `std::optional>` | optional raft::host_vector_view to a vector of indices [n_rows]. If the original index is empty (`orig_index.size() == 0`), you can pass `std::nullopt` here to imply a continuous range `[0...n_rows)`. | +| `idx` | in | `const cuvs::neighbors::ivf_flat::index&` | original index | + +**Returns** + +`cuvs::neighbors::ivf_flat::index` + +the constructed extended ivf-flat index + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:1281`_ + +### cuvs::neighbors::ivf_flat::extend + +Extend the index in-place with the new data. + +```cpp +void extend(raft::resources const& handle, +raft::host_matrix_view new_vectors, +std::optional> new_indices, +cuvs::neighbors::ivf_flat::index* idx); +``` + +Note, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | | +| `new_vectors` | in | `raft::host_matrix_view` | raft::host_matrix_view to a row-major matrix [n_rows, index.dim()] | +| `new_indices` | in | `std::optional>` | optional raft::host_vector_view to a vector of indices [n_rows]. If the original index is empty (`orig_index.size() == 0`), you can pass `std::nullopt` here to imply a continuous range `[0...n_rows)`. | +| `idx` | inout | `cuvs::neighbors::ivf_flat::index*` | pointer to index, to be overwritten in-place | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:1317`_ + +### cuvs::neighbors::ivf_flat::extend + +Build a new index containing the data of the original plus new extra vectors. + +```cpp +auto extend(raft::resources const& handle, +raft::host_matrix_view new_vectors, +std::optional> new_indices, +const cuvs::neighbors::ivf_flat::index& idx) +-> cuvs::neighbors::ivf_flat::index; +``` + +Note, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. Implementation note: The new data is clustered according to existing kmeans clusters, then the cluster centers are adjusted to match the newly labeled data. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | | +| `new_vectors` | in | `raft::host_matrix_view` | raft::host_matrix_view to a row-major matrix [n_rows, index.dim()] | +| `new_indices` | in | `std::optional>` | optional raft::host_vector_view to a vector of indices [n_rows]. If the original index is empty (`orig_index.size() == 0`), you can pass `std::nullopt` here to imply a continuous range `[0...n_rows)`. | +| `idx` | in | `const cuvs::neighbors::ivf_flat::index&` | original index | + +**Returns** + +`cuvs::neighbors::ivf_flat::index` + +the constructed extended ivf-flat index + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:1357`_ + +### cuvs::neighbors::ivf_flat::extend + +Extend the index in-place with the new data. + +```cpp +void extend(raft::resources const& handle, +raft::host_matrix_view new_vectors, +std::optional> new_indices, +cuvs::neighbors::ivf_flat::index* idx); +``` + +Note, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | | +| `new_vectors` | in | `raft::host_matrix_view` | raft::host_matrix_view to a row-major matrix [n_rows, index.dim()] | +| `new_indices` | in | `std::optional>` | optional raft::host_vector_view to a vector of indices [n_rows]. If the original index is empty (`orig_index.size() == 0`), you can pass `std::nullopt` here to imply a continuous range `[0...n_rows)`. | +| `idx` | inout | `cuvs::neighbors::ivf_flat::index*` | pointer to index, to be overwritten in-place | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:1393`_ + +## IVF-Flat index serialize + +_Doxygen group: `ivf_flat_cpp_serialize`_ + +### cuvs::neighbors::ivf_flat::serialize + +Save the index to file. + +```cpp +void serialize(raft::resources const& handle, +const std::string& filename, +const cuvs::neighbors::ivf_flat::index& index); +``` + +Experimental, both the API and the serialization format are subject to change. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | the raft handle | +| `filename` | in | `const std::string&` | the file name for saving the index | +| `index` | in | `const cuvs::neighbors::ivf_flat::index&` | IVF-Flat index | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:1612`_ + +### cuvs::neighbors::ivf_flat::deserialize + +Load index from file. + +```cpp +void deserialize(raft::resources const& handle, +const std::string& filename, +cuvs::neighbors::ivf_flat::index* index); +``` + +Experimental, both the API and the serialization format are subject to change. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | the raft handle | +| `filename` | in | `const std::string&` | the name of the file that stores the index | +| `index` | in | `cuvs::neighbors::ivf_flat::index*` | IVF-Flat index | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:1640`_ + +### cuvs::neighbors::ivf_flat::serialize + +Write the index to an output stream + +```cpp +void serialize(raft::resources const& handle, +std::ostream& os, +const cuvs::neighbors::ivf_flat::index& index); +``` + +Experimental, both the API and the serialization format are subject to change. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | the raft handle | +| `os` | in | `std::ostream&` | output stream | +| `index` | in | `const cuvs::neighbors::ivf_flat::index&` | IVF-Flat index | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:1666`_ + +### cuvs::neighbors::ivf_flat::deserialize + +Load index from input stream + +```cpp +void deserialize(raft::resources const& handle, +std::istream& is, +cuvs::neighbors::ivf_flat::index* index); +``` + +Experimental, both the API and the serialization format are subject to change. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | the raft handle | +| `is` | in | `std::istream&` | input stream | +| `index` | in | `cuvs::neighbors::ivf_flat::index*` | IVF-Flat index | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:1694`_ + +### cuvs::neighbors::ivf_flat::serialize + +Save the index to file. + +```cpp +void serialize(raft::resources const& handle, +const std::string& filename, +const cuvs::neighbors::ivf_flat::index& index); +``` + +Experimental, both the API and the serialization format are subject to change. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | the raft handle | +| `filename` | in | `const std::string&` | the file name for saving the index | +| `index` | in | `const cuvs::neighbors::ivf_flat::index&` | IVF-Flat index | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:1720`_ + +### cuvs::neighbors::ivf_flat::deserialize + +Load index from file. + +```cpp +void deserialize(raft::resources const& handle, +const std::string& filename, +cuvs::neighbors::ivf_flat::index* index); +``` + +Experimental, both the API and the serialization format are subject to change. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | the raft handle | +| `filename` | in | `const std::string&` | the name of the file that stores the index | +| `index` | in | `cuvs::neighbors::ivf_flat::index*` | IVF-Flat index | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:1748`_ + +### cuvs::neighbors::ivf_flat::serialize + +Write the index to an output stream + +```cpp +void serialize(raft::resources const& handle, +std::ostream& os, +const cuvs::neighbors::ivf_flat::index& index); +``` + +Experimental, both the API and the serialization format are subject to change. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | the raft handle | +| `os` | in | `std::ostream&` | output stream | +| `index` | in | `const cuvs::neighbors::ivf_flat::index&` | IVF-Flat index | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:1774`_ + +### cuvs::neighbors::ivf_flat::deserialize + +Load index from input stream + +```cpp +void deserialize(raft::resources const& handle, +std::istream& is, +cuvs::neighbors::ivf_flat::index* index); +``` + +Experimental, both the API and the serialization format are subject to change. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | the raft handle | +| `is` | in | `std::istream&` | input stream | +| `index` | in | `cuvs::neighbors::ivf_flat::index*` | IVF-Flat index | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:1802`_ + +### cuvs::neighbors::ivf_flat::serialize + +Save the index to file. + +```cpp +void serialize(raft::resources const& handle, +const std::string& filename, +const cuvs::neighbors::ivf_flat::index& index); +``` + +Experimental, both the API and the serialization format are subject to change. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | the raft handle | +| `filename` | in | `const std::string&` | the file name for saving the index | +| `index` | in | `const cuvs::neighbors::ivf_flat::index&` | IVF-Flat index | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:1828`_ + +### cuvs::neighbors::ivf_flat::deserialize + +Load index from file. + +```cpp +void deserialize(raft::resources const& handle, +const std::string& filename, +cuvs::neighbors::ivf_flat::index* index); +``` + +Experimental, both the API and the serialization format are subject to change. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | the raft handle | +| `filename` | in | `const std::string&` | the name of the file that stores the index | +| `index` | in | `cuvs::neighbors::ivf_flat::index*` | IVF-Flat index | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:1856`_ + +### cuvs::neighbors::ivf_flat::serialize + +Write the index to an output stream + +```cpp +void serialize(raft::resources const& handle, +std::ostream& os, +const cuvs::neighbors::ivf_flat::index& index); +``` + +Experimental, both the API and the serialization format are subject to change. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | the raft handle | +| `os` | in | `std::ostream&` | output stream | +| `index` | in | `const cuvs::neighbors::ivf_flat::index&` | IVF-Flat index | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:1882`_ + +### cuvs::neighbors::ivf_flat::deserialize + +Load index from input stream + +```cpp +void deserialize(raft::resources const& handle, +std::istream& is, +cuvs::neighbors::ivf_flat::index* index); +``` + +Experimental, both the API and the serialization format are subject to change. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | the raft handle | +| `is` | in | `std::istream&` | input stream | +| `index` | in | `cuvs::neighbors::ivf_flat::index*` | IVF-Flat index | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:1910`_ + +### cuvs::neighbors::ivf_flat::serialize + +Save the index to file. + +```cpp +void serialize(raft::resources const& handle, +const std::string& filename, +const cuvs::neighbors::ivf_flat::index& index); +``` + +Experimental, both the API and the serialization format are subject to change. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | the raft handle | +| `filename` | in | `const std::string&` | the file name for saving the index | +| `index` | in | `const cuvs::neighbors::ivf_flat::index&` | IVF-Flat index | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:1936`_ + +### cuvs::neighbors::ivf_flat::deserialize + +Load index from file. + +```cpp +void deserialize(raft::resources const& handle, +const std::string& filename, +cuvs::neighbors::ivf_flat::index* index); +``` + +Experimental, both the API and the serialization format are subject to change. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | the raft handle | +| `filename` | in | `const std::string&` | the name of the file that stores the index | +| `index` | in | `cuvs::neighbors::ivf_flat::index*` | IVF-Flat index | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:1964`_ + +### cuvs::neighbors::ivf_flat::serialize + +Write the index to an output stream + +```cpp +void serialize(raft::resources const& handle, +std::ostream& os, +const cuvs::neighbors::ivf_flat::index& index); +``` + +Experimental, both the API and the serialization format are subject to change. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | the raft handle | +| `os` | in | `std::ostream&` | output stream | +| `index` | in | `const cuvs::neighbors::ivf_flat::index&` | IVF-Flat index | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:1990`_ + +### cuvs::neighbors::ivf_flat::deserialize + +Load index from input stream + +```cpp +void deserialize(raft::resources const& handle, +std::istream& is, +cuvs::neighbors::ivf_flat::index* index); +``` + +Experimental, both the API and the serialization format are subject to change. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | the raft handle | +| `is` | in | `std::istream&` | input stream | +| `index` | in | `cuvs::neighbors::ivf_flat::index*` | IVF-Flat index | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:2018`_ + +## Helper functions for IVF Flat + +_Doxygen group: `ivf_flat_helpers`_ + +### namespace codepacker \{ + +Helper functions for IVF Flat + +```cpp +namespace codepacker { +``` + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:2484`_ + +### codepacker::pack + +Write flat codes into an existing list by the given offset. + +```cpp +void pack(raft::resources const& res, +raft::device_matrix_view codes, +uint32_t veclen, +uint32_t offset, +raft::device_mdspan::list_extents, +raft::row_major> list_data); +``` + +NB: no memory allocation happens here; the list must fit the data (offset + n_vec). Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | | +| `codes` | in | `raft::device_matrix_view` | flat codes [n_vec, dim] | +| `veclen` | in | `uint32_t` | size of interleaved data chunks | +| `offset` | in | `uint32_t` | how many records to skip before writing the data into the list | +| `list_data` | inout | `raft::device_mdspan::list_extents, raft::row_major>` | block to write into | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:2508`_ + +### codepacker::pack + +Write flat codes into an existing list by the given offset. + +```cpp +void pack(raft::resources const& res, +raft::device_matrix_view codes, +uint32_t veclen, +uint32_t offset, +raft::device_mdspan::list_extents, +raft::row_major> list_data); +``` + +NB: no memory allocation happens here; the list must fit the data (offset + n_vec). Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | | +| `codes` | in | `raft::device_matrix_view` | flat codes [n_vec, dim] | +| `veclen` | in | `uint32_t` | size of interleaved data chunks | +| `offset` | in | `uint32_t` | how many records to skip before writing the data into the list | +| `list_data` | inout | `raft::device_mdspan::list_extents, raft::row_major>` | block to write into | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:2538`_ + +### codepacker::pack + +Write flat codes into an existing list by the given offset. + +```cpp +void pack(raft::resources const& res, +raft::device_matrix_view codes, +uint32_t veclen, +uint32_t offset, +raft::device_mdspan::list_extents, +raft::row_major> list_data); +``` + +NB: no memory allocation happens here; the list must fit the data (offset + n_vec). Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | | +| `codes` | in | `raft::device_matrix_view` | flat codes [n_vec, dim] | +| `veclen` | in | `uint32_t` | size of interleaved data chunks | +| `offset` | in | `uint32_t` | how many records to skip before writing the data into the list | +| `list_data` | inout | `raft::device_mdspan::list_extents, raft::row_major>` | block to write into | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:2568`_ + +### codepacker::pack + +Write flat codes into an existing list by the given offset. + +```cpp +void pack(raft::resources const& res, +raft::device_matrix_view codes, +uint32_t veclen, +uint32_t offset, +raft::device_mdspan::list_extents, +raft::row_major> list_data); +``` + +NB: no memory allocation happens here; the list must fit the data (offset + n_vec). Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | | +| `codes` | in | `raft::device_matrix_view` | flat codes [n_vec, dim] | +| `veclen` | in | `uint32_t` | size of interleaved data chunks | +| `offset` | in | `uint32_t` | how many records to skip before writing the data into the list | +| `list_data` | inout | `raft::device_mdspan::list_extents, raft::row_major>` | block to write into | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:2598`_ + +### codepacker::unpack + +Unpack `n_take` consecutive records of a single list (cluster) in the compressed index + +```cpp +void unpack(raft::resources const& res, +raft::device_mdspan::list_extents, +raft::row_major> list_data, +uint32_t veclen, +uint32_t offset, +raft::device_matrix_view codes); +``` + +starting at given `offset`. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resource | +| `list_data` | in | `raft::device_mdspan::list_extents, raft::row_major>` | block to read from | +| `veclen` | in | `uint32_t` | size of interleaved data chunks | +| `offset` | in | `uint32_t` | How many records in the list to skip. | +| `codes` | inout | `raft::device_matrix_view` | the destination buffer [n_take, index.dim()]. The length `n_take` defines how many records to unpack, it must be <= the list size. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:2631`_ + +### codepacker::unpack + +Unpack `n_take` consecutive records of a single list (cluster) in the compressed index + +```cpp +void unpack(raft::resources const& res, +raft::device_mdspan::list_extents, +raft::row_major> list_data, +uint32_t veclen, +uint32_t offset, +raft::device_matrix_view codes); +``` + +starting at given `offset`. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resource | +| `list_data` | in | `raft::device_mdspan::list_extents, raft::row_major>` | block to read from | +| `veclen` | in | `uint32_t` | size of interleaved data chunks | +| `offset` | in | `uint32_t` | How many records in the list to skip. | +| `codes` | inout | `raft::device_matrix_view` | the destination buffer [n_take, index.dim()]. The length `n_take` defines how many records to unpack, it must be <= the list size. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:2664`_ + +### codepacker::unpack + +Unpack `n_take` consecutive records of a single list (cluster) in the compressed index + +```cpp +void unpack(raft::resources const& res, +raft::device_mdspan::list_extents, +raft::row_major> list_data, +uint32_t veclen, +uint32_t offset, +raft::device_matrix_view codes); +``` + +starting at given `offset`. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resource | +| `list_data` | in | `raft::device_mdspan::list_extents, raft::row_major>` | block to read from | +| `veclen` | in | `uint32_t` | size of interleaved data chunks | +| `offset` | in | `uint32_t` | How many records in the list to skip. | +| `codes` | inout | `raft::device_matrix_view` | the destination buffer [n_take, index.dim()]. The length `n_take` defines how many records to unpack, it must be <= the list size. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:2696`_ + +### codepacker::unpack + +Unpack `n_take` consecutive records of a single list (cluster) in the compressed index + +```cpp +void unpack(raft::resources const& res, +raft::device_mdspan::list_extents, +raft::row_major> list_data, +uint32_t veclen, +uint32_t offset, +raft::device_matrix_view codes); +``` + +starting at given `offset`. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resource | +| `list_data` | in | `raft::device_mdspan::list_extents, raft::row_major>` | block to read from | +| `veclen` | in | `uint32_t` | size of interleaved data chunks | +| `offset` | in | `uint32_t` | How many records in the list to skip. | +| `codes` | inout | `raft::device_matrix_view` | the destination buffer [n_take, index.dim()]. The length `n_take` defines how many records to unpack, it must be <= the list size. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:2729`_ + +### codepacker::pack_1 + +Write one flat code into a block by the given offset. The offset indicates the id of the record + +```cpp +void pack_1(const float* flat_code, float* block, uint32_t dim, uint32_t veclen, uint32_t offset); +``` + +in the list. This function interleaves the code and is intended to later copy the interleaved codes over to the IVF list on device. NB: no memory allocation happens here; the block must fit the record (offset + 1). + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `flat_code` | in | `const float*` | input flat code | +| `block` | out | `float*` | block of memory to write interleaved codes to | +| `dim` | in | `uint32_t` | dimension of the flat code | +| `veclen` | in | `uint32_t` | size of interleaved data chunks | +| `offset` | in | `uint32_t` | how many records to skip before writing the data into the list | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:2749`_ + +### codepacker::pack_1 + +Write one flat code into a block by the given offset. The offset indicates the id of the record + +```cpp +void pack_1(const half* flat_code, half* block, uint32_t dim, uint32_t veclen, uint32_t offset); +``` + +in the list. This function interleaves the code and is intended to later copy the interleaved codes over to the IVF list on device. NB: no memory allocation happens here; the block must fit the record (offset + 1). + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `flat_code` | in | `const half*` | input flat code | +| `block` | out | `half*` | block of memory to write interleaved codes to | +| `dim` | in | `uint32_t` | dimension of the flat code | +| `veclen` | in | `uint32_t` | size of interleaved data chunks | +| `offset` | in | `uint32_t` | how many records to skip before writing the data into the list | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:2763`_ + +### codepacker::pack_1 + +Write one flat code into a block by the given offset. The offset indicates the id of the record + +```cpp +void pack_1(const int8_t* flat_code, int8_t* block, uint32_t dim, uint32_t veclen, uint32_t offset); +``` + +in the list. This function interleaves the code and is intended to later copy the interleaved codes over to the IVF list on device. NB: no memory allocation happens here; the block must fit the record (offset + 1). + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `flat_code` | in | `const int8_t*` | input flat code | +| `block` | out | `int8_t*` | block of memory to write interleaved codes to | +| `dim` | in | `uint32_t` | dimension of the flat code | +| `veclen` | in | `uint32_t` | size of interleaved data chunks | +| `offset` | in | `uint32_t` | how many records to skip before writing the data into the list | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:2777`_ + +### codepacker::pack_1 + +Write one flat code into a block by the given offset. The offset indicates the id of the record + +```cpp +void pack_1( +const uint8_t* flat_code, uint8_t* block, uint32_t dim, uint32_t veclen, uint32_t offset); +``` + +in the list. This function interleaves the code and is intended to later copy the interleaved codes over to the IVF list on device. NB: no memory allocation happens here; the block must fit the record (offset + 1). + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `flat_code` | in | `const uint8_t*` | input flat code | +| `block` | out | `uint8_t*` | block of memory to write interleaved codes to | +| `dim` | in | `uint32_t` | dimension of the flat code | +| `veclen` | in | `uint32_t` | size of interleaved data chunks | +| `offset` | in | `uint32_t` | how many records to skip before writing the data into the list | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:2791`_ + +### codepacker::unpack_1 + +Unpack 1 record of a single list (cluster) in the index to fetch the flat code. The offset + +```cpp +void unpack_1(const float* block, float* flat_code, uint32_t dim, uint32_t veclen, uint32_t offset); +``` + +indicates the id of the record. This function fetches one flat code from an interleaved code. interleaved format. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `block` | in | `const float*` | interleaved block. The block can be thought of as the whole inverted list in | +| `flat_code` | out | `float*` | output flat code | +| `dim` | in | `uint32_t` | dimension of the flat code | +| `veclen` | in | `uint32_t` | size of interleaved data chunks | +| `offset` | in | `uint32_t` | fetch the flat code by the given offset | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:2805`_ + +### codepacker::unpack_1 + +Unpack 1 record of a single list (cluster) in the index to fetch the flat code. The offset + +```cpp +void unpack_1(const half* block, half* flat_code, uint32_t dim, uint32_t veclen, uint32_t offset); +``` + +indicates the id of the record. This function fetches one flat code from an interleaved code. interleaved format. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `block` | in | `const half*` | interleaved block. The block can be thought of as the whole inverted list in | +| `flat_code` | out | `half*` | output flat code | +| `dim` | in | `uint32_t` | dimension of the flat code | +| `veclen` | in | `uint32_t` | size of interleaved data chunks | +| `offset` | in | `uint32_t` | fetch the flat code by the given offset | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:2818`_ + +### codepacker::unpack_1 + +Unpack 1 record of a single list (cluster) in the index to fetch the flat code. The offset + +```cpp +void unpack_1( +const int8_t* block, int8_t* flat_code, uint32_t dim, uint32_t veclen, uint32_t offset); +``` + +indicates the id of the record. This function fetches one flat code from an interleaved code. interleaved format. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `block` | in | `const int8_t*` | interleaved block. The block can be thought of as the whole inverted list in | +| `flat_code` | out | `int8_t*` | output flat code | +| `dim` | in | `uint32_t` | dimension of the flat code | +| `veclen` | in | `uint32_t` | size of interleaved data chunks | +| `offset` | in | `uint32_t` | fetch the flat code by the given offset | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:2831`_ + +### codepacker::unpack_1 + +Unpack 1 record of a single list (cluster) in the index to fetch the flat code. The offset + +```cpp +void unpack_1( +const uint8_t* block, uint8_t* flat_code, uint32_t dim, uint32_t veclen, uint32_t offset); +``` + +indicates the id of the record. This function fetches one flat code from an interleaved code. interleaved format. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `block` | in | `const uint8_t*` | interleaved block. The block can be thought of as the whole inverted list in | +| `flat_code` | out | `uint8_t*` | output flat code | +| `dim` | in | `uint32_t` | dimension of the flat code | +| `veclen` | in | `uint32_t` | size of interleaved data chunks | +| `offset` | in | `uint32_t` | fetch the flat code by the given offset | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:2845`_ + +### codepacker::reset_index + +Public helper API to reset the data and indices ptrs, and the list sizes. Useful for + +```cpp +void reset_index(const raft::resources& res, index* index); +``` + +externally modifying the index without going through the build stage. The data and indices of the IVF lists will be lost. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `const raft::resources&` | raft resource | +| `index` | inout | `index*` | pointer to IVF-Flat index | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:2870`_ + +### codepacker::reset_index + +Public helper API to reset the data and indices ptrs, and the list sizes. Useful for + +```cpp +void reset_index(const raft::resources& res, index* index); +``` + +externally modifying the index without going through the build stage. The data and indices of the IVF lists will be lost. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `const raft::resources&` | raft resource | +| `index` | inout | `index*` | pointer to IVF-Flat index | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:2892`_ + +### codepacker::reset_index + +Public helper API to reset the data and indices ptrs, and the list sizes. Useful for + +```cpp +void reset_index(const raft::resources& res, index* index); +``` + +externally modifying the index without going through the build stage. The data and indices of the IVF lists will be lost. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `const raft::resources&` | raft resource | +| `index` | inout | `index*` | pointer to IVF-Flat index | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:2914`_ + +### codepacker::reset_index + +Public helper API to reset the data and indices ptrs, and the list sizes. Useful for + +```cpp +void reset_index(const raft::resources& res, index* index); +``` + +externally modifying the index without going through the build stage. The data and indices of the IVF lists will be lost. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `const raft::resources&` | raft resource | +| `index` | inout | `index*` | pointer to IVF-Flat index | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:2936`_ + +### codepacker::recompute_internal_state + +Helper exposing the re-computation of list sizes and related arrays if IVF lists have been + +```cpp +void recompute_internal_state(const raft::resources& res, index* index); +``` + +modified externally. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `const raft::resources&` | raft resource | +| `index` | inout | `index*` | pointer to IVF-Flat index | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:2964`_ + +### codepacker::recompute_internal_state + +Helper exposing the re-computation of list sizes and related arrays if IVF lists have been + +```cpp +void recompute_internal_state(const raft::resources& res, index* index); +``` + +modified externally. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `const raft::resources&` | raft resource | +| `index` | inout | `index*` | pointer to IVF-Flat index | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:2992`_ + +### codepacker::recompute_internal_state + +Helper exposing the re-computation of list sizes and related arrays if IVF lists have been + +```cpp +void recompute_internal_state(const raft::resources& res, index* index); +``` + +modified externally. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `const raft::resources&` | raft resource | +| `index` | inout | `index*` | pointer to IVF-Flat index | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:3020`_ + +### codepacker::recompute_internal_state + +Helper exposing the re-computation of list sizes and related arrays if IVF lists have been + +```cpp +void recompute_internal_state(const raft::resources& res, index* index); +``` + +modified externally. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `const raft::resources&` | raft resource | +| `index` | inout | `index*` | pointer to IVF-Flat index | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:3048`_ diff --git a/fern/pages/cpp_api/cpp-api-neighbors-ivf-pq.md b/fern/pages/cpp_api/cpp-api-neighbors-ivf-pq.md new file mode 100644 index 0000000000..ca70dd3a7e --- /dev/null +++ b/fern/pages/cpp_api/cpp-api-neighbors-ivf-pq.md @@ -0,0 +1,2547 @@ +--- +slug: api-reference/cpp-api-neighbors-ivf-pq +--- + +# IVF PQ + +_Source header: `cpp/include/cuvs/neighbors/ivf_pq.hpp`_ + +## IVF-PQ index build parameters + +_Doxygen group: `ivf_pq_cpp_index_params`_ + +### cuvs::neighbors::ivf_pq::codebook_gen + +A type for specifying how PQ codebooks are created. + +```cpp +enum class codebook_gen { ... } ; +``` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:31`_ + +### cuvs::neighbors::ivf_pq::list_layout + +A type for specifying the memory layout of PQ codes in IVF lists. + +```cpp +enum class list_layout { ... } ; +``` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:37`_ + +### cuvs::neighbors::ivf_pq::from_dataset + +Creates index_params based on shape of the input dataset. + +```cpp +static index_params from_dataset( +raft::matrix_extent dataset, +cuvs::distance::DistanceType metric = cuvs::distance::DistanceType::L2Expanded); +``` + +Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `dataset` | | `raft::matrix_extent` | | +| `metric` | | `cuvs::distance::DistanceType` | Default: `cuvs::distance::DistanceType::L2Expanded`. | + +**Returns** + +`static index_params` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:145`_ + +## IVF-PQ index search parameters + +_Doxygen group: `ivf_pq_cpp_search_params`_ + +### cuvs::neighbors::ivf_pq::search_params + +IVF-PQ index search parameters + +```cpp +struct search_params : cuvs::neighbors::search_params { ... } ; +``` + +**Fields** + +| Name | Type | Description | +| --- | --- | --- | +| `n_probes` | `uint32_t` | The number of clusters to search. | +| `lut_dtype` | `cudaDataType_t` | Data type of look up table to be created dynamically at search time. | +| `internal_distance_dtype` | `cudaDataType_t` | Storage data type for distance/similarity computed at search time. | +| `preferred_shmem_carveout` | `double` | Preferred fraction of SM's unified memory / L1 cache to be used as shared memory. | +| `coarse_search_dtype` | `cudaDataType_t` | [Experimental] The data type to use as the GEMM element type when searching the clusters to | +| `max_internal_batch_size` | `uint32_t` | Set the internal batch size to improve GPU utilization at the cost of larger memory footprint. | + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:157`_ + +## IVF-PQ index + +_Doxygen group: `ivf_pq_cpp_index`_ + +### cuvs::neighbors::ivf_pq::index + +Construct an empty index. + +```cpp +index(raft::resources const& handle); +``` + +Constructs an empty index. This index will either need to be trained with `build` or loaded from a saved copy with `deserialize` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | | `raft::resources const&` | | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:493`_ + +### cuvs::neighbors::ivf_pq::index + +Construct an index with specified parameters. + +```cpp +index(raft::resources const& handle, +cuvs::distance::DistanceType metric, +codebook_gen codebook_kind, +uint32_t n_lists, +uint32_t dim, +uint32_t pq_bits = 8, +uint32_t pq_dim = 0, +bool conservative_memory_allocation = false); +``` + +This constructor creates an owning index with the given parameters. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | | `raft::resources const&` | RAFT resources handle | +| `metric` | | `cuvs::distance::DistanceType` | Distance metric for clustering | +| `codebook_kind` | | `codebook_gen` | How PQ codebooks are created | +| `n_lists` | | `uint32_t` | Number of inverted lists (clusters) | +| `dim` | | `uint32_t` | Dimensionality of the input data | +| `pq_bits` | | `uint32_t` | Bit length of vector elements after PQ compression Default: `8`. | +| `pq_dim` | | `uint32_t` | Dimensionality after PQ compression (0 = auto-select) Default: `0`. | +| `conservative_memory_allocation` | | `bool` | Memory allocation strategy Default: `false`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:509`_ + +### cuvs::neighbors::ivf_pq::index + +Construct an index from index parameters. + +```cpp +index(raft::resources const& handle, const index_params& params, uint32_t dim); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | | `raft::resources const&` | RAFT resources handle | +| `params` | | `const index_params&` | Index parameters | +| `dim` | | `uint32_t` | Dimensionality of the input data | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:525`_ + +### cuvs::neighbors::ivf_pq::size + +Total length of the index. + +```cpp +IdxT size() const noexcept override; +``` + +**Returns** + +`IdxT` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:528`_ + +### cuvs::neighbors::ivf_pq::dim + +Dimensionality of the input data. + +```cpp +uint32_t dim() const noexcept override; +``` + +**Returns** + +`uint32_t` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:531`_ + +### cuvs::neighbors::ivf_pq::dim_ext + +Dimensionality of the cluster centers: + +```cpp +uint32_t dim_ext() const noexcept; +``` + +input data dim extended with vector norms and padded to 8 elems. + +**Returns** + +`uint32_t` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:537`_ + +### cuvs::neighbors::ivf_pq::rot_dim + +Dimensionality of the data after transforming it for PQ processing + +```cpp +uint32_t rot_dim() const noexcept; +``` + +(rotated and augmented to be muplitple of `pq_dim`). + +**Returns** + +`uint32_t` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:543`_ + +### cuvs::neighbors::ivf_pq::pq_bits + +The bit length of an encoded vector element after compression by PQ. + +```cpp +uint32_t pq_bits() const noexcept override; +``` + +**Returns** + +`uint32_t` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:546`_ + +### cuvs::neighbors::ivf_pq::pq_dim + +The dimensionality of an encoded vector after compression by PQ. + +```cpp +uint32_t pq_dim() const noexcept override; +``` + +**Returns** + +`uint32_t` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:549`_ + +### cuvs::neighbors::ivf_pq::pq_len + +Dimensionality of a subspace, i.e. the number of vector components mapped to a subspace + +```cpp +uint32_t pq_len() const noexcept; +``` + +**Returns** + +`uint32_t` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:552`_ + +### cuvs::neighbors::ivf_pq::pq_book_size + +The number of vectors in a PQ codebook (`1 << pq_bits`). + +```cpp +uint32_t pq_book_size() const noexcept; +``` + +**Returns** + +`uint32_t` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:555`_ + +### cuvs::neighbors::ivf_pq::metric + +Distance metric used for clustering. + +```cpp +cuvs::distance::DistanceType metric() const noexcept override; +``` + +**Returns** + +`cuvs::distance::DistanceType` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:558`_ + +### cuvs::neighbors::ivf_pq::codebook_kind + +How PQ codebooks are created. + +```cpp +codebook_gen codebook_kind() const noexcept override; +``` + +**Returns** + +`codebook_gen` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:561`_ + +### cuvs::neighbors::ivf_pq::codes_layout + +Memory layout of PQ codes in IVF lists. + +```cpp +list_layout codes_layout() const noexcept override; +``` + +**Returns** + +`list_layout` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:564`_ + +### cuvs::neighbors::ivf_pq::n_lists + +Number of clusters/inverted lists (first level quantization). + +```cpp +uint32_t n_lists() const noexcept; +``` + +**Returns** + +`uint32_t` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:567`_ + +### cuvs::neighbors::ivf_pq::conservative_memory_allocation + +Whether to use conservative memory allocation when extending the list (cluster) data + +```cpp +bool conservative_memory_allocation() const noexcept override; +``` + +(see index_params.conservative_memory_allocation). + +**Returns** + +`bool` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:573`_ + +### cuvs::neighbors::ivf_pq::pq_centers + +PQ cluster centers + +```cpp +raft::device_mdspan pq_centers() +const noexcept override; +``` + +- codebook_gen::PER_SUBSPACE: [pq_dim , pq_len, pq_book_size] - codebook_gen::PER_CLUSTER: [n_lists, pq_len, pq_book_size] + +**Returns** + +`raft::device_mdspan` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:581`_ + +### cuvs::neighbors::ivf_pq::lists + +Lists' data and indices (polymorphic, works for both FLAT and INTERLEAVED layouts). + +```cpp +std::vector>>& lists() noexcept override; +``` + +**Returns** + +`std::vector>>&` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:585`_ + +### cuvs::neighbors::ivf_pq::data_ptrs + +Pointers to the inverted lists (clusters) data [n_lists]. + +```cpp +raft::device_vector_view data_ptrs() noexcept override; +``` + +**Returns** + +`raft::device_vector_view` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:589`_ + +### cuvs::neighbors::ivf_pq::inds_ptrs + +Pointers to the inverted lists (clusters) indices [n_lists]. + +```cpp +raft::device_vector_view inds_ptrs() noexcept override; +``` + +**Returns** + +`raft::device_vector_view` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:594`_ + +### cuvs::neighbors::ivf_pq::rotation_matrix + +The transform matrix (original space -> rotated padded space) [rot_dim, dim] + +```cpp +raft::device_matrix_view rotation_matrix() +const noexcept override; +``` + +**Returns** + +`raft::device_matrix_view` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:599`_ + +### cuvs::neighbors::ivf_pq::accum_sorted_sizes + +Accumulated list sizes, sorted in descending order [n_lists + 1]. + +```cpp +raft::host_vector_view accum_sorted_sizes() noexcept override; +``` + +The last value contains the total length of the index. The value at index zero is always zero. That is, the content of this span is as if the `list_sizes` was sorted and then accumulated. This span is used during search to estimate the maximum size of the workspace. + +**Returns** + +`raft::host_vector_view` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:616`_ + +### cuvs::neighbors::ivf_pq::list_sizes + +Sizes of the lists [n_lists]. + +```cpp +raft::device_vector_view list_sizes() noexcept override; +``` + +**Returns** + +`raft::device_vector_view` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:621`_ + +### cuvs::neighbors::ivf_pq::centers + +Cluster centers corresponding to the lists in the original space [n_lists, dim_ext] + +```cpp +raft::device_matrix_view centers() +const noexcept override; +``` + +**Returns** + +`raft::device_matrix_view` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:626`_ + +### cuvs::neighbors::ivf_pq::centers_rot + +Cluster centers corresponding to the lists in the rotated space [n_lists, rot_dim] + +```cpp +raft::device_matrix_view centers_rot() +const noexcept override; +``` + +**Returns** + +`raft::device_matrix_view` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:635`_ + +### cuvs::neighbors::ivf_pq::get_list_size_in_bytes + +fetch size of a particular IVF list in bytes using the list extents. + +```cpp +uint32_t get_list_size_in_bytes(uint32_t label) const override; +``` + +Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `label` | in | `uint32_t` | list ID | + +**Returns** + +`uint32_t` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:654`_ + +### cuvs::neighbors::ivf_pq::index + +Construct index from implementation pointer. + +```cpp +explicit index(std::unique_ptr> impl); +``` + +This constructor is used internally by build/extend/deserialize functions. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `impl` | | `std::unique_ptr>` | Implementation pointer (owning or view) | + +**Returns** + +`explicit` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:663`_ + +## IVF-PQ index build + +_Doxygen group: `ivf_pq_cpp_index_build`_ + +### cuvs::neighbors::ivf_pq::build + +Build the index from the dataset for efficient search. + +```cpp +auto build(raft::resources const& handle, +const cuvs::neighbors::ivf_pq::index_params& index_params, +raft::device_matrix_view dataset) +-> cuvs::neighbors::ivf_pq::index; +``` + +Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | | +| `index_params` | in | `const cuvs::neighbors::ivf_pq::index_params&` | configure the index building | +| `dataset` | in | `raft::device_matrix_view` | a device matrix view to a row-major matrix [n_rows, dim] | + +**Returns** + +`cuvs::neighbors::ivf_pq::index` + +the constructed ivf-pq index + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:699`_ + +### cuvs::neighbors::ivf_pq::build + +Build the index from the dataset for efficient search. + +```cpp +void build(raft::resources const& handle, +const cuvs::neighbors::ivf_pq::index_params& index_params, +raft::device_matrix_view dataset, +cuvs::neighbors::ivf_pq::index* idx); +``` + +NB: Currently, the following distance metrics are supported: - L2Expanded - L2Unexpanded - InnerProduct - CosineExpanded Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | | +| `index_params` | in | `const cuvs::neighbors::ivf_pq::index_params&` | configure the index building | +| `dataset` | in | `raft::device_matrix_view` | raft::device_matrix_view to a row-major matrix [n_rows, dim] | +| `idx` | out | `cuvs::neighbors::ivf_pq::index*` | reference to ivf_pq::index | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:729`_ + +### cuvs::neighbors::ivf_pq::build + +Build the index from the dataset for efficient search. + +```cpp +auto build(raft::resources const& handle, +const cuvs::neighbors::ivf_pq::index_params& index_params, +raft::device_matrix_view dataset) +-> cuvs::neighbors::ivf_pq::index; +``` + +Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | | +| `index_params` | in | `const cuvs::neighbors::ivf_pq::index_params&` | configure the index building | +| `dataset` | in | `raft::device_matrix_view` | a device matrix view to a row-major matrix [n_rows, dim] | + +**Returns** + +`cuvs::neighbors::ivf_pq::index` + +the constructed ivf-pq index + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:752`_ + +### cuvs::neighbors::ivf_pq::build + +Build the index from the dataset for efficient search. + +```cpp +void build(raft::resources const& handle, +const cuvs::neighbors::ivf_pq::index_params& index_params, +raft::device_matrix_view dataset, +cuvs::neighbors::ivf_pq::index* idx); +``` + +NB: Currently, the following distance metrics are supported: - L2Expanded - L2Unexpanded - InnerProduct - CosineExpanded Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | | +| `index_params` | in | `const cuvs::neighbors::ivf_pq::index_params&` | configure the index building | +| `dataset` | in | `raft::device_matrix_view` | raft::device_matrix_view to a row-major matrix [n_rows, dim] | +| `idx` | out | `cuvs::neighbors::ivf_pq::index*` | reference to ivf_pq::index | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:782`_ + +### cuvs::neighbors::ivf_pq::build + +Build the index from the dataset for efficient search. + +```cpp +auto build(raft::resources const& handle, +const cuvs::neighbors::ivf_pq::index_params& index_params, +raft::device_matrix_view dataset) +-> cuvs::neighbors::ivf_pq::index; +``` + +Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | | +| `index_params` | in | `const cuvs::neighbors::ivf_pq::index_params&` | configure the index building | +| `dataset` | in | `raft::device_matrix_view` | a device matrix view to a row-major matrix [n_rows, dim] | + +**Returns** + +`cuvs::neighbors::ivf_pq::index` + +the constructed ivf-pq index + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:804`_ + +### cuvs::neighbors::ivf_pq::build + +Build the index from the dataset for efficient search. + +```cpp +void build(raft::resources const& handle, +const cuvs::neighbors::ivf_pq::index_params& index_params, +raft::device_matrix_view dataset, +cuvs::neighbors::ivf_pq::index* idx); +``` + +NB: Currently, the following distance metrics are supported: - L2Expanded - L2Unexpanded - InnerProduct - CosineExpanded Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | | +| `index_params` | in | `const cuvs::neighbors::ivf_pq::index_params&` | configure the index building | +| `dataset` | in | `raft::device_matrix_view` | raft::device_matrix_view to a row-major matrix [n_rows, dim] | +| `idx` | out | `cuvs::neighbors::ivf_pq::index*` | reference to ivf_pq::index | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:834`_ + +### cuvs::neighbors::ivf_pq::build + +Build the index from the dataset for efficient search. + +```cpp +auto build(raft::resources const& handle, +const cuvs::neighbors::ivf_pq::index_params& index_params, +raft::device_matrix_view dataset) +-> cuvs::neighbors::ivf_pq::index; +``` + +Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | | +| `index_params` | in | `const cuvs::neighbors::ivf_pq::index_params&` | configure the index building | +| `dataset` | in | `raft::device_matrix_view` | a device matrix view to a row-major matrix [n_rows, dim] | + +**Returns** + +`cuvs::neighbors::ivf_pq::index` + +the constructed ivf-pq index + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:857`_ + +### cuvs::neighbors::ivf_pq::build + +Build the index from the dataset for efficient search. + +```cpp +void build(raft::resources const& handle, +const cuvs::neighbors::ivf_pq::index_params& index_params, +raft::device_matrix_view dataset, +cuvs::neighbors::ivf_pq::index* idx); +``` + +NB: Currently, the following distance metrics are supported: - L2Expanded - L2Unexpanded - InnerProduct - CosineExpanded Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | | +| `index_params` | in | `const cuvs::neighbors::ivf_pq::index_params&` | configure the index building | +| `dataset` | in | `raft::device_matrix_view` | raft::device_matrix_view to a row-major matrix [n_rows, dim] | +| `idx` | out | `cuvs::neighbors::ivf_pq::index*` | reference to ivf_pq::index | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:887`_ + +### cuvs::neighbors::ivf_pq::build + +Build the index from the dataset for efficient search. + +```cpp +auto build(raft::resources const& handle, +const cuvs::neighbors::ivf_pq::index_params& index_params, +raft::host_matrix_view dataset) +-> cuvs::neighbors::ivf_pq::index; +``` + +Note, if index_params.add_data_on_build is set to true, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | | +| `index_params` | in | `const cuvs::neighbors::ivf_pq::index_params&` | configure the index building | +| `dataset` | in | `raft::host_matrix_view` | a host_matrix_view to a row-major matrix [n_rows, dim] | + +**Returns** + +`cuvs::neighbors::ivf_pq::index` + +the constructed ivf-pq index + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:916`_ + +### cuvs::neighbors::ivf_pq::build + +Build the index from the dataset for efficient search. + +```cpp +void build(raft::resources const& handle, +const cuvs::neighbors::ivf_pq::index_params& index_params, +raft::host_matrix_view dataset, +cuvs::neighbors::ivf_pq::index* idx); +``` + +NB: Currently, the following distance metrics are supported: - L2Expanded - L2Unexpanded - InnerProduct - CosineExpanded Note, if index_params.add_data_on_build is set to true, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | | +| `index_params` | in | `const cuvs::neighbors::ivf_pq::index_params&` | configure the index building | +| `dataset` | in | `raft::host_matrix_view` | raft::host_matrix_view to a row-major matrix [n_rows, dim] | +| `idx` | out | `cuvs::neighbors::ivf_pq::index*` | reference to ivf_pq::index | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:953`_ + +### cuvs::neighbors::ivf_pq::build + +Build the index from the dataset for efficient search. + +```cpp +auto build(raft::resources const& handle, +const cuvs::neighbors::ivf_pq::index_params& index_params, +raft::host_matrix_view dataset) +-> cuvs::neighbors::ivf_pq::index; +``` + +Note, if index_params.add_data_on_build is set to true, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | | +| `index_params` | in | `const cuvs::neighbors::ivf_pq::index_params&` | configure the index building | +| `dataset` | in | `raft::host_matrix_view` | a host_matrix_view to a row-major matrix [n_rows, dim] | + +**Returns** + +`cuvs::neighbors::ivf_pq::index` + +the constructed ivf-pq index + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:983`_ + +### cuvs::neighbors::ivf_pq::build + +Build the index from the dataset for efficient search. + +```cpp +void build(raft::resources const& handle, +const cuvs::neighbors::ivf_pq::index_params& index_params, +raft::host_matrix_view dataset, +cuvs::neighbors::ivf_pq::index* idx); +``` + +NB: Currently, the following distance metrics are supported: - L2Expanded - L2Unexpanded - InnerProduct - CosineExpanded Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | | +| `index_params` | in | `const cuvs::neighbors::ivf_pq::index_params&` | configure the index building | +| `dataset` | in | `raft::host_matrix_view` | raft::host_matrix_view to a row-major matrix [n_rows, dim] | +| `idx` | out | `cuvs::neighbors::ivf_pq::index*` | reference to ivf_pq::index | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:1013`_ + +### cuvs::neighbors::ivf_pq::build + +Build the index from the dataset for efficient search. + +```cpp +auto build(raft::resources const& handle, +const cuvs::neighbors::ivf_pq::index_params& index_params, +raft::host_matrix_view dataset) +-> cuvs::neighbors::ivf_pq::index; +``` + +Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | | +| `index_params` | in | `const cuvs::neighbors::ivf_pq::index_params&` | configure the index building | +| `dataset` | in | `raft::host_matrix_view` | a host_matrix_view to a row-major matrix [n_rows, dim] | + +**Returns** + +`cuvs::neighbors::ivf_pq::index` + +the constructed ivf-pq index + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:1036`_ + +### cuvs::neighbors::ivf_pq::build + +Build the index from the dataset for efficient search. + +```cpp +void build(raft::resources const& handle, +const cuvs::neighbors::ivf_pq::index_params& index_params, +raft::host_matrix_view dataset, +cuvs::neighbors::ivf_pq::index* idx); +``` + +NB: Currently, the following distance metrics are supported: - L2Expanded - L2Unexpanded - InnerProduct - CosineExpanded Note, if index_params.add_data_on_build is set to true, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | | +| `index_params` | in | `const cuvs::neighbors::ivf_pq::index_params&` | configure the index building | +| `dataset` | in | `raft::host_matrix_view` | raft::host_matrix_view to a row-major matrix [n_rows, dim] | +| `idx` | out | `cuvs::neighbors::ivf_pq::index*` | reference to ivf_pq::index | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:1073`_ + +### cuvs::neighbors::ivf_pq::build + +Build the index from the dataset for efficient search. + +```cpp +auto build(raft::resources const& handle, +const cuvs::neighbors::ivf_pq::index_params& index_params, +raft::host_matrix_view dataset) +-> cuvs::neighbors::ivf_pq::index; +``` + +Note, if index_params.add_data_on_build is set to true, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | | +| `index_params` | in | `const cuvs::neighbors::ivf_pq::index_params&` | configure the index building | +| `dataset` | in | `raft::host_matrix_view` | a host_matrix_view to a row-major matrix [n_rows, dim] | + +**Returns** + +`cuvs::neighbors::ivf_pq::index` + +the constructed ivf-pq index + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:1103`_ + +### cuvs::neighbors::ivf_pq::build + +Build the index from the dataset for efficient search. + +```cpp +void build(raft::resources const& handle, +const cuvs::neighbors::ivf_pq::index_params& index_params, +raft::host_matrix_view dataset, +cuvs::neighbors::ivf_pq::index* idx); +``` + +NB: Currently, the following distance metrics are supported: - L2Expanded - L2Unexpanded - InnerProduct - CosineExpanded Note, if index_params.add_data_on_build is set to true, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | | +| `index_params` | in | `const cuvs::neighbors::ivf_pq::index_params&` | configure the index building | +| `dataset` | in | `raft::host_matrix_view` | raft::host_matrix_view to a row-major matrix [n_rows, dim] | +| `idx` | out | `cuvs::neighbors::ivf_pq::index*` | reference to ivf_pq::index | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:1140`_ + +### cuvs::neighbors::ivf_pq::build + +Build a view-type IVF-PQ index from device memory centroids and codebook. + +```cpp +auto build(raft::resources const& handle, +const cuvs::neighbors::ivf_pq::index_params& index_params, +const uint32_t dim, +raft::device_mdspan, raft::row_major> pq_centers, +raft::device_matrix_view centers, +raft::device_matrix_view centers_rot, +raft::device_matrix_view rotation_matrix) +-> cuvs::neighbors::ivf_pq::index; +``` + +This function creates a non-owning index that stores a reference to the provided device data. All parameters must be provided with correct extents. The caller is responsible for ensuring the lifetime of the input data exceeds the lifetime of the returned index. The index_params must be consistent with the provided matrices. Specifically: - index_params.codebook_kind determines the expected shape of pq_centers - index_params.metric will be stored in the index - index_params.conservative_memory_allocation will be stored in the index The function will verify consistency between index_params, dim, and the matrix extents. dim] + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | raft resources handle | +| `index_params` | in | `const cuvs::neighbors::ivf_pq::index_params&` | configure the index (metric, codebook_kind, etc.). Must be consistent with the provided matrices. | +| `dim` | in | `const uint32_t` | dimensionality of the input data | +| `pq_centers` | in | `raft::device_mdspan, raft::row_major>` | PQ codebook on device memory with required extents: - codebook_gen::PER_SUBSPACE: [pq_dim, pq_len, pq_book_size] - codebook_gen::PER_CLUSTER: [n_lists, pq_len, pq_book_size] | +| `centers` | in | `raft::device_matrix_view` | Cluster centers in the original space [n_lists, dim_ext] where dim_ext = round_up(dim + 1, 8) | +| `centers_rot` | in | `raft::device_matrix_view` | Rotated cluster centers [n_lists, rot_dim] where rot_dim = pq_len * pq_dim | +| `rotation_matrix` | in | `raft::device_matrix_view` | Transform matrix (original space -> rotated padded space) [rot_dim, | + +**Returns** + +`cuvs::neighbors::ivf_pq::index` + +A view-type ivf_pq index that references the provided data + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:1174`_ + +### cuvs::neighbors::ivf_pq::build + +Build an IVF-PQ index from device memory centroids and codebook. + +```cpp +void build(raft::resources const& handle, +const cuvs::neighbors::ivf_pq::index_params& index_params, +const uint32_t dim, +raft::device_mdspan, raft::row_major> pq_centers, +raft::device_matrix_view centers, +raft::device_matrix_view centers_rot, +raft::device_matrix_view rotation_matrix, +cuvs::neighbors::ivf_pq::index* idx); +``` + +This function creates a non-owning index that references the provided device data directly. All parameters must be provided with correct extents. The caller is responsible for ensuring the lifetime of the input data exceeds the lifetime of the returned index. The index_params must be consistent with the provided matrices. Specifically: - index_params.codebook_kind determines the expected shape of pq_centers - index_params.metric will be stored in the index - index_params.conservative_memory_allocation will be stored in the index The function will verify consistency between index_params, dim, and the matrix extents. dim] + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | raft resources handle | +| `index_params` | in | `const cuvs::neighbors::ivf_pq::index_params&` | configure the index (metric, codebook_kind, etc.). Must be consistent with the provided matrices. | +| `dim` | in | `const uint32_t` | dimensionality of the input data | +| `pq_centers` | in | `raft::device_mdspan, raft::row_major>` | PQ codebook on device memory with required extents: - codebook_gen::PER_SUBSPACE: [pq_dim, pq_len, pq_book_size] - codebook_gen::PER_CLUSTER: [n_lists, pq_len, pq_book_size] | +| `centers` | in | `raft::device_matrix_view` | Cluster centers in the original space [n_lists, dim_ext] where dim_ext = round_up(dim + 1, 8) | +| `centers_rot` | in | `raft::device_matrix_view` | Rotated cluster centers [n_lists, rot_dim] where rot_dim = pq_len * pq_dim | +| `rotation_matrix` | in | `raft::device_matrix_view` | Transform matrix (original space -> rotated padded space) [rot_dim, | +| `idx` | out | `cuvs::neighbors::ivf_pq::index*` | pointer to ivf_pq::index | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:1211`_ + +### cuvs::neighbors::ivf_pq::build + +Build an IVF-PQ index from host memory centroids and codebook (in-place). + +```cpp +auto build( +raft::resources const& handle, +const cuvs::neighbors::ivf_pq::index_params& index_params, +const uint32_t dim, +raft::host_mdspan, raft::row_major> pq_centers, +raft::host_matrix_view centers, +std::optional> centers_rot, +std::optional> rotation_matrix) +-> cuvs::neighbors::ivf_pq::index; +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | raft resources handle | +| `index_params` | in | `const cuvs::neighbors::ivf_pq::index_params&` | configure the index building | +| `dim` | in | `const uint32_t` | dimensionality of the input data | +| `pq_centers` | in | `raft::host_mdspan, raft::row_major>` | PQ codebook | +| `centers` | in | `raft::host_matrix_view` | Cluster centers | +| `centers_rot` | in | `std::optional>` | Optional rotated cluster centers | +| `rotation_matrix` | in | `std::optional>` | Optional rotation matrix | + +**Returns** + +`cuvs::neighbors::ivf_pq::index` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:1231`_ + +### cuvs::neighbors::ivf_pq::build + +Build an IVF-PQ index from host memory centroids and codebook (in-place). + +```cpp +void build( +raft::resources const& handle, +const cuvs::neighbors::ivf_pq::index_params& index_params, +const uint32_t dim, +raft::host_mdspan, raft::row_major> pq_centers, +raft::host_matrix_view centers, +std::optional> centers_rot, +std::optional> rotation_matrix, +cuvs::neighbors::ivf_pq::index* idx); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | raft resources handle | +| `index_params` | in | `const cuvs::neighbors::ivf_pq::index_params&` | configure the index building | +| `dim` | in | `const uint32_t` | dimensionality of the input data | +| `pq_centers` | in | `raft::host_mdspan, raft::row_major>` | PQ codebook on host memory | +| `centers` | in | `raft::host_matrix_view` | Cluster centers on host memory | +| `centers_rot` | in | `std::optional>` | Optional rotated cluster centers on host | +| `rotation_matrix` | in | `std::optional>` | Optional rotation matrix on host | +| `idx` | out | `cuvs::neighbors::ivf_pq::index*` | pointer to IVF-PQ index to be built | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:1253`_ + +## IVF-PQ index extend + +_Doxygen group: `ivf_pq_cpp_index_extend`_ + +### cuvs::neighbors::ivf_pq::extend + +Extend the index with the new data. + +```cpp +auto extend(raft::resources const& handle, +raft::device_matrix_view new_vectors, +std::optional> new_indices, +const cuvs::neighbors::ivf_pq::index& idx) +-> cuvs::neighbors::ivf_pq::index; +``` + +Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | | +| `new_vectors` | in | `raft::device_matrix_view` | a device matrix view to a row-major matrix [n_rows, idx.dim()] | +| `new_indices` | in | `std::optional>` | a device vector view to a vector of indices [n_rows]. If the original index is empty (`idx.size() == 0`), you can pass `std::nullopt` here to imply a continuous range `[0...n_rows)`. | +| `idx` | inout | `const cuvs::neighbors::ivf_pq::index&` | | + +**Returns** + +`cuvs::neighbors::ivf_pq::index` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:1293`_ + +### cuvs::neighbors::ivf_pq::extend + +Extend the index with the new data. + +```cpp +void extend(raft::resources const& handle, +raft::device_matrix_view new_vectors, +std::optional> new_indices, +cuvs::neighbors::ivf_pq::index* idx); +``` + +Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | | +| `new_vectors` | in | `raft::device_matrix_view` | a device matrix view to a row-major matrix [n_rows, idx.dim()] | +| `new_indices` | in | `std::optional>` | a device vector view to a vector of indices [n_rows]. If the original index is empty (`idx.size() == 0`), you can pass `std::nullopt` here to imply a continuous range `[0...n_rows)`. | +| `idx` | inout | `cuvs::neighbors::ivf_pq::index*` | | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:1322`_ + +### cuvs::neighbors::ivf_pq::extend + +Extend the index with the new data. + +```cpp +auto extend(raft::resources const& handle, +raft::device_matrix_view new_vectors, +std::optional> new_indices, +const cuvs::neighbors::ivf_pq::index& idx) +-> cuvs::neighbors::ivf_pq::index; +``` + +Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | | +| `new_vectors` | in | `raft::device_matrix_view` | a device matrix view to a row-major matrix [n_rows, idx.dim()] | +| `new_indices` | in | `std::optional>` | a device vector view to a vector of indices [n_rows]. If the original index is empty (`idx.size() == 0`), you can pass `std::nullopt` here to imply a continuous range `[0...n_rows)`. | +| `idx` | inout | `const cuvs::neighbors::ivf_pq::index&` | | + +**Returns** + +`cuvs::neighbors::ivf_pq::index` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:1350`_ + +### cuvs::neighbors::ivf_pq::extend + +Extend the index with the new data. + +```cpp +void extend(raft::resources const& handle, +raft::device_matrix_view new_vectors, +std::optional> new_indices, +cuvs::neighbors::ivf_pq::index* idx); +``` + +Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | | +| `new_vectors` | in | `raft::device_matrix_view` | a device matrix view to a row-major matrix [n_rows, idx.dim()] | +| `new_indices` | in | `std::optional>` | a device vector view to a vector of indices [n_rows]. If the original index is empty (`idx.size() == 0`), you can pass `std::nullopt` here to imply a continuous range `[0...n_rows)`. | +| `idx` | inout | `cuvs::neighbors::ivf_pq::index*` | | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:1379`_ + +### cuvs::neighbors::ivf_pq::extend + +Extend the index with the new data. + +```cpp +auto extend(raft::resources const& handle, +raft::device_matrix_view new_vectors, +std::optional> new_indices, +const cuvs::neighbors::ivf_pq::index& idx) +-> cuvs::neighbors::ivf_pq::index; +``` + +Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | | +| `new_vectors` | in | `raft::device_matrix_view` | a device matrix view to a row-major matrix [n_rows, idx.dim()] | +| `new_indices` | in | `std::optional>` | a device vector view to a vector of indices [n_rows]. If the original index is empty (`idx.size() == 0`), you can pass `std::nullopt` here to imply a continuous range `[0...n_rows)`. | +| `idx` | inout | `const cuvs::neighbors::ivf_pq::index&` | | + +**Returns** + +`cuvs::neighbors::ivf_pq::index` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:1407`_ + +### cuvs::neighbors::ivf_pq::extend + +Extend the index with the new data. + +```cpp +void extend(raft::resources const& handle, +raft::device_matrix_view new_vectors, +std::optional> new_indices, +cuvs::neighbors::ivf_pq::index* idx); +``` + +Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | | +| `new_vectors` | in | `raft::device_matrix_view` | a device matrix view to a row-major matrix [n_rows, idx.dim()] | +| `new_indices` | in | `std::optional>` | a device vector view to a vector of indices [n_rows]. If the original index is empty (`idx.size() == 0`), you can pass `std::nullopt` here to imply a continuous range `[0...n_rows)`. | +| `idx` | inout | `cuvs::neighbors::ivf_pq::index*` | | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:1436`_ + +### cuvs::neighbors::ivf_pq::extend + +Extend the index with the new data. + +```cpp +auto extend(raft::resources const& handle, +raft::device_matrix_view new_vectors, +std::optional> new_indices, +const cuvs::neighbors::ivf_pq::index& idx) +-> cuvs::neighbors::ivf_pq::index; +``` + +Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | | +| `new_vectors` | in | `raft::device_matrix_view` | a device matrix view to a row-major matrix [n_rows, idx.dim()] | +| `new_indices` | in | `std::optional>` | a device vector view to a vector of indices [n_rows]. If the original index is empty (`idx.size() == 0`), you can pass `std::nullopt` here to imply a continuous range `[0...n_rows)`. | +| `idx` | inout | `const cuvs::neighbors::ivf_pq::index&` | | + +**Returns** + +`cuvs::neighbors::ivf_pq::index` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:1464`_ + +### cuvs::neighbors::ivf_pq::extend + +Extend the index with the new data. + +```cpp +void extend(raft::resources const& handle, +raft::device_matrix_view new_vectors, +std::optional> new_indices, +cuvs::neighbors::ivf_pq::index* idx); +``` + +Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | | +| `new_vectors` | in | `raft::device_matrix_view` | a device matrix view to a row-major matrix [n_rows, idx.dim()] | +| `new_indices` | in | `std::optional>` | a device vector view to a vector of indices [n_rows]. If the original index is empty (`idx.size() == 0`), you can pass `std::nullopt` here to imply a continuous range `[0...n_rows)`. | +| `idx` | inout | `cuvs::neighbors::ivf_pq::index*` | | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:1493`_ + +### cuvs::neighbors::ivf_pq::extend + +Extend the index with the new data. + +```cpp +auto extend(raft::resources const& handle, +raft::host_matrix_view new_vectors, +std::optional> new_indices, +const cuvs::neighbors::ivf_pq::index& idx) +-> cuvs::neighbors::ivf_pq::index; +``` + +Note, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | | +| `new_vectors` | in | `raft::host_matrix_view` | a host matrix view to a row-major matrix [n_rows, idx.dim()] | +| `new_indices` | in | `std::optional>` | a host vector view to a vector of indices [n_rows]. If the original index is empty (`idx.size() == 0`), you can pass `std::nullopt` here to imply a continuous range `[0...n_rows)`. | +| `idx` | inout | `const cuvs::neighbors::ivf_pq::index&` | | + +**Returns** + +`cuvs::neighbors::ivf_pq::index` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:1527`_ + +### cuvs::neighbors::ivf_pq::extend + +Extend the index with the new data. + +```cpp +void extend(raft::resources const& handle, +raft::host_matrix_view new_vectors, +std::optional> new_indices, +cuvs::neighbors::ivf_pq::index* idx); +``` + +Note, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | | +| `new_vectors` | in | `raft::host_matrix_view` | a host matrix view to a row-major matrix [n_rows, idx.dim()] | +| `new_indices` | in | `std::optional>` | a host vector view to a vector of indices [n_rows]. If the original index is empty (`idx.size() == 0`), you can pass `std::nullopt` here to imply a continuous range `[0...n_rows)`. | +| `idx` | inout | `cuvs::neighbors::ivf_pq::index*` | | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:1562`_ + +### cuvs::neighbors::ivf_pq::extend + +Extend the index with the new data. + +```cpp +auto extend(raft::resources const& handle, +raft::host_matrix_view new_vectors, +std::optional> new_indices, +const cuvs::neighbors::ivf_pq::index& idx) +-> cuvs::neighbors::ivf_pq::index; +``` + +Note, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | | +| `new_vectors` | in | `raft::host_matrix_view` | a host matrix view to a row-major matrix [n_rows, idx.dim()] | +| `new_indices` | in | `std::optional>` | a host vector view to a vector of indices [n_rows]. If the original index is empty (`idx.size() == 0`), you can pass `std::nullopt` here to imply a continuous range `[0...n_rows)`. | +| `idx` | inout | `const cuvs::neighbors::ivf_pq::index&` | | + +**Returns** + +`cuvs::neighbors::ivf_pq::index` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:1596`_ + +### cuvs::neighbors::ivf_pq::extend + +Extend the index with the new data. + +```cpp +void extend(raft::resources const& handle, +raft::host_matrix_view new_vectors, +std::optional> new_indices, +cuvs::neighbors::ivf_pq::index* idx); +``` + +Note, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | | +| `new_vectors` | in | `raft::host_matrix_view` | a host matrix view to a row-major matrix [n_rows, idx.dim()] | +| `new_indices` | in | `std::optional>` | a host vector view to a vector of indices [n_rows]. If the original index is empty (`idx.size() == 0`), you can pass `std::nullopt` here to imply a continuous range `[0...n_rows)`. | +| `idx` | inout | `cuvs::neighbors::ivf_pq::index*` | | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:1631`_ + +### cuvs::neighbors::ivf_pq::extend + +Extend the index with the new data. + +```cpp +auto extend(raft::resources const& handle, +raft::host_matrix_view new_vectors, +std::optional> new_indices, +const cuvs::neighbors::ivf_pq::index& idx) +-> cuvs::neighbors::ivf_pq::index; +``` + +Note, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | | +| `new_vectors` | in | `raft::host_matrix_view` | a host matrix view to a row-major matrix [n_rows, idx.dim()] | +| `new_indices` | in | `std::optional>` | a host vector view to a vector of indices [n_rows]. If the original index is empty (`idx.size() == 0`), you can pass `std::nullopt` here to imply a continuous range `[0...n_rows)`. | +| `idx` | inout | `const cuvs::neighbors::ivf_pq::index&` | | + +**Returns** + +`cuvs::neighbors::ivf_pq::index` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:1665`_ + +### cuvs::neighbors::ivf_pq::extend + +Extend the index with the new data. + +```cpp +void extend(raft::resources const& handle, +raft::host_matrix_view new_vectors, +std::optional> new_indices, +cuvs::neighbors::ivf_pq::index* idx); +``` + +Note, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | | +| `new_vectors` | in | `raft::host_matrix_view` | a host matrix view to a row-major matrix [n_rows, idx.dim()] | +| `new_indices` | in | `std::optional>` | a host vector view to a vector of indices [n_rows]. If the original index is empty (`idx.size() == 0`), you can pass `std::nullopt` here to imply a continuous range `[0...n_rows)`. | +| `idx` | inout | `cuvs::neighbors::ivf_pq::index*` | | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:1700`_ + +### cuvs::neighbors::ivf_pq::extend + +Extend the index with the new data. + +```cpp +auto extend(raft::resources const& handle, +raft::host_matrix_view new_vectors, +std::optional> new_indices, +const cuvs::neighbors::ivf_pq::index& idx) +-> cuvs::neighbors::ivf_pq::index; +``` + +Note, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | | +| `new_vectors` | in | `raft::host_matrix_view` | a host matrix view to a row-major matrix [n_rows, idx.dim()] | +| `new_indices` | in | `std::optional>` | a host vector view to a vector of indices [n_rows]. If the original index is empty (`idx.size() == 0`), you can pass `std::nullopt` here to imply a continuous range `[0...n_rows)`. | +| `idx` | inout | `const cuvs::neighbors::ivf_pq::index&` | | + +**Returns** + +`cuvs::neighbors::ivf_pq::index` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:1734`_ + +### cuvs::neighbors::ivf_pq::extend + +Extend the index with the new data. + +```cpp +void extend(raft::resources const& handle, +raft::host_matrix_view new_vectors, +std::optional> new_indices, +cuvs::neighbors::ivf_pq::index* idx); +``` + +Note, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | | +| `new_vectors` | in | `raft::host_matrix_view` | a host matrix view to a row-major matrix [n_rows, idx.dim()] | +| `new_indices` | in | `std::optional>` | a host vector view to a vector of indices [n_rows]. If the original index is empty (`idx.size() == 0`), you can pass `std::nullopt` here to imply a continuous range `[0...n_rows)`. | +| `idx` | inout | `cuvs::neighbors::ivf_pq::index*` | | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:1770`_ + +## IVF-PQ index transform + +_Doxygen group: `ivf_pq_cpp_transform`_ + +### cuvs::neighbors::ivf_pq::transform + +Transform a dataset by applying pq-encoding to each vector + +```cpp +void transform(raft::resources const& handle, +const cuvs::neighbors::ivf_pq::index& index, +raft::device_matrix_view dataset, +raft::device_vector_view output_labels, +raft::device_matrix_view output_dataset); +``` + +cluster ids (labels) for each vector in the input dataset index.pq_bits(), 8)]] that will get populated with the pq-encoded dataset + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | | +| `index` | in | `const cuvs::neighbors::ivf_pq::index&` | ivf-pq constructed index | +| `dataset` | in | `raft::device_matrix_view` | a device matrix view to a row-major matrix [n_rows, index.dim()] | +| `output_labels` | out | `raft::device_vector_view` | a device vector view [n_rows] that will get populaterd with the | +| `output_dataset` | out | `raft::device_matrix_view` | a device matrix view [n_rows, ceildiv(index.pq_dim() * | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:1981`_ + +### cuvs::neighbors::ivf_pq::transform + +```cpp +void transform(raft::resources const& handle, +const cuvs::neighbors::ivf_pq::index& index, +raft::device_matrix_view dataset, +raft::device_vector_view output_labels, +raft::device_matrix_view output_dataset); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | | `raft::resources const&` | | +| `index` | | `const cuvs::neighbors::ivf_pq::index&` | | +| `dataset` | | `raft::device_matrix_view` | | +| `output_labels` | | `raft::device_vector_view` | | +| `output_dataset` | | `raft::device_matrix_view` | | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:1987`_ + +### cuvs::neighbors::ivf_pq::transform + +```cpp +void transform(raft::resources const& handle, +const cuvs::neighbors::ivf_pq::index& index, +raft::device_matrix_view dataset, +raft::device_vector_view output_labels, +raft::device_matrix_view output_dataset); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | | `raft::resources const&` | | +| `index` | | `const cuvs::neighbors::ivf_pq::index&` | | +| `dataset` | | `raft::device_matrix_view` | | +| `output_labels` | | `raft::device_vector_view` | | +| `output_dataset` | | `raft::device_matrix_view` | | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:1993`_ + +### cuvs::neighbors::ivf_pq::transform + +```cpp +void transform(raft::resources const& handle, +const cuvs::neighbors::ivf_pq::index& index, +raft::device_matrix_view dataset, +raft::device_vector_view output_labels, +raft::device_matrix_view output_dataset); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | | `raft::resources const&` | | +| `index` | | `const cuvs::neighbors::ivf_pq::index&` | | +| `dataset` | | `raft::device_matrix_view` | | +| `output_labels` | | `raft::device_vector_view` | | +| `output_dataset` | | `raft::device_matrix_view` | | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:1999`_ + +## IVF-PQ index serialize + +_Doxygen group: `ivf_pq_cpp_serialize`_ + +### cuvs::neighbors::ivf_pq::serialize + +Write the index to an output stream + +```cpp +void serialize(raft::resources const& handle, +std::ostream& os, +const cuvs::neighbors::ivf_pq::index& index); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | the raft handle | +| `os` | in | `std::ostream&` | output stream | +| `index` | in | `const cuvs::neighbors::ivf_pq::index&` | IVF-PQ index | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:2031`_ + +### cuvs::neighbors::ivf_pq::serialize + +Save the index to file. + +```cpp +void serialize(raft::resources const& handle, +const std::string& filename, +const cuvs::neighbors::ivf_pq::index& index); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | the raft handle | +| `filename` | in | `const std::string&` | the file name for saving the index | +| `index` | in | `const cuvs::neighbors::ivf_pq::index&` | IVF-PQ index | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:2054`_ + +### cuvs::neighbors::ivf_pq::deserialize + +Load index from input stream + +```cpp +void deserialize(raft::resources const& handle, +std::istream& str, +cuvs::neighbors::ivf_pq::index* index); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | the raft handle | +| `str` | in | `std::istream&` | the name of the file that stores the index | +| `index` | out | `cuvs::neighbors::ivf_pq::index*` | IVF-PQ index | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:2081`_ + +### cuvs::neighbors::ivf_pq::deserialize + +Load index from file. + +```cpp +void deserialize(raft::resources const& handle, +const std::string& filename, +cuvs::neighbors::ivf_pq::index* index); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | the raft handle | +| `filename` | in | `const std::string&` | the name of the file that stores the index | +| `index` | out | `cuvs::neighbors::ivf_pq::index*` | IVF-PQ index | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:2106`_ + +## IVF-PQ helper methods + +_Doxygen group: `ivf_pq_cpp_helpers`_ + +### namespace codepacker \{ + +IVF-PQ helper methods + +```cpp +namespace codepacker { +``` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:2561`_ + +### codepacker::unpack + +Unpack `n_take` consecutive records of a single list (cluster) in the compressed index + +```cpp +void unpack(raft::resources const& res, +raft::device_mdspan::list_extents, +raft::row_major> list_data, +uint32_t pq_bits, +uint32_t offset, +raft::device_matrix_view codes); +``` + +starting at given `offset`. Bit compression is removed, which means output will have pq_dim dimensional vectors (one code per byte, instead of ceildiv(pq_dim * pq_bits, 8) bytes of pq codes). Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resource | +| `list_data` | in | `raft::device_mdspan::list_extents, raft::row_major>` | block to read from | +| `pq_bits` | in | `uint32_t` | bit length of encoded vector elements | +| `offset` | in | `uint32_t` | How many records in the list to skip. | +| `codes` | out | `raft::device_matrix_view` | the destination buffer [n_take, index.pq_dim()]. The length `n_take` defines how many records to unpack, it must be smaller than the list size. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:2594`_ + +### codepacker::unpack_contiguous + +Unpack `n_rows` consecutive records of a single list (cluster) in the compressed index + +```cpp +void unpack_contiguous(raft::resources const& res, +raft::device_mdspan::list_extents, +raft::row_major> list_data, +uint32_t pq_bits, +uint32_t offset, +uint32_t n_rows, +uint32_t pq_dim, +uint8_t* codes); +``` + +starting at given `offset`. The output codes of a single vector are contiguous, not expanded to one code per byte, which means the output has ceildiv(pq_dim * pq_bits, 8) bytes per PQ encoded vector. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resource | +| `list_data` | in | `raft::device_mdspan::list_extents, raft::row_major>` | block to read from | +| `pq_bits` | in | `uint32_t` | bit length of encoded vector elements | +| `offset` | in | `uint32_t` | How many records in the list to skip. | +| `n_rows` | in | `uint32_t` | How many records to unpack | +| `pq_dim` | in | `uint32_t` | The dimensionality of the PQ compressed records | +| `codes` | out | `uint8_t*` | the destination buffer [n_rows, ceildiv(pq_dim * pq_bits, 8)]. The length `n_rows` defines how many records to unpack, it must be smaller than the list size. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:2634`_ + +### codepacker::pack + +Write flat PQ codes into an existing list by the given offset. + +```cpp +void pack(raft::resources const& res, +raft::device_matrix_view codes, +uint32_t pq_bits, +uint32_t offset, +raft::device_mdspan::list_extents, +raft::row_major> list_data); +``` + +NB: no memory allocation happens here; the list must fit the data (offset + n_vec). Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resource | +| `codes` | in | `raft::device_matrix_view` | flat PQ codes, one code per byte [n_vec, pq_dim] | +| `pq_bits` | in | `uint32_t` | bit length of encoded vector elements | +| `offset` | in | `uint32_t` | how many records to skip before writing the data into the list | +| `list_data` | in | `raft::device_mdspan::list_extents, raft::row_major>` | block to write into | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:2666`_ + +### codepacker::pack_contiguous + +Write flat PQ codes into an existing list by the given offset. The input codes of a single vector + +```cpp +void pack_contiguous(raft::resources const& res, +const uint8_t* codes, +uint32_t n_rows, +uint32_t pq_dim, +uint32_t pq_bits, +uint32_t offset, +raft::device_mdspan::list_extents, +raft::row_major> list_data); +``` + +are contiguous (not expanded to one code per byte). NB: no memory allocation happens here; the list must fit the data (offset + n_rows records). Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resource | +| `codes` | in | `const uint8_t*` | flat PQ codes, [n_vec, ceildiv(pq_dim * pq_bits, 8)] | +| `n_rows` | in | `uint32_t` | number of records | +| `pq_dim` | in | `uint32_t` | | +| `pq_bits` | in | `uint32_t` | bit length of encoded vector elements | +| `offset` | in | `uint32_t` | how many records to skip before writing the data into the list | +| `list_data` | in | `raft::device_mdspan::list_extents, raft::row_major>` | block to write into | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:2702`_ + +### codepacker::pack_list_data + +Write flat PQ codes into an existing list by the given offset. + +```cpp +void pack_list_data(raft::resources const& res, +index* index, +raft::device_matrix_view codes, +uint32_t label, +uint32_t offset); +``` + +The list is identified by its label. NB: no memory allocation happens here; the list must fit the data (offset + n_vec). Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resource | +| `index` | inout | `index*` | IVF-PQ index. | +| `codes` | in | `raft::device_matrix_view` | flat PQ codes, one code per byte [n_rows, pq_dim] | +| `label` | in | `uint32_t` | The id of the list (cluster) into which we write. | +| `offset` | in | `uint32_t` | how many records to skip before writing the data into the list | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:2736`_ + +### codepacker::pack_contiguous_list_data + +Write flat PQ codes into an existing list by the given offset. Use this when the input + +```cpp +void pack_contiguous_list_data(raft::resources const& res, +index* index, +uint8_t* codes, +uint32_t n_rows, +uint32_t label, +uint32_t offset); +``` + +vectors are PQ encoded and not expanded to one code per byte. The list is identified by its label. NB: no memory allocation happens here; the list into which the vectors are packed must fit offset + n_rows rows. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resource | +| `index` | inout | `index*` | pointer to IVF-PQ index | +| `codes` | in | `uint8_t*` | flat contiguous PQ codes [n_rows, ceildiv(pq_dim * pq_bits, 8)] | +| `n_rows` | in | `uint32_t` | how many records to pack | +| `label` | in | `uint32_t` | The id of the list (cluster) into which we write. | +| `offset` | in | `uint32_t` | how many records to skip before writing the data into the list | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:2779`_ + +### codepacker::unpack_list_data + +Unpack `n_take` consecutive records of a single list (cluster) in the compressed index + +```cpp +void unpack_list_data(raft::resources const& res, +const index& index, +raft::device_matrix_view out_codes, +uint32_t label, +uint32_t offset); +``` + +starting at given `offset`, one code per byte (independently of pq_bits). Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | | +| `index` | in | `const index&` | | +| `out_codes` | out | `raft::device_matrix_view` | the destination buffer [n_take, index.pq_dim()]. The length `n_take` defines how many records to unpack, it must be smaller than the list size. | +| `label` | in | `uint32_t` | The id of the list (cluster) to decode. | +| `offset` | in | `uint32_t` | How many records in the list to skip. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:2815`_ + +### codepacker::unpack_list_data + +Unpack a series of records of a single list (cluster) in the compressed index + +```cpp +void unpack_list_data(raft::resources const& res, +const index& index, +raft::device_vector_view in_cluster_indices, +raft::device_matrix_view out_codes, +uint32_t label); +``` + +by their in-list offsets, one code per byte (independently of pq_bits). Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resource | +| `index` | in | `const index&` | IVF-PQ index (passed by reference) | +| `in_cluster_indices` | in | `raft::device_vector_view` | The offsets of the selected indices within the cluster. | +| `out_codes` | out | `raft::device_matrix_view` | the destination buffer [n_take, index.pq_dim()]. The length `n_take` defines how many records to unpack, it must be smaller than the list size. | +| `label` | in | `uint32_t` | The id of the list (cluster) to decode. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:2851`_ + +### codepacker::unpack_contiguous_list_data + +Unpack `n_rows` consecutive PQ encoded vectors of a single list (cluster) in the + +```cpp +void unpack_contiguous_list_data(raft::resources const& res, +const index& index, +uint8_t* out_codes, +uint32_t n_rows, +uint32_t label, +uint32_t offset); +``` + +compressed index starting at given `offset`, not expanded to one code per byte. Each code in the output buffer occupies ceildiv(index.pq_dim() * index.pq_bits(), 8) bytes. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resource | +| `index` | in | `const index&` | IVF-PQ index (passed by reference) | +| `out_codes` | out | `uint8_t*` | the destination buffer [n_rows, ceildiv(index.pq_dim() * index.pq_bits(), 8)]. The length `n_rows` defines how many records to unpack, offset + n_rows must be smaller than or equal to the list size. | +| `n_rows` | in | `uint32_t` | how many codes to unpack | +| `label` | in | `uint32_t` | The id of the list (cluster) to decode. | +| `offset` | in | `uint32_t` | How many records in the list to skip. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:2892`_ + +### codepacker::reconstruct_list_data + +Decode `n_take` consecutive records of a single list (cluster) in the compressed index + +```cpp +void reconstruct_list_data(raft::resources const& res, +const index& index, +raft::device_matrix_view out_vectors, +uint32_t label, +uint32_t offset); +``` + +starting at given `offset`. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | | +| `index` | in | `const index&` | | +| `out_vectors` | out | `raft::device_matrix_view` | the destination buffer [n_take, index.dim()]. The length `n_take` defines how many records to reconstruct, it must be smaller than the list size. | +| `label` | in | `uint32_t` | The id of the list (cluster) to decode. | +| `offset` | in | `uint32_t` | How many records in the list to skip. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:2929`_ + +### codepacker::reconstruct_list_data + +Decode a series of records of a single list (cluster) in the compressed index + +```cpp +void reconstruct_list_data(raft::resources const& res, +const index& index, +raft::device_vector_view in_cluster_indices, +raft::device_matrix_view out_vectors, +uint32_t label); +``` + +by their in-list offsets. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | | +| `index` | in | `const index&` | | +| `in_cluster_indices` | in | `raft::device_vector_view` | The offsets of the selected indices within the cluster. | +| `out_vectors` | out | `raft::device_matrix_view` | the destination buffer [n_take, index.dim()]. The length `n_take` defines how many records to reconstruct, it must be smaller than the list size. | +| `label` | in | `uint32_t` | The id of the list (cluster) to decode. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:2984`_ + +### codepacker::extend_list_with_codes + +Extend one list of the index in-place, by the list label, skipping the classification and + +```cpp +void extend_list_with_codes( +raft::resources const& res, +index* index, +raft::device_matrix_view new_codes, +raft::device_vector_view new_indices, +uint32_t label); +``` + +encoding steps. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | | +| `index` | inout | `index*` | | +| `new_codes` | in | `raft::device_matrix_view` | flat PQ codes, one code per byte [n_rows, index.pq_dim()] | +| `new_indices` | in | `raft::device_vector_view` | source indices [n_rows] | +| `label` | in | `uint32_t` | the id of the target list (cluster). | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:3032`_ + +### codepacker::extend_list_with_contiguous_codes + +Extend one list of the index in-place, by the list label, skipping the classification and + +```cpp +void extend_list_with_contiguous_codes( +raft::resources const& res, +index* index, +raft::device_matrix_view new_codes, +raft::device_vector_view new_indices, +uint32_t label); +``` + +encoding steps. Uses contiguous/packed codes format. This is similar to extend_list_with_codes but takes codes in contiguous packed format [n_rows, ceildiv(pq_dim * pq_bits, 8)] instead of unpacked format [n_rows, pq_dim]. This works correctly with any pq_bits value. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | | +| `index` | inout | `index*` | | +| `new_codes` | in | `raft::device_matrix_view` | flat contiguous PQ codes [n_rows, ceildiv(pq_dim * pq_bits, 8)] | +| `new_indices` | in | `raft::device_vector_view` | source indices [n_rows] | +| `label` | in | `uint32_t` | the id of the target list (cluster). | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:3071`_ + +### codepacker::extend_list + +Extend one list of the index in-place, by the list label, skipping the classification + +```cpp +void extend_list(raft::resources const& res, +index* index, +raft::device_matrix_view new_vectors, +raft::device_vector_view new_indices, +uint32_t label); +``` + +step. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | | +| `index` | inout | `index*` | | +| `new_vectors` | in | `raft::device_matrix_view` | data to encode [n_rows, index.dim()] | +| `new_indices` | in | `raft::device_vector_view` | source indices [n_rows] | +| `label` | in | `uint32_t` | the id of the target list (cluster). | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:3106`_ + +### codepacker::erase_list + +Remove all data from a single list (cluster) in the index. + +```cpp +void erase_list(raft::resources const& res, index* index, uint32_t label); +``` + +Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | | +| `index` | inout | `index*` | | +| `label` | in | `uint32_t` | the id of the target list (cluster). | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:3141`_ + +### codepacker::reset_index + +Public helper API to reset the data and indices ptrs, and the list sizes. Useful for + +```cpp +void reset_index(const raft::resources& res, index* index); +``` + +externally modifying the index without going through the build stage. The data and indices of the IVF lists will be lost. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `const raft::resources&` | raft resource | +| `index` | inout | `index*` | pointer to IVF-PQ index | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:3163`_ + +### codepacker::pad_centers_with_norms + +Pad cluster centers with their L2 norms for efficient GEMM operations. + +```cpp +void pad_centers_with_norms( +raft::resources const& res, +raft::device_matrix_view centers, +raft::device_matrix_view padded_centers); +``` + +This function takes cluster centers and pads them with their L2 norms to create extended centers suitable for coarse search operations. The output has dimensions [n_centers, dim_ext] where dim_ext = round_up(dim + 1, 8). + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resource | +| `centers` | in | `raft::device_matrix_view` | cluster centers [n_centers, dim] | +| `padded_centers` | out | `raft::device_matrix_view` | padded centers with norms [n_centers, dim_ext] | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:3176`_ + +### codepacker::pad_centers_with_norms + +Pad cluster centers with their L2 norms for efficient GEMM operations. + +```cpp +void pad_centers_with_norms( +raft::resources const& res, +raft::host_matrix_view centers, +raft::device_matrix_view padded_centers); +``` + +This function takes cluster centers and pads them with their L2 norms to create extended centers suitable for coarse search operations. The output has dimensions [n_centers, dim_ext] where dim_ext = round_up(dim + 1, 8). + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resource | +| `centers` | in | `raft::host_matrix_view` | cluster centers [n_centers, dim] | +| `padded_centers` | out | `raft::device_matrix_view` | padded centers with norms [n_centers, dim_ext] | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:3192`_ + +### codepacker::rotate_padded_centers + +Rotate padded centers with the rotation matrix. + +```cpp +void rotate_padded_centers( +raft::resources const& res, +raft::device_matrix_view padded_centers, +raft::device_matrix_view rotation_matrix, +raft::device_matrix_view rotated_centers); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resource | +| `padded_centers` | in | `raft::device_matrix_view` | padded centers [n_centers, dim_ext] | +| `rotation_matrix` | in | `raft::device_matrix_view` | rotation matrix [rot_dim, dim] | +| `rotated_centers` | out | `raft::device_matrix_view` | rotated centers [n_centers, rot_dim] | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:3205`_ + +### codepacker::extract_centers + +Public helper API for fetching a trained index's IVF centroids + +```cpp +void extract_centers(raft::resources const& res, +const index& index, +raft::device_matrix_view cluster_centers); +``` + +Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resource | +| `index` | in | `const index&` | IVF-PQ index (passed by reference) | +| `cluster_centers` | out | `raft::device_matrix_view` | IVF cluster centers [index.n_lists(), index.dim] | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:3228`_ + +### codepacker::extract_centers + +```cpp +void extract_centers(raft::resources const& res, +const index& index, +raft::host_matrix_view cluster_centers); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | | `raft::resources const&` | | +| `index` | | `const index&` | | +| `cluster_centers` | | `raft::host_matrix_view` | | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:3233`_ + +### codepacker::recompute_internal_state + +Helper exposing the re-computation of list sizes and related arrays if IVF lists have been + +```cpp +void recompute_internal_state(const raft::resources& res, index* index); +``` + +modified externally. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `const raft::resources&` | raft resource | +| `index` | inout | `index*` | pointer to IVF-PQ index | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:3262`_ + +### codepacker::make_rotation_matrix + +Generate a rotation matrix into user-provided buffer (standalone version). + +```cpp +void make_rotation_matrix( +raft::resources const& res, +raft::device_matrix_view rotation_matrix, +bool force_random_rotation); +``` + +This standalone helper generates a rotation matrix without requiring an index object. Users can call this to prepare a rotation matrix before building from precomputed data. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resource | +| `rotation_matrix` | out | `raft::device_matrix_view` | Output buffer [rot_dim, dim] for the rotation matrix | +| `force_random_rotation` | in | `bool` | If false and rot_dim == dim, creates identity matrix. If true or rot_dim != dim, creates random orthogonal matrix. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:3289`_ + +### codepacker::resize_list + +Resize an IVF-PQ list with flat layout. + +```cpp +void resize_list(raft::resources const& res, +std::shared_ptr>& orig_list, +const list_spec_flat& spec, +uint32_t new_used_size, +uint32_t old_used_size); +``` + +This helper resizes an IVF list that uses the flat (non-interleaved) PQ code layout. If the new size exceeds the current capacity, a new list is allocated and existing data is copied. The function handles the type casting internally. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resource | +| `orig_list` | inout | `std::shared_ptr>&` | the list to resize (may be replaced with a new allocation) | +| `spec` | in | `const list_spec_flat&` | the list specification containing pq_bits, pq_dim, and allocation settings | +| `new_used_size` | in | `uint32_t` | the new size of the list (number of vectors) | +| `old_used_size` | in | `uint32_t` | the current size of the list (data up to this size is preserved) | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:3319`_ + +### codepacker::resize_list + +Resize an IVF-PQ list with interleaved layout. + +```cpp +void resize_list(raft::resources const& res, +std::shared_ptr>& orig_list, +const list_spec_interleaved& spec, +uint32_t new_used_size, +uint32_t old_used_size); +``` + +This helper resizes an IVF list that uses the interleaved PQ code layout (default). If the new size exceeds the current capacity, a new list is allocated and existing data is copied. The function handles the type casting internally. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resource | +| `orig_list` | inout | `std::shared_ptr>&` | the list to resize (may be replaced with a new allocation) | +| `spec` | in | `const list_spec_interleaved&` | the list specification containing pq_bits, pq_dim, and allocation settings | +| `new_used_size` | in | `uint32_t` | the new size of the list (number of vectors) | +| `old_used_size` | in | `uint32_t` | the current size of the list (data up to this size is preserved) | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:3350`_ diff --git a/fern/pages/cpp_api/cpp-api-neighbors-nn-descent.md b/fern/pages/cpp_api/cpp-api-neighbors-nn-descent.md new file mode 100644 index 0000000000..5a9827d645 --- /dev/null +++ b/fern/pages/cpp_api/cpp-api-neighbors-nn-descent.md @@ -0,0 +1,494 @@ +--- +slug: api-reference/cpp-api-neighbors-nn-descent +--- + +# NN Descent + +_Source header: `cpp/include/cuvs/neighbors/nn_descent.hpp`_ + +## The nn-descent algorithm parameters. + +_Doxygen group: `nn_descent_cpp_index_params`_ + +### cuvs::neighbors::nn_descent::DIST_COMP_DTYPE + +Dtype to use for distance computation + +- `AUTO`: Automatically determine the best dtype for distance computation based on the dataset dimensions. - `FP32`: Use fp32 distance computation for better precision at the cost of performance and memory usage. - `FP16`: Use fp16 distance computation. + +```cpp +enum class DIST_COMP_DTYPE { ... } ; +``` + +**Values** + +| Name | Value | +| --- | --- | +| `AUTO` | `0` | +| `FP32` | `1` | +| `FP16` | `2` | + +_Source: `cpp/include/cuvs/neighbors/nn_descent.hpp:35`_ + +### cuvs::neighbors::nn_descent::index_params + +Parameters used to build an nn-descent index + +- `graph_degree`: For an input dataset of dimensions (N, D), determines the final dimensions of the all-neighbors knn graph which turns out to be of dimensions (N, graph_degree) - `intermediate_graph_degree`: Internally, nn-descent builds an all-neighbors knn graph of dimensions (N, intermediate_graph_degree) before selecting the final `graph_degree` neighbors. It's recommended that `intermediate_graph_degree` >= 1.5 * graph_degree - `max_iterations`: The number of iterations that nn-descent will refine the graph for. More iterations produce a better quality graph at cost of performance - `termination_threshold`: The delta at which nn-descent will terminate its iterations - `return_distances`: Boolean to decide whether to return distances array - `dist_comp_dtype`: dtype to use for distance computation. Defaults to `AUTO` which automatically determines the best dtype for distance computation based on the dataset dimensions. Use `FP32` for better precision at the cost of performance and memory usage. This option is only valid when data type is fp32. Use `FP16` for better performance and memory usage at the cost of precision. + +```cpp +struct index_params : cuvs::neighbors::index_params { ... } ; +``` + +**Fields** + +| Name | Type | Description | +| --- | --- | --- | +| `index_params` | `index_params(size_t` | Construct NN descent parameters for a specific kNN graph degree | +| `graph_degree` | `size_t` | | +| `intermediate_graph_degree` | `size_t` | | +| `max_iterations` | `size_t` | | +| `termination_threshold` | `float` | | +| `return_distances` | `bool` | | +| `dist_comp_dtype` | `DIST_COMP_DTYPE` | | + +_Source: `cpp/include/cuvs/neighbors/nn_descent.hpp:56`_ + +### cuvs::neighbors::nn_descent::index_params + +Construct NN descent parameters for a specific kNN graph degree + +```cpp +index_params(size_t graph_degree = 64, +cuvs::distance::DistanceType metric = cuvs::distance::DistanceType::L2Expanded); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `graph_degree` | | `size_t` | output graph degree Default: `64`. | +| `metric` | | `cuvs::distance::DistanceType` | distance metric to use Default: `cuvs::distance::DistanceType::L2Expanded`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/nn_descent.hpp:69`_ + +## nn-descent index + +_Doxygen group: `nn_descent_cpp_index`_ + +### cuvs::neighbors::nn_descent::index + +Construct a new index object + +```cpp +index(raft::resources const& res, +int64_t n_rows, +int64_t n_cols, +bool return_distances = false, +cuvs::distance::DistanceType metric = cuvs::distance::DistanceType::L2Expanded) +: cuvs::neighbors::index(), +``` + +This constructor creates an nn-descent index which is a knn-graph in host memory. The type of the knn-graph is a dense raft::host_matrix and dimensions are (n_rows, n_cols). + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | | `raft::resources const&` | raft::resources is an object managing resources | +| `n_rows` | | `int64_t` | number of rows in knn-graph | +| `n_cols` | | `int64_t` | number of cols in knn-graph | +| `return_distances` | | `bool` | whether to return distances Default: `false`. | +| `metric` | | `cuvs::distance::DistanceType` | distance metric to use Default: `cuvs::distance::DistanceType::L2Expanded`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/nn_descent.hpp:110`_ + +### cuvs::neighbors::nn_descent::index + +Construct a new index object + +```cpp +index(raft::resources const& res, +raft::host_matrix_view graph_view, +std::optional> distances_view = +std::nullopt, +cuvs::distance::DistanceType metric = cuvs::distance::DistanceType::L2Expanded) +: cuvs::neighbors::index(), +``` + +This constructor creates an nn-descent index using a user allocated host memory knn-graph. The type of the knn-graph is a dense raft::host_matrix and dimensions are (n_rows, n_cols). distances + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | | `raft::resources const&` | raft::resources is an object managing resources | +| `graph_view` | | `raft::host_matrix_view` | raft::host_matrix_view<IdxT, int64_t, raft::row_major> for storing knn-graph | +| `distances_view` | | `std::optional>` | optional raft::device_matrix_view<float, int64_t, row_major> for storing Default: `std::nullopt`. | +| `metric` | | `cuvs::distance::DistanceType` | distance metric to use Default: `cuvs::distance::DistanceType::L2Expanded`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/nn_descent.hpp:141`_ + +### cuvs::neighbors::nn_descent::metric + +Distance metric used for clustering. + +```cpp +[[nodiscard]] constexpr inline auto metric() const noexcept -> cuvs::distance::DistanceType; +``` + +**Returns** + +`cuvs::distance::DistanceType` + +_Source: `cpp/include/cuvs/neighbors/nn_descent.hpp:157`_ + +### cuvs::neighbors::nn_descent::size + +Total length of the index (number of vectors). + +```cpp +[[nodiscard]] constexpr inline auto size() const noexcept -> IdxT; +``` + +**Returns** + +`IdxT` + +_Source: `cpp/include/cuvs/neighbors/nn_descent.hpp:163`_ + +### cuvs::neighbors::nn_descent::graph_degree + +Graph degree + +```cpp +[[nodiscard]] constexpr inline auto graph_degree() const noexcept -> uint32_t; +``` + +**Returns** + +`uint32_t` + +_Source: `cpp/include/cuvs/neighbors/nn_descent.hpp:169`_ + +### cuvs::neighbors::nn_descent::graph + +neighborhood graph [size, graph-degree] + +```cpp +[[nodiscard]] inline auto graph() noexcept +-> raft::host_matrix_view; +``` + +**Returns** + +`raft::host_matrix_view` + +_Source: `cpp/include/cuvs/neighbors/nn_descent.hpp:175`_ + +### cuvs::neighbors::nn_descent::distances + +neighborhood graph distances [size, graph-degree] + +```cpp +[[nodiscard]] inline auto distances() noexcept +-> std::optional>; +``` + +**Returns** + +`std::optional>` + +_Source: `cpp/include/cuvs/neighbors/nn_descent.hpp:182`_ + +## nn-descent index build + +_Doxygen group: `nn_descent_cpp_index_build`_ + +### cuvs::neighbors::nn_descent::build + +Build nn-descent Index with dataset in device memory + +```cpp +auto build(raft::resources const& res, +index_params const& params, +raft::device_matrix_view dataset, +std::optional> graph = +std::nullopt) -> cuvs::neighbors::nn_descent::index; +``` + +The following distance metrics are supported: - L2Expanded - L2SqrtExpanded - CosineExpanded - InnerProduct - L1 Usage example: the output graph + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft::resources is an object managing resources | +| `params` | in | `index_params const&` | an instance of nn_descent::index_params that are parameters to run the nn-descent algorithm | +| `dataset` | in | `raft::device_matrix_view` | raft::device_matrix_view input dataset expected to be located in device memory | +| `graph` | in | `std::optional>` | optional raft::host_matrix_view<uint32_t, int64_t, raft::row_major> for owning Default: `std::nullopt`. | + +**Returns** + +`cuvs::neighbors::nn_descent::index` + +index<IdxT> index containing all-neighbors knn graph in host memory + +_Source: `cpp/include/cuvs/neighbors/nn_descent.hpp:244`_ + +### cuvs::neighbors::nn_descent::build + +Build nn-descent Index with dataset in host memory + +```cpp +auto build(raft::resources const& res, +index_params const& params, +raft::host_matrix_view dataset, +std::optional> graph = +std::nullopt) -> cuvs::neighbors::nn_descent::index; +``` + +The following distance metrics are supported: - L2Expanded - L2SqrtExpanded - CosineExpanded - InnerProduct - L1 Usage example: the output graph + +**Template Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `T` | `` | data-type of the input dataset | +| `IdxT` | `` | data-type for the output index | + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | | `raft::resources const&` | raft::resources is an object managing resources | +| `params` | in | `index_params const&` | an instance of nn_descent::index_params that are parameters to run the nn-descent algorithm | +| `dataset` | in | `raft::host_matrix_view` | raft::host_matrix_view input dataset expected to be located in host memory | +| `graph` | in | `std::optional>` | optional raft::host_matrix_view<uint32_t, int64_t, raft::row_major> for owning Default: `std::nullopt`. | + +**Returns** + +`cuvs::neighbors::nn_descent::index` + +index<IdxT> index containing all-neighbors knn graph in host memory + +_Source: `cpp/include/cuvs/neighbors/nn_descent.hpp:283`_ + +### cuvs::neighbors::nn_descent::build + +Build nn-descent Index with dataset in device memory + +```cpp +auto build(raft::resources const& res, +index_params const& params, +raft::device_matrix_view dataset, +std::optional> graph = +std::nullopt) -> cuvs::neighbors::nn_descent::index; +``` + +The following distance metrics are supported: - L2Expanded - L2SqrtExpanded - CosineExpanded - InnerProduct - L1 Usage example: the output graph + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft::resources is an object managing resources | +| `params` | in | `index_params const&` | an instance of nn_descent::index_params that are parameters to run the nn-descent algorithm | +| `dataset` | in | `raft::device_matrix_view` | raft::device_matrix_view input dataset expected to be located in device memory | +| `graph` | in | `std::optional>` | optional raft::host_matrix_view<uint32_t, int64_t, raft::row_major> for owning Default: `std::nullopt`. | + +**Returns** + +`cuvs::neighbors::nn_descent::index` + +index<IdxT> index containing all-neighbors knn graph in host memory + +_Source: `cpp/include/cuvs/neighbors/nn_descent.hpp:320`_ + +### cuvs::neighbors::nn_descent::build + +Build nn-descent Index with dataset in host memory + +```cpp +auto build(raft::resources const& res, +index_params const& params, +raft::host_matrix_view dataset, +std::optional> graph = +std::nullopt) -> cuvs::neighbors::nn_descent::index; +``` + +The following distance metrics are supported: - L2Expanded - L2SqrtExpanded - CosineExpanded - InnerProduct - L1 Usage example: the output graph + +**Template Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `T` | `` | data-type of the input dataset | +| `IdxT` | `` | data-type for the output index | + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | | `raft::resources const&` | raft::resources is an object managing resources | +| `params` | in | `index_params const&` | an instance of nn_descent::index_params that are parameters to run the nn-descent algorithm | +| `dataset` | in | `raft::host_matrix_view` | raft::host_matrix_view input dataset expected to be located in host memory | +| `graph` | in | `std::optional>` | optional raft::host_matrix_view<uint32_t, int64_t, raft::row_major> for owning Default: `std::nullopt`. | + +**Returns** + +`cuvs::neighbors::nn_descent::index` + +index<IdxT> index containing all-neighbors knn graph in host memory + +_Source: `cpp/include/cuvs/neighbors/nn_descent.hpp:359`_ + +### cuvs::neighbors::nn_descent::build + +Build nn-descent Index with dataset in device memory + +```cpp +auto build(raft::resources const& res, +index_params const& params, +raft::device_matrix_view dataset, +std::optional> graph = +std::nullopt) -> cuvs::neighbors::nn_descent::index; +``` + +The following distance metrics are supported: - L2Expanded - L2SqrtExpanded - CosineExpanded - InnerProduct - L1 - BitwiseHamming Usage example: the output graph + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft::resources is an object managing resources | +| `params` | in | `index_params const&` | an instance of nn_descent::index_params that are parameters to run the nn-descent algorithm | +| `dataset` | in | `raft::device_matrix_view` | raft::device_matrix_view input dataset expected to be located in device memory | +| `graph` | in | `std::optional>` | optional raft::host_matrix_view<uint32_t, int64_t, raft::row_major> for owning Default: `std::nullopt`. | + +**Returns** + +`cuvs::neighbors::nn_descent::index` + +index<IdxT> index containing all-neighbors knn graph in host memory + +_Source: `cpp/include/cuvs/neighbors/nn_descent.hpp:397`_ + +### cuvs::neighbors::nn_descent::build + +Build nn-descent Index with dataset in host memory + +```cpp +auto build(raft::resources const& res, +index_params const& params, +raft::host_matrix_view dataset, +std::optional> graph = +std::nullopt) -> cuvs::neighbors::nn_descent::index; +``` + +The following distance metrics are supported: - L2Expanded - L2SqrtExpanded - CosineExpanded - InnerProduct - L1 - BitwiseHamming Usage example: the output graph + +**Template Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `T` | `` | data-type of the input dataset | +| `IdxT` | `` | data-type for the output index | + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | | `raft::resources const&` | raft::resources is an object managing resources | +| `params` | in | `index_params const&` | an instance of nn_descent::index_params that are parameters to run the nn-descent algorithm | +| `dataset` | in | `raft::host_matrix_view` | raft::host_matrix_view input dataset expected to be located in host memory | +| `graph` | in | `std::optional>` | optional raft::host_matrix_view<uint32_t, int64_t, raft::row_major> for owning Default: `std::nullopt`. | + +**Returns** + +`cuvs::neighbors::nn_descent::index` + +index<IdxT> index containing all-neighbors knn graph in host memory + +_Source: `cpp/include/cuvs/neighbors/nn_descent.hpp:437`_ + +### cuvs::neighbors::nn_descent::build + +Build nn-descent Index with dataset in device memory + +```cpp +auto build(raft::resources const& res, +index_params const& params, +raft::device_matrix_view dataset, +std::optional> graph = +std::nullopt) -> cuvs::neighbors::nn_descent::index; +``` + +The following distance metrics are supported: - L2Expanded - L2SqrtExpanded - CosineExpanded - InnerProduct - L1 - BitwiseHamming Usage example: the output graph + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft::resources is an object managing resources | +| `params` | in | `index_params const&` | an instance of nn_descent::index_params that are parameters to run the nn-descent algorithm | +| `dataset` | in | `raft::device_matrix_view` | raft::device_matrix_view input dataset expected to be located in device memory | +| `graph` | in | `std::optional>` | optional raft::host_matrix_view<uint32_t, int64_t, raft::row_major> for owning Default: `std::nullopt`. | + +**Returns** + +`cuvs::neighbors::nn_descent::index` + +index<IdxT> index containing all-neighbors knn graph in host memory + +_Source: `cpp/include/cuvs/neighbors/nn_descent.hpp:475`_ + +### cuvs::neighbors::nn_descent::build + +Build nn-descent Index with dataset in host memory + +```cpp +auto build(raft::resources const& res, +index_params const& params, +raft::host_matrix_view dataset, +std::optional> graph = +std::nullopt) -> cuvs::neighbors::nn_descent::index; +``` + +The following distance metrics are supported: - L2Expanded - L2SqrtExpanded - CosineExpanded - InnerProduct - L1 - BitwiseHamming Usage example: the output graph + +**Template Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `T` | `` | data-type of the input dataset | +| `IdxT` | `` | data-type for the output index | + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | | `raft::resources const&` | raft::resources is an object managing resources | +| `params` | in | `index_params const&` | an instance of nn_descent::index_params that are parameters to run the nn-descent algorithm | +| `dataset` | in | `raft::host_matrix_view` | raft::host_matrix_view input dataset expected to be located in host memory | +| `graph` | in | `std::optional>` | optional raft::host_matrix_view<uint32_t, int64_t, raft::row_major> for owning Default: `std::nullopt`. | + +**Returns** + +`cuvs::neighbors::nn_descent::index` + +index<IdxT> index containing all-neighbors knn graph in host memory + +_Source: `cpp/include/cuvs/neighbors/nn_descent.hpp:515`_ diff --git a/fern/pages/cpp_api/cpp-api-neighbors-refine.md b/fern/pages/cpp_api/cpp-api-neighbors-refine.md new file mode 100644 index 0000000000..1b1cd3cc60 --- /dev/null +++ b/fern/pages/cpp_api/cpp-api-neighbors-refine.md @@ -0,0 +1,351 @@ +--- +slug: api-reference/cpp-api-neighbors-refine +--- + +# Refine + +_Source header: `cpp/include/cuvs/neighbors/refine.hpp`_ + +## Approximate Nearest Neighbors Refinement + +_Doxygen group: `ann_refine`_ + +### cuvs::neighbors::refine + +Refine nearest neighbor search. + +```cpp +void refine(raft::resources const& handle, +raft::device_matrix_view dataset, +raft::device_matrix_view queries, +raft::device_matrix_view neighbor_candidates, +raft::device_matrix_view indices, +raft::device_matrix_view distances, +cuvs::distance::DistanceType metric = cuvs::distance::DistanceType::L2Unexpanded); +``` + +Refinement is an operation that follows an approximate NN search. The approximate search has already selected n_candidates neighbor candidates for each query. We narrow it down to k neighbors. For each query, we calculate the exact distance between the query and its n_candidates neighbor candidate, and select the k nearest ones. The k nearest neighbors and distances are returned. Example usage + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | the raft handle | +| `dataset` | in | `raft::device_matrix_view` | device matrix that stores the dataset [n_rows, dims] | +| `queries` | in | `raft::device_matrix_view` | device matrix of the queries [n_queris, dims] | +| `neighbor_candidates` | in | `raft::device_matrix_view` | indices of candidate vectors [n_queries, n_candidates], where n_candidates >= k | +| `indices` | out | `raft::device_matrix_view` | device matrix that stores the refined indices [n_queries, k] | +| `distances` | out | `raft::device_matrix_view` | device matrix that stores the refined distances [n_queries, k] | +| `metric` | in | `cuvs::distance::DistanceType` | distance metric to use. Euclidean (L2) is used by default Default: `cuvs::distance::DistanceType::L2Unexpanded`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/refine.hpp:60`_ + +### cuvs::neighbors::refine + +Refine nearest neighbor search. + +```cpp +void refine(raft::resources const& handle, +raft::device_matrix_view dataset, +raft::device_matrix_view queries, +raft::device_matrix_view neighbor_candidates, +raft::device_matrix_view indices, +raft::device_matrix_view distances, +cuvs::distance::DistanceType metric = cuvs::distance::DistanceType::L2Unexpanded); +``` + +Refinement is an operation that follows an approximate NN search. The approximate search has already selected n_candidates neighbor candidates for each query. We narrow it down to k neighbors. For each query, we calculate the exact distance between the query and its n_candidates neighbor candidate, and select the k nearest ones. The k nearest neighbors and distances are returned. Example usage + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | the raft handle | +| `dataset` | in | `raft::device_matrix_view` | device matrix that stores the dataset [n_rows, dims] | +| `queries` | in | `raft::device_matrix_view` | device matrix of the queries [n_queris, dims] | +| `neighbor_candidates` | in | `raft::device_matrix_view` | indices of candidate vectors [n_queries, n_candidates], where n_candidates >= k | +| `indices` | out | `raft::device_matrix_view` | device matrix that stores the refined indices [n_queries, k] | +| `distances` | out | `raft::device_matrix_view` | device matrix that stores the refined distances [n_queries, k] | +| `metric` | in | `cuvs::distance::DistanceType` | distance metric to use. Euclidean (L2) is used by default Default: `cuvs::distance::DistanceType::L2Unexpanded`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/refine.hpp:105`_ + +### cuvs::neighbors::refine + +Refine nearest neighbor search. + +```cpp +void refine(raft::resources const& handle, +raft::device_matrix_view dataset, +raft::device_matrix_view queries, +raft::device_matrix_view neighbor_candidates, +raft::device_matrix_view indices, +raft::device_matrix_view distances, +cuvs::distance::DistanceType metric = cuvs::distance::DistanceType::L2Unexpanded); +``` + +Refinement is an operation that follows an approximate NN search. The approximate search has already selected n_candidates neighbor candidates for each query. We narrow it down to k neighbors. For each query, we calculate the exact distance between the query and its n_candidates neighbor candidate, and select the k nearest ones. The k nearest neighbors and distances are returned. Example usage + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | the raft handle | +| `dataset` | in | `raft::device_matrix_view` | device matrix that stores the dataset [n_rows, dims] | +| `queries` | in | `raft::device_matrix_view` | device matrix of the queries [n_queris, dims] | +| `neighbor_candidates` | in | `raft::device_matrix_view` | indices of candidate vectors [n_queries, n_candidates], where n_candidates >= k | +| `indices` | out | `raft::device_matrix_view` | device matrix that stores the refined indices [n_queries, k] | +| `distances` | out | `raft::device_matrix_view` | device matrix that stores the refined distances [n_queries, k] | +| `metric` | in | `cuvs::distance::DistanceType` | distance metric to use. Euclidean (L2) is used by default Default: `cuvs::distance::DistanceType::L2Unexpanded`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/refine.hpp:150`_ + +### cuvs::neighbors::refine + +Refine nearest neighbor search. + +```cpp +void refine(raft::resources const& handle, +raft::device_matrix_view dataset, +raft::device_matrix_view queries, +raft::device_matrix_view neighbor_candidates, +raft::device_matrix_view indices, +raft::device_matrix_view distances, +cuvs::distance::DistanceType metric = cuvs::distance::DistanceType::L2Unexpanded); +``` + +Refinement is an operation that follows an approximate NN search. The approximate search has already selected n_candidates neighbor candidates for each query. We narrow it down to k neighbors. For each query, we calculate the exact distance between the query and its n_candidates neighbor candidate, and select the k nearest ones. The k nearest neighbors and distances are returned. Example usage + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | the raft handle | +| `dataset` | in | `raft::device_matrix_view` | device matrix that stores the dataset [n_rows, dims] | +| `queries` | in | `raft::device_matrix_view` | device matrix of the queries [n_queris, dims] | +| `neighbor_candidates` | in | `raft::device_matrix_view` | indices of candidate vectors [n_queries, n_candidates], where n_candidates >= k | +| `indices` | out | `raft::device_matrix_view` | device matrix that stores the refined indices [n_queries, k] | +| `distances` | out | `raft::device_matrix_view` | device matrix that stores the refined distances [n_queries, k] | +| `metric` | in | `cuvs::distance::DistanceType` | distance metric to use. Euclidean (L2) is used by default Default: `cuvs::distance::DistanceType::L2Unexpanded`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/refine.hpp:195`_ + +### cuvs::neighbors::refine + +Refine nearest neighbor search. + +```cpp +void refine(raft::resources const& handle, +raft::device_matrix_view dataset, +raft::device_matrix_view queries, +raft::device_matrix_view neighbor_candidates, +raft::device_matrix_view indices, +raft::device_matrix_view distances, +cuvs::distance::DistanceType metric = cuvs::distance::DistanceType::L2Unexpanded); +``` + +Refinement is an operation that follows an approximate NN search. The approximate search has already selected n_candidates neighbor candidates for each query. We narrow it down to k neighbors. For each query, we calculate the exact distance between the query and its n_candidates neighbor candidate, and select the k nearest ones. The k nearest neighbors and distances are returned. Example usage + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | the raft handle | +| `dataset` | in | `raft::device_matrix_view` | device matrix that stores the dataset [n_rows, dims] | +| `queries` | in | `raft::device_matrix_view` | device matrix of the queries [n_queris, dims] | +| `neighbor_candidates` | in | `raft::device_matrix_view` | indices of candidate vectors [n_queries, n_candidates], where n_candidates >= k | +| `indices` | out | `raft::device_matrix_view` | device matrix that stores the refined indices [n_queries, k] | +| `distances` | out | `raft::device_matrix_view` | device matrix that stores the refined distances [n_queries, k] | +| `metric` | in | `cuvs::distance::DistanceType` | distance metric to use. Euclidean (L2) is used by default Default: `cuvs::distance::DistanceType::L2Unexpanded`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/refine.hpp:240`_ + +### cuvs::neighbors::refine + +Refine nearest neighbor search. + +```cpp +void refine(raft::resources const& handle, +raft::host_matrix_view dataset, +raft::host_matrix_view queries, +raft::host_matrix_view neighbor_candidates, +raft::host_matrix_view indices, +raft::host_matrix_view distances, +cuvs::distance::DistanceType metric = cuvs::distance::DistanceType::L2Unexpanded); +``` + +Refinement is an operation that follows an approximate NN search. The approximate search has already selected n_candidates neighbor candidates for each query. We narrow it down to k neighbors. For each query, we calculate the exact distance between the query and its n_candidates neighbor candidate, and select the k nearest ones. The k nearest neighbors and distances are returned. Example usage + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | the raft handle | +| `dataset` | in | `raft::host_matrix_view` | host matrix that stores the dataset [n_rows, dims] | +| `queries` | in | `raft::host_matrix_view` | host matrix of the queries [n_queris, dims] | +| `neighbor_candidates` | in | `raft::host_matrix_view` | host matrix with indices of candidate vectors [n_queries, n_candidates], where n_candidates >= k | +| `indices` | out | `raft::host_matrix_view` | host matrix that stores the refined indices [n_queries, k] | +| `distances` | out | `raft::host_matrix_view` | host matrix that stores the refined distances [n_queries, k] | +| `metric` | in | `cuvs::distance::DistanceType` | distance metric to use. Euclidean (L2) is used by default Default: `cuvs::distance::DistanceType::L2Unexpanded`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/refine.hpp:285`_ + +### cuvs::neighbors::refine + +Refine nearest neighbor search. + +```cpp +void refine(raft::resources const& handle, +raft::host_matrix_view dataset, +raft::host_matrix_view queries, +raft::host_matrix_view neighbor_candidates, +raft::host_matrix_view indices, +raft::host_matrix_view distances, +cuvs::distance::DistanceType metric = cuvs::distance::DistanceType::L2Unexpanded); +``` + +Refinement is an operation that follows an approximate NN search. The approximate search has already selected n_candidates neighbor candidates for each query. We narrow it down to k neighbors. For each query, we calculate the exact distance between the query and its n_candidates neighbor candidate, and select the k nearest ones. The k nearest neighbors and distances are returned. Example usage + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | the raft handle | +| `dataset` | in | `raft::host_matrix_view` | host matrix that stores the dataset [n_rows, dims] | +| `queries` | in | `raft::host_matrix_view` | host matrix of the queries [n_queris, dims] | +| `neighbor_candidates` | in | `raft::host_matrix_view` | host matrix with indices of candidate vectors [n_queries, n_candidates], where n_candidates >= k | +| `indices` | out | `raft::host_matrix_view` | host matrix that stores the refined indices [n_queries, k] | +| `distances` | out | `raft::host_matrix_view` | host matrix that stores the refined distances [n_queries, k] | +| `metric` | in | `cuvs::distance::DistanceType` | distance metric to use. Euclidean (L2) is used by default Default: `cuvs::distance::DistanceType::L2Unexpanded`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/refine.hpp:330`_ + +### cuvs::neighbors::refine + +Refine nearest neighbor search. + +```cpp +void refine(raft::resources const& handle, +raft::host_matrix_view dataset, +raft::host_matrix_view queries, +raft::host_matrix_view neighbor_candidates, +raft::host_matrix_view indices, +raft::host_matrix_view distances, +cuvs::distance::DistanceType metric = cuvs::distance::DistanceType::L2Unexpanded); +``` + +Refinement is an operation that follows an approximate NN search. The approximate search has already selected n_candidates neighbor candidates for each query. We narrow it down to k neighbors. For each query, we calculate the exact distance between the query and its n_candidates neighbor candidate, and select the k nearest ones. The k nearest neighbors and distances are returned. Example usage + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | the raft handle | +| `dataset` | in | `raft::host_matrix_view` | host matrix that stores the dataset [n_rows, dims] | +| `queries` | in | `raft::host_matrix_view` | host matrix of the queries [n_queris, dims] | +| `neighbor_candidates` | in | `raft::host_matrix_view` | host matrix with indices of candidate vectors [n_queries, n_candidates], where n_candidates >= k | +| `indices` | out | `raft::host_matrix_view` | host matrix that stores the refined indices [n_queries, k] | +| `distances` | out | `raft::host_matrix_view` | host matrix that stores the refined distances [n_queries, k] | +| `metric` | in | `cuvs::distance::DistanceType` | distance metric to use. Euclidean (L2) is used by default Default: `cuvs::distance::DistanceType::L2Unexpanded`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/refine.hpp:375`_ + +### cuvs::neighbors::refine + +Refine nearest neighbor search. + +```cpp +void refine(raft::resources const& handle, +raft::host_matrix_view dataset, +raft::host_matrix_view queries, +raft::host_matrix_view neighbor_candidates, +raft::host_matrix_view indices, +raft::host_matrix_view distances, +cuvs::distance::DistanceType metric = cuvs::distance::DistanceType::L2Unexpanded); +``` + +Refinement is an operation that follows an approximate NN search. The approximate search has already selected n_candidates neighbor candidates for each query. We narrow it down to k neighbors. For each query, we calculate the exact distance between the query and its n_candidates neighbor candidate, and select the k nearest ones. The k nearest neighbors and distances are returned. Example usage + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | the raft handle | +| `dataset` | in | `raft::host_matrix_view` | host matrix that stores the dataset [n_rows, dims] | +| `queries` | in | `raft::host_matrix_view` | host matrix of the queries [n_queris, dims] | +| `neighbor_candidates` | in | `raft::host_matrix_view` | host matrix with indices of candidate vectors [n_queries, n_candidates], where n_candidates >= k | +| `indices` | out | `raft::host_matrix_view` | host matrix that stores the refined indices [n_queries, k] | +| `distances` | out | `raft::host_matrix_view` | host matrix that stores the refined distances [n_queries, k] | +| `metric` | in | `cuvs::distance::DistanceType` | distance metric to use. Euclidean (L2) is used by default Default: `cuvs::distance::DistanceType::L2Unexpanded`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/refine.hpp:420`_ + +### cuvs::neighbors::refine + +Refine nearest neighbor search. + +```cpp +void refine(raft::resources const& handle, +raft::host_matrix_view dataset, +raft::host_matrix_view queries, +raft::host_matrix_view neighbor_candidates, +raft::host_matrix_view indices, +raft::host_matrix_view distances, +cuvs::distance::DistanceType metric = cuvs::distance::DistanceType::L2Unexpanded); +``` + +Refinement is an operation that follows an approximate NN search. The approximate search has already selected n_candidates neighbor candidates for each query. We narrow it down to k neighbors. For each query, we calculate the exact distance between the query and its n_candidates neighbor candidate, and select the k nearest ones. The k nearest neighbors and distances are returned. Example usage + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | the raft handle | +| `dataset` | in | `raft::host_matrix_view` | host matrix that stores the dataset [n_rows, dims] | +| `queries` | in | `raft::host_matrix_view` | host matrix of the queries [n_queris, dims] | +| `neighbor_candidates` | in | `raft::host_matrix_view` | host matrix with indices of candidate vectors [n_queries, n_candidates], where n_candidates >= k | +| `indices` | out | `raft::host_matrix_view` | host matrix that stores the refined indices [n_queries, k] | +| `distances` | out | `raft::host_matrix_view` | host matrix that stores the refined distances [n_queries, k] | +| `metric` | in | `cuvs::distance::DistanceType` | distance metric to use. Euclidean (L2) is used by default Default: `cuvs::distance::DistanceType::L2Unexpanded`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/refine.hpp:465`_ diff --git a/fern/pages/cpp_api/cpp-api-neighbors-scann.md b/fern/pages/cpp_api/cpp-api-neighbors-scann.md new file mode 100644 index 0000000000..4d59c9d21f --- /dev/null +++ b/fern/pages/cpp_api/cpp-api-neighbors-scann.md @@ -0,0 +1,168 @@ +--- +slug: api-reference/cpp-api-neighbors-scann +--- + +# Scann + +_Source header: `cpp/include/cuvs/neighbors/scann.hpp`_ + +## ScaNN index build parameters + +_Doxygen group: `scann_cpp_index_params`_ + +### cuvs::neighbors::experimental::scann::index_params + +ANN parameters used by ScaNN to build index + +```cpp +struct index_params : cuvs::neighbors::index_params { ... } ; +``` + +**Fields** + +| Name | Type | Description | +| --- | --- | --- | +| `n_leaves` | `uint32_t` | the number of leaves in the tree * | +| `kmeans_n_rows_train` | `int64_t` | the number of rows for training the tree structures * | +| `kmeans_n_iters` | `uint32_t` | the max number of iterations for training the tree structure * | +| `partitioning_eta` | `float` | the value of eta for AVQ adjustment during partitioning * | +| `soar_lambda` | `float` | the value of lambda for SOAR spilling * | +| `pq_dim` | `uint32_t` | the dimension of pq subspaces (must divide dataset dimension)* | +| `pq_bits` | `uint32_t` | the number of bits for pq codes (must be 4 or 8, for 16 and 256 codes respectively) * | +| `pq_n_rows_train` | `int64_t` | the number of rows for PQ training (internally capped to 100k) * | +| `pq_train_iters` | `uint32_t` | the max number of iterations for PQ training * | +| `reordering_bf16` | `bool` | whether to apply bf16 quantization of dataset vectors * | +| `reordering_noise_shaping_threshold` | `float` | Threshold T for computing AVQ eta = (dim - 1) ( T^2 / \|\| x \|\|^2) / ( 1 - T^2 / \|\| x \|\|^2) | + +_Source: `cpp/include/cuvs/neighbors/scann.hpp:36`_ + +## ScaNN index type + +_Doxygen group: `scann_cpp_index`_ + +### cuvs::neighbors::experimental::scann::metric + +Distance metric used for clustering. + +```cpp +[[nodiscard]] constexpr inline auto metric() const noexcept -> cuvs::distance::DistanceType; +``` + +**Returns** + +`cuvs::distance::DistanceType` + +_Source: `cpp/include/cuvs/neighbors/scann.hpp:110`_ + +### cuvs::neighbors::experimental::scann::size + +Total length of the index (number of vectors). + +```cpp +IdxT size() const noexcept; +``` + +**Returns** + +`IdxT` + +_Source: `cpp/include/cuvs/neighbors/scann.hpp:116`_ + +### cuvs::neighbors::experimental::scann::dim + +Dimensionality of the data. + +```cpp +[[nodiscard]] constexpr inline auto dim() const noexcept -> uint32_t; +``` + +**Returns** + +`uint32_t` + +_Source: `cpp/include/cuvs/neighbors/scann.hpp:119`_ + +## ScaNN index build functions + +_Doxygen group: `scann_cpp_index_build`_ + +### cuvs::neighbors::experimental::scann::build + +Build the index from the dataset for efficient search. + +```cpp +auto build(raft::resources const& handle, +const cuvs::neighbors::experimental::scann::index_params& params, +raft::device_matrix_view dataset) +-> cuvs::neighbors::experimental::scann::index; +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | | `raft::resources const&` | | +| `params` | | `const cuvs::neighbors::experimental::scann::index_params&` | | +| `dataset` | | `raft::device_matrix_view` | | + +**Returns** + +`cuvs::neighbors::experimental::scann::index` + +_Source: `cpp/include/cuvs/neighbors/scann.hpp:291`_ + +### cuvs::neighbors::experimental::scann::serialize + +Save the index to files in a directory + +```cpp +void serialize(raft::resources const& handle, +const std::string& file_prefix, +const cuvs::neighbors::experimental::scann::index& index); +``` + +This serializes the index into a list of files for integration into OSS ScaNN for use with search NOTE: the implementation of ScaNN index build is EXPERIMENTAL and currently not subject to comprehensive, automated testing. Accuracy and performance are not guaranteed, and could diverge without warning. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | | `raft::resources const&` | | +| `file_prefix` | | `const std::string&` | | +| `index` | | `const cuvs::neighbors::experimental::scann::index&` | | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/scann.hpp:316`_ + +## ScaNN serialize functions + +_Doxygen group: `scann_cpp_serialize`_ + +### cuvs::neighbors::experimental::scann::serialize + +Save the index to files in a directory + +```cpp +void serialize(raft::resources const& handle, +const std::string& file_prefix, +const cuvs::neighbors::experimental::scann::index& index); +``` + +This serializes the index into a list of files for integration into OSS ScaNN for use with search NOTE: the implementation of ScaNN index build is EXPERIMENTAL and currently not subject to comprehensive, automated testing. Accuracy and performance are not guaranteed, and could diverge without warning. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | | `raft::resources const&` | | +| `file_prefix` | | `const std::string&` | | +| `index` | | `const cuvs::neighbors::experimental::scann::index&` | | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/scann.hpp:316`_ diff --git a/fern/pages/cpp_api/cpp-api-neighbors-vamana.md b/fern/pages/cpp_api/cpp-api-neighbors-vamana.md new file mode 100644 index 0000000000..01f8992dbb --- /dev/null +++ b/fern/pages/cpp_api/cpp-api-neighbors-vamana.md @@ -0,0 +1,600 @@ +--- +slug: api-reference/cpp-api-neighbors-vamana +--- + +# Vamana + +_Source header: `cpp/include/cuvs/neighbors/vamana.hpp`_ + +## Vamana index build parameters + +_Doxygen group: `vamana_cpp_index_params`_ + +### cuvs::neighbors::vamana::index_params + +Parameters used to build DiskANN index + +`graph_degree`: Maximum degree of graph; corresponds to the R parameter of Vamana algorithm in the literature. `visited_size`: Maximum number of visited nodes per search during Vamana algorithm. Loosely corresponds to the L parameter in the literature. `vamana_iters`: The number of times all vectors are inserted into the graph. If > 1, all vectors are re-inserted to improve graph quality. `max_fraction`: The maximum batch size is this fraction of the total dataset size. Larger gives faster build but lower graph quality. `alpha`: Used to determine how aggressive the pruning will be. + +```cpp +struct index_params : cuvs::neighbors::index_params { ... } ; +``` + +**Fields** + +| Name | Type | Description | +| --- | --- | --- | +| `graph_degree` | `uint32_t` | Maximum degree of output graph corresponds to the R parameter in the original Vamana | +| `visited_size` | `uint32_t` | Maximum number of visited nodes per search corresponds to the L parameter in the Vamana | +| `vamana_iters` | `float` | Number of Vamana vector insertion iterations (each iteration inserts all vectors). | +| `alpha` | `float` | Alpha for pruning parameter | +| `max_fraction` | `float` | Maximum fraction of dataset inserted per batch. * | +| `batch_base` | `float` | Base of growth rate of batch sizes * | +| `queue_size` | `uint32_t` | Size of candidate queue structure - should be (2^x)-1 | +| `reverse_batchsize` | `uint32_t` | Max batchsize of reverse edge processing (reduces memory footprint) | +| `codebooks` | `std::optional>` | Codebooks and related parameters | + +_Source: `cpp/include/cuvs/neighbors/vamana.hpp:56`_ + +## Vamana index type + +_Doxygen group: `vamana_cpp_index`_ + +### cuvs::neighbors::vamana::metric + +Distance metric used for clustering. + +```cpp +[[nodiscard]] constexpr inline auto metric() const noexcept -> cuvs::distance::DistanceType; +``` + +**Returns** + +`cuvs::distance::DistanceType` + +_Source: `cpp/include/cuvs/neighbors/vamana.hpp:108`_ + +### cuvs::neighbors::vamana::size + +Total length of the index (number of vectors). + +```cpp +[[nodiscard]] constexpr inline auto size() const noexcept -> IdxT; +``` + +**Returns** + +`IdxT` + +_Source: `cpp/include/cuvs/neighbors/vamana.hpp:114`_ + +### cuvs::neighbors::vamana::dim + +Dimensionality of the data. + +```cpp +[[nodiscard]] constexpr inline auto dim() const noexcept -> uint32_t; +``` + +**Returns** + +`uint32_t` + +_Source: `cpp/include/cuvs/neighbors/vamana.hpp:121`_ + +### cuvs::neighbors::vamana::graph_degree + +Graph degree + +```cpp +[[nodiscard]] constexpr inline auto graph_degree() const noexcept -> uint32_t; +``` + +**Returns** + +`uint32_t` + +_Source: `cpp/include/cuvs/neighbors/vamana.hpp:123`_ + +### cuvs::neighbors::vamana::data + +Dataset [size, dim] + +```cpp +[[nodiscard]] inline auto data() const noexcept -> const cuvs::neighbors::dataset&; +``` + +**Returns** + +`const cuvs::neighbors::dataset&` + +_Source: `cpp/include/cuvs/neighbors/vamana.hpp:129`_ + +### cuvs::neighbors::vamana::quantized_data + +Quantized dataset [size, codes_rowlen] + +```cpp +[[nodiscard]] inline auto quantized_data() const noexcept +-> raft::device_matrix_view; +``` + +**Returns** + +`raft::device_matrix_view` + +_Source: `cpp/include/cuvs/neighbors/vamana.hpp:135`_ + +### cuvs::neighbors::vamana::graph + +vamana graph [size, graph-degree] + +```cpp +[[nodiscard]] inline auto graph() const noexcept +-> raft::device_matrix_view; +``` + +**Returns** + +`raft::device_matrix_view` + +_Source: `cpp/include/cuvs/neighbors/vamana.hpp:142`_ + +### cuvs::neighbors::vamana::medoid + +Return the id of the vector selected as the medoid. + +```cpp +[[nodiscard]] inline auto medoid() const noexcept -> IdxT; +``` + +**Returns** + +`IdxT` + +_Source: `cpp/include/cuvs/neighbors/vamana.hpp:149`_ + +### cuvs::neighbors::vamana::index + +```cpp +index(const index&) = delete; +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `arg1` | | `const index&` | | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/vamana.hpp:153`_ + +### cuvs::neighbors::vamana::index + +Construct an empty index. + +```cpp +index(raft::resources const& res, +cuvs::distance::DistanceType metric = cuvs::distance::DistanceType::L2Expanded) +: cuvs::neighbors::index(), +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | | `raft::resources const&` | | +| `metric` | | `cuvs::distance::DistanceType` | Default: `cuvs::distance::DistanceType::L2Expanded`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/vamana.hpp:161`_ + +### cuvs::neighbors::vamana::index + +Construct an index from dataset and vamana graph + +```cpp +template +index(raft::resources const& res, +cuvs::distance::DistanceType metric, +raft::mdspan, raft::row_major, data_accessor> dataset, +raft::mdspan, raft::row_major, graph_accessor> +vamana_graph, +IdxT medoid_id) +: cuvs::neighbors::index(), +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | | `raft::resources const&` | | +| `metric` | | `cuvs::distance::DistanceType` | | +| `dataset` | | `raft::mdspan, raft::row_major, data_accessor>` | | +| `vamana_graph` | | `raft::mdspan, raft::row_major, graph_accessor>` | | +| `medoid_id` | | `IdxT` | | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/vamana.hpp:174`_ + +### cuvs::neighbors::vamana::update_graph + +Replace the graph with a new graph. + +```cpp +void update_graph(raft::resources const& res, +raft::device_matrix_view new_graph); +``` + +Since the new graph is a device array, we store a reference to that, and it is the caller's responsibility to ensure that knn_graph stays alive as long as the index. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | | `raft::resources const&` | | +| `new_graph` | | `raft::device_matrix_view` | | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/vamana.hpp:201`_ + +### cuvs::neighbors::vamana::update_graph + +Replace the graph with a new graph. + +```cpp +void update_graph(raft::resources const& res, +raft::host_matrix_view new_graph); +``` + +We create a copy of the graph on the device. The index manages the lifetime of this copy. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | | `raft::resources const&` | | +| `new_graph` | | `raft::host_matrix_view` | | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/vamana.hpp:212`_ + +### cuvs::neighbors::vamana::update_quantized_dataset + +Replace the current quantized dataset with a new quantized dataset. + +```cpp +void update_quantized_dataset( +raft::resources const& res, +raft::device_matrix_view new_quantized_dataset); +``` + +We create a copy of the quantized dataset on the device. The index manages the lifetime of this copy. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | | +| `new_quantized_dataset` | in | `raft::device_matrix_view` | the new quantized dataset for the index | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/vamana.hpp:240`_ + +## Vamana index build functions + +_Doxygen group: `vamana_cpp_index_build`_ + +### cuvs::neighbors::vamana::build + +Build the index from the dataset for efficient DiskANN search. + +```cpp +auto build(raft::resources const& res, +const cuvs::neighbors::vamana::index_params& params, +raft::device_matrix_view dataset) +-> cuvs::neighbors::vamana::index; +``` + +The build utilities the Vamana insertion-based algorithm to create the graph. The algorithm starts with an empty graph and iteratively iserts batches of nodes. Each batch involves performing a greedy search for each vector to be inserted, and inserting it with edges to all nodes traversed during the search. Reverse edges are also inserted and robustPrune is applied to improve graph quality. The index_params struct controls the degree of the final graph. The following distance metrics are supported: - L2 Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | | +| `params` | in | `const cuvs::neighbors::vamana::index_params&` | parameters for building the index | +| `dataset` | in | `raft::device_matrix_view` | a matrix view (device) to a row-major matrix [n_rows, dim] | + +**Returns** + +`cuvs::neighbors::vamana::index` + +the constructed vamana index + +_Source: `cpp/include/cuvs/neighbors/vamana.hpp:305`_ + +### cuvs::neighbors::vamana::build + +Build the index from the dataset for efficient DiskANN search. + +```cpp +auto build(raft::resources const& res, +const cuvs::neighbors::vamana::index_params& params, +raft::host_matrix_view dataset) +-> cuvs::neighbors::vamana::index; +``` + +The build utilities the Vamana insertion-based algorithm to create the graph. The algorithm starts with an empty graph and iteratively iserts batches of nodes. Each batch involves performing a greedy search for each vector to be inserted, and inserting it with edges to all nodes traversed during the search. Reverse edges are also inserted and robustPrune is applied to improve graph quality. The index_params struct controls the degree of the final graph. The following distance metrics are supported: - L2 Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | | +| `params` | in | `const cuvs::neighbors::vamana::index_params&` | parameters for building the index | +| `dataset` | in | `raft::host_matrix_view` | a matrix view (host) to a row-major matrix [n_rows, dim] | + +**Returns** + +`cuvs::neighbors::vamana::index` + +the constructed vamana index + +_Source: `cpp/include/cuvs/neighbors/vamana.hpp:339`_ + +### cuvs::neighbors::vamana::build + +Build the index from the dataset for efficient DiskANN search. + +```cpp +auto build(raft::resources const& res, +const cuvs::neighbors::vamana::index_params& params, +raft::device_matrix_view dataset) +-> cuvs::neighbors::vamana::index; +``` + +The build utilities the Vamana insertion-based algorithm to create the graph. The algorithm starts with an empty graph and iteratively iserts batches of nodes. Each batch involves performing a greedy search for each vector to be inserted, and inserting it with edges to all nodes traversed during the search. Reverse edges are also inserted and robustPrune is applied to improve graph quality. The index_params struct controls the degree of the final graph. The following distance metrics are supported: - L2 Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | | +| `params` | in | `const cuvs::neighbors::vamana::index_params&` | parameters for building the index | +| `dataset` | in | `raft::device_matrix_view` | a matrix view (device) to a row-major matrix [n_rows, dim] | + +**Returns** + +`cuvs::neighbors::vamana::index` + +the constructed vamana index + +_Source: `cpp/include/cuvs/neighbors/vamana.hpp:373`_ + +### cuvs::neighbors::vamana::build + +Build the index from the dataset for efficient DiskANN search. + +```cpp +auto build(raft::resources const& res, +const cuvs::neighbors::vamana::index_params& params, +raft::host_matrix_view dataset) +-> cuvs::neighbors::vamana::index; +``` + +The build utilities the Vamana insertion-based algorithm to create the graph. The algorithm starts with an empty graph and iteratively iserts batches of nodes. Each batch involves performing a greedy search for each vector to be inserted, and inserting it with edges to all nodes traversed during the search. Reverse edges are also inserted and robustPrune is applied to improve graph quality. The index_params struct controls the degree of the final graph. The following distance metrics are supported: - L2 Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | | +| `params` | in | `const cuvs::neighbors::vamana::index_params&` | parameters for building the index | +| `dataset` | in | `raft::host_matrix_view` | a matrix view (host) to a row-major matrix [n_rows, dim] | + +**Returns** + +`cuvs::neighbors::vamana::index` + +the constructed vamana index + +_Source: `cpp/include/cuvs/neighbors/vamana.hpp:407`_ + +### cuvs::neighbors::vamana::build + +Build the index from the dataset for efficient DiskANN search. + +```cpp +auto build(raft::resources const& res, +const cuvs::neighbors::vamana::index_params& params, +raft::device_matrix_view dataset) +-> cuvs::neighbors::vamana::index; +``` + +The build utilities the Vamana insertion-based algorithm to create the graph. The algorithm starts with an empty graph and iteratively iserts batches of nodes. Each batch involves performing a greedy search for each vector to be inserted, and inserting it with edges to all nodes traversed during the search. Reverse edges are also inserted and robustPrune is applied to improve graph quality. The index_params struct controls the degree of the final graph. The following distance metrics are supported: - L2 Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | | +| `params` | in | `const cuvs::neighbors::vamana::index_params&` | parameters for building the index | +| `dataset` | in | `raft::device_matrix_view` | a matrix view (device) to a row-major matrix [n_rows, dim] | + +**Returns** + +`cuvs::neighbors::vamana::index` + +the constructed vamana index + +_Source: `cpp/include/cuvs/neighbors/vamana.hpp:441`_ + +### cuvs::neighbors::vamana::build + +Build the index from the dataset for efficient DiskANN search. + +```cpp +auto build(raft::resources const& res, +const cuvs::neighbors::vamana::index_params& params, +raft::host_matrix_view dataset) +-> cuvs::neighbors::vamana::index; +``` + +The build utilities the Vamana insertion-based algorithm to create the graph. The algorithm starts with an empty graph and iteratively iserts batches of nodes. Each batch involves performing a greedy search for each vector to be inserted, and inserting it with edges to all nodes traversed during the search. Reverse edges are also inserted and robustPrune is applied to improve graph quality. The index_params struct controls the degree of the final graph. The following distance metrics are supported: - L2 Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | | +| `params` | in | `const cuvs::neighbors::vamana::index_params&` | parameters for building the index | +| `dataset` | in | `raft::host_matrix_view` | a matrix view (host) to a row-major matrix [n_rows, dim] | + +**Returns** + +`cuvs::neighbors::vamana::index` + +the constructed vamana index + +_Source: `cpp/include/cuvs/neighbors/vamana.hpp:475`_ + +## Vamana serialize functions + +_Doxygen group: `vamana_cpp_serialize`_ + +### cuvs::neighbors::vamana::serialize + +Save the index to file. + +```cpp +void serialize(raft::resources const& handle, +const std::string& file_prefix, +const cuvs::neighbors::vamana::index& index, +bool include_dataset = true, +bool sector_aligned = false); +``` + +Matches the file format used by the DiskANN open-source repository, allowing cross-compatibility. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | the raft handle | +| `file_prefix` | in | `const std::string&` | prefix of path and name of index files | +| `index` | in | `const cuvs::neighbors::vamana::index&` | Vamana index | +| `include_dataset` | in | `bool` | whether or not to serialize the dataset Default: `true`. | +| `sector_aligned` | in | `bool` | whether output file should be aligned to disk sectors of 4096 bytes Default: `false`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/vamana.hpp:514`_ + +### cuvs::neighbors::vamana::serialize + +Save the index to file. + +```cpp +void serialize(raft::resources const& handle, +const std::string& file_prefix, +const cuvs::neighbors::vamana::index& index, +bool include_dataset = true, +bool sector_aligned = false); +``` + +Matches the file format used by the DiskANN open-source repository, allowing cross-compatibility. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | the raft handle | +| `file_prefix` | in | `const std::string&` | prefix of path and name of index files | +| `index` | in | `const cuvs::neighbors::vamana::index&` | Vamana index | +| `include_dataset` | in | `bool` | whether or not to serialize the dataset Default: `true`. | +| `sector_aligned` | in | `bool` | whether output file should be aligned to disk sectors of 4096 bytes Default: `false`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/vamana.hpp:544`_ + +### cuvs::neighbors::vamana::serialize + +Save the index to file. + +```cpp +void serialize(raft::resources const& handle, +const std::string& file_prefix, +const cuvs::neighbors::vamana::index& index, +bool include_dataset = true, +bool sector_aligned = false); +``` + +Matches the file format used by the DiskANN open-source repository, allowing cross-compatibility. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | the raft handle | +| `file_prefix` | in | `const std::string&` | prefix of path and name of index files | +| `index` | in | `const cuvs::neighbors::vamana::index&` | Vamana index | +| `include_dataset` | in | `bool` | whether or not to serialize the dataset Default: `true`. | +| `sector_aligned` | in | `bool` | whether output file should be aligned to disk sectors of 4096 bytes Default: `false`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/neighbors/vamana.hpp:574`_ + +## Vamana codebook functions + +_Doxygen group: `vamana_cpp_codebook`_ + +### cuvs::neighbors::vamana::deserialize_codebooks + +Construct codebook parameters from input codebook files + +```cpp +auto deserialize_codebooks(const std::string& codebook_prefix, const int dim) +-> codebook_params; +``` + +Expects pq pivots file at "$\{codebook_prefix\}_pq_pivots.bin" and rotation matrix file at "$\{codebook_prefix\}_pq_pivots.bin_rotation_matrix.bin". + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `codebook_prefix` | in | `const std::string&` | path prefix to pq pivots and rotation matrix files | +| `dim` | in | `const int` | dimension of vectors in dataset | + +**Returns** + +`codebook_params` + +_Source: `cpp/include/cuvs/neighbors/vamana.hpp:611`_ diff --git a/fern/pages/cpp_api/cpp-api-preprocessing-pca.md b/fern/pages/cpp_api/cpp-api-preprocessing-pca.md new file mode 100644 index 0000000000..146f95dbb4 --- /dev/null +++ b/fern/pages/cpp_api/cpp-api-preprocessing-pca.md @@ -0,0 +1,161 @@ +--- +slug: api-reference/cpp-api-preprocessing-pca +--- + +# PCA + +_Source header: `cpp/include/cuvs/preprocessing/pca.hpp`_ + +## PCA (Principal Component Analysis) + +_Doxygen group: `pca`_ + +### cuvs::preprocessing::pca::fit + +Perform PCA fit operation. + +```cpp +void fit(raft::resources const& handle, +const params& config, +raft::device_matrix_view input, +raft::device_matrix_view components, +raft::device_vector_view explained_var, +raft::device_vector_view explained_var_ratio, +raft::device_vector_view singular_vals, +raft::device_vector_view mu, +raft::device_scalar_view noise_vars, +bool flip_signs_based_on_U = false); +``` + +Computes the principal components, explained variances, singular values, and column means from the input data. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | raft resource handle | +| `config` | in | `const params&` | PCA parameters | +| `input` | inout | `raft::device_matrix_view` | input data [n_rows x n_cols] (col-major). Modified temporarily. | +| `components` | out | `raft::device_matrix_view` | principal components [n_components x n_cols] (col-major) | +| `explained_var` | out | `raft::device_vector_view` | explained variances [n_components] | +| `explained_var_ratio` | out | `raft::device_vector_view` | explained variance ratios [n_components] | +| `singular_vals` | out | `raft::device_vector_view` | singular values [n_components] | +| `mu` | out | `raft::device_vector_view` | column means [n_cols] | +| `noise_vars` | out | `raft::device_scalar_view` | noise variance (scalar) | +| `flip_signs_based_on_U` | in | `bool` | whether to determine signs by U (true) or V.T (false) Default: `false`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/preprocessing/pca.hpp:99`_ + +### cuvs::preprocessing::pca::fit_transform + +Perform PCA fit and transform operations. + +```cpp +void fit_transform(raft::resources const& handle, +const params& config, +raft::device_matrix_view input, +raft::device_matrix_view trans_input, +raft::device_matrix_view components, +raft::device_vector_view explained_var, +raft::device_vector_view explained_var_ratio, +raft::device_vector_view singular_vals, +raft::device_vector_view mu, +raft::device_scalar_view noise_vars, +bool flip_signs_based_on_U = false); +``` + +Computes the principal components and transforms the input data into the eigenspace in a single operation. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | raft resource handle | +| `config` | in | `const params&` | PCA parameters | +| `input` | inout | `raft::device_matrix_view` | input data [n_rows x n_cols] (col-major). Modified temporarily. | +| `trans_input` | out | `raft::device_matrix_view` | transformed data [n_rows x n_components] (col-major) | +| `components` | out | `raft::device_matrix_view` | principal components [n_components x n_cols] (col-major) | +| `explained_var` | out | `raft::device_vector_view` | explained variances [n_components] | +| `explained_var_ratio` | out | `raft::device_vector_view` | explained variance ratios [n_components] | +| `singular_vals` | out | `raft::device_vector_view` | singular values [n_components] | +| `mu` | out | `raft::device_vector_view` | column means [n_cols] | +| `noise_vars` | out | `raft::device_scalar_view` | noise variance (scalar) | +| `flip_signs_based_on_U` | in | `bool` | whether to determine signs by U (true) or V.T (false) Default: `false`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/preprocessing/pca.hpp:128`_ + +### cuvs::preprocessing::pca::transform + +Perform PCA transform operation. + +```cpp +void transform(raft::resources const& handle, +const params& config, +raft::device_matrix_view input, +raft::device_matrix_view components, +raft::device_vector_view singular_vals, +raft::device_vector_view mu, +raft::device_matrix_view trans_input); +``` + +Transforms the input data into the eigenspace using previously computed principal components. (mean-centered then restored). + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | raft resource handle | +| `config` | in | `const params&` | PCA parameters | +| `input` | inout | `raft::device_matrix_view` | data to transform [n_rows x n_cols] (col-major). Modified temporarily | +| `components` | in | `raft::device_matrix_view` | principal components [n_components x n_cols] (col-major) | +| `singular_vals` | in | `raft::device_vector_view` | singular values [n_components] | +| `mu` | in | `raft::device_vector_view` | column means [n_cols] | +| `trans_input` | out | `raft::device_matrix_view` | transformed data [n_rows x n_components] (col-major) | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/preprocessing/pca.hpp:154`_ + +### cuvs::preprocessing::pca::inverse_transform + +Perform PCA inverse transform operation. + +```cpp +void inverse_transform(raft::resources const& handle, +const params& config, +raft::device_matrix_view trans_input, +raft::device_matrix_view components, +raft::device_vector_view singular_vals, +raft::device_vector_view mu, +raft::device_matrix_view output); +``` + +Transforms data from the eigenspace back to the original space. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | raft resource handle | +| `config` | in | `const params&` | PCA parameters | +| `trans_input` | in | `raft::device_matrix_view` | transformed data [n_rows x n_components] (col-major) | +| `components` | in | `raft::device_matrix_view` | principal components [n_components x n_cols] (col-major) | +| `singular_vals` | in | `raft::device_vector_view` | singular values [n_components] | +| `mu` | in | `raft::device_vector_view` | column means [n_cols] | +| `output` | out | `raft::device_matrix_view` | reconstructed data [n_rows x n_cols] (col-major) | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/preprocessing/pca.hpp:175`_ diff --git a/fern/pages/cpp_api/cpp-api-preprocessing-quantize-binary.md b/fern/pages/cpp_api/cpp-api-preprocessing-quantize-binary.md new file mode 100644 index 0000000000..09b5c727a5 --- /dev/null +++ b/fern/pages/cpp_api/cpp-api-preprocessing-quantize-binary.md @@ -0,0 +1,554 @@ +--- +slug: api-reference/cpp-api-preprocessing-quantize-binary +--- + +# Binary + +_Source header: `cpp/include/cuvs/preprocessing/quantize/binary.hpp`_ + +## Binary quantizer utilities + +_Doxygen group: `binary`_ + +### cuvs::preprocessing::quantize::binary::bit_threshold + +quantizer algorithms. The mean and sampling_median thresholds are calculated separately + +for each dimension. + +```cpp +enum class bit_threshold { ... } ; +``` + +**Values** + +| Name | Value | +| --- | --- | +| `zero` | `` | +| `mean` | `` | +| `sampling_median` | `` | + +_Source: `cpp/include/cuvs/preprocessing/quantize/binary.hpp:27`_ + +### cuvs::preprocessing::quantize::binary::params + +quantizer parameters. + +```cpp +struct params { ... } ; +``` + +**Fields** + +| Name | Type | Description | +| --- | --- | --- | +| `threshold` | `bit_threshold` | Threshold method for binarization. | +| `sampling_ratio` | `float` | Specifies the sampling ratio. | + +_Source: `cpp/include/cuvs/preprocessing/quantize/binary.hpp:32`_ + +### cuvs::preprocessing::quantize::binary::quantizer + +Construct a quantizer with an empty threshold vector. + +```cpp +quantizer(raft::resources const& res) : threshold(raft::make_device_vector(res, 0)); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | | `raft::resources const&` | | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/preprocessing/quantize/binary.hpp:54`_ + +### cuvs::preprocessing::quantize::binary::train + +Initializes a binary quantizer to be used later for quantizing the dataset. + +```cpp +quantizer train(raft::resources const& res, +const params params, +raft::device_matrix_view dataset); +``` + +Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resource | +| `params` | in | `const params` | configure binary quantizer, e.g. threshold | +| `dataset` | in | `raft::device_matrix_view` | a row-major matrix view on device | + +**Returns** + +`quantizer` + +quantizer + +_Source: `cpp/include/cuvs/preprocessing/quantize/binary.hpp:73`_ + +### cuvs::preprocessing::quantize::binary::train + +Initializes a binary quantizer to be used later for quantizing the dataset. + +```cpp +quantizer train(raft::resources const& res, +const params params, +raft::host_matrix_view dataset); +``` + +Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resource | +| `params` | in | `const params` | configure binary quantizer, e.g. threshold | +| `dataset` | in | `raft::host_matrix_view` | a row-major matrix view on host | + +**Returns** + +`quantizer` + +quantizer + +_Source: `cpp/include/cuvs/preprocessing/quantize/binary.hpp:93`_ + +### cuvs::preprocessing::quantize::binary::transform + +Applies binary quantization transform to given dataset. If a dataset element is positive, + +```cpp +void transform(raft::resources const& res, +const quantizer& quantizer, +raft::device_matrix_view dataset, +raft::device_matrix_view out); +``` + +set the corresponding bit to 1. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resource | +| `quantizer` | in | `const quantizer&` | a binary quantizer | +| `dataset` | in | `raft::device_matrix_view` | a row-major matrix view on device | +| `out` | out | `raft::device_matrix_view` | a row-major matrix view on device | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/preprocessing/quantize/binary.hpp:119`_ + +### cuvs::preprocessing::quantize::binary::transform + +Applies binary quantization transform to given dataset. If a dataset element is positive, + +```cpp +void transform(raft::resources const& res, +const quantizer& quantizer, +raft::host_matrix_view dataset, +raft::host_matrix_view out); +``` + +set the corresponding bit to 1. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resource | +| `quantizer` | in | `const quantizer&` | a binary quantizer | +| `dataset` | in | `raft::host_matrix_view` | a row-major matrix view on host | +| `out` | out | `raft::host_matrix_view` | a row-major matrix view on host | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/preprocessing/quantize/binary.hpp:146`_ + +### cuvs::preprocessing::quantize::binary::train + +Initializes a binary quantizer to be used later for quantizing the dataset. + +```cpp +quantizer train(raft::resources const& res, +const params params, +raft::device_matrix_view dataset); +``` + +Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resource | +| `params` | in | `const params` | configure binary quantizer, e.g. threshold | +| `dataset` | in | `raft::device_matrix_view` | a row-major matrix view on device | + +**Returns** + +`quantizer` + +quantizer + +_Source: `cpp/include/cuvs/preprocessing/quantize/binary.hpp:167`_ + +### cuvs::preprocessing::quantize::binary::train + +Initializes a binary quantizer to be used later for quantizing the dataset. + +```cpp +quantizer train(raft::resources const& res, +const params params, +raft::host_matrix_view dataset); +``` + +Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resource | +| `params` | in | `const params` | configure binary quantizer, e.g. threshold | +| `dataset` | in | `raft::host_matrix_view` | a row-major matrix view on host | + +**Returns** + +`quantizer` + +quantizer + +_Source: `cpp/include/cuvs/preprocessing/quantize/binary.hpp:187`_ + +### cuvs::preprocessing::quantize::binary::transform + +Applies binary quantization transform to given dataset. If a dataset element is positive, + +```cpp +void transform(raft::resources const& res, +const quantizer& quantizer, +raft::device_matrix_view dataset, +raft::device_matrix_view out); +``` + +set the corresponding bit to 1. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resource | +| `quantizer` | in | `const quantizer&` | a binary quantizer | +| `dataset` | in | `raft::device_matrix_view` | a row-major matrix view on device | +| `out` | out | `raft::device_matrix_view` | a row-major matrix view on device | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/preprocessing/quantize/binary.hpp:215`_ + +### cuvs::preprocessing::quantize::binary::transform + +Applies binary quantization transform to given dataset. If a dataset element is positive, + +```cpp +void transform(raft::resources const& res, +const quantizer& quantizer, +raft::host_matrix_view dataset, +raft::host_matrix_view out); +``` + +set the corresponding bit to 1. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resource | +| `quantizer` | in | `const quantizer&` | a binary quantizer | +| `dataset` | in | `raft::host_matrix_view` | a row-major matrix view on host | +| `out` | out | `raft::host_matrix_view` | a row-major matrix view on host | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/preprocessing/quantize/binary.hpp:244`_ + +### cuvs::preprocessing::quantize::binary::train + +Initializes a binary quantizer to be used later for quantizing the dataset. + +```cpp +quantizer train(raft::resources const& res, +const params params, +raft::device_matrix_view dataset); +``` + +Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resource | +| `params` | in | `const params` | configure binary quantizer, e.g. threshold | +| `dataset` | in | `raft::device_matrix_view` | a row-major matrix view on device | + +**Returns** + +`quantizer` + +quantizer + +_Source: `cpp/include/cuvs/preprocessing/quantize/binary.hpp:265`_ + +### cuvs::preprocessing::quantize::binary::train + +Initializes a binary quantizer to be used later for quantizing the dataset. + +```cpp +quantizer train(raft::resources const& res, +const params params, +raft::host_matrix_view dataset); +``` + +Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resource | +| `params` | in | `const params` | configure binary quantizer, e.g. threshold | +| `dataset` | in | `raft::host_matrix_view` | a row-major matrix view on host | + +**Returns** + +`quantizer` + +quantizer + +_Source: `cpp/include/cuvs/preprocessing/quantize/binary.hpp:285`_ + +### cuvs::preprocessing::quantize::binary::transform + +Applies binary quantization transform to given dataset. + +```cpp +void transform(raft::resources const& res, +const quantizer& quantizer, +raft::device_matrix_view dataset, +raft::device_matrix_view out); +``` + +Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resource | +| `quantizer` | in | `const quantizer&` | a binary quantizer | +| `dataset` | in | `raft::device_matrix_view` | a row-major matrix view on device | +| `out` | out | `raft::device_matrix_view` | a row-major matrix view on device | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/preprocessing/quantize/binary.hpp:312`_ + +### cuvs::preprocessing::quantize::binary::transform + +Applies binary quantization transform to given dataset. + +```cpp +void transform(raft::resources const& res, +const quantizer& quantizer, +raft::host_matrix_view dataset, +raft::host_matrix_view out); +``` + +Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resource | +| `quantizer` | in | `const quantizer&` | a binary quantizer | +| `dataset` | in | `raft::host_matrix_view` | a row-major matrix view on host | +| `out` | out | `raft::host_matrix_view` | a row-major matrix view on host | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/preprocessing/quantize/binary.hpp:340`_ + +### cuvs::preprocessing::quantize::binary::[[deprecated + +[deprecated] Applies binary quantization transform to given dataset. If a dataset element + +```cpp +[[deprecated("please create and specify a quantizer")]] void transform( +raft::resources const& res, +raft::device_matrix_view dataset, +raft::device_matrix_view out); +``` + +is positive, set the corresponding bit to 1. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `arg1` | | `"please create and specify a quantizer"` | | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/preprocessing/quantize/binary.hpp:354`_ + +### cuvs::preprocessing::quantize::binary::[[deprecated + +[deprecated] Applies binary quantization transform to given dataset. If a dataset element + +```cpp +[[deprecated("please create and specify a quantizer")]] void transform( +raft::resources const& res, +raft::host_matrix_view dataset, +raft::host_matrix_view out); +``` + +is positive, set the corresponding bit to 1. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `arg1` | | `"please create and specify a quantizer"` | | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/preprocessing/quantize/binary.hpp:368`_ + +### cuvs::preprocessing::quantize::binary::[[deprecated + +[deprecated] Applies binary quantization transform to given dataset. If a dataset element + +```cpp +[[deprecated("please create and specify a quantizer")]] void transform( +raft::resources const& res, +raft::device_matrix_view dataset, +raft::device_matrix_view out); +``` + +is positive, set the corresponding bit to 1. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `arg1` | | `"please create and specify a quantizer"` | | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/preprocessing/quantize/binary.hpp:382`_ + +### cuvs::preprocessing::quantize::binary::[[deprecated + +[deprecated] Applies binary quantization transform to given dataset. If a dataset element + +```cpp +[[deprecated("please create and specify a quantizer")]] void transform( +raft::resources const& res, +raft::host_matrix_view dataset, +raft::host_matrix_view out); +``` + +is positive, set the corresponding bit to 1. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `arg1` | | `"please create and specify a quantizer"` | | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/preprocessing/quantize/binary.hpp:396`_ + +### cuvs::preprocessing::quantize::binary::[[deprecated + +[deprecated] Applies binary quantization transform to given dataset. If a dataset element + +```cpp +[[deprecated("please create and specify a quantizer")]] void transform( +raft::resources const& res, +raft::device_matrix_view dataset, +raft::device_matrix_view out); +``` + +is positive, set the corresponding bit to 1. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `arg1` | | `"please create and specify a quantizer"` | | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/preprocessing/quantize/binary.hpp:410`_ + +### cuvs::preprocessing::quantize::binary::[[deprecated + +[deprecated] Applies binary quantization transform to given dataset. If a dataset element + +```cpp +[[deprecated("please create and specify a quantizer")]] void transform( +raft::resources const& res, +raft::host_matrix_view dataset, +raft::host_matrix_view out); +``` + +is positive, set the corresponding bit to 1. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `arg1` | | `"please create and specify a quantizer"` | | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/preprocessing/quantize/binary.hpp:424`_ diff --git a/fern/pages/cpp_api/cpp-api-preprocessing-quantize-pq.md b/fern/pages/cpp_api/cpp-api-preprocessing-quantize-pq.md new file mode 100644 index 0000000000..c9a9aced13 --- /dev/null +++ b/fern/pages/cpp_api/cpp-api-preprocessing-quantize-pq.md @@ -0,0 +1,230 @@ +--- +slug: api-reference/cpp-api-preprocessing-quantize-pq +--- + +# PQ + +_Source header: `cpp/include/cuvs/preprocessing/quantize/pq.hpp`_ + +## Product Quantizer utilities + +_Doxygen group: `pq`_ + +### cuvs::preprocessing::quantize::pq::params + +Product Quantizer parameters. + +```cpp +struct params { ... } ; +``` + +**Fields** + +| Name | Type | Description | +| --- | --- | --- | +| `params` | `params(uint32_t pq_bits, uint32_t pq_dim, bool use_subspaces, bool use_vq, uint32_t vq_n_centers, uint32_t kmeans_n_iters, cuvs::cluster::kmeans::kmeans_type` | Simplified constructor that will build an appropriate kmeans params object. | +| `pq_bits` | `uint32_t` | The bit length of the vector element after compression by PQ. | +| `pq_dim` | `uint32_t` | The dimensionality of the vector after compression by PQ. | +| `use_subspaces` | `bool` | Whether to use subspaces for product quantization (PQ). | +| `use_vq` | `bool` | Whether to use Vector Quantization (KMeans) before product quantization (PQ). | +| `vq_n_centers` | `uint32_t` | Vector Quantization (VQ) codebook size - number of "coarse cluster centers". | +| `kmeans_params` | `kmeans_params_variant` | K-means parameters for PQ codebook training. | +| `max_train_points_per_pq_code` | `uint32_t` | The max number of data points to use per PQ code during PQ codebook training. Using more data | +| `max_train_points_per_vq_cluster` | `uint32_t` | The max number of data points to use per VQ cluster during training. | + +_Source: `cpp/include/cuvs/preprocessing/quantize/pq.hpp:30`_ + +### cuvs::preprocessing::quantize::pq::params + +Simplified constructor that will build an appropriate kmeans params object. + +```cpp +params(uint32_t pq_bits, +uint32_t pq_dim, +bool use_subspaces, +bool use_vq, +uint32_t vq_n_centers, +uint32_t kmeans_n_iters, +cuvs::cluster::kmeans::kmeans_type pq_kmeans_type = +cuvs::cluster::kmeans::kmeans_type::KMeansBalanced, +uint32_t max_train_points_per_pq_code = 256, +uint32_t max_train_points_per_vq_cluster = 1024) +: pq_bits(pq_bits), +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `pq_bits` | | `uint32_t` | | +| `pq_dim` | | `uint32_t` | | +| `use_subspaces` | | `bool` | | +| `use_vq` | | `bool` | | +| `vq_n_centers` | | `uint32_t` | | +| `kmeans_n_iters` | | `uint32_t` | | +| `pq_kmeans_type` | | `cuvs::cluster::kmeans::kmeans_type` | Default: `cuvs::cluster::kmeans::kmeans_type::KMeansBalanced`. | +| `max_train_points_per_pq_code` | | `uint32_t` | Default: `256`. | +| `max_train_points_per_vq_cluster` | | `uint32_t` | Default: `1024`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/preprocessing/quantize/pq.hpp:34`_ + +### cuvs::preprocessing::quantize::pq::build + +Initializes a product quantizer to be used later for quantizing the dataset. + +```cpp +quantizer build(raft::resources const& res, +const params params, +raft::device_matrix_view dataset); +``` + +The use of a pool memory resource is recommended for more consistent training performance. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resource | +| `params` | in | `const params` | configure product quantizer, e.g. quantile | +| `dataset` | in | `raft::device_matrix_view` | a row-major matrix view on device or host | + +**Returns** + +`quantizer` + +quantizer + +_Source: `cpp/include/cuvs/preprocessing/quantize/pq.hpp:169`_ + +### cuvs::preprocessing::quantize::pq::build + +```cpp +quantizer build(raft::resources const& res, +const params params, +raft::host_matrix_view dataset); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | | `raft::resources const&` | | +| `params` | | `const params` | | +| `dataset` | | `raft::host_matrix_view` | | + +**Returns** + +`quantizer` + +_Source: `cpp/include/cuvs/preprocessing/quantize/pq.hpp:174`_ + +### cuvs::preprocessing::quantize::pq::transform + +Applies quantization transform to given dataset + +```cpp +void transform(raft::resources const& res, +const quantizer& quant, +raft::device_matrix_view dataset, +raft::device_matrix_view codes_out, +std::optional> vq_labels = std::nullopt); +``` + +Usage example: used, optional + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resource | +| `quant` | in | `const quantizer&` | a product quantizer | +| `dataset` | in | `raft::device_matrix_view` | a row-major matrix view on device or host | +| `codes_out` | out | `raft::device_matrix_view` | a row-major matrix view on device containing the PQ codes | +| `vq_labels` | out | `std::optional>` | a vector view on device containing the VQ labels when VQ is Default: `std::nullopt`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/preprocessing/quantize/pq.hpp:201`_ + +### cuvs::preprocessing::quantize::pq::transform + +```cpp +void transform(raft::resources const& res, +const quantizer& quant, +raft::host_matrix_view dataset, +raft::device_matrix_view codes_out, +std::optional> vq_labels = std::nullopt); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | | `raft::resources const&` | | +| `quant` | | `const quantizer&` | | +| `dataset` | | `raft::host_matrix_view` | | +| `codes_out` | | `raft::device_matrix_view` | | +| `vq_labels` | | `std::optional>` | Default: `std::nullopt`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/preprocessing/quantize/pq.hpp:208`_ + +### cuvs::preprocessing::quantize::pq::get_quantized_dim + +Get the dimension of the quantized dataset (in bytes) + +```cpp +inline int64_t get_quantized_dim(const params& config); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `config` | in | `const params&` | product quantizer parameters | + +**Returns** + +`inline int64_t` + +the dimension of the quantized dataset + +_Source: `cpp/include/cuvs/preprocessing/quantize/pq.hpp:220`_ + +### cuvs::preprocessing::quantize::pq::inverse_transform + +Applies inverse quantization transform to given dataset + +```cpp +void inverse_transform( +raft::resources const& res, +const quantizer& quant, +raft::device_matrix_view pq_codes, +raft::device_matrix_view out, +std::optional> vq_labels = std::nullopt); +``` + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resource | +| `quant` | in | `const quantizer&` | a product quantizer | +| `pq_codes` | in | `raft::device_matrix_view` | a row-major matrix view on device containing the PQ codes | +| `out` | out | `raft::device_matrix_view` | a row-major matrix view on device | +| `vq_labels` | in | `std::optional>` | a vector view on device containing the VQ labels when VQ is used, optional Default: `std::nullopt`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/preprocessing/quantize/pq.hpp:235`_ diff --git a/fern/pages/cpp_api/cpp-api-preprocessing-quantize-scalar.md b/fern/pages/cpp_api/cpp-api-preprocessing-quantize-scalar.md new file mode 100644 index 0000000000..8a08820f37 --- /dev/null +++ b/fern/pages/cpp_api/cpp-api-preprocessing-quantize-scalar.md @@ -0,0 +1,531 @@ +--- +slug: api-reference/cpp-api-preprocessing-quantize-scalar +--- + +# Scalar + +_Source header: `cpp/include/cuvs/preprocessing/quantize/scalar.hpp`_ + +## Scalar quantizer utilities + +_Doxygen group: `scalar`_ + +### cuvs::preprocessing::quantize::scalar::params + +quantizer parameters. + +```cpp +struct params { ... } ; +``` + +**Fields** + +| Name | Type | Description | +| --- | --- | --- | +| `quantile` | `float` | Specifies how many outliers at top & bottom will be ignored. | + +_Source: `cpp/include/cuvs/preprocessing/quantize/scalar.hpp:26`_ + +### cuvs::preprocessing::quantize::scalar::train + +Initializes a scalar quantizer to be used later for quantizing the dataset. + +```cpp +quantizer train(raft::resources const& res, +const params params, +raft::device_matrix_view dataset); +``` + +Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resource | +| `params` | in | `const params` | configure scalar quantizer, e.g. quantile | +| `dataset` | in | `raft::device_matrix_view` | a row-major matrix view on device | + +**Returns** + +`quantizer` + +quantizer + +_Source: `cpp/include/cuvs/preprocessing/quantize/scalar.hpp:67`_ + +### cuvs::preprocessing::quantize::scalar::train + +Initializes a scalar quantizer to be used later for quantizing the dataset. + +```cpp +quantizer train(raft::resources const& res, +const params params, +raft::host_matrix_view dataset); +``` + +Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resource | +| `params` | in | `const params` | configure scalar quantizer, e.g. quantile | +| `dataset` | in | `raft::host_matrix_view` | a row-major matrix view on host | + +**Returns** + +`quantizer` + +quantizer + +_Source: `cpp/include/cuvs/preprocessing/quantize/scalar.hpp:87`_ + +### cuvs::preprocessing::quantize::scalar::transform + +Applies quantization transform to given dataset + +```cpp +void transform(raft::resources const& res, +const quantizer& quantizer, +raft::device_matrix_view dataset, +raft::device_matrix_view out); +``` + +Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resource | +| `quantizer` | in | `const quantizer&` | a scalar quantizer | +| `dataset` | in | `raft::device_matrix_view` | a row-major matrix view on device | +| `out` | out | `raft::device_matrix_view` | a row-major matrix view on device | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/preprocessing/quantize/scalar.hpp:110`_ + +### cuvs::preprocessing::quantize::scalar::transform + +Applies quantization transform to given dataset + +```cpp +void transform(raft::resources const& res, +const quantizer& quantizer, +raft::host_matrix_view dataset, +raft::host_matrix_view out); +``` + +Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resource | +| `quantizer` | in | `const quantizer&` | a scalar quantizer | +| `dataset` | in | `raft::host_matrix_view` | a row-major matrix view on host | +| `out` | out | `raft::host_matrix_view` | a row-major matrix view on host | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/preprocessing/quantize/scalar.hpp:134`_ + +### cuvs::preprocessing::quantize::scalar::inverse_transform + +Perform inverse quantization step on previously quantized dataset + +```cpp +void inverse_transform(raft::resources const& res, +const quantizer& quantizer, +raft::device_matrix_view dataset, +raft::device_matrix_view out); +``` + +Note that depending on the chosen data types train dataset the conversion is not lossless. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resource | +| `quantizer` | in | `const quantizer&` | a scalar quantizer | +| `dataset` | in | `raft::device_matrix_view` | a row-major matrix view on device | +| `out` | out | `raft::device_matrix_view` | a row-major matrix view on device | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/preprocessing/quantize/scalar.hpp:161`_ + +### cuvs::preprocessing::quantize::scalar::inverse_transform + +Perform inverse quantization step on previously quantized dataset + +```cpp +void inverse_transform(raft::resources const& res, +const quantizer& quantizer, +raft::host_matrix_view dataset, +raft::host_matrix_view out); +``` + +Note that depending on the chosen data types train dataset the conversion is not lossless. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resource | +| `quantizer` | in | `const quantizer&` | a scalar quantizer | +| `dataset` | in | `raft::host_matrix_view` | a row-major matrix view on host | +| `out` | out | `raft::host_matrix_view` | a row-major matrix view on host | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/preprocessing/quantize/scalar.hpp:187`_ + +### cuvs::preprocessing::quantize::scalar::train + +Initializes a scalar quantizer to be used later for quantizing the dataset. + +```cpp +quantizer train(raft::resources const& res, +const params params, +raft::device_matrix_view dataset); +``` + +Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resource | +| `params` | in | `const params` | configure scalar quantizer, e.g. quantile | +| `dataset` | in | `raft::device_matrix_view` | a row-major matrix view on device | + +**Returns** + +`quantizer` + +quantizer + +_Source: `cpp/include/cuvs/preprocessing/quantize/scalar.hpp:208`_ + +### cuvs::preprocessing::quantize::scalar::train + +Initializes a scalar quantizer to be used later for quantizing the dataset. + +```cpp +quantizer train(raft::resources const& res, +const params params, +raft::host_matrix_view dataset); +``` + +Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resource | +| `params` | in | `const params` | configure scalar quantizer, e.g. quantile | +| `dataset` | in | `raft::host_matrix_view` | a row-major matrix view on host | + +**Returns** + +`quantizer` + +quantizer + +_Source: `cpp/include/cuvs/preprocessing/quantize/scalar.hpp:228`_ + +### cuvs::preprocessing::quantize::scalar::transform + +Applies quantization transform to given dataset + +```cpp +void transform(raft::resources const& res, +const quantizer& quantizer, +raft::device_matrix_view dataset, +raft::device_matrix_view out); +``` + +Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resource | +| `quantizer` | in | `const quantizer&` | a scalar quantizer | +| `dataset` | in | `raft::device_matrix_view` | a row-major matrix view on device | +| `out` | out | `raft::device_matrix_view` | a row-major matrix view on device | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/preprocessing/quantize/scalar.hpp:251`_ + +### cuvs::preprocessing::quantize::scalar::transform + +Applies quantization transform to given dataset + +```cpp +void transform(raft::resources const& res, +const quantizer& quantizer, +raft::host_matrix_view dataset, +raft::host_matrix_view out); +``` + +Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resource | +| `quantizer` | in | `const quantizer&` | a scalar quantizer | +| `dataset` | in | `raft::host_matrix_view` | a row-major matrix view on host | +| `out` | out | `raft::host_matrix_view` | a row-major matrix view on host | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/preprocessing/quantize/scalar.hpp:275`_ + +### cuvs::preprocessing::quantize::scalar::inverse_transform + +Perform inverse quantization step on previously quantized dataset + +```cpp +void inverse_transform(raft::resources const& res, +const quantizer& quantizer, +raft::device_matrix_view dataset, +raft::device_matrix_view out); +``` + +Note that depending on the chosen data types train dataset the conversion is not lossless. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resource | +| `quantizer` | in | `const quantizer&` | a scalar quantizer | +| `dataset` | in | `raft::device_matrix_view` | a row-major matrix view on device | +| `out` | out | `raft::device_matrix_view` | a row-major matrix view on device | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/preprocessing/quantize/scalar.hpp:301`_ + +### cuvs::preprocessing::quantize::scalar::inverse_transform + +Perform inverse quantization step on previously quantized dataset + +```cpp +void inverse_transform(raft::resources const& res, +const quantizer& quantizer, +raft::host_matrix_view dataset, +raft::host_matrix_view out); +``` + +Note that depending on the chosen data types train dataset the conversion is not lossless. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resource | +| `quantizer` | in | `const quantizer&` | a scalar quantizer | +| `dataset` | in | `raft::host_matrix_view` | a row-major matrix view on host | +| `out` | out | `raft::host_matrix_view` | a row-major matrix view on host | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/preprocessing/quantize/scalar.hpp:327`_ + +### cuvs::preprocessing::quantize::scalar::train + +Initializes a scalar quantizer to be used later for quantizing the dataset. + +```cpp +quantizer train(raft::resources const& res, +const params params, +raft::device_matrix_view dataset); +``` + +Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resource | +| `params` | in | `const params` | configure scalar quantizer, e.g. quantile | +| `dataset` | in | `raft::device_matrix_view` | a row-major matrix view on device | + +**Returns** + +`quantizer` + +quantizer + +_Source: `cpp/include/cuvs/preprocessing/quantize/scalar.hpp:348`_ + +### cuvs::preprocessing::quantize::scalar::train + +Initializes a scalar quantizer to be used later for quantizing the dataset. + +```cpp +quantizer train(raft::resources const& res, +const params params, +raft::host_matrix_view dataset); +``` + +Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resource | +| `params` | in | `const params` | configure scalar quantizer, e.g. quantile | +| `dataset` | in | `raft::host_matrix_view` | a row-major matrix view on host | + +**Returns** + +`quantizer` + +quantizer + +_Source: `cpp/include/cuvs/preprocessing/quantize/scalar.hpp:368`_ + +### cuvs::preprocessing::quantize::scalar::transform + +Applies quantization transform to given dataset + +```cpp +void transform(raft::resources const& res, +const quantizer& quantizer, +raft::device_matrix_view dataset, +raft::device_matrix_view out); +``` + +Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resource | +| `quantizer` | in | `const quantizer&` | a scalar quantizer | +| `dataset` | in | `raft::device_matrix_view` | a row-major matrix view on device | +| `out` | out | `raft::device_matrix_view` | a row-major matrix view on device | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/preprocessing/quantize/scalar.hpp:391`_ + +### cuvs::preprocessing::quantize::scalar::transform + +Applies quantization transform to given dataset + +```cpp +void transform(raft::resources const& res, +const quantizer& quantizer, +raft::host_matrix_view dataset, +raft::host_matrix_view out); +``` + +Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resource | +| `quantizer` | in | `const quantizer&` | a scalar quantizer | +| `dataset` | in | `raft::host_matrix_view` | a row-major matrix view on host | +| `out` | out | `raft::host_matrix_view` | a row-major matrix view on host | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/preprocessing/quantize/scalar.hpp:415`_ + +### cuvs::preprocessing::quantize::scalar::inverse_transform + +Perform inverse quantization step on previously quantized dataset + +```cpp +void inverse_transform(raft::resources const& res, +const quantizer& quantizer, +raft::device_matrix_view dataset, +raft::device_matrix_view out); +``` + +Note that depending on the chosen data types train dataset the conversion is not lossless. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resource | +| `quantizer` | in | `const quantizer&` | a scalar quantizer | +| `dataset` | in | `raft::device_matrix_view` | a row-major matrix view on device | +| `out` | out | `raft::device_matrix_view` | a row-major matrix view on device | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/preprocessing/quantize/scalar.hpp:441`_ + +### cuvs::preprocessing::quantize::scalar::inverse_transform + +Perform inverse quantization step on previously quantized dataset + +```cpp +void inverse_transform(raft::resources const& res, +const quantizer& quantizer, +raft::host_matrix_view dataset, +raft::host_matrix_view out); +``` + +Note that depending on the chosen data types train dataset the conversion is not lossless. Usage example: + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `res` | in | `raft::resources const&` | raft resource | +| `quantizer` | in | `const quantizer&` | a scalar quantizer | +| `dataset` | in | `raft::host_matrix_view` | a row-major matrix view on host | +| `out` | out | `raft::host_matrix_view` | a row-major matrix view on host | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/preprocessing/quantize/scalar.hpp:467`_ diff --git a/fern/pages/cpp_api/cpp-api-preprocessing-spectral-embedding.md b/fern/pages/cpp_api/cpp-api-preprocessing-spectral-embedding.md new file mode 100644 index 0000000000..778dcf8fb3 --- /dev/null +++ b/fern/pages/cpp_api/cpp-api-preprocessing-spectral-embedding.md @@ -0,0 +1,67 @@ +--- +slug: api-reference/cpp-api-preprocessing-spectral-embedding +--- + +# Spectral Embedding + +_Source header: `cpp/include/cuvs/preprocessing/spectral_embedding.hpp`_ + +## Spectral Embedding + +_Doxygen group: `spectral_embedding`_ + +### cuvs::preprocessing::spectral_embedding::transform + +Perform spectral embedding on input dataset + +```cpp +void transform(raft::resources const& handle, +params config, +raft::device_matrix_view dataset, +raft::device_matrix_view embedding); +``` + +This function computes the spectral embedding of the input dataset by: 1. Constructing a k-nearest neighbors graph from the input data 2. Computing the graph Laplacian (normalized or unnormalized) 3. Finding the eigenvectors corresponding to the smallest eigenvalues 4. Using these eigenvectors as the embedding coordinates + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | RAFT resource handle for managing CUDA resources | +| `config` | in | `params` | Parameters controlling the spectral embedding algorithm | +| `dataset` | in | `raft::device_matrix_view` | Input dataset in row-major format [n_samples x n_features] | +| `embedding` | out | `raft::device_matrix_view` | Output embedding in column-major format [n_samples x n_components] | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/preprocessing/spectral_embedding.hpp:115`_ + +### cuvs::preprocessing::spectral_embedding::transform + +Perform spectral embedding using a precomputed connectivity graph + +```cpp +void transform(raft::resources const& handle, +params config, +raft::device_coo_matrix_view connectivity_graph, +raft::device_matrix_view embedding); +``` + +This function computes the spectral embedding from a precomputed sparse connectivity graph (e.g., from a k-NN search or custom similarity matrix). This is useful when you want to use a custom graph construction method or when you have a precomputed similarity/affinity matrix. The function: 1. Converts the COO matrix to the graph Laplacian 2. Computes eigenvectors of the Laplacian 3. Returns the eigenvectors as the embedding + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | RAFT resource handle for managing CUDA resources | +| `config` | in | `params` | Parameters controlling the spectral embedding algorithm (n_neighbors parameter is ignored when using precomputed graph) | +| `connectivity_graph` | in | `raft::device_coo_matrix_view` | Precomputed sparse connectivity/affinity graph in COO format representing weighted connections between samples | +| `embedding` | out | `raft::device_matrix_view` | Output embedding in column-major format [n_samples x n_components] | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/preprocessing/spectral_embedding.hpp:167`_ diff --git a/fern/pages/cpp_api/cpp-api-selection-select-k.md b/fern/pages/cpp_api/cpp-api-selection-select-k.md new file mode 100644 index 0000000000..7957ae9c70 --- /dev/null +++ b/fern/pages/cpp_api/cpp-api-selection-select-k.md @@ -0,0 +1,128 @@ +--- +slug: api-reference/cpp-api-selection-select-k +--- + +# Select K + +_Source header: `cpp/include/cuvs/selection/select_k.hpp`_ + +## Batched-select k smallest or largest key/values + +_Doxygen group: `select_k`_ + +### cuvs::selection::select_k + +Select k smallest or largest key/values from each row in the input data. + +```cpp +void select_k( +raft::resources const& handle, +raft::device_matrix_view in_val, +std::optional> in_idx, +raft::device_matrix_view out_val, +raft::device_matrix_view out_idx, +bool select_min, +bool sorted = false, +SelectAlgo algo = SelectAlgo::kAuto, +std::optional> len_i = std::nullopt); +``` + +If you think of the input data `in_val` as a row-major matrix with `len` columns and `batch_size` rows, then this function selects `k` smallest/largest values in each row and fills in the row-major matrix `out_val` of size (batch_size, k). Example usage + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | container of reusable resources | +| `in_val` | in | `raft::device_matrix_view` | inputs values [batch_size, len]; these are compared and selected. | +| `in_idx` | in | `std::optional>` | optional input payload [batch_size, len]; typically, these are indices of the corresponding `in_val`. If `in_idx` is `std::nullopt`, a contiguous array `0...len-1` is implied. | +| `out_val` | out | `raft::device_matrix_view` | output values [batch_size, k]; the k smallest/largest values from each row of the `in_val`. | +| `out_idx` | out | `raft::device_matrix_view` | output payload (e.g. indices) [batch_size, k]; the payload selected together with `out_val`. | +| `select_min` | in | `bool` | whether to select k smallest (true) or largest (false) keys. | +| `sorted` | in | `bool` | whether to make sure selected pairs are sorted by value Default: `false`. | +| `algo` | in | `SelectAlgo` | the selection algorithm to use Default: `SelectAlgo::kAuto`. | +| `len_i` | in | `std::optional>` | optional array of size (batch_size) providing lengths for each individual row Default: `std::nullopt`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/selection/select_k.hpp:68`_ + +### cuvs::selection::select_k + +Select k smallest or largest key/values from each row in the input data. + +```cpp +void select_k( +raft::resources const& handle, +raft::device_matrix_view in_val, +std::optional> in_idx, +raft::device_matrix_view out_val, +raft::device_matrix_view out_idx, +bool select_min, +bool sorted = false, +SelectAlgo algo = SelectAlgo::kAuto, +std::optional> len_i = std::nullopt); +``` + +If you think of the input data `in_val` as a row-major matrix with `len` columns and `batch_size` rows, then this function selects `k` smallest/largest values in each row and fills in the row-major matrix `out_val` of size (batch_size, k). Example usage + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | container of reusable resources | +| `in_val` | in | `raft::device_matrix_view` | inputs values [batch_size, len]; these are compared and selected. | +| `in_idx` | in | `std::optional>` | optional input payload [batch_size, len]; typically, these are indices of the corresponding `in_val`. If `in_idx` is `std::nullopt`, a contiguous array `0...len-1` is implied. | +| `out_val` | out | `raft::device_matrix_view` | output values [batch_size, k]; the k smallest/largest values from each row of the `in_val`. | +| `out_idx` | out | `raft::device_matrix_view` | output payload (e.g. indices) [batch_size, k]; the payload selected together with `out_val`. | +| `select_min` | in | `bool` | whether to select k smallest (true) or largest (false) keys. | +| `sorted` | in | `bool` | whether to make sure selected pairs are sorted by value Default: `false`. | +| `algo` | in | `SelectAlgo` | the selection algorithm to use Default: `SelectAlgo::kAuto`. | +| `len_i` | in | `std::optional>` | optional array of size (batch_size) providing lengths for each individual row Default: `std::nullopt`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/selection/select_k.hpp:133`_ + +### cuvs::selection::select_k + +Select k smallest or largest key/values from each row in the input data. + +```cpp +void select_k( +raft::resources const& handle, +raft::device_matrix_view in_val, +std::optional> in_idx, +raft::device_matrix_view out_val, +raft::device_matrix_view out_idx, +bool select_min, +bool sorted = false, +SelectAlgo algo = SelectAlgo::kAuto, +std::optional> len_i = std::nullopt); +``` + +If you think of the input data `in_val` as a row-major matrix with `len` columns and `batch_size` rows, then this function selects `k` smallest/largest values in each row and fills in the row-major matrix `out_val` of size (batch_size, k). Example usage + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | container of reusable resources | +| `in_val` | in | `raft::device_matrix_view` | inputs values [batch_size, len]; these are compared and selected. | +| `in_idx` | in | `std::optional>` | optional input payload [batch_size, len]; typically, these are indices of the corresponding `in_val`. If `in_idx` is `std::nullopt`, a contiguous array `0...len-1` is implied. | +| `out_val` | out | `raft::device_matrix_view` | output values [batch_size, k]; the k smallest/largest values from each row of the `in_val`. | +| `out_idx` | out | `raft::device_matrix_view` | output payload (e.g. indices) [batch_size, k]; the payload selected together with `out_val`. | +| `select_min` | in | `bool` | whether to select k smallest (true) or largest (false) keys. | +| `sorted` | in | `bool` | whether to make sure selected pairs are sorted by value Default: `false`. | +| `algo` | in | `SelectAlgo` | the selection algorithm to use Default: `SelectAlgo::kAuto`. | +| `len_i` | in | `std::optional>` | optional array of size (batch_size) providing lengths for each individual row Default: `std::nullopt`. | + +**Returns** + +`void` + +_Source: `cpp/include/cuvs/selection/select_k.hpp:188`_ diff --git a/fern/pages/cpp_api/cpp-api-stats-silhouette-score.md b/fern/pages/cpp_api/cpp-api-stats-silhouette-score.md new file mode 100644 index 0000000000..45393cc4bb --- /dev/null +++ b/fern/pages/cpp_api/cpp-api-stats-silhouette-score.md @@ -0,0 +1,155 @@ +--- +slug: api-reference/cpp-api-stats-silhouette-score +--- + +# Silhouette Score + +_Source header: `cpp/include/cuvs/stats/silhouette_score.hpp`_ + +## Silhouette Score + +_Doxygen group: `stats_silhouette_score`_ + +### stats::silhouette_score + +main function that returns the average silhouette score for a given set of data and its + +```cpp +float silhouette_score( +raft::resources const& handle, +raft::device_matrix_view X_in, +raft::device_vector_view labels, +std::optional> silhouette_score_per_sample, +int64_t n_unique_labels, +cuvs::distance::DistanceType metric = cuvs::distance::DistanceType::L2Unexpanded); +``` + +clusterings nRows) for every sample (length: nRows) + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | : raft handle for managing expensive resources | +| `X_in` | in | `raft::device_matrix_view` | : input matrix Data in row-major format (nRows x nCols) | +| `labels` | in | `raft::device_vector_view` | : the pointer to the array containing labels for every data sample (length: | +| `silhouette_score_per_sample` | out | `std::optional>` | : optional array populated with the silhouette score | +| `n_unique_labels` | in | `int64_t` | : number of unique labels in the labels array | +| `metric` | in | `cuvs::distance::DistanceType` | : Distance metric to use. Euclidean (L2) is used by default Default: `cuvs::distance::DistanceType::L2Unexpanded`. | + +**Returns** + +`float` + +: The silhouette score. + +_Source: `cpp/include/cuvs/stats/silhouette_score.hpp:31`_ + +### stats::silhouette_score_batched + +function that returns the average silhouette score for a given set of data and its + +```cpp +float silhouette_score_batched( +raft::resources const& handle, +raft::device_matrix_view X, +raft::device_vector_view labels, +std::optional> silhouette_score_per_sample, +int64_t n_unique_labels, +int64_t batch_size, +cuvs::distance::DistanceType metric = cuvs::distance::DistanceType::L2Unexpanded); +``` + +clusterings nRows) for every sample (length: nRows) the calculations + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | : raft handle for managing expensive resources | +| `X` | in | `raft::device_matrix_view` | : input matrix Data in row-major format (nRows x nCols) | +| `labels` | in | `raft::device_vector_view` | : the pointer to the array containing labels for every data sample (length: | +| `silhouette_score_per_sample` | out | `std::optional>` | : optional array populated with the silhouette score | +| `n_unique_labels` | in | `int64_t` | : number of unique labels in the labels array | +| `batch_size` | in | `int64_t` | : number of samples per batch | +| `metric` | in | `cuvs::distance::DistanceType` | : the numerical value that maps to the type of distance metric to be used in Default: `cuvs::distance::DistanceType::L2Unexpanded`. | + +**Returns** + +`float` + +: The silhouette score. + +_Source: `cpp/include/cuvs/stats/silhouette_score.hpp:54`_ + +### stats::silhouette_score + +main function that returns the average silhouette score for a given set of data and its + +```cpp +double silhouette_score( +raft::resources const& handle, +raft::device_matrix_view X_in, +raft::device_vector_view labels, +std::optional> silhouette_score_per_sample, +int64_t n_unique_labels, +cuvs::distance::DistanceType metric = cuvs::distance::DistanceType::L2Unexpanded); +``` + +clusterings nRows) for every sample (length: nRows) the calculations + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | : raft handle for managing expensive resources | +| `X_in` | in | `raft::device_matrix_view` | : input matrix Data in row-major format (nRows x nCols) | +| `labels` | in | `raft::device_vector_view` | : the pointer to the array containing labels for every data sample (length: | +| `silhouette_score_per_sample` | out | `std::optional>` | : optional array populated with the silhouette score | +| `n_unique_labels` | in | `int64_t` | : number of unique labels in the labels array | +| `metric` | in | `cuvs::distance::DistanceType` | : the numerical value that maps to the type of distance metric to be used in Default: `cuvs::distance::DistanceType::L2Unexpanded`. | + +**Returns** + +`double` + +: The silhouette score. + +_Source: `cpp/include/cuvs/stats/silhouette_score.hpp:77`_ + +### stats::silhouette_score_batched + +function that returns the average silhouette score for a given set of data and its + +```cpp +double silhouette_score_batched( +raft::resources const& handle, +raft::device_matrix_view X, +raft::device_vector_view labels, +std::optional> silhouette_score_per_sample, +int64_t n_unique_labels, +int64_t batch_size, +cuvs::distance::DistanceType metric = cuvs::distance::DistanceType::L2Unexpanded); +``` + +clusterings nRows) for every sample (length: nRows) the calculations + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | : raft handle for managing expensive resources | +| `X` | in | `raft::device_matrix_view` | : input matrix Data in row-major format (nRows x nCols) | +| `labels` | in | `raft::device_vector_view` | : the pointer to the array containing labels for every data sample (length: | +| `silhouette_score_per_sample` | out | `std::optional>` | : optional array populated with the silhouette score | +| `n_unique_labels` | in | `int64_t` | : number of unique labels in the labels array | +| `batch_size` | in | `int64_t` | : number of samples per batch | +| `metric` | in | `cuvs::distance::DistanceType` | : the numerical value that maps to the type of distance metric to be used in Default: `cuvs::distance::DistanceType::L2Unexpanded`. | + +**Returns** + +`double` + +: The silhouette score. + +_Source: `cpp/include/cuvs/stats/silhouette_score.hpp:100`_ diff --git a/fern/pages/cpp_api/cpp-api-stats-trustworthiness-score.md b/fern/pages/cpp_api/cpp-api-stats-trustworthiness-score.md new file mode 100644 index 0000000000..8327221db2 --- /dev/null +++ b/fern/pages/cpp_api/cpp-api-stats-trustworthiness-score.md @@ -0,0 +1,46 @@ +--- +slug: api-reference/cpp-api-stats-trustworthiness-score +--- + +# Trustworthiness Score + +_Source header: `cpp/include/cuvs/stats/trustworthiness_score.hpp`_ + +## Trustworthiness + +_Doxygen group: `stats_trustworthiness`_ + +### stats::trustworthiness_score + +Compute the trustworthiness score + +```cpp +double trustworthiness_score( +raft::resources const& handle, +raft::device_matrix_view X, +raft::device_matrix_view X_embedded, +int n_neighbors, +cuvs::distance::DistanceType metric = cuvs::distance::DistanceType::L2SqrtUnexpanded, +int batch_size = 512); +``` + +modified. + +**Parameters** + +| Name | Direction | Type | Description | +| --- | --- | --- | --- | +| `handle` | in | `raft::resources const&` | the raft handle | +| `X` | in | `raft::device_matrix_view` | : Data in original dimension | +| `X_embedded` | in | `raft::device_matrix_view` | : Data in target dimension (embedding) | +| `n_neighbors` | in | `int` | Number of neighbors considered by trustworthiness score | +| `metric` | in | `cuvs::distance::DistanceType` | Distance metric to use. Euclidean (L2) is used by default Default: `cuvs::distance::DistanceType::L2SqrtUnexpanded`. | +| `batch_size` | in | `int` | Batch size Default: `512`. | + +**Returns** + +`double` + +Trustworthiness score + +_Source: `cpp/include/cuvs/stats/trustworthiness_score.hpp:30`_ diff --git a/fern/pages/cpp_api/index.md b/fern/pages/cpp_api/index.md new file mode 100644 index 0000000000..96932a032c --- /dev/null +++ b/fern/pages/cpp_api/index.md @@ -0,0 +1,30 @@ +# C++ API Documentation + +These pages are generated from the documented public headers in the cuVS source tree. + +- [Agglomerative](/api-reference/cpp-api-cluster-agglomerative) +- [K-Means](/api-reference/cpp-api-cluster-kmeans) +- [Spectral](/api-reference/cpp-api-cluster-spectral) +- [Distance](/api-reference/cpp-api-distance-distance) +- [All Neighbors](/api-reference/cpp-api-neighbors-all-neighbors) +- [Ball Cover](/api-reference/cpp-api-neighbors-ball-cover) +- [Brute Force](/api-reference/cpp-api-neighbors-brute-force) +- [Cagra](/api-reference/cpp-api-neighbors-cagra) +- [Common](/api-reference/cpp-api-neighbors-common) +- [Dynamic Batching](/api-reference/cpp-api-neighbors-dynamic-batching) +- [Epsilon Neighborhood](/api-reference/cpp-api-neighbors-epsilon-neighborhood) +- [HNSW](/api-reference/cpp-api-neighbors-hnsw) +- [IVF Flat](/api-reference/cpp-api-neighbors-ivf-flat) +- [IVF PQ](/api-reference/cpp-api-neighbors-ivf-pq) +- [NN Descent](/api-reference/cpp-api-neighbors-nn-descent) +- [Refine](/api-reference/cpp-api-neighbors-refine) +- [Scann](/api-reference/cpp-api-neighbors-scann) +- [Vamana](/api-reference/cpp-api-neighbors-vamana) +- [PCA](/api-reference/cpp-api-preprocessing-pca) +- [Binary](/api-reference/cpp-api-preprocessing-quantize-binary) +- [PQ](/api-reference/cpp-api-preprocessing-quantize-pq) +- [Scalar](/api-reference/cpp-api-preprocessing-quantize-scalar) +- [Spectral Embedding](/api-reference/cpp-api-preprocessing-spectral-embedding) +- [Select K](/api-reference/cpp-api-selection-select-k) +- [Silhouette Score](/api-reference/cpp-api-stats-silhouette-score) +- [Trustworthiness Score](/api-reference/cpp-api-stats-trustworthiness-score) diff --git a/docs/source/cuvs_bench/build.rst b/fern/pages/cuvs_bench/build.md similarity index 70% rename from docs/source/cuvs_bench/build.rst rename to fern/pages/cuvs_bench/build.md index d579a3424d..ba2f7f622e 100644 --- a/docs/source/cuvs_bench/build.rst +++ b/fern/pages/cuvs_bench/build.md @@ -1,13 +1,10 @@ -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Build cuVS Bench From Source -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Build cuVS Bench From Source -Dependencies -============ +## Dependencies CUDA 12 and a GPU with Volta architecture or later are required to run the benchmarks. -Please refer to the :doc:`installation docs <../build>` for the base requirements to build cuVS. +Please refer to the [installation docs](../build.md) for the base requirements to build cuVS. In addition to the base requirements for building cuVS, additional dependencies needed to build the ANN benchmarks include: @@ -18,31 +15,30 @@ In addition to the base requirements for building cuVS, additional dependencies 5. nlohmann_json 6. GGNN -`rapids-cmake `_ is used to build the ANN benchmarks so the code for dependencies not already supplied in the CUDA toolkit will be downloaded and built automatically. +[rapids-cmake](https://github.com/rapidsai/rapids-cmake) is used to build the ANN benchmarks so the code for dependencies not already supplied in the CUDA toolkit will be downloaded and built automatically. The easiest (and most reproducible) way to install the dependencies needed to build the ANN benchmarks is to use the conda environment file located in the `conda/environments` directory of the cuVS repository. The following command will use `mamba` (which is preferred over `conda`) to build and activate a new environment for compiling the benchmarks: -.. code-block:: bash - - conda env create --name cuvs_benchmarks -f conda/environments/bench_ann_cuda-131_arch-$(uname -m).yaml - conda activate cuvs_benchmarks +```bash +conda env create --name cuvs_benchmarks -f conda/environments/bench_ann_cuda-131_arch-$(uname -m).yaml +conda activate cuvs_benchmarks +``` The above conda environment will also reduce the compile times as dependencies like FAISS will already be installed and not need to be compiled with `rapids-cmake`. -Compiling the Benchmarks -======================== +## Compiling the Benchmarks After the needed dependencies are satisfied, the easiest way to compile ANN benchmarks is through the `build.sh` script in the root of the RAFT source code repository. The following will build the executables for all the support algorithms: -.. code-block:: bash - - ./build.sh bench-ann +```bash +./build.sh bench-ann +``` You can limit the algorithms that are built by providing a semicolon-delimited list of executable names (each algorithm is suffixed with `_ANN_BENCH`): -.. code-block:: bash - - ./build.sh bench-ann -n --limit-bench-ann=HNSWLIB_ANN_BENCH;CUVS_IVF_PQ_ANN_BENCH +```bash +./build.sh bench-ann -n --limit-bench-ann=HNSWLIB_ANN_BENCH;CUVS_IVF_PQ_ANN_BENCH +``` Available targets to use with `--limit-bench-ann` are: diff --git a/docs/source/cuvs_bench/datasets.rst b/fern/pages/cuvs_bench/datasets.md similarity index 57% rename from docs/source/cuvs_bench/datasets.rst rename to fern/pages/cuvs_bench/datasets.md index e6a53ca82b..f06595f24b 100644 --- a/docs/source/cuvs_bench/datasets.rst +++ b/fern/pages/cuvs_bench/datasets.md @@ -1,6 +1,4 @@ -~~~~~~~~~~~~~~~~~~~ -cuVS Bench Datasets -~~~~~~~~~~~~~~~~~~~ +# cuVS Bench Datasets A dataset usually has 4 binary files containing database vectors, query vectors, ground truth neighbors and their corresponding distances. For example, Glove-100 dataset has files `base.fbin` (database vectors), `query.fbin` (query vectors), `groundtruth.neighbors.ibin` (ground truth neighbors), and `groundtruth.distances.fbin` (ground truth distances). The first two files are for index building and searching, while the other two are associated with a particular distance and are used for evaluation. @@ -10,53 +8,52 @@ These binary files are little-endian and the format is: the first 8 bytes are `n Some implementation can take `float16` database and query vectors as inputs and will have better performance. Use `python/cuvs_bench/cuvs_bench/get_dataset/fbin_to_f16bin.py` to transform dataset from `float32` to `float16` type. Commonly used datasets can be downloaded from two websites: -#. Million-scale datasets can be found at the `Data sets `_ section of `ann-benchmarks `_. +1. Million-scale datasets can be found at the [Data sets](https://github.com/erikbern/ann-benchmarks#data-sets) section of [ann-benchmarks](https://github.com/erikbern/ann-benchmarks). However, these datasets are in HDF5 format. Use `python/cuvs_bench/cuvs_bench/get_dataset/hdf5_to_fbin.py` to transform the format. The usage of this script is: - .. code-block:: bash - - $ python/cuvs_bench/cuvs_bench/get_dataset/hdf5_to_fbin.py - usage: hdf5_to_fbin.py [-n] .hdf5 - -n: normalize base/query set - outputs: .base.fbin - .query.fbin - .groundtruth.neighbors.ibin - .groundtruth.distances.fbin + ```bash + $ python/cuvs_bench/cuvs_bench/get_dataset/hdf5_to_fbin.py + usage: hdf5_to_fbin.py [-n] <input>.hdf5 + -n: normalize base/query set + outputs: <input>.base.fbin + <input>.query.fbin + <input>.groundtruth.neighbors.ibin + <input>.groundtruth.distances.fbin + ``` So for an input `.hdf5` file, four output binary files will be produced. See previous section for an example of prepossessing GloVe dataset. Most datasets provided by `ann-benchmarks` use `Angular` or `Euclidean` distance. `Angular` denotes cosine distance. However, computing cosine distance reduces to computing inner product by normalizing vectors beforehand. In practice, we can always do the normalization to decrease computation cost, so it's better to measure the performance of inner product rather than cosine distance. The `-n` option of `hdf5_to_fbin.py` can be used to normalize the dataset. -#. Billion-scale datasets can be found at `big-ann-benchmarks `_. The ground truth file contains both neighbors and distances, thus should be split. A script is provided for this: +1. Billion-scale datasets can be found at [big-ann-benchmarks](http://big-ann-benchmarks.com). The ground truth file contains both neighbors and distances, thus should be split. A script is provided for this: Take Deep-1B dataset as an example: - .. code-block:: bash - - mkdir -p data/deep-1B && cd data/deep-1B + ```bash + mkdir -p data/deep-1B && cd data/deep-1B - # download manually "Ground Truth" file of "Yandex DEEP" - # suppose the file name is deep_new_groundtruth.public.10K.bin - python -m cuvs_bench.split_groundtruth deep_new_groundtruth.public.10K.bin groundtruth + # download manually "Ground Truth" file of "Yandex DEEP" + # suppose the file name is deep_new_groundtruth.public.10K.bin + python -m cuvs_bench.split_groundtruth deep_new_groundtruth.public.10K.bin groundtruth - # two files 'groundtruth.neighbors.ibin' and 'groundtruth.distances.fbin' should be produced + # two files 'groundtruth.neighbors.ibin' and 'groundtruth.distances.fbin' should be produced + ``` Besides ground truth files for the whole billion-scale datasets, this site also provides ground truth files for the first 10M or 100M vectors of the base sets. This mean we can use these billion-scale datasets as million-scale datasets. To facilitate this, an optional parameter `subset_size` for dataset can be used. See the next step for further explanation. -Generate ground truth -===================== +## Generate ground truth If you have a dataset, but no corresponding ground truth file, then you can generate ground trunth using the `generate_groundtruth` utility. Example usage: -.. code-block:: bash - - # With existing query file - python -m cuvs_bench.generate_groundtruth --dataset /dataset/base.fbin --output=groundtruth_dir --queries=/dataset/query.public.10K.fbin +```bash +# With existing query file +python -m cuvs_bench.generate_groundtruth --dataset /dataset/base.fbin --output=groundtruth_dir --queries=/dataset/query.public.10K.fbin - # With randomly generated queries - python -m cuvs_bench.generate_groundtruth --dataset /dataset/base.fbin --output=groundtruth_dir --queries=random --n_queries=10000 +# With randomly generated queries +python -m cuvs_bench.generate_groundtruth --dataset /dataset/base.fbin --output=groundtruth_dir --queries=random --n_queries=10000 - # Using only a subset of the dataset. Define queries by randomly - # selecting vectors from the (subset of the) dataset. - python -m cuvs_bench.generate_groundtruth --dataset /dataset/base.fbin --nrows=2000000 --output=groundtruth_dir --queries=random-choice --n_queries=10000 +# Using only a subset of the dataset. Define queries by randomly +# selecting vectors from the (subset of the) dataset. +python -m cuvs_bench.generate_groundtruth --dataset /dataset/base.fbin --nrows=2000000 --output=groundtruth_dir --queries=random-choice --n_queries=10000 +``` diff --git a/fern/pages/cuvs_bench/index.md b/fern/pages/cuvs_bench/index.md new file mode 100644 index 0000000000..70b589c9e0 --- /dev/null +++ b/fern/pages/cuvs_bench/index.md @@ -0,0 +1,512 @@ +# cuVS Bench + +cuVS bench provides a reproducible benchmarking tool for various ANN search implementations. It's especially suitable for comparing GPU implementations as well as comparing GPU against CPU. One of the primary goals of cuVS is to capture ideal index configurations for a variety of important usage patterns so the results can be reproduced easily on different hardware environments, such as on-prem and cloud. + +This tool offers several benefits, including + +1. Making fair comparisons of index build times + +1. Making fair comparisons of index search throughput and/or latency + +1. Finding the optimal parameter settings for a range of recall buckets + +1. Easily generating consistently styled plots for index build and search + +1. Profiling blind spots and potential for algorithm optimization + +1. Investigating the relationship between different parameter settings, index build times, and search performance. + +- [Installing the benchmarks](#installing-the-benchmarks) + + * [Conda](#conda) + + * [Docker](#docker) + +- [Running the benchmarks](#running-the-benchmarks) + + * [End-to-end: smaller-scale benchmarks (<1M to 10M)](#end-to-end-smaller-scale-benchmarks-1m-to-10m) + + * [End-to-end: large-scale benchmarks (>10M vectors)](#end-to-end-large-scale-benchmarks-10m-vectors) + + * [Running with Docker containers](#running-with-docker-containers) + + * [End-to-end run on GPU](#end-to-end-run-on-gpu) + + * [Manually run the scripts inside the container](#manually-run-the-scripts-inside-the-container) + + * [Evaluating the results](#evaluating-the-results) + +- [Creating and customizing dataset configurations](#creating-and-customizing-dataset-configurations) + + * [Multi-GPU benchmarks](#multi-gpu-benchmarks) + +- [Adding a new index algorithm](#adding-a-new-index-algorithm) + + * [Implementation and configuration](#implementation-and-configuration) + + * [Adding a Cmake target](#adding-a-cmake-target) + +## Installing the benchmarks + +There are two main ways pre-compiled benchmarks are distributed: + +- [Conda](#conda) For users not using containers but want an easy to install and use Python package. Pip wheels are planned to be added as an alternative for users that cannot use conda and prefer to not use containers. +- [Docker](#docker) Only needs docker and [NVIDIA docker](https://github.com/NVIDIA/nvidia-docker) to use. Provides a single docker run command for basic dataset benchmarking, as well as all the functionality of the conda solution inside the containers. + +### Conda + +```bash +conda create --name cuvs_benchmarks +conda activate cuvs_benchmarks + +# to install GPU package: +conda install -c rapidsai -c conda-forge cuvs-bench= cuda-version=13.1* + +# to install CPU package for usage in CPU-only systems: +conda install -c rapidsai -c conda-forge cuvs-bench-cpu +``` + +The channel `rapidsai` can easily be substituted with `rapidsai-nightly` if nightly benchmarks are desired. The CPU package currently allows to run the HNSW benchmarks. + +Please see the [build instructions](build.md) to build the benchmarks from source. + +### Docker + +We provide images for GPU enabled systems, as well as systems without a GPU. The following images are available: + +- `cuvs-bench`: Contains GPU and CPU benchmarks, can run all algorithms supported. Will download million-scale datasets as required. Best suited for users that prefer a smaller container size for GPU based systems. Requires the NVIDIA Container Toolkit to run GPU algorithms, can run CPU algorithms without it. +- `cuvs-bench-cpu`: Contains only CPU benchmarks with minimal size. Best suited for users that want the smallest containers to reproduce benchmarks on systems without a GPU. + +Nightly images are located in [dockerhub](https://hub.docker.com/r/rapidsai/cuvs-bench/tags). + +The following command pulls the nightly container for Python version 3.13, CUDA version 12.9, and cuVS version 26.06: + +```bash +docker pull rapidsai/cuvs-bench:26.06a-cuda12-py3.13 # substitute cuvs-bench for the exact desired container. +``` + +The CUDA and python versions can be changed for the supported values: +- Supported CUDA versions: 12, 13 +- Supported Python versions: 3.11, 3.11, 3.13, and 3.14 + +You can see the exact versions as well in the dockerhub site: +- [cuVS bench images](https://hub.docker.com/r/rapidsai/cuvs-bench/tags) +- [cuVS bench CPU only images](https://hub.docker.com/r/rapidsai/cuvs-bench-cpu/tags) + +**Note:** GPU containers use the CUDA toolkit from inside the container, the only requirement is a driver installed on the host machine that supports that version. So, for example, CUDA 12 containers can run in systems with a CUDA 13.x capable driver. Please also note that the Nvidia-Docker runtime from the [Nvidia Container Toolkit](https://github.com/NVIDIA/nvidia-docker) is required to use GPUs inside docker containers. + +## Running the benchmarks + +### End-to-end: smaller-scale benchmarks (<1M to 10M) + +The steps below demonstrate how to download, install, and run benchmarks on a subset of 10M vectors from the Yandex Deep-1B dataset. By default the datasets will be stored and used from the folder indicated by the `RAPIDS_DATASET_ROOT_DIR` environment variable if defined, otherwise a datasets sub-folder from where the script is being called. + +```bash +# (1) Prepare dataset. +python -m cuvs_bench.get_dataset --dataset deep-image-96-angular --normalize +``` + +```python +# (2) Build and search index. +from cuvs_bench.orchestrator import BenchmarkOrchestrator + +orchestrator = BenchmarkOrchestrator(backend_type="cpp_gbench") +results = orchestrator.run_benchmark( + dataset="deep-image-96-inner", + algorithms="cuvs_cagra", + count=10, + batch_size=10, + build=True, + search=True, +) +``` + +```bash +# (3) Export data. +python -m cuvs_bench.run --data-export --dataset deep-image-96-inner + +# (4) Plot results. +python -m cuvs_bench.plot --dataset deep-image-96-inner +``` + +| Dataset name | Train rows | Columns | Test rows | Distance | +| --- | --- | --- | --- | --- | +| `deep-image-96-angular` | 10M | 96 | 10K | Angular | +| `fashion-mnist-784-euclidean` | 60K | 784 | 10K | Euclidean | +| `glove-50-angular` | 1.1M | 50 | 10K | Angular | +| `glove-100-angular` | 1.1M | 100 | 10K | Angular | +| `mnist-784-euclidean` | 60K | 784 | 10K | Euclidean | +| `nytimes-256-angular` | 290K | 256 | 10K | Angular | +| `sift-128-euclidean` | 1M | 128 | 10K | Euclidean | + +All of the datasets above contain ground test datasets with 100 neighbors. Thus `k` for these datasets must be less than or equal to 100. + +### End-to-end: large-scale benchmarks (>10M vectors) + +`cuvs_bench.get_dataset` cannot be used to download the billion-scale datasets due to their size. You should instead use our billion-scale datasets guide to download and prepare them. +All other python commands mentioned below work as intended once the billion-scale dataset has been downloaded. + +To download billion-scale datasets, visit [big-ann-benchmarks](http://big-ann-benchmarks.com/neurips21.html) + +We also provide a new dataset called `wiki-all` containing 88 million 768-dimensional vectors. This dataset is meant for benchmarking a realistic retrieval-augmented generation (RAG)/LLM embedding size at scale. It also contains 1M and 10M vector subsets for smaller-scale experiments. See our [Wiki-all Dataset Guide](wiki_all_dataset.md) for more information and to download the dataset. + +The steps below demonstrate how to download, install, and run benchmarks on a subset of 100M vectors from the Yandex Deep-1B dataset. Please note that datasets of this scale are recommended for GPUs with larger amounts of memory, such as the A100 or H100. + +```bash +mkdir -p datasets/deep-1B +# (1) Prepare dataset. +# download manually "Ground Truth" file of "Yandex DEEP" +# suppose the file name is deep_new_groundtruth.public.10K.bin +python -m cuvs_bench.split_groundtruth --groundtruth datasets/deep-1B/deep_new_groundtruth.public.10K.bin +# two files 'groundtruth.neighbors.ibin' and 'groundtruth.distances.fbin' should be produced +``` + +```python +# (2) Build and search index. +from cuvs_bench.orchestrator import BenchmarkOrchestrator + +orchestrator = BenchmarkOrchestrator(backend_type="cpp_gbench") +results = orchestrator.run_benchmark( + dataset="deep-1B", + algorithms="cuvs_cagra", + count=10, + batch_size=10, + build=True, + search=True, +) +``` + +```bash +# (3) Export data. +python -m cuvs_bench.run --data-export --dataset deep-1B + +# (4) Plot results. +python -m cuvs_bench.plot --dataset deep-1B +``` + +The usage of `python -m cuvs_bench.split_groundtruth` is: + +```bash +usage: split_groundtruth.py [-h] --groundtruth GROUNDTRUTH + +options: + -h, --help show this help message and exit + --groundtruth GROUNDTRUTH + Path to billion-scale dataset groundtruth file (default: None) +``` + +### Testing on new datasets + +To run benchmark on a dataset, it is required have a descriptor that defines the file names and a few other properties of that dataset. +Descriptors for several popular datasets are already available in [datasets.yaml](https://github.com/rapidsai/cuvs/blob/branch-25.04/python/cuvs_bench/cuvs_bench/config/datasets/datasets.yaml). + +Let's consider how to test on a new dataset. First we create a descriptor `mydataset.yaml` + +```yaml +- name: mydata-1M + base_file: mydata-1M/base.100M.u8bin + subset_size: 1000000 + dims: 128 + query_file: mydata-10M/queries.u8bin + groundtruth_neighbors_file: mydata-1M/groundtruth.neighbors.ibin + distance: euclidean +``` + +Here `name` can be chosen arbitrarily. We pass `name` as the `--dataset` argument for the benchmark. The file names are relative to the path given by `--dataset-path` argument. +The `subset_size` field is optional. This argument defines how many vectors to use from the dataset file, the first `subset_size` vectors will be used. +This way you can define benchmarks on multiple subsets of the same dataset without duplicating the dataset vectors. +Note that the ground truth vectors have to be generated for each subset separately. + +To run the benchmark on the newly defined `mydata-1M` dataset, you can use the following command line: + +```bash +python -m cuvs_bench.run --dataset mydata-1M --dataset-path=/path/to/data/folder --dataset-configuration=mydataset.yaml --algorithms=cuvs_cagra +``` + +### Running with Docker containers + +Two methods are provided for running the benchmarks with the Docker containers. + +#### End-to-end run on GPU + +When no other entrypoint is provided, an end-to-end script will run through all the steps in [Running the benchmarks](#running-the-benchmarks) above. + +For GPU-enabled systems, the `DATA_FOLDER` variable should be a local folder where you want datasets stored in `$DATA_FOLDER/datasets` and results in `$DATA_FOLDER/result` (we highly recommend `$DATA_FOLDER` to be a dedicated folder for the datasets and results of the containers): + +```bash +export DATA_FOLDER=path/to/store/datasets/and/results +docker run --gpus all --rm -it -u $(id -u) \ + -v $DATA_FOLDER:/data/benchmarks \ + rapidsai/cuvs-bench:26.06a-cuda12-py3.13 \ + "--dataset deep-image-96-angular" \ + "--normalize" \ + "--algorithms cuvs_cagra,cuvs_ivf_pq --batch-size 10 -k 10" \ + "" +``` + +Usage of the above command is as follows: + +| Argument | Description | +| --- | --- | +| `rapidsai/cuvs-bench:26.06a-cuda12-py3.13` | Image to use. See "Docker" section for links to lists of available tags. | +| `"--dataset deep-image-96-angular"` | Dataset name | +| `"--normalize"` | Whether to normalize the dataset | +| `"--algorithms cuvs_cagra,hnswlib --batch-size 10 -k 10"` | Arguments passed to the `run` script, such as the algorithms to benchmark, the batch size, and `k` | +| `""` | Additional (optional) arguments that will be passed to the `plot` script. | + +***Note about user and file permissions:*** The flag `-u $(id -u)` allows the user inside the container to match the `uid` of the user outside the container, allowing the container to read and write to the mounted volume indicated by the `$DATA_FOLDER` variable. + +#### End-to-end run on CPU + +The container arguments in the above section also be used for the CPU-only container, which can be used on systems that don't have a GPU installed. + +***Note:*** the image changes to `cuvs-bench-cpu` container and the `--gpus all` argument is no longer used: + +```bash +export DATA_FOLDER=path/to/store/datasets/and/results +docker run --rm -it -u $(id -u) \ + -v $DATA_FOLDER:/data/benchmarks \ + rapidsai/cuvs-bench-cpu:26.06a-py3.13 \ + "--dataset deep-image-96-angular" \ + "--normalize" \ + "--algorithms hnswlib --batch-size 10 -k 10" \ + "" +``` + +#### Manually run the scripts inside the container + +All of the `cuvs-bench` images contain the Conda packages, so they can be used directly by logging directly into the container itself: + +```bash +export DATA_FOLDER=path/to/store/datasets/and/results +docker run --gpus all --rm -it -u $(id -u) \ + --entrypoint /bin/bash \ + --workdir /data/benchmarks \ + -v $DATA_FOLDER:/data/benchmarks \ + rapidsai/cuvs-bench:26.06a-cuda12-py3.13 +``` + +This will drop you into a command line in the container, with the `cuvs-bench` python package ready to use, as described in the [Running the benchmarks](#running-the-benchmarks) section above: + +```bash +(base) root@00b068fbb862:/data/benchmarks# python -m cuvs_bench.get_dataset --dataset deep-image-96-angular --normalize +``` + +Additionally, the containers can be run in detached mode without any issue. + +### Evaluating the results + +The benchmarks capture several different measurements. The table below describes each of the measurements for index build benchmarks: + +| Name | Description | +| --- | --- | +| Benchmark | A name that uniquely identifies the benchmark instance | +| Time | Wall-time spent training the index | +| CPU | CPU time spent training the index | +| Iterations | Number of iterations (this is usually 1) | +| GPU | GU time spent building | +| index_size | Number of vectors used to train index | + +The table below describes each of the measurements for the index search benchmarks. The most important measurements `Latency`, `items_per_second`, `end_to_end`. + +| Name | Description | +| --- | --- | +| Benchmark | A name that uniquely identifies the benchmark instance | +| Time | The wall-clock time of a single iteration (batch) divided by the number of threads. | +| CPU | The average CPU time (user + sys time). This does not include idle time (which can also happen while waiting for GPU sync). | +| Iterations | Total number of batches. This is going to be `total_queries` / `n_queries`. | +| GPU | GPU latency of a single batch (seconds). In throughput mode this is averaged over multiple threads. | +| Latency | Latency of a single batch (seconds), calculated from wall-clock time. In throughput mode this is averaged over multiple threads. | +| Recall | Proportion of correct neighbors to ground truth neighbors. Note this column is only present if groundtruth file is specified in dataset configuration. | +| items_per_second | Total throughput, a.k.a Queries per second (QPS). This is approximately `total_queries` / `end_to_end`. | +| k | Number of neighbors being queried in each iteration | +| end_to_end | Total time taken to run all batches for all iterations | +| n_queries | Total number of query vectors in each batch | +| total_queries | Total number of vectors queries across all iterations ( = `iterations` * `n_queries`) | + +Note the following: +- A slightly different method is used to measure `Time` and `end_to_end`. That is why `end_to_end` = `Time` * `Iterations` holds only approximately. +- The actual table displayed on the screen may differ slightly as the hyper-parameters will also be displayed for each different combination being benchmarked. +- Recall calculation: the number of queries processed per test depends on the number of iterations. Because of this, recall can show slight fluctuations if less neighbors are processed then it is available for the benchmark. + +## Creating and customizing dataset configurations + +A single configuration will often define a set of algorithms, with associated index and search parameters, that can be generalize across datasets. We use YAML to define dataset specific and algorithm specific configurations. + +A default `datasets.yaml` is provided by CUVS in `${CUVS_HOME}/python/cuvs_bench/cuvs_bench/config/datasets/datasets.yaml` with configurations available for several datasets. Here's a simple example entry for the `sift-128-euclidean` dataset: + +```yaml +- name: sift-128-euclidean + base_file: sift-128-euclidean/base.fbin + query_file: sift-128-euclidean/query.fbin + groundtruth_neighbors_file: sift-128-euclidean/groundtruth.neighbors.ibin + dims: 128 + distance: euclidean +``` + +Configuration files for ANN algorithms supported by `cuvs-bench` are provided in `${CUVS_HOME}/python/cuvs_bench/cuvs_bench/config/algos`. `cuvs_cagra` algorithm configuration looks like: + +```yaml +name: cuvs_cagra +constraints: + build: cuvs_bench.config.algos.constraints.cuvs_cagra_build + search: cuvs_bench.config.algos.constraints.cuvs_cagra_search +groups: + base: + build: + graph_degree: [32, 64] + intermediate_graph_degree: [64, 96] + graph_build_algo: ["NN_DESCENT"] + search: + itopk: [32, 64, 128] + + large: + build: + graph_degree: [32, 64] + search: + itopk: [32, 64, 128] +``` + +The default parameters for which the benchmarks are run can be overridden by creating a custom YAML file for algorithms with a `base` group. + +The config above has 3 fields: + +1. `name` - The name of the algorithm for which the parameters are being specified. +2. `constraints` - Optional. Python import paths to functions that validate build and search parameter combinations (e.g. `cuvs_bench.config.algos.constraints.cuvs_cagra_build`). Each function returns `True` if the parameters are valid, `False` otherwise; invalid combinations are skipped and not benchmarked. +3. `groups` - Run groups, each with a set of parameters. Each group defines a cross-product of all hyper-parameter fields for `build` and `search`. + +The table below contains all algorithms supported by cuVS. Each unique algorithm will have its own set of `build` and `search` settings. The [ANN Algorithm Parameter Tuning Guide](param_tuning.md) contains detailed instructions on choosing build and search parameters for each supported algorithm. + +| Library | Algorithms | +| --- | --- | +| FAISS_GPU | `faiss_gpu_flat`, `faiss_gpu_ivf_flat`, `faiss_gpu_ivf_pq`, `faiss_gpu_cagra` | +| FAISS_CPU | `faiss_cpu_flat`, `faiss_cpu_ivf_flat`, `faiss_cpu_ivf_pq`, `faiss_cpu_hnsw_flat` | +| GGNN | `ggnn` | +| HNSWLIB | `hnswlib` | +| DiskANN | `diskann_memory`, `diskann_ssd` | +| cuVS | `cuvs_brute_force`, `cuvs_cagra`, `cuvs_ivf_flat`, `cuvs_ivf_pq`, `cuvs_cagra_hnswlib`, `cuvs_vamana` | + +### Multi-GPU benchmarks + +cuVS implements single node multi-GPU versions of IVF-Flat, IVF-PQ and CAGRA indexes. + +| Index type | Multi-GPU algo name | +| --- | --- | +| IVF-Flat | `cuvs_mg_ivf_flat` | +| IVF-PQ | `cuvs_mg_ivf_pq` | +| CAGRA | `cuvs_mg_cagra` | + +## Adding a new index algorithm + +### Implementation and configuration + +Implementation of a new algorithm should be a C++ class that inherits `class ANN` (defined in `cpp/bench/ann/src/ann.h`) and implements all the pure virtual functions. + +In addition, it should define two `struct`s for building and searching parameters. The searching parameter class should inherit `struct ANN<T>::AnnSearchParam`. Take `class HnswLib` as an example, its definition is: + +```c++ +template +class HnswLib : public ANN { +public: + struct BuildParam { + int M; + int ef_construction; + int num_threads; + }; + + using typename ANN::AnnSearchParam; + struct SearchParam : public AnnSearchParam { + int ef; + int num_threads; + }; + + // ... +}; +``` + +The benchmark program uses JSON format natively in a configuration file to specify indexes to build, along with the build and search parameters. However the JSON config files are overly verbose and are not meant to be used directly. Instead, the Python scripts parse YAML and create these json files automatically. It's important to realize that these json objects align with the yaml objects for `build_param`, whose value is a JSON object, and `search_param`, whose value is an array of JSON objects. Take the json configuration for `HnswLib` as an example of the json after it's been parsed from yaml: + +```json +{ + "name" : "hnswlib.M12.ef500.th32", + "algo" : "hnswlib", + "build_param": {"M":12, "efConstruction":500, "numThreads":32}, + "file" : "/path/to/file", + "search_params" : [ + {"ef":10, "numThreads":1}, + {"ef":20, "numThreads":1}, + {"ef":40, "numThreads":1}, + ], + "search_result_file" : "/path/to/file" +}, +``` + +The build and search params are ultimately passed to the C++ layer as json objects for each param configuration to benchmark. The code below shows how to parse these params for `Hnswlib`: + +1. First, add two functions for parsing JSON object to `struct BuildParam` and `struct SearchParam`, respectively: + +```c++ +template +void parse_build_param(const nlohmann::json& conf, + typename cuann::HnswLib::BuildParam& param) { + param.ef_construction = conf.at("efConstruction"); + param.M = conf.at("M"); + if (conf.contains("numThreads")) { + param.num_threads = conf.at("numThreads"); + } +} + +template +void parse_search_param(const nlohmann::json& conf, + typename cuann::HnswLib::SearchParam& param) { + param.ef = conf.at("ef"); + if (conf.contains("numThreads")) { + param.num_threads = conf.at("numThreads"); + } +} +``` + +2. Next, add corresponding `if` case to functions `create_algo()` (in `cpp/bench/ann/) and `create_search_param()` by calling parsing functions. The string literal in `if` condition statement must be the same as the value of `algo` in configuration file. For example, + +```c++ +// JSON configuration file contains a line like: "algo" : "hnswlib" +if (algo == "hnswlib") { + // ... +} +``` + +### Adding a Cmake target + +In `cuvs/cpp/bench/ann/CMakeLists.txt`, we provide a `CMake` function to configure a new Benchmark target with the following signature: + +```cmake +ConfigureAnnBench( + NAME + PATH + INCLUDES + CXXFLAGS + LINKS +) +``` + +To add a target for `HNSWLIB`, we would call the function as: + +```cmake +ConfigureAnnBench( + NAME HNSWLIB PATH bench/ann/src/hnswlib/hnswlib_benchmark.cpp INCLUDES + ${CMAKE_CURRENT_BINARY_DIR}/_deps/hnswlib-src/hnswlib CXXFLAGS "${HNSW_CXX_FLAGS}" +) +``` + +This will create an executable called `HNSWLIB_ANN_BENCH`, which can then be used to run `HNSWLIB` benchmarks. + +Add a new entry to `algos.yaml` to map the name of the algorithm to its binary executable and specify whether the algorithm requires GPU support. + +```yaml +cuvs_ivf_pq: + executable: CUVS_IVF_PQ_ANN_BENCH + requires_gpu: true +``` + +`executable` : specifies the name of the binary that will build/search the index. It is assumed to be available in `cuvs/cpp/build/`. +`requires_gpu` : denotes whether an algorithm requires GPU to run. diff --git a/fern/pages/cuvs_bench/param_tuning.md b/fern/pages/cuvs_bench/param_tuning.md new file mode 100644 index 0000000000..e5150fd63f --- /dev/null +++ b/fern/pages/cuvs_bench/param_tuning.md @@ -0,0 +1,251 @@ +# cuVS Bench Parameter Tuning Guide + +This guide outlines the various parameter settings that can be specified in [cuVS Benchmarks](index.md) yaml configuration files and explains the impact they have on corresponding algorithms to help inform their settings for benchmarking across desired levels of recall. + +## Benchmark modes + +When you run benchmarks with `BenchmarkOrchestrator.run_benchmark()`, you can choose how parameters are explored: + +**Sweep mode (default)** + +Pass `mode="sweep"` or omit `mode`. The orchestrator builds the full Cartesian product of all build and search parameter lists defined in the algorithm YAML (see [Creating and customizing dataset configurations](index.md)). Every valid combination (after constraint filtering) is run. Use this for exhaustive comparison across the configured parameter grid. + +**Tune mode** + +Pass `mode="tune"` to perform hyperparameter optimization using Optuna instead of running every combination. You must pass: + +- **constraints** (dict): The optimization target and optional bounds. One metric must be `"maximize"` or `"minimize"` (the goal). Others can set hard limits with `{"min": X}` or `{"max": X}`. Examples: `{"recall": "maximize", "latency": {"max": 10}}` or `{"latency": "minimize", "recall": {"min": 0.95}}`. +- **n_trials** (int, optional): Maximum number of Optuna trials (default 100). Ignored in sweep mode. + +Example: + +```python +results = orchestrator.run_benchmark( + mode="tune", + dataset="deep-image-96-inner", + algorithms="cuvs_cagra", + constraints={"recall": "maximize", "latency": {"max": 5.0}}, + n_trials=50, + count=10, + batch_size=10, +) +``` + +The parameter tables below describe the build and search knobs that sweep mode varies and that tune mode can optimize. + +## cuVS Indexes + +### cuvs_brute_force + +Use cuVS brute-force index for exact search. Brute-force has no further build or search parameters. + +### cuvs_ivf_flat + +IVF-flat uses an inverted-file index, which partitions the vectors into a series of clusters, or lists, storing them in an interleaved format which is optimized for fast distance computation. The searching of an IVF-flat index reduces the total vectors in the index to those within some user-specified nearest clusters called probes. + +IVF-flat is a simple algorithm which won't save any space, but it provides competitive search times even at higher levels of recall. + +| Parameter | Type | Required | Data Type | Default | Description | +| --- | --- | --- | --- | --- | --- | +| `nlist` | `build` | Y | Positive integer >0 | 1024 | Number of clusters to partition the vectors into. Larger values will put less points into each cluster but this will impact index build time as more clusters need to be trained. | +| `niter` | `build` | N | Positive integer >0 | 20 | Number of kmeans iterations to use when training the ivf clusters | +| `ratio` | `build` | N | Positive integer >0 | 2 | `1/ratio` is the number of training points which should be used to train the clusters. | +| `dataset_memory_type` | `build` | N | [`device`, `host`, `mmap`] | `mmap` | Where should the dataset reside? | +| `query_memory_type` | `search` | N | [`device`, `host`, `mmap`] | `device` | Where should the queries reside? | +| `nprobe` | `search` | Y | Positive integer >0 | | The closest number of clusters to search for each query vector. Larger values will improve recall but will search more points in the index. | + +### cuvs_ivf_pq + +IVF-pq is an inverted-file index, which partitions the vectors into a series of clusters, or lists, in a similar way to IVF-flat above. The difference is that IVF-PQ uses product quantization to also compress the vectors, giving the index a smaller memory footprint. Unfortunately, higher levels of compression can also shrink recall, which a refinement step can improve when the original vectors are still available. + +| Parameter | Type | Required | Data Type | Default | Description | +| --- | --- | --- | --- | --- | --- | +| `nlist` | `build` | Y | Positive integer >0 | 1024 | Number of clusters to partition the vectors into. Larger values will put less points into each cluster but this will impact index build time as more clusters need to be trained. | +| `niter` | `build` | N | Positive integer >0 | 20 | Number of kmeans iterations to use when training the ivf clusters | +| `ratio` | `build` | N | Positive integer >0 | 2 | `1/ratio` is the number of training points which should be used to train the clusters. | +| `pq_dim` | `build` | N | Positive integer. Multiple of 8. | 0 | Dimensionality of the vector after product quantization. When 0, a heuristic is used to select this value. | +| `pq_bits` | `build` | N | Positive integer [4-8] | 8 | Bit length of the vector element after quantization. | +| `codebook_kind` | `build` | N | [`cluster`, `subspace`] | `subspace` | Type of codebook. See [IVF-PQ index overview](../neighbors/ivfpq.md) for more detail | +| `dataset_memory_type` | `build` | N | [`device`, `host`, `mmap`] | `mmap` | Where should the dataset reside? | +| `query_memory_type` | `search` | N | [`device`, `host`, `mmap`] | `device` | Where should the queries reside? | +| `nprobe` | `search` | Y | Positive integer >0 | 20 | The closest number of clusters to search for each query vector. Larger values will improve recall but will search more points in the index. | +| `internalDistanceDtype` | `search` | N | [`float`, `half`] | `half` | The precision to use for the distance computations. Lower precision can increase performance at the cost of accuracy. | +| `smemLutDtype` | `search` | N | [`float`, `half`, `fp8`] | `half` | The precision to use for the lookup table in shared memory. Lower precision can increase performance at the cost of accuracy. | +| `refine_ratio` | `search` | N | Positive integer >0 | 1 | `refine_ratio * k` nearest neighbors are queried from the index initially and an additional refinement step improves recall by selecting only the best `k` neighbors. | + +### cuvs_cagra + +CAGRA uses a graph-based index, which creates an intermediate, approximate kNN graph using IVF-PQ and then further refining and optimizing to create a final kNN graph. This kNN graph is used by CAGRA as an index for search. + +| Parameter | Type | Required | Data Type | Default | Description | +| --- | --- | --- | --- | --- | --- | +| `graph_degree` | `build` | N | Positive integer >0 | 64 | Degree of the final kNN graph index. | +| `intermediate_graph_degree` | `build` | N | Positive integer >0 | 128 | Degree of the intermediate kNN graph before the CAGRA graph is optimized | +| `graph_build_algo` | `build` | `N` | [`IVF_PQ`, `NN_DESCENT`, `ACE`] | `IVF_PQ` | Algorithm to use for building the initial kNN graph, from which CAGRA will optimize into the navigable CAGRA graph | +| `dataset_memory_type` | `build` | N | [`device`, `host`, `mmap`] | `mmap` | Where should the dataset reside? | +| `npartitions` | `build` | N | Positive integer >0 | 1 | The number of partitions to use for the ACE build. Small values might improve recall but potentially degrade performance and increase memory usage. Partitions should not be too small to prevent issues in KNN graph construction. The partition size is on average 2 * (n_rows / npartitions) * dim * sizeof(T). 2 is because of the core and augmented vectors. Please account for imbalance in the partition sizes (up to 3x in our tests). | +| `build_dir` | `build` | N | String | "/tmp/ace_build" | The directory to use for the ACE build. Must be specified when using ACE build. This should be the fastest disk in the system and hold enough space for twice the dataset, final graph, and label mapping. | +| `ef_construction` | `build` | Y | Positive integer >0 | 120 | Controls index time and accuracy when using ACE build. Bigger values increase the index quality. At some point, increasing this will no longer improve the quality. | +| `use_disk` | `build` | N | Boolean | `false` | Whether to use disk-based storage for ACE build. When true, forces ACE to use disk-based storage even if the graph fits in host and GPU memory. When false, ACE will use in-memory storage if the graph fits in host and GPU memory and disk-based storage otherwise. | +| `query_memory_type` | `search` | N | [`device`, `host`, `mmap`] | `device` | Where should the queries reside? | +| `itopk` | `search` | N | Positive integer >0 | 64 | Number of intermediate search results retained during the search. Higher values improve search accuracy at the cost of speed | +| `search_width` | `search` | N | Positive integer >0 | 1 | Number of graph nodes to select as the starting point for the search in each iteration. | +| `max_iterations` | `search` | N | Positive integer >=0 | 0 | Upper limit of search iterations. Auto select when 0 | +| `algo` | `search` | N | [`auto`, `single_cta`, `multi_cta`, `multi_kernel`] | `auto` | Algorithm to use for search. It's usually best to leave this to `auto`. | +| `graph_memory_type` | `search` | N | [`device`, `host_pinned`, `host_huge_page`] | `device` | Memory type to store graph | +| `internal_dataset_memory_type` | `search` | N | [`device`, `host_pinned`, `host_huge_page`] | `device` | Memory type to store dataset | + +The `graph_memory_type` or `internal_dataset_memory_type` options can be useful for large datasets that do not fit the device memory. Setting `internal_dataset_memory_type` other than `device` has negative impact on search speed. Using `host_huge_page` option is only supported on systems with Heterogeneous Memory Management or on platforms that natively support GPU access to system allocated memory, for example Grace Hopper. + +To fine tune CAGRA index building we can customize IVF-PQ index builder options using the following settings. These take effect only if `graph_build_algo == "IVF_PQ"`. It is recommended to experiment using a separate IVF-PQ index to find the config that gives the largest QPS for large batch. Recall does not need to be very high, since CAGRA further optimizes the kNN neighbor graph. Some of the default values are derived from the dataset size which is assumed to be [n_vecs, dim]. + +| Parameter | Type | Required | Data Type | Default | Description | +| --- | --- | --- | --- | --- | --- | +| `ivf_pq_build_nlist` | `build` | N | Positive integer >0 | sqrt(n_vecs) | Number of clusters to partition the vectors into. Larger values will put less points into each cluster but this will impact index build time as more clusters need to be trained. | +| `ivf_pq_build_niter` | `build` | N | Positive integer >0 | 25 | Number of k-means iterations to use when training the clusters. | +| `ivf_pq_build_ratio` | `build` | N | Positive integer >0 | 10 | `1/ratio` is the number of training points which should be used to train the clusters. | +| `ivf_pq_pq_dim` | `build` | N | Positive integer. Multiple of 8 | dim/2 rounded up to 8 | Dimensionality of the vector after product quantization. When 0, a heuristic is used to select this value. `pq_dim` * `pq_bits` must be a multiple of 8. | +| `ivf_pq_build_pq_bits` | `build` | N | Positive integer [4-8] | 8 | Bit length of the vector element after quantization. | +| `ivf_pq_build_codebook_kind` | `build` | N | [`cluster`, `subspace`] | `subspace` | Type of codebook. See [IVF-PQ index overview](../neighbors/ivfpq.md) for more detail | +| `ivf_pq_build_nprobe` | `search` | N | Positive integer >0 | min(2*dim, nlist) | The closest number of clusters to search for each query vector. Larger values will improve recall but will search more points in the index. | +| `ivf_pq_build_internalDistanceDtype` | `search` | N | [`float`, `half`] | `half` | The precision to use for the distance computations. Lower precision can increase performance at the cost of accuracy. | +| `ivf_pq_build_smemLutDtype` | `search` | N | [`float`, `half`, `fp8`] | `fp8` | The precision to use for the lookup table in shared memory. Lower precision can increase performance at the cost of accuracy. | +| `ivf_pq_build_refine_ratio` | `search` | N | Positive integer >0 | 2 | `refine_ratio * k` nearest neighbors are queried from the index initially and an additional refinement step improves recall by selecting only the best `k` neighbors. | + +Alternatively, if `graph_build_algo == "NN_DESCENT"`, then we can customize the following parameters + +| Parameter | Type | Required | Data Type | Default | Description | +| --- | --- | --- | --- | --- | --- | +| `nn_descent_niter` | `build` | N | Positive integer >0 | 20 | Number of nn-descent iterations | +| `nn_descent_intermediate_graph_degree` | `build` | N | Positive integer >0 | `cagra.intermediate_graph_degree` * 1.5 | Intermadiate graph degree during nn-descent iterations | +| nn_descent_termination_threshold | `build` | N | Positive float >0 | 1e-4 | Early stopping threshold for nn-descent convergence | + +### cuvs_cagra_hnswlib + +This is a benchmark that enables interoperability between `CAGRA` built `HNSW` search. It uses the `CAGRA` built graph as the base layer of an `hnswlib` index to search queries only within the base layer (this is enabled with a simple patch to `hnswlib`). + +`build` : Same as `build` of CAGRA + +`search` : Same as `search` of Hnswlib + +### cuvs_vamana + +Benchmark for building an in-memory Vamana graph based index on the GPU and interoperability with DiskANN for search. + +| Parameter | Type | Required | Data Type | Default | Description | +| --- | --- | --- | --- | --- | --- | +| `graph_degree` | `build` | N | Positive integer >0 | 32 | Maximum degree of the graph index | +| `visited_size` | `build` | N | Positive integer >0 | 64 | Maximum number of visited nodes per search corresponds to the L parameter in the Vamana literature | +| `alpha` | `build` | N | Positive float >0 | 1.2 | Alpha for pruning parameter | +| `L_search` | `search` | Y | Positive integer >0 | | Maximum number of visited nodes per search corresponds to the L parameter in the Vamana literature. Larger values improve recall at the cost of search time. | + +## FAISS Indexes + +### faiss_gpu_flat + +Use FAISS flat index on the GPU, which performs an exact search using brute-force and doesn't have any further build or search parameters. + +### faiss_gpu_ivf_flat + +IVF-flat uses an inverted-file index, which partitions the vectors into a series of clusters, or lists, storing them in an interleaved format which is optimized for fast distance computation. The searching of an IVF-flat index reduces the total vectors in the index to those within some user-specified nearest clusters called probes. + +IVF-flat is a simple algorithm which won't save any space, but it provides competitive search times even at higher levels of recall. + +| Parameter | Type | Required | Data Type | Default | Description | +| --- | --- | --- | --- | --- | --- | +| `nlists` | `build` | Y | Positive integer >0 | | Number of clusters to partition the vectors into. Larger values will put less points into each cluster but this will impact index build time as more clusters need to be trained | +| `ratio` | `build` | N | Positive integer >0 | 2 | `1/ratio` is the number of training points which should be used to train the clusters. | +| `nprobe` | `search` | Y | Positive integer >0 | 20 | The closest number of clusters to search for each query vector. Larger values will improve recall but will search more points in the index. | + +### faiss_gpu_ivf_pq + +IVF-pq is an inverted-file index, which partitions the vectors into a series of clusters, or lists, in a similar way to IVF-flat above. The difference is that IVF-PQ uses product quantization to also compress the vectors, giving the index a smaller memory footprint. Unfortunately, higher levels of compression can also shrink recall, which a refinement step can improve when the original vectors are still available. + +| Parameter | Type | Required | Data Type | Default | Description | +| --- | --- | --- | --- | --- | --- | +| `nlist` | `build` | Y | Positive integer >0 | | Number of clusters to partition the vectors into. Larger values will put less points into each cluster but this will impact index build time as more clusters need to be trained. | +| `ratio` | `build` | N | Positive integer >0 | 2 | `1/ratio` is the number of training points which should be used to train the clusters. | +| `M_ratio` | `build` | Y | Positive integer. Power of 2 [8-64] | | Ratio of number of chunks or subquantizers for each vector. Computed by `dims` / `M_ratio` | +| `usePrecomputed` | `build` | N | Boolean | `false` | Use pre-computed lookup tables to speed up search at the cost of increased memory usage. | +| `useFloat16` | `build` | N | Boolean | `false` | Use half-precision floats for clustering step. | +| `nprobe` | `search` | Y | Positive integer >0 | | The closest number of clusters to search for each query vector. Larger values will improve recall but will search more points in the index. | +| `refine_ratio` | `search` | N | Positive number >=1 | 1 | `refine_ratio * k` nearest neighbors are queried from the index initially and an additional refinement step improves recall by selecting only the best `k` neighbors. | + +### faiss_cpu_flat + +Use FAISS flat index on the CPU, which performs an exact search using brute-force and doesn't have any further build or search parameters. + +| Parameter | Type | Required | Data Type | Default | Description | +| --- | --- | --- | --- | --- | --- | +| `numThreads` | `search` | N | Positive integer >0 | 1 | Number of threads to use for queries. | + +### faiss_cpu_ivf_flat + +Use FAISS IVF-Flat index on CPU + +| Parameter | Type | Required | Data Type | Default | Description | +| --- | --- | --- | --- | --- | --- | +| `nlists` | `build` | Y | Positive integer >0 | | Number of clusters to partition the vectors into. Larger values will put less points into each cluster but this will impact index build time as more clusters need to be trained | +| `ratio` | `build` | N | Positive integer >0 | 2 | `1/ratio` is the number of training points which should be used to train the clusters. | +| `nprobe` | `search` | Y | Positive integer >0 | | The closest number of clusters to search for each query vector. Larger values will improve recall but will search more points in the index. | +| `numThreads` | `search` | N | Positive integer >0 | 1 | Number of threads to use for queries. | + +### faiss_cpu_ivf_pq + +Use FAISS IVF-PQ index on CPU + +| Parameter | Type | Required | Data Type | Default | Description | +| --- | --- | --- | --- | --- | --- | +| `nlist` | `build` | Y | Positive integer >0 | | Number of clusters to partition the vectors into. Larger values will put less points into each cluster but this will impact index build time as more clusters need to be trained. | +| `ratio` | `build` | N | Positive integer >0 | 2 | `1/ratio` is the number of training points which should be used to train the clusters. | +| `M` | `build` | Y | Positive integer. Power of 2 [8-64] | | Ratio of number of chunks or subquantizers for each vector. Computed by `dims` / `M_ratio` | +| `usePrecomputed` | `build` | N | Boolean | `false` | Use pre-computed lookup tables to speed up search at the cost of increased memory usage. | +| `bitsPerCode` | `build` | N | Positive integer [4-8] | 8 | Number of bits for representing each quantized code. | +| `nprobe` | `search` | Y | Positive integer >0 | | The closest number of clusters to search for each query vector. Larger values will improve recall but will search more points in the index. | +| `refine_ratio` | `search` | N | Positive number >=1 | 1 | `refine_ratio * k` nearest neighbors are queried from the index initially and an additional refinement step improves recall by selecting only the best `k` neighbors. | +| `numThreads` | `search` | N | Positive integer >0 | 1 | Number of threads to use for queries. | + +## HNSW + +### cuvs_hnsw + +cuVS HNSW builds an HNSW index using the ACE (Augmented Core Extraction) algorithm, which enables GPU-accelerated HNSW index construction for datasets too large to fit in GPU memory. + +| Parameter | Type | Required | Data Type | Default | Description | +| --- | --- | --- | --- | --- | --- | +| `hierarchy` | `build` | N | [`NONE`, `CPU`, `GPU`] | `NONE` | Type of HNSW hierarchy to build. `NONE` creates a base-layer-only index, `CPU` builds full hierarchy on CPU, `GPU` builds full hierarchy on GPU. | +| `efConstruction` | `build` | Y | Positive integer >0 | | Controls index time and accuracy. Bigger values increase the index quality. At some point, increasing this will no longer improve the quality. | +| `M` | `build` | Y | Positive integer. Often between 2-100 | | Number of bi-directional links create for every new element during construction. Higher values work for higher intrinsic dimensionality and/or high recall, low values can work for datasets with low intrinsic dimensionality and/or low recalls. Also affects the algorithm's memory consumption. | +| `numThreads` | `build` | N | Positive integer >0 | 1 | Number of threads to use to build the index. | +| `npartitions` | `build` | N | Positive integer >0 | 1 | Number of partitions to use for the ACE build. Small values might improve recall but potentially degrade performance and increase memory usage. The partition size is on average 2 * (n_rows / npartitions) * dim * sizeof(T). 2 is because of the core and augmented vectors. Please account for imbalance in the partition sizes (up to 3x in our tests). | +| `ef_construction` | `build` | N | Positive integer >0 | 120 | Controls index time and accuracy when using ACE build. Bigger values increase the index quality. At some point, increasing this will no longer improve the quality. | +| `build_dir` | `build` | N | String | "/tmp/ace_build" | The directory to use for the ACE build. This should be the fastest disk in the system and hold enough space for twice the dataset, final graph, and label mapping. | +| `use_disk` | `build` | N | Boolean | `false` | Whether to use disk-based storage for ACE build. When true, forces ACE to use disk-based storage even if the graph fits in host and GPU memory. When false, ACE will use in-memory storage if the graph fits in host and GPU memory and disk-based storage otherwise. | +| `ef` | `search` | Y | Positive integer >0 | | Size of the dynamic list for the nearest neighbors used for search. Higher value leads to more accurate but slower search. Cannot be lower than `k`. | +| `numThreads` | `search` | N | Positive integer >0 | 1 | Number of threads to use for queries. | + +### hnswlib + +| Parameter | Type | Required | Data Type | Default | Description | +| --- | --- | --- | --- | --- | --- | +| `efConstruction` | `build` | Y | Positive integer >0 | | Controls index time and accuracy. Bigger values increase the index quality. At some point, increasing this will no longer improve the quality. | +| `M` | `build` | Y | Positive integer. Often between 2-100 | | Number of bi-directional links create for every new element during construction. Higher values work for higher intrinsic dimensionality and/or high recall, low values can work for datasets with low intrinsic dimensionality and/or low recalls. Also affects the algorithm's memory consumption. | +| `numThreads` | `build` | N | Positive integer >0 | 1 | Number of threads to use to build the index. | +| `ef` | `search` | Y | Positive integer >0 | | Size of the dynamic list for the nearest neighbors used for search. Higher value leads to more accurate but slower search. Cannot be lower than `k`. | +| `numThreads` | `search` | N | Positive integer >0 | 1 | Number of threads to use for queries. | + +Please refer to [HNSW algorithm parameters guide](https://github.com/nmslib/hnswlib/blob/master/ALGO_PARAMS.md) from `hnswlib` to learn more about these arguments. + +## DiskANN + +### diskann_memory + +Use DiskANN in-memory index for approximate search. + +| Parameter | Type | Required | Data Type | Default | Description | +| --- | --- | --- | --- | --- | --- | +| `R` | `build` | Y | Positive integer >0 | | Maximum degree of the graph index | +| `L_build` | `build` | Y | Positive integer >0 | | number of visited nodes per greedy search during graph construction | +| `alpha` | `build` | N | Positive number >=1 | 1.2 | controls the pruning parameter of the graph construction | +| `num_threads` | `build` | N | Positive integer >0 | omp_get_max_threads() | Number of CPU threads to use to build the index. | +| `L_search` | `search` | Y | Positive integer >0 | | visited list size during search | diff --git a/fern/pages/cuvs_bench/pluggable_backend.md b/fern/pages/cuvs_bench/pluggable_backend.md new file mode 100644 index 0000000000..309abe9c0b --- /dev/null +++ b/fern/pages/cuvs_bench/pluggable_backend.md @@ -0,0 +1,224 @@ +# Pluggable Backend + +cuVS Bench uses a pluggable API so that benchmarks can be run through different execution paths. The default path runs C++ benchmark executables; other backends (e.g. Elasticsearch, Milvus) can be added by implementing the same interface and registering them. Two pieces work together: a **config loader** turns the user's arguments (dataset, algorithms, k, batch_size, and the like) into a structured configuration; a **backend** takes that configuration and runs build and search. Both are registered under a backend type name (e.g. `cpp_gbench`). When `BenchmarkOrchestrator(backend_type="cpp_gbench").run_benchmark(...)` is called, the orchestrator uses the config loader for that type to produce the configuration, then passes it to the backend for that type. + +The following shows how the default backend is used: + +```python +from cuvs_bench.orchestrator import BenchmarkOrchestrator + +orchestrator = BenchmarkOrchestrator(backend_type="cpp_gbench") +results = orchestrator.run_benchmark( + dataset="deep-image-96-inner", + algorithms="cuvs_cagra", + count=10, + batch_size=10, + build=True, + search=True, +) +``` + +## How a run flows + +1. The user calls `orchestrator.run_benchmark(backend_type="...", dataset=..., algorithms=..., count=..., **kwargs)`. + +2. The orchestrator looks up the **config loader** for that `backend_type` and calls its **load()** method. The loader reads YAML (or other sources), expands parameter combinations, applies constraints, and returns a **DatasetConfig** and a list of **BenchmarkConfig** (each describing one or more index configs: algorithm, build params, search params). + +3. The orchestrator obtains the **backend** for that `backend_type` from the **BackendRegistry** (instantiating it with the config it needs, e.g. executable path, host/port). + +4. The orchestrator calls the backend's **build(dataset, indexes, ...)** then **search(dataset, indexes, k, batch_size, ...)**. The backend uses the same config shape that its loader produced. + +5. The backend returns **BuildResult** and **SearchResult**; the orchestrator aggregates and returns them. + +The config loader and the backend are thus a pair: the loader defines what to run (which algorithms and parameters); the backend defines how it runs (C++ subprocess, HTTP to a service, and so on). + +## What the config loader produces + +The orchestrator calls the config loader's **load()** method with the same arguments passed to `run_benchmark()` (e.g. `dataset`, `dataset_path`, `algorithms`, `count`, `batch_size`, `groups`, `algo_groups`, and backend-specific options). The loader must return two things: + +- **DatasetConfig** – Dataset metadata: `name`, `base_file`, `query_file`, `groundtruth_neighbors_file`, `distance` (e.g. `"euclidean"`), `dims`, and optional `subset_size`. These are used by the orchestrator to build the in-memory `Dataset` and by the backend if it needs file paths. + +- **List[BenchmarkConfig]** – Each **BenchmarkConfig** has: + - **indexes**: a list of **IndexConfig**. Each **IndexConfig** has `name` (e.g. `"my_algo.param1value"`), `algo` (algorithm name), `build_param` (dict of build parameters), `search_params` (list of dicts, one per search parameter combination to benchmark), and `file` (path or identifier where the index is stored). + - **backend_config**: a dict passed to the backend constructor (e.g. `executable_path` for C++, or `host`, `port`, `index_name` for a network backend). The backend receives this as its `config[in](#in)_init__`. + +The following shows how to construct a minimal `DatasetConfig` and one `BenchmarkConfig` (one index, one search param set) so the backend runs a single build and search configuration: + +```python +from cuvs_bench.orchestrator.config_loaders import ( + ConfigLoader, + DatasetConfig, + BenchmarkConfig, + IndexConfig, +) + +class MyConfigLoader(ConfigLoader): + @property + def backend_type(self) -> str: + return "my_backend" + + def load(self, dataset, dataset_path, algorithms, count=10, batch_size=10000, **kwargs): + path_to_base = ... # path to base vectors file + path_to_queries = ... # path to query file + path_to_groundtruth = ... # path to groundtruth neighbors file + path_to_index = ... # path or id where the index is stored + dataset_config = DatasetConfig( + name=dataset, + base_file=path_to_base, + query_file=path_to_queries, + groundtruth_neighbors_file=path_to_groundtruth, + distance="euclidean", + dims=128, + ) + index = IndexConfig( + name=f"{algorithms}.default", + algo=algorithms, + build_param={"nlist": 1024}, + search_params=[{"nprobe": 10}], + file=path_to_index, + ) + benchmark_config = BenchmarkConfig( + indexes=[index], + backend_config={ + "host": ..., # backend host + "port": ..., # backend port + "index_name": ..., # name of the index on the backend + }, + ) + return dataset_config, [benchmark_config] +``` + +## Adding a new backend + +To add a new execution path (e.g. Elasticsearch): + +1. Implement a **config loader**. Subclass **ConfigLoader** (from `cuvs_bench.orchestrator.config_loaders`). Implement **load()** to accept the kwargs the orchestrator passes (dataset, dataset_path, algorithms, count, batch_size, and the like) and return `(DatasetConfig, List[BenchmarkConfig])`. Populate **DatasetConfig** with dataset paths and metadata; for each run you want, add an **IndexConfig** (name, algo, build_param, search_params, file) and a **BenchmarkConfig** (indexes, backend_config). The **backend_config** dict is passed to your backend's constructor. Register the loader with **register_config_loader("my_backend", MyConfigLoader)**. + +2. Implement the **backend**. Subclass **BenchmarkBackend** (from `cuvs_bench.backends.base`). In **__init__(self, config)**, store the config (this is the **backend_config** produced by the loader). Implement **build(dataset, indexes, force=False, dry_run=False)** to return a **BuildResult** (index_path, build_time_seconds, index_size_bytes, algorithm, build_params, metadata, success). Implement **search(dataset, indexes, k, batch_size, mode=..., ...)** to return a **SearchResult** (neighbors, distances, search_time_ms, queries_per_second, recall, algorithm, search_params, success). Implement the **algo** property (e.g. from `self.config["algo"]`). Set **requires_gpu** or **requires_network** in config if the backend needs them. Register the class with **get_registry().register("my_backend", MyBackend)**. + +3. Use the new backend by calling `BenchmarkOrchestrator(backend_type="my_backend").run_benchmark(dataset=..., dataset_path=..., algorithms=..., **kwargs)`. The orchestrator will use your loader to build the configuration and your backend to run build and search. + +After implementing your loader and backend, register them as follows: + +```python +from cuvs_bench.orchestrator import register_config_loader +from cuvs_bench.backends import get_registry + +register_config_loader("my_backend", MyConfigLoader) +get_registry().register("my_backend", MyBackend) +``` + +## Example: adding an Elasticsearch backend + +The following example shows a minimal Elasticsearch-style backend. The config loader builds one dataset config and one benchmark config with a single index; the backend stubs build and search and returns the result types the orchestrator expects. In practice you would replace the stub logic with real Elasticsearch API calls. + +Config loader: the **load()** method receives `dataset`, `dataset_path`, `algorithms`, `count`, `batch_size`, and optional kwargs. It returns a **DatasetConfig** (filled from dataset path and name) and a list of one **BenchmarkConfig** containing one **IndexConfig** and a **backend_config** with `host`, `port`, and `index_name` for the backend to use. + +```python +from cuvs_bench.orchestrator.config_loaders import ( + ConfigLoader, + DatasetConfig, + BenchmarkConfig, + IndexConfig, +) + +class ElasticsearchConfigLoader(ConfigLoader): + @property + def backend_type(self) -> str: + return "elasticsearch" + + def load(self, dataset, dataset_path, algorithms, count=10, batch_size=10000, **kwargs): + path_to_base = ... # path to base vectors (e.g. from dataset_path/dataset) + path_to_queries = ... # path to query vectors + path_to_groundtruth = ... # path to groundtruth file + path_to_index = ... # path or id for the index + dataset_config = DatasetConfig( + name=dataset, + base_file=path_to_base, + query_file=path_to_queries, + groundtruth_neighbors_file=path_to_groundtruth, + distance="euclidean", + dims=kwargs.get("dims", 128), + ) + index = IndexConfig( + name=f"{algorithms}.es", + algo=algorithms, + build_param={}, + search_params=[{"ef_search": 100}], + file=path_to_index, + ) + benchmark_config = BenchmarkConfig( + indexes=[index], + backend_config={ + "host": ..., # Elasticsearch host + "port": ..., # Elasticsearch port + "index_name": ..., # name of the vector index + "algo": algorithms, + }, + ) + return dataset_config, [benchmark_config] +``` + +Backend: the backend is constructed with **backend_config** (host, port, index_name, algo). **build()** and **search()** return **BuildResult** and **SearchResult** with the required fields; here they are stubbed with minimal values. Replace the stub body with actual Elasticsearch index creation and search calls. + +```python +import numpy as np +from cuvs_bench.backends.base import ( + BenchmarkBackend, + Dataset, + BuildResult, + SearchResult, +) +from cuvs_bench.orchestrator.config_loaders import IndexConfig + +class ElasticsearchBackend(BenchmarkBackend): + @property + def algo(self) -> str: + return self.config.get("algo", "elasticsearch") + + def build(self, dataset, indexes, force=False, dry_run=False): + # Stub: in practice, create ES index and bulk-index dataset.base_vectors + return BuildResult( + index_path=indexes[0].file if indexes else "", + build_time_seconds=0.0, + index_size_bytes=0, + algorithm=self.algo, + build_params=indexes[0].build_param if indexes else {}, + metadata={}, + success=True, + ) + + def search(self, dataset, indexes, k, batch_size=10000, mode="latency", force=False, search_threads=None, dry_run=False): + # Stub: in practice, run ES kNN search and compute recall + n_queries = dataset.n_queries + return SearchResult( + neighbors=np.zeros((n_queries, k), dtype=np.int64), + distances=np.zeros((n_queries, k), dtype=np.float32), + search_time_ms=0.0, + queries_per_second=0.0, + recall=0.0, + algorithm=self.algo, + search_params=indexes[0].search_params if indexes else [], + success=True, + ) +``` + +Registration: + +```python +from cuvs_bench.orchestrator import register_config_loader +from cuvs_bench.backends import get_registry + +register_config_loader("elasticsearch", ElasticsearchConfigLoader) +get_registry().register("elasticsearch", ElasticsearchBackend) +``` + +The built-in **CppGoogleBenchmarkBackend** (`backend_type="cpp_gbench"`) is one such pair: **CppGBenchConfigLoader** reads the YAML under `config/datasets` and `config/algos`, expands the Cartesian product, and validates with the constraint functions; the backend runs the C++ benchmark executables and merges results. Adding a new C++ algorithm (see [index](index.md)) only adds another executable and config for this backend; it does not add a new backend. + +## Components at a glance + +| Component | Description | +| --- | --- | +| ConfigLoader | Abstract. **load(**kwargs)** returns `(DatasetConfig, List[BenchmarkConfig])`. Register with **register_config_loader(backend_type, loader_class)**. | +| BenchmarkBackend | Abstract. **build(dataset, indexes, force, dry_run)** returns `BuildResult`; **search(dataset, indexes, k, batch_size, mode, ...)** returns `SearchResult`. Optional **initialize()** and **cleanup()**. Properties: **algo**, **requires_gpu**, **requires_network** (from config). Register with **BackendRegistry.register(name, backend_class)**; get an instance with **get_backend(name, config)**. | +| BackendRegistry | **get_registry()** returns the singleton. **register(name, backend_class)** and **get_backend(name, config)** tie a backend type name to the class and to instances. | diff --git a/docs/source/cuvs_bench/wiki_all_dataset.rst b/fern/pages/cuvs_bench/wiki_all_dataset.md similarity index 54% rename from docs/source/cuvs_bench/wiki_all_dataset.rst rename to fern/pages/cuvs_bench/wiki_all_dataset.md index 38b72ae3f5..427a9c9923 100644 --- a/docs/source/cuvs_bench/wiki_all_dataset.rst +++ b/fern/pages/cuvs_bench/wiki_all_dataset.md @@ -1,56 +1,68 @@ -~~~~~~~~~~~~~~~~ -Wiki-all Dataset -~~~~~~~~~~~~~~~~ - +# Wiki-all Dataset The `wiki-all` dataset was created to stress vector search algorithms at scale with both a large number of vectors and dimensions. The entire dataset contains 88M vectors with 768 dimensions and is meant for testing the types of vectors one would typically encounter in retrieval augmented generation (RAG) workloads. The full dataset is ~251GB in size, which is intentionally larger than the typical memory of GPUs. The massive scale is intended to promote the use of compression and efficient out-of-core methods for both indexing and search. -The dataset is composed of English wiki texts from `Kaggle `_ and multi-lingual wiki texts from `Cohere Wikipedia `_. +The dataset is composed of English wiki texts from [Kaggle](https://www.kaggle.com/datasets/jjinho/wikipedia-20230701) and multi-lingual wiki texts from [Cohere Wikipedia](https://huggingface.co/datasets/Cohere/wikipedia-22-12). Cohere's English Texts are older (2022) and smaller than the Kaggle English Wiki texts (2023) so the English texts have been removed from Cohere completely. The final Wiki texts include English Wiki from Kaggle and the other languages from Cohere. The English texts constitute 50% of the total text size. -To form the final dataset, the Wiki texts were chunked into 85 million 128-token pieces. For reference, Cohere chunks Wiki texts into 104-token pieces. Finally, the embeddings of each chunk were computed using the `paraphrase-multilingual-mpnet-base-v2 `_ embedding model. The resulting dataset is an embedding matrix of size 88 million by 768. Also included with the dataset is a query file containing 10k query vectors and a groundtruth file to evaluate nearest neighbors algorithms. +To form the final dataset, the Wiki texts were chunked into 85 million 128-token pieces. For reference, Cohere chunks Wiki texts into 104-token pieces. Finally, the embeddings of each chunk were computed using the [paraphrase-multilingual-mpnet-base-v2](https://huggingface.co/sentence-transformers/paraphrase-multilingual-mpnet-base-v2) embedding model. The resulting dataset is an embedding matrix of size 88 million by 768. Also included with the dataset is a query file containing 10k query vectors and a groundtruth file to evaluate nearest neighbors algorithms. -Getting the dataset -=================== +## Getting the dataset -Full dataset ------------- +### Full dataset -A version of the dataset is made available in the binary format that can be used directly by the :doc:`cuvs-bench ` tool. The full 88M dataset is ~251GB and the download link below contains tarballs that have been split into multiple parts. +A version of the dataset is made available in the binary format that can be used directly by the [cuvs-bench](index.md) tool. The full 88M dataset is ~251GB and the download link below contains tarballs that have been split into multiple parts. The following will download all 10 the parts and untar them to a `wiki_all_88M` directory: -.. code-block:: bash - - curl -s https://data.rapids.ai/raft/datasets/wiki_all/wiki_all.tar.{00..9} | tar -xf - -C wiki_all_88M/ +```bash +curl -s https://data.rapids.ai/raft/datasets/wiki_all/wiki_all.tar.{00..9} | tar -xf - -C wiki_all_88M/ +``` The above has the unfortunate drawback that if the command should fail for any reason, all the parts need to be re-downloaded. The files can also be downloaded individually and then untarred to the directory. Each file is ~27GB and there are 10 of them. -.. code-block:: bash - - curl -s https://data.rapids.ai/raft/datasets/wiki_all/wiki_all.tar.00 - ... - curl -s https://data.rapids.ai/raft/datasets/wiki_all/wiki_all.tar.09 - - cat wiki_all.tar.* | tar -xf - -C wiki_all_88M/ - -1M and 10M subsets ------------------- +```bash +curl -s https://data.rapids.ai/raft/datasets/wiki_all/wiki_all.tar.00 +```python +```python +```python +```python +```python +```python +```python +```python +```python +```python +... +``` +``` +``` +``` +``` +``` +``` +``` +``` +``` +curl -s https://data.rapids.ai/raft/datasets/wiki_all/wiki_all.tar.09 + +cat wiki_all.tar.* | tar -xf - -C wiki_all_88M/ +``` + +### 1M and 10M subsets Also available are 1M and 10M subsets of the full dataset which are 2.9GB and 29GB, respectively. These subsets also include query sets of 10k vectors and corresponding groundtruth files. -.. code-block:: bash - - curl -s https://data.rapids.ai/raft/datasets/wiki_all_1M/wiki_all_1M.tar - curl -s https://data.rapids.ai/raft/datasets/wiki_all_10M/wiki_all_10M.tar +```bash +curl -s https://data.rapids.ai/raft/datasets/wiki_all_1M/wiki_all_1M.tar +curl -s https://data.rapids.ai/raft/datasets/wiki_all_10M/wiki_all_10M.tar +``` -Using the dataset -================= +## Using the dataset After the dataset is downloaded and extracted to the `wiki_all_88M` directory (or `wiki_all_1M`/`wiki_all_10M` depending on whether the subsets are used), the files can be used in the benchmarking tool. The dataset name is `wiki_all` (or `wiki_all_1M`/`wiki_all_10M`), and the benchmarking tool can be used by specifying the appropriate name `--dataset wiki_all_88M` in the scripts. -License info -============ +## License info -The English wiki texts available on Kaggle come with the `CC BY-NCSA 4.0 `_ license and the Cohere wikipedia data set comes with the `Apache 2.0 `_ license. +The English wiki texts available on Kaggle come with the [CC BY-NCSA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/) license and the Cohere wikipedia data set comes with the [Apache 2.0](https://choosealicense.com/licenses/apache-2.0/) license. diff --git a/docs/source/developer_guide.md b/fern/pages/developer_guide.md similarity index 94% rename from docs/source/developer_guide.md rename to fern/pages/developer_guide.md index c323de0286..5fa59609c4 100644 --- a/docs/source/developer_guide.md +++ b/fern/pages/developer_guide.md @@ -7,7 +7,6 @@ Please start by reading the [Contributor Guide](contributing.md). 1. In performance critical sections of the code, favor `cudaDeviceGetAttribute` over `cudaDeviceGetProperties`. See corresponding CUDA devblog [here](https://devblogs.nvidia.com/cuda-pro-tip-the-fast-way-to-query-device-properties/) to know more. 2. If an algo requires you to launch GPU work in multiple cuda streams, do not create multiple `raft::resources` objects, one for each such work stream. Instead, use the stream pool configured on the given `raft::resources` instance's `raft::resources::get_stream_from_stream_pool()` to pick up the right cuda stream. Refer to the section on [CUDA Resources](#resource-management) and the section on [Threading](#threading-model) for more details. TIP: use `raft::resources::get_stream_pool_size()` to know how many such streams are available at your disposal. - ## Local Development Developing features and fixing bugs for the RAFT library itself is straightforward and only requires building and installing the relevant RAFT artifacts. @@ -16,7 +15,6 @@ The process for working on a CUDA/C++ feature which might span RAFT and one or m If building a feature which spans projects and not using the source build in cmake, the RAFT changes (both C++ and Python) will need to be installed into the environment of the consuming project before they can be used. The ideal integration of RAFT into consuming projects will enable both the source build in the consuming project only for this case but also rely on a more stable packaging (such as conda packaging) otherwise. - ## Threading Model With the exception of the `raft::resources`, RAFT algorithms should maintain thread-safety and are, in general, @@ -37,11 +35,51 @@ A good example of an acceptable use of host threads within a RAFT algorithm migh #include raft::resources res; +```python +```python +```python +```python +```python +```python +```python +```python +```python +```python ... +``` +``` +``` +``` +``` +``` +``` +``` +``` +``` sync_stream(res); +```python +```python +```python +```python +```python +```python +```python +```python +```python +```python ... +``` +``` +``` +``` +``` +``` +``` +``` +``` +``` int n_streams = get_stream_pool_size(res); @@ -131,7 +169,6 @@ namespace raft::ivf_pq { } ``` - ## Coding style ### Code Formatting @@ -181,7 +218,7 @@ You can skip these checks with `git commit --no-verify` or with the short versio The following section describes some of the core pre-commit hooks used by the repository. See `.pre-commit-config.yaml` for a full list. -C++/CUDA is formatted with [`clang-format`](https://clang.llvm.org/docs/ClangFormat.html). +C++/CUDA is formatted with [clang-format](https://clang.llvm.org/docs/ClangFormat.html). RAFT relies on `clang-format` to enforce code style across all C++ and CUDA source code. The coding style is based on the [Google style guide](https://google.github.io/styleguide/cppguide.html#Formatting). The only digressions from this style are the following. 1. Do not split empty functions/records/namespaces. @@ -189,7 +226,7 @@ RAFT relies on `clang-format` to enforce code style across all C++ and CUDA sour 3. Disable reflowing of comments. The reasons behind these deviations from the Google style guide are given in comments [here](https://github.com/rapidsai/cuvs/blob/main/cpp/.clang-format). -[`doxygen`](https://doxygen.nl/) is used as documentation generator and also as a documentation linter. +[doxygen](https://doxygen.nl/) is used as documentation generator and also as a documentation linter. In order to run doxygen as a linter on C++/CUDA code, run ```bash @@ -231,7 +268,7 @@ Call CUDA APIs via the provided helper macros `RAFT_CUDA_TRY`, `RAFT_CUBLAS_TRY` 1. Use the `hpp` extension for files which can be compiled with `gcc` against the CUDA-runtime. Use the `cuh` extension for files which require `nvcc` to be compiled. `hpp` can also be used for functions marked `__host__ __device__` only if proper checks are in place to remove the `__device__` designation when not compiling with `nvcc`. -2. When additional classes, structs, or general POCO types are needed to be used for representing data in the public API, place them in a new file called `_types.hpp`. This tells users they are safe to expose these types on their own public APIs without bringing in device code. At a minimum, the definitions for these types, at least, should not require `nvcc`. In general, these classes should only store very simple state and should not perform their own computations. Instead, new functions should be exposed on the public API which accept these objects, reading or updating their state as necessary. +2. When additional classes, structs, or general POCO types are needed to be used for representing data in the public API, place them in a new file called `<primitive_name>_types.hpp`. This tells users they are safe to expose these types on their own public APIs without bringing in device code. At a minimum, the definitions for these types, at least, should not require `nvcc`. In general, these classes should only store very simple state and should not perform their own computations. Instead, new functions should be exposed on the public API which accept these objects, reading or updating their state as necessary. 3. Documentation for public APIs should be well documented, easy to use, and it is highly preferred that they include usage instructions. @@ -351,7 +388,27 @@ E.g. with a CUDA-aware MPI, a RAFT user could use code like this to inject an in #include #include #include +```python +```python +```python +```python +```python +```python +```python +```python +```python +```python ... +``` +``` +``` +``` +``` +``` +``` +``` +``` +``` int main(int argc, char * argv[]) { MPI_Init(&argc, &argv); @@ -415,4 +472,4 @@ This approach ultimately enables: - **Reduced binary size**: Compile fragments once, combine many ways - **User Defined Functions**: Link UDFs in cuVS CUDA kernels -For more information on JIT LTO, see [Advanced Topics](advanced_topics). For a complete guide on implementing JIT LTO kernels, including step-by-step examples, see the [JIT LTO Guide](jit_lto_guide.md). +For more information on JIT LTO, see [Advanced Topics](advanced_topics.md). For a complete guide on implementing JIT LTO kernels, including step-by-step examples, see the [JIT LTO Guide](jit_lto_guide.md). diff --git a/fern/pages/filtering.md b/fern/pages/filtering.md new file mode 100644 index 0000000000..2eee8c5b13 --- /dev/null +++ b/fern/pages/filtering.md @@ -0,0 +1,108 @@ +<a id="filtering"></a> + +# Filtering vector indexes + +cuVS supports different type of filtering depending on the vector index being used. The main method used in all of the vector indexes +is pre-filtering, which is a technique that will take into account the filtering of the vectors before computing its closest neighbors, saving +some computation from calculating distances. + +## Bitset + +A bitset is an array of bits where each bit can have two possible values: `0` and `1`, which signify in the context of filtering whether +a sample should be filtered or not. `0` means that the corresponding vector will be filtered, and will therefore not be present in the results of the search. +This mechanism is optimized to take as little memory space as possible, and is available through the RAFT library +(check out RAFT's [bitset API documentation](https://docs.rapids.ai/api/raft/stable/cpp_api/core_bitset/)). When calling a search function of an ANN index, the +bitset length should match the number of vectors present in the database. + +## Bitmap + +A bitmap is based on the same principle as a bitset, but in two dimensions. This allows users to provide a different bitset for each query +being searched. Check out RAFT's [bitmap API documentation](https://docs.rapids.ai/api/raft/stable/cpp_api/core_bitmap/). + +## Examples + +### Using a Bitset filter on a CAGRA index + +```c++ +#include +#include + +using namespace cuvs::neighbors; +cagra::index index; + +// ... build index ... + +cagra::search_params search_params; +raft::device_resources res; +raft::device_matrix_view queries = load_queries(); +raft::device_matrix_view neighbors = make_device_matrix_view(n_queries, k); +raft::device_matrix_view distances = make_device_matrix_view(n_queries, k); + +// Load a list of all the samples that will get filtered +std::vector removed_indices_host = get_invalid_indices(); +auto removed_indices_device = + raft::make_device_vector(res, removed_indices_host.size()); +// Copy this list to device +raft::copy(removed_indices_device.data_handle(), removed_indices_host.data(), + removed_indices_host.size(), raft::resource::get_cuda_stream(res)); + +// Create a bitset with the list of samples to filter. +cuvs::core::bitset removed_indices_bitset( + res, removed_indices_device.view(), index.size()); +// Use a `bitset_filter` in the `cagra::search` function call. +auto bitset_filter = + cuvs::neighbors::filtering::bitset_filter(removed_indices_bitset.view()); +cagra::search(res, + search_params, + index, + queries, + neighbors, + distances, + bitset_filter); +``` + +### Using a Bitmap filter on a Brute-force index + +```c++ +#include +#include + +using namespace cuvs::neighbors; +using indexing_dtype = int64_t; + +// ... build index ... +brute_force::index_params index_params; +brute_force::search_params search_params; +raft::device_resources res; +raft::device_matrix_view dataset = load_dataset(n_vectors, dim); +raft::device_matrix_view queries = load_queries(n_queries, dim); +auto index = brute_force::build(res, index_params, raft::make_const_mdspan(dataset.view())); + +// Load a list of all the samples that will get filtered +std::vector removed_indices_host = get_invalid_indices(); +auto removed_indices_device = + raft::make_device_vector(res, removed_indices_host.size()); +// Copy this list to device +raft::copy(removed_indices_device.data_handle(), removed_indices_host.data(), + removed_indices_host.size(), raft::resource::get_cuda_stream(res)); + +// Create a bitmap with the list of samples to filter. +cuvs::core::bitset removed_indices_bitset( + res, removed_indices_device.view(), n_queries * n_vectors); +cuvs::core::bitmap_view removed_indices_bitmap( + removed_indices_bitset.data(), n_queries, n_vectors); + +// Use a `bitmap_filter` in the `brute_force::search` function call. +auto bitmap_filter = + cuvs::neighbors::filtering::bitmap_filter(removed_indices_bitmap); + +auto neighbors = raft::make_device_matrix_view(n_queries, k); +auto distances = raft::make_device_matrix_view(n_queries, k); +brute_force::search(res, + search_params, + index, + raft::make_const_mdspan(queries.view()), + neighbors.view(), + distances.view(), + bitmap_filter); +``` diff --git a/fern/pages/getting_started.md b/fern/pages/getting_started.md new file mode 100644 index 0000000000..c995af239c --- /dev/null +++ b/fern/pages/getting_started.md @@ -0,0 +1,100 @@ +# Getting Started + +- [New to vector search?](#new-to-vector-search) + + * [Primer on vector search](choosing_and_configuring_indexes.md) + + * [Vector search indexes vs vector databases](vector_databases_vs_vector_search.md) + + * [Index tuning guide](tuning_guide.md) + + * [Comparing vector search index performance](comparing_indexes.md) + +- [Supported indexes](#supported-indexes) + + * [Vector search index guide](neighbors/neighbors.md) + +- [Using cuVS APIs](#using-cuvs-apis) + + * [C API Docs](/api-reference/c-api-documentation) + + * [C++ API Docs](/api-reference/cpp-api-documentation) + + * [Python API Docs](/api-reference/python-api-documentation) + + * [Java API Docs](/api-reference/java-api-documentation) + + * [Rust API Docs](/api-reference/rust-api-documentation) + + * [Go API Docs](/api-reference/go-api-documentation) + + * [API basics](api_basics.md) + + * [API interoperability](api_interoperability.md) + +- [Where to next?](#where-to-next) + + * [Social media](#social-media) + + * [Blogs](#blogs) + + * [Research](#research) + + * [Get involved](#get-involved) + +## New to vector search? + +If you are unfamiliar with the basics of vector search or how vector search differs from vector databases, then [this primer on vector search guide](choosing_and_configuring_indexes.md) should provide some good insight. Another good resource for the uninitiated is our [vector databases vs vector search](vector_databases_vs_vector_search.md) guide. As outlined in the primer, vector search as used in vector databases is often closer to machine learning than to traditional databases. This means that while traditional databases can often be slow without any performance tuning, they will usually still yield the correct results. Unfortunately, vector search indexes, like other machine learning models, can yield garbage results if not tuned correctly. + +Fortunately, this opens up the whole world of hyperparameter optimization to improve vector search performance and quality. Please see our [index tuning guide](tuning_guide.md) for more information. + +When comparing the performance of vector search indexes, it is important that considerations are made with respect to three main dimensions: + +1. Build time +1. Search quality +1. Search performance + +Please see the [primer on comparing vector search index performance](comparing_indexes.md) for more information on methodologies and how to make a fair apples-to-apples comparison during your evaluations. + +## Supported indexes + +cuVS supports many of the standard index types with the list continuing to grow and stay current with the state-of-the-art. Please refer to our [vector search index guide](neighbors/neighbors.md) to learn more about each individual index type, when they can be useful on the GPU, the tuning knobs they offer to trade off performance and quality. + +The primary goal of cuVS is to enable speed, scale, and flexibility (in that order)- and one of the important value propositions is to enhance existing software deployments with extensible GPU capabilities to improve pain points while not interrupting parts of the system that work well today with CPU. + +## Using cuVS APIs + +cuVS is a C++ library at its core, which is wrapped with a C library and exposed further through various different languages. cuVS currently provides APIs and documentation for [C](/api-reference/c-api-documentation), [C++](/api-reference/cpp-api-documentation), [Python](/api-reference/python-api-documentation), [Java](/api-reference/java-api-documentation), [Rust](/api-reference/rust-api-documentation), and [Go](/api-reference/go-api-documentation). our [API basics](api_basics.md) provides some background and context about the important paradigms and vocabulary types you'll encounter when working with cuVS types. + +Please refer to the [guide on API interoperability](api_interoperability.md) for more information on how cuVS can work seamlessly with other libraries like numpy, cupy, tensorflow, and pytorch, even without having to copy device memory. + +## Where to next? + +cuVS is free and open source software, licensed under Apache 2.0 Once you are familiar with and/or have used cuVS, you can access the developer community most easily through [Github](https://github.com/rapidsai/cuvs). Please open Github issues for any bugs, questions or feature requests. + +### Social media + +You can access the RAPIDS community through [Slack](https://rapids.ai/slack-invite) , [Stack Overflow](https://stackoverflow.com/tags/rapids) and [X](https://twitter.com/rapidsai) + +### Blogs + +We frequently publish blogs on GPU-enabled vector search, which can provide great deep dives into various important topics and breakthroughs: + +1. [See all cuVS blogs](https://developer.nvidia.com/blog/recent-posts/?products=cuVS) +1. [Accelerated Vector Search: Approximating with cuVS IVF-Flat](https://developer.nvidia.com/blog/accelerated-vector-search-approximating-with-rapids-raft-ivf-flat/) +1. Accelerating Vector Search with cuVS IVF-PQ ([Part 1](https://developer.nvidia.com/blog/accelerating-vector-search-rapids-cuvs-ivf-pq-deep-dive-part-1/), [Part 2](https://developer.nvidia.com/blog/accelerating-vector-search-nvidia-cuvs-ivf-pq-performance-tuning-part-2/)) + +### Research + +For the interested reader, many of the accelerated implementations in cuVS are also based on research papers which can provide a lot more background. We also ask you to please cite the corresponding algorithms by referencing them in your own research. + +1. [CAGRA: Highly Parallel Graph Construction and Approximate Nearest Neighbor Search](https://arxiv.org/abs/2308.15136) +1. [Top-K Algorithms on GPU: A Comprehensive Study and New Methods](https://dl.acm.org/doi/10.1145/3581784.3607062) +1. [Fast K-NN Graph Construction by GPU Based NN-Descent](https://dl.acm.org/doi/abs/10.1145/3459637.3482344?casa_token=O_nan1B1F5cAAAAA:QHWDEhh0wmd6UUTLY9_Gv6c3XI-5DXM9mXVaUXOYeStlpxTPmV3nKvABRfoivZAaQ3n8FWyrkWw) +1. [cuSLINK: Single-linkage Agglomerative Clustering on the GPU](https://arxiv.org/abs/2306.16354) +1. [GPU Semiring Primitives for Sparse Neighborhood Methods](https://arxiv.org/abs/2104.06357) +1. [VecFlow: A High-Performance Vector Data Management System for Filtered-Search on GPUs](https://arxiv.org/abs/2506.00812) + +### Get involved + +We always welcome patches for new features and bug fixes. Please read our [contributing guide](contributing.md) for more information on contributing patches to cuVS. diff --git a/fern/pages/go_api/go-api-brute-force.md b/fern/pages/go_api/go-api-brute-force.md new file mode 100644 index 0000000000..9e8a45d87c --- /dev/null +++ b/fern/pages/go_api/go-api-brute-force.md @@ -0,0 +1,79 @@ +--- +slug: api-reference/go-api-brute-force +--- + +# Brute Force Package + +_Go package: `brute_force`_ + +_Sources: `go/brute_force`_ + +## Types + +### BruteForceIndex + +```go +type BruteForceIndex struct { ... } +``` + +Brute Force KNN Index + +_Source: `go/brute_force/brute_force.go:14`_ + +## Functions + +### BuildIndex + +```go +func BuildIndex[T any](Resources cuvs.Resource, Dataset *cuvs.Tensor[T], metric cuvs.Distance, metric_arg float32, index *BruteForceIndex) error +``` + +Builds a new Brute Force KNN Index from the dataset for efficient search. + +#### Arguments + +* `Resources` - Resources to use +* `Dataset` - A row-major matrix on either the host or device to index +* `metric` - Distance type to use for building the index +* `metric_arg` - Value of `p` for Minkowski distances - set to 2.0 if not applicable + +_Source: `go/brute_force/brute_force.go:48`_ + +### CreateIndex + +```go +func CreateIndex() (*BruteForceIndex, error) +``` + +Creates a new empty Brute Force KNN Index + +_Source: `go/brute_force/brute_force.go:20`_ + +### SearchIndex + +```go +func SearchIndex[T any](resources cuvs.Resource, index BruteForceIndex, queries *cuvs.Tensor[T], neighbors *cuvs.Tensor[int64], distances *cuvs.Tensor[float32]) error +``` + +Perform a Nearest Neighbors search on the Index + +#### Arguments + +* `Resources` - Resources to use +* `queries` - Tensor in device memory to query for +* `neighbors` - Tensor in device memory that receives the indices of the nearest neighbors +* `distances` - Tensor in device memory that receives the distances of the nearest neighbors + +_Source: `go/brute_force/brute_force.go:72`_ + +## Methods + +### BruteForceIndex.Close + +```go +func (index *BruteForceIndex) Close() error +``` + +Destroys the Brute Force KNN Index + +_Source: `go/brute_force/brute_force.go:32`_ diff --git a/fern/pages/go_api/go-api-cagra.md b/fern/pages/go_api/go-api-cagra.md new file mode 100644 index 0000000000..7f331c41ce --- /dev/null +++ b/fern/pages/go_api/go-api-cagra.md @@ -0,0 +1,529 @@ +--- +slug: api-reference/go-api-cagra +--- + +# Cagra Package + +_Go package: `cagra`_ + +_Sources: `go/cagra`_ + +## Constants + +### BuildAlgo Constants + +```go +const ( +IvfPq BuildAlgo = iota +NnDescent +AutoSelect +) +``` + +_Source: `go/cagra/index_params.go:23`_ + +### HashmapMode Constants + +```go +const ( +HashmapModeHash HashmapMode = iota +HashmapModeSmall +HashmapModeAuto +) +``` + +_Source: `go/cagra/search_params.go:28`_ + +### SearchAlgo Constants + +```go +const ( +SearchAlgoSingleCta SearchAlgo = iota +SearchAlgoMultiCta +SearchAlgoMultiKernel +SearchAlgoAuto +) +``` + +_Source: `go/cagra/search_params.go:19`_ + +## Types + +### BuildAlgo + +```go +type BuildAlgo int +``` + +_Source: `go/cagra/index_params.go:21`_ + +### CagraIndex + +```go +type CagraIndex struct { ... } +``` + +Cagra ANN Index + +_Source: `go/cagra/cagra.go:14`_ + +### CompressionParams + +```go +type CompressionParams struct { ... } +``` + +Supplemental parameters to build CAGRA Index + +_Source: `go/cagra/index_params.go:17`_ + +### ExtendParams + +```go +type ExtendParams struct { ... } +``` + +Parameters to extend CAGRA Index + +_Source: `go/cagra/extend_params.go:11`_ + +### HashmapMode + +```go +type HashmapMode int +``` + +_Source: `go/cagra/search_params.go:26`_ + +### IndexParams + +```go +type IndexParams struct { ... } +``` + +_Source: `go/cagra/index_params.go:12`_ + +### SearchAlgo + +```go +type SearchAlgo int +``` + +_Source: `go/cagra/search_params.go:17`_ + +### SearchParams + +```go +type SearchParams struct { ... } +``` + +Supplemental parameters to search CAGRA Index + +_Source: `go/cagra/search_params.go:13`_ + +## Functions + +### BuildIndex + +```go +func BuildIndex[T any](Resources cuvs.Resource, params *IndexParams, dataset *cuvs.Tensor[T], index *CagraIndex) error +``` + +Builds a new Index from the dataset for efficient search. + +#### Arguments + +* `Resources` - Resources to use +* `params` - Parameters for building the index +* `dataset` - A row-major Tensor on either the host or device to index +* `index` - CagraIndex to build + +_Source: `go/cagra/cagra.go:38`_ + +### CreateCompressionParams + +```go +func CreateCompressionParams() (*CompressionParams, error) +``` + +Creates a new CompressionParams + +_Source: `go/cagra/index_params.go:36`_ + +### CreateExtendParams + +```go +func CreateExtendParams() (*ExtendParams, error) +``` + +Creates a new ExtendParams + +_Source: `go/cagra/extend_params.go:16`_ + +### CreateIndex + +```go +func CreateIndex() (*CagraIndex, error) +``` + +Creates a new empty Cagra Index + +_Source: `go/cagra/cagra.go:20`_ + +### CreateIndexParams + +```go +func CreateIndexParams() (*IndexParams, error) +``` + +Creates a new IndexParams + +_Source: `go/cagra/index_params.go:99`_ + +### CreateSearchParams + +```go +func CreateSearchParams() (*SearchParams, error) +``` + +Creates a new SearchParams + +_Source: `go/cagra/search_params.go:35`_ + +### ExtendIndex + +```go +func ExtendIndex[T any](Resources cuvs.Resource, params *ExtendParams, additional_dataset *cuvs.Tensor[T], index *CagraIndex) error +``` + +Extends the index with additional data + +#### Arguments + +* `Resources` - Resources to use +* `params` - Parameters for extending the index +* `additional_dataset` - A row-major Tensor on the device to extend the index with +* `index` - CagraIndex to extend + +_Source: `go/cagra/cagra.go:55`_ + +### SearchIndex + +```go +func SearchIndex[T any](Resources cuvs.Resource, params *SearchParams, index *CagraIndex, queries *cuvs.Tensor[T], neighbors *cuvs.Tensor[uint32], distances *cuvs.Tensor[T], allowList []uint32) error +``` + +Perform a Approximate Nearest Neighbors search on the Index + +#### Arguments + +* `Resources` - Resources to use +* `params` - Parameters to use in searching the index +* `queries` - A tensor in device memory to query for +* `neighbors` - Tensor in device memory that receives the indices of the nearest neighbors +* `distances` - Tensor in device memory that receives the distances of the nearest neighbors +* `allowList` - List of indices to allow in the search, if nil, no filtering is applied + +_Source: `go/cagra/cagra.go:85`_ + +## Methods + +### CagraIndex.Close + +```go +func (index *CagraIndex) Close() error +``` + +Destroys the Cagra Index + +_Source: `go/cagra/cagra.go:67`_ + +### CompressionParams.SetKMeansNIters + +```go +func (p *CompressionParams) SetKMeansNIters(kmeans_n_iters uint32) (*CompressionParams, error) +``` + +The number of iterations searching for kmeans centers (both VQ & PQ +phases). + +_Source: `go/cagra/index_params.go:76`_ + +### CompressionParams.SetPQBits + +```go +func (p *CompressionParams) SetPQBits(pq_bits uint32) (*CompressionParams, error) +``` + +The bit length of the vector element after compression by PQ. + +_Source: `go/cagra/index_params.go:52`_ + +### CompressionParams.SetPQDim + +```go +func (p *CompressionParams) SetPQDim(pq_dim uint32) (*CompressionParams, error) +``` + +The dimensionality of the vector after compression by PQ. When zero, +an optimal value is selected using a heuristic. + +_Source: `go/cagra/index_params.go:60`_ + +### CompressionParams.SetPQKMeansTrainsetFraction + +```go +func (p *CompressionParams) SetPQKMeansTrainsetFraction(pq_kmeans_trainset_fraction float64) (*CompressionParams, error) +``` + +The fraction of data to use during iterative kmeans building (PQ +phase). When zero, an optimal value is selected using a heuristic. + +_Source: `go/cagra/index_params.go:92`_ + +### CompressionParams.SetVQKMeansTrainsetFraction + +```go +func (p *CompressionParams) SetVQKMeansTrainsetFraction(vq_kmeans_trainset_fraction float64) (*CompressionParams, error) +``` + +The fraction of data to use during iterative kmeans building (VQ +phase). When zero, an optimal value is selected using a heuristic. + +_Source: `go/cagra/index_params.go:84`_ + +### CompressionParams.SetVQNCenters + +```go +func (p *CompressionParams) SetVQNCenters(vq_n_centers uint32) (*CompressionParams, error) +``` + +Vector Quantization (VQ) codebook size - number of "coarse cluster +centers". When zero, an optimal value is selected using a heuristic. + +_Source: `go/cagra/index_params.go:68`_ + +### ExtendParams.Close + +```go +func (p *ExtendParams) Close() error +``` + +_Source: `go/cagra/extend_params.go:40`_ + +### ExtendParams.SetMaxChunkSize + +```go +func (p *ExtendParams) SetMaxChunkSize(max_chunk_size uint32) (*ExtendParams, error) +``` + +The additional dataset is divided into chunks and added to the graph. +This is the knob to adjust the tradeoff between the recall and operation throughput. +Large chunk sizes can result in high throughput, but use more +working memory (O(max_chunk_size*degree^2)). +This can also degrade recall because no edges are added between the nodes in the same chunk. +Auto select when 0. + +_Source: `go/cagra/extend_params.go:35`_ + +### IndexParams.Close + +```go +func (p *IndexParams) Close() error +``` + +Destroys IndexParams + +_Source: `go/cagra/index_params.go:152`_ + +### IndexParams.SetBuildAlgo + +```go +func (p *IndexParams) SetBuildAlgo(build_algo BuildAlgo) (*IndexParams, error) +``` + +ANN algorithm to build knn graph + +_Source: `go/cagra/index_params.go:126`_ + +### IndexParams.SetCompression + +```go +func (p *IndexParams) SetCompression(compression *CompressionParams) (*IndexParams, error) +``` + +Compression parameters + +_Source: `go/cagra/index_params.go:145`_ + +### IndexParams.SetGraphDegree + +```go +func (p *IndexParams) SetGraphDegree(intermediate_graph_degree uintptr) (*IndexParams, error) +``` + +Degree of output graph + +_Source: `go/cagra/index_params.go:119`_ + +### IndexParams.SetIntermediateGraphDegree + +```go +func (p *IndexParams) SetIntermediateGraphDegree(intermediate_graph_degree uintptr) (*IndexParams, error) +``` + +Degree of input graph for pruning + +_Source: `go/cagra/index_params.go:113`_ + +### IndexParams.SetNNDescentNiter + +```go +func (p *IndexParams) SetNNDescentNiter(nn_descent_niter uint32) (*IndexParams, error) +``` + +Number of iterations to run if building with NN_DESCENT + +_Source: `go/cagra/index_params.go:138`_ + +### SearchParams.Close + +```go +func (p *SearchParams) Close() error +``` + +Destroys SearchParams + +_Source: `go/cagra/search_params.go:157`_ + +### SearchParams.SetAlgo + +```go +func (p *SearchParams) SetAlgo(algo SearchAlgo) (*SearchParams, error) +``` + +Which search implementation to use. + +_Source: `go/cagra/search_params.go:67`_ + +### SearchParams.SetHashmapMaxFillRate + +```go +func (p *SearchParams) SetHashmapMaxFillRate(hashmap_max_fill_rate float32) (*SearchParams, error) +``` + +Upper limit of hashmap fill rate. More than 0.1, less than 0.9. + +_Source: `go/cagra/search_params.go:139`_ + +### SearchParams.SetHashmapMinBitlen + +```go +func (p *SearchParams) SetHashmapMinBitlen(hashmap_min_bitlen uintptr) (*SearchParams, error) +``` + +Lower limit of hashmap bit length. More than 8. + +_Source: `go/cagra/search_params.go:133`_ + +### SearchParams.SetHashmapMode + +```go +func (p *SearchParams) SetHashmapMode(hashmap_mode HashmapMode) (*SearchParams, error) +``` + +Hashmap type. Auto selection when AUTO. + +_Source: `go/cagra/search_params.go:113`_ + +### SearchParams.SetItopkSize + +```go +func (p *SearchParams) SetItopkSize(itopk_size uintptr) (*SearchParams, error) +``` + +Number of intermediate search results retained during the search. +This is the main knob to adjust trade off between accuracy and search speed. +Higher values improve the search accuracy + +_Source: `go/cagra/search_params.go:55`_ + +### SearchParams.SetMaxIterations + +```go +func (p *SearchParams) SetMaxIterations(max_iterations uintptr) (*SearchParams, error) +``` + +Upper limit of search iterations. Auto select when 0. + +_Source: `go/cagra/search_params.go:61`_ + +### SearchParams.SetMaxQueries + +```go +func (p *SearchParams) SetMaxQueries(max_queries uintptr) (*SearchParams, error) +``` + +Maximum number of queries to search at the same time (batch size). Auto select when 0 + +_Source: `go/cagra/search_params.go:47`_ + +### SearchParams.SetMinIterations + +```go +func (p *SearchParams) SetMinIterations(min_iterations uintptr) (*SearchParams, error) +``` + +Lower limit of search iterations. + +_Source: `go/cagra/search_params.go:95`_ + +### SearchParams.SetNumRandomSamplings + +```go +func (p *SearchParams) SetNumRandomSamplings(num_random_samplings uint32) (*SearchParams, error) +``` + +Number of iterations of initial random seed node selection. 1 or more. + +_Source: `go/cagra/search_params.go:145`_ + +### SearchParams.SetRandXorMask + +```go +func (p *SearchParams) SetRandXorMask(rand_xor_mask uint64) (*SearchParams, error) +``` + +Bit mask used for initial random seed node selection. + +_Source: `go/cagra/search_params.go:151`_ + +### SearchParams.SetSearchWidth + +```go +func (p *SearchParams) SetSearchWidth(search_width uintptr) (*SearchParams, error) +``` + +How many nodes to search at once. Auto select when 0. + +_Source: `go/cagra/search_params.go:101`_ + +### SearchParams.SetTeamSize + +```go +func (p *SearchParams) SetTeamSize(team_size uintptr) (*SearchParams, error) +``` + +Number of threads used to calculate a single distance. 4, 8, 16, or 32. + +_Source: `go/cagra/search_params.go:89`_ + +### SearchParams.SetThreadBlockSize + +```go +func (p *SearchParams) SetThreadBlockSize(thread_block_size uintptr) (*SearchParams, error) +``` + +Thread block size. 0, 64, 128, 256, 512, 1024. Auto selection when 0. + +_Source: `go/cagra/search_params.go:107`_ diff --git a/fern/pages/go_api/go-api-cuvs.md b/fern/pages/go_api/go-api-cuvs.md new file mode 100644 index 0000000000..bbbccc6b81 --- /dev/null +++ b/fern/pages/go_api/go-api-cuvs.md @@ -0,0 +1,339 @@ +--- +slug: api-reference/go-api-cuvs +--- + +# cuVS Package + +_Go package: `cuvs`_ + +_Sources: `go`_ + +## Constants + +### CuvsMemoryNew Constants + +```go +const ( +CuvsMemoryNew = iota +CuvsMemoryRelease +) +``` + +_Source: `go/memory_resource.go:12`_ + +### Supported Distance Metrics + +```go +const ( +DistanceL2 Distance = iota +DistanceSQEuclidean +DistanceEuclidean +DistanceL1 +DistanceCityblock +DistanceInnerProduct +DistanceChebyshev +DistanceCanberra +DistanceCosine +DistanceLp +DistanceCorrelation +DistanceJaccard +DistanceHellinger +DistanceBrayCurtis +DistanceJensenShannon +DistanceHamming +DistanceKLDivergence +DistanceMinkowski +DistanceRusselRao +DistanceDice +) +``` + +Supported distance metrics + +_Source: `go/distance.go:14`_ + +## Variables + +### CDistances + +```go +var CDistances = map[Distance]int{ +``` + +Maps cuvs Go distances to C distances + +_Source: `go/distance.go:38`_ + +### DeviceDataPointer + +```go +var DeviceDataPointer unsafe.Pointer +``` + +_Source: `go/dlpack.go:219`_ + +### NewDeviceDataPointer + +```go +var NewDeviceDataPointer unsafe.Pointer +``` + +_Source: `go/dlpack.go:274`_ + +## Types + +### CuvsError + +```go +type CuvsError C.cuvsError_t +``` + +_Source: `go/exceptions.go:7`_ + +### CuvsMemoryCommand + +```go +type CuvsMemoryCommand int +``` + +_Source: `go/memory_resource.go:10`_ + +### CuvsPoolMemory + +```go +type CuvsPoolMemory struct { ... } +``` + +_Source: `go/memory_resource.go:17`_ + +### Distance + +```go +type Distance int +``` + +_Source: `go/distance.go:11`_ + +### Resource + +```go +type Resource struct { ... } +``` + +Resources are objects that are shared between function calls, +and includes things like CUDA streams, cuBLAS handles and other +resources that are expensive to create. + +_Source: `go/resources.go:11`_ + +### Tensor + +```go +type Tensor[T any] struct { ... } +``` + +ManagedTensor is a wrapper around a dlpack DLManagedTensor object. +This lets you pass matrices in device or host memory into cuvs. + +_Source: `go/dlpack.go:21`_ + +### TensorNumberType + +```go +type TensorNumberType interface { ... } +``` + +_Source: `go/dlpack.go:15`_ + +## Functions + +### CheckCuda + +```go +func CheckCuda(error C.cudaError_t) error +``` + +Wrapper function to convert cuda error to Go error + +_Source: `go/exceptions.go:18`_ + +### CheckCuvs + +```go +func CheckCuvs(error CuvsError) error +``` + +Wrapper function to convert cuvs error to Go error + +_Source: `go/exceptions.go:10`_ + +### Example + +```go +func Example() error +``` + +_Source: `go/memory_resource.go:81`_ + +### NewCuvsPoolMemory + +```go +func NewCuvsPoolMemory(initial_pool_size_percent int, max_pool_size_percent int, managed bool) (*CuvsPoolMemory, error) +``` + +Creates new CuvsPoolMemory struct +initial_pool_size_percent is the initial size of the pool in percent of total available device memory +max_pool_size_percent is the maximum size of the pool in percent of total available device memory +managed is whether to use CUDA managed memory + +_Source: `go/memory_resource.go:29`_ + +### NewResource + +```go +func NewResource(stream C.cudaStream_t) (Resource, error) +``` + +Returns a new Resource object + +_Source: `go/resources.go:16`_ + +### NewTensor + +```go +func NewTensor[T TensorNumberType](data [][]T) (Tensor[T], error) +``` + +Creates a new Tensor on the host and copies the data into it. + +_Source: `go/dlpack.go:27`_ + +### NewTensorOnDevice + +```go +func NewTensorOnDevice[T TensorNumberType](res *Resource, shape []int64) (Tensor[T], error) +``` + +Creates a new Tensor with uninitialized data on the current device. + +_Source: `go/dlpack.go:131`_ + +### NewVector + +```go +func NewVector[T TensorNumberType](data []T) (Tensor[T], error) +``` + +_Source: `go/dlpack.go:79`_ + +### PairwiseDistance + +```go +func PairwiseDistance[T any](Resources Resource, x *Tensor[T], y *Tensor[T], distances *Tensor[float32], metric Distance, metric_arg float32) error +``` + +Computes the pairwise distance between two vectors. + +_Source: `go/distance.go:62`_ + +## Methods + +### CuvsPoolMemory.Close + +```go +func (m *CuvsPoolMemory) Close() error +``` + +Disables pool memory + +_Source: `go/memory_resource.go:73`_ + +### Resource.Close + +```go +func (r Resource) Close() error +``` + +_Source: `go/resources.go:50`_ + +### Resource.GetCudaStream + +```go +func (r Resource) GetCudaStream() (C.cudaStream_t, error) +``` + +Gets the current cuda stream + +_Source: `go/resources.go:39`_ + +### Resource.Sync + +```go +func (r Resource) Sync() error +``` + +Syncs the current cuda stream + +_Source: `go/resources.go:34`_ + +### Tensor.Close + +```go +func (t *Tensor[T]) Close() error +``` + +Destroys Tensor, freeing the memory it was allocated on. + +_Source: `go/dlpack.go:184`_ + +### Tensor.Expand + +```go +func (t *Tensor[T]) Expand(res *Resource, newData [][]T) (*Tensor[T], error) +``` + +Expands the Tensor by adding newData to the end of the current data. +The Tensor must be on the device. + +_Source: `go/dlpack.go:250`_ + +### Tensor.Shape + +```go +func (t *Tensor[T]) Shape() []int64 +``` + +Returns the shape of the Tensor. + +_Source: `go/dlpack.go:244`_ + +### Tensor.Slice + +```go +func (t *Tensor[T]) Slice() ([][]T, error) +``` + +Returns a slice of the data in the Tensor. +The Tensor must be on the host. + +_Source: `go/dlpack.go:358`_ + +### Tensor.ToDevice + +```go +func (t *Tensor[T]) ToDevice(res *Resource) (*Tensor[T], error) +``` + +Transfers the data in the Tensor to the device. + +_Source: `go/dlpack.go:216`_ + +### Tensor.ToHost + +```go +func (t *Tensor[T]) ToHost(res *Resource) (*Tensor[T], error) +``` + +Transfers the data in the Tensor to the host. + +_Source: `go/dlpack.go:325`_ diff --git a/fern/pages/go_api/go-api-ivf-flat.md b/fern/pages/go_api/go-api-ivf-flat.md new file mode 100644 index 0000000000..16b66c1369 --- /dev/null +++ b/fern/pages/go_api/go-api-ivf-flat.md @@ -0,0 +1,238 @@ +--- +slug: api-reference/go-api-ivf-flat +--- + +# Ivf Flat Package + +_Go package: `ivf_flat`_ + +_Sources: `go/ivf_flat`_ + +## Types + +### IndexParams + +```go +type IndexParams struct { ... } +``` + +Supplemental parameters to build IVF Flat Index + +_Source: `go/ivf_flat/index_params.go:13`_ + +### IvfFlatIndex + +```go +type IvfFlatIndex struct { ... } +``` + +IVF Flat Index + +_Source: `go/ivf_flat/ivf_flat.go:14`_ + +### SearchParams + +```go +type SearchParams struct { ... } +``` + +_Source: `go/ivf_flat/search_params.go:10`_ + +## Functions + +### BuildIndex + +```go +func BuildIndex[T any](Resources cuvs.Resource, params *IndexParams, dataset *cuvs.Tensor[T], index *IvfFlatIndex) error +``` + +Builds an IvfFlatIndex from the dataset for efficient search. + +#### Arguments + +* `Resources` - Resources to use +* `params` - Parameters for building the index +* `dataset` - A row-major Tensor on either the host or device to index +* `index` - IvfFlatIndex to build + +_Source: `go/ivf_flat/ivf_flat.go:38`_ + +### CreateIndex + +```go +func CreateIndex[T any](params *IndexParams, dataset *cuvs.Tensor[T]) (*IvfFlatIndex, error) +``` + +Creates a new empty IvfFlatIndex + +_Source: `go/ivf_flat/ivf_flat.go:20`_ + +### CreateIndexParams + +```go +func CreateIndexParams() (*IndexParams, error) +``` + +Creates a new IndexParams + +_Source: `go/ivf_flat/index_params.go:18`_ + +### CreateSearchParams + +```go +func CreateSearchParams() (*SearchParams, error) +``` + +Creates a new SearchParams + +_Source: `go/ivf_flat/search_params.go:15`_ + +### GetCenters + +```go +func GetCenters[T any](index *IvfFlatIndex, centers *cuvs.Tensor[T]) error +``` + +_Source: `go/ivf_flat/ivf_flat.go:108`_ + +### GetDim + +```go +func GetDim(index *IvfFlatIndex) (dim int64, err error) +``` + +_Source: `go/ivf_flat/ivf_flat.go:93`_ + +### GetNLists + +```go +func GetNLists(index *IvfFlatIndex) (nlist int64, err error) +``` + +_Source: `go/ivf_flat/ivf_flat.go:78`_ + +### SearchIndex + +```go +func SearchIndex[T any](Resources cuvs.Resource, params *SearchParams, index *IvfFlatIndex, queries *cuvs.Tensor[T], neighbors *cuvs.Tensor[int64], distances *cuvs.Tensor[T]) error +``` + +Perform a Approximate Nearest Neighbors search on the Index + +#### Arguments + +* `Resources` - Resources to use +* `params` - Parameters to use in searching the index +* `index` - IvfFlatIndex to search +* `queries` - A tensor in device memory to query for +* `neighbors` - Tensor in device memory that receives the indices of the nearest neighbors +* `distances` - Tensor in device memory that receives the distances of the nearest neighbors + +_Source: `go/ivf_flat/ivf_flat.go:66`_ + +## Methods + +### IndexParams.Close + +```go +func (p *IndexParams) Close() error +``` + +Destroys IndexParams + +_Source: `go/ivf_flat/index_params.go:81`_ + +### IndexParams.SetAddDataOnBuild + +```go +func (p *IndexParams) SetAddDataOnBuild(add_data_on_build bool) (*IndexParams, error) +``` + +After training the coarse and fine quantizers, we will populate +the index with the dataset if add_data_on_build == true, otherwise +the index is left empty, and the extend method can be used +to add new vectors to the index. + +_Source: `go/ivf_flat/index_params.go:71`_ + +### IndexParams.SetKMeansNIters + +```go +func (p *IndexParams) SetKMeansNIters(kmeans_n_iters uint32) (*IndexParams, error) +``` + +The number of iterations searching for kmeans centers during index building. + +_Source: `go/ivf_flat/index_params.go:54`_ + +### IndexParams.SetKMeansTrainsetFraction + +```go +func (p *IndexParams) SetKMeansTrainsetFraction(kmeans_trainset_fraction float64) (*IndexParams, error) +``` + +If kmeans_trainset_fraction is less than 1, then the dataset is +subsampled, and only n_samples * kmeans_trainset_fraction rows +are used for training. + +_Source: `go/ivf_flat/index_params.go:62`_ + +### IndexParams.SetMetric + +```go +func (p *IndexParams) SetMetric(metric cuvs.Distance) (*IndexParams, error) +``` + +Distance Type to use for building the index + +_Source: `go/ivf_flat/index_params.go:36`_ + +### IndexParams.SetMetricArg + +```go +func (p *IndexParams) SetMetricArg(metric_arg float32) (*IndexParams, error) +``` + +Metric argument for Minkowski distances - set to 2.0 if not applicable + +_Source: `go/ivf_flat/index_params.go:48`_ + +### IndexParams.SetNLists + +```go +func (p *IndexParams) SetNLists(n_lists uint32) (*IndexParams, error) +``` + +The number of clusters used in the coarse quantizer. + +_Source: `go/ivf_flat/index_params.go:30`_ + +### IvfFlatIndex.Close + +```go +func (index *IvfFlatIndex) Close() error +``` + +Destroys the IvfFlatIndex + +_Source: `go/ivf_flat/ivf_flat.go:48`_ + +### SearchParams.Close + +```go +func (p *SearchParams) Close() error +``` + +Destroy SearchParams + +_Source: `go/ivf_flat/search_params.go:33`_ + +### SearchParams.SetNProbes + +```go +func (p *SearchParams) SetNProbes(n_probes uint32) (*SearchParams, error) +``` + +The number of clusters to search. + +_Source: `go/ivf_flat/search_params.go:27`_ diff --git a/fern/pages/go_api/go-api-ivf-pq.md b/fern/pages/go_api/go-api-ivf-pq.md new file mode 100644 index 0000000000..0a3d6e0f72 --- /dev/null +++ b/fern/pages/go_api/go-api-ivf-pq.md @@ -0,0 +1,346 @@ +--- +slug: api-reference/go-api-ivf-pq +--- + +# Ivf Pq Package + +_Go package: `ivf_pq`_ + +_Sources: `go/ivf_pq`_ + +## Constants + +### InternalDistance_Float32 Constants + +```go +const ( +InternalDistance_Float32 internalDistanceDtype = iota +InternalDistance_Float64 +) +``` + +_Source: `go/ivf_pq/search_params.go:43`_ + +### Lut_Uint8 Constants + +```go +const ( +Lut_Uint8 lutDtype = iota +Lut_Uint16 +Lut_Uint32 +Lut_Uint64 +Lut_Int8 +Lut_Int16 +Lut_Int32 +Lut_Int64 +) +``` + +_Source: `go/ivf_pq/search_params.go:19`_ + +### Subspace Constants + +```go +const ( +Subspace codebookKind = iota +Cluster +) +``` + +_Source: `go/ivf_pq/index_params.go:18`_ + +## Variables + +### CInternalDistanceDtypes + +```go +var CInternalDistanceDtypes = map[internalDistanceDtype]int{ +``` + +_Source: `go/ivf_pq/search_params.go:48`_ + +## Types + +### IndexParams + +```go +type IndexParams struct { ... } +``` + +_Source: `go/ivf_pq/index_params.go:12`_ + +### IvfPqIndex + +```go +type IvfPqIndex struct { ... } +``` + +IVF PQ Index + +_Source: `go/ivf_pq/ivf_pq.go:14`_ + +### SearchParams + +```go +type SearchParams struct { ... } +``` + +Supplemental parameters to search IVF PQ Index + +_Source: `go/ivf_pq/search_params.go:13`_ + +## Functions + +### BuildIndex + +```go +func BuildIndex[T any](Resources cuvs.Resource, params *IndexParams, dataset *cuvs.Tensor[T], index *IvfPqIndex) error +``` + +Builds an IvfPqIndex from the dataset for efficient search. + +#### Arguments + +* `Resources` - Resources to use +* `params` - Parameters for building the index +* `dataset` - A row-major Tensor on either the host or device to index +* `index` - IvfPqIndex to build + +_Source: `go/ivf_pq/ivf_pq.go:39`_ + +### CreateIndex + +```go +func CreateIndex(params *IndexParams, dataset *cuvs.Tensor[float32]) (*IvfPqIndex, error) +``` + +Creates a new empty IvfPqIndex + +_Source: `go/ivf_pq/ivf_pq.go:20`_ + +### CreateIndexParams + +```go +func CreateIndexParams() (*IndexParams, error) +``` + +Creates a new IndexParams + +_Source: `go/ivf_pq/index_params.go:29`_ + +### CreateSearchParams + +```go +func CreateSearchParams() (*SearchParams, error) +``` + +Creates a new SearchParams + +_Source: `go/ivf_pq/search_params.go:54`_ + +### SearchIndex + +```go +func SearchIndex[T any](Resources cuvs.Resource, params *SearchParams, index *IvfPqIndex, queries *cuvs.Tensor[T], neighbors *cuvs.Tensor[int64], distances *cuvs.Tensor[T]) error +``` + +Perform a Approximate Nearest Neighbors search on the Index + +#### Arguments + +* `Resources` - Resources to use +* `params` - Parameters to use in searching the index +* `index` - IvfPqIndex to search +* `queries` - A tensor in device memory to query for +* `neighbors` - Tensor in device memory that receives the indices of the nearest neighbors +* `distances` - Tensor in device memory that receives the distances of the nearest neighbors + +_Source: `go/ivf_pq/ivf_pq.go:67`_ + +## Methods + +### IndexParams.Close + +```go +func (p *IndexParams) Close() error +``` + +Destroys IndexParams + +_Source: `go/ivf_pq/index_params.go:143`_ + +### IndexParams.SetAddDataOnBuild + +```go +func (p *IndexParams) SetAddDataOnBuild(add_data_on_build bool) (*IndexParams, error) +``` + +After training the coarse and fine quantizers, we will populate +the index with the dataset if add_data_on_build == true, otherwise +the index is left empty, and the extend method can be used +to add new vectors to the index. + +_Source: `go/ivf_pq/index_params.go:133`_ + +### IndexParams.SetCodebookKind + +```go +func (p *IndexParams) SetCodebookKind(codebook_kind codebookKind) (*IndexParams, error) +``` + +_Source: `go/ivf_pq/index_params.go:98`_ + +### IndexParams.SetForceRandomRotation + +```go +func (p *IndexParams) SetForceRandomRotation(force_random_rotation bool) (*IndexParams, error) +``` + +Apply a random rotation matrix on the input data and queries even +if `dim % pq_dim == 0`. Note: if `dim` is not multiple of `pq_dim`, +a random rotation is always applied to the input data and queries +to transform the working space from `dim` to `rot_dim`, which may +be slightly larger than the original space and and is a multiple +of `pq_dim` (`rot_dim % pq_dim == 0`). However, this transform is +not necessary when `dim` is multiple of `pq_dim` (`dim == rot_dim`, +hence no need in adding "extra" data columns / features). By +default, if `dim == rot_dim`, the rotation transform is +initialized with the identity matrix. When +`force_random_rotation == True`, a random orthogonal transform + +_Source: `go/ivf_pq/index_params.go:120`_ + +### IndexParams.SetKMeansNIters + +```go +func (p *IndexParams) SetKMeansNIters(kmeans_n_iters uint32) (*IndexParams, error) +``` + +The number of iterations searching for kmeans centers during index building. + +_Source: `go/ivf_pq/index_params.go:65`_ + +### IndexParams.SetKMeansTrainsetFraction + +```go +func (p *IndexParams) SetKMeansTrainsetFraction(kmeans_trainset_fraction float64) (*IndexParams, error) +``` + +If kmeans_trainset_fraction is less than 1, then the dataset is +subsampled, and only n_samples * kmeans_trainset_fraction rows +are used for training. + +_Source: `go/ivf_pq/index_params.go:73`_ + +### IndexParams.SetMetric + +```go +func (p *IndexParams) SetMetric(metric cuvs.Distance) (*IndexParams, error) +``` + +Distance Type to use for building the index + +_Source: `go/ivf_pq/index_params.go:47`_ + +### IndexParams.SetMetricArg + +```go +func (p *IndexParams) SetMetricArg(metric_arg float32) (*IndexParams, error) +``` + +Metric argument for Minkowski distances - set to 2.0 if not applicable + +_Source: `go/ivf_pq/index_params.go:59`_ + +### IndexParams.SetNLists + +```go +func (p *IndexParams) SetNLists(n_lists uint32) (*IndexParams, error) +``` + +The number of clusters used in the coarse quantizer. + +_Source: `go/ivf_pq/index_params.go:41`_ + +### IndexParams.SetPQBits + +```go +func (p *IndexParams) SetPQBits(pq_bits uint32) (*IndexParams, error) +``` + +The bit length of the vector element after quantization. + +_Source: `go/ivf_pq/index_params.go:79`_ + +### IndexParams.SetPQDim + +```go +func (p *IndexParams) SetPQDim(pq_dim uint32) (*IndexParams, error) +``` + +The dimensionality of a the vector after product quantization. +When zero, an optimal value is selected using a heuristic. Note +pq_dim * pq_bits must be a multiple of 8. Hint: a smaller 'pq_dim' +results in a smaller index size and better search performance, but +lower recall. If 'pq_bits' is 8, 'pq_dim' can be set to any number, +but multiple of 8 are desirable for good performance. If 'pq_bits' +is not 8, 'pq_dim' should be a multiple of 8. For good performance, +it is desirable that 'pq_dim' is a multiple of 32. Ideally, +'pq_dim' should be also a divisor of the dataset dim. + +_Source: `go/ivf_pq/index_params.go:93`_ + +### IvfPqIndex.Close + +```go +func (index *IvfPqIndex) Close() error +``` + +Destroys the IvfPqIndex + +_Source: `go/ivf_pq/ivf_pq.go:49`_ + +### SearchParams.Close + +```go +func (p *SearchParams) Close() error +``` + +Destroys SearchParams + +_Source: `go/ivf_pq/search_params.go:101`_ + +### SearchParams.SetInternalDistanceDtype + +```go +func (p *SearchParams) SetInternalDistanceDtype(internal_distance_dtype internalDistanceDtype) (*SearchParams, error) +``` + +Storage data type for distance/similarity computation. + +_Source: `go/ivf_pq/search_params.go:89`_ + +### SearchParams.SetLutDtype + +```go +func (p *SearchParams) SetLutDtype(lut_dtype lutDtype) (*SearchParams, error) +``` + +Data type of look up table to be created dynamically at search +time. The use of low-precision types reduces the amount of shared +memory required at search time, so fast shared memory kernels can +be used even for datasets with large dimansionality. Note that +the recall is slightly degraded when low-precision type is +selected. + +_Source: `go/ivf_pq/search_params.go:77`_ + +### SearchParams.SetNProbes + +```go +func (p *SearchParams) SetNProbes(n_probes uint32) (*SearchParams, error) +``` + +The number of clusters to search. + +_Source: `go/ivf_pq/search_params.go:66`_ diff --git a/fern/pages/go_api/index.md b/fern/pages/go_api/index.md new file mode 100644 index 0000000000..452108fbf8 --- /dev/null +++ b/fern/pages/go_api/index.md @@ -0,0 +1,9 @@ +# Go API Documentation + +These pages are generated from the Go source files under `go`. + +- [`brute_force`](/api-reference/go-api-brute-force) +- [`cagra`](/api-reference/go-api-cagra) +- [`cuvs`](/api-reference/go-api-cuvs) +- [`ivf_flat`](/api-reference/go-api-ivf-flat) +- [`ivf_pq`](/api-reference/go-api-ivf-pq) diff --git a/docs/source/images/build_benchmarks.png b/fern/pages/images/build_benchmarks.png similarity index 100% rename from docs/source/images/build_benchmarks.png rename to fern/pages/images/build_benchmarks.png diff --git a/docs/source/images/index_recalls.png b/fern/pages/images/index_recalls.png similarity index 100% rename from docs/source/images/index_recalls.png rename to fern/pages/images/index_recalls.png diff --git a/docs/source/images/recall_buckets.png b/fern/pages/images/recall_buckets.png similarity index 100% rename from docs/source/images/recall_buckets.png rename to fern/pages/images/recall_buckets.png diff --git a/fern/pages/img/tech_stack.png b/fern/pages/img/tech_stack.png new file mode 100644 index 0000000000000000000000000000000000000000..65ffe57f4974aba6d0d14953dfd4cb2c72b9b1d3 GIT binary patch literal 189873 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%0AY}Kq3==!q-gav&Yv2@Ws}k4ir)ucM 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�&0EV@I^c?T9_&te+c!e7<4nyCXJqhv8@FfWN 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ЀwcRIxjtoTL&6h1y8l? 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%0A^~nCEm_nabIawq_a)SgL@+J{ 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. +Welcome to cuVS, the premier library for GPU-accelerated vector search and clustering! cuVS provides several core building blocks for constructing new algorithms, as well as end-to-end vector search and clustering algorithms for use either standalone or through a growing list of [integrations](integrations.md). -Useful Resources -################ +## Useful Resources -.. _cuvs_reference: https://docs.rapids.ai/api/cuvs/stable/ +[cuvs_reference]: https://docs.rapids.ai/api/cuvs/stable/ -- `Example Notebooks `_: Example notebooks -- `Code Examples `_: Self-contained code examples -- `RAPIDS Community `_: Get help, contribute, and collaborate. -- `GitHub repository `_: Download the cuVS source code. -- `Issue tracker `_: Report issues or request features. +- [Example Notebooks](https://github.com/rapidsai/cuvs/tree/HEAD/notebooks): Example notebooks +- [Code Examples](https://github.com/rapidsai/cuvs/tree/HEAD/examples): Self-contained code examples +- [RAPIDS Community](https://rapids.ai/community.html): Get help, contribute, and collaborate. +- [GitHub repository](https://github.com/rapidsai/cuvs): Download the cuVS source code. +- [Issue tracker](https://github.com/rapidsai/cuvs/issues): Report issues or request features. - - -What is cuVS? -############# +## What is cuVS? cuVS contains state-of-the-art implementations of several algorithms for running approximate and exact nearest neighbors and clustering on the GPU. It can be used directly or through the various databases and other libraries that have integrated it. The primary goal of cuVS is to simplify the use of GPUs for vector similarity search and clustering. Vector search is an information retrieval method that has been growing in popularity over the past few years, partly because of the rising importance of multimedia embeddings created from unstructured data and the need to perform semantic search on the embeddings to find items which are semantically similar to each other. -Vector search is also used in *data mining and machine learning* tasks and comprises an important step in many *clustering* and *visualization* algorithms like `UMAP `_, `t-SNE `_, K-means, and `HDBSCAN `_. +Vector search is also used in *data mining and machine learning* tasks and comprises an important step in many *clustering* and *visualization* algorithms like [UMAP](https://arxiv.org/abs/2008.00325), [t-SNE](https://lvdmaaten.github.io/tsne/), K-means, and [HDBSCAN](https://hdbscan.readthedocs.io/en/latest/how_hdbscan_works.html). -Finally, faster vector search enables interactions between dense vectors and graphs. Converting a pile of dense vectors into nearest neighbors graphs unlocks the entire world of graph analysis algorithms, such as those found in `GraphBLAS `_ and `cuGraph `_. +Finally, faster vector search enables interactions between dense vectors and graphs. Converting a pile of dense vectors into nearest neighbors graphs unlocks the entire world of graph analysis algorithms, such as those found in [GraphBLAS](https://graphblas.org/) and [cuGraph](https://github.com/rapidsai/cugraph). Below are some common use-cases for vector search -Semantic search -~~~~~~~~~~~~~~~ +### Semantic search - Generative AI & Retrieval augmented generation (RAG) - Recommender systems - Computer vision @@ -40,9 +34,7 @@ Semantic search - Molecular search - Model training - -Data mining -~~~~~~~~~~~ +### Data mining - Clustering algorithms - Visualization algorithms - Sampling algorithms @@ -50,8 +42,7 @@ Data mining - Ensemble methods - k-NN graph construction -Why cuVS? -######### +## Why cuVS? There are several benefits to using cuVS and GPUs for vector search, including @@ -65,28 +56,19 @@ There are several benefits to using cuVS and GPUs for vector search, including In addition to the items above, cuVS shoulders the responsibility of keeping non-trivial accelerated code up to date as new NVIDIA architectures and CUDA versions are released. This provides a delightful development experience, guaranteeing that any libraries, databases, or applications built on top of it will always be receiving the best performance and scale. -cuVS Technology Stack -##################### +## cuVS Technology Stack cuVS is built on top of the RAPIDS RAFT library of high performance machine learning primitives and provides all the necessary routines for vector search and clustering on the GPU. -.. image:: ../../img/tech_stack.png - :width: 600 - :alt: cuVS is built on top of low-level CUDA libraries and provides many important routines that enable vector search and clustering on the GPU - - - -Contents -######## +![cuVS is built on top of low-level CUDA libraries and provides many important routines that enable vector search and clustering on the GPU](img/tech_stack.png) -.. toctree:: - :maxdepth: 4 +## Pages - build.rst - getting_started.rst - integrations.rst - cuvs_bench/index.rst - api_docs.rst - advanced_topics.rst - contributing.md - developer_guide.md +- [Installation](build.md) +- [Getting Started](getting_started.md) +- [Integrations](integrations.md) +- [cuVS Bench](cuvs_bench/index.md) +- [API Reference](api_docs.md) +- [Advanced Topics](advanced_topics.md) +- [Contributing](contributing.md) +- [Developer Guide](developer_guide.md) diff --git a/fern/pages/integrations.md b/fern/pages/integrations.md new file mode 100644 index 0000000000..3e43f1b689 --- /dev/null +++ b/fern/pages/integrations.md @@ -0,0 +1,10 @@ +# Integrations + +Aside from using cuVS standalone, it can be consumed through a number of sdk and vector database integrations. + +## Pages + +- [Faiss](integrations/faiss.md) +- [Milvus](integrations/milvus.md) +- [Lucene](integrations/lucene.md) +- [Kinetica](integrations/kinetica.md) diff --git a/docs/source/integrations/faiss.rst b/fern/pages/integrations/faiss.md similarity index 73% rename from docs/source/integrations/faiss.rst rename to fern/pages/integrations/faiss.md index 1fc88d921c..6f6aee53e0 100644 --- a/docs/source/integrations/faiss.rst +++ b/fern/pages/integrations/faiss.md @@ -1,6 +1,5 @@ -Faiss ------ +# Faiss Faiss v1.10.0 and beyond provides a special conda package that enables a cuVS backend for the Flat, IVF-Flat, IVF-PQ and CAGRA indexes on the GPU. Like the classical Faiss GPU indexes, the cuVS backend also enables interoperability between Faiss CPU indexes, allowing an index to be trained on GPU, searched on CPU, and vice versa. -The cuVS backend can be enabled by setting the appropriate cmake flag while building Faiss from source. A pre-compiled conda package can also be installed. Refer to `Faiss installation guidelines `_ for more information. +The cuVS backend can be enabled by setting the appropriate cmake flag while building Faiss from source. A pre-compiled conda package can also be installed. Refer to [Faiss installation guidelines](https://github.com/facebookresearch/faiss/blob/main/INSTALL.md) for more information. diff --git a/fern/pages/integrations/kinetica.md b/fern/pages/integrations/kinetica.md new file mode 100644 index 0000000000..e690e6738a --- /dev/null +++ b/fern/pages/integrations/kinetica.md @@ -0,0 +1,5 @@ +# Kinetica + +Starting with release 7.2, Kinetica supports the graph-based the CAGRA algorithm from RAFT. Kinetica will continue to improve its support over coming versions, while also migrating to cuVS as we work to move the vector search algorithms out of RAFT and into cuVS. + +Kinetica currently offers the ability to create a CAGRA index in a SQL `CREATE_TABLE` statement, as outlined in their [vector search indexing docs](https://docs.kinetica.com/7.2/concepts/indexes/#cagra-index). Kinetica is not open source, but the RAFT indexes can be enabled in the developer edition, which can be installed [here](https://www.kinetica.com/try/#download_instructions). diff --git a/docs/source/integrations/lucene.rst b/fern/pages/integrations/lucene.md similarity index 74% rename from docs/source/integrations/lucene.rst rename to fern/pages/integrations/lucene.md index d20052545b..bc60123c3f 100644 --- a/docs/source/integrations/lucene.rst +++ b/fern/pages/integrations/lucene.md @@ -1,6 +1,5 @@ -Lucene ------- +# Lucene An experimental Lucene connector for cuVS enables GPU-accelerated vector search indexes through Lucene. Initial benchmarks are showing that this connector can drastically improve the performance of both indexing and search in Lucene. This connector will continue to be improved over time and any interested developers are encouraged to contribute. -Install and evaluate the `lucene-cuvs` connector on `Github `_. +Install and evaluate the `lucene-cuvs` connector on [Github](https://github.com/SearchScale/lucene-cuvs). diff --git a/docs/source/integrations/milvus.rst b/fern/pages/integrations/milvus.md similarity index 59% rename from docs/source/integrations/milvus.rst rename to fern/pages/integrations/milvus.md index 4139cca526..e33ab43b59 100644 --- a/docs/source/integrations/milvus.rst +++ b/fern/pages/integrations/milvus.md @@ -1,8 +1,7 @@ -Milvus ------- +# Milvus -In version 2.3, Milvus released support for IVF-Flat and IVF-PQ indexes on the GPU through RAFT. Version 2.4 adds support for brute-force and the graph-based CAGRA index on the GPU. Please refer to the `Milvus documentation `_ to install Milvus with GPU support. +In version 2.3, Milvus released support for IVF-Flat and IVF-PQ indexes on the GPU through RAFT. Version 2.4 adds support for brute-force and the graph-based CAGRA index on the GPU. Please refer to the [Milvus documentation](https://milvus.io/docs/install_standalone-docker-compose-gpu.md) to install Milvus with GPU support. -The GPU indexes can be enabled by using the index types prefixed with `GPU_`, as outlined in the `Milvus index build guide `_. +The GPU indexes can be enabled by using the index types prefixed with `GPU_`, as outlined in the [Milvus index build guide](https://milvus.io/docs/build_index.md#Prepare-index-parameter). Milvus will be migrating their GPU support from RAFT to cuVS as we continue to move the vector search algorithms out of RAFT and into cuVS. diff --git a/fern/pages/java_api/index.md b/fern/pages/java_api/index.md new file mode 100644 index 0000000000..968ba23c62 --- /dev/null +++ b/fern/pages/java_api/index.md @@ -0,0 +1,44 @@ +# Java API Documentation + +These pages are generated from the Java source files in `java/cuvs-java/src/main`. + +## `com.nvidia.cuvs` + +- [BruteForceIndex](/api-reference/java-api-com-nvidia-cuvs-bruteforceindex) +- [BruteForceIndexParams](/api-reference/java-api-com-nvidia-cuvs-bruteforceindexparams) +- [BruteForceQuery](/api-reference/java-api-com-nvidia-cuvs-bruteforcequery) +- [CagraCompressionParams](/api-reference/java-api-com-nvidia-cuvs-cagracompressionparams) +- [CagraIndex](/api-reference/java-api-com-nvidia-cuvs-cagraindex) +- [CagraIndexParams](/api-reference/java-api-com-nvidia-cuvs-cagraindexparams) +- [CagraMergeParams](/api-reference/java-api-com-nvidia-cuvs-cagramergeparams) +- [CagraQuery](/api-reference/java-api-com-nvidia-cuvs-cagraquery) +- [CagraSearchParams](/api-reference/java-api-com-nvidia-cuvs-cagrasearchparams) +- [CuVSAceParams](/api-reference/java-api-com-nvidia-cuvs-cuvsaceparams) +- [CuVSDeviceMatrix](/api-reference/java-api-com-nvidia-cuvs-cuvsdevicematrix) +- [CuVSHostMatrix](/api-reference/java-api-com-nvidia-cuvs-cuvshostmatrix) +- [CuVSIvfPqIndexParams](/api-reference/java-api-com-nvidia-cuvs-cuvsivfpqindexparams) +- [CuVSIvfPqParams](/api-reference/java-api-com-nvidia-cuvs-cuvsivfpqparams) +- [CuVSIvfPqSearchParams](/api-reference/java-api-com-nvidia-cuvs-cuvsivfpqsearchparams) +- [CuVSMatrix](/api-reference/java-api-com-nvidia-cuvs-cuvsmatrix) +- [CuVSResources](/api-reference/java-api-com-nvidia-cuvs-cuvsresources) +- [CuVSResourcesInfo](/api-reference/java-api-com-nvidia-cuvs-cuvsresourcesinfo) +- [DelegatingScopedAccess](/api-reference/java-api-com-nvidia-cuvs-delegatingscopedaccess) +- [GPUInfo](/api-reference/java-api-com-nvidia-cuvs-gpuinfo) +- [GPUInfoProvider](/api-reference/java-api-com-nvidia-cuvs-gpuinfoprovider) +- [HnswAceParams](/api-reference/java-api-com-nvidia-cuvs-hnswaceparams) +- [HnswIndex](/api-reference/java-api-com-nvidia-cuvs-hnswindex) +- [HnswIndexParams](/api-reference/java-api-com-nvidia-cuvs-hnswindexparams) +- [HnswQuery](/api-reference/java-api-com-nvidia-cuvs-hnswquery) +- [HnswSearchParams](/api-reference/java-api-com-nvidia-cuvs-hnswsearchparams) +- [LibraryException](/api-reference/java-api-com-nvidia-cuvs-libraryexception) +- [RowView](/api-reference/java-api-com-nvidia-cuvs-rowview) +- [SearchResults](/api-reference/java-api-com-nvidia-cuvs-searchresults) +- [SynchronizedCuVSResources](/api-reference/java-api-com-nvidia-cuvs-synchronizedcuvsresources) +- [TieredIndex](/api-reference/java-api-com-nvidia-cuvs-tieredindex) +- [TieredIndexParams](/api-reference/java-api-com-nvidia-cuvs-tieredindexparams) +- [TieredIndexQuery](/api-reference/java-api-com-nvidia-cuvs-tieredindexquery) + +## `com.nvidia.cuvs.spi` + +- [CuVSProvider](/api-reference/java-api-com-nvidia-cuvs-spi-cuvsprovider) +- [CuVSServiceProvider](/api-reference/java-api-com-nvidia-cuvs-spi-cuvsserviceprovider) diff --git a/fern/pages/java_api/java-api-com-nvidia-cuvs-bruteforceindex.md b/fern/pages/java_api/java-api-com-nvidia-cuvs-bruteforceindex.md new file mode 100644 index 0000000000..72f8cbe709 --- /dev/null +++ b/fern/pages/java_api/java-api-com-nvidia-cuvs-bruteforceindex.md @@ -0,0 +1,203 @@ +--- +slug: api-reference/java-api-com-nvidia-cuvs-bruteforceindex +--- + +# BruteForceIndex + +_Java package: `com.nvidia.cuvs`_ + +```java +public interface BruteForceIndex extends AutoCloseable +``` + +`BruteForceIndex` encapsulates a BRUTEFORCE index, along with methods +to interact with it. + +## Public Members + +### close + +```java +@Override void close() throws Exception +``` + +Invokes the native destroy_brute_force_index function to de-allocate +BRUTEFORCE index + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/BruteForceIndex.java:25`_ + +### search + +```java +SearchResults search(BruteForceQuery cuvsQuery) throws Throwable +``` + +Invokes the native search_brute_force_index via the Panama API for searching +a BRUTEFORCE index. + +**Parameters** + +| Name | Description | +| --- | --- | +| `cuvsQuery` | an instance of `BruteForceQuery` holding the query vectors and other parameters | + +**Returns** + +an instance of `SearchResults` containing the results + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/BruteForceIndex.java:36`_ + +### serialize + +```java +void serialize(OutputStream outputStream) throws Throwable +``` + +A method to persist a BRUTEFORCE index using an instance of +`OutputStream` for writing index bytes. + +**Parameters** + +| Name | Description | +| --- | --- | +| `outputStream` | an instance of `OutputStream` to write the index bytes into | + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/BruteForceIndex.java:45`_ + +### serialize + +```java +void serialize(OutputStream outputStream, Path tempFile) throws Throwable +``` + +A method to persist a BRUTEFORCE index using an instance of +`OutputStream` and path to the intermediate temporary file. + +**Parameters** + +| Name | Description | +| --- | --- | +| `outputStream` | an instance of `OutputStream` to write the index bytes to | +| `tempFile` | an intermediate `Path` where BRUTEFORCE index is written temporarily | + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/BruteForceIndex.java:56`_ + +### newBuilder + +```java +static Builder newBuilder(CuVSResources cuvsResources) +``` + +Creates a new Builder with an instance of `CuVSResources`. + +**Parameters** + +| Name | Description | +| --- | --- | +| `cuvsResources` | an instance of `CuVSResources` | + +**Throws** + +| Type | Description | +| --- | --- | +| `UnsupportedOperationException` | if the provider does not cuvs | + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/BruteForceIndex.java:64`_ + +### withIndexParams + +```java +Builder withIndexParams(BruteForceIndexParams bruteForceIndexParams) +``` + +Registers an instance of configured `BruteForceIndexParams` with this +Builder. + +**Parameters** + +| Name | Description | +| --- | --- | +| `bruteForceIndexParams` | An instance of BruteForceIndexParams | + +**Returns** + +An instance of this Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/BruteForceIndex.java:81`_ + +### from + +```java +Builder from(InputStream inputStream) +``` + +Sets an instance of InputStream typically used when index deserialization is +needed. + +**Parameters** + +| Name | Description | +| --- | --- | +| `inputStream` | an instance of `InputStream` | + +**Returns** + +an instance of this Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/BruteForceIndex.java:90`_ + +### withDataset + +```java +Builder withDataset(float[][] vectors) +``` + +Sets the dataset vectors for building the `BruteForceIndex`. + +**Parameters** + +| Name | Description | +| --- | --- | +| `vectors` | a two-dimensional float array | + +**Returns** + +an instance of this Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/BruteForceIndex.java:98`_ + +### withDataset + +```java +Builder withDataset(CuVSMatrix dataset) +``` + +Sets the dataset for building the `BruteForceIndex`. + +**Parameters** + +| Name | Description | +| --- | --- | +| `dataset` | a `CuVSMatrix` object containing the vectors | + +**Returns** + +an instance of this Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/BruteForceIndex.java:106`_ + +### build + +```java +BruteForceIndex build() throws Throwable +``` + +Builds and returns an instance of `BruteForceIndex`. + +**Returns** + +an instance of `BruteForceIndex` + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/BruteForceIndex.java:113`_ + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/BruteForceIndex.java:20`_ diff --git a/fern/pages/java_api/java-api-com-nvidia-cuvs-bruteforceindexparams.md b/fern/pages/java_api/java-api-com-nvidia-cuvs-bruteforceindexparams.md new file mode 100644 index 0000000000..7ee1620cad --- /dev/null +++ b/fern/pages/java_api/java-api-com-nvidia-cuvs-bruteforceindexparams.md @@ -0,0 +1,61 @@ +--- +slug: api-reference/java-api-com-nvidia-cuvs-bruteforceindexparams +--- + +# BruteForceIndexParams + +_Java package: `com.nvidia.cuvs`_ + +```java +public class BruteForceIndexParams +``` + +Supplemental parameters to build BRUTEFORCE index. + +## Public Members + +### getNumWriterThreads + +```java +public int getNumWriterThreads() +``` + +Gets the number of threads used to build the index. + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/BruteForceIndexParams.java:27`_ + +### withNumWriterThreads + +```java +public Builder withNumWriterThreads(int numWriterThreads) +``` + +Sets the number of writer threads to use for indexing. + +**Parameters** + +| Name | Description | +| --- | --- | +| `numWriterThreads` | number of writer threads to use | + +**Returns** + +an instance of Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/BruteForceIndexParams.java:44`_ + +### build + +```java +public BruteForceIndexParams build() +``` + +Builds an instance of `BruteForceIndexParams`. + +**Returns** + +an instance of `BruteForceIndexParams` + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/BruteForceIndexParams.java:54`_ + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/BruteForceIndexParams.java:12`_ diff --git a/fern/pages/java_api/java-api-com-nvidia-cuvs-bruteforcequery.md b/fern/pages/java_api/java-api-com-nvidia-cuvs-bruteforcequery.md new file mode 100644 index 0000000000..1e9302b6d6 --- /dev/null +++ b/fern/pages/java_api/java-api-com-nvidia-cuvs-bruteforcequery.md @@ -0,0 +1,237 @@ +--- +slug: api-reference/java-api-com-nvidia-cuvs-bruteforcequery +--- + +# BruteForceQuery + +_Java package: `com.nvidia.cuvs`_ + +```java +public class BruteForceQuery +``` + +BruteForceQuery holds the query vectors to be used while invoking search. + +Thread Safety: Each BruteForceQuery instance should use its own +CuVSResources object that is not shared with other threads. Sharing CuVSResources +between threads can lead to memory allocation errors or JVM crashes. + +## Public Members + +### BruteForceQuery + +```java +public BruteForceQuery( float[][] queryVectors, LongToIntFunction mapping, int topK, BitSet[] prefilters, int numDocs, CuVSResources resources) +``` + +Constructs an instance of `BruteForceQuery` using queryVectors, +mapping, and topK. + +**Parameters** + +| Name | Description | +| --- | --- | +| `queryVectors` | 2D float query vector array | +| `mapping` | a function mapping ordinals (neighbor IDs) to custom user IDs | +| `topK` | the top k results to return | +| `prefilters` | the prefilters data to use while searching the BRUTEFORCE index | +| `numDocs` | Maximum of bits in each prefilter, representing number of documents in this index. Used only when prefilter(s) is/are passed. | +| `resources` | CuVSResources instance to use for this query | + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/BruteForceQuery.java:42`_ + +### getQueryVectors + +```java +public float[][] getQueryVectors() +``` + +Gets the query vector 2D float array. + +**Returns** + +2D float array + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/BruteForceQuery.java:62`_ + +### getMapping + +```java +public LongToIntFunction getMapping() +``` + +Gets the function mapping ordinals (neighbor IDs) to custom user IDs + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/BruteForceQuery.java:69`_ + +### getTopK + +```java +public int getTopK() +``` + +Gets the topK value. + +**Returns** + +an integer + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/BruteForceQuery.java:78`_ + +### getPrefilters + +```java +public BitSet[] getPrefilters() +``` + +Gets the prefilter long array + +**Returns** + +an array of bitsets + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/BruteForceQuery.java:87`_ + +### getNumDocs + +```java +public int getNumDocs() +``` + +Gets the number of documents supposed to be in this index, as used for prefilters + +**Returns** + +number of documents as an integer + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/BruteForceQuery.java:96`_ + +### getResources + +```java +public CuVSResources getResources() +``` + +Gets the CuVSResources instance for this query. + +**Returns** + +the CuVSResources instance + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/BruteForceQuery.java:105`_ + +### Builder + +```java +public Builder(CuVSResources resources) +``` + +Constructor that requires CuVSResources. + +Important: The provided CuVSResources instance should not be +shared with other threads. Each thread performing searches should create its own +CuVSResources instance to avoid memory allocation conflicts and potential JVM crashes. + +**Parameters** + +| Name | Description | +| --- | --- | +| `resources` | the CuVSResources instance to use for this query (must not be shared between threads) | + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/BruteForceQuery.java:143`_ + +### withQueryVectors + +```java +public Builder withQueryVectors(float[][] queryVectors) +``` + +Registers the query vectors to be passed in the search call. + +**Parameters** + +| Name | Description | +| --- | --- | +| `queryVectors` | 2D float query vector array | + +**Returns** + +an instance of this Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/BruteForceQuery.java:153`_ + +### withMapping + +```java +public Builder withMapping(LongToIntFunction mapping) +``` + +Sets the function used to map ordinals (neighbor IDs) to custom user IDs + +**Parameters** + +| Name | Description | +| --- | --- | +| `mapping` | a function mapping ordinals (neighbor IDs) to custom user IDs | + +**Returns** + +an instance of this Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/BruteForceQuery.java:164`_ + +### withTopK + +```java +public Builder withTopK(int topK) +``` + +Registers the topK value. + +**Parameters** + +| Name | Description | +| --- | --- | +| `topK` | the topK value used to retrieve the topK results | + +**Returns** + +an instance of this Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/BruteForceQuery.java:175`_ + +### withPrefilters + +```java +public Builder withPrefilters(BitSet[] prefilters, int numDocs) +``` + +Sets the prefilters data for building the `BruteForceQuery`. + +**Parameters** + +| Name | Description | +| --- | --- | +| `prefilters` | array of bitsets, as many as queries, each containing as many bits as there are vectors in the index | + +**Returns** + +an instance of this Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/BruteForceQuery.java:187`_ + +### build + +```java +public BruteForceQuery build() +``` + +Builds an instance of `BruteForceQuery` + +**Returns** + +an instance of `BruteForceQuery` + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/BruteForceQuery.java:198`_ + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/BruteForceQuery.java:21`_ diff --git a/fern/pages/java_api/java-api-com-nvidia-cuvs-cagracompressionparams.md b/fern/pages/java_api/java-api-com-nvidia-cuvs-cagracompressionparams.md new file mode 100644 index 0000000000..4aad7e30de --- /dev/null +++ b/fern/pages/java_api/java-api-com-nvidia-cuvs-cagracompressionparams.md @@ -0,0 +1,273 @@ +--- +slug: api-reference/java-api-com-nvidia-cuvs-cagracompressionparams +--- + +# CagraCompressionParams + +_Java package: `com.nvidia.cuvs`_ + +```java +public class CagraCompressionParams +``` + +Supplemental compression parameters to build CAGRA Index. + +## Public Members + +### CagraCompressionParams + +```java +private CagraCompressionParams( int pqBits, int pqDim, int vqNCenters, int kmeansNIters, double vqKmeansTrainsetFraction, double pqKmeansTrainsetFraction) +``` + +Constructs an instance of CagraCompressionParams with passed search +parameters. + +**Parameters** + +| Name | Description | +| --- | --- | +| `pqBits` | the bit length of the vector element after compression by PQ | +| `pqDim` | the dimensionality of the vector after compression by PQ | +| `vqNCenters` | the vector quantization (VQ) codebook size - number of “coarse cluster centers” | +| `kmeansNIters` | the number of iterations searching for kmeans centers (both VQ and PQ phases) | +| `vqKmeansTrainsetFraction` | the fraction of data to use during iterative kmeans building (VQ phase) | +| `pqKmeansTrainsetFraction` | the fraction of data to use during iterative kmeans building (PQ phase) | + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraCompressionParams.java:37`_ + +### getPqBits + +```java +public int getPqBits() +``` + +Gets the bit length of the vector element after compression by PQ. + +**Returns** + +the bit length of the vector element after compression by PQ. + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraCompressionParams.java:57`_ + +### getPqDim + +```java +public int getPqDim() +``` + +Gets the dimensionality of the vector after compression by PQ. + +**Returns** + +the dimensionality of the vector after compression by PQ. + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraCompressionParams.java:66`_ + +### getVqNCenters + +```java +public int getVqNCenters() +``` + +Gets the vector quantization (VQ) codebook size - number of “coarse cluster +centers”. + +**Returns** + +the vector quantization (VQ) codebook size - number of “coarse cluster centers”. + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraCompressionParams.java:77`_ + +### getKmeansNIters + +```java +public int getKmeansNIters() +``` + +Gets the number of iterations searching for kmeans centers (both VQ and PQ +phases). + +**Returns** + +the number of iterations searching for kmeans centers (both VQ and PQ phases). + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraCompressionParams.java:88`_ + +### getVqKmeansTrainsetFraction + +```java +public double getVqKmeansTrainsetFraction() +``` + +Gets the fraction of data to use during iterative kmeans building (VQ phase). + +**Returns** + +the fraction of data to use during iterative kmeans building (VQ phase). + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraCompressionParams.java:98`_ + +### getPqKmeansTrainsetFraction + +```java +public double getPqKmeansTrainsetFraction() +``` + +Gets the fraction of data to use during iterative kmeans building (PQ phase). + +**Returns** + +the fraction of data to use during iterative kmeans building (PQ phase). + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraCompressionParams.java:108`_ + +### withPqBits + +```java +public Builder withPqBits(int pqBits) +``` + +Sets the bit length of the vector element after compression by PQ. + +Possible values: [4, 5, 6, 7, 8]. Hint: the smaller the ‘pq_bits’, the +smaller the index size and the better the search performance, but the lower +the recall. + +**Parameters** + +| Name | Description | +| --- | --- | +| `pqBits` | | + +**Returns** + +an instance of Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraCompressionParams.java:153`_ + +### withPqDim + +```java +public Builder withPqDim(int pqDim) +``` + +Sets the dimensionality of the vector after compression by PQ. + +When zero, an optimal value is selected using a heuristic. + +**Parameters** + +| Name | Description | +| --- | --- | +| `pqDim` | | + +**Returns** + +an instance of Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraCompressionParams.java:166`_ + +### withVqNCenters + +```java +public Builder withVqNCenters(int vqNCenters) +``` + +Sets the vector quantization (VQ) codebook size - number of “coarse cluster +centers”. + +When zero, an optimal value is selected using a heuristic. + +**Parameters** + +| Name | Description | +| --- | --- | +| `vqNCenters` | | + +**Returns** + +an instance of Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraCompressionParams.java:180`_ + +### withKmeansNIters + +```java +public Builder withKmeansNIters(int kmeansNIters) +``` + +Sets the number of iterations searching for kmeans centers (both VQ and PQ +phases). + +**Parameters** + +| Name | Description | +| --- | --- | +| `kmeansNIters` | | + +**Returns** + +an instance of Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraCompressionParams.java:192`_ + +### withVqKmeansTrainsetFraction + +```java +public Builder withVqKmeansTrainsetFraction(double vqKmeansTrainsetFraction) +``` + +Sets the fraction of data to use during iterative kmeans building (VQ phase). + +When zero, an optimal value is selected using a heuristic. + +**Parameters** + +| Name | Description | +| --- | --- | +| `vqKmeansTrainsetFraction` | | + +**Returns** + +an instance of Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraCompressionParams.java:205`_ + +### withPqKmeansTrainsetFraction + +```java +public Builder withPqKmeansTrainsetFraction(double pqKmeansTrainsetFraction) +``` + +Sets the fraction of data to use during iterative kmeans building (PQ phase). + +When zero, an optimal value is selected using a heuristic. + +**Parameters** + +| Name | Description | +| --- | --- | +| `pqKmeansTrainsetFraction` | | + +**Returns** + +an instance of Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraCompressionParams.java:218`_ + +### build + +```java +public CagraCompressionParams build() +``` + +Builds an instance of `CagraCompressionParams`. + +**Returns** + +an instance of `CagraCompressionParams` + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraCompressionParams.java:228`_ + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraCompressionParams.java:12`_ diff --git a/fern/pages/java_api/java-api-com-nvidia-cuvs-cagraindex.md b/fern/pages/java_api/java-api-com-nvidia-cuvs-cagraindex.md new file mode 100644 index 0000000000..5805278f99 --- /dev/null +++ b/fern/pages/java_api/java-api-com-nvidia-cuvs-cagraindex.md @@ -0,0 +1,409 @@ +--- +slug: api-reference/java-api-com-nvidia-cuvs-cagraindex +--- + +# CagraIndex + +_Java package: `com.nvidia.cuvs`_ + +```java +public interface CagraIndex extends AutoCloseable +``` + +`CagraIndex` encapsulates a CAGRA index, along with methods to interact +with it. + +CAGRA is a graph-based nearest neighbors algorithm that was built from the +ground up for GPU acceleration. CAGRA demonstrates state-of-the art index +build and query performance for both small and large-batch sized search. Know +more about this algorithm +here + +## Public Members + +### close + +```java +@Override void close() throws Exception +``` + +Invokes the native destroy_cagra_index to de-allocate the CAGRA index + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndex.java:29`_ + +### search + +```java +SearchResults search(CagraQuery query) throws Throwable +``` + +Invokes the native search_cagra_index via the Panama API for searching a +CAGRA index. + +**Parameters** + +| Name | Description | +| --- | --- | +| `query` | an instance of `CagraQuery` holding the query vectors and other parameters | + +**Returns** + +an instance of `SearchResults` containing the results + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndex.java:40`_ + +### getGraph + +```java +CuVSDeviceMatrix getGraph() +``` + +Returns the CAGRA graph + +**Returns** + +a `CuVSDeviceMatrix` encapsulating the native int (uint32_t) array used to represent the cagra graph + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndex.java:47`_ + +### serialize + +```java +void serialize(OutputStream outputStream) throws Throwable +``` + +A method to persist a CAGRA index using an instance of `OutputStream` +for writing index bytes. + +**Parameters** + +| Name | Description | +| --- | --- | +| `outputStream` | an instance of `OutputStream` to write the index bytes into | + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndex.java:56`_ + +### serialize + +```java +void serialize(OutputStream outputStream, int bufferLength) throws Throwable +``` + +A method to persist a CAGRA index using an instance of `OutputStream` +for writing index bytes. + +**Parameters** + +| Name | Description | +| --- | --- | +| `outputStream` | an instance of `OutputStream` to write the index bytes into | +| `bufferLength` | the length of buffer to use for writing bytes. Default value is 1024 | + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndex.java:67`_ + +### serialize + +```java +default void serialize(OutputStream outputStream, Path tempFile) throws Throwable +``` + +A method to persist a CAGRA index using an instance of `OutputStream` +for writing index bytes. + +**Parameters** + +| Name | Description | +| --- | --- | +| `outputStream` | an instance of `OutputStream` to write the index bytes into | +| `tempFile` | an intermediate `Path` where CAGRA index is written temporarily | + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndex.java:78`_ + +### serialize + +```java +void serialize(OutputStream outputStream, Path tempFile, int bufferLength) throws Throwable +``` + +A method to persist a CAGRA index using an instance of `OutputStream` +and path to the intermediate temporary file. + +**Parameters** + +| Name | Description | +| --- | --- | +| `outputStream` | an instance of `OutputStream` to write the index bytes to | +| `tempFile` | an intermediate `Path` where CAGRA index is written temporarily | +| `bufferLength` | the length of buffer to use for writing bytes. Default value is 1024 | + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndex.java:93`_ + +### serializeToHNSW + +```java +void serializeToHNSW(OutputStream outputStream) throws Throwable +``` + +A method to create and persist HNSW index from CAGRA index using an instance +of `OutputStream` and path to the intermediate temporary file. + +**Parameters** + +| Name | Description | +| --- | --- | +| `outputStream` | an instance of `OutputStream` to write the index bytes to | + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndex.java:102`_ + +### serializeToHNSW + +```java +void serializeToHNSW(OutputStream outputStream, int bufferLength) throws Throwable +``` + +A method to create and persist HNSW index from CAGRA index using an instance +of `OutputStream` and path to the intermediate temporary file. + +**Parameters** + +| Name | Description | +| --- | --- | +| `outputStream` | an instance of `OutputStream` to write the index bytes to | +| `bufferLength` | the length of buffer to use for writing bytes. Default value is 1024 | + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndex.java:113`_ + +### serializeToHNSW + +```java +default void serializeToHNSW(OutputStream outputStream, Path tempFile) throws Throwable +``` + +A method to create and persist HNSW index from CAGRA index using an instance +of `OutputStream` and path to the intermediate temporary file. + +**Parameters** + +| Name | Description | +| --- | --- | +| `outputStream` | an instance of `OutputStream` to write the index bytes to | +| `tempFile` | an intermediate `Path` where CAGRA index is written temporarily | + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndex.java:124`_ + +### serializeToHNSW + +```java +void serializeToHNSW(OutputStream outputStream, Path tempFile, int bufferLength) throws Throwable +``` + +A method to create and persist HNSW index from CAGRA index using an instance +of `OutputStream` and path to the intermediate temporary file. + +**Parameters** + +| Name | Description | +| --- | --- | +| `outputStream` | an instance of `OutputStream` to write the index bytes to | +| `tempFile` | an intermediate `Path` where CAGRA index is written temporarily | +| `bufferLength` | the length of buffer to use for writing bytes. Default value is 1024 | + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndex.java:139`_ + +### getCuVSResources + +```java +CuVSResources getCuVSResources() +``` + +Gets an instance of `CuVSResources` + +**Returns** + +an instance of `CuVSResources` + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndex.java:146`_ + +### newBuilder + +```java +static Builder newBuilder(CuVSResources cuvsResources) +``` + +Creates a new Builder with an instance of `CuVSResources`. + +**Parameters** + +| Name | Description | +| --- | --- | +| `cuvsResources` | an instance of `CuVSResources` | + +**Throws** + +| Type | Description | +| --- | --- | +| `UnsupportedOperationException` | if the provider does not cuvs | + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndex.java:154`_ + +### merge + +```java +static CagraIndex merge(CagraIndex[] indexes) throws Throwable +``` + +Merges multiple CAGRA indexes into a single index using default merge parameters. + +**Parameters** + +| Name | Description | +| --- | --- | +| `indexes` | Array of CAGRA indexes to merge | + +**Returns** + +A new merged CAGRA index + +**Throws** + +| Type | Description | +| --- | --- | +| `Throwable` | if an error occurs during the merge operation | + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndex.java:166`_ + +### merge + +```java +static CagraIndex merge(CagraIndex[] indexes, CagraIndexParams mergeParams) throws Throwable +``` + +Merges multiple CAGRA indexes into a single index with the specified merge parameters. + +**Parameters** + +| Name | Description | +| --- | --- | +| `indexes` | Array of CAGRA indexes to merge | +| `mergeParams` | Parameters to control the merge operation, or null to use defaults | + +**Returns** + +A new merged CAGRA index + +**Throws** + +| Type | Description | +| --- | --- | +| `Throwable` | if an error occurs during the merge operation | + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndex.java:178`_ + +### from + +```java +Builder from(InputStream inputStream) +``` + +Sets an instance of InputStream typically used when index deserialization is +needed. + +**Parameters** + +| Name | Description | +| --- | --- | +| `inputStream` | an instance of `InputStream` | + +**Returns** + +an instance of this Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndex.java:205`_ + +### from + +```java +Builder from(CuVSMatrix graph) +``` + +Sets a CAGRA graph instance to re-create an index from a +previously built graph. + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndex.java:211`_ + +### withDataset + +```java +Builder withDataset(float[][] vectors) +``` + +Sets the dataset vectors for building the `CagraIndex`. + +**Parameters** + +| Name | Description | +| --- | --- | +| `vectors` | a two-dimensional float array | + +**Returns** + +an instance of this Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndex.java:219`_ + +### withDataset + +```java +Builder withDataset(CuVSMatrix dataset) +``` + +Sets the dataset for building the `CagraIndex`. + +**Parameters** + +| Name | Description | +| --- | --- | +| `dataset` | a `CuVSMatrix` object containing the vectors | + +**Returns** + +an instance of this Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndex.java:227`_ + +### withIndexParams + +```java +Builder withIndexParams(CagraIndexParams cagraIndexParameters) +``` + +Registers an instance of configured `CagraIndexParams` with this +Builder. + +**Parameters** + +| Name | Description | +| --- | --- | +| `cagraIndexParameters` | An instance of CagraIndexParams. | + +**Returns** + +An instance of this Builder. + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndex.java:236`_ + +### build + +```java +CagraIndex build() throws Throwable +``` + +Builds and returns an instance of CagraIndex. + +**Returns** + +an instance of CagraIndex + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndex.java:243`_ + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndex.java:25`_ diff --git a/fern/pages/java_api/java-api-com-nvidia-cuvs-cagraindexparams.md b/fern/pages/java_api/java-api-com-nvidia-cuvs-cagraindexparams.md new file mode 100644 index 0000000000..81d0c922d1 --- /dev/null +++ b/fern/pages/java_api/java-api-com-nvidia-cuvs-cagraindexparams.md @@ -0,0 +1,608 @@ +--- +slug: api-reference/java-api-com-nvidia-cuvs-cagraindexparams +--- + +# CagraIndexParams + +_Java package: `com.nvidia.cuvs`_ + +```java +public class CagraIndexParams +``` + +Supplemental parameters to build CAGRA Index. + +## Public Members + +### AUTO_SELECT + +```java +AUTO_SELECT(0), /** * Use IVF-PQ to build all-neighbors knn graph */ IVF_PQ(1), /** * Experimental, use NN-Descent to build all-neighbors knn graph */ NN_DESCENT(2), /** * Experimental, use ACE (Augmented Core Extraction) to build graph for large datasets. * 4 to be consistent with the other interfaces. */ ACE(4) +``` + +Select build algorithm automatically + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndexParams.java:36`_ + +### IVF_PQ + +```java +IVF_PQ(1), /** * Experimental, use NN-Descent to build all-neighbors knn graph */ NN_DESCENT(2), /** * Experimental, use ACE (Augmented Core Extraction) to build graph for large datasets. * 4 to be consistent with the other interfaces. */ ACE(4) +``` + +Use IVF-PQ to build all-neighbors knn graph + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndexParams.java:40`_ + +### NN_DESCENT + +```java +NN_DESCENT(2), /** * Experimental, use ACE (Augmented Core Extraction) to build graph for large datasets. * 4 to be consistent with the other interfaces. */ ACE(4) +``` + +Experimental, use NN-Descent to build all-neighbors knn graph + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndexParams.java:44`_ + +### ACE + +```java +ACE(4) +``` + +Experimental, use ACE (Augmented Core Extraction) to build graph for large datasets. +4 to be consistent with the other interfaces. + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndexParams.java:49`_ + +### SIMILAR_SEARCH_PERFORMANCE + +```java +SIMILAR_SEARCH_PERFORMANCE(0), /** * Create a graph that has the same binary size as an HNSW graph with the given parameters * (graph_degree = 2 * M) while trying to match the search performance as closely as possible. * * The reference HNSW index and the corresponding from-CAGRA generated HNSW index will NOT produce * the same recalls and QPS for the same parameter ef. The graphs are different internally. For * the same ef, the from-CAGRA index likely has a slightly higher recall and slightly lower QPS. * However, the Recall-QPS curves should be similar (i.e. the points are just shifted along the * curve). */ SAME_GRAPH_FOOTPRINT(1) +``` + +Create a graph that is very similar to an HNSW graph in +terms of the number of nodes and search performance. Since HNSW produces a variable-degree +graph (2M being the max graph degree) and CAGRA produces a fixed-degree graph, there's always a +difference in the performance of the two. + +This function attempts to produce such a graph that the QPS and recall of the two graphs being +searched by HNSW are close for any search parameter combination. The CAGRA-produced graph tends +to have a "longer tail" on the low recall side (that is being slightly faster and less +precise). + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndexParams.java:85`_ + +### SAME_GRAPH_FOOTPRINT + +```java +SAME_GRAPH_FOOTPRINT(1) +``` + +Create a graph that has the same binary size as an HNSW graph with the given parameters +(graph_degree = 2 * M) while trying to match the search performance as closely as possible. + +The reference HNSW index and the corresponding from-CAGRA generated HNSW index will NOT produce +the same recalls and QPS for the same parameter ef. The graphs are different internally. For +the same ef, the from-CAGRA index likely has a slightly higher recall and slightly lower QPS. +However, the Recall-QPS curves should be similar (i.e. the points are just shifted along the +curve). + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndexParams.java:96`_ + +### L2Expanded + +```java +L2Expanded(0), /** * same as above, but inside the epilogue, perform square root operation */ L2SqrtExpanded(1), /** * cosine distance */ CosineExpanded(2), /** * L1 distance * */ L1(3), /** * evaluate as dist_ij += (x_ik - y-jk)^2 * */ L2Unexpanded(4), /** * same as above, but inside the epilogue, perform square root operation */ L2SqrtUnexpanded(5), /** * basic inner product */ InnerProduct(6), /** * Chebyshev (Linf) distance */ Linf(7), /** * Canberra distance */ Canberra(8), /** * Generalized Minkowski distance */ LpUnexpanded(9), /** * Correlation distance */ CorrelationExpanded(10), /** * Jaccard distance */ JaccardExpanded(11), /** * Hellinger distance */ HellingerExpanded(12), /** * Haversine distance */ Haversine(13), /** * Bray-Curtis distance */ BrayCurtis(14), /** * Jensen-Shannon distance */ JensenShannon(15), /** * Hamming distance */ HammingUnexpanded(16), /** * KLDivergence */ KLDivergence(17), /** * RusselRao */ RusselRaoExpanded(18), /** * Dice-Sorensen distance */ DiceExpanded(19), /** * Precomputed (special value) */ Precomputed(100) +``` + +evaluate as dist_ij = sum(x_ik^2) + sum(y_ij)^2 - 2*sum(x_ik * y_jk) + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndexParams.java:124`_ + +### L2SqrtExpanded + +```java +L2SqrtExpanded(1), /** * cosine distance */ CosineExpanded(2), /** * L1 distance * */ L1(3), /** * evaluate as dist_ij += (x_ik - y-jk)^2 * */ L2Unexpanded(4), /** * same as above, but inside the epilogue, perform square root operation */ L2SqrtUnexpanded(5), /** * basic inner product */ InnerProduct(6), /** * Chebyshev (Linf) distance */ Linf(7), /** * Canberra distance */ Canberra(8), /** * Generalized Minkowski distance */ LpUnexpanded(9), /** * Correlation distance */ CorrelationExpanded(10), /** * Jaccard distance */ JaccardExpanded(11), /** * Hellinger distance */ HellingerExpanded(12), /** * Haversine distance */ Haversine(13), /** * Bray-Curtis distance */ BrayCurtis(14), /** * Jensen-Shannon distance */ JensenShannon(15), /** * Hamming distance */ HammingUnexpanded(16), /** * KLDivergence */ KLDivergence(17), /** * RusselRao */ RusselRaoExpanded(18), /** * Dice-Sorensen distance */ DiceExpanded(19), /** * Precomputed (special value) */ Precomputed(100) +``` + +same as above, but inside the epilogue, perform square root operation + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndexParams.java:128`_ + +### CosineExpanded + +```java +CosineExpanded(2), /** * L1 distance * */ L1(3), /** * evaluate as dist_ij += (x_ik - y-jk)^2 * */ L2Unexpanded(4), /** * same as above, but inside the epilogue, perform square root operation */ L2SqrtUnexpanded(5), /** * basic inner product */ InnerProduct(6), /** * Chebyshev (Linf) distance */ Linf(7), /** * Canberra distance */ Canberra(8), /** * Generalized Minkowski distance */ LpUnexpanded(9), /** * Correlation distance */ CorrelationExpanded(10), /** * Jaccard distance */ JaccardExpanded(11), /** * Hellinger distance */ HellingerExpanded(12), /** * Haversine distance */ Haversine(13), /** * Bray-Curtis distance */ BrayCurtis(14), /** * Jensen-Shannon distance */ JensenShannon(15), /** * Hamming distance */ HammingUnexpanded(16), /** * KLDivergence */ KLDivergence(17), /** * RusselRao */ RusselRaoExpanded(18), /** * Dice-Sorensen distance */ DiceExpanded(19), /** * Precomputed (special value) */ Precomputed(100) +``` + +cosine distance + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndexParams.java:132`_ + +### L1 + +```java +L1(3), /** * evaluate as dist_ij += (x_ik - y-jk)^2 * */ L2Unexpanded(4), /** * same as above, but inside the epilogue, perform square root operation */ L2SqrtUnexpanded(5), /** * basic inner product */ InnerProduct(6), /** * Chebyshev (Linf) distance */ Linf(7), /** * Canberra distance */ Canberra(8), /** * Generalized Minkowski distance */ LpUnexpanded(9), /** * Correlation distance */ CorrelationExpanded(10), /** * Jaccard distance */ JaccardExpanded(11), /** * Hellinger distance */ HellingerExpanded(12), /** * Haversine distance */ Haversine(13), /** * Bray-Curtis distance */ BrayCurtis(14), /** * Jensen-Shannon distance */ JensenShannon(15), /** * Hamming distance */ HammingUnexpanded(16), /** * KLDivergence */ KLDivergence(17), /** * RusselRao */ RusselRaoExpanded(18), /** * Dice-Sorensen distance */ DiceExpanded(19), /** * Precomputed (special value) */ Precomputed(100) +``` + +L1 distance * + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndexParams.java:136`_ + +### L2Unexpanded + +```java +L2Unexpanded(4), /** * same as above, but inside the epilogue, perform square root operation */ L2SqrtUnexpanded(5), /** * basic inner product */ InnerProduct(6), /** * Chebyshev (Linf) distance */ Linf(7), /** * Canberra distance */ Canberra(8), /** * Generalized Minkowski distance */ LpUnexpanded(9), /** * Correlation distance */ CorrelationExpanded(10), /** * Jaccard distance */ JaccardExpanded(11), /** * Hellinger distance */ HellingerExpanded(12), /** * Haversine distance */ Haversine(13), /** * Bray-Curtis distance */ BrayCurtis(14), /** * Jensen-Shannon distance */ JensenShannon(15), /** * Hamming distance */ HammingUnexpanded(16), /** * KLDivergence */ KLDivergence(17), /** * RusselRao */ RusselRaoExpanded(18), /** * Dice-Sorensen distance */ DiceExpanded(19), /** * Precomputed (special value) */ Precomputed(100) +``` + +evaluate as dist_ij += (x_ik - y-jk)^2 * + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndexParams.java:140`_ + +### L2SqrtUnexpanded + +```java +L2SqrtUnexpanded(5), /** * basic inner product */ InnerProduct(6), /** * Chebyshev (Linf) distance */ Linf(7), /** * Canberra distance */ Canberra(8), /** * Generalized Minkowski distance */ LpUnexpanded(9), /** * Correlation distance */ CorrelationExpanded(10), /** * Jaccard distance */ JaccardExpanded(11), /** * Hellinger distance */ HellingerExpanded(12), /** * Haversine distance */ Haversine(13), /** * Bray-Curtis distance */ BrayCurtis(14), /** * Jensen-Shannon distance */ JensenShannon(15), /** * Hamming distance */ HammingUnexpanded(16), /** * KLDivergence */ KLDivergence(17), /** * RusselRao */ RusselRaoExpanded(18), /** * Dice-Sorensen distance */ DiceExpanded(19), /** * Precomputed (special value) */ Precomputed(100) +``` + +same as above, but inside the epilogue, perform square root operation + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndexParams.java:144`_ + +### InnerProduct + +```java +InnerProduct(6), /** * Chebyshev (Linf) distance */ Linf(7), /** * Canberra distance */ Canberra(8), /** * Generalized Minkowski distance */ LpUnexpanded(9), /** * Correlation distance */ CorrelationExpanded(10), /** * Jaccard distance */ JaccardExpanded(11), /** * Hellinger distance */ HellingerExpanded(12), /** * Haversine distance */ Haversine(13), /** * Bray-Curtis distance */ BrayCurtis(14), /** * Jensen-Shannon distance */ JensenShannon(15), /** * Hamming distance */ HammingUnexpanded(16), /** * KLDivergence */ KLDivergence(17), /** * RusselRao */ RusselRaoExpanded(18), /** * Dice-Sorensen distance */ DiceExpanded(19), /** * Precomputed (special value) */ Precomputed(100) +``` + +basic inner product + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndexParams.java:148`_ + +### Linf + +```java +Linf(7), /** * Canberra distance */ Canberra(8), /** * Generalized Minkowski distance */ LpUnexpanded(9), /** * Correlation distance */ CorrelationExpanded(10), /** * Jaccard distance */ JaccardExpanded(11), /** * Hellinger distance */ HellingerExpanded(12), /** * Haversine distance */ Haversine(13), /** * Bray-Curtis distance */ BrayCurtis(14), /** * Jensen-Shannon distance */ JensenShannon(15), /** * Hamming distance */ HammingUnexpanded(16), /** * KLDivergence */ KLDivergence(17), /** * RusselRao */ RusselRaoExpanded(18), /** * Dice-Sorensen distance */ DiceExpanded(19), /** * Precomputed (special value) */ Precomputed(100) +``` + +Chebyshev (Linf) distance + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndexParams.java:152`_ + +### Canberra + +```java +Canberra(8), /** * Generalized Minkowski distance */ LpUnexpanded(9), /** * Correlation distance */ CorrelationExpanded(10), /** * Jaccard distance */ JaccardExpanded(11), /** * Hellinger distance */ HellingerExpanded(12), /** * Haversine distance */ Haversine(13), /** * Bray-Curtis distance */ BrayCurtis(14), /** * Jensen-Shannon distance */ JensenShannon(15), /** * Hamming distance */ HammingUnexpanded(16), /** * KLDivergence */ KLDivergence(17), /** * RusselRao */ RusselRaoExpanded(18), /** * Dice-Sorensen distance */ DiceExpanded(19), /** * Precomputed (special value) */ Precomputed(100) +``` + +Canberra distance + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndexParams.java:156`_ + +### LpUnexpanded + +```java +LpUnexpanded(9), /** * Correlation distance */ CorrelationExpanded(10), /** * Jaccard distance */ JaccardExpanded(11), /** * Hellinger distance */ HellingerExpanded(12), /** * Haversine distance */ Haversine(13), /** * Bray-Curtis distance */ BrayCurtis(14), /** * Jensen-Shannon distance */ JensenShannon(15), /** * Hamming distance */ HammingUnexpanded(16), /** * KLDivergence */ KLDivergence(17), /** * RusselRao */ RusselRaoExpanded(18), /** * Dice-Sorensen distance */ DiceExpanded(19), /** * Precomputed (special value) */ Precomputed(100) +``` + +Generalized Minkowski distance + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndexParams.java:160`_ + +### CorrelationExpanded + +```java +CorrelationExpanded(10), /** * Jaccard distance */ JaccardExpanded(11), /** * Hellinger distance */ HellingerExpanded(12), /** * Haversine distance */ Haversine(13), /** * Bray-Curtis distance */ BrayCurtis(14), /** * Jensen-Shannon distance */ JensenShannon(15), /** * Hamming distance */ HammingUnexpanded(16), /** * KLDivergence */ KLDivergence(17), /** * RusselRao */ RusselRaoExpanded(18), /** * Dice-Sorensen distance */ DiceExpanded(19), /** * Precomputed (special value) */ Precomputed(100) +``` + +Correlation distance + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndexParams.java:164`_ + +### JaccardExpanded + +```java +JaccardExpanded(11), /** * Hellinger distance */ HellingerExpanded(12), /** * Haversine distance */ Haversine(13), /** * Bray-Curtis distance */ BrayCurtis(14), /** * Jensen-Shannon distance */ JensenShannon(15), /** * Hamming distance */ HammingUnexpanded(16), /** * KLDivergence */ KLDivergence(17), /** * RusselRao */ RusselRaoExpanded(18), /** * Dice-Sorensen distance */ DiceExpanded(19), /** * Precomputed (special value) */ Precomputed(100) +``` + +Jaccard distance + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndexParams.java:168`_ + +### HellingerExpanded + +```java +HellingerExpanded(12), /** * Haversine distance */ Haversine(13), /** * Bray-Curtis distance */ BrayCurtis(14), /** * Jensen-Shannon distance */ JensenShannon(15), /** * Hamming distance */ HammingUnexpanded(16), /** * KLDivergence */ KLDivergence(17), /** * RusselRao */ RusselRaoExpanded(18), /** * Dice-Sorensen distance */ DiceExpanded(19), /** * Precomputed (special value) */ Precomputed(100) +``` + +Hellinger distance + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndexParams.java:172`_ + +### Haversine + +```java +Haversine(13), /** * Bray-Curtis distance */ BrayCurtis(14), /** * Jensen-Shannon distance */ JensenShannon(15), /** * Hamming distance */ HammingUnexpanded(16), /** * KLDivergence */ KLDivergence(17), /** * RusselRao */ RusselRaoExpanded(18), /** * Dice-Sorensen distance */ DiceExpanded(19), /** * Precomputed (special value) */ Precomputed(100) +``` + +Haversine distance + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndexParams.java:176`_ + +### BrayCurtis + +```java +BrayCurtis(14), /** * Jensen-Shannon distance */ JensenShannon(15), /** * Hamming distance */ HammingUnexpanded(16), /** * KLDivergence */ KLDivergence(17), /** * RusselRao */ RusselRaoExpanded(18), /** * Dice-Sorensen distance */ DiceExpanded(19), /** * Precomputed (special value) */ Precomputed(100) +``` + +Bray-Curtis distance + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndexParams.java:180`_ + +### JensenShannon + +```java +JensenShannon(15), /** * Hamming distance */ HammingUnexpanded(16), /** * KLDivergence */ KLDivergence(17), /** * RusselRao */ RusselRaoExpanded(18), /** * Dice-Sorensen distance */ DiceExpanded(19), /** * Precomputed (special value) */ Precomputed(100) +``` + +Jensen-Shannon distance + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndexParams.java:184`_ + +### HammingUnexpanded + +```java +HammingUnexpanded(16), /** * KLDivergence */ KLDivergence(17), /** * RusselRao */ RusselRaoExpanded(18), /** * Dice-Sorensen distance */ DiceExpanded(19), /** * Precomputed (special value) */ Precomputed(100) +``` + +Hamming distance + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndexParams.java:188`_ + +### KLDivergence + +```java +KLDivergence(17), /** * RusselRao */ RusselRaoExpanded(18), /** * Dice-Sorensen distance */ DiceExpanded(19), /** * Precomputed (special value) */ Precomputed(100) +``` + +KLDivergence + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndexParams.java:192`_ + +### RusselRaoExpanded + +```java +RusselRaoExpanded(18), /** * Dice-Sorensen distance */ DiceExpanded(19), /** * Precomputed (special value) */ Precomputed(100) +``` + +RusselRao + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndexParams.java:196`_ + +### DiceExpanded + +```java +DiceExpanded(19), /** * Precomputed (special value) */ Precomputed(100) +``` + +Dice-Sorensen distance + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndexParams.java:200`_ + +### Precomputed + +```java +Precomputed(100) +``` + +Precomputed (special value) + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndexParams.java:204`_ + +### getIntermediateGraphDegree + +```java +public long getIntermediateGraphDegree() +``` + +Gets the degree of input graph for pruning. + +**Returns** + +the degree of input graph + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndexParams.java:366`_ + +### getGraphDegree + +```java +public long getGraphDegree() +``` + +Gets the degree of output graph. + +**Returns** + +the degree of output graph + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndexParams.java:375`_ + +### getCagraGraphBuildAlgo + +```java +public CagraGraphBuildAlgo getCagraGraphBuildAlgo() +``` + +Gets the `CagraGraphBuildAlgo` used to build the index. + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndexParams.java:382`_ + +### getNNDescentNumIterations + +```java +public long getNNDescentNumIterations() +``` + +Gets the number of iterations to run if building with +`CagraGraphBuildAlgo#NN_DESCENT` + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndexParams.java:390`_ + +### getCuvsDistanceType + +```java +public CuvsDistanceType getCuvsDistanceType() +``` + +Gets the `CuvsDistanceType` used to build the index. + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndexParams.java:397`_ + +### getNumWriterThreads + +```java +public int getNumWriterThreads() +``` + +Gets the number of threads used to build the index. + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndexParams.java:404`_ + +### getCuVSIvfPqParams + +```java +public CuVSIvfPqParams getCuVSIvfPqParams() +``` + +Gets the IVF_PQ parameters. + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndexParams.java:411`_ + +### getCuVSAceParams + +```java +public CuVSAceParams getCuVSAceParams() +``` + +Gets the ACE parameters. + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndexParams.java:418`_ + +### getCuvsCagraGraphBuildAlgo + +```java +public CagraGraphBuildAlgo getCuvsCagraGraphBuildAlgo() +``` + +Gets the CAGRA build algorithm. + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndexParams.java:425`_ + +### getCagraCompressionParams + +```java +public CagraCompressionParams getCagraCompressionParams() +``` + +Gets the CAGRA compression parameters. + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndexParams.java:432`_ + +### withIntermediateGraphDegree + +```java +public Builder withIntermediateGraphDegree(long intermediateGraphDegree) +``` + +Sets the degree of input graph for pruning. + +**Parameters** + +| Name | Description | +| --- | --- | +| `intermediateGraphDegree` | degree of input graph for pruning | + +**Returns** + +an instance of Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndexParams.java:482`_ + +### withGraphDegree + +```java +public Builder withGraphDegree(long graphDegree) +``` + +Sets the degree of output graph. + +**Parameters** + +| Name | Description | +| --- | --- | +| `graphDegree` | degree of output graph | + +**Returns** + +an instance to Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndexParams.java:493`_ + +### withCagraGraphBuildAlgo + +```java +public Builder withCagraGraphBuildAlgo(CagraGraphBuildAlgo cuvsCagraGraphBuildAlgo) +``` + +Sets the CuvsCagraGraphBuildAlgo to use. + +**Parameters** + +| Name | Description | +| --- | --- | +| `cuvsCagraGraphBuildAlgo` | the CuvsCagraGraphBuildAlgo to use | + +**Returns** + +an instance of Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndexParams.java:504`_ + +### withMetric + +```java +public Builder withMetric(CuvsDistanceType cuvsDistanceType) +``` + +Sets the metric to use. + +**Parameters** + +| Name | Description | +| --- | --- | +| `cuvsDistanceType` | the `CuvsDistanceType` to use | + +**Returns** + +an instance of Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndexParams.java:515`_ + +### withNNDescentNumIterations + +```java +public Builder withNNDescentNumIterations(long nnDescentNiter) +``` + +Sets the Number of Iterations to run if building with +`CagraGraphBuildAlgo#NN_DESCENT`. + +**Parameters** + +| Name | Description | +| --- | --- | +| `nnDescentNiter` | number of Iterations to run if building with `CagraGraphBuildAlgo#NN_DESCENT` | + +**Returns** + +an instance of Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndexParams.java:528`_ + +### withNumWriterThreads + +```java +public Builder withNumWriterThreads(int numWriterThreads) +``` + +Sets the number of writer threads to use for indexing. + +**Parameters** + +| Name | Description | +| --- | --- | +| `numWriterThreads` | number of writer threads to use | + +**Returns** + +an instance of Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndexParams.java:539`_ + +### withCuVSIvfPqParams + +```java +public Builder withCuVSIvfPqParams(CuVSIvfPqParams cuVSIvfPqParams) +``` + +Sets the IVF_PQ index parameters. + +**Parameters** + +| Name | Description | +| --- | --- | +| `cuVSIvfPqParams` | the IVF_PQ index parameters | + +**Returns** + +an instance of Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndexParams.java:550`_ + +### withCuVSAceParams + +```java +public Builder withCuVSAceParams(CuVSAceParams cuVSAceParams) +``` + +Sets the ACE index parameters. + +**Parameters** + +| Name | Description | +| --- | --- | +| `cuVSAceParams` | the ACE index parameters | + +**Returns** + +an instance of Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndexParams.java:561`_ + +### withCompressionParams + +```java +public Builder withCompressionParams(CagraCompressionParams cagraCompressionParams) +``` + +Registers an instance of configured `CagraCompressionParams` with this +Builder. + +**Parameters** + +| Name | Description | +| --- | --- | +| `cagraCompressionParams` | An instance of CagraCompressionParams. | + +**Returns** + +An instance of this Builder. + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndexParams.java:573`_ + +### build + +```java +public CagraIndexParams build() +``` + +Builds an instance of `CagraIndexParams`. + +**Returns** + +an instance of `CagraIndexParams` + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndexParams.java:583`_ + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraIndexParams.java:18`_ diff --git a/fern/pages/java_api/java-api-com-nvidia-cuvs-cagramergeparams.md b/fern/pages/java_api/java-api-com-nvidia-cuvs-cagramergeparams.md new file mode 100644 index 0000000000..2fae4815d6 --- /dev/null +++ b/fern/pages/java_api/java-api-com-nvidia-cuvs-cagramergeparams.md @@ -0,0 +1,114 @@ +--- +slug: api-reference/java-api-com-nvidia-cuvs-cagramergeparams +--- + +# CagraMergeParams + +_Java package: `com.nvidia.cuvs`_ + +```java +public class CagraMergeParams +``` + +## Public Members + +### CagraMergeParams + +```java +private CagraMergeParams(CagraIndexParams outputIndexParams, MergeStrategy strategy) +``` + +Constructs a CagraMergeParams with the given output index parameters and merge strategy. + +**Parameters** + +| Name | Description | +| --- | --- | +| `outputIndexParams` | Index parameters for the output index | +| `strategy` | Merge strategy to use | + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraMergeParams.java:17`_ + +### getOutputIndexParams + +```java +public CagraIndexParams getOutputIndexParams() +``` + +Gets the index parameters for the output index. + +**Returns** + +Index parameters to use for the output index + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraMergeParams.java:27`_ + +### getStrategy + +```java +public MergeStrategy getStrategy() +``` + +Gets the merge strategy to use. + +**Returns** + +The merge strategy + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraMergeParams.java:36`_ + +### withOutputIndexParams + +```java +public Builder withOutputIndexParams(CagraIndexParams outputIndexParams) +``` + +Sets the index parameters for the output index. + +**Parameters** + +| Name | Description | +| --- | --- | +| `outputIndexParams` | Index parameters to use for the output index | + +**Returns** + +This builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraMergeParams.java:68`_ + +### withStrategy + +```java +public Builder withStrategy(MergeStrategy strategy) +``` + +Sets the merge strategy. + +**Parameters** + +| Name | Description | +| --- | --- | +| `strategy` | The merge strategy to use | + +**Returns** + +This builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraMergeParams.java:79`_ + +### build + +```java +public CagraMergeParams build() +``` + +Builds the `CagraMergeParams` object. + +**Returns** + +The built parameters + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraMergeParams.java:89`_ + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraMergeParams.java:7`_ diff --git a/fern/pages/java_api/java-api-com-nvidia-cuvs-cagraquery.md b/fern/pages/java_api/java-api-com-nvidia-cuvs-cagraquery.md new file mode 100644 index 0000000000..ca4b6b0760 --- /dev/null +++ b/fern/pages/java_api/java-api-com-nvidia-cuvs-cagraquery.md @@ -0,0 +1,273 @@ +--- +slug: api-reference/java-api-com-nvidia-cuvs-cagraquery +--- + +# CagraQuery + +_Java package: `com.nvidia.cuvs`_ + +```java +public class CagraQuery +``` + +CagraQuery holds the CagraSearchParams and the query vectors to be used while +invoking search. + +Thread Safety: Each CagraQuery instance should use its own +CuVSResources object that is not shared with other threads. Sharing CuVSResources +between threads can lead to memory allocation errors or JVM crashes. + +## Public Members + +### CagraQuery + +```java +private CagraQuery( CagraSearchParams cagraSearchParameters, CuVSMatrix queryVectors, LongToIntFunction mapping, int topK, BitSet prefilter, int numDocs, CuVSResources resources) +``` + +Constructs an instance of `CagraQuery` using cagraSearchParameters, +preFilter, queryVectors, mapping, and topK. + +**Parameters** + +| Name | Description | +| --- | --- | +| `cagraSearchParameters` | an instance of `CagraSearchParams` holding the search parameters | +| `queryVectors` | 2D float query vector array | +| `mapping` | a function mapping ordinals (neighbor IDs) to custom user IDs | +| `topK` | the top k results to return | +| `prefilter` | A single BitSet to use as filter while searching the CAGRA index | +| `numDocs` | Total number of dataset vectors; used to align the prefilter correctly | +| `resources` | CuVSResources instance to use for this query | + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraQuery.java:43`_ + +### getCagraSearchParameters + +```java +public CagraSearchParams getCagraSearchParameters() +``` + +Gets the instance of CagraSearchParams initially set. + +**Returns** + +an instance CagraSearchParams + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraQuery.java:66`_ + +### getQueryVectors + +```java +public CuVSMatrix getQueryVectors() +``` + +Gets the query vector matrix. + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraQuery.java:73`_ + +### getMapping + +```java +public LongToIntFunction getMapping() +``` + +Gets the function mapping ordinals (neighbor IDs) to custom user IDs + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraQuery.java:80`_ + +### getTopK + +```java +public int getTopK() +``` + +Gets the topK value. + +**Returns** + +the topK value + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraQuery.java:89`_ + +### getPrefilter + +```java +public BitSet getPrefilter() +``` + +Gets the prefilter BitSet. + +**Returns** + +a BitSet object representing the prefilter + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraQuery.java:98`_ + +### getNumDocs + +```java +public int getNumDocs() +``` + +Gets the number of documents in this index, as used for prefilter + +**Returns** + +number of documents as an integer + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraQuery.java:107`_ + +### getResources + +```java +public CuVSResources getResources() +``` + +Gets the CuVSResources instance for this query. + +**Returns** + +the CuVSResources instance + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraQuery.java:116`_ + +### Builder + +```java +public Builder(CuVSResources resources) +``` + +Constructor that requires CuVSResources. + +Important: The provided CuVSResources instance should not be +shared with other threads. Each thread performing searches should create its own +CuVSResources instance to avoid memory allocation conflicts and potential JVM crashes. + +**Parameters** + +| Name | Description | +| --- | --- | +| `resources` | the CuVSResources instance to use for this query (must not be shared between threads) | + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraQuery.java:155`_ + +### withSearchParams + +```java +public Builder withSearchParams(CagraSearchParams cagraSearchParams) +``` + +Sets the instance of configured CagraSearchParams to be passed for search. + +**Parameters** + +| Name | Description | +| --- | --- | +| `cagraSearchParams` | an instance of the configured CagraSearchParams to be used for this query | + +**Returns** + +an instance of this Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraQuery.java:166`_ + +### withQueryVectors + +```java +public Builder withQueryVectors(CuVSMatrix queryVectors) +``` + +Registers the query vectors to be passed in the search call. + +**Parameters** + +| Name | Description | +| --- | --- | +| `queryVectors` | 2D query vector array | + +**Returns** + +an instance of this Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraQuery.java:177`_ + +### withMapping + +```java +public Builder withMapping(LongToIntFunction mapping) +``` + +Sets the function used to map ordinals (neighbor IDs) to custom user IDs + +**Parameters** + +| Name | Description | +| --- | --- | +| `mapping` | a function mapping ordinals (neighbor IDs) to custom user IDs | + +**Returns** + +an instance of this Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraQuery.java:188`_ + +### withTopK + +```java +public Builder withTopK(int topK) +``` + +Registers the topK value. + +**Parameters** + +| Name | Description | +| --- | --- | +| `topK` | the topK value used to retrieve the topK results | + +**Returns** + +an instance of this Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraQuery.java:199`_ + +### withPrefilter + +```java +public Builder withPrefilter(BitSet prefilter, int numDocs) +``` + +Sets a global prefilter for all queries in this `CagraQuery`. +The `prefilter` array must contain exactly one `BitSet`, +which is applied to all queries. A bit value of `1` includes the +corresponding dataset vector; `0` excludes it. + +**Parameters** + +| Name | Description | +| --- | --- | +| `prefilter` | an array with the global filter BitSet | +| `numDocs` | total number of vectors in the dataset (for alignment) | + +**Returns** + +this `Builder` instance + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraQuery.java:214`_ + +### build + +```java +public CagraQuery build() +``` + +Builds an instance of CuVSQuery. + +**Returns** + +an instance of CuVSQuery + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraQuery.java:225`_ + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraQuery.java:21`_ diff --git a/fern/pages/java_api/java-api-com-nvidia-cuvs-cagrasearchparams.md b/fern/pages/java_api/java-api-com-nvidia-cuvs-cagrasearchparams.md new file mode 100644 index 0000000000..8346f8dba2 --- /dev/null +++ b/fern/pages/java_api/java-api-com-nvidia-cuvs-cagrasearchparams.md @@ -0,0 +1,591 @@ +--- +slug: api-reference/java-api-com-nvidia-cuvs-cagrasearchparams +--- + +# CagraSearchParams + +_Java package: `com.nvidia.cuvs`_ + +```java +public class CagraSearchParams +``` + +CagraSearchParams encapsulates the logic for configuring and holding search +parameters. + +## Public Members + +### SINGLE_CTA + +```java +SINGLE_CTA(0), /** * for small batch sizes */ MULTI_CTA(1), /** * MULTI_KERNEL */ MULTI_KERNEL(2), /** * AUTO */ AUTO(100) +``` + +for large batch sizes + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraSearchParams.java:35`_ + +### MULTI_CTA + +```java +MULTI_CTA(1), /** * MULTI_KERNEL */ MULTI_KERNEL(2), /** * AUTO */ AUTO(100) +``` + +for small batch sizes + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraSearchParams.java:39`_ + +### MULTI_KERNEL + +```java +MULTI_KERNEL(2), /** * AUTO */ AUTO(100) +``` + +MULTI_KERNEL + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraSearchParams.java:43`_ + +### AUTO + +```java +AUTO(100) +``` + +AUTO + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraSearchParams.java:47`_ + +### HASH + +```java +HASH(0), /** * SMALL */ SMALL(1), /** * AUTO_HASH */ AUTO_HASH(100) +``` + +HASH + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraSearchParams.java:66`_ + +### SMALL + +```java +SMALL(1), /** * AUTO_HASH */ AUTO_HASH(100) +``` + +SMALL + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraSearchParams.java:70`_ + +### AUTO_HASH + +```java +AUTO_HASH(100) +``` + +AUTO_HASH + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraSearchParams.java:74`_ + +### CagraSearchParams + +```java +private CagraSearchParams( int maxQueries, int iTopKSize, int maxIterations, SearchAlgo searchAlgo, int teamSize, int searchWidth, int minIterations, int threadBlockSize, HashMapMode hashmapMode, int hashmapMinBitlen, float hashmapMaxFillRate, int numRandomSamplings, long randXORMask) +``` + +Constructs an instance of CagraSearchParams with passed search parameters. + +**Parameters** + +| Name | Description | +| --- | --- | +| `maxQueries` | the maximum number of queries to search at the same time (batch size) | +| `iTopKSize` | the number of intermediate search results retained during the search | +| `maxIterations` | the upper limit of search iterations | +| `searchAlgo` | the search implementation is configured | +| `teamSize` | the number of threads used to calculate a single distance | +| `searchWidth` | the number of graph nodes to select as the starting point for the search in each iteration | +| `minIterations` | the lower limit of search iterations | +| `threadBlockSize` | the thread block size | +| `hashmapMode` | the hash map type configured | +| `hashmapMinBitlen` | the lower limit of hash map bit length | +| `hashmapMaxFillRate` | the upper limit of hash map fill rate | +| `numRandomSamplings` | the number of iterations of initial random seed node selection | +| `randXORMask` | the bit mask used for initial random seed node selection | + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraSearchParams.java:109`_ + +### getMaxQueries + +```java +public int getMaxQueries() +``` + +Gets the maximum number of queries to search at the same time (batch size). + +**Returns** + +the maximum number of queries + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraSearchParams.java:143`_ + +### getITopKSize + +```java +public int getITopKSize() +``` + +Gets the number of intermediate search results retained during the search. + +**Returns** + +the number of intermediate search results + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraSearchParams.java:152`_ + +### getMaxIterations + +```java +public int getMaxIterations() +``` + +Gets the upper limit of search iterations. + +**Returns** + +the upper limit value + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraSearchParams.java:161`_ + +### getTeamSize + +```java +public int getTeamSize() +``` + +Gets the number of threads used to calculate a single distance. + +**Returns** + +the number of threads configured + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraSearchParams.java:170`_ + +### getSearchWidth + +```java +public int getSearchWidth() +``` + +Gets the number of graph nodes to select as the starting point for the search +in each iteration. + +**Returns** + +the number of graph nodes + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraSearchParams.java:180`_ + +### getMinIterations + +```java +public int getMinIterations() +``` + +Gets the lower limit of search iterations. + +**Returns** + +the lower limit value + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraSearchParams.java:189`_ + +### getThreadBlockSize + +```java +public int getThreadBlockSize() +``` + +Gets the thread block size. + +**Returns** + +the thread block size + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraSearchParams.java:198`_ + +### getHashmapMinBitlen + +```java +public int getHashmapMinBitlen() +``` + +Gets the lower limit of hash map bit length. + +**Returns** + +the lower limit value + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraSearchParams.java:207`_ + +### getNumRandomSamplings + +```java +public int getNumRandomSamplings() +``` + +Gets the number of iterations of initial random seed node selection. + +**Returns** + +the number of iterations + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraSearchParams.java:216`_ + +### getHashMapMaxFillRate + +```java +public float getHashMapMaxFillRate() +``` + +Gets the upper limit of hash map fill rate. + +**Returns** + +the upper limit of hash map fill rate + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraSearchParams.java:225`_ + +### getRandXORMask + +```java +public long getRandXORMask() +``` + +Gets the bit mask used for initial random seed node selection. + +**Returns** + +the bit mask value + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraSearchParams.java:234`_ + +### getCagraSearchAlgo + +```java +public SearchAlgo getCagraSearchAlgo() +``` + +Gets which search implementation is configured. + +**Returns** + +the configured `SearchAlgo` + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraSearchParams.java:243`_ + +### getHashMapMode + +```java +public HashMapMode getHashMapMode() +``` + +Gets the hash map mode configured. + +**Returns** + +the configured `HashMapMode` + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraSearchParams.java:252`_ + +### Builder + +```java +public Builder() +``` + +Default constructor. + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraSearchParams.java:309`_ + +### withMaxQueries + +```java +public Builder withMaxQueries(int maxQueries) +``` + +Sets the maximum number of queries to search at the same time (batch size). +Auto select when 0. + +**Parameters** + +| Name | Description | +| --- | --- | +| `maxQueries` | the maximum number of queries | + +**Returns** + +an instance of this Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraSearchParams.java:318`_ + +### withItopkSize + +```java +public Builder withItopkSize(int iTopKSize) +``` + +Sets the number of intermediate search results retained during the search. +This is the main knob to adjust trade off between accuracy and search speed. +Higher values improve the search accuracy. + +**Parameters** + +| Name | Description | +| --- | --- | +| `iTopKSize` | the number of intermediate search results | + +**Returns** + +an instance of this Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraSearchParams.java:331`_ + +### withMaxIterations + +```java +public Builder withMaxIterations(int maxIterations) +``` + +Sets the upper limit of search iterations. Auto select when 0. + +**Parameters** + +| Name | Description | +| --- | --- | +| `maxIterations` | the upper limit of search iterations | + +**Returns** + +an instance of this Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraSearchParams.java:342`_ + +### withAlgo + +```java +public Builder withAlgo(SearchAlgo cuvsCagraSearchAlgo) +``` + +Sets which search implementation to use. + +**Parameters** + +| Name | Description | +| --- | --- | +| `cuvsCagraSearchAlgo` | the `SearchAlgo` to use | + +**Returns** + +an instance of this Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraSearchParams.java:353`_ + +### withTeamSize + +```java +public Builder withTeamSize(int teamSize) +``` + +Sets the number of threads used to calculate a single distance. 4, 8, 16, or +32. + +**Parameters** + +| Name | Description | +| --- | --- | +| `teamSize` | the number of threads used to calculate a single distance | + +**Returns** + +an instance of this Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraSearchParams.java:365`_ + +### withSearchWidth + +```java +public Builder withSearchWidth(int searchWidth) +``` + +Sets the number of graph nodes to select as the starting point for the search +in each iteration. + +**Parameters** + +| Name | Description | +| --- | --- | +| `searchWidth` | the number of graph nodes to select | + +**Returns** + +an instance of this Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraSearchParams.java:377`_ + +### withMinIterations + +```java +public Builder withMinIterations(int minIterations) +``` + +Sets the lower limit of search iterations. + +**Parameters** + +| Name | Description | +| --- | --- | +| `minIterations` | the lower limit of search iterations | + +**Returns** + +an instance of this Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraSearchParams.java:388`_ + +### withThreadBlockSize + +```java +public Builder withThreadBlockSize(int threadBlockSize) +``` + +Sets the thread block size. 0, 64, 128, 256, 512, 1024. Auto selection when +0. + +**Parameters** + +| Name | Description | +| --- | --- | +| `threadBlockSize` | the thread block size | + +**Returns** + +an instance of this Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraSearchParams.java:400`_ + +### withHashMapMode + +```java +public Builder withHashMapMode(HashMapMode hashMapMode) +``` + +Sets the hash map type. Auto selection when AUTO. + +**Parameters** + +| Name | Description | +| --- | --- | +| `hashMapMode` | the `HashMapMode` | + +**Returns** + +an instance of this Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraSearchParams.java:411`_ + +### withHashMapMinBitlen + +```java +public Builder withHashMapMinBitlen(int hashMapMinBitlen) +``` + +Sets the lower limit of hash map bit length. More than 8. + +**Parameters** + +| Name | Description | +| --- | --- | +| `hashMapMinBitlen` | the lower limit of hash map bit length | + +**Returns** + +an instance of this Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraSearchParams.java:422`_ + +### withHashMapMaxFillRate + +```java +public Builder withHashMapMaxFillRate(float hashMapMaxFillRate) +``` + +Sets the upper limit of hash map fill rate. More than 0.1, less than 0.9. + +**Parameters** + +| Name | Description | +| --- | --- | +| `hashMapMaxFillRate` | the upper limit of hash map fill rate | + +**Returns** + +an instance of this Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraSearchParams.java:433`_ + +### withNumRandomSamplings + +```java +public Builder withNumRandomSamplings(int numRandomSamplings) +``` + +Sets the number of iterations of initial random seed node selection. 1 or +more. + +**Parameters** + +| Name | Description | +| --- | --- | +| `numRandomSamplings` | the number of iterations of initial random seed node selection | + +**Returns** + +an instance of this Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraSearchParams.java:446`_ + +### withRandXorMask + +```java +public Builder withRandXorMask(long randXORMask) +``` + +Sets the bit mask used for initial random seed node selection. + +**Parameters** + +| Name | Description | +| --- | --- | +| `randXORMask` | the bit mask used for initial random seed node selection | + +**Returns** + +an instance of this Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraSearchParams.java:457`_ + +### build + +```java +public CagraSearchParams build() +``` + +Builds an instance of `CagraSearchParams` with passed search +parameters. + +**Returns** + +an instance of CagraSearchParams + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraSearchParams.java:468`_ + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CagraSearchParams.java:13`_ diff --git a/fern/pages/java_api/java-api-com-nvidia-cuvs-cuvsaceparams.md b/fern/pages/java_api/java-api-com-nvidia-cuvs-cuvsaceparams.md new file mode 100644 index 0000000000..90d0f44bf9 --- /dev/null +++ b/fern/pages/java_api/java-api-com-nvidia-cuvs-cuvsaceparams.md @@ -0,0 +1,246 @@ +--- +slug: api-reference/java-api-com-nvidia-cuvs-cuvsaceparams +--- + +# CuVSAceParams + +_Java package: `com.nvidia.cuvs`_ + +```java +public class CuVSAceParams +``` + +Parameters for ACE (Augmented Core Extraction) graph build algorithm. +ACE enables building indexes for datasets too large to fit in GPU memory by: +1. Partitioning the dataset in core (closest) and augmented (second-closest) +partitions using balanced k-means. +2. Building sub-indexes for each partition independently +3. Concatenating sub-graphs into a final unified index + +## Public Members + +### getNpartitions + +```java +public long getNpartitions() +``` + +Gets the number of partitions. + +**Returns** + +the number of partitions + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSAceParams.java:92`_ + +### getEfConstruction + +```java +public long getEfConstruction() +``` + +Gets the `ef_construction` parameter. + +**Returns** + +the `ef_construction` parameter + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSAceParams.java:101`_ + +### getBuildDir + +```java +public String getBuildDir() +``` + +Gets the build directory path. + +**Returns** + +the build directory path + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSAceParams.java:110`_ + +### isUseDisk + +```java +public boolean isUseDisk() +``` + +Gets whether disk-based mode is enabled. + +**Returns** + +true if disk-based mode is enabled + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSAceParams.java:119`_ + +### getMaxHostMemoryGb + +```java +public double getMaxHostMemoryGb() +``` + +Gets the maximum host memory limit in GiB. + +**Returns** + +the max host memory limit (0 means use available memory) + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSAceParams.java:128`_ + +### getMaxGpuMemoryGb + +```java +public double getMaxGpuMemoryGb() +``` + +Gets the maximum GPU memory limit in GiB. + +**Returns** + +the max GPU memory limit (0 means use available memory) + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSAceParams.java:137`_ + +### withNpartitions + +```java +public Builder withNpartitions(long npartitions) +``` + +Sets the number of partitions. + +**Parameters** + +| Name | Description | +| --- | --- | +| `npartitions` | the number of partitions | + +**Returns** + +an instance of Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSAceParams.java:189`_ + +### withEfConstruction + +```java +public Builder withEfConstruction(long efConstruction) +``` + +Sets the ef_construction parameter. + +**Parameters** + +| Name | Description | +| --- | --- | +| `efConstruction` | the ef_construction parameter | + +**Returns** + +an instance of Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSAceParams.java:200`_ + +### withBuildDir + +```java +public Builder withBuildDir(String buildDir) +``` + +Sets the build directory path. + +**Parameters** + +| Name | Description | +| --- | --- | +| `buildDir` | the build directory path | + +**Returns** + +an instance of Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSAceParams.java:211`_ + +### withUseDisk + +```java +public Builder withUseDisk(boolean useDisk) +``` + +Sets whether to use disk-based mode. + +**Parameters** + +| Name | Description | +| --- | --- | +| `useDisk` | whether to use disk-based mode | + +**Returns** + +an instance of Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSAceParams.java:222`_ + +### withMaxHostMemoryGb + +```java +public Builder withMaxHostMemoryGb(double maxHostMemoryGb) +``` + +Sets the maximum host memory to use for ACE build in GiB. + +When set to 0 (default), uses available host memory. +Useful for testing or when running alongside other memory-intensive processes. + +**Parameters** + +| Name | Description | +| --- | --- | +| `maxHostMemoryGb` | the max host memory in GiB | + +**Returns** + +an instance of Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSAceParams.java:236`_ + +### withMaxGpuMemoryGb + +```java +public Builder withMaxGpuMemoryGb(double maxGpuMemoryGb) +``` + +Sets the maximum GPU memory to use for ACE build in GiB. + +When set to 0 (default), uses available GPU memory. +Useful for testing or when running alongside other memory-intensive processes. + +**Parameters** + +| Name | Description | +| --- | --- | +| `maxGpuMemoryGb` | the max GPU memory in GiB | + +**Returns** + +an instance of Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSAceParams.java:250`_ + +### build + +```java +public CuVSAceParams build() +``` + +Builds an instance of `CuVSAceParams`. + +**Returns** + +an instance of `CuVSAceParams` + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSAceParams.java:260`_ + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSAceParams.java:17`_ diff --git a/fern/pages/java_api/java-api-com-nvidia-cuvs-cuvsdevicematrix.md b/fern/pages/java_api/java-api-com-nvidia-cuvs-cuvsdevicematrix.md new file mode 100644 index 0000000000..73ed360d77 --- /dev/null +++ b/fern/pages/java_api/java-api-com-nvidia-cuvs-cuvsdevicematrix.md @@ -0,0 +1,29 @@ +--- +slug: api-reference/java-api-com-nvidia-cuvs-cuvsdevicematrix +--- + +# CuVSDeviceMatrix + +_Java package: `com.nvidia.cuvs`_ + +```java +public interface CuVSDeviceMatrix extends CuVSMatrix +``` + +A Dataset implementation backed by device (GPU) memory. + +## Public Members + +### toHost + +```java +default CuVSHostMatrix toHost() +``` + +Returns a new host matrix with data from this device matrix. +The returned host matrix will need to be managed by the caller, which will be +responsible to call `CuVSMatrix#close()` to free its resources when done. + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSDeviceMatrix.java:16`_ + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSDeviceMatrix.java:10`_ diff --git a/fern/pages/java_api/java-api-com-nvidia-cuvs-cuvshostmatrix.md b/fern/pages/java_api/java-api-com-nvidia-cuvs-cuvshostmatrix.md new file mode 100644 index 0000000000..e0533c039e --- /dev/null +++ b/fern/pages/java_api/java-api-com-nvidia-cuvs-cuvshostmatrix.md @@ -0,0 +1,15 @@ +--- +slug: api-reference/java-api-com-nvidia-cuvs-cuvshostmatrix +--- + +# CuVSHostMatrix + +_Java package: `com.nvidia.cuvs`_ + +```java +public interface CuVSHostMatrix extends CuVSMatrix +``` + +A Dataset implementation backed by host (CPU) memory. + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSHostMatrix.java:10`_ diff --git a/fern/pages/java_api/java-api-com-nvidia-cuvs-cuvsivfpqindexparams.md b/fern/pages/java_api/java-api-com-nvidia-cuvs-cuvsivfpqindexparams.md new file mode 100644 index 0000000000..9b9d37a42c --- /dev/null +++ b/fern/pages/java_api/java-api-com-nvidia-cuvs-cuvsivfpqindexparams.md @@ -0,0 +1,439 @@ +--- +slug: api-reference/java-api-com-nvidia-cuvs-cuvsivfpqindexparams +--- + +# CuVSIvfPqIndexParams + +_Java package: `com.nvidia.cuvs`_ + +```java +public class CuVSIvfPqIndexParams +``` + +## Public Members + +### getMetric + +```java +public CuvsDistanceType getMetric() +``` + +Gets the distance type. + +**Returns** + +the distance type + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSIvfPqIndexParams.java:143`_ + +### getCodebookKind + +```java +public CodebookGen getCodebookKind() +``` + +Gets how PQ codebooks are created + +**Returns** + +how PQ codebooks are created + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSIvfPqIndexParams.java:152`_ + +### getMetricArg + +```java +public float getMetricArg() +``` + +Gets the argument used by some distance metrics + +**Returns** + +the argument used by some distance metrics + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSIvfPqIndexParams.java:161`_ + +### getKmeansTrainsetFraction + +```java +public double getKmeansTrainsetFraction() +``` + +Gets the fraction of data to use during iterative kmeans building + +**Returns** + +the fraction of data to use during iterative kmeans building + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSIvfPqIndexParams.java:170`_ + +### getnLists + +```java +public int getnLists() +``` + +Gets the number of inverted lists (clusters) + +**Returns** + +the number of inverted lists (clusters) + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSIvfPqIndexParams.java:179`_ + +### getKmeansNIters + +```java +public int getKmeansNIters() +``` + +Gets the number of iterations searching for kmeans centers + +**Returns** + +the number of iterations searching for kmeans centers + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSIvfPqIndexParams.java:188`_ + +### getPqBits + +```java +public int getPqBits() +``` + +Gets the bit length of the vector element after compression by PQ + +**Returns** + +the bit length of the vector element after compression by PQ + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSIvfPqIndexParams.java:197`_ + +### getPqDim + +```java +public int getPqDim() +``` + +Gets the dimensionality of the vector after compression by PQ + +**Returns** + +the dimensionality of the vector after compression by PQ + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSIvfPqIndexParams.java:206`_ + +### isAddDataOnBuild + +```java +public boolean isAddDataOnBuild() +``` + +Gets whether the dataset content is added to the index + +**Returns** + +whether the dataset content is added to the index + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSIvfPqIndexParams.java:215`_ + +### isForceRandomRotation + +```java +public boolean isForceRandomRotation() +``` + +Gets the random rotation matrix on the input data and queries + +**Returns** + +the random rotation matrix on the input data and queries + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSIvfPqIndexParams.java:224`_ + +### isConservativeMemoryAllocation + +```java +public boolean isConservativeMemoryAllocation() +``` + +Gets if conservative allocation behavior is set + +**Returns** + +if conservative allocation behavior is set + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSIvfPqIndexParams.java:233`_ + +### getMaxTrainPointsPerPqCode + +```java +public int getMaxTrainPointsPerPqCode() +``` + +Gets whether max number of data points to use per PQ code during PQ codebook +training is set + +**Returns** + +whether max number of data points to use per PQ code during PQ codebook training is set + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSIvfPqIndexParams.java:244`_ + +### withMetric + +```java +public Builder withMetric(CuvsDistanceType metric) +``` + +Sets the distance type. + +**Parameters** + +| Name | Description | +| --- | --- | +| `metric` | distance type | + +**Returns** + +an instance of Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSIvfPqIndexParams.java:389`_ + +### withMetricArg + +```java +public Builder withMetricArg(float metricArg) +``` + +Sets the argument used by some distance metrics. + +**Parameters** + +| Name | Description | +| --- | --- | +| `metricArg` | argument used by some distance metrics | + +**Returns** + +an instance of Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSIvfPqIndexParams.java:400`_ + +### withAddDataOnBuild + +```java +public Builder withAddDataOnBuild(boolean addDataOnBuild) +``` + +Sets whether to add the dataset content to the index. + +**Parameters** + +| Name | Description | +| --- | --- | +| `addDataOnBuild` | whether to add the dataset content to the index | + +**Returns** + +an instance of Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSIvfPqIndexParams.java:411`_ + +### withNLists + +```java +public Builder withNLists(int nLists) +``` + +Sets the number of inverted lists (clusters) + +**Parameters** + +| Name | Description | +| --- | --- | +| `nLists` | number of inverted lists (clusters) | + +**Returns** + +an instance of Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSIvfPqIndexParams.java:422`_ + +### withKmeansNIters + +```java +public Builder withKmeansNIters(int kmeansNIters) +``` + +Sets the number of iterations searching for kmeans centers + +**Parameters** + +| Name | Description | +| --- | --- | +| `kmeansNIters` | number of iterations searching for kmeans centers | + +**Returns** + +an instance of Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSIvfPqIndexParams.java:433`_ + +### withKmeansTrainsetFraction + +```java +public Builder withKmeansTrainsetFraction(double kmeansTrainsetFraction) +``` + +Sets the fraction of data to use during iterative kmeans building. + +**Parameters** + +| Name | Description | +| --- | --- | +| `kmeansTrainsetFraction` | fraction of data to use during iterative kmeans building | + +**Returns** + +an instance of Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSIvfPqIndexParams.java:445`_ + +### withPqBits + +```java +public Builder withPqBits(int pqBits) +``` + +Sets the bit length of the vector element after compression by PQ. + +**Parameters** + +| Name | Description | +| --- | --- | +| `pqBits` | bit length of the vector element after compression by PQ | + +**Returns** + +an instance of Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSIvfPqIndexParams.java:456`_ + +### withPqDim + +```java +public Builder withPqDim(int pqDim) +``` + +Sets the dimensionality of the vector after compression by PQ. + +**Parameters** + +| Name | Description | +| --- | --- | +| `pqDim` | dimensionality of the vector after compression by PQ | + +**Returns** + +an instance of Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSIvfPqIndexParams.java:467`_ + +### withCodebookKind + +```java +public Builder withCodebookKind(CodebookGen codebookKind) +``` + +Sets how PQ codebooks are created. + +**Parameters** + +| Name | Description | +| --- | --- | +| `codebookKind` | how PQ codebooks are created | + +**Returns** + +an instance of Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSIvfPqIndexParams.java:478`_ + +### withForceRandomRotation + +```java +public Builder withForceRandomRotation(boolean forceRandomRotation) +``` + +Sets the random rotation matrix on the input data and queries. + +**Parameters** + +| Name | Description | +| --- | --- | +| `forceRandomRotation` | random rotation matrix on the input data and queries | + +**Returns** + +an instance of Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSIvfPqIndexParams.java:490`_ + +### withConservativeMemoryAllocation + +```java +public Builder withConservativeMemoryAllocation(boolean conservativeMemoryAllocation) +``` + +Sets the conservative allocation behavior + +**Parameters** + +| Name | Description | +| --- | --- | +| `conservativeMemoryAllocation` | conservative allocation behavior | + +**Returns** + +an instance of Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSIvfPqIndexParams.java:501`_ + +### withMaxTrainPointsPerPqCode + +```java +public Builder withMaxTrainPointsPerPqCode(int maxTrainPointsPerPqCode) +``` + +Sets the max number of data points to use per PQ code during PQ codebook +training + +**Parameters** + +| Name | Description | +| --- | --- | +| `maxTrainPointsPerPqCode` | max number of data points to use per PQ code during PQ codebook training | + +**Returns** + +an instance of Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSIvfPqIndexParams.java:514`_ + +### build + +```java +public CuVSIvfPqIndexParams build() +``` + +Builds an instance of `CuVSIvfPqIndexParams`. + +**Returns** + +an instance of `CuVSIvfPqIndexParams` + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSIvfPqIndexParams.java:524`_ + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSIvfPqIndexParams.java:10`_ diff --git a/fern/pages/java_api/java-api-com-nvidia-cuvs-cuvsivfpqparams.md b/fern/pages/java_api/java-api-com-nvidia-cuvs-cuvsivfpqparams.md new file mode 100644 index 0000000000..7ac190e2ed --- /dev/null +++ b/fern/pages/java_api/java-api-com-nvidia-cuvs-cuvsivfpqparams.md @@ -0,0 +1,133 @@ +--- +slug: api-reference/java-api-com-nvidia-cuvs-cuvsivfpqparams +--- + +# CuVSIvfPqParams + +_Java package: `com.nvidia.cuvs`_ + +```java +public class CuVSIvfPqParams +``` + +## Public Members + +### getIndexParams + +```java +public CuVSIvfPqIndexParams getIndexParams() +``` + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSIvfPqParams.java:29`_ + +### getSearchParams + +```java +public CuVSIvfPqSearchParams getSearchParams() +``` + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSIvfPqParams.java:37`_ + +### getRefinementRate + +```java +public float getRefinementRate() +``` + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSIvfPqParams.java:45`_ + +### Builder + +```java +private CuVSIvfPqIndexParams cuVSIvfPqIndexParams = new CuVSIvfPqIndexParams.Builder().build() +``` + +CuVS IVF_PQ index parameters + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSIvfPqParams.java:66`_ + +### Builder + +```java +private CuVSIvfPqSearchParams cuVSIvfPqSearchParams = new CuVSIvfPqSearchParams.Builder().build() +``` + +CuVS IVF_PQ search parameters + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSIvfPqParams.java:69`_ + +### withCuVSIvfPqIndexParams + +```java +public Builder withCuVSIvfPqIndexParams(CuVSIvfPqIndexParams cuVSIvfPqIndexParams) +``` + +Sets the CuVS IVF_PQ index parameters. + +**Parameters** + +| Name | Description | +| --- | --- | +| `cuVSIvfPqIndexParams` | the CuVS IVF_PQ index parameters | + +**Returns** + +an instance of Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSIvfPqParams.java:83`_ + +### withCuVSIvfPqSearchParams + +```java +public Builder withCuVSIvfPqSearchParams(CuVSIvfPqSearchParams cuVSIvfPqSearchParams) +``` + +Sets the CuVS IVF_PQ search parameters. + +**Parameters** + +| Name | Description | +| --- | --- | +| `cuVSIvfPqSearchParams` | the CuVS IVF_PQ search parameters | + +**Returns** + +an instance of Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSIvfPqParams.java:94`_ + +### withRefinementRate + +```java +public Builder withRefinementRate(float refinementRate) +``` + +Sets the refinement rate, default 2.0. + +**Parameters** + +| Name | Description | +| --- | --- | +| `refinementRate` | the refinement rate | + +**Returns** + +an instance of Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSIvfPqParams.java:105`_ + +### build + +```java +public CuVSIvfPqParams build() +``` + +Builds an instance of `CuVSIvfPqParams`. + +**Returns** + +an instance of `CuVSIvfPqParams` + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSIvfPqParams.java:115`_ + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSIvfPqParams.java:7`_ diff --git a/fern/pages/java_api/java-api-com-nvidia-cuvs-cuvsivfpqsearchparams.md b/fern/pages/java_api/java-api-com-nvidia-cuvs-cuvsivfpqsearchparams.md new file mode 100644 index 0000000000..71d600d983 --- /dev/null +++ b/fern/pages/java_api/java-api-com-nvidia-cuvs-cuvsivfpqsearchparams.md @@ -0,0 +1,168 @@ +--- +slug: api-reference/java-api-com-nvidia-cuvs-cuvsivfpqsearchparams +--- + +# CuVSIvfPqSearchParams + +_Java package: `com.nvidia.cuvs`_ + +```java +public class CuVSIvfPqSearchParams +``` + +## Public Members + +### getnProbes + +```java +public int getnProbes() +``` + +Gets the number of clusters to search + +**Returns** + +the number of clusters to search + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSIvfPqSearchParams.java:71`_ + +### getLutDtype + +```java +public CudaDataType getLutDtype() +``` + +Gets the data type of look up table to be created dynamically at search time + +**Returns** + +the data type of look up table to be created dynamically at search time + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSIvfPqSearchParams.java:81`_ + +### getInternalDistanceDtype + +```java +public CudaDataType getInternalDistanceDtype() +``` + +Gets the storage data type for distance/similarity computed at search time + +**Returns** + +the storage data type for distance/similarity computed at search time + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSIvfPqSearchParams.java:90`_ + +### getPreferredShmemCarveout + +```java +public double getPreferredShmemCarveout() +``` + +Gets the preferred fraction of SM's unified memory / L1 cache to be used as +shared memory + +**Returns** + +the preferred fraction of SM's unified memory / L1 cache to be used as shared memory + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSIvfPqSearchParams.java:101`_ + +### withNProbes + +```java +public Builder withNProbes(int nProbes) +``` + +Sets the number of clusters to search. + +**Parameters** + +| Name | Description | +| --- | --- | +| `nProbes` | the number of clusters to search | + +**Returns** + +an instance of Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSIvfPqSearchParams.java:175`_ + +### withLutDtype + +```java +public Builder withLutDtype(CudaDataType lutDtype) +``` + +Sets the the data type of look up table to be created dynamically at search +time. + +**Parameters** + +| Name | Description | +| --- | --- | +| `lutDtype` | the data type of look up table to be created dynamically at search time | + +**Returns** + +an instance of Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSIvfPqSearchParams.java:188`_ + +### withInternalDistanceDtype + +```java +public Builder withInternalDistanceDtype(CudaDataType internalDistanceDtype) +``` + +Sets the storage data type for distance/similarity computed at search time. + +**Parameters** + +| Name | Description | +| --- | --- | +| `internalDistanceDtype` | storage data type for distance/similarity computed at search time | + +**Returns** + +an instance of Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSIvfPqSearchParams.java:200`_ + +### withPreferredShmemCarveout + +```java +public Builder withPreferredShmemCarveout(double preferredShmemCarveout) +``` + +Sets the preferred fraction of SM's unified memory / L1 cache to be used as +shared memory. + +**Parameters** + +| Name | Description | +| --- | --- | +| `preferredShmemCarveout` | preferred fraction of SM's unified memory / L1 cache to be used as shared memory | + +**Returns** + +an instance of Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSIvfPqSearchParams.java:213`_ + +### build + +```java +public CuVSIvfPqSearchParams build() +``` + +Builds an instance of `CuVSIvfPqSearchParams`. + +**Returns** + +an instance of `CuVSIvfPqSearchParams` + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSIvfPqSearchParams.java:223`_ + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSIvfPqSearchParams.java:9`_ diff --git a/fern/pages/java_api/java-api-com-nvidia-cuvs-cuvsmatrix.md b/fern/pages/java_api/java-api-com-nvidia-cuvs-cuvsmatrix.md new file mode 100644 index 0000000000..ae594ff923 --- /dev/null +++ b/fern/pages/java_api/java-api-com-nvidia-cuvs-cuvsmatrix.md @@ -0,0 +1,366 @@ +--- +slug: api-reference/java-api-com-nvidia-cuvs-cuvsmatrix +--- + +# CuVSMatrix + +_Java package: `com.nvidia.cuvs`_ + +```java +public interface CuVSMatrix extends AutoCloseable +``` + +This represents a wrapper for a dataset to be used for index construction. +The purpose is to allow a caller to place the vectors into native memory +directly, instead of requiring the caller to load all the vectors into the heap +(e.g. with a float[][]). + +## Public Members + +### ofArray + +```java +static CuVSMatrix ofArray(float[][] vectors) +``` + +Creates a dataset from an on-heap array of vectors. +This method will allocate an additional MemorySegment to hold the graph data. + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSMatrix.java:46`_ + +### ofArray + +```java +static CuVSMatrix ofArray(int[][] vectors) +``` + +Creates a dataset from an on-heap array of vectors. +This method will allocate an additional MemorySegment to hold the graph data. + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSMatrix.java:56`_ + +### ofArray + +```java +static CuVSMatrix ofArray(byte[][] vectors) +``` + +Creates a dataset from an on-heap array of vectors. +This method will allocate an additional MemorySegment to hold the graph data. + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSMatrix.java:66`_ + +### addVector + +```java +void addVector(float[] vector) +``` + +Adds a single vector to the matrix. + +**Parameters** + +| Name | Description | +| --- | --- | +| `vector` | A float array of as many elements as the dimensions | + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSMatrix.java:80`_ + +### addVector + +```java +void addVector(byte[] vector) +``` + +Adds a single vector to the matrix. + +**Parameters** + +| Name | Description | +| --- | --- | +| `vector` | A byte array of as many elements as the dimensions | + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSMatrix.java:87`_ + +### addVector + +```java +void addVector(int[] vector) +``` + +Adds a single vector to the matrix. + +**Parameters** + +| Name | Description | +| --- | --- | +| `vector` | An int array of as many elements as the dimensions | + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSMatrix.java:94`_ + +### hostBuilder + +```java +static Builder hostBuilder(long size, long columns, DataType dataType) +``` + +Returns a builder to create a new instance of a host-memory matrix + +**Parameters** + +| Name | Description | +| --- | --- | +| `size` | Number of rows (e.g. vectors in a dataset) | +| `columns` | Number of columns (e.g. dimension of each vector in the dataset) | +| `dataType` | The data type of the dataset elements | + +**Returns** + +a builder for creating a `CuVSHostMatrix` + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSMatrix.java:107`_ + +### hostBuilder + +```java +static Builder hostBuilder( long size, long columns, int rowStride, int columnStride, DataType dataType) +``` + +Returns a builder to create a new instance of a host-memory matrix + +**Parameters** + +| Name | Description | +| --- | --- | +| `size` | Number of rows (e.g. vectors in a dataset) | +| `columns` | Number of columns (e.g. dimension of each vector in the dataset) | +| `rowStride` | The stride (in number of elements) for each row. Must be -1 or > than `columns` | +| `columnStride` | The stride for each column. Currently, it is not supported (must be -1) | +| `dataType` | The data type of the dataset elements | + +**Returns** + +a builder for creating a `CuVSDeviceMatrix` + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSMatrix.java:121`_ + +### deviceBuilder + +```java +static Builder deviceBuilder( CuVSResources resources, long size, long columns, DataType dataType) +``` + +Returns a builder to create a new instance of a dataset + +**Parameters** + +| Name | Description | +| --- | --- | +| `resources` | CuVS resources used to allocate the device memory needed | +| `size` | Number of rows (e.g. vectors in a dataset) | +| `columns` | Number of columns (e.g. dimension of each vector in the dataset) | +| `dataType` | The data type of the dataset elements | + +**Returns** + +a builder for creating a `CuVSDeviceMatrix` + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSMatrix.java:136`_ + +### deviceBuilder + +```java +static Builder deviceBuilder( CuVSResources resources, long size, long columns, int rowStride, int columnStride, DataType dataType) +``` + +Returns a builder to create a new instance of a dataset + +**Parameters** + +| Name | Description | +| --- | --- | +| `resources` | CuVS resources used to allocate the device memory needed | +| `size` | Number of rows (e.g. vectors in a dataset) | +| `columns` | Number of columns (e.g. dimension of each vector in the dataset) | +| `rowStride` | The stride (in number of elements) for each row. Must be -1 or > than `columns` | +| `columnStride` | The stride for each column. Currently, it is not supported (must be -1) | +| `dataType` | The data type of the dataset elements | + +**Returns** + +a builder for creating a `CuVSDeviceMatrix` + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSMatrix.java:152`_ + +### size + +```java +long size() +``` + +Gets the size of the dataset + +**Returns** + +Size of the dataset + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSMatrix.java:168`_ + +### columns + +```java +long columns() +``` + +Gets the number of columns in the Dataset (e.g. the dimensions of the vectors in this dataset, +or the graph degree for the graph represented as a list of neighbours + +**Returns** + +Dimensions of the vectors in the dataset + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSMatrix.java:176`_ + +### dataType + +```java +DataType dataType() +``` + +Gets the element type + +**Returns** + +a `DataType` describing the matrix element type + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSMatrix.java:183`_ + +### getRow + +```java +RowView getRow(long row) +``` + +Get a view (0-copy) of the row data, as a list of integers (32 bit) + +**Parameters** + +| Name | Description | +| --- | --- | +| `row` | the row for which to return the data | + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSMatrix.java:190`_ + +### toArray + +```java +void toArray(int[][] array) +``` + +Copies the content of this dataset to an on-heap Java matrix (array of arrays). + +**Parameters** + +| Name | Description | +| --- | --- | +| `array` | the destination array. Must be of length `CuVSMatrix#size()` or bigger, and each element must be of length `CuVSMatrix#columns()` or bigger. | + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSMatrix.java:198`_ + +### toArray + +```java +void toArray(float[][] array) +``` + +Copies the content of this dataset to an on-heap Java matrix (array of arrays). + +**Parameters** + +| Name | Description | +| --- | --- | +| `array` | the destination array. Must be of length `CuVSMatrix#size()` or bigger, and each element must be of length `CuVSMatrix#columns()` or bigger. | + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSMatrix.java:206`_ + +### toArray + +```java +void toArray(byte[][] array) +``` + +Copies the content of this dataset to an on-heap Java matrix (array of arrays). + +**Parameters** + +| Name | Description | +| --- | --- | +| `array` | the destination array. Must be of length `CuVSMatrix#size()` or bigger, and each element must be of length `CuVSMatrix#columns()` or bigger. | + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSMatrix.java:214`_ + +### toHost + +```java +void toHost(CuVSHostMatrix hostMatrix) +``` + +Fills the provided, pre-allocated host matrix with data from this matrix. +The content of the provided host matrix will be overwritten; the 2 matrices must have the +same element type and dimension. + +**Parameters** + +| Name | Description | +| --- | --- | +| `hostMatrix` | the host-memory-backed matrix to fill. | + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSMatrix.java:223`_ + +### toHost + +```java +CuVSHostMatrix toHost() +``` + +Returns a host matrix; if the matrix is already a host matrix, a "weak" reference to the same host memory +is returned. If the matrix is a device matrix, a newly allocated matrix will be populated with data from +the device matrix. +The returned host matrix will need to be managed by the caller, which will be +responsible to call `CuVSMatrix#close()` to free its resources when done. + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSMatrix.java:232`_ + +### toDevice + +```java +void toDevice(CuVSDeviceMatrix deviceMatrix, CuVSResources cuVSResources) +``` + +Fills the provided, pre-allocated device matrix with data from this matrix. +The content of the provided device matrix will be overwritten; the 2 matrices must have the +same element type and dimension. + +**Parameters** + +| Name | Description | +| --- | --- | +| `deviceMatrix` | the device-memory-backed matrix to fill. | + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSMatrix.java:241`_ + +### toDevice + +```java +CuVSDeviceMatrix toDevice(CuVSResources cuVSResources) +``` + +Returns a device matrix; if this matrix is already a device matrix, a "weak" reference to the same host memory +is returned. If the matrix is a host matrix, a newly allocated matrix will be populated with data from +the host matrix. +The returned device matrix will need to be managed by the caller, which will be +responsible to call `CuVSMatrix#close()` to free its resources when done. + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSMatrix.java:250`_ + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSMatrix.java:17`_ diff --git a/fern/pages/java_api/java-api-com-nvidia-cuvs-cuvsresources.md b/fern/pages/java_api/java-api-com-nvidia-cuvs-cuvsresources.md new file mode 100644 index 0000000000..f235382555 --- /dev/null +++ b/fern/pages/java_api/java-api-com-nvidia-cuvs-cuvsresources.md @@ -0,0 +1,115 @@ +--- +slug: api-reference/java-api-com-nvidia-cuvs-cuvsresources +--- + +# CuVSResources + +_Java package: `com.nvidia.cuvs`_ + +```java +public interface CuVSResources extends AutoCloseable +``` + +Used for allocating resources for cuVS + +## Public Members + +### handle + +```java +long handle() +``` + +Gets the opaque CuVSResources handle, to be used whenever we need to pass a cuvsResources_t parameter + +**Returns** + +the CuVSResources handle + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSResources.java:25`_ + +### access + +```java +ScopedAccess access() +``` + +Gets scoped access to the native resources object. +The native resource object is not thread safe: only a single thread at every time should access +concurrently the same native resources. Calling this method from multiple thread is OK, but the +returned `ScopedAccess` object must be closed before calling `access()` again from a +different thread. + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSResources.java:38`_ + +### deviceId + +```java +int deviceId() +``` + +Get the logical id of the device associated with this resources object. +Information about the device id is immutable, so it is safe to expose it without getting `ScopedAccess` +to the enclosing resources. + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSResources.java:45`_ + +### close + +```java +@Override void close() +``` + +Closes this CuVSResources object and releases any resources associated with it. + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSResources.java:50`_ + +### tempDirectory + +```java +Path tempDirectory() +``` + +The temporary directory to use for intermediate operations. +Defaults to \{@systemProperty java.io.tmpdir\}. + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSResources.java:57`_ + +### create + +```java +static CuVSResources create() throws Throwable +``` + +Creates a new resources. +Equivalent to +\{@code +create(CuVSProvider.tempDirectory()) +\} + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSResources.java:66`_ + +### create + +```java +static CuVSResources create(Path tempDirectory) throws Throwable +``` + +Creates a new resources. + +**Parameters** + +| Name | Description | +| --- | --- | +| `tempDirectory` | the temporary directory to use for intermediate operations | + +**Throws** + +| Type | Description | +| --- | --- | +| `UnsupportedOperationException` | if the provider does not cuvs | +| `LibraryException` | if the native library cannot be loaded | + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSResources.java:77`_ + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSResources.java:15`_ diff --git a/fern/pages/java_api/java-api-com-nvidia-cuvs-cuvsresourcesinfo.md b/fern/pages/java_api/java-api-com-nvidia-cuvs-cuvsresourcesinfo.md new file mode 100644 index 0000000000..0423ffe111 --- /dev/null +++ b/fern/pages/java_api/java-api-com-nvidia-cuvs-cuvsresourcesinfo.md @@ -0,0 +1,24 @@ +--- +slug: api-reference/java-api-com-nvidia-cuvs-cuvsresourcesinfo +--- + +# CuVSResourcesInfo + +_Java package: `com.nvidia.cuvs`_ + +```java +public record CuVSResourcesInfo(long freeDeviceMemoryInBytes, long totalDeviceMemoryInBytes) +``` + +Contains performance-related information associated to a `CuVSResources` and its GPU. +Can be extended to report different types of GPU memory linked to the resources, +e.g. the type and capacity of the underlying RMM `device_memory_resource` + +**Parameters** + +| Name | Description | +| --- | --- | +| `freeDeviceMemoryInBytes` | free memory in bytes, as reported by the device driver | +| `totalDeviceMemoryInBytes` | total device memory in bytes | + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/CuVSResourcesInfo.java:15`_ diff --git a/fern/pages/java_api/java-api-com-nvidia-cuvs-delegatingscopedaccess.md b/fern/pages/java_api/java-api-com-nvidia-cuvs-delegatingscopedaccess.md new file mode 100644 index 0000000000..cf63b21f70 --- /dev/null +++ b/fern/pages/java_api/java-api-com-nvidia-cuvs-delegatingscopedaccess.md @@ -0,0 +1,13 @@ +--- +slug: api-reference/java-api-com-nvidia-cuvs-delegatingscopedaccess +--- + +# DelegatingScopedAccess + +_Java package: `com.nvidia.cuvs`_ + +```java +public final class DelegatingScopedAccess implements CuVSResources.ScopedAccess +``` + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/DelegatingScopedAccess.java:7`_ diff --git a/fern/pages/java_api/java-api-com-nvidia-cuvs-gpuinfo.md b/fern/pages/java_api/java-api-com-nvidia-cuvs-gpuinfo.md new file mode 100644 index 0000000000..b2098b1641 --- /dev/null +++ b/fern/pages/java_api/java-api-com-nvidia-cuvs-gpuinfo.md @@ -0,0 +1,27 @@ +--- +slug: api-reference/java-api-com-nvidia-cuvs-gpuinfo +--- + +# GPUInfo + +_Java package: `com.nvidia.cuvs`_ + +```java +public record GPUInfo( int gpuId, String name, long totalDeviceMemoryInBytes, int computeCapabilityMajor, int computeCapabilityMinor, boolean supportsConcurrentCopy, boolean supportsConcurrentKernels) +``` + +Contains GPU information + +**Parameters** + +| Name | Description | +| --- | --- | +| `gpuId` | id of the GPU starting from 0 | +| `name` | ASCII string identifying device | +| `totalDeviceMemoryInBytes` | total device memory in bytes | +| `computeCapabilityMajor` | the compute capability of the device (major) | +| `computeCapabilityMinor` | the compute capability of the device (minor) | +| `supportsConcurrentCopy` | whether the device can concurrently copy memory between host and device while executing a kernel | +| `supportsConcurrentKernels` | whether the device supports executing multiple kernels within the same context simultaneously | + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/GPUInfo.java:20`_ diff --git a/fern/pages/java_api/java-api-com-nvidia-cuvs-gpuinfoprovider.md b/fern/pages/java_api/java-api-com-nvidia-cuvs-gpuinfoprovider.md new file mode 100644 index 0000000000..4a77bc3404 --- /dev/null +++ b/fern/pages/java_api/java-api-com-nvidia-cuvs-gpuinfoprovider.md @@ -0,0 +1,64 @@ +--- +slug: api-reference/java-api-com-nvidia-cuvs-gpuinfoprovider +--- + +# GPUInfoProvider + +_Java package: `com.nvidia.cuvs`_ + +```java +public interface GPUInfoProvider +``` + +## Public Members + +### availableGPUs + +```java +List availableGPUs() +``` + +Gets all the available GPUs + +**Returns** + +a list of `GPUInfo` objects with GPU details + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/GPUInfoProvider.java:20`_ + +### compatibleGPUs + +```java +List compatibleGPUs() +``` + +Get the list of compatible GPUs based on compute capability >= 7.0 and total +memory >= 8GB + +**Returns** + +a list of compatible GPUs. See `GPUInfo` + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/GPUInfoProvider.java:28`_ + +### getCurrentInfo + +```java +CuVSResourcesInfo getCurrentInfo(CuVSResources resources) +``` + +Gets memory information relative to a `CuVSResources` + +**Parameters** + +| Name | Description | +| --- | --- | +| `resources` | from which to obtain memory information | + +**Returns** + +a `CuVSResourcesInfo` record containing the memory information + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/GPUInfoProvider.java:35`_ + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/GPUInfoProvider.java:9`_ diff --git a/fern/pages/java_api/java-api-com-nvidia-cuvs-hnswaceparams.md b/fern/pages/java_api/java-api-com-nvidia-cuvs-hnswaceparams.md new file mode 100644 index 0000000000..11d71dff1b --- /dev/null +++ b/fern/pages/java_api/java-api-com-nvidia-cuvs-hnswaceparams.md @@ -0,0 +1,236 @@ +--- +slug: api-reference/java-api-com-nvidia-cuvs-hnswaceparams +--- + +# HnswAceParams + +_Java package: `com.nvidia.cuvs`_ + +```java +public class HnswAceParams +``` + +Parameters for ACE (Augmented Core Extraction) graph build for HNSW. +ACE enables building indexes for datasets too large to fit in GPU memory by: +1. Partitioning the dataset in core and augmented partitions using balanced k-means +2. Building sub-indexes for each partition independently +3. Concatenating sub-graphs into a final unified index + +## Public Members + +### getNpartitions + +```java +public long getNpartitions() +``` + +Gets the number of partitions for ACE partitioned build. + +**Returns** + +the number of partitions + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswAceParams.java:37`_ + +### getBuildDir + +```java +public String getBuildDir() +``` + +Gets the directory to store ACE build artifacts. + +**Returns** + +the build directory path + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswAceParams.java:46`_ + +### isUseDisk + +```java +public boolean isUseDisk() +``` + +Gets whether disk-based storage is enabled for ACE build. + +**Returns** + +true if disk mode is enabled + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswAceParams.java:55`_ + +### getMaxHostMemoryGb + +```java +public double getMaxHostMemoryGb() +``` + +Gets the maximum host memory limit in GiB. + +**Returns** + +the max host memory limit (0 means use available memory) + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswAceParams.java:64`_ + +### getMaxGpuMemoryGb + +```java +public double getMaxGpuMemoryGb() +``` + +Gets the maximum GPU memory limit in GiB. + +**Returns** + +the max GPU memory limit (0 means use available memory) + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswAceParams.java:73`_ + +### Builder + +```java +public Builder() +``` + +Constructs this Builder. + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswAceParams.java:106`_ + +### withNpartitions + +```java +public Builder withNpartitions(long npartitions) +``` + +Sets the number of partitions for ACE partitioned build. + +When set to 0 (default), the number of partitions is automatically derived +based on available host and GPU memory to maximize partition size while +ensuring the build fits in memory. + +Small values might improve recall but potentially degrade performance. +The partition size is on average 2 * (n_rows / npartitions) * dim * +sizeof(T). 2 is because of the core and augmented vectors. Please account +for imbalance in the partition sizes (up to 3x in our tests). + +If the specified number of partitions results in partitions that exceed +available memory, the value will be automatically increased to fit memory +constraints and a warning will be issued. + +**Parameters** + +| Name | Description | +| --- | --- | +| `npartitions` | the number of partitions | + +**Returns** + +an instance of Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswAceParams.java:127`_ + +### withBuildDir + +```java +public Builder withBuildDir(String buildDir) +``` + +Sets the directory to store ACE build artifacts. +Used when useDisk is true or when the graph does not fit in memory. + +**Parameters** + +| Name | Description | +| --- | --- | +| `buildDir` | the build directory path | + +**Returns** + +an instance of Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswAceParams.java:139`_ + +### withUseDisk + +```java +public Builder withUseDisk(boolean useDisk) +``` + +Sets whether to use disk-based storage for ACE build. +When true, enables disk-based operations for memory-efficient graph construction. + +**Parameters** + +| Name | Description | +| --- | --- | +| `useDisk` | true to enable disk mode | + +**Returns** + +an instance of Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswAceParams.java:151`_ + +### withMaxHostMemoryGb + +```java +public Builder withMaxHostMemoryGb(double maxHostMemoryGb) +``` + +Sets the maximum host memory to use for ACE build in GiB. + +When set to 0 (default), uses available host memory. +Useful for testing or when running alongside other memory-intensive processes. + +**Parameters** + +| Name | Description | +| --- | --- | +| `maxHostMemoryGb` | the max host memory in GiB | + +**Returns** + +an instance of Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswAceParams.java:165`_ + +### withMaxGpuMemoryGb + +```java +public Builder withMaxGpuMemoryGb(double maxGpuMemoryGb) +``` + +Sets the maximum GPU memory to use for ACE build in GiB. + +When set to 0 (default), uses available GPU memory. +Useful for testing or when running alongside other memory-intensive processes. + +**Parameters** + +| Name | Description | +| --- | --- | +| `maxGpuMemoryGb` | the max GPU memory in GiB | + +**Returns** + +an instance of Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswAceParams.java:179`_ + +### build + +```java +public HnswAceParams build() +``` + +Builds an instance of `HnswAceParams`. + +**Returns** + +an instance of `HnswAceParams` + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswAceParams.java:189`_ + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswAceParams.java:16`_ diff --git a/fern/pages/java_api/java-api-com-nvidia-cuvs-hnswindex.md b/fern/pages/java_api/java-api-com-nvidia-cuvs-hnswindex.md new file mode 100644 index 0000000000..df40dd733f --- /dev/null +++ b/fern/pages/java_api/java-api-com-nvidia-cuvs-hnswindex.md @@ -0,0 +1,189 @@ +--- +slug: api-reference/java-api-com-nvidia-cuvs-hnswindex +--- + +# HnswIndex + +_Java package: `com.nvidia.cuvs`_ + +```java +public interface HnswIndex extends AutoCloseable +``` + +`HnswIndex` encapsulates a HNSW index, along with methods to interact +with it. + +## Public Members + +### close + +```java +@Override void close() throws Exception +``` + +Invokes the native destroy_hnsw_index to de-allocate the HNSW index + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswIndex.java:21`_ + +### search + +```java +SearchResults search(HnswQuery query) throws Throwable +``` + +Invokes the native search_hnsw_index via the Panama API for searching a HNSW +index. + +**Parameters** + +| Name | Description | +| --- | --- | +| `query` | an instance of `HnswQuery` holding the query vectors and other parameters | + +**Returns** + +an instance of `SearchResults` containing the results + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswIndex.java:32`_ + +### newBuilder + +```java +static HnswIndex.Builder newBuilder(CuVSResources cuvsResources) +``` + +Creates a new Builder with an instance of `CuVSResources`. + +**Parameters** + +| Name | Description | +| --- | --- | +| `cuvsResources` | an instance of `CuVSResources` | + +**Throws** + +| Type | Description | +| --- | --- | +| `UnsupportedOperationException` | if the provider does not cuvs | + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswIndex.java:40`_ + +### fromCagra + +```java +static HnswIndex fromCagra(HnswIndexParams hnswParams, CagraIndex cagraIndex) throws Throwable +``` + +Creates an HNSW index from an existing CAGRA index. + +**Parameters** + +| Name | Description | +| --- | --- | +| `hnswParams` | Parameters for the HNSW index | +| `cagraIndex` | The CAGRA index to convert from | + +**Returns** + +A new HNSW index + +**Throws** + +| Type | Description | +| --- | --- | +| `Throwable` | if an error occurs during conversion | + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswIndex.java:53`_ + +### build + +```java +static HnswIndex build(CuVSResources resources, HnswIndexParams hnswParams, CuVSMatrix dataset) throws Throwable +``` + +Builds an HNSW index using the ACE (Augmented Core Extraction) algorithm. + +ACE enables building HNSW indexes for datasets too large to fit in GPU +memory by partitioning the dataset and building sub-indexes for each +partition independently. + +NOTE: This method requires `hnswParams.getAceParams()` to be set with +an instance of HnswAceParams. + +**Parameters** + +| Name | Description | +| --- | --- | +| `resources` | The CuVS resources | +| `hnswParams` | Parameters for the HNSW index with ACE configuration | +| `dataset` | The dataset to build the index from | + +**Returns** + +A new HNSW index ready for search + +**Throws** + +| Type | Description | +| --- | --- | +| `Throwable` | if an error occurs during building | + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswIndex.java:75`_ + +### from + +```java +Builder from(InputStream inputStream) +``` + +Sets an instance of InputStream typically used when index deserialization is +needed. + +**Parameters** + +| Name | Description | +| --- | --- | +| `inputStream` | an instance of `InputStream` | + +**Returns** + +an instance of this Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswIndex.java:96`_ + +### withIndexParams + +```java +Builder withIndexParams(HnswIndexParams hnswIndexParameters) +``` + +Registers an instance of configured `HnswIndexParams` with this +Builder. + +**Parameters** + +| Name | Description | +| --- | --- | +| `hnswIndexParameters` | An instance of HnswIndexParams. | + +**Returns** + +An instance of this Builder. + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswIndex.java:105`_ + +### build + +```java +HnswIndex build() throws Throwable +``` + +Builds and returns an instance of CagraIndex. + +**Returns** + +an instance of CagraIndex + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswIndex.java:112`_ + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswIndex.java:17`_ diff --git a/fern/pages/java_api/java-api-com-nvidia-cuvs-hnswindexparams.md b/fern/pages/java_api/java-api-com-nvidia-cuvs-hnswindexparams.md new file mode 100644 index 0000000000..518043dc8d --- /dev/null +++ b/fern/pages/java_api/java-api-com-nvidia-cuvs-hnswindexparams.md @@ -0,0 +1,294 @@ +--- +slug: api-reference/java-api-com-nvidia-cuvs-hnswindexparams +--- + +# HnswIndexParams + +_Java package: `com.nvidia.cuvs`_ + +```java +public class HnswIndexParams +``` + +Supplemental parameters to build HNSW index. + +## Public Members + +### NONE + +```java +NONE(0), /** * Full hierarchy is built using the CPU */ CPU(1), /** * Full hierarchy is built using the GPU */ GPU(2) +``` + +Flat hierarchy, search is base-layer only + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswIndexParams.java:38`_ + +### CPU + +```java +CPU(1), /** * Full hierarchy is built using the GPU */ GPU(2) +``` + +Full hierarchy is built using the CPU + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswIndexParams.java:43`_ + +### GPU + +```java +GPU(2) +``` + +Full hierarchy is built using the GPU + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswIndexParams.java:48`_ + +### getHierarchy + +```java +public CuvsHnswHierarchy getHierarchy() +``` + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswIndexParams.java:98`_ + +### getEfConstruction + +```java +public int getEfConstruction() +``` + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswIndexParams.java:106`_ + +### getNumThreads + +```java +public int getNumThreads() +``` + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswIndexParams.java:114`_ + +### getVectorDimension + +```java +public int getVectorDimension() +``` + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswIndexParams.java:122`_ + +### getM + +```java +public long getM() +``` + +Gets the HNSW M parameter: number of bi-directional links per node +(used when building with ACE). graph_degree = m * 2, +intermediate_graph_degree = m * 3. + +**Returns** + +the M parameter + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswIndexParams.java:133`_ + +### getMetric + +```java +public CuvsDistanceType getMetric() +``` + +Gets the distance metric type. + +**Returns** + +the metric type + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswIndexParams.java:142`_ + +### getAceParams + +```java +public HnswAceParams getAceParams() +``` + +Gets the ACE parameters for building HNSW index using ACE algorithm. + +**Returns** + +the ACE parameters, or null if not set + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswIndexParams.java:151`_ + +### Builder + +```java +public Builder() +``` + +Constructs this Builder with an instance of Arena. + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswIndexParams.java:190`_ + +### withHierarchy + +```java +public Builder withHierarchy(CuvsHnswHierarchy hierarchy) +``` + +Sets the hierarchy for HNSW index when converting from CAGRA index. + +NOTE: When the value is `NONE`, the HNSW index is built as a base-layer-only +index. + +**Parameters** + +| Name | Description | +| --- | --- | +| `hierarchy` | the hierarchy for HNSW index when converting from CAGRA index | + +**Returns** + +an instance of Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswIndexParams.java:202`_ + +### withEfConstruction + +```java +public Builder withEfConstruction(int efConstruction) +``` + +Sets the size of the candidate list during hierarchy construction when +hierarchy is `CPU`. + +**Parameters** + +| Name | Description | +| --- | --- | +| `efConstruction` | the size of the candidate list during hierarchy construction when hierarchy is `CPU` | + +**Returns** + +an instance of Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswIndexParams.java:215`_ + +### withNumThreads + +```java +public Builder withNumThreads(int numThreads) +``` + +Sets the number of host threads to use to construct hierarchy when hierarchy +is `CPU`. + +**Parameters** + +| Name | Description | +| --- | --- | +| `numThreads` | the number of threads | + +**Returns** + +an instance of Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswIndexParams.java:227`_ + +### withVectorDimension + +```java +public Builder withVectorDimension(int vectorDimension) +``` + +Sets the vector dimension + +**Parameters** + +| Name | Description | +| --- | --- | +| `vectorDimension` | the vector dimension | + +**Returns** + +an instance of Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswIndexParams.java:238`_ + +### withM + +```java +public Builder withM(long m) +``` + +Sets the HNSW M parameter: number of bi-directional links per node +(used when building with ACE). graph_degree = m * 2, +intermediate_graph_degree = m * 3. + +**Parameters** + +| Name | Description | +| --- | --- | +| `m` | the M parameter | + +**Returns** + +an instance of Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswIndexParams.java:251`_ + +### withMetric + +```java +public Builder withMetric(CuvsDistanceType metric) +``` + +Sets the distance metric type. + +**Parameters** + +| Name | Description | +| --- | --- | +| `metric` | the metric type | + +**Returns** + +an instance of Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswIndexParams.java:262`_ + +### withAceParams + +```java +public Builder withAceParams(HnswAceParams aceParams) +``` + +Sets the ACE parameters for building HNSW index using ACE algorithm. + +**Parameters** + +| Name | Description | +| --- | --- | +| `aceParams` | the ACE parameters | + +**Returns** + +an instance of Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswIndexParams.java:273`_ + +### build + +```java +public HnswIndexParams build() +``` + +Builds an instance of `HnswIndexParams`. + +**Returns** + +an instance of `HnswIndexParams` + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswIndexParams.java:283`_ + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswIndexParams.java:12`_ diff --git a/fern/pages/java_api/java-api-com-nvidia-cuvs-hnswquery.md b/fern/pages/java_api/java-api-com-nvidia-cuvs-hnswquery.md new file mode 100644 index 0000000000..c66a6b64e7 --- /dev/null +++ b/fern/pages/java_api/java-api-com-nvidia-cuvs-hnswquery.md @@ -0,0 +1,223 @@ +--- +slug: api-reference/java-api-com-nvidia-cuvs-hnswquery +--- + +# HnswQuery + +_Java package: `com.nvidia.cuvs`_ + +```java +public class HnswQuery +``` + +HnswQuery holds the query vectors to be used while invoking search on the +HNSW index. + +Thread Safety: Each HnswQuery instance should use its own +CuVSResources object that is not shared with other threads. Sharing CuVSResources +between threads can lead to memory allocation errors or JVM crashes. + +## Public Members + +### HnswQuery + +```java +private HnswQuery( HnswSearchParams hnswSearchParams, float[][] queryVectors, LongToIntFunction mapping, int topK, CuVSResources resources) +``` + +Constructs an instance of `HnswQuery` using queryVectors, mapping, and +topK. + +**Parameters** + +| Name | Description | +| --- | --- | +| `hnswSearchParams` | the search parameters to use | +| `queryVectors` | 2D float query vector array | +| `mapping` | a function mapping ordinals (neighbor IDs) to custom user IDs | +| `topK` | the top k results to return | +| `resources` | CuVSResources instance to use for this query | + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswQuery.java:38`_ + +### getHnswSearchParams + +```java +public HnswSearchParams getHnswSearchParams() +``` + +Gets the instance of HnswSearchParams. + +**Returns** + +the instance of `HnswSearchParams` + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswQuery.java:56`_ + +### getQueryVectors + +```java +public float[][] getQueryVectors() +``` + +Gets the query vector 2D float array. + +**Returns** + +2D float array + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswQuery.java:65`_ + +### getMapping + +```java +public LongToIntFunction getMapping() +``` + +Gets the function mapping ordinals (neighbor IDs) to custom user IDs + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswQuery.java:72`_ + +### getTopK + +```java +public int getTopK() +``` + +Gets the topK value. + +**Returns** + +an integer + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswQuery.java:81`_ + +### getResources + +```java +public CuVSResources getResources() +``` + +Gets the CuVSResources instance for this query. + +**Returns** + +the CuVSResources instance + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswQuery.java:90`_ + +### Builder + +```java +public Builder(CuVSResources resources) +``` + +Constructor that requires CuVSResources. + +Important: The provided CuVSResources instance should not be +shared with other threads. Each thread performing searches should create its own +CuVSResources instance to avoid memory allocation conflicts and potential JVM crashes. + +**Parameters** + +| Name | Description | +| --- | --- | +| `resources` | the CuVSResources instance to use for this query (must not be shared between threads) | + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswQuery.java:125`_ + +### withSearchParams + +```java +public Builder withSearchParams(HnswSearchParams hnswSearchParams) +``` + +Sets the instance of configured HnswSearchParams to be passed for search. + +**Parameters** + +| Name | Description | +| --- | --- | +| `hnswSearchParams` | an instance of the configured HnswSearchParams to be used for this query | + +**Returns** + +an instance of this Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswQuery.java:136`_ + +### withQueryVectors + +```java +public Builder withQueryVectors(float[][] queryVectors) +``` + +Registers the query vectors to be passed in the search call. + +**Parameters** + +| Name | Description | +| --- | --- | +| `queryVectors` | 2D float query vector array | + +**Returns** + +an instance of this Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswQuery.java:147`_ + +### withMapping + +```java +public Builder withMapping(LongToIntFunction mapping) +``` + +Sets the function used to map ordinals (neighbor IDs) to custom user IDs + +**Parameters** + +| Name | Description | +| --- | --- | +| `mapping` | a function mapping ordinals (neighbor IDs) to custom user IDs | + +**Returns** + +an instance of this Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswQuery.java:158`_ + +### withTopK + +```java +public Builder withTopK(int topK) +``` + +Registers the topK value. + +**Parameters** + +| Name | Description | +| --- | --- | +| `topK` | the topK value used to retrieve the topK results | + +**Returns** + +an instance of this Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswQuery.java:169`_ + +### build + +```java +public HnswQuery build() +``` + +Builds an instance of `HnswQuery` + +**Returns** + +an instance of `HnswQuery` + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswQuery.java:179`_ + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswQuery.java:21`_ diff --git a/fern/pages/java_api/java-api-com-nvidia-cuvs-hnswsearchparams.md b/fern/pages/java_api/java-api-com-nvidia-cuvs-hnswsearchparams.md new file mode 100644 index 0000000000..5fea6b1277 --- /dev/null +++ b/fern/pages/java_api/java-api-com-nvidia-cuvs-hnswsearchparams.md @@ -0,0 +1,89 @@ +--- +slug: api-reference/java-api-com-nvidia-cuvs-hnswsearchparams +--- + +# HnswSearchParams + +_Java package: `com.nvidia.cuvs`_ + +```java +public record HnswSearchParams(int ef, int numThreads) +``` + +HnswSearchParams encapsulates the logic for configuring and holding search +parameters for HNSW index. + +**Parameters** + +| Name | Description | +| --- | --- | +| `ef` | the ef value | +| `numThreads` | the number of threads | + +## Public Members + +### Builder + +```java +public Builder() +``` + +Constructs this Builder with an instance of Arena. + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswSearchParams.java:39`_ + +### withEF + +```java +public Builder withEF(int ef) +``` + +Sets the ef value + +**Parameters** + +| Name | Description | +| --- | --- | +| `ef` | the ef value | + +**Returns** + +an instance of this Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswSearchParams.java:47`_ + +### withNumThreads + +```java +public Builder withNumThreads(int numThreads) +``` + +Sets the number of threads + +**Parameters** + +| Name | Description | +| --- | --- | +| `numThreads` | the number of threads | + +**Returns** + +an instance of this Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswSearchParams.java:58`_ + +### build + +```java +public HnswSearchParams build() +``` + +Builds an instance of `HnswSearchParams` with passed search parameters. + +**Returns** + +an instance of HnswSearchParams + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswSearchParams.java:68`_ + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/HnswSearchParams.java:15`_ diff --git a/fern/pages/java_api/java-api-com-nvidia-cuvs-libraryexception.md b/fern/pages/java_api/java-api-com-nvidia-cuvs-libraryexception.md new file mode 100644 index 0000000000..679b8f9281 --- /dev/null +++ b/fern/pages/java_api/java-api-com-nvidia-cuvs-libraryexception.md @@ -0,0 +1,13 @@ +--- +slug: api-reference/java-api-com-nvidia-cuvs-libraryexception +--- + +# LibraryException + +_Java package: `com.nvidia.cuvs`_ + +```java +public class LibraryException extends RuntimeException +``` + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/LibraryException.java:7`_ diff --git a/fern/pages/java_api/java-api-com-nvidia-cuvs-rowview.md b/fern/pages/java_api/java-api-com-nvidia-cuvs-rowview.md new file mode 100644 index 0000000000..b75ef47922 --- /dev/null +++ b/fern/pages/java_api/java-api-com-nvidia-cuvs-rowview.md @@ -0,0 +1,119 @@ +--- +slug: api-reference/java-api-com-nvidia-cuvs-rowview +--- + +# RowView + +_Java package: `com.nvidia.cuvs`_ + +```java +public interface RowView +``` + +Represent a contiguous list of elements backed by off-heap memory. + +## Public Members + +### getAsInt + +```java +int getAsInt(long index) +``` + +Returns the integer element at the given position. Asserts that the +data type of the dataset on top of which this view is instantiates is +`CuVSMatrix.DataType#INT` + +**Parameters** + +| Name | Description | +| --- | --- | +| `index` | the element index | + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/RowView.java:22`_ + +### getAsFloat + +```java +float getAsFloat(long index) +``` + +Returns the integer element at the given position. Asserts that the +data type of the dataset on top of which this view is instantiates is +`CuVSMatrix.DataType#FLOAT` + +**Parameters** + +| Name | Description | +| --- | --- | +| `index` | the element index | + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/RowView.java:31`_ + +### getAsByte + +```java +byte getAsByte(long index) +``` + +Returns the integer element at the given position. Asserts that the +data type of the dataset on top of which this view is instantiates is +`CuVSMatrix.DataType#BYTE` + +**Parameters** + +| Name | Description | +| --- | --- | +| `index` | the element index | + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/RowView.java:40`_ + +### toArray + +```java +void toArray(int[] array) +``` + +Copies the content of this row to an on-heap Java array. + +**Parameters** + +| Name | Description | +| --- | --- | +| `array` | the destination array. Must be of length `RowView#size()` or bigger. | + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/RowView.java:47`_ + +### toArray + +```java +void toArray(float[] array) +``` + +Copies the content of this row to an on-heap Java array. + +**Parameters** + +| Name | Description | +| --- | --- | +| `array` | the destination array. Must be of length `RowView#size()` or bigger. | + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/RowView.java:54`_ + +### toArray + +```java +void toArray(byte[] array) +``` + +Copies the content of this row to an on-heap Java array. + +**Parameters** + +| Name | Description | +| --- | --- | +| `array` | the destination array. Must be of length `RowView#size()` or bigger. | + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/RowView.java:61`_ + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/RowView.java:12`_ diff --git a/fern/pages/java_api/java-api-com-nvidia-cuvs-searchresults.md b/fern/pages/java_api/java-api-com-nvidia-cuvs-searchresults.md new file mode 100644 index 0000000000..41a323e123 --- /dev/null +++ b/fern/pages/java_api/java-api-com-nvidia-cuvs-searchresults.md @@ -0,0 +1,49 @@ +--- +slug: api-reference/java-api-com-nvidia-cuvs-searchresults +--- + +# SearchResults + +_Java package: `com.nvidia.cuvs`_ + +```java +public interface SearchResults +``` + +## Public Members + +### mappingsFromList + +```java +static LongToIntFunction mappingsFromList(List mappingAsList) +``` + +Creates a mapping function from a list lookup of custom user IDs + +**Parameters** + +| Name | Description | +| --- | --- | +| `mappingAsList` | a positional list of custom user IDs | + +**Returns** + +a function that maps the input ordinal to a custom user IDs, using the input as an index in the list + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/SearchResults.java:22`_ + +### getResults + +```java +List> getResults() +``` + +Gets a list results as a map of neighbor IDs to distances. + +**Returns** + +a list of results for each query as a map of neighbor IDs to distance + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/SearchResults.java:31`_ + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/SearchResults.java:11`_ diff --git a/fern/pages/java_api/java-api-com-nvidia-cuvs-spi-cuvsprovider.md b/fern/pages/java_api/java-api-com-nvidia-cuvs-spi-cuvsprovider.md new file mode 100644 index 0000000000..17557e5e57 --- /dev/null +++ b/fern/pages/java_api/java-api-com-nvidia-cuvs-spi-cuvsprovider.md @@ -0,0 +1,415 @@ +--- +slug: api-reference/java-api-com-nvidia-cuvs-spi-cuvsprovider +--- + +# CuVSProvider + +_Java package: `com.nvidia.cuvs.spi`_ + +```java +public interface CuVSProvider +``` + +A provider of low-level cuvs resources and builders. + +## Public Members + +### tempDirectory + +```java +static Path tempDirectory() +``` + +The temporary directory to use for intermediate operations. +Defaults to \{@systemProperty java.io.tmpdir\}. + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/spi/CuVSProvider.java:22`_ + +### nativeLibraryPath + +```java +default Path nativeLibraryPath() +``` + +The directory where to extract and install the native library. +Defaults to \{@systemProperty java.io.tmpdir\}. + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/spi/CuVSProvider.java:30`_ + +### newCuVSResources + +```java +CuVSResources newCuVSResources(Path tempDirectory) throws Throwable +``` + +Creates a new CuVSResources. + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/spi/CuVSProvider.java:35`_ + +### newHostMatrixBuilder + +```java +CuVSMatrix.Builder newHostMatrixBuilder( long size, long dimensions, CuVSMatrix.DataType dataType) +``` + +Create a `CuVSMatrix.Builder` instance for a host memory matrix * + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/spi/CuVSProvider.java:38`_ + +### newHostMatrixBuilder + +```java +CuVSMatrix.Builder newHostMatrixBuilder( long size, long columns, int rowStride, int columnStride, CuVSMatrix.DataType dataType) +``` + +Create a `CuVSMatrix.Builder` instance for a host memory matrix * + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/spi/CuVSProvider.java:42`_ + +### newDeviceMatrixBuilder + +```java +CuVSMatrix.Builder newDeviceMatrixBuilder( CuVSResources cuVSResources, long size, long dimensions, CuVSMatrix.DataType dataType) +``` + +Create a `CuVSMatrix.Builder` instance for a device memory matrix * + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/spi/CuVSProvider.java:46`_ + +### newDeviceMatrixBuilder + +```java +CuVSMatrix.Builder newDeviceMatrixBuilder( CuVSResources cuVSResources, long size, long dimensions, int rowStride, int columnStride, CuVSMatrix.DataType dataType) +``` + +Create a `CuVSMatrix.Builder` instance for a device memory matrix * + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/spi/CuVSProvider.java:50`_ + +### newNativeMatrixBuilder + +```java +MethodHandle newNativeMatrixBuilder() +``` + +Returns the factory method used to build a CuVSMatrix from native memory. +The factory method will have this signature: +`CuVSMatrix createNativeMatrix(memorySegment, size, dimensions, dataType)`, +where `memorySegment` is a `java.lang.foreign.MemorySegment` containing `int size` vectors of +`int dimensions` length of type `CuVSMatrix.DataType`. + +In order to expose this factory in a way that is compatible with Java 21, the factory method is returned as a +`MethodHandle` with `MethodType` equal to +`(CuVSMatrix.class, MemorySegment.class, int.class, int.class, CuVSMatrix.DataType.class)`. +The caller will need to invoke the factory via the `MethodHandle#invokeExact` method: +`var matrix = (CuVSMatrix)newNativeMatrixBuilder().invokeExact(memorySegment, size, dimensions, dataType)` + +**Returns** + +a MethodHandle which can be invoked to build a CuVSMatrix from an external `MemorySegment` + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/spi/CuVSProvider.java:73`_ + +### newNativeMatrixBuilderWithStrides + +```java +MethodHandle newNativeMatrixBuilderWithStrides() +``` + +Returns the factory method used to build a CuVSMatrix from native memory, with strides. +The factory method will have this signature: +`CuVSMatrix createNativeMatrix(memorySegment, size, dimensions, rowStride, columnStride, dataType)`, +where `memorySegment` is a `java.lang.foreign.MemorySegment` containing `int size` vectors of +`int dimensions` length of type `CuVSMatrix.DataType`. Rows have a stride of `rowStride`, +where 0 indicates "no stride" (a stride equal to the number of columns), and columns have a stride of +`columnStride` + +In order to expose this factory in a way that is compatible with Java 21, the factory method is returned as a +`MethodHandle` with `MethodType` equal to +`(CuVSMatrix.class, MemorySegment.class, int.class, int.class, int.class, int.class, DataType.class)`. +The caller will need to invoke the factory via the `MethodHandle#invokeExact` method: +`var matrix = (CuVSMatrix)newNativeMatrixBuilder().invokeExact(memorySegment, size, dimensions, rowStride, columnStride, dataType)` + +**Returns** + +a MethodHandle which can be invoked to build a CuVSMatrix from an external `MemorySegment` + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/spi/CuVSProvider.java:92`_ + +### newMatrixFromArray + +```java +CuVSMatrix newMatrixFromArray(float[][] vectors) +``` + +Create a `CuVSMatrix` from an on-heap array * + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/spi/CuVSProvider.java:95`_ + +### newMatrixFromArray + +```java +CuVSMatrix newMatrixFromArray(int[][] vectors) +``` + +Create a `CuVSMatrix` from an on-heap array * + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/spi/CuVSProvider.java:98`_ + +### newMatrixFromArray + +```java +CuVSMatrix newMatrixFromArray(byte[][] vectors) +``` + +Create a `CuVSMatrix` from an on-heap array * + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/spi/CuVSProvider.java:101`_ + +### newBruteForceIndexBuilder + +```java +BruteForceIndex.Builder newBruteForceIndexBuilder(CuVSResources cuVSResources) throws UnsupportedOperationException +``` + +Creates a new BruteForceIndex Builder. + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/spi/CuVSProvider.java:104`_ + +### newCagraIndexBuilder + +```java +CagraIndex.Builder newCagraIndexBuilder(CuVSResources cuVSResources) throws UnsupportedOperationException +``` + +Creates a new CagraIndex Builder. + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/spi/CuVSProvider.java:108`_ + +### newHnswIndexBuilder + +```java +HnswIndex.Builder newHnswIndexBuilder(CuVSResources cuVSResources) throws UnsupportedOperationException +``` + +Creates a new HnswIndex Builder. + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/spi/CuVSProvider.java:112`_ + +### hnswIndexFromCagra + +```java +HnswIndex hnswIndexFromCagra(HnswIndexParams hnswParams, CagraIndex cagraIndex) throws Throwable +``` + +Creates an HNSW index from an existing CAGRA index. + +**Parameters** + +| Name | Description | +| --- | --- | +| `hnswParams` | Parameters for the HNSW index | +| `cagraIndex` | The CAGRA index to convert from | + +**Returns** + +A new HNSW index + +**Throws** + +| Type | Description | +| --- | --- | +| `Throwable` | if an error occurs during conversion | + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/spi/CuVSProvider.java:123`_ + +### hnswIndexBuild + +```java +HnswIndex hnswIndexBuild(CuVSResources resources, HnswIndexParams hnswParams, CuVSMatrix dataset) throws Throwable +``` + +Builds an HNSW index using the ACE (Augmented Core Extraction) algorithm. + +**Parameters** + +| Name | Description | +| --- | --- | +| `resources` | The CuVS resources | +| `hnswParams` | Parameters for the HNSW index with ACE configuration | +| `dataset` | The dataset to build the index from | + +**Returns** + +A new HNSW index ready for search + +**Throws** + +| Type | Description | +| --- | --- | +| `Throwable` | if an error occurs during building | + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/spi/CuVSProvider.java:134`_ + +### newTieredIndexBuilder + +```java +TieredIndex.Builder newTieredIndexBuilder(CuVSResources cuVSResources) throws UnsupportedOperationException +``` + +Creates a new TieredIndex Builder. + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/spi/CuVSProvider.java:138`_ + +### mergeCagraIndexes + +```java +CagraIndex mergeCagraIndexes(CagraIndex[] indexes) throws Throwable +``` + +Merges multiple CAGRA indexes into a single index. + +**Parameters** + +| Name | Description | +| --- | --- | +| `indexes` | Array of CAGRA indexes to merge | + +**Returns** + +A new merged CAGRA index + +**Throws** + +| Type | Description | +| --- | --- | +| `Throwable` | if an error occurs during the merge operation | + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/spi/CuVSProvider.java:148`_ + +### mergeCagraIndexes + +```java +default CagraIndex mergeCagraIndexes(CagraIndex[] indexes, CagraIndexParams mergeParams) throws Throwable +``` + +Merges multiple CAGRA indexes into a single index with the specified merge parameters. + +**Parameters** + +| Name | Description | +| --- | --- | +| `indexes` | Array of CAGRA indexes to merge | +| `mergeParams` | Parameters to control the merge operation, or null to use defaults | + +**Returns** + +A new merged CAGRA index + +**Throws** + +| Type | Description | +| --- | --- | +| `Throwable` | if an error occurs during the merge operation | + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/spi/CuVSProvider.java:158`_ + +### gpuInfoProvider + +```java +GPUInfoProvider gpuInfoProvider() +``` + +Returns a `GPUInfoProvider` to query the system for GPU related information + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/spi/CuVSProvider.java:165`_ + +### enableRMMPooledMemory + +```java +void enableRMMPooledMemory(int initialPoolSizePercent, int maxPoolSizePercent) +``` + +Switch RMM allocations (used internally by various cuVS algorithms and by the default implementation of +`CuVSDeviceMatrix`) to use pooled memory. +This operation has a global effect, and will affect all resources on the current device. + +**Parameters** + +| Name | Description | +| --- | --- | +| `initialPoolSizePercent` | The initial pool size, in percentage of the total GPU memory | +| `maxPoolSizePercent` | The maximum pool size, in percentage of the total GPU memory | + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/spi/CuVSProvider.java:179`_ + +### enableRMMManagedPooledMemory + +```java +void enableRMMManagedPooledMemory(int initialPoolSizePercent, int maxPoolSizePercent) +``` + +Switch RMM allocations (used internally by various cuVS algorithms and by the default implementation of +`CuVSDeviceMatrix`) to use pooled memory. +This operation has a global effect, and will affect all resources on the current device. + +**Parameters** + +| Name | Description | +| --- | --- | +| `initialPoolSizePercent` | The initial pool size, in percentage of the total GPU memory | +| `maxPoolSizePercent` | The maximum pool size, in percentage of the total GPU memory | + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/spi/CuVSProvider.java:189`_ + +### resetRMMPooledMemory + +```java +void resetRMMPooledMemory() +``` + +Disables pooled memory on the current device, reverting back to the default setting. + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/spi/CuVSProvider.java:192`_ + +### provider + +```java +static CuVSProvider provider() +``` + +Retrieves the system-wide provider. + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/spi/CuVSProvider.java:195`_ + +### cagraIndexParamsFromHnswParams + +```java +CagraIndexParams cagraIndexParamsFromHnswParams( long rows, long dim, int m, int efConstruction, CagraIndexParams.HnswHeuristicType heuristic, CagraIndexParams.CuvsDistanceType metric) +``` + +Create a CAGRA index parameters compatible with HNSW index + +Note: The reference HNSW index and the corresponding from-CAGRA generated HNSW index will NOT produce +exactly the same recalls and QPS for the same parameter `ef`. The graphs are different +internally. Depending on the selected heuristics, the CAGRA-produced graph's QPS-Recall curve +may be shifted along the curve right or left. See the heuristics descriptions for more details. + +**Parameters** + +| Name | Description | +| --- | --- | +| `rows` | The number of rows in the input dataset | +| `dim` | The number of dimensions in the input dataset | +| `m` | HNSW index parameter M | +| `efConstruction` | HNSW index parameter ef_construction | +| `heuristic` | The heuristic to use for selecting the graph build parameters | +| `metric` | The distance metric to search | + +**Returns** + +A new CAGRA index parameters object + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/spi/CuVSProvider.java:215`_ + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/spi/CuVSProvider.java:15`_ diff --git a/fern/pages/java_api/java-api-com-nvidia-cuvs-spi-cuvsserviceprovider.md b/fern/pages/java_api/java-api-com-nvidia-cuvs-spi-cuvsserviceprovider.md new file mode 100644 index 0000000000..ac032739d0 --- /dev/null +++ b/fern/pages/java_api/java-api-com-nvidia-cuvs-spi-cuvsserviceprovider.md @@ -0,0 +1,37 @@ +--- +slug: api-reference/java-api-com-nvidia-cuvs-spi-cuvsserviceprovider +--- + +# CuVSServiceProvider + +_Java package: `com.nvidia.cuvs.spi`_ + +```java +public abstract class CuVSServiceProvider +``` + +Service-provider class for \{@linkplain CuVSProvider\}. + +## Public Members + +### get + +```java +public abstract CuVSProvider get(CuVSProvider builtinProvider) +``` + +Initialize and return an `CuVSProvider` provided by this provider. + +**Parameters** + +| Name | Description | +| --- | --- | +| `builtinProvider` | the built-in provider. | + +**Returns** + +the CuVSProvider provided by this provider + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/spi/CuVSServiceProvider.java:22`_ + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/spi/CuVSServiceProvider.java:16`_ diff --git a/fern/pages/java_api/java-api-com-nvidia-cuvs-synchronizedcuvsresources.md b/fern/pages/java_api/java-api-com-nvidia-cuvs-synchronizedcuvsresources.md new file mode 100644 index 0000000000..718651bc0f --- /dev/null +++ b/fern/pages/java_api/java-api-com-nvidia-cuvs-synchronizedcuvsresources.md @@ -0,0 +1,15 @@ +--- +slug: api-reference/java-api-com-nvidia-cuvs-synchronizedcuvsresources +--- + +# SynchronizedCuVSResources + +_Java package: `com.nvidia.cuvs`_ + +```java +public class SynchronizedCuVSResources implements CuVSResources +``` + +A decorator for CuVSResources that guarantees synchronized (blocking) access to the wrapped CuVSResource + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/SynchronizedCuVSResources.java:13`_ diff --git a/fern/pages/java_api/java-api-com-nvidia-cuvs-tieredindex.md b/fern/pages/java_api/java-api-com-nvidia-cuvs-tieredindex.md new file mode 100644 index 0000000000..ae36870257 --- /dev/null +++ b/fern/pages/java_api/java-api-com-nvidia-cuvs-tieredindex.md @@ -0,0 +1,312 @@ +--- +slug: api-reference/java-api-com-nvidia-cuvs-tieredindex +--- + +# TieredIndex + +_Java package: `com.nvidia.cuvs`_ + +```java +public interface TieredIndex extends AutoCloseable +``` + +`TieredIndex` encapsulates a Tiered index, along with methods to +interact with it. + +## Public Members + +### close + +```java +@Override void close() throws Exception +``` + +Destroys the underlying native TieredIndex object and releases associated +resources. + +**Throws** + +| Type | Description | +| --- | --- | +| `Exception` | if an error occurs during index destruction | + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/TieredIndex.java:22`_ + +### search + +```java +SearchResults search(TieredIndexQuery query) throws Throwable +``` + +Searches the index with the specified query and search parameters. + +**Parameters** + +| Name | Description | +| --- | --- | +| `query` | An instance of `TieredIndexQuery` describing the queries and search parameters | + +**Returns** + +An instance of `SearchResults` containing the k-nearest neighbors and their distances for each query + +**Throws** + +| Type | Description | +| --- | --- | +| `Throwable` | if an error occurs during the search operation | + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/TieredIndex.java:34`_ + +### getIndexType + +```java +TieredIndexType getIndexType() +``` + +Returns the algorithm type backing this TieredIndex. + +**Returns** + +The `TieredIndexType` indicating the underlying algorithm (e.g., CAGRA) + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/TieredIndex.java:42`_ + +### getCuVSResources + +```java +CuVSResources getCuVSResources() +``` + +Returns the resources handle associated with this TieredIndex. + +**Returns** + +The `CuVSResources` instance used by this index + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/TieredIndex.java:49`_ + +### newBuilder + +```java +static Builder newBuilder(CuVSResources cuvsResources) +``` + +Creates a new Builder with an instance of `CuVSResources`. + +**Parameters** + +| Name | Description | +| --- | --- | +| `cuvsResources` | An instance of `CuVSResources` | + +**Returns** + +A new `Builder` instance for constructing a TieredIndex + +**Throws** + +| Type | Description | +| --- | --- | +| `NullPointerException` | if cuvsResources is null | + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/TieredIndex.java:58`_ + +### extend + +```java +ExtendBuilder extend() +``` + +Returns an ExtendBuilder to add new data to the existing index. + +**Returns** + +An `ExtendBuilder` instance for extending the index + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/TieredIndex.java:68`_ + +### from + +```java +Builder from(InputStream inputStream) +``` + +**Parameters** + +| Name | Description | +| --- | --- | +| `inputStream` | The input stream containing serialized index data | + +**Returns** + +This Builder instance for method chaining + +**Throws** + +| Type | Description | +| --- | --- | +| `UnsupportedOperationException` | as deserialization is not yet supported | + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/TieredIndex.java:82`_ + +### withDataset + +```java +Builder withDataset(float[][] vectors) +``` + +Sets the dataset vectors for building the TieredIndex. + +**Parameters** + +| Name | Description | +| --- | --- | +| `vectors` | A two-dimensional float array containing the dataset vectors [n_vectors, dimensions] | + +**Returns** + +This Builder instance for method chaining + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/TieredIndex.java:91`_ + +### withDataset + +```java +Builder withDataset(CuVSMatrix dataset) +``` + +Sets the dataset for building the TieredIndex. + +**Parameters** + +| Name | Description | +| --- | --- | +| `dataset` | A `CuVSMatrix` instance containing the vectors | + +**Returns** + +This Builder instance for method chaining + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/TieredIndex.java:99`_ + +### withIndexParams + +```java +Builder withIndexParams(TieredIndexParams params) +``` + +Registers TieredIndex parameters with this Builder. + +**Parameters** + +| Name | Description | +| --- | --- | +| `params` | An instance of `TieredIndexParams` containing the index configuration | + +**Returns** + +This Builder instance for method chaining + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/TieredIndex.java:108`_ + +### withIndexType + +```java +Builder withIndexType(TieredIndexType indexType) +``` + +Sets the index type for the TieredIndex. + +**Parameters** + +| Name | Description | +| --- | --- | +| `indexType` | The `TieredIndexType` to use (currently only CAGRA is supported) | + +**Returns** + +This Builder instance for method chaining + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/TieredIndex.java:117`_ + +### build + +```java +TieredIndex build() throws Throwable +``` + +Builds and returns an instance of TieredIndex with the configured +parameters. + +**Returns** + +A new `TieredIndex` instance + +**Throws** + +| Type | Description | +| --- | --- | +| `Throwable` | if an error occurs during index construction | +| `IllegalArgumentException` | if both vectors and dataset are provided, or if required parameters are missing | + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/TieredIndex.java:129`_ + +### withDataset + +```java +ExtendBuilder withDataset(float[][] vectors) +``` + +Sets the vectors to add to the existing index. + +**Parameters** + +| Name | Description | +| --- | --- | +| `vectors` | A two-dimensional float array containing the new vectors to add [n_new_vectors, dimensions] | + +**Returns** + +This ExtendBuilder instance for method chaining + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/TieredIndex.java:152`_ + +### withDataset + +```java +ExtendBuilder withDataset(CuVSMatrix dataset) +``` + +Sets the dataset to add to the existing index. + +**Parameters** + +| Name | Description | +| --- | --- | +| `dataset` | A `CuVSMatrix` instance containing the new vectors to add | + +**Returns** + +This ExtendBuilder instance for method chaining + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/TieredIndex.java:161`_ + +### execute + +```java +void execute() throws Throwable +``` + +Executes the extend operation, adding the specified data to the index. + +**Throws** + +| Type | Description | +| --- | --- | +| `Throwable` | if an error occurs during the extend operation | +| `IllegalArgumentException` | if both vectors and dataset are provided, or if no data is provided | + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/TieredIndex.java:171`_ + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/TieredIndex.java:15`_ diff --git a/fern/pages/java_api/java-api-com-nvidia-cuvs-tieredindexparams.md b/fern/pages/java_api/java-api-com-nvidia-cuvs-tieredindexparams.md new file mode 100644 index 0000000000..86e0362450 --- /dev/null +++ b/fern/pages/java_api/java-api-com-nvidia-cuvs-tieredindexparams.md @@ -0,0 +1,233 @@ +--- +slug: api-reference/java-api-com-nvidia-cuvs-tieredindexparams +--- + +# TieredIndexParams + +_Java package: `com.nvidia.cuvs`_ + +```java +public final class TieredIndexParams +``` + +Configuration parameters for building a `TieredIndex`. +Only CAGRA is currently supported as the underlying ANN algorithm. + +## Public Members + +### product + +```java +L2, /** Inner product (cosine similarity) distance metric */ INNER_PRODUCT } private final Metric metric +``` + +L2 (Euclidean) distance metric + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/TieredIndexParams.java:20`_ + +### TieredIndexParams + +```java +private TieredIndexParams(Builder builder) +``` + +Private constructor used by the Builder. + +**Parameters** + +| Name | Description | +| --- | --- | +| `builder` | The Builder instance containing the configuration | + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/TieredIndexParams.java:35`_ + +### getMetric + +```java +public Metric getMetric() +``` + +Returns the distance metric used for similarity computation. + +**Returns** + +The `Metric` (L2 or Inner Product) + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/TieredIndexParams.java:47`_ + +### getMinAnnRows + +```java +public int getMinAnnRows() +``` + +Returns the minimum number of rows required to use the ANN algorithm. + +**Returns** + +The minimum row count threshold for ANN algorithm usage + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/TieredIndexParams.java:56`_ + +### isCreateAnnIndexOnExtend + +```java +public boolean isCreateAnnIndexOnExtend() +``` + +Returns whether to create an ANN index when extending the dataset. + +**Returns** + +true if ANN index should be created on extend, false otherwise + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/TieredIndexParams.java:65`_ + +### getCagraParams + +```java +public CagraIndexParams getCagraParams() +``` + +Returns the CAGRA-specific parameters for the ANN algorithm. + +**Returns** + +The `CagraIndexParams` configuration, or null if not using CAGRA + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/TieredIndexParams.java:75`_ + +### newBuilder + +```java +public static Builder newBuilder() +``` + +Creates a new Builder for constructing TieredIndexParams. + +**Returns** + +A new Builder instance + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/TieredIndexParams.java:84`_ + +### metric + +```java +public Builder metric(Metric metric) +``` + +Sets the distance metric for similarity computation. + +**Parameters** + +| Name | Description | +| --- | --- | +| `metric` | The `Metric` to use (L2 or Inner Product) | + +**Returns** + +This Builder instance for method chaining + +**Throws** + +| Type | Description | +| --- | --- | +| `NullPointerException` | if metric is null | + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/TieredIndexParams.java:104`_ + +### minAnnRows + +```java +public Builder minAnnRows(int minAnnRows) +``` + +Sets the minimum number of rows required to use the ANN algorithm. + +**Parameters** + +| Name | Description | +| --- | --- | +| `minAnnRows` | The minimum row count threshold (must be positive) | + +**Returns** + +This Builder instance for method chaining + +**Throws** + +| Type | Description | +| --- | --- | +| `IllegalArgumentException` | if minAnnRows is not positive | + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/TieredIndexParams.java:116`_ + +### createAnnIndexOnExtend + +```java +public Builder createAnnIndexOnExtend(boolean val) +``` + +Sets whether to create an ANN index when extending the dataset. + +**Parameters** + +| Name | Description | +| --- | --- | +| `val` | true to create ANN index on extend, false otherwise | + +**Returns** + +This Builder instance for method chaining + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/TieredIndexParams.java:130`_ + +### withCagraParams + +```java +public Builder withCagraParams(CagraIndexParams params) +``` + +Sets the CAGRA-specific parameters for the ANN algorithm. + +**Parameters** + +| Name | Description | +| --- | --- | +| `params` | The `CagraIndexParams` configuration for CAGRA algorithm | + +**Returns** + +This Builder instance for method chaining + +**Throws** + +| Type | Description | +| --- | --- | +| `NullPointerException` | if params is null | + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/TieredIndexParams.java:143`_ + +### build + +```java +public TieredIndexParams build() +``` + +Builds and returns a `TieredIndexParams` instance with the +configured parameters. + +**Returns** + +A new TieredIndexParams instance + +**Throws** + +| Type | Description | +| --- | --- | +| `IllegalStateException` | if CAGRA params are required but not provided | + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/TieredIndexParams.java:156`_ + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/TieredIndexParams.java:14`_ diff --git a/fern/pages/java_api/java-api-com-nvidia-cuvs-tieredindexquery.md b/fern/pages/java_api/java-api-com-nvidia-cuvs-tieredindexquery.md new file mode 100644 index 0000000000..42be99ccda --- /dev/null +++ b/fern/pages/java_api/java-api-com-nvidia-cuvs-tieredindexquery.md @@ -0,0 +1,315 @@ +--- +slug: api-reference/java-api-com-nvidia-cuvs-tieredindexquery +--- + +# TieredIndexQuery + +_Java package: `com.nvidia.cuvs`_ + +```java +public class TieredIndexQuery +``` + +TieredIndexQuery holds the search parameters and query vectors to be used +while invoking search. Currently only supports CAGRA index type. + +Thread Safety: Each TieredIndexQuery instance should use its own +CuVSResources object that is not shared with other threads. Sharing CuVSResources +between threads can lead to memory allocation errors or JVM crashes. + +## Public Members + +### getIndexType + +```java +public TieredIndexType getIndexType() +``` + +Gets the index type for this query. + +**Returns** + +the TieredIndexType + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/TieredIndexQuery.java:57`_ + +### getCagraSearchParameters + +```java +public CagraSearchParams getCagraSearchParameters() +``` + +Gets the instance of CagraSearchParams initially set. + +**Returns** + +an instance CagraSearchParams + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/TieredIndexQuery.java:66`_ + +### getQueryVectors + +```java +public float[][] getQueryVectors() +``` + +Gets the query vector 2D float array. + +**Returns** + +2D float array + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/TieredIndexQuery.java:75`_ + +### getMapping + +```java +public List getMapping() +``` + +Gets the passed map instance. + +**Returns** + +a map of ID mappings + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/TieredIndexQuery.java:84`_ + +### getTopK + +```java +public int getTopK() +``` + +Gets the topK value. + +**Returns** + +the topK value + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/TieredIndexQuery.java:93`_ + +### getPrefilter + +```java +public BitSet getPrefilter() +``` + +Gets the prefilter BitSet. + +**Returns** + +a BitSet object representing the prefilter + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/TieredIndexQuery.java:102`_ + +### getNumDocs + +```java +public long getNumDocs() +``` + +Gets the number of documents in this index, as used for prefilter. + +**Returns** + +number of documents as an integer + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/TieredIndexQuery.java:111`_ + +### getResources + +```java +public CuVSResources getResources() +``` + +Gets the CuVSResources instance for this query. + +**Returns** + +the CuVSResources instance + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/TieredIndexQuery.java:120`_ + +### newBuilder + +```java +public static Builder newBuilder(CuVSResources resources) +``` + +Creates a new Builder instance. + +**Parameters** + +| Name | Description | +| --- | --- | +| `resources` | the CuVSResources instance to use for this query | + +**Returns** + +a new Builder instance + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/TieredIndexQuery.java:145`_ + +### Builder + +```java +public Builder(CuVSResources resources) +``` + +Constructor that requires CuVSResources. + +Important: The provided CuVSResources instance should not be +shared with other threads. Each thread performing searches should create its own +CuVSResources instance to avoid memory allocation conflicts and potential JVM crashes. + +**Parameters** + +| Name | Description | +| --- | --- | +| `resources` | the CuVSResources instance to use for this query (must not be shared between threads) | + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/TieredIndexQuery.java:171`_ + +### withIndexType + +```java +public Builder withIndexType(TieredIndexType indexType) +``` + +Sets the index type for this query. + +**Parameters** + +| Name | Description | +| --- | --- | +| `indexType` | the index type | + +**Returns** + +an instance of this Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/TieredIndexQuery.java:181`_ + +### withSearchParams + +```java +public Builder withSearchParams(CagraSearchParams cagraSearchParams) +``` + +Sets the instance of configured CagraSearchParams to be passed for search. + +**Parameters** + +| Name | Description | +| --- | --- | +| `cagraSearchParams` | an instance of the configured CagraSearchParams to be used for this query | + +**Returns** + +an instance of this Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/TieredIndexQuery.java:193`_ + +### withQueryVectors + +```java +public Builder withQueryVectors(float[][] queryVectors) +``` + +Registers the query vectors to be passed in the search call. + +**Parameters** + +| Name | Description | +| --- | --- | +| `queryVectors` | 2D float query vector array | + +**Returns** + +an instance of this Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/TieredIndexQuery.java:204`_ + +### withMapping + +```java +public Builder withMapping(List mapping) +``` + +Sets the instance of mapping to be used for ID mapping. + +**Parameters** + +| Name | Description | +| --- | --- | +| `mapping` | the ID mapping instance | + +**Returns** + +an instance of this Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/TieredIndexQuery.java:215`_ + +### withTopK + +```java +public Builder withTopK(int topK) +``` + +Registers the topK value. + +**Parameters** + +| Name | Description | +| --- | --- | +| `topK` | the topK value used to retrieve the topK results | + +**Returns** + +an instance of this Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/TieredIndexQuery.java:226`_ + +### withPrefilter + +```java +public Builder withPrefilter(BitSet prefilter, int numDocs) +``` + +Sets a BitSet to use as prefilter while searching. + +**Parameters** + +| Name | Description | +| --- | --- | +| `prefilter` | the BitSet to use as prefilter | +| `numDocs` | Total number of dataset vectors; used to align the prefilter correctly | + +**Returns** + +an instance of this Builder + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/TieredIndexQuery.java:239`_ + +### build + +```java +public TieredIndexQuery build() +``` + +Builds an instance of TieredIndexQuery. + +**Returns** + +an instance of TieredIndexQuery + +**Throws** + +| Type | Description | +| --- | --- | +| `IllegalStateException` | if required parameters are missing | + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/TieredIndexQuery.java:251`_ + +_Source: `java/cuvs-java/src/main/java/com/nvidia/cuvs/TieredIndexQuery.java:23`_ diff --git a/docs/source/jit_lto_guide.md b/fern/pages/jit_lto_guide.md similarity index 99% rename from docs/source/jit_lto_guide.md rename to fern/pages/jit_lto_guide.md index 490bec5914..e6cb2e3f09 100644 --- a/docs/source/jit_lto_guide.md +++ b/fern/pages/jit_lto_guide.md @@ -473,7 +473,7 @@ extern "C" __global__ void search_kernel( } // namespace example::detail ``` -**Note**: The kernel uses generic function templates (`compute_distance` and `apply_filter`) that are resolved at link time. The specific implementations (euclidean vs inner_product, filter_none vs filter_bitset) are provided by the fragments that get linked together. +**Note**: The kernel uses generic function templates (`compute_distance<T>` and `apply_filter<IdxT>`) that are resolved at link time. The specific implementations (euclidean vs inner_product, filter_none vs filter_bitset) are provided by the fragments that get linked together. ### Step 5: Create `.cpp.in` Template Files for Embedding diff --git a/docs/source/neighbors/all_neighbors.rst b/fern/pages/neighbors/all_neighbors.md similarity index 89% rename from docs/source/neighbors/all_neighbors.rst rename to fern/pages/neighbors/all_neighbors.md index a70414fe06..4e5d77da2e 100644 --- a/docs/source/neighbors/all_neighbors.rst +++ b/fern/pages/neighbors/all_neighbors.md @@ -1,5 +1,4 @@ -All-neighbors -============= +# All-neighbors All-neighbors is a specialized algorithm for building approximate all-neighbors k-NN graphs. Unlike traditional nearest neighbor indexes that are designed for searching, all-neighbors focuses on constructing complete k-NN graphs for entire datasets. @@ -16,15 +15,14 @@ All-neighbors supports multiple underlying algorithms: The algorithm partitions the dataset into clusters and distributes the work across multiple GPUs when possible, making it suitable for large-scale graph construction tasks. -[ :doc:`C API <../c_api/neighbors_all_neighbors_c>` | :doc:`C++ API <../cpp_api/neighbors_all_neighbors>` | :doc:`Python API <../python_api/neighbors_all_neighbors>` ] +[C API](/api-reference/c-api-neighbors-all-neighbors) | [C++ API](/api-reference/cpp-api-neighbors-all-neighbors) | [Python API](/api-reference/python-api-neighbors-all-neighbors) -Algorithm Overview ------------------- +## Algorithm Overview All-neighbors works by: 1. **Partitioning**: Dividing the dataset into `n_clusters` clusters/batches -2. **Assignment**: Assigning each point to `overlap_factor` clusters (must be < n_clusters) +2. **Assignment**: Assigning each point to `overlap_factor` clusters (must be < n_clusters) 3. **Local Computation**: Building k-NN graphs within each cluster using the specified algorithm 4. **Aggregation**: Combining results from all clusters to form the complete graph @@ -33,8 +31,7 @@ This approach enables: - **Memory Efficiency**: Processing large datasets that don't fit in single GPU memory - **Flexibility**: Choice of underlying algorithm based on accuracy vs. speed requirements -Use Cases ---------- +## Use Cases **Data Mining and Machine Learning** - Clustering algorithms (K-means, HDBSCAN) @@ -51,8 +48,7 @@ Use Cases - Batch processing for distributed computing environments - Building graphs for graph databases and analytics -Parameters ----------- +## Parameters - **algo**: Underlying algorithm (brute_force, ivf_pq, nn_descent) - **overlap_factor**: Number of clusters each point is assigned to @@ -60,8 +56,7 @@ Parameters - **metric**: Distance metric for graph construction - **algorithm-specific parameters**: IVF-PQ or NN-Descent specific settings -Performance Characteristics ---------------------------- +## Performance Characteristics - **Build Time**: Scales with dataset size and chosen algorithm - **Memory Usage**: Depends on cluster size and overlap factor diff --git a/docs/source/neighbors/bruteforce.rst b/fern/pages/neighbors/bruteforce.md similarity index 69% rename from docs/source/neighbors/bruteforce.rst rename to fern/pages/neighbors/bruteforce.md index 3dc1155073..fc40d09873 100644 --- a/docs/source/neighbors/bruteforce.rst +++ b/fern/pages/neighbors/bruteforce.md @@ -1,9 +1,8 @@ -Brute-force -=========== +# Brute-force Brute-force, or flat index, is the most simple index type, as it ultimately boils down to an exhaustive matrix multiplication. -While it scales with :math:`O(N^2*D)`, brute-force can be a great choice when +While it scales with $O(N^2*D)$, brute-force can be a great choice when 1. exact nearest neighbors are required, and 2. when the number of vectors is relatively small (a few thousand to a few million) @@ -12,10 +11,9 @@ Brute-force can also be a good choice for heavily filtered queries where other a when filtering out 90%-95% of the vectors from a search, the IVF methods could struggle to return anything at all with smaller number of probes and graph-based algorithms with limited hash table memory could end up skipping over important unfiltered entries. -[ :doc:`C API <../c_api/neighbors_bruteforce_c>` | :doc:`C++ API <../cpp_api/neighbors_bruteforce>` | :doc:`Python API <../python_api/neighbors_brute_force>` | :doc:`Rust API <../rust_api/index>` ] +[C API](/api-reference/c-api-neighbors-brute-force) | [C++ API](/api-reference/cpp-api-neighbors-brute-force) | [Python API](/api-reference/python-api-neighbors-brute-force) | [Rust API](/api-reference/rust-api-documentation) -Filtering considerations ------------------------- +## Filtering considerations Because it is exhaustive, brute-force can quickly become the slowest, albeit most accurate form of search. However, even when the number of vectors in an index are very large, brute-force can still be used to search vectors efficiently with a filter. @@ -25,38 +23,29 @@ inherent in other approximate algorithms would simply not include expected vecto brute-force, the computation is inverted so distances are only computed between vectors that pass the filter, significantly reducing the amount of computation required. -Configuration parameters ------------------------- +## Configuration parameters -Build parameters -~~~~~~~~~~~~~~~~ +### Build parameters None -Search Parameters -~~~~~~~~~~~~~~~~~ +### Search Parameters None - -Tuning Considerations ---------------------- +## Tuning Considerations Brute-force is exact but that doesn't always mean it's deterministic. For example, when there are many nearest neighbors with the same distances it's possible they might be ordered differently across different runs. This especially becomes apparent in cases where there are points with the same distance right near the cutoff of `k`, which can cause the final list of neighbors to differ from ground truth. This is not often a problem in practice and can usually be mitigated by increasing `k`. +## Memory footprint -Memory footprint ----------------- - -:math:`precision` is the number of bytes in each element of each vector (e.g. 32-bit = 4-bytes) - +$precision$ is the number of bytes in each element of each vector (e.g. 32-bit = 4-bytes) -Index footprint -~~~~~~~~~~~~~~~ +### Index footprint -Raw vectors: :math:`n\_vectors * n\_dimensions * precision` +Raw vectors: $n\_vectors * n\_dimensions * precision$ -Vector norms (for distances which require them): :math:`n\_vectors * precision` +Vector norms (for distances which require them): $n\_vectors * precision$ diff --git a/fern/pages/neighbors/cagra.md b/fern/pages/neighbors/cagra.md new file mode 100644 index 0000000000..a641037903 --- /dev/null +++ b/fern/pages/neighbors/cagra.md @@ -0,0 +1,224 @@ +# CAGRA + +CAGRA, or (C)UDA (A)NN (GRA)ph-based, is a graph-based index that is based loosely on the popular navigable small-world graph (NSG) algorithm, but which has been +built from the ground-up specifically for the GPU. CAGRA constructs a flat graph representation by first building a kNN graph +of the training points and then removing redundant paths between neighbors. + +The CAGRA algorithm has two basic steps- +* 1. Construct a kNN graph +* 2. Prune redundant routes from the kNN graph. + +I-force could be used to construct the initial kNN graph. This would yield the most accurate graph but would be very slow and +we find that in practice the kNN graph does not need to be very accurate since the pruning step helps to boost the overall recall of +the index. cuVS provides IVF-PQ and NN-Descent strategies for building the initial kNN graph and these can be selected in index params object during index construction. + +[C API](/api-reference/c-api-neighbors-cagra) | [C++ API](/api-reference/cpp-api-neighbors-cagra) | [Python API](/api-reference/python-api-neighbors-cagra) | [Rust API](/api-reference/rust-api-documentation) + +## Interoperability with HNSW + +cuVS provides the capability to convert a CAGRA graph to an HNSW graph, which enables the GPU to be used only for building the index +while the CPU can be leveraged for search. + +## Filtering considerations + +CAGRA supports filtered search and has improved multi-CTA algorithm in branch-25.02 to provide reasonable recall and performance for filtering rate as high as 90% or more. + +To obtain an appropriate recall in filtered search, it is necessary to set search parameters according to the filtering rate, but since it is difficult for users to do this, CAGRA automatically adjusts `itopk_size` internally according to the filtering rate on a heuristic basis. If you want to disable this automatic adjustment, set `filtering_rate`, one of the search parameters, to `0.0`, and `itopk_size` will not be adjusted automatically. + +## Configuration parameters + +### Build parameters + +| Name | Default | Description | +| --- | --- | --- | +| compression | None | For large datasets, the raw vectors can be compressed using product quantization so they can be placed on device. This comes at the cost of lowering recall, though a refinement reranking step can be used to make up the lost recall after search. | +| graph_build_algo | 'IVF_PQ' | The graph build algorithm to use for building | +| graph_build_params | None | Specify explicit build parameters for the corresponding graph build algorithms | +| graph_degree | 32 | The degree of the final CAGRA graph. All vertices in the graph will have this degree. During search, a larger graph degree allows for more exploration of the search space and improves recall but at the expense of searching more vertices. | +| intermediate_graph_degree | 64 | The degree of the initial knn graph before it is optimized into the final CAGRA graph. A larger value increases connectivity of the initial graph so that it performs better once pruned. Larger values come at the cost of increased device memory usage and increases the time of initial knn graph construction. | +| guarantee_connectivity | False | Uses a degree-constrained minimum spanning tree to guarantee the initial knn graph is connected. This can improve recall on some datasets. | +| attach_data_on_build | True | Should the dataset be attached to the index after the index is built? Setting this to `False` can improve memory usage and performance, for example if the graph is being serialized to disk or converted to HNSW right after building it. | + +### Search parameters + +| Name | Default | Description | +| --- | --- | --- | +| itopk_size | 64 | Number of intermediate search results retained during search. This value needs to be >=k. This is the main knob to tweak search performance. | +| max_iterations | 0 | The maximum number of iterations during search. Default is to auto-select. | +| max_queries | 0 | Max number of search queries to perform concurrently (batch size). Default is to auto-select. | +| team_size | 0 | Number of CUDA threads for calculating each distance. Can be 4, 8, 16, or 32. Default is to auto-select. | +| search_width | 1 | Number of vertices to select as the starting point for the search in each iteration. | +| min_iterations | 0 | Minimum number of search iterations to perform | + +## Tuning Considerations + +The 3 hyper-parameters that are most often tuned are `graph_degree`, `intermediate_graph_degree`, and `itopk_size`. + +# Memory footprint + +CAGRA builds a nearest-neighbor graph (stored on host) while keeping the original dataset vectors around. During index build, the dataset must reside in device (GPU) memory. After building, the dataset can optionally be detached from the index — for example, when immediately converting the CAGRA graph to a CPU-based format like HNSW for search. + +## Baseline Memory Footprint + +The baseline memory footprint after index construction: + +$$ +\text\\\\\\\\{dataset_size (device)\\\\\\\\} +\;=\; +\text\\\\\\\\{number_vectors\\\\\\\\} \times \text\\\\\\\\{vector_dimension\\\\\\\\} \times \text\\\\\\\\{bytes_per_dimension\\\\\\\\} +$$ + +$$ +\text\\\\\\\\{graph_size (host)\\\\\\\\} +\;=\; +\text\\\\\\\\{number_vectors\\\\\\\\} \times \text\\\\\\\\{graph_degree\\\\\\\\} \times \operatorname\\\\\\\\{sizeof\\\\\\\\}\!\big(\mathrm\\\\\\\\{IdxT\\\\\\\\}\big) +$$ + +Note: The dataset must be in GPU memory during index build, but can be detached afterward if not needed for search. + +**Example** (1,000,000 vectors, dim = 1024, fp32, graph\_degree = 64, IdxT = int32): + +- dataset\_size = 4,096,000,000 B = 3906.25 MB +- graph\_size = 256,000,000 B = 244.14 MB + +## Build peak memory usage + +Index build has two phases: (1) construct a knn graph, then (2) optimize it to remove redundant and unnecessary paths. +The initial knn graph can be built with IVF-PQ or nn-descent. IVF-PQ has the additional benefit that it supports out-of-core construction, allowing CAGRA to be trained on datasets larger than available GPU memory. +The steps below are sequential with distinct peak memory consumption. The overall peak memory utilization depends on the configured RMM memory resource. + +### knn graph build phase using IVF-PQ + +The knn graph can be constructed using the IVF-PQ algorithm, which works in two stages: first, an IVF-PQ index is trained on a subset of vectors to learn cluster centroids; then, the full dataset is queried against this index in batches to find approximate nearest neighbors for each vector. + +**IVF-PQ Build (centroid training)** — uses a training subset to compute cluster centroids and PQ codebooks. + +$$ +\text\\\\\\\\{IVFPQ_build_peak\\\\\\\\} +\;=\; +\frac\\\\\\\\{n_\\\\\\\\{\text\\\\\\\\{vectors\\\\\\\\}\\\\\\\\}\\\\\\\\}\\\\\\\\{\text\\\\\\\\{train_set_ratio\\\\\\\\}\\\\\\\\} \times \text\\\\\\\\{dim\\\\\\\\} \times 4 +\;+\; +n_\\\\\\\\{\text\\\\\\\\{clusters\\\\\\\\}\\\\\\\\} \times \text\\\\\\\\{dim\\\\\\\\} \times 4 +\;+\; +\frac\\\\\\\\{n_\\\\\\\\{\text\\\\\\\\{vectors\\\\\\\\}\\\\\\\\}\\\\\\\\}\\\\\\\\{\text\\\\\\\\{train_set_ratio\\\\\\\\}\\\\\\\\} \times \operatorname\\\\\\\\{sizeof\\\\\\\\}(\mathrm\\\\\\\\{uint32\_t\\\\\\\\}) +$$ + +**Example** (n = 1e6; dim = 1024; n\_clusters = 1024; train\_set\_ratio = 10): 395.01 MB + +**IVF-PQ Search (forms the intermediate graph)** — Constructs the knn graph in batches by querying the IVF-PQ index for the nearest neighbors of all training points. + +$$ +\text\\\\\\\\{IVFPQ_search_peak\\\\\\\\} +\;=\; +\text\\\\\\\\{batch_size\\\\\\\\} \times \text\\\\\\\\{dim\\\\\\\\} \times 4 +\;+\; +\text\\\\\\\\{batch_size\\\\\\\\} \times \text\\\\\\\\{intermediate_degree\\\\\\\\} \times \operatorname\\\\\\\\{sizeof\\\\\\\\}(\mathrm\\\\\\\\{uint32\_t\\\\\\\\}) +\;+\; +\text\\\\\\\\{batch_size\\\\\\\\} \times \text\\\\\\\\{intermediate_degree\\\\\\\\} \times 4 +$$ + +**Example** (batch = 1024, dim = 1024, intermediate\_degree = 128): 5.00 MB + +### knn graph build phase using NN-DESCENT + +**Peak device memory:** + +$$ +\text\\\\\\\\{NND_device_peak\\\\\\\\} +\;=\; +n_\text\\\\\\\\{vectors\\\\\\\\} \times (n_\text\\\\\\\\{dims\\\\\\\\} \times 2 + 276) +$$ + +- Data vectors (transferred to device and stored as fp16): $n_\text\\\\\\\\{dims\\\\\\\\} \times 2$ bytes per vector +- Small working graph, locks, edge counters: 276 bytes per vector (fixed) +- Additional $4$ bytes per vector when using L2 metric (for precomputed norms) + +**Peak host memory:** + +$$ +\text\\\\\\\\{NND_host_peak\\\\\\\\} +\;=\; +n_\text\\\\\\\\{vectors\\\\\\\\} \times (13 \times \text\\\\\\\\{intermediate_graph_degree\\\\\\\\} + 912) +$$ + +- Full graph with distances (~1.3x overallocation): $1.3 \times 8 \times \text\\\\\\\\{intermediate_graph_degree\\\\\\\\}$ bytes per vector +- Bloom filter for sampling: $1.3 \times 2 \times \text\\\\\\\\{intermediate_graph_degree\\\\\\\\}$ bytes per vector +- 5 sample buffers (degree 32 each): 640 bytes per vector +- Graph update buffer (degree 32): 256 bytes per vector +- Edge counters: 16 bytes per vector + +### Optimize phase + +Pruning/reordering the intermediate graph; peak scales linearly with intermediate degree. + +$$ +\text\\\\\\\\{optimize_peak\\\\\\\\} +\;=\; +n_\\\\\\\\{\text\\\\\\\\{vectors\\\\\\\\}\\\\\\\\} \times +\Big( 4 + \big(\operatorname\\\\\\\\{sizeof\\\\\\\\}(\mathrm\\\\\\\\{IdxT\\\\\\\\}) + 1\big)\times \text\\\\\\\\{intermediate_degree\\\\\\\\} \Big) +$$ + +**Example** (n = 1e6, intermediate\_degree = 128, IdxT = int32): 614.17 MB +Out-of-core CAGRA build consists of IVF-PQ build, IVF-PQ search, CAGRA optimization. Note that these steps are performed sequentially, so they are not additive. + +### Overall Build Peak Memory Usage + +The overall peak memory footprint on the device is the maximum allocation across each sequential step, since RMM's `device_memory_resource` releases memory between steps. + +**Using IVF-PQ:** + +$$ +\text\\\\\\\\{build_peak\\\\\\\\} +\;=\; +\text\\\\\\\\{dataset_size\\\\\\\\} +\;+\; +\max\!\big(\text\\\\\\\\{IVFPQ_build_peak\\\\\\\\},\ \text\\\\\\\\{IVFPQ_search_peak\\\\\\\\},\ \text\\\\\\\\{optimize_peak\\\\\\\\}\big) +$$ + +**Example:** 3906.25 + max(395.01, 5.00, 614.17) = 4520.42 MB + +**Using NN-Descent:** + +$$ +\text\\\\\\\\{build_peak\\\\\\\\} +\;=\; +\text\\\\\\\\{dataset_size\\\\\\\\}^\\\\\\\\{*\\\\\\\\} +\;+\; +\max\!\big(\text\\\\\\\\{NND_device_peak\\\\\\\\},\ \text\\\\\\\\{optimize_peak\\\\\\\\}\big) +$$ + +$\text\\\\\\\\{dataset_size\\\\\\\\}^\\\\\\\\{*\\\\\\\\}$ applies only when the user passes data residing in device memory; NN-Descent internally copies the dataset to the device as fp16, so host-memory inputs do not add this term. + +## Search peak memory usage + +CAGRA search requires the dataset and graph to already be resident in GPU memory. When using CAGRA-Q (compressed/quantized), the original dataset can reside in host memory instead. Additionally, temporary workspace memory is needed to store the search results for a batch of queries. +If multiple batches are to be launched concurrently or overlapped, separate results buffers will be needed for each. +The below memory estimate assumes just one batch of queries being run at a time and reusing the buffers. + +$$ +\text\\\\\\\\{search_memory\\\\\\\\} +\;=\; +\text\\\\\\\\{dataset_size\\\\\\\\} + \text\\\\\\\\{graph_size\\\\\\\\} + \text\\\\\\\\{workspace_size\\\\\\\\} +$$ + +Where `workspace_size` is the temporary memory used for query vectors and result storage: + +$$ +\text\\\\\\\\{query_size\\\\\\\\} +\;=\; +\text\\\\\\\\{batch_size\\\\\\\\} \times \text\\\\\\\\{dim\\\\\\\\} \times \operatorname\\\\\\\\{sizeof\\\\\\\\}(\mathrm\\\\\\\\{float\\\\\\\\}) +$$ + +$$ +\text\\\\\\\\{result_size\\\\\\\\} +\;=\; +\text\\\\\\\\{batch_size\\\\\\\\} \times \text\\\\\\\\{topk\\\\\\\\} \times +\big(\operatorname\\\\\\\\{sizeof\\\\\\\\}(\mathrm\\\\\\\\{IdxT\\\\\\\\}) + \operatorname\\\\\\\\{sizeof\\\\\\\\}(\mathrm\\\\\\\\{float\\\\\\\\})\big) +$$ + +**Example** (dim = 1024, batch\_size = 100, topk = 10, IdxT = int32): + +- query\_size = 409,600 B = 0.39 MB +- result\_size = 8,000 B = 0.0076 MB +- workspace\_size = query\_size + result\_size = 0.40 MB +- Total search memory ≈ 3906.25 + 244.14 + 0.40 = 4150.79 MB diff --git a/fern/pages/neighbors/ivfflat.md b/fern/pages/neighbors/ivfflat.md new file mode 100644 index 0000000000..5230a2a093 --- /dev/null +++ b/fern/pages/neighbors/ivfflat.md @@ -0,0 +1,77 @@ +# IVF-Flat + +IVF-Flat is an inverted file index (IVF) algorithm, which in the context of nearest neighbors means that data points are +partitioned into clusters. At search time, brute-force is performed only in a (user-defined) subset of the closest clusters. +In practice, this algorithm can search the index much faster than brute-force and often still maintain an acceptable +recall, though this comes with the drawback that the index itself copies the original training vectors into a memory layout +that is optimized for fast memory reads and adds some additional memory storage overheads. Once the index is trained, +this algorithm no longer requires the original raw training vectors. + +IVF-Flat tends to be a great choice when + +1. like brute-force, there is enough device memory available to fit all of the vectors +in the index, and +2. exact recall is not needed. as with the other index types, the tuning parameters are used to trade-off recall for search latency / throughput. + +[C API](/api-reference/c-api-neighbors-ivf-flat) | [C++ API](/api-reference/cpp-api-neighbors-ivf-flat) | [Python API](/api-reference/python-api-neighbors-ivf-flat) | [Rust API](/api-reference/rust-api-documentation) + +## Filtering considerations + +IVF methods only apply filters to the lists which are probed for each query point. As a result, the results of a filtered query will likely differ significantly from the results of a filtering applid to an exact method like brute-force. For example. imagine you have 3 IVF lists each containing 2 vectors and you perform a query against only the closest 2 lists but you filter out all but 1 element. If that remaining element happens to be in one of the lists which was not proved, it will not be considered at all in the search results. It's important to consider this when using any of the IVF methods in your applications. + +## Configuration parameters + +### Build parameters + +| Name | Default | Description | +| --- | --- | --- | +| n_lists | sqrt(n) | Number of coarse clusters used to partition the index. A good heuristic for this value is sqrt(n_vectors_in_index) | +| add_data_on_build | True | Should the training points be added to the index after the index is built? | +| kmeans_train_iters | 20 | Max number of iterations for k-means training before convergence is assumed. Note that convergence could happen before this number of iterations. | +| kmeans_trainset_fraction | 0.5 | Fraction of points that should be subsampled from the original dataset to train the k-means clusters. Default is 1/2 the training dataset. This can often be reduced for very large datasets to improve both cluster quality and the build time. | +| adaptive_centers | false | Should the existing trained centroids adapt to new points that are added to the index? This provides a trade-off between improving recall at the expense of having to compute new centroids for clusters when new points are added. When points are added in large batches, the performance cost may not be noticeable. | +| conservative_memory_allocation | false | To support dynamic indexes, where points are expected to be added later, the individual IVF lists can be imtentionally overallocated up front to reduce the amount and impact of increasing list sizes, which requires allocating more memory and copying the old list to the new, larger, list. | + +### Search parameters + +| Name | Default | Description | +| --- | --- | --- | +| n_probes | 20 | Number of closest IVF lists to scan for each query point. | + +## Tuning Considerations + +Since IVF methods use clustering to establish spatial locality and partition data points into individual lists, there's an inherent +assumption that the number of lists, and thus the max size of the data in the index is known up front. For some use-cases, this +might not matter. For example, most vector databases build many smaller physical approximate nearest neighbors indexes, each from +fixed-size or maximum-sized immutable segments and so the number of lists can be tuned based on the number of vectors in the indexes. + +Empirically, we've found $\sqrt\\\\\\\\{n\_index\_vectors\\\\\\\\}$ to be a good starting point for the $n\_lists$ hyper-parameter. Remember, having more +lists means less points to search within each list, but it could also mean more $n\_probes$ are needed at search time to reach an acceptable +recall. + +## Memory footprint + +Each cluster is padded to at least 32 vectors (but potentially up to 1024). Assuming uniform random distribution of vectors/list, we would have +$cluster\_overhead = (conservative\_memory\_allocation ? 16 : 512 ) * dim * sizeof_\\\\\\\\{float\\\\\\\\}$ + +Note that each cluster is allocated as a separate allocation. If we use a `cuda_memory_resource`, that would grab memory in 1 MiB chunks, so on average we might have 0.5 MiB overhead per cluster. If we us 10s of thousands of clusters, it becomes essential to use pool allocator to avoid this overhead. + +$cluster\_overhead = 0.5 MiB$ // if we do not use pool allocator + +### Index (device memory): + +$$ +n\_vectors * n\_dimensions * sizeof(T) + + +n\_vectors * sizeof(int_type) + + +n\_clusters * n\_dimensions * sizeof(T) + + +n\_clusters * cluster_overhead` +$$ + +### Peak device memory usage for index build: + +$workspace = min(1GB, n\_queries * [(n\_lists + 1 + n\_probes * (k + 1)) * sizeof_\\\\\\\\{float\\\\\\\\} + n\_probes * k * sizeof_\\\\\\\\{idx\\\\\\\\}])$ + +$index\_size + workspace$ diff --git a/fern/pages/neighbors/ivfpq.md b/fern/pages/neighbors/ivfpq.md new file mode 100644 index 0000000000..61e96aae88 --- /dev/null +++ b/fern/pages/neighbors/ivfpq.md @@ -0,0 +1,85 @@ +# IVF-PQ + +IVF-PQ is an inverted file index (IVF) algorithm, which is an extension to the IVF-Flat algorithm (e.g. data points are first +partitioned into clusters) where product quantization is performed within each cluster in order to shrink the memory footprint +of the index. Product quantization is a lossy compression method and it is capable of storing larger number of vectors +on the GPU by offloading the original vectors to main memory, however higher compression levels often lead to reduced recall. +Often a strategy called refinement reranking is employed to make up for the lost recall by querying the IVF-PQ index for a larger +`k` than desired and performing a reordering and reduction to `k` based on the distances from the unquantized vectors. Unfortunately, +this does mean that the unquantized raw vectors need to be available and often this can be done efficiently using multiple CPU threads. + +[C API](/api-reference/c-api-neighbors-ivf-pq) | [C++ API](/api-reference/cpp-api-neighbors-ivf-pq) | [Python API](/api-reference/python-api-neighbors-ivf-pq) | [Rust API](/api-reference/rust-api-documentation) + +## Configuration parameters + +### Build parameters + +| Name | Default | Description | +| --- | --- | --- | +| n_lists | sqrt(n) | Number of coarse clusters used to partition the index. A good heuristic for this value is sqrt(n_vectors_in_index) | +| kmeans_n_iters | 20 | The number of iterations when searching for k-means centers | +| kmeans_trainset_fraction | 0.5 | The fraction of training data to use for iterative k-means building | +| pq_bits | 8 | The bit length of each vector element after compressing with PQ. Possible values are any integer between 4 and 8. | +| pq_dim | 0 | The dimensionality of each vector after compressing with PQ. When 0, the dim is set heuristically. | +| codebook_kind | per_subspace | How codebooks are created. `per_subspace` trains kmeans on some number of sub-dimensions while `per_cluster` | +| force_random_rotation | false | Apply a random rotation matrix on the input data and queries even if `dim % pq_dim == 0` | +| conservative_memory_allocation | false | To support dynamic indexes, where points are expected to be added later, the individual IVF lists can be imtentionally overallocated up front to reduce the amount and impact of increasing list sizes, which requires allocating more memory and copying the old list to the new, larger, list. | +| add_data_on_build | True | Should the training points be added to the index after the index is built? | +| max_train_points_per_pq_code | 256 | The max number of data points to use per PQ code during PQ codebook training. | + +### Search parameters + +| Name | Default | Description | +| --- | --- | --- | +| n_probes | 20 | Number of closest IVF lists to scan for each query point. | +| lut_dtype | cuda_r_32f | Datatype to store the pq lookup tables. Can also use cuda_r_16f for half-precision and cuda_r_8u for 8-bit precision. Smaller lookup tables can fit into shared memory and significantly improve search times. | +| internal_distance_dtype | cuda_r_32f | Storage data type for distance/similarity computed at search time. Can also use cuda_r_16f for half-precision. | +| preferred_smem_carveout | 1.0 | Preferred fraction of SM's unified memory / L1 cache to be used as shared memory. Default is 100% | + +## Tuning Considerations + +IVF-PQ has similar tuning considerations to IVF-flat, though the PQ compression ratio adds an additional variable to trade-off index size for search quality. + +It's important to note that IVF-PQ becomes very lossy very quickly, and so refinement reranking is often needed to get a reasonable recall. This step usually consists of searching initially for more k-neighbors than needed and then reducing the resulting neighborhoods down to k by computing exact distances. This step can be performed efficiently on CPU or GPU and generally has only a marginal impact on search latency. + +## Memory footprint + +### Index (device memory): + +Simple approximate formula: $n\_vectors * (pq\_dim * \frac\\\\\\\\{pq\_bits\\\\\\\\}\\\\\\\\{8\\\\\\\\} + sizeof_\\\\\\\\{idx\\\\\\\\}) + n\_clusters$ + +The IVF lists end up being represented by a sparse data structure that stores the pointers to each list, an indices array that contains the indexes of each vector in each list, and an array with the encoded (and interleaved) data for each list. + +IVF list pointers: $n\_clusters * sizeof_\\\\\\\\{uint32\_t\\\\\\\\}$ + +Indices: $n\_vectors * sizeof_\\\\\\\\{idx\\\\\\\\}$ + +Encoded data (interleaved): $n\_vectors * pq\_dim * \frac\\\\\\\\{pq\_bits\\\\\\\\}\\\\\\\\{8\\\\\\\\}$ + +Per subspace method: $4 * pq\_dim * pq\_len * 2^\\\\\\\\{pq\_bits\\\\\\\\}$ + +Per cluster method: $4 * n\_clusters * pq\_len * 2^\\\\\\\\{pq\_bits\\\\\\\\}$ + +Extras: $n\_clusters * (20 + 8 * dim)$ + +### Index (host memory): + +When refinement is used with the dataset on host, the original raw vectors are needed: $n\_vectors * dims * sizeof_\\\\\\\\{float\\\\\\\\}$ + +### Search peak memory usage (device); + +Total usage: $index + queries + output\_indices + output\_distances + workspace$ + +Workspace size is not trivial, a heuristic controls the batch size to make sure the workspace fits the `raft::resource::get_workspace_free_bytes(res)`. + +### Build peak memory usage (device): + +$$ +\frac\\\\\\\\{n\_vectors\\\\\\\\}\\\\\\\\{trainset\_ratio * dims * sizeof_\\\\\\\\{float\\\\\\\\}\\\\\\\\} + ++ \frac\\\\\\\\{n\_vectors\\\\\\\\}\\\\\\\\{trainset\_ratio * sizeof_\\\\\\\\{uint32\_t\\\\\\\\}\\\\\\\\} + ++ n\_clusters * dim * sizeof_\\\\\\\\{float\\\\\\\\} +$$ + +Note, if there’s not enough space left in the workspace memory resource, IVF-PQ build automatically switches to the managed memory for the training set and labels. diff --git a/fern/pages/neighbors/neighbors.md b/fern/pages/neighbors/neighbors.md new file mode 100644 index 0000000000..0ac4ef0260 --- /dev/null +++ b/fern/pages/neighbors/neighbors.md @@ -0,0 +1,10 @@ +# Nearest Neighbor + +## Pages + +- [Brute-force](bruteforce.md) +- [CAGRA](cagra.md) +- [IVF-Flat](ivfflat.md) +- [IVF-PQ](ivfpq.md) +- [Vamana](vamana.md) +- [All-neighbors](all_neighbors.md) diff --git a/fern/pages/neighbors/vamana.md b/fern/pages/neighbors/vamana.md new file mode 100644 index 0000000000..fbdb30c5a9 --- /dev/null +++ b/fern/pages/neighbors/vamana.md @@ -0,0 +1,49 @@ +# Vamana + +VAMANA is the underlying graph construction algorithm used to construct indexes for the DiskANN vector search solution. DiskANN and the Vamana algorithm are described in detail in the [published paper](https://papers.nips.cc/paper/9527-rand-nsg-fast-accurate-billion-point-nearest-neighbor-search-on-a-single-node.pdf), and a highly optimized [open-source repository](https://github.com/microsoft/DiskANN) includes many features for index construction and search. In cuVS, we provide a version of the Vamana algorithm optimized for GPU architectures to accelreate graph construction to build DiskANN idnexes. At a high level, the Vamana algorithm operates as follows: + +* 1. Starting with an empty graph, select a medoid vector from the D-dimension vector dataset and insert it into the graph. +* 2. Iteratively insert batches of dataset vectors into the graph, connecting each inserted vector to neighbors based on a graph traversal. +* 3. For each batch, create reverse edges and prune unnecessary edges. + +There are many algorithmic details that are outlined in the [paper](https://papers.nips.cc/paper/9527-rand-nsg-fast-accurate-billion-point-nearest-neighbor-search-on-a-single-node.pdf), and many GPU-specific optimizations are included in this implementation. + +The current implementation of DiskANN in cuVS only includes the 'in-memory' graph construction and a serialization step that writes the index to a file. This index file can be then used by the [open-source DiskANN](https://github.com/microsoft/DiskANN) library to perform efficient search. Additional DiskANN functionality, including GPU-accelerated search and 'ssd' index build are planned for future cuVS releases. + +[C++ API](/api-reference/cpp-api-neighbors-vamana) + +## Interoperability with CPU DiskANN + +The 'vamana::serialize' API calls writes the index to a file with a format that is compatible with the [open-source DiskANN repositoriy](https://github.com/microsoft/DiskANN). This allows cuVS to be used to accelerate index construction while leveraging the efficient CPU-based search currently available. + +## Configuration parameters + +### Build parameters + +| Name | Default | Description | +| --- | --- | --- | +| graph_degree | 32 | The maximum degre of the final Vamana graph. The internal representation of the graph includes this many edges for every node, but serialize will compress the graph into a 'CSR' format with, potentially, fewer edges. | +| visited_size | 64 | Maximum number of visited nodes saved during each traversal to insert a new node. This corresponds to the 'L' parameter in the paper. | +| vamana_iters | 1 | Number of iterations ran to improve the graph. Each iteration involves inserting every vector in the dataset. | +| alpha | 1.2 | Alpha parameter that defines how aggressively to prune edges. | +| max_fraction | 0.06 | Maximum fraction of the dataset that will be inserted as a single batch. Larger max batch size decreases graph quality but improves speed. | +| batch_base | 2 | Base of growth rate of batch sizes. Insertion batch sizes increase exponentially based on this parameter until max_fraction is reached. | +| queue_size | 127 | Size of the candidate queue structure used during graph traversal. Must be (2^x)-1 for some x, and must be > visited_size. | + +## Tuning Considerations + +The 2 hyper-parameters that are most often tuned are `graph_degree` and `visited_size`. The time needed to create a graph increases dramatically when increasing `graph_degree`, in particular. However, larger graphs may be needed to achieve very high recall search, especially for large datasets. + +## Memory footprint + +Vamana builds a graph that is stored in device memory. However, in order to serialize the index and write it to a file for later use, it must be moved into host memory. If the `include_dataset` parameter is also set, then the dataset must be resident in host memory when calling serialize as well. + +### Device memory usage + +The built index represents the graph as fixed degree, storing a total of $graph\_degree * n\_index\_vectors$ edges. Graph construction also requires the dataset be in device memory (or it copies it to device during build). In addition, device memory is used during construction to sort and create the reverse edges. Thus, the amount of device memory needed depends on the dataset itself, but it is bounded by a maximum sum of: + +- vector dataset: $n\_index\_vectors * n\_dims * sizeof(T)$ +- output graph: $graph\_degree * n\_index\_vectors * sizeof(IdxT)$ +- scratch memory: $n\_index\_vectors * max\_fraction * (2 + graph\_degree) * sizeof(IdxT)$ + +Reduction in scratch device memory requirements are planned for upcoming releases of cuVS. diff --git a/fern/pages/python_api/index.md b/fern/pages/python_api/index.md new file mode 100644 index 0000000000..41773574fa --- /dev/null +++ b/fern/pages/python_api/index.md @@ -0,0 +1,42 @@ +# Python API Documentation + +These pages are generated from the Python and Cython sources under `python/cuvs/cuvs`. + +## Cluster + +- [Kmeans](/api-reference/python-api-cluster-kmeans) + +## Common + +- [Common](/api-reference/python-api-common) + +## Distance + +- [Distance](/api-reference/python-api-distance) + +## Multi-GPU Neighbors + +- [Multi-GPU Cagra](/api-reference/python-api-neighbors-mg-cagra) +- [Multi-GPU IVF Flat](/api-reference/python-api-neighbors-mg-ivf-flat) +- [Multi-GPU IVF PQ](/api-reference/python-api-neighbors-mg-ivf-pq) + +## Nearest Neighbors + +- [All Neighbors](/api-reference/python-api-neighbors-all-neighbors) +- [Brute Force](/api-reference/python-api-neighbors-brute-force) +- [Cagra](/api-reference/python-api-neighbors-cagra) +- [Filters](/api-reference/python-api-neighbors-filters) +- [HNSW](/api-reference/python-api-neighbors-hnsw) +- [IVF Flat](/api-reference/python-api-neighbors-ivf-flat) +- [IVF PQ](/api-reference/python-api-neighbors-ivf-pq) +- [NN Descent](/api-reference/python-api-neighbors-nn-descent) +- [Neighbors](/api-reference/python-api-neighbors) +- [Tiered Index](/api-reference/python-api-neighbors-tiered-index) +- [Vamana](/api-reference/python-api-neighbors-vamana) + +## Preprocessing + +- [Binary](/api-reference/python-api-preprocessing-quantize-binary) +- [PCA](/api-reference/python-api-preprocessing-pca) +- [PQ](/api-reference/python-api-preprocessing-quantize-pq) +- [Scalar](/api-reference/python-api-preprocessing-quantize-scalar) diff --git a/fern/pages/python_api/python-api-cluster-kmeans.md b/fern/pages/python_api/python-api-cluster-kmeans.md new file mode 100644 index 0000000000..01dadfe66a --- /dev/null +++ b/fern/pages/python_api/python-api-cluster-kmeans.md @@ -0,0 +1,334 @@ +--- +slug: api-reference/python-api-cluster-kmeans +--- + +# Kmeans + +_Python module: `cuvs.cluster.kmeans`_ + +## KMeansParams + +```python +cdef class KMeansParams +``` + +Hyper-parameters for the kmeans algorithm + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `metric` | `str` | String denoting the metric type. | +| `n_clusters` | `int` | The number of clusters to form as well as the number of centroids to generate | +| `init_method` | `str` | Method for initializing clusters. One of: "KMeansPlusPlus" : Use scalable k-means++ algorithm to select initial cluster centers "Random" : Choose 'n_clusters' observations at random from the input data "Array" : Use centroids as initial cluster centers | +| `max_iter` | `int` | Maximum number of iterations of the k-means algorithm for a single run | +| `tol` | `float` | Relative tolerance with regards to inertia to declare convergence. | +| `n_init` | `int` | Number of instance k-means algorithm will be run with different seeds | +| `oversampling_factor` | `double` | Oversampling factor for use in the k-means\|\| algorithm | +| `batch_samples` | `int` | Number of samples to process in each batch for tiled 1NN computation. Useful to optimize/control memory footprint. Default tile is [batch_samples x n_clusters]. | +| `batch_centroids` | `int` | Number of centroids to process in each batch. If 0, uses n_clusters. | +| `inertia_check` | `bool` | If True, check inertia during iterations for early convergence. | +| `streaming_batch_size` | `int` | Number of samples to process per GPU batch when fitting with host (numpy) data. When set to 0, defaults to n_samples (process all at once). Only used by the batched (host-data) code path. Reducing streaming_batch_size can help reduce GPU memory pressure but increases overhead as the number of times centroid adjustments are computed increases.

Default: 0 (process all data at once). | +| `hierarchical` | `bool` | Whether to use hierarchical (balanced) kmeans or not | +| `hierarchical_n_iters` | `int` | For hierarchical k-means , defines the number of training iterations | + +**Constructor** + +```python +def __init__(self, *, metric=None, n_clusters=None, init_method=None, max_iter=None, tol=None, n_init=None, oversampling_factor=None, batch_samples=None, batch_centroids=None, inertia_check=None, streaming_batch_size=None, hierarchical=None, hierarchical_n_iters=None) +``` + +**Members** + +| Name | Kind | Source | +| --- | --- | --- | +| `metric` | property | `python/cuvs/cuvs/cluster/kmeans/kmeans.pyx:150` | +| `n_clusters` | property | `python/cuvs/cuvs/cluster/kmeans/kmeans.pyx:154` | +| `init_method` | property | `python/cuvs/cuvs/cluster/kmeans/kmeans.pyx:158` | +| `max_iter` | property | `python/cuvs/cuvs/cluster/kmeans/kmeans.pyx:162` | +| `tol` | property | `python/cuvs/cuvs/cluster/kmeans/kmeans.pyx:166` | +| `n_init` | property | `python/cuvs/cuvs/cluster/kmeans/kmeans.pyx:170` | +| `oversampling_factor` | property | `python/cuvs/cuvs/cluster/kmeans/kmeans.pyx:174` | +| `batch_samples` | property | `python/cuvs/cuvs/cluster/kmeans/kmeans.pyx:178` | +| `batch_centroids` | property | `python/cuvs/cuvs/cluster/kmeans/kmeans.pyx:182` | +| `inertia_check` | property | `python/cuvs/cuvs/cluster/kmeans/kmeans.pyx:186` | +| `streaming_batch_size` | property | `python/cuvs/cuvs/cluster/kmeans/kmeans.pyx:190` | +| `hierarchical` | property | `python/cuvs/cuvs/cluster/kmeans/kmeans.pyx:194` | +| `hierarchical_n_iters` | property | `python/cuvs/cuvs/cluster/kmeans/kmeans.pyx:198` | + +### metric + +```python +def metric(self) +``` + +_Source: `python/cuvs/cuvs/cluster/kmeans/kmeans.pyx:150`_ + +### n_clusters + +```python +def n_clusters(self) +``` + +_Source: `python/cuvs/cuvs/cluster/kmeans/kmeans.pyx:154`_ + +### init_method + +```python +def init_method(self) +``` + +_Source: `python/cuvs/cuvs/cluster/kmeans/kmeans.pyx:158`_ + +### max_iter + +```python +def max_iter(self) +``` + +_Source: `python/cuvs/cuvs/cluster/kmeans/kmeans.pyx:162`_ + +### tol + +```python +def tol(self) +``` + +_Source: `python/cuvs/cuvs/cluster/kmeans/kmeans.pyx:166`_ + +### n_init + +```python +def n_init(self) +``` + +_Source: `python/cuvs/cuvs/cluster/kmeans/kmeans.pyx:170`_ + +### oversampling_factor + +```python +def oversampling_factor(self) +``` + +_Source: `python/cuvs/cuvs/cluster/kmeans/kmeans.pyx:174`_ + +### batch_samples + +```python +def batch_samples(self) +``` + +_Source: `python/cuvs/cuvs/cluster/kmeans/kmeans.pyx:178`_ + +### batch_centroids + +```python +def batch_centroids(self) +``` + +_Source: `python/cuvs/cuvs/cluster/kmeans/kmeans.pyx:182`_ + +### inertia_check + +```python +def inertia_check(self) +``` + +_Source: `python/cuvs/cuvs/cluster/kmeans/kmeans.pyx:186`_ + +### streaming_batch_size + +```python +def streaming_batch_size(self) +``` + +_Source: `python/cuvs/cuvs/cluster/kmeans/kmeans.pyx:190`_ + +### hierarchical + +```python +def hierarchical(self) +``` + +_Source: `python/cuvs/cuvs/cluster/kmeans/kmeans.pyx:194`_ + +### hierarchical_n_iters + +```python +def hierarchical_n_iters(self) +``` + +_Source: `python/cuvs/cuvs/cluster/kmeans/kmeans.pyx:198`_ + +_Source: `python/cuvs/cuvs/cluster/kmeans/kmeans.pyx:47`_ + +## cluster_cost + +`@auto_sync_resources` +`@auto_convert_output` + +```python +def cluster_cost(X, centroids, resources=None) +``` + +Compute cluster cost given an input matrix and existing centroids + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `X` | `Input CUDA array interface compliant matrix shape (m, k)` | | +| `centroids` | `Input CUDA array interface compliant matrix shape` | (n_clusters, k) | +| `resources` | `cuvs.common.Resources, optional` | | + +**Returns** + +| Name | Type | Description | +| --- | --- | --- | +| `inertia` | `float` | The cluster cost between the input matrix and existing centroids | + +**Examples** + +```python +>>> import cupy as cp +>>> +>>> from cuvs.cluster.kmeans import cluster_cost +>>> +>>> n_samples = 5000 +>>> n_features = 50 +>>> n_clusters = 3 +>>> +>>> X = cp.random.random_sample((n_samples, n_features), +... dtype=cp.float32) +``` + +```python +>>> centroids = cp.random.random_sample((n_clusters, n_features), +... dtype=cp.float32) +``` + +```python +>>> inertia = cluster_cost(X, centroids) +``` + +_Source: `python/cuvs/cuvs/cluster/kmeans/kmeans.pyx:435`_ + +## fit + +`@auto_sync_resources` +`@auto_convert_output` + +```python +def fit( KMeansParams params, X, centroids=None, sample_weights=None, resources=None ) +``` + +Find clusters with the k-means algorithm + +When X is a device array (CUDA array interface), standard on-device +k-means is used. When X is a host array (numpy ndarray or +``__array_interface__``), data is streamed to the GPU in batches +controlled by ``params.streaming_batch_size``. For large host datasets, consider +reducing ``streaming_batch_size`` to reduce GPU memory usage. + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `params` | `KMeansParams` | Parameters to use to fit KMeans model. For host data, ``params.streaming_batch_size`` controls how many samples are sent to the GPU per batch. | +| `X` | `array-like` | Training instances, shape (m, k). Accepts both device arrays (cupy / CUDA array interface) and host arrays (numpy). | +| `centroids` | `Optional writable CUDA array interface compliant matrix` | shape (n_clusters, k) | +| `sample_weights` | `Optional weights per observation. Must reside on` | the same memory space as X (device or host). default: None | +| `resources` | `cuvs.common.Resources, optional` | | + +**Returns** + +| Name | Type | Description | +| --- | --- | --- | +| `centroids` | `raft.device_ndarray` | The computed centroids for each cluster | +| `inertia` | `float` | Sum of squared distances of samples to their closest cluster center | +| `n_iter` | `int` | The number of iterations used to fit the model | + +**Examples** + +```python +>>> import cupy as cp +>>> +>>> from cuvs.cluster.kmeans import fit, KMeansParams +>>> +>>> n_samples = 5000 +>>> n_features = 50 +>>> n_clusters = 3 +>>> +>>> X = cp.random.random_sample((n_samples, n_features), +... dtype=cp.float32) +``` + +```python +>>> params = KMeansParams(n_clusters=n_clusters) +>>> centroids, inertia, n_iter = fit(params, X) +``` + +Host-data (batched) example: + +```python +>>> import numpy as np +>>> X_host = np.random.random((10_000_000, 128)).astype(np.float32) +>>> params = KMeansParams(n_clusters=1000, streaming_batch_size=1_000_000) +>>> centroids, inertia, n_iter = fit(params, X_host) +``` + +_Source: `python/cuvs/cuvs/cluster/kmeans/kmeans.pyx:207`_ + +## predict + +`@auto_sync_resources` +`@auto_convert_output` + +```python +def predict( KMeansParams params, X, centroids, sample_weights=None, labels=None, normalize_weight=True, resources=None ) +``` + +Predict clusters with the k-means algorithm + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `params` | `KMeansParams` | Parameters to used in fitting KMeans model | +| `X` | `Input CUDA array interface compliant matrix shape (m, k)` | | +| `centroids` | `CUDA array interface compliant matrix, calculated by fit` | shape (n_clusters, k) | +| `sample_weights` | `Optional input CUDA array interface compliant matrix shape` | (n_clusters, 1) default: None | +| `labels` | `Optional preallocated CUDA array interface matrix shape (m, 1)` | to hold the output | +| `normalize_weight` | `bool` | True if the weights should be normalized | +| `resources` | `cuvs.common.Resources, optional` | | + +**Returns** + +| Name | Type | Description | +| --- | --- | --- | +| `labels` | `raft.device_ndarray` | The label for each datapoint in X | +| `inertia` | `float` | Sum of squared distances of samples to their closest cluster center | + +**Examples** + +```python +>>> import cupy as cp +>>> +>>> from cuvs.cluster.kmeans import fit, predict, KMeansParams +>>> +>>> n_samples = 5000 +>>> n_features = 50 +>>> n_clusters = 3 +>>> +>>> X = cp.random.random_sample((n_samples, n_features), +... dtype=cp.float32) +``` + +```python +>>> params = KMeansParams(n_clusters=n_clusters) +>>> centroids, inertia, n_iter = fit(params, X) +>>> +>>> labels, inertia = predict(params, X, centroids) +``` + +_Source: `python/cuvs/cuvs/cluster/kmeans/kmeans.pyx:344`_ diff --git a/fern/pages/python_api/python-api-common.md b/fern/pages/python_api/python-api-common.md new file mode 100644 index 0000000000..27f5806426 --- /dev/null +++ b/fern/pages/python_api/python-api-common.md @@ -0,0 +1,215 @@ +--- +slug: api-reference/python-api-common +--- + +# Common + +_Python module: `cuvs.common`_ + +## auto_sync_resources + +```python +def auto_sync_resources(f) +``` + +Decorator to automatically call sync on a cuVS Resources object when +it isn't passed to a function. + +When a resources=None is passed to the wrapped function, this decorator +will automatically create a default resources for the function, and +call sync on that resources when the function exits. + +This will also insert the appropriate docstring for the resources parameter + +_Source: `python/cuvs/cuvs/common/resources.pyx:83`_ + +## Resources + +```python +cdef class Resources +``` + +Resources is a lightweight python wrapper around the corresponding +C++ class of resources exposed by RAFT's C++ interface. Refer to +the header file raft/core/resources.hpp for interface level +details of this struct. + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `stream` | `Optional stream to use for ordering CUDA instructions` | | + +**Examples** + +Basic usage: + +```python +>>> from cuvs.common import Resources +>>> handle = Resources() +>>> +>>> # call algos here +>>> +>>> # final sync of all work launched in the stream of this handle +>>> handle.sync() +``` + +Using a cuPy stream with cuVS Resources: + +```python +>>> import cupy +>>> from cuvs.common import Resources +>>> +>>> cupy_stream = cupy.cuda.Stream() +>>> handle = Resources(stream=cupy_stream.ptr) +``` + +**Members** + +| Name | Kind | Source | +| --- | --- | --- | +| `sync` | method | `python/cuvs/cuvs/common/resources.pyx:60` | +| `get_c_obj` | method | `python/cuvs/cuvs/common/resources.pyx:63` | + +### sync + +```python +def sync(self) +``` + +_Source: `python/cuvs/cuvs/common/resources.pyx:60`_ + +### get_c_obj + +```python +def get_c_obj(self) +``` + +Return the pointer to the underlying c_obj as a size_t + +_Source: `python/cuvs/cuvs/common/resources.pyx:63`_ + +_Source: `python/cuvs/cuvs/common/resources.pyx:22`_ + +## MultiGpuResources + +```python +cdef class MultiGpuResources +``` + +Multi-GPU Resources is a lightweight python wrapper around the +corresponding C++ class of multi-GPU resources exposed by RAFT's C++ +interface. This class provides a handle for multi-GPU operations across +all available GPUs. + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `stream` | `int, optional` | A CUDA stream pointer to use for this resource handle. If None, a default stream will be used. | +| `device_ids` | `list of int, optional` | A list of device IDs to use for multi-GPU operations. If None, all available GPUs will be used. | + +**Examples** + +Basic usage: + +```python +>>> from cuvs.common import MultiGpuResources +>>> handle = MultiGpuResources() +>>> +>>> # call multi-GPU algos here +>>> +>>> # final sync of all work launched in the stream of this handle +>>> handle.sync() +``` + +Using a cuPy stream with cuVS Multi-GPU Resources: + +```python +>>> import cupy +>>> from cuvs.common import MultiGpuResources +>>> +>>> cupy_stream = cupy.cuda.Stream() +>>> handle = MultiGpuResources(stream=cupy_stream.ptr) +``` + +Using specific device IDs: + +```python +>>> from cuvs.common import MultiGpuResources +>>> handle = MultiGpuResources(device_ids=[0]) +>>> +>>> # call multi-GPU algos here +>>> +>>> handle.sync() +``` + +**Members** + +| Name | Kind | Source | +| --- | --- | --- | +| `sync` | method | `python/cuvs/cuvs/common/mg_resources.pyx:90` | +| `set_memory_pool` | method | `python/cuvs/cuvs/common/mg_resources.pyx:93` | +| `get_c_obj` | method | `python/cuvs/cuvs/common/mg_resources.pyx:111` | + +### sync + +```python +def sync(self) +``` + +_Source: `python/cuvs/cuvs/common/mg_resources.pyx:90`_ + +### set_memory_pool + +```python +def set_memory_pool(self, percent_of_free_memory) +``` + +Set a memory pool on all devices managed by these resources. + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `percent_of_free_memory` | `int` | Percentage of free device memory to allocate for the pool. | + +**Examples** + +```python +>>> from cuvs.common import MultiGpuResources +>>> handle = MultiGpuResources() +>>> handle.set_memory_pool(80) # Use 80% of free memory +``` + +_Source: `python/cuvs/cuvs/common/mg_resources.pyx:93`_ + +### get_c_obj + +```python +def get_c_obj(self) +``` + +Return the pointer to the underlying c_obj as a size_t + +_Source: `python/cuvs/cuvs/common/mg_resources.pyx:111`_ + +_Source: `python/cuvs/cuvs/common/mg_resources.pyx:26`_ + +## auto_sync_multi_gpu_resources + +```python +def auto_sync_multi_gpu_resources(f) +``` + +Decorator to automatically call sync on a cuVS Multi-GPU Resources +object when it isn't passed to a function. + +When a resources=None is passed to the wrapped function, this decorator +will automatically create a default multi-GPU resources for the function, +and call sync on that resources when the function exits. + +This will also insert the appropriate docstring for the resources +parameter + +_Source: `python/cuvs/cuvs/common/mg_resources.pyx:132`_ diff --git a/fern/pages/python_api/python-api-distance.md b/fern/pages/python_api/python-api-distance.md new file mode 100644 index 0000000000..c100a0fb0c --- /dev/null +++ b/fern/pages/python_api/python-api-distance.md @@ -0,0 +1,89 @@ +--- +slug: api-reference/python-api-distance +--- + +# Distance + +_Python module: `cuvs.distance`_ + +## DISTANCE_NAMES + +```python +DISTANCE_NAMES = {v: k for k, v in DISTANCE_TYPES.items()} +``` + +_Source: `python/cuvs/cuvs/distance/distance.pyx:41`_ + +## DISTANCE_TYPES + +```python +DISTANCE_TYPES = { +"l2": cuvsDistanceType.L2SqrtExpanded, +"sqeuclidean": cuvsDistanceType.L2Expanded, +"euclidean": cuvsDistanceType.L2SqrtExpanded, +"l1": cuvsDistanceType.L1, +"cityblock": cuvsDistanceType.L1, +"inner_product": cuvsDistanceType.InnerProduct, +"chebyshev": cuvsDistanceType.Linf, +"canberra": cuvsDistanceType.Canberra, +"cosine": cuvsDistanceType.CosineExpanded, +"lp": cuvsDistanceType.LpUnexpanded, +"correlation": cuvsDistanceType.CorrelationExpanded, +"jaccard": cuvsDistanceType.JaccardExpanded, +"hellinger": cuvsDistanceType.HellingerExpanded, +"braycurtis": cuvsDistanceType.BrayCurtis, +"jensenshannon": cuvsDistanceType.JensenShannon, +"hamming": cuvsDistanceType.HammingUnexpanded, +"kl_divergence": cuvsDistanceType.KLDivergence, +"minkowski": cuvsDistanceType.LpUnexpanded, +"russellrao": cuvsDistanceType.RusselRaoExpanded, +"dice": cuvsDistanceType.DiceExpanded, +"bitwise_hamming": cuvsDistanceType.BitwiseHamming +} +``` + +_Source: `python/cuvs/cuvs/distance/distance.pyx:17`_ + +## pairwise_distance + +`@auto_sync_resources` +`@auto_convert_output` + +```python +def pairwise_distance(X, Y, out=None, metric="euclidean", p=2.0, resources=None) +``` + +Compute pairwise distances between X and Y + +Valid values for metric: +["euclidean", "l2", "l1", "cityblock", "inner_product", +"chebyshev", "canberra", "lp", "hellinger", "jensenshannon", +"kl_divergence", "russellrao", "minkowski", "correlation", +"cosine"] + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `X` | `CUDA array interface compliant matrix shape (m, k)` | | +| `Y` | `CUDA array interface compliant matrix shape (n, k)` | | +| `out` | `Optional writable CUDA array interface matrix shape (m, n)` | | +| `metric` | `string denoting the metric type (default="euclidean")` | | +| `p` | `metric parameter (currently used only for "minkowski")` | | +| `resources` | `cuvs.common.Resources, optional` | | + +**Examples** + +```python +>>> import cupy as cp +>>> from cuvs.distance import pairwise_distance +>>> n_samples = 5000 +>>> n_features = 50 +>>> in1 = cp.random.random_sample((n_samples, n_features), +... dtype=cp.float32) +>>> in2 = cp.random.random_sample((n_samples, n_features), +... dtype=cp.float32) +>>> output = pairwise_distance(in1, in2, metric="euclidean") +``` + +_Source: `python/cuvs/cuvs/distance/distance.pyx:51`_ diff --git a/fern/pages/python_api/python-api-neighbors-all-neighbors.md b/fern/pages/python_api/python-api-neighbors-all-neighbors.md new file mode 100644 index 0000000000..c760f3545d --- /dev/null +++ b/fern/pages/python_api/python-api-neighbors-all-neighbors.md @@ -0,0 +1,129 @@ +--- +slug: api-reference/python-api-neighbors-all-neighbors +--- + +# All Neighbors + +_Python module: `cuvs.neighbors.all_neighbors`_ + +## AllNeighborsParams + +```python +cdef class AllNeighborsParams +``` + +Parameters for all-neighbors k-NN graph building. + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `algo` | `str or cuvsAllNeighborsAlgo` | Algorithm to use for local k-NN graph building. Options: "brute_force", "ivf_pq", "nn_descent" | +| `overlap_factor` | `int, default=2` | Number of clusters each point is assigned to (must be < n_clusters) | +| `n_clusters` | `int, default=1` | Number of clusters/batches to partition the dataset into (> overlap_factor). Use n_clusters>1 to distribute the work across GPUs. | +| `metric` | `str or cuvsDistanceType, default="sqeuclidean"` | Distance metric to use for graph construction | +| `ivf_pq_params` | `cuvs.neighbors.ivf_pq.IndexParams, optional` | IVF-PQ specific parameters (used when algo="ivf_pq") | +| `nn_descent_params` | `cuvs.neighbors.nn_descent.IndexParams, optional` | NN-Descent specific parameters (used when algo="nn_descent") | + +**Constructor** + +```python +def __init__(self, *, algo="nn_descent", overlap_factor=2, n_clusters=1, metric="sqeuclidean", ivf_pq_params=None, nn_descent_params=None) +``` + +**Members** + +| Name | Kind | Source | +| --- | --- | --- | +| `get_handle` | method | `python/cuvs/cuvs/neighbors/all_neighbors/all_neighbors.pyx:159` | +| `algo` | property | `python/cuvs/cuvs/neighbors/all_neighbors/all_neighbors.pyx:164` | +| `overlap_factor` | property | `python/cuvs/cuvs/neighbors/all_neighbors/all_neighbors.pyx:176` | +| `n_clusters` | property | `python/cuvs/cuvs/neighbors/all_neighbors/all_neighbors.pyx:181` | +| `metric` | property | `python/cuvs/cuvs/neighbors/all_neighbors/all_neighbors.pyx:186` | + +### get_handle + +```python +def get_handle(self) +``` + +Get a pointer to the underlying C object. + +_Source: `python/cuvs/cuvs/neighbors/all_neighbors/all_neighbors.pyx:159`_ + +### algo + +```python +def algo(self) +``` + +Algorithm used for local k-NN graph building. + +_Source: `python/cuvs/cuvs/neighbors/all_neighbors/all_neighbors.pyx:164`_ + +### overlap_factor + +```python +def overlap_factor(self) +``` + +Number of clusters each point is assigned to. + +_Source: `python/cuvs/cuvs/neighbors/all_neighbors/all_neighbors.pyx:176`_ + +### n_clusters + +```python +def n_clusters(self) +``` + +Number of clusters/batches to partition the dataset into. + +_Source: `python/cuvs/cuvs/neighbors/all_neighbors/all_neighbors.pyx:181`_ + +### metric + +```python +def metric(self) +``` + +Distance metric used for graph construction. + +_Source: `python/cuvs/cuvs/neighbors/all_neighbors/all_neighbors.pyx:186`_ + +_Source: `python/cuvs/cuvs/neighbors/all_neighbors/all_neighbors.pyx:66`_ + +## build + +`@auto_convert_output` + +```python +def build(dataset, k, params, *, indices=None, distances=None, core_distances=None, alpha=1.0, resources=None) +``` + +All-neighbors allows building an approximate all-neighbors knn graph. +Given a full dataset, it finds nearest neighbors for all the training +vectors in the dataset. + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `dataset` | `array_like` | Training dataset to build the k-NN graph for. Can be provided on host (for multi-GPU build) or device (for single-GPU build). Host vs device location is automatically detected. Supported dtype: float32 | +| `k` | `int` | Number of nearest neighbors to find for each point | +| `params` | `AllNeighborsParams` | Parameters object containing all build settings including algorithm choice and algorithm-specific parameters. | +| `indices` | `array_like, optional` | Optional output buffer for indices [num_rows x k] on device (int64). If not provided, will be allocated automatically. | +| `distances` | `array_like, optional` | Optional output buffer for distances [num_rows x k] on device (float32) | +| `core_distances` | `array_like, optional` | Optional output buffer for core distances [num_rows] on device (float32). Requires distances parameter to be provided. | +| `alpha` | `float, default=1.0` | Mutual-reachability scaling; used only when core_distances is provided | +| `resources` | `Resources or MultiGpuResources, optional` | CUDA resources to use for the operation. If not provided, a default Resources object will be created. Use MultiGpuResources to enable multi-GPU execution across multiple devices. | + +**Returns** + +| Name | Type | Description | +| --- | --- | --- | +| `indices` | `array_like` | k-NN indices for each point [num_rows x k], always on device. If indices buffer was provided, returns the same array filled with results. | +| `distances` | `array_like or None` | k-NN distances if distances buffer was provided, None otherwise | +| `core_distances` | `array_like or None` | Core distances if core_distances buffer was provided, None otherwise | + +_Source: `python/cuvs/cuvs/neighbors/all_neighbors/all_neighbors.pyx:196`_ diff --git a/fern/pages/python_api/python-api-neighbors-brute-force.md b/fern/pages/python_api/python-api-neighbors-brute-force.md new file mode 100644 index 0000000000..54f105871e --- /dev/null +++ b/fern/pages/python_api/python-api-neighbors-brute-force.md @@ -0,0 +1,248 @@ +--- +slug: api-reference/python-api-neighbors-brute-force +--- + +# Brute Force + +_Python module: `cuvs.neighbors.brute_force`_ + +## Index + +```python +cdef class Index +``` + +Brute Force index object. This object stores the trained Brute Force +which can be used to perform nearest neighbors searches. + +**Members** + +| Name | Kind | Source | +| --- | --- | --- | +| `trained` | property | `python/cuvs/cuvs/neighbors/brute_force/brute_force.pyx:52` | + +### trained + +```python +def trained(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/brute_force/brute_force.pyx:52`_ + +_Source: `python/cuvs/cuvs/neighbors/brute_force/brute_force.pyx:34`_ + +## build + +`@auto_sync_resources` + +```python +def build(dataset, metric="sqeuclidean", metric_arg=2.0, resources=None) +``` + +Build the Brute Force index from the dataset for efficient search. + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `dataset` | `CUDA array interface compliant matrix shape (n_samples, dim)` | Supported dtype [float32, float16] | +| `metric` | `Distance metric to use. Default is sqeuclidean` | | +| `metric_arg` | `value of 'p' for Minkowski distances` | | +| `resources` | `cuvs.common.Resources, optional` | | + +**Returns** + +| Name | Type | Description | +| --- | --- | --- | +| `index` | `cuvs.neighbors.brute_force.Index` | | + +**Examples** + +```python +>>> import cupy as cp +>>> from cuvs.neighbors import brute_force +>>> n_samples = 50000 +>>> n_features = 50 +>>> n_queries = 1000 +>>> k = 10 +>>> dataset = cp.random.random_sample((n_samples, n_features), +... dtype=cp.float32) +>>> index = brute_force.build(dataset, metric="cosine") +>>> distances, neighbors = brute_force.search(index, dataset, k) +>>> distances = cp.asarray(distances) +>>> neighbors = cp.asarray(neighbors) +``` + +_Source: `python/cuvs/cuvs/neighbors/brute_force/brute_force.pyx:60`_ + +## search + +`@auto_sync_resources` +`@auto_convert_output` + +```python +def search(Index index, queries, k, neighbors=None, distances=None, resources=None, prefilter=None) +``` + +Find the k nearest neighbors for each query. + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `index` | `Index` | Trained Brute Force index. | +| `queries` | `CUDA array interface compliant matrix shape (n_samples, dim)` | Supported dtype [float32, float16] | +| `k` | `int` | The number of neighbors. | +| `neighbors` | `Optional CUDA array interface compliant matrix shape` | (n_queries, k), dtype int64_t. If supplied, neighbor indices will be written here in-place. (default None) | +| `distances` | `Optional CUDA array interface compliant matrix shape` | (n_queries, k) If supplied, the distances to the neighbors will be written here in-place. (default None) | +| `prefilter` | `Optional, cuvs.neighbors.cuvsFilter` | An optional filter to exclude certain query-neighbor pairs using a bitmap or bitset. The filter function should have a row-major layout with logical shape `(n_prefilter_rows, n_samples)`, where: - `n_prefilter_rows == n_queries` when using a bitmap filter. - `n_prefilter_rows == 1` when using a bitset prefilter. Each bit in `n_samples` determines whether `queries[i]` should be considered for distance computation with the index. (default None) | +| `resources` | `cuvs.common.Resources, optional` | | + +**Examples** + +```python +>>> # Example without pre-filter +>>> import cupy as cp +>>> from cuvs.neighbors import brute_force +>>> n_samples = 50000 +>>> n_features = 50 +>>> n_queries = 1000 +>>> dataset = cp.random.random_sample((n_samples, n_features), +... dtype=cp.float32) +>>> # Build index +>>> index = brute_force.build(dataset, metric="sqeuclidean") +>>> # Search using the built index +>>> queries = cp.random.random_sample((n_queries, n_features), +... dtype=cp.float32) +>>> k = 10 +>>> # Using a pooling allocator reduces overhead of temporary array +>>> # creation during search. This is useful if multiple searches +>>> # are performed with same query size. +>>> distances, neighbors = brute_force.search(index, queries, k) +>>> neighbors = cp.asarray(neighbors) +>>> distances = cp.asarray(distances) +``` + +```python +>>> # Example with pre-filter +>>> import numpy as np +>>> import cupy as cp +>>> from cuvs.neighbors import brute_force, filters +>>> n_samples = 50000 +>>> n_features = 50 +>>> n_queries = 1000 +>>> dataset = cp.random.random_sample((n_samples, n_features), +... dtype=cp.float32) +>>> # Build index +>>> index = brute_force.build(dataset, metric="sqeuclidean") +>>> # Search using the built index +>>> queries = cp.random.random_sample((n_queries, n_features), +... dtype=cp.float32) +>>> # Build filters +>>> n_bitmap = np.ceil(n_samples * n_queries / 32).astype(int) +>>> # Create your own bitmap as the filter by replacing the random one. +>>> bitmap = cp.random.randint(1, 100, size=(n_bitmap,), dtype=cp.uint32) +>>> bitmap_prefilter = filters.from_bitmap(bitmap) +>>> +>>> # or Build bitset prefilter: +>>> # n_bitset = np.ceil(n_samples * 1 / 32).astype(int) +>>> # # Create your own bitset as the filter by replacing the random one. +>>> # bitset = cp.random.randint(1, 100, size=(n_bitset,), dtype=cp.uint32) +>>> # bitset_prefilter = filters.from_bitset(bitset) +>>> +>>> k = 10 +>>> # Using a pooling allocator reduces overhead of temporary array +>>> # creation during search. This is useful if multiple searches +>>> # are performed with same query size. +>>> distances, neighbors = brute_force.search(index, queries, k, +... prefilter=bitmap_prefilter) +>>> neighbors = cp.asarray(neighbors) +>>> distances = cp.asarray(distances) +``` + +_Source: `python/cuvs/cuvs/neighbors/brute_force/brute_force.pyx:120`_ + +## save + +`@auto_sync_resources` + +```python +def save(filename, Index index, bool include_dataset=True, resources=None) +``` + +Saves the index to a file. + +The serialization format can be subject to changes, therefore loading +an index saved with a previous version of cuvs is not guaranteed +to work. + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `filename` | `string` | Name of the file. | +| `index` | `Index` | Trained Brute Force index. | +| `resources` | `cuvs.common.Resources, optional` | | + +**Examples** + +```python +>>> import cupy as cp +>>> from cuvs.neighbors import brute_force +>>> n_samples = 50000 +>>> n_features = 50 +>>> dataset = cp.random.random_sample((n_samples, n_features), +... dtype=cp.float32) +>>> # Build index +>>> index = brute_force.build(dataset) +>>> # Serialize and deserialize the brute_force index built +>>> brute_force.save("my_index.bin", index) +>>> index_loaded = brute_force.load("my_index.bin") +``` + +_Source: `python/cuvs/cuvs/neighbors/brute_force/brute_force.pyx:266`_ + +## load + +`@auto_sync_resources` + +```python +def load(filename, resources=None) +``` + +Loads index from file. + +The serialization format can be subject to changes, therefore loading +an index saved with a previous version of cuvs is not guaranteed +to work. + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `filename` | `string` | Name of the file. | +| `resources` | `cuvs.common.Resources, optional` | | + +**Returns** + +| Name | Type | Description | +| --- | --- | --- | +| `index` | `Index` | | + +**Examples** + +```python +>>> import cupy as cp +>>> from cuvs.neighbors import brute_force +>>> n_samples = 50000 +>>> n_features = 50 +>>> dataset = cp.random.random_sample((n_samples, n_features), +... dtype=cp.float32) +>>> # Build index +>>> index = brute_force.build(dataset) +>>> # Serialize and deserialize the brute_force index built +>>> brute_force.save("my_index.bin", index) +>>> index_loaded = brute_force.load("my_index.bin") +``` + +_Source: `python/cuvs/cuvs/neighbors/brute_force/brute_force.pyx:304`_ diff --git a/fern/pages/python_api/python-api-neighbors-cagra.md b/fern/pages/python_api/python-api-neighbors-cagra.md new file mode 100644 index 0000000000..ec6bb8a628 --- /dev/null +++ b/fern/pages/python_api/python-api-neighbors-cagra.md @@ -0,0 +1,806 @@ +--- +slug: api-reference/python-api-neighbors-cagra +--- + +# Cagra + +_Python module: `cuvs.neighbors.cagra`_ + +## AceParams + +```python +cdef class AceParams +``` + +Parameters for ACE (Augmented Core Extraction) graph building algorithm. + +ACE enables building indexes for datasets too large to fit in GPU memory by +partitioning the dataset using balanced k-means and building sub-indexes +for each partition independently. + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `npartitions` | `int, default = 0` | Number of partitions for ACE partitioned build. When set to 0 (default), the number of partitions is automatically derived based on available host and GPU memory to maximize partition size while ensuring the build fits in memory.

Small values might improve recall but potentially degrade performance and increase memory usage. Partitions should not be too small to prevent issues in KNN graph construction. The partition size is on average 2 * (n_rows / npartitions) * dim * sizeof(T). 2 is because of the core and augmented vectors. Please account for imbalance in the partition sizes (up to 3x in our tests).

If the specified number of partitions results in partitions that exceed available memory, the value will be automatically increased to fit memory constraints and a warning will be issued. | +| `ef_construction` | `int, default = 120` | The index quality for the ACE build. Bigger values increase the index quality. At some point, increasing this will no longer improve the quality. | +| `build_dir` | `str, default = "/tmp/ace_build"` | Directory to store ACE build artifacts (e.g., KNN graph, optimized graph). Used when `use_disk` is true or when the graph does not fit in host and GPU memory. This should be the fastest disk in the system and hold enough space for twice the dataset, final graph, and label mapping. | +| `use_disk` | `bool, default = False` | Whether to use disk-based storage for ACE build. When true, enables disk-based operations for memory-efficient graph construction. | +| `max_host_memory_gb` | `float, default = 0` | Maximum host memory to use for ACE build in GiB. When set to 0 (default), uses available host memory. Useful for testing or when running alongside other memory-intensive processes. | +| `max_gpu_memory_gb` | `float, default = 0` | Maximum GPU memory to use for ACE build in GiB. When set to 0 (default), uses available GPU memory. Useful for testing or when running alongside other memory-intensive processes. | + +**Constructor** + +```python +def __init__(self, *, npartitions=0, ef_construction=120, build_dir="/tmp/ace_build", use_disk=False, max_host_memory_gb=0, max_gpu_memory_gb=0) +``` + +**Members** + +| Name | Kind | Source | +| --- | --- | --- | +| `npartitions` | property | `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:211` | +| `ef_construction` | property | `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:215` | +| `build_dir` | property | `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:219` | +| `use_disk` | property | `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:226` | +| `max_host_memory_gb` | property | `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:230` | +| `max_gpu_memory_gb` | property | `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:234` | +| `get_handle` | method | `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:237` | + +### npartitions + +```python +def npartitions(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:211`_ + +### ef_construction + +```python +def ef_construction(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:215`_ + +### build_dir + +```python +def build_dir(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:219`_ + +### use_disk + +```python +def use_disk(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:226`_ + +### max_host_memory_gb + +```python +def max_host_memory_gb(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:230`_ + +### max_gpu_memory_gb + +```python +def max_gpu_memory_gb(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:234`_ + +### get_handle + +```python +def get_handle(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:237`_ + +_Source: `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:127`_ + +## CompressionParams + +```python +cdef class CompressionParams +``` + +Parameters for VPQ Compression + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `pq_bits` | `int` | The bit length of the vector element after compression by PQ. Possible values: [4, 5, 6, 7, 8]. The smaller the 'pq_bits', the smaller the index size and the better the search performance, but the lower the recall. | +| `pq_dim` | `int` | The dimensionality of the vector after compression by PQ. When zero, an optimal value is selected using a heuristic. | +| `vq_n_centers` | `int` | Vector Quantization (VQ) codebook size - number of "coarse cluster centers". When zero, an optimal value is selected using a heuristic. | +| `kmeans_n_iters` | `int` | The number of iterations searching for kmeans centers (both VQ & PQ phases). | +| `vq_kmeans_trainset_fraction` | `float` | The fraction of data to use during iterative kmeans building (VQ phase). When zero, an optimal value is selected using a heuristic. | +| `pq_kmeans_trainset_fraction` | `float` | The fraction of data to use during iterative kmeans building (PQ phase). When zero, an optimal value is selected using a heuristic. | + +**Constructor** + +```python +def __init__(self, *, pq_bits=8, pq_dim=0, vq_n_centers=0, kmeans_n_iters=25, vq_kmeans_trainset_fraction=0.0, pq_kmeans_trainset_fraction=0.0) +``` + +**Members** + +| Name | Kind | Source | +| --- | --- | --- | +| `pq_bits` | property | `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:100` | +| `pq_dim` | property | `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:104` | +| `vq_n_centers` | property | `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:108` | +| `kmeans_n_iters` | property | `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:112` | +| `vq_kmeans_trainset_fraction` | property | `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:116` | +| `pq_kmeans_trainset_fraction` | property | `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:120` | +| `get_handle` | method | `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:123` | + +### pq_bits + +```python +def pq_bits(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:100`_ + +### pq_dim + +```python +def pq_dim(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:104`_ + +### vq_n_centers + +```python +def vq_n_centers(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:108`_ + +### kmeans_n_iters + +```python +def kmeans_n_iters(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:112`_ + +### vq_kmeans_trainset_fraction + +```python +def vq_kmeans_trainset_fraction(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:116`_ + +### pq_kmeans_trainset_fraction + +```python +def pq_kmeans_trainset_fraction(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:120`_ + +### get_handle + +```python +def get_handle(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:123`_ + +_Source: `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:50`_ + +## ExtendParams + +```python +cdef class ExtendParams +``` + +Supplemental parameters to extend CAGRA Index + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `max_chunk_size` | `int` | The additional dataset is divided into chunks and added to the graph. This is the knob to adjust the tradeoff between the recall and operation throughput. Large chunk sizes can result in high throughput, but use more working memory (O(max_chunk_size*degree^2)). This can also degrade recall because no edges are added between the nodes in the same chunk. Auto select when 0. | + +**Constructor** + +```python +def __init__(self, *, max_chunk_size=None) +``` + +**Members** + +| Name | Kind | Source | +| --- | --- | --- | +| `max_chunk_size` | property | `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:1060` | + +### max_chunk_size + +```python +def max_chunk_size(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:1060`_ + +_Source: `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:1032`_ + +## Index + +```python +cdef class Index +``` + +**Members** + +| Name | Kind | Source | +| --- | --- | --- | +| `trained` | property | `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:436` | +| `dim` | property | `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:440` | +| `graph_degree` | property | `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:446` | +| `dtype` | property | `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:457` | +| `dataset` | property | `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:461` | +| `graph` | property | `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:479` | + +### trained + +```python +def trained(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:436`_ + +### dim + +```python +def dim(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:440`_ + +### graph_degree + +```python +def graph_degree(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:446`_ + +### dtype + +```python +def dtype(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:457`_ + +### dataset + +```python +def dataset(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:461`_ + +### graph + +```python +def graph(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:479`_ + +_Source: `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:425`_ + +## IndexParams + +```python +cdef class IndexParams +``` + +Parameters to build index for CAGRA nearest neighbor search + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `metric` | `str, default = "sqeuclidean"` | String denoting the metric type, valid values for metric are ["sqeuclidean", "inner_product", "cosine"], where:

- sqeuclidean is the euclidean distance without the square root operation, i.e.: distance(a,b) = \\sum_i (a_i - b_i)^2 - inner_product distance is defined as distance(a, b) = \\sum_i a_i * b_i. - cosine distance is defined as distance(a, b) = 1 - \\sum_i a_i * b_i / ( \|\|a\|\|_2 * \|\|b\|\|_2). | +| `intermediate_graph_degree` | `int, default = 128` | | +| `graph_degree` | `int, default = 64` | | +| `build_algo` | `str, default = "ivf_pq"` | string denoting the graph building algorithm to use. Valid values for algo: ["ivf_pq", "nn_descent", "iterative_cagra_search", "ace"], where

- ivf_pq will use the IVF-PQ algorithm for building the knn graph - nn_descent (experimental) will use the NN-Descent algorithm for building the knn graph. It is expected to be generally faster than ivf_pq. - iterative_cagra_search will iteratively build the knn graph using CAGRA's search() and optimize() - ace will use ACE (Augmented Core Extraction) for building indices for datasets too large to fit in GPU memory | +| `compression` | `CompressionParams, optional` | If compression is desired should be a CompressionParams object. If None compression will be disabled. | +| `ivf_pq_build_params` | `cuvs.neighbors.ivf_pq.IndexParams, optional` | Parameters for IVF-PQ algorithm. If provided, it will be used for building the graph. | +| `ivf_pq_search_params` | `cuvs.neighbors.ivf_pq.SearchParams, optional` | Parameters for IVF-PQ search. If provided, it will be used for searching the graph. | +| `ace_params` | `AceParams, optional` | Parameters for ACE algorithm. If provided, it will be used for building the graph with ACE partitioning. | +| `refinement_rate` | `float, default = 1.0` | | + +**Constructor** + +```python +def __init__(self, *, metric="sqeuclidean", intermediate_graph_degree=128, graph_degree=64, build_algo="ivf_pq", nn_descent_niter=20, compression=None, ivf_pq_build_params: ivf_pq.IndexParams = None, ivf_pq_search_params: ivf_pq.SearchParams = None, ace_params: AceParams = None, refinement_rate: float = 1.0) +``` + +**Members** + +| Name | Kind | Source | +| --- | --- | --- | +| `get_handle` | method | `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:389` | +| `metric` | property | `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:393` | +| `intermediate_graph_degree` | property | `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:397` | +| `graph_degree` | property | `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:401` | +| `build_algo` | property | `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:405` | +| `nn_descent_niter` | property | `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:409` | +| `refinement_rate` | property | `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:413` | + +### get_handle + +```python +def get_handle(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:389`_ + +### metric + +```python +def metric(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:393`_ + +### intermediate_graph_degree + +```python +def intermediate_graph_degree(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:397`_ + +### graph_degree + +```python +def graph_degree(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:401`_ + +### build_algo + +```python +def build_algo(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:405`_ + +### nn_descent_niter + +```python +def nn_descent_niter(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:409`_ + +### refinement_rate + +```python +def refinement_rate(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:413`_ + +_Source: `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:241`_ + +## SearchParams + +```python +cdef class SearchParams +``` + +CAGRA search parameters + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `max_queries` | `int, default = 0` | Maximum number of queries to search at the same time (batch size). Auto select when 0. | +| `itopk_size` | `int, default = 64` | Number of intermediate search results retained during the search. This is the main knob to adjust trade off between accuracy and search speed. Higher values improve the search accuracy. | +| `max_iterations` | `int, default = 0` | Upper limit of search iterations. Auto select when 0. | +| `algo` | `str, default = "auto"` | String denoting the search algorithm to use Valid values for algo: ["auto", "single_cta", "multi_cta"], where:

- auto will automatically select the best value based on query size - single_cta is better when query contains larger number of vectors (e.g >10) - multi_cta is better when query contains only a few vectors | +| `team_size` | `int, default = 0` | Number of threads used to calculate a single distance. 4, 8, 16, or 32. | +| `search_width` | `int, default = 1` | Number of graph nodes to select as the starting point for the search in each iteration. | +| `min_iterations` | `int, default = 0` | Lower limit of search iterations. | +| `thread_block_size` | `int, default = 0` | Thread block size. 0, 64, 128, 256, 512, 1024. Auto selection when 0. | +| `hashmap_mode` | `str, default = "auto"` | String denoting the type of hash map to use. It's usually better to allow the algorithm to select this value, Valid values for hashmap_mode: ["auto", "small", "hash"], where:

- auto will automatically select the best value based on algo - small will use the small shared memory hash table with resetting. - hash will use a single hash table in global memory. | +| `hashmap_min_bitlen` | `int, default = 0` | Upper limit of hashmap fill rate. More than 0.1, less than 0.9. | +| `hashmap_max_fill_rate` | `float, default = 0.5` | Upper limit of hashmap fill rate. More than 0.1, less than 0.9. | +| `num_random_samplings` | `int, default = 1` | Number of iterations of initial random seed node selection. 1 or more. | +| `rand_xor_mask` | `int, default = 0x128394` | Bit mask used for initial random seed node selection. | +| `persistent` | `bool, default = false` | Whether to use the persistent version of the kernel | +| `persistent_lifetime` | `float` | Persistent kernel: time in seconds before the kernel stops if no requests are received. | +| `persistent_device_usage` | `float` | Sets the fraction of maximum grid size used by persistent kernel. | + +**Constructor** + +```python +def __init__(self, *, max_queries=0, itopk_size=64, max_iterations=0, algo="auto", team_size=0, search_width=1, min_iterations=0, thread_block_size=0, hashmap_mode="auto", hashmap_min_bitlen=0, hashmap_max_fill_rate=0.5, num_random_samplings=1, rand_xor_mask=0x128394, persistent=False, persistent_lifetime=None, persistent_device_usage=None ) +``` + +**Members** + +| Name | Kind | Source | +| --- | --- | --- | +| `get_handle` | method | `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:737` | +| `max_queries` | property | `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:741` | +| `itopk_size` | property | `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:745` | +| `max_iterations` | property | `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:749` | +| `algo` | property | `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:753` | +| `team_size` | property | `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:757` | +| `search_width` | property | `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:761` | +| `min_iterations` | property | `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:765` | +| `thread_block_size` | property | `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:769` | +| `hashmap_mode` | property | `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:773` | +| `hashmap_min_bitlen` | property | `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:777` | +| `hashmap_max_fill_rate` | property | `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:781` | +| `num_random_samplings` | property | `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:785` | +| `rand_xor_mask` | property | `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:789` | + +### get_handle + +```python +def get_handle(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:737`_ + +### max_queries + +```python +def max_queries(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:741`_ + +### itopk_size + +```python +def itopk_size(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:745`_ + +### max_iterations + +```python +def max_iterations(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:749`_ + +### algo + +```python +def algo(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:753`_ + +### team_size + +```python +def team_size(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:757`_ + +### search_width + +```python +def search_width(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:761`_ + +### min_iterations + +```python +def min_iterations(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:765`_ + +### thread_block_size + +```python +def thread_block_size(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:769`_ + +### hashmap_mode + +```python +def hashmap_mode(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:773`_ + +### hashmap_min_bitlen + +```python +def hashmap_min_bitlen(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:777`_ + +### hashmap_max_fill_rate + +```python +def hashmap_max_fill_rate(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:781`_ + +### num_random_samplings + +```python +def num_random_samplings(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:785`_ + +### rand_xor_mask + +```python +def rand_xor_mask(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:789`_ + +_Source: `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:601`_ + +## build + +`@auto_sync_resources` + +```python +def build(IndexParams index_params, dataset, resources=None) +``` + +Build the CAGRA index from the dataset for efficient search. + +The build performs two different steps- first an intermediate knn-graph is +constructed, then it's optimized it to create the final graph. The +index_params object controls the node degree of these graphs. + +It is required that both the dataset and the optimized graph fit the +GPU memory. + +Note: When using ACE (Augmented Core Extraction) build algorithm, the +dataset must be in host memory (CPU). The ACE algorithm is designed for +datasets too large to fit in GPU memory. + +The following distance metrics are supported: +- L2 +- InnerProduct +- Cosine + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `index_params` | `IndexParams object` | | +| `dataset` | `CUDA array interface compliant matrix shape (n_samples, dim)` | Supported dtype [float, half, int8, uint8] **Note:** For ACE build algorithm, the dataset MUST be in host memory. Use NumPy arrays or call .get() on CuPy arrays before passing. | +| `resources` | `cuvs.common.Resources, optional` | | + +**Returns** + +| Name | Type | Description | +| --- | --- | --- | +| `index` | `cuvs.cagra.Index` | | + +**Examples** + +```python +>>> import cupy as cp +>>> from cuvs.neighbors import cagra +>>> n_samples = 50000 +>>> n_features = 50 +>>> n_queries = 1000 +>>> k = 10 +>>> dataset = cp.random.random_sample((n_samples, n_features), +... dtype=cp.float32) +>>> build_params = cagra.IndexParams(metric="sqeuclidean") +>>> index = cagra.build(build_params, dataset) +>>> queries = cp.random.random_sample((n_queries, n_features), +... dtype=cp.float32) +>>> distances, neighbors = cagra.search(cagra.SearchParams(), +... index, queries, +... k) +>>> distances = cp.asarray(distances) +>>> neighbors = cp.asarray(neighbors) +``` + +_Source: `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:497`_ + +## extend + +`@auto_sync_resources` + +```python +def extend(ExtendParams params, Index index, additional_dataset, resources=None) +``` + +Extend a CAGRA index with additional vectors + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `params` | `ExtendParams object` | | +| `index` | `Index` | Existing cagra index to extend | +| `additional_dataset` | `CUDA array interface compliant matrix shape` | Supported dtype [float, half, int8, uint8] | +| `resources` | `cuvs.common.Resources, optional` | | + +_Source: `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:1065`_ + +## from_graph + +`@auto_sync_resources` + +```python +def from_graph(graph, dataset, metric="sqeuclidean", resources=None) +``` + +Construct a cagra index from an existing graph and dataset + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `graph` | `Array interface compliant matrix with shape (n_samples, graph_degree)` | | +| `dataset` | `Array interface compliant matrix shape (n_samples, dim)` | Supported dtype [float32, float16, int8, uint8] | +| `metric` | `str` | | +| `resources` | `cuvs.common.Resources, optional` | | + +**Returns** + +| Name | Type | Description | +| --- | --- | --- | +| `index` | `cuvs.cagra.Index` | | + +_Source: `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:987`_ + +## load + +`@auto_sync_resources` + +```python +def load(filename, resources=None) +``` + +Loads index from file. + +Saving / loading the index is experimental. The serialization format is +subject to change, therefore loading an index saved with a previous +version of cuvs is not guaranteed to work. + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `filename` | `string` | Name of the file. | +| `resources` | `cuvs.common.Resources, optional` | | + +**Returns** + +| Name | Type | Description | +| --- | --- | --- | +| `index` | `Index` | | + +_Source: `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:954`_ + +## save + +`@auto_sync_resources` + +```python +def save(filename, Index index, bool include_dataset=True, resources=None) +``` + +Saves the index to a file. + +Saving / loading the index is experimental. The serialization format is +subject to change. + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `filename` | `string` | Name of the file. | +| `index` | `Index` | Trained CAGRA index. | +| `include_dataset` | `bool` | Whether or not to write out the dataset along with the index. Including the dataset in the serialized index will use extra disk space, and might not be desired if you already have a copy of the dataset on disk. If this option is set to false, you will have to call `index.update_dataset(dataset)` after loading the index. | +| `resources` | `cuvs.common.Resources, optional` | | + +**Examples** + +```python +>>> import cupy as cp +>>> from cuvs.neighbors import cagra +>>> n_samples = 50000 +>>> n_features = 50 +>>> dataset = cp.random.random_sample((n_samples, n_features), +... dtype=cp.float32) +>>> # Build index +>>> index = cagra.build(cagra.IndexParams(), dataset) +>>> # Serialize and deserialize the cagra index built +>>> cagra.save("my_index.bin", index) +>>> index_loaded = cagra.load("my_index.bin") +``` + +_Source: `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:910`_ + +## search + +`@auto_sync_resources` +`@auto_convert_output` + +```python +def search(SearchParams search_params, Index index, queries, k, neighbors=None, distances=None, resources=None, filter=None) +``` + +Find the k nearest neighbors for each query. + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `search_params` | `SearchParams` | | +| `index` | `Index` | Trained CAGRA index. | +| `queries` | `CUDA array interface compliant matrix shape (n_samples, dim)` | Supported dtype [float, int8, uint8] | +| `k` | `int` | The number of neighbors. | +| `neighbors` | `Optional CUDA array interface compliant matrix shape` | (n_queries, k), dtype int64_t. If supplied, neighbor indices will be written here in-place. (default None) | +| `distances` | `Optional CUDA array interface compliant matrix shape` | (n_queries, k) If supplied, the distances to the neighbors will be written here in-place. (default None) | +| `filter` | `Optional cuvs.neighbors.cuvsFilter can be used to filter` | neighbors based on a given bitset. (default None) | +| `resources` | `cuvs.common.Resources, optional` | | + +**Examples** + +```python +>>> import cupy as cp +>>> from cuvs.neighbors import cagra +>>> n_samples = 50000 +>>> n_features = 50 +>>> n_queries = 1000 +>>> dataset = cp.random.random_sample((n_samples, n_features), +... dtype=cp.float32) +>>> # Build index +>>> index = cagra.build(cagra.IndexParams(), dataset) +>>> # Search using the built index +>>> queries = cp.random.random_sample((n_queries, n_features), +... dtype=cp.float32) +>>> k = 10 +>>> search_params = cagra.SearchParams( +... max_queries=100, +... itopk_size=64 +... ) +>>> # Using a pooling allocator reduces overhead of temporary array +>>> # creation during search. This is useful if multiple searches +>>> # are performed with same query size. +>>> distances, neighbors = cagra.search(search_params, index, queries, +... k) +>>> neighbors = cp.asarray(neighbors) +>>> distances = cp.asarray(distances) +``` + +_Source: `python/cuvs/cuvs/neighbors/cagra/cagra.pyx:795`_ diff --git a/fern/pages/python_api/python-api-neighbors-filters.md b/fern/pages/python_api/python-api-neighbors-filters.md new file mode 100644 index 0000000000..eedea7b127 --- /dev/null +++ b/fern/pages/python_api/python-api-neighbors-filters.md @@ -0,0 +1,107 @@ +--- +slug: api-reference/python-api-neighbors-filters +--- + +# Filters + +_Python module: `cuvs.neighbors.filters`_ + +## no_filter + +```python +def no_filter() +``` + +Create a default pre-filter which filters nothing. + +_Source: `python/cuvs/cuvs/neighbors/filters/filters.pyx:29`_ + +## from_bitmap + +```python +def from_bitmap(bitmap) +``` + +Create a pre-filter from an array with type of uint32. + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `bitmap` | `numpy.ndarray` | An array with type of `uint32` where each bit in the array corresponds to if a sample and query pair is greenlit (not filtered) or filtered. The array is row-major, meaning the bits are ordered by rows first. Each bit in a `uint32` element represents a different sample-query pair.

- Bit value of 1: The sample-query pair is greenlit (allowed). - Bit value of 0: The sample-query pair is filtered. | + +**Returns** + +| Name | Type | Description | +| --- | --- | --- | +| `filter` | `cuvs.neighbors.filters.Prefilter` | An instance of `Prefilter` that can be used to filter neighbors based on the given bitmap. | +| `resources` | `cuvs.common.Resources, optional` | | + +**Examples** + +```python +>>> import cupy as cp +>>> import numpy as np +>>> from cuvs.neighbors import filters +>>> +>>> n_samples = 50000 +>>> n_queries = 1000 +>>> +>>> n_bitmap = np.ceil(n_samples * n_queries / 32).astype(int) +>>> bitmap = cp.random.randint(1, 100, size=(n_bitmap,), dtype=cp.uint32) +>>> prefilter = filters.from_bitmap(bitmap) +``` + +_Source: `python/cuvs/cuvs/neighbors/filters/filters.pyx:39`_ + +## from_bitset + +```python +def from_bitset(bitset) +``` + +Create a pre-filter from an array with type of uint32. + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `bitset` | `numpy.ndarray` | An array with type of `uint32` where each bit in the array corresponds to if a sample is greenlit (not filtered) or filtered. Each bit in a `uint32` element represents a different sample of the dataset.

- Bit value of 1: The sample is greenlit (allowed). - Bit value of 0: The sample pair is filtered. | + +**Returns** + +| Name | Type | Description | +| --- | --- | --- | +| `filter` | `cuvs.neighbors.filters.Prefilter` | An instance of `Prefilter` that can be used to filter neighbors based on the given bitset. | +| `resources` | `cuvs.common.Resources, optional` | | + +**Examples** + +```python +>>> import cupy as cp +>>> import numpy as np +>>> from cuvs.neighbors import filters +>>> +>>> n_samples = 50000 +>>> n_queries = 1000 +>>> +>>> n_bitset = np.ceil(n_samples / 32).astype(int) +>>> bitset = cp.random.randint(1, 100, size=(n_bitset,), dtype=cp.uint32) +>>> prefilter = filters.from_bitset(bitset) +``` + +_Source: `python/cuvs/cuvs/neighbors/filters/filters.pyx:89`_ + +## Prefilter + +```python +cdef class Prefilter +``` + +**Constructor** + +```python +def __init__(self, cuvsFilter prefilter, parent=None) +``` + +_Source: `python/cuvs/cuvs/neighbors/filters/filters.pyx:19`_ diff --git a/fern/pages/python_api/python-api-neighbors-hnsw.md b/fern/pages/python_api/python-api-neighbors-hnsw.md new file mode 100644 index 0000000000..d06de7b770 --- /dev/null +++ b/fern/pages/python_api/python-api-neighbors-hnsw.md @@ -0,0 +1,593 @@ +--- +slug: api-reference/python-api-neighbors-hnsw +--- + +# HNSW + +_Python module: `cuvs.neighbors.hnsw`_ + +## AceParams + +```python +cdef class AceParams +``` + +Parameters for ACE (Augmented Core Extraction) graph build for HNSW. + +ACE enables building HNSW indices for datasets too large to fit in GPU +memory by partitioning the dataset and building sub-indices for each +partition independently. + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `npartitions` | `int, default = 0 (optional)` | Number of partitions for ACE partitioned build. When set to 0 (default), the number of partitions is automatically derived based on available host and GPU memory to maximize partition size while ensuring the build fits in memory.

Small values might improve recall but potentially degrade performance and increase memory usage. Partitions should not be too small to prevent issues in KNN graph construction. The partition size is on average 2 * (n_rows / npartitions) * dim * sizeof(T). 2 is because of the core and augmented vectors. Please account for imbalance in the partition sizes (up to 3x in our tests).

If the specified number of partitions results in partitions that exceed available memory, the value will be automatically increased to fit memory constraints and a warning will be issued. | +| `build_dir` | `string, default = "/tmp/hnsw_ace_build" (optional)` | Directory to store ACE build artifacts (KNN graph, optimized graph). Used when `use_disk` is true or when the graph does not fit in memory. | +| `use_disk` | `bool, default = False (optional)` | Whether to use disk-based storage for ACE build. When true, enables disk-based operations for memory-efficient graph construction. | +| `max_host_memory_gb` | `float, default = 0 (optional)` | Maximum host memory to use for ACE build in GiB. When set to 0 (default), uses available host memory. Useful for testing or when running alongside other memory-intensive processes. | +| `max_gpu_memory_gb` | `float, default = 0 (optional)` | Maximum GPU memory to use for ACE build in GiB. When set to 0 (default), uses available GPU memory. Useful for testing or when running alongside other memory-intensive processes. | + +**Constructor** + +```python +def __init__(self, *, npartitions=0, build_dir="/tmp/hnsw_ace_build", use_disk=False, max_host_memory_gb=0, max_gpu_memory_gb=0) +``` + +**Members** + +| Name | Kind | Source | +| --- | --- | --- | +| `npartitions` | property | `python/cuvs/cuvs/neighbors/hnsw/hnsw.pyx:98` | +| `build_dir` | property | `python/cuvs/cuvs/neighbors/hnsw/hnsw.pyx:102` | +| `use_disk` | property | `python/cuvs/cuvs/neighbors/hnsw/hnsw.pyx:108` | +| `max_host_memory_gb` | property | `python/cuvs/cuvs/neighbors/hnsw/hnsw.pyx:112` | +| `max_gpu_memory_gb` | property | `python/cuvs/cuvs/neighbors/hnsw/hnsw.pyx:116` | + +### npartitions + +```python +def npartitions(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/hnsw/hnsw.pyx:98`_ + +### build_dir + +```python +def build_dir(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/hnsw/hnsw.pyx:102`_ + +### use_disk + +```python +def use_disk(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/hnsw/hnsw.pyx:108`_ + +### max_host_memory_gb + +```python +def max_host_memory_gb(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/hnsw/hnsw.pyx:112`_ + +### max_gpu_memory_gb + +```python +def max_gpu_memory_gb(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/hnsw/hnsw.pyx:116`_ + +_Source: `python/cuvs/cuvs/neighbors/hnsw/hnsw.pyx:31`_ + +## IndexParams + +```python +cdef class IndexParams +``` + +Parameters to build index for HNSW nearest neighbor search + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `hierarchy` | `string, default = "gpu" (optional)` | The hierarchy of the HNSW index. Valid values are ["none", "cpu", "gpu"]. - "none": No hierarchy is built. - "cpu": Hierarchy is built using CPU. - "gpu": Hierarchy is built using GPU. | +| `ef_construction` | `int, default = 200 (optional)` | Maximum number of candidate list size used during construction when hierarchy is `cpu`. | +| `num_threads` | `int, default = 0 (optional)` | Number of CPU threads used to increase construction parallelism when hierarchy is `cpu` or `gpu`. When the value is 0, the number of threads is automatically determined to the maximum number of threads available. NOTE: When hierarchy is `gpu`, while the majority of the work is done on the GPU, initialization of the HNSW index itself and some other work is parallelized with the help of CPU threads. | +| `M` | `int, default = 32 (optional)` | HNSW M parameter: number of bi-directional links per node (used when building with ACE). graph_degree = m * 2, intermediate_graph_degree = m * 3. | +| `metric` | `string, default = "sqeuclidean" (optional)` | Distance metric to use. Valid values: ["sqeuclidean", "inner_product"] | +| `ace_params` | `AceParams, default = None (optional)` | ACE parameters for building HNSW index using ACE algorithm. If set, enables the build() function to use ACE for index construction. | + +**Constructor** + +```python +def __init__(self, *, hierarchy="gpu", ef_construction=200, num_threads=0, M=32, metric="sqeuclidean", ace_params=None) +``` + +**Members** + +| Name | Kind | Source | +| --- | --- | --- | +| `hierarchy` | property | `python/cuvs/cuvs/neighbors/hnsw/hnsw.pyx:193` | +| `ef_construction` | property | `python/cuvs/cuvs/neighbors/hnsw/hnsw.pyx:202` | +| `num_threads` | property | `python/cuvs/cuvs/neighbors/hnsw/hnsw.pyx:206` | +| `m` | property | `python/cuvs/cuvs/neighbors/hnsw/hnsw.pyx:210` | +| `ace_params` | property | `python/cuvs/cuvs/neighbors/hnsw/hnsw.pyx:214` | + +### hierarchy + +```python +def hierarchy(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/hnsw/hnsw.pyx:193`_ + +### ef_construction + +```python +def ef_construction(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/hnsw/hnsw.pyx:202`_ + +### num_threads + +```python +def num_threads(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/hnsw/hnsw.pyx:206`_ + +### m + +```python +def m(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/hnsw/hnsw.pyx:210`_ + +### ace_params + +```python +def ace_params(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/hnsw/hnsw.pyx:214`_ + +_Source: `python/cuvs/cuvs/neighbors/hnsw/hnsw.pyx:120`_ + +## Index + +```python +cdef class Index +``` + +HNSW index object. This object stores the trained HNSW index state +which can be used to perform nearest neighbors searches. + +**Members** + +| Name | Kind | Source | +| --- | --- | --- | +| `trained` | property | `python/cuvs/cuvs/neighbors/hnsw/hnsw.pyx:236` | + +### trained + +```python +def trained(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/hnsw/hnsw.pyx:236`_ + +_Source: `python/cuvs/cuvs/neighbors/hnsw/hnsw.pyx:218`_ + +## ExtendParams + +```python +cdef class ExtendParams +``` + +Parameters to extend the HNSW index with new data + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `num_threads` | `int, default = 0 (optional)` | Number of CPU threads used to increase construction parallelism. When set to 0, the number of threads is automatically determined. | + +**Constructor** + +```python +def __init__(self, *, num_threads=0) +``` + +**Members** + +| Name | Kind | Source | +| --- | --- | --- | +| `num_threads` | property | `python/cuvs/cuvs/neighbors/hnsw/hnsw.pyx:269` | + +### num_threads + +```python +def num_threads(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/hnsw/hnsw.pyx:269`_ + +_Source: `python/cuvs/cuvs/neighbors/hnsw/hnsw.pyx:245`_ + +## build + +`@auto_sync_resources` + +```python +def build(IndexParams index_params, dataset, resources=None) +``` + +Build an HNSW index using the ACE (Augmented Core Extraction) algorithm. + +ACE enables building HNSW indices for datasets too large to fit in GPU +memory by partitioning the dataset and building sub-indices for each +partition independently. + +NOTE: This function requires `index_params.ace_params` to be set with +an instance of AceParams. + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `index_params` | `IndexParams` | Parameters for the HNSW index with ACE configuration. Must have `ace_params` set. | +| `dataset` | `Host array interface compliant matrix shape (n_samples, dim)` | Supported dtype [float32, float16, int8, uint8] | +| `resources` | `cuvs.common.Resources, optional` | | + +**Returns** + +| Name | Type | Description | +| --- | --- | --- | +| `index` | `Index` | Trained HNSW index ready for search. | + +**Examples** + +```python +>>> import numpy as np +>>> from cuvs.neighbors import hnsw +>>> +>>> n_samples = 50000 +>>> n_features = 50 +>>> dataset = np.random.random_sample((n_samples, n_features), +... dtype=np.float32) +>>> +>>> # Create ACE parameters +>>> ace_params = hnsw.AceParams( +... npartitions=4, +... use_disk=True, +... build_dir="/tmp/hnsw_ace_build" +... ) +>>> +>>> # Create index parameters with ACE +>>> index_params = hnsw.IndexParams( +... hierarchy="gpu", +... ace_params=ace_params, +... ef_construction=120, +... M=32, +... metric="sqeuclidean" +... ) +>>> +>>> # Build the index +>>> index = hnsw.build(index_params, dataset) +>>> +>>> # Search the index +>>> queries = np.random.random_sample((10, n_features), dtype=np.float32) +>>> distances, neighbors = hnsw.search( +... hnsw.SearchParams(ef=200), +... index, +... queries, +... k=10 +... ) +``` + +_Source: `python/cuvs/cuvs/neighbors/hnsw/hnsw.pyx:472`_ + +## extend + +`@auto_sync_resources` + +```python +def extend(ExtendParams extend_params, Index index, data, resources=None) +``` + +Extends the HNSW index with new data. + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `extend_params` | `ExtendParams` | | +| `index` | `Index` | Trained HNSW index. | +| `data` | `Host array interface compliant matrix shape (n_samples, dim)` | Supported dtype [float32, float16, int8, uint8] | +| `resources` | `cuvs.common.Resources, optional` | | + +**Examples** + +```python +>>> import numpy as np +>>> from cuvs.neighbors import hnsw, cagra +>>> +>>> n_samples = 50000 +>>> n_features = 50 +>>> dataset = np.random.random_sample((n_samples, n_features)) +>>> +>>> # Build index +>>> index = cagra.build(hnsw.IndexParams(), dataset) +>>> # Load index +>>> hnsw_index = hnsw.from_cagra(hnsw.IndexParams(hierarchy="cpu"), index) +>>> # Extend the index with new data +>>> new_data = np.random.random_sample((n_samples, n_features)) +>>> hnsw.extend(hnsw.ExtendParams(), hnsw_index, new_data) +``` + +_Source: `python/cuvs/cuvs/neighbors/hnsw/hnsw.pyx:561`_ + +## SearchParams + +```python +cdef class SearchParams +``` + +HNSW search parameters + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `ef` | `int, default = 200` | Maximum number of candidate list size used during search. | +| `num_threads` | `int, default = 0` | Number of CPU threads used to increase search parallelism. When set to 0, the number of threads is automatically determined using OpenMP's `omp_get_max_threads()`. | + +**Constructor** + +```python +def __init__(self, *, ef=200, num_threads=0) +``` + +**Members** + +| Name | Kind | Source | +| --- | --- | --- | +| `ef` | property | `python/cuvs/cuvs/neighbors/hnsw/hnsw.pyx:638` | +| `num_threads` | property | `python/cuvs/cuvs/neighbors/hnsw/hnsw.pyx:642` | + +### ef + +```python +def ef(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/hnsw/hnsw.pyx:638`_ + +### num_threads + +```python +def num_threads(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/hnsw/hnsw.pyx:642`_ + +_Source: `python/cuvs/cuvs/neighbors/hnsw/hnsw.pyx:609`_ + +## load + +`@auto_sync_resources` + +```python +def load(IndexParams index_params, filename, dim, dtype, metric="sqeuclidean", resources=None) +``` + +Loads an HNSW index. +If the index was constructed with `hnsw.IndexParams(hierarchy="none")`, +then the loaded index is immutable and can only be searched by the hnswlib +wrapper in cuVS, as the format is not compatible with the original hnswlib. +However, if the index was constructed with +`hnsw.IndexParams(hierarchy="cpu")`, then the loaded index is mutable and +compatible with the original hnswlib. + +Saving / loading the index is experimental. The serialization format is +subject to change, therefore loading an index saved with a previous +version of cuVS is not guaranteed to work. + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `index_params` | `IndexParams` | Parameters that were used to convert CAGRA index to HNSW index. | +| `filename` | `string` | Name of the file. | +| `dim` | `int` | Dimensions of the training dataest | +| `dtype` | `np.dtype of the saved index` | Valid values for dtype: [np.float32, np.byte, np.ubyte] | +| `metric` | `string denoting the metric type, default="sqeuclidean"` | Valid values for metric: ["sqeuclidean", "inner_product"], where - sqeuclidean is the euclidean distance without the square root operation, i.e.: distance(a,b) = \\sum_i (a_i - b_i)^2, - inner_product distance is defined as distance(a, b) = \\sum_i a_i * b_i. | +| `resources` | `cuvs.common.Resources, optional` | | + +**Returns** + +| Name | Type | Description | +| --- | --- | --- | +| `index` | `HnswIndex` | | + +**Examples** + +```python +>>> import cupy as cp +>>> from cuvs.neighbors import cagra +>>> from cuvs.neighbors import hnsw +>>> n_samples = 50000 +>>> n_features = 50 +>>> dataset = cp.random.random_sample((n_samples, n_features), +... dtype=cp.float32) +>>> # Build index +>>> index = cagra.build(cagra.IndexParams(), dataset) +>>> # Serialize the CAGRA index to hnswlib base layer only index format +>>> hnsw.save("my_index.bin", index) +>>> index = hnsw.load("my_index.bin", n_features, np.float32, +... "sqeuclidean") +``` + +_Source: `python/cuvs/cuvs/neighbors/hnsw/hnsw.pyx:317`_ + +## save + +`@auto_sync_resources` + +```python +def save(filename, Index index, resources=None) +``` + +Saves the CAGRA index to a file as an hnswlib index. +If the index was constructed with `hnsw.IndexParams(hierarchy="none")`, +then the saved index is immutable and can only be searched by the hnswlib +wrapper in cuVS, as the format is not compatible with the original hnswlib. +However, if the index was constructed with +`hnsw.IndexParams(hierarchy="cpu")`, then the saved index is mutable and +compatible with the original hnswlib. + +Saving / loading the index is experimental. The serialization format is +subject to change. + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `filename` | `string` | Name of the file. | +| `index` | `Index` | Trained HNSW index. | +| `resources` | `cuvs.common.Resources, optional` | | + +**Examples** + +```python +>>> import cupy as cp +>>> from cuvs.neighbors import cagra +>>> n_samples = 50000 +>>> n_features = 50 +>>> dataset = cp.random.random_sample((n_samples, n_features), +... dtype=cp.float32) +>>> # Build index +>>> cagra_index = cagra.build(cagra.IndexParams(), dataset) +>>> # Serialize and deserialize the cagra index built +>>> hnsw_index = hnsw.from_cagra(hnsw.IndexParams(), cagra_index) +>>> hnsw.save("my_index.bin", hnsw_index) +``` + +_Source: `python/cuvs/cuvs/neighbors/hnsw/hnsw.pyx:274`_ + +## search + +`@auto_sync_resources` +`@auto_convert_output` + +```python +def search(SearchParams search_params, Index index, queries, k, neighbors=None, distances=None, resources=None) +``` + +Find the k nearest neighbors for each query. + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `search_params` | `SearchParams` | | +| `index` | `Index` | Trained HNSW index. | +| `queries` | `CPU array interface compliant matrix shape (n_samples, dim)` | Supported dtype [float, int] | +| `k` | `int` | The number of neighbors. | +| `neighbors` | `Optional CPU array interface compliant matrix shape` | (n_queries, k), dtype uint64_t. If supplied, neighbor indices will be written here in-place. (default None) | +| `distances` | `Optional CPU array interface compliant matrix shape` | (n_queries, k) If supplied, the distances to the neighbors will be written here in-place. (default None) | +| `resources` | `cuvs.common.Resources, optional` | | + +**Examples** + +```python +>>> import cupy as cp +>>> from cuvs.neighbors import cagra, hnsw +>>> n_samples = 50000 +>>> n_features = 50 +>>> n_queries = 1000 +>>> dataset = cp.random.random_sample((n_samples, n_features), +... dtype=cp.float32) +>>> # Build index +>>> index = cagra.build(cagra.IndexParams(), dataset) +>>> # Search using the built index +>>> queries = cp.random.random_sample((n_queries, n_features), +... dtype=cp.float32) +>>> k = 10 +>>> search_params = hnsw.SearchParams( +... ef=200, +... num_threads=0 +... ) +>>> # Convert CAGRA index to HNSW +>>> hnsw_index = hnsw.from_cagra(hnsw.IndexParams(), index) +>>> # Using a pooling allocator reduces overhead of temporary array +>>> # creation during search. This is useful if multiple searches +>>> # are performed with same query size. +>>> distances, neighbors = hnsw.search(search_params, index, queries, +... k) +>>> neighbors = cp.asarray(neighbors) +>>> distances = cp.asarray(distances) +``` + +_Source: `python/cuvs/cuvs/neighbors/hnsw/hnsw.pyx:648`_ + +## from_cagra + +`@auto_sync_resources` + +```python +def from_cagra(IndexParams index_params, cagra.Index cagra_index, temporary_index_path=None, resources=None) +``` + +Returns an HNSW index from a CAGRA index. + +NOTE: When `index_params.hierarchy` is: + +1. `NONE`: This method uses the filesystem to write the CAGRA index in +`/tmp/<random_number>.bin` before reading it as an hnswlib index, then +deleting the temporary file. The returned index is immutable and can only +be searched by the hnswlib wrapper in cuVS, as the format is not +compatible with the original hnswlib. +2. `CPU`: The returned index is mutable and can be extended with additional +vectors. The serialized index is also compatible with the original hnswlib +library. + +Saving / loading the index is experimental. The serialization format is +subject to change. + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `index_params` | `IndexParams` | Parameters to convert the CAGRA index to HNSW index. | +| `cagra_index` | `cagra.Index` | Trained CAGRA index. | +| `temporary_index_path` | `string, default = None` | Path to save the temporary index file. If None, the temporary file will be saved in `/tmp/<random_number>.bin`. | +| `resources` | `cuvs.common.Resources, optional` | | + +**Examples** + +```python +>>> import cupy as cp +>>> from cuvs.neighbors import cagra +>>> from cuvs.neighbors import hnsw +>>> n_samples = 50000 +>>> n_features = 50 +>>> dataset = cp.random.random_sample((n_samples, n_features), +... dtype=cp.float32) +>>> # Build index +>>> index = cagra.build(cagra.IndexParams(), dataset) +>>> # Serialize the CAGRA index to hnswlib base layer only index format +>>> hnsw_index = hnsw.from_cagra(hnsw.IndexParams(), index) +``` + +_Source: `python/cuvs/cuvs/neighbors/hnsw/hnsw.pyx:410`_ diff --git a/fern/pages/python_api/python-api-neighbors-ivf-flat.md b/fern/pages/python_api/python-api-neighbors-ivf-flat.md new file mode 100644 index 0000000000..8be854a43a --- /dev/null +++ b/fern/pages/python_api/python-api-neighbors-ivf-flat.md @@ -0,0 +1,441 @@ +--- +slug: api-reference/python-api-neighbors-ivf-flat +--- + +# IVF Flat + +_Python module: `cuvs.neighbors.ivf_flat`_ + +## Index + +```python +cdef class Index +``` + +IvfFlat index object. This object stores the trained IvfFlat index state +which can be used to perform nearest neighbors searches. + +**Members** + +| Name | Kind | Source | +| --- | --- | --- | +| `trained` | property | `python/cuvs/cuvs/neighbors/ivf_flat/ivf_flat.pyx:170` | +| `n_lists` | property | `python/cuvs/cuvs/neighbors/ivf_flat/ivf_flat.pyx:177` | +| `dim` | property | `python/cuvs/cuvs/neighbors/ivf_flat/ivf_flat.pyx:184` | +| `centers` | property | `python/cuvs/cuvs/neighbors/ivf_flat/ivf_flat.pyx:191` | + +### trained + +```python +def trained(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/ivf_flat/ivf_flat.pyx:170`_ + +### n_lists + +```python +def n_lists(self) +``` + +The number of inverted lists (clusters) + +_Source: `python/cuvs/cuvs/neighbors/ivf_flat/ivf_flat.pyx:177`_ + +### dim + +```python +def dim(self) +``` + +dimensionality of the cluster centers + +_Source: `python/cuvs/cuvs/neighbors/ivf_flat/ivf_flat.pyx:184`_ + +### centers + +```python +def centers(self) +``` + +Get the cluster centers corresponding to the lists in the +original space + +_Source: `python/cuvs/cuvs/neighbors/ivf_flat/ivf_flat.pyx:191`_ + +_Source: `python/cuvs/cuvs/neighbors/ivf_flat/ivf_flat.pyx:153`_ + +## IndexParams + +```python +cdef class IndexParams +``` + +Parameters to build index for IvfFlat nearest neighbor search + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `n_lists` | `int, default = 1024` | The number of clusters used in the coarse quantizer. | +| `metric` | `str, default = "sqeuclidean"` | String denoting the metric type. Valid values for metric: ["sqeuclidean", "inner_product", "euclidean", "cosine"], where

- sqeuclidean is the euclidean distance without the square root operation, i.e.: distance(a,b) = \\sum_i (a_i - b_i)^2, - euclidean is the euclidean distance - inner product distance is defined as distance(a, b) = \\sum_i a_i * b_i. - cosine distance is defined as distance(a, b) = 1 - \\sum_i a_i * b_i / ( \|\|a\|\|_2 * \|\|b\|\|_2). | +| `kmeans_n_iters` | `int, default = 20` | The number of iterations searching for kmeans centers during index building. The default setting is often fine, but this parameter can be decreased to improve training time wih larger trainset fractions (10M+ vectors) or increased for smaller trainset fractions (very small number of vectors) to improve recall. | +| `kmeans_trainset_fraction` | `int, default = 0.5` | If kmeans_trainset_fraction is less than 1, then the dataset is subsampled, and only n_samples * kmeans_trainset_fraction rows are used for training. | +| `add_data_on_build` | `bool, default = True` | After training the coarse and fine quantizers, we will populate the index with the dataset if add_data_on_build == True, otherwise the index is left empty, and the extend method can be used to add new vectors to the index. | +| `adaptive_centers` | `bool, default = False` | By default (adaptive_centers = False), the cluster centers are trained in `ivf_flat.build`, and and never modified in `ivf_flat.extend`. The alternative behavior (adaptive_centers = true) is to update the cluster centers for new data when it is added. In this case, `index.centers()` are always exactly the centroids of the data in the corresponding clusters. The drawback of this behavior is that the centroids depend on the order of adding new data (through the classification of the added data); that is, `index.centers()` "drift" together with the changing distribution of the newly added data. | + +**Constructor** + +```python +def __init__(self, *, n_lists=1024, metric="sqeuclidean", metric_arg=2.0, kmeans_n_iters=20, kmeans_trainset_fraction=0.5, adaptive_centers=False, add_data_on_build=True, conservative_memory_allocation=False) +``` + +**Members** + +| Name | Kind | Source | +| --- | --- | --- | +| `get_handle` | method | `python/cuvs/cuvs/neighbors/ivf_flat/ivf_flat.pyx:117` | +| `metric` | property | `python/cuvs/cuvs/neighbors/ivf_flat/ivf_flat.pyx:121` | +| `metric_arg` | property | `python/cuvs/cuvs/neighbors/ivf_flat/ivf_flat.pyx:125` | +| `add_data_on_build` | property | `python/cuvs/cuvs/neighbors/ivf_flat/ivf_flat.pyx:129` | +| `n_lists` | property | `python/cuvs/cuvs/neighbors/ivf_flat/ivf_flat.pyx:133` | +| `kmeans_n_iters` | property | `python/cuvs/cuvs/neighbors/ivf_flat/ivf_flat.pyx:137` | +| `kmeans_trainset_fraction` | property | `python/cuvs/cuvs/neighbors/ivf_flat/ivf_flat.pyx:141` | +| `adaptive_centers` | property | `python/cuvs/cuvs/neighbors/ivf_flat/ivf_flat.pyx:145` | +| `conservative_memory_allocation` | property | `python/cuvs/cuvs/neighbors/ivf_flat/ivf_flat.pyx:149` | + +### get_handle + +```python +def get_handle(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/ivf_flat/ivf_flat.pyx:117`_ + +### metric + +```python +def metric(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/ivf_flat/ivf_flat.pyx:121`_ + +### metric_arg + +```python +def metric_arg(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/ivf_flat/ivf_flat.pyx:125`_ + +### add_data_on_build + +```python +def add_data_on_build(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/ivf_flat/ivf_flat.pyx:129`_ + +### n_lists + +```python +def n_lists(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/ivf_flat/ivf_flat.pyx:133`_ + +### kmeans_n_iters + +```python +def kmeans_n_iters(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/ivf_flat/ivf_flat.pyx:137`_ + +### kmeans_trainset_fraction + +```python +def kmeans_trainset_fraction(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/ivf_flat/ivf_flat.pyx:141`_ + +### adaptive_centers + +```python +def adaptive_centers(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/ivf_flat/ivf_flat.pyx:145`_ + +### conservative_memory_allocation + +```python +def conservative_memory_allocation(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/ivf_flat/ivf_flat.pyx:149`_ + +_Source: `python/cuvs/cuvs/neighbors/ivf_flat/ivf_flat.pyx:41`_ + +## SearchParams + +```python +cdef class SearchParams +``` + +Supplemental parameters to search IVF-Flat index + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `n_probes` | `int` | The number of clusters to search. | + +**Constructor** + +```python +def __init__(self, *, n_probes=20) +``` + +**Members** + +| Name | Kind | Source | +| --- | --- | --- | +| `get_handle` | method | `python/cuvs/cuvs/neighbors/ivf_flat/ivf_flat.pyx:285` | +| `n_probes` | property | `python/cuvs/cuvs/neighbors/ivf_flat/ivf_flat.pyx:289` | + +### get_handle + +```python +def get_handle(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/ivf_flat/ivf_flat.pyx:285`_ + +### n_probes + +```python +def n_probes(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/ivf_flat/ivf_flat.pyx:289`_ + +_Source: `python/cuvs/cuvs/neighbors/ivf_flat/ivf_flat.pyx:265`_ + +## build + +`@auto_sync_resources` + +```python +def build(IndexParams index_params, dataset, resources=None) +``` + +Build the IvfFlat index from the dataset for efficient search. + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `index_params` | `cuvs.neighbors.ivf_flat.IndexParams` | | +| `dataset` | `CUDA array interface compliant matrix shape (n_samples, dim)` | Supported dtype [float32, float16, int8, uint8] | +| `resources` | `cuvs.common.Resources, optional` | | + +**Returns** + +| Name | Type | Description | +| --- | --- | --- | +| `index` | `cuvs.neighbors.ivf_flat.Index` | | + +**Examples** + +```python +>>> import cupy as cp +>>> from cuvs.neighbors import ivf_flat +>>> n_samples = 50000 +>>> n_features = 50 +>>> n_queries = 1000 +>>> k = 10 +>>> dataset = cp.random.random_sample((n_samples, n_features), +... dtype=cp.float32) +>>> build_params = ivf_flat.IndexParams(metric="sqeuclidean") +>>> index = ivf_flat.build(build_params, dataset) +>>> distances, neighbors = ivf_flat.search(ivf_flat.SearchParams(), +... index, dataset, +... k) +>>> distances = cp.asarray(distances) +>>> neighbors = cp.asarray(neighbors) +``` + +_Source: `python/cuvs/cuvs/neighbors/ivf_flat/ivf_flat.pyx:207`_ + +## extend + +`@auto_sync_resources` + +```python +def extend(Index index, new_vectors, new_indices, resources=None) +``` + +Extend an existing index with new vectors. + +The input array can be either CUDA array interface compliant matrix or +array interface compliant matrix in host memory. + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `index` | `ivf_flat.Index` | Trained ivf_flat object. | +| `new_vectors` | `array interface compliant matrix shape (n_samples, dim)` | Supported dtype [float32, float16, int8, uint8] | +| `new_indices` | `array interface compliant vector shape (n_samples)` | Supported dtype [int64] | +| `resources` | `cuvs.common.Resources, optional` | | + +**Returns** + +| Name | Type | Description | +| --- | --- | --- | +| `index` | `cuvs.neighbors.ivf_flat.Index` | | + +**Examples** + +```python +>>> import cupy as cp +>>> from cuvs.neighbors import ivf_flat +>>> n_samples = 50000 +>>> n_features = 50 +>>> n_queries = 1000 +>>> dataset = cp.random.random_sample((n_samples, n_features), +... dtype=cp.float32) +>>> index = ivf_flat.build(ivf_flat.IndexParams(), dataset) +>>> n_rows = 100 +>>> more_data = cp.random.random_sample((n_rows, n_features), +... dtype=cp.float32) +>>> indices = n_samples + cp.arange(n_rows, dtype=cp.int64) +>>> index = ivf_flat.extend(index, more_data, indices) +>>> # Search using the built index +>>> queries = cp.random.random_sample((n_queries, n_features), +... dtype=cp.float32) +>>> distances, neighbors = ivf_flat.search(ivf_flat.SearchParams(), +... index, queries, +... k=10) +``` + +_Source: `python/cuvs/cuvs/neighbors/ivf_flat/ivf_flat.pyx:467`_ + +## load + +`@auto_sync_resources` + +```python +def load(filename, resources=None) +``` + +Loads index from file. + +Saving / loading the index is experimental. The serialization format is +subject to change, therefore loading an index saved with a previous +version of cuvs is not guaranteed to work. + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `filename` | `string` | Name of the file. | +| `resources` | `cuvs.common.Resources, optional` | | + +**Returns** + +| Name | Type | Description | +| --- | --- | --- | +| `index` | `Index` | | + +_Source: `python/cuvs/cuvs/neighbors/ivf_flat/ivf_flat.pyx:434`_ + +## save + +`@auto_sync_resources` + +```python +def save(filename, Index index, bool include_dataset=True, resources=None) +``` + +Saves the index to a file. + +Saving / loading the index is experimental. The serialization format is +subject to change. + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `filename` | `string` | Name of the file. | +| `index` | `Index` | Trained IVF-Flat index. | +| `resources` | `cuvs.common.Resources, optional` | | + +**Examples** + +```python +>>> import cupy as cp +>>> from cuvs.neighbors import ivf_flat +>>> n_samples = 50000 +>>> n_features = 50 +>>> dataset = cp.random.random_sample((n_samples, n_features), +... dtype=cp.float32) +>>> # Build index +>>> index = ivf_flat.build(ivf_flat.IndexParams(), dataset) +>>> # Serialize and deserialize the ivf_flat index built +>>> ivf_flat.save("my_index.bin", index) +>>> index_loaded = ivf_flat.load("my_index.bin") +``` + +_Source: `python/cuvs/cuvs/neighbors/ivf_flat/ivf_flat.pyx:397`_ + +## search + +`@auto_sync_resources` +`@auto_convert_output` + +```python +def search(SearchParams search_params, Index index, queries, k, neighbors=None, distances=None, resources=None, filter=None) +``` + +Find the k nearest neighbors for each query. + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `search_params` | `cuvs.neighbors.ivf_flat.SearchParams` | | +| `index` | `cuvs.neighbors.ivf_flat.Index` | Trained IvfFlat index. | +| `queries` | `CUDA array interface compliant matrix shape (n_samples, dim)` | Supported dtype [float32, float16, int8, uint8] | +| `k` | `int` | The number of neighbors. | +| `neighbors` | `Optional CUDA array interface compliant matrix shape` | (n_queries, k), dtype int64_t. If supplied, neighbor indices will be written here in-place. (default None) | +| `distances` | `Optional CUDA array interface compliant matrix shape` | (n_queries, k) If supplied, the distances to the neighbors will be written here in-place. (default None) | +| `filter` | `Optional cuvs.neighbors.cuvsFilter can be used to filter` | neighbors based on a given bitset. (default None) | +| `resources` | `cuvs.common.Resources, optional` | | + +**Examples** + +```python +>>> import cupy as cp +>>> from cuvs.neighbors import ivf_flat +>>> n_samples = 50000 +>>> n_features = 50 +>>> n_queries = 1000 +>>> dataset = cp.random.random_sample((n_samples, n_features), +... dtype=cp.float32) +>>> # Build the index +>>> index = ivf_flat.build(ivf_flat.IndexParams(), dataset) +>>> +>>> # Search using the built index +>>> queries = cp.random.random_sample((n_queries, n_features), +... dtype=cp.float32) +>>> k = 10 +>>> search_params = ivf_flat.SearchParams(n_probes=20) +>>> +>>> distances, neighbors = ivf_flat.search(search_params, index, queries, +... k) +``` + +_Source: `python/cuvs/cuvs/neighbors/ivf_flat/ivf_flat.pyx:295`_ diff --git a/fern/pages/python_api/python-api-neighbors-ivf-pq.md b/fern/pages/python_api/python-api-neighbors-ivf-pq.md new file mode 100644 index 0000000000..e7b1368169 --- /dev/null +++ b/fern/pages/python_api/python-api-neighbors-ivf-pq.md @@ -0,0 +1,809 @@ +--- +slug: api-reference/python-api-neighbors-ivf-pq +--- + +# IVF PQ + +_Python module: `cuvs.neighbors.ivf_pq`_ + +## Index + +```python +cdef class Index +``` + +IvfPq index object. This object stores the trained IvfPq index state +which can be used to perform nearest neighbors searches. + +**Members** + +| Name | Kind | Source | +| --- | --- | --- | +| `trained` | property | `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:256` | +| `n_lists` | property | `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:263` | +| `dim` | property | `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:270` | +| `pq_dim` | property | `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:277` | +| `pq_len` | property | `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:284` | +| `pq_bits` | property | `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:292` | +| `centers` | property | `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:305` | +| `centers_padded` | property | `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:319` | +| `pq_centers` | property | `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:335` | +| `centers_rot` | property | `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:349` | +| `rotation_matrix` | property | `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:364` | +| `list_sizes` | property | `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:379` | +| `lists` | method | `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:392` | +| `list_data` | method | `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:411` | +| `list_indices` | method | `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:451` | + +### trained + +```python +def trained(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:256`_ + +### n_lists + +```python +def n_lists(self) +``` + +The number of inverted lists (clusters) + +_Source: `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:263`_ + +### dim + +```python +def dim(self) +``` + +dimensionality of the cluster centers + +_Source: `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:270`_ + +### pq_dim + +```python +def pq_dim(self) +``` + +The dimensionality of an encoded vector after compression by PQ + +_Source: `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:277`_ + +### pq_len + +```python +def pq_len(self) +``` + +The dimensionality of a subspace, i.e. the number of vector +components mapped to a subspace + +_Source: `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:284`_ + +### pq_bits + +```python +def pq_bits(self) +``` + +The bit length of an encoded vector element after +compression by PQ. + +_Source: `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:292`_ + +### centers + +```python +def centers(self) +``` + +Get the cluster centers corresponding to the lists in the +original space + +_Source: `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:305`_ + +### centers_padded + +```python +def centers_padded(self) +``` + +Get the padded cluster centers [n_lists, dim_ext] +where dim_ext = round_up(dim + 1, 8). +This returns contiguous data suitable for build_precomputed. + +_Source: `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:319`_ + +### pq_centers + +```python +def pq_centers(self) +``` + +Get the PQ cluster centers + +_Source: `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:335`_ + +### centers_rot + +```python +def centers_rot(self) +``` + +Get the rotated cluster centers [n_lists, rot_dim] +where rot_dim = pq_len * pq_dim + +_Source: `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:349`_ + +### rotation_matrix + +```python +def rotation_matrix(self) +``` + +Get the rotation matrix [rot_dim, dim] +Transform matrix (original space -> rotated padded space) + +_Source: `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:364`_ + +### list_sizes + +```python +def list_sizes(self) +``` + +Get the sizes of each list + +_Source: `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:379`_ + +### lists + +```python +def lists(self, resources=None) +``` + +Iterates through the pq-encoded list data + +This function returns an iterator over each list, +with each value being the pq-encoded data for the +entire list + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `resources` | `cuvs.common.Resources, optional` | | + +_Source: `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:392`_ + +### list_data + +```python +def list_data(self, label, n_rows=0, offset=0, out_codes=None, resources=None) +``` + +Gets unpacked list data for a single list (cluster) + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `label`, `int` | | The cluster to get data for | +| `n_rows`, `int` | | The number of rows to return for the cluster (0 is all rows) | +| `offset`, `int` | | The row to start getting data at out_codes, CAI Optional buffer to hold memory. Will be created if None | +| `resources` | `cuvs.common.Resources, optional` | | + +_Source: `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:411`_ + +### list_indices + +```python +def list_indices(self, label, n_rows=0) +``` + +Gets indices for a single cluster (list) + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `label`, `int` | | The cluster to get data for n_rows, int, optional Number of rows in the list | + +_Source: `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:451`_ + +_Source: `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:239`_ + +## IndexParams + +```python +cdef class IndexParams +``` + +Parameters to build index for IvfPq nearest neighbor search + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `n_lists` | `int, default = 1024` | The number of clusters used in the coarse quantizer. | +| `metric` | `str, default="sqeuclidean"` | String denoting the metric type. Valid values for metric: ["sqeuclidean", "inner_product", "euclidean", "cosine"], where:

- sqeuclidean is the euclidean distance without the square root operation, i.e.: distance(a,b) = \\sum_i (a_i - b_i)^2, - euclidean is the euclidean distance - inner product distance is defined as distance(a, b) = \\sum_i a_i * b_i. - cosine distance is defined as distance(a, b) = 1 - \\sum_i a_i * b_i / ( \|\|a\|\|_2 * \|\|b\|\|_2). | +| `kmeans_n_iters` | `int, default = 20` | The number of iterations searching for kmeans centers during index building. | +| `kmeans_trainset_fraction` | `int, default = 0.5` | If kmeans_trainset_fraction is less than 1, then the dataset is subsampled, and only n_samples * kmeans_trainset_fraction rows are used for training. | +| `pq_bits` | `int, default = 8` | The bit length of the vector element after quantization. | +| `pq_dim` | `int, default = 0` | The dimensionality of a the vector after product quantization. When zero, an optimal value is selected using a heuristic. Note pq_dim * pq_bits must be a multiple of 8. Hint: a smaller 'pq_dim' results in a smaller index size and better search performance, but lower recall. If 'pq_bits' is 8, 'pq_dim' can be set to any number, but multiple of 8 are desirable for good performance. If 'pq_bits' is not 8, 'pq_dim' should be a multiple of 8. For good performance, it is desirable that 'pq_dim' is a multiple of 32. Ideally, 'pq_dim' should be also a divisor of the dataset dim. | +| `codebook_kind` | `string, default = "subspace"` | Valid values ["subspace", "cluster"] | +| `force_random_rotation` | `bool, default = False` | Apply a random rotation matrix on the input data and queries even if `dim % pq_dim == 0`. Note: if `dim` is not multiple of `pq_dim`, a random rotation is always applied to the input data and queries to transform the working space from `dim` to `rot_dim`, which may be slightly larger than the original space and and is a multiple of `pq_dim` (`rot_dim % pq_dim == 0`). However, this transform is not necessary when `dim` is multiple of `pq_dim` (`dim == rot_dim`, hence no need in adding "extra" data columns / features). By default, if `dim == rot_dim`, the rotation transform is initialized with the identity matrix. When `force_random_rotation == True`, a random orthogonal transform matrix is generated regardless of the values of `dim` and `pq_dim`. | +| `add_data_on_build` | `bool, default = True` | After training the coarse and fine quantizers, we will populate the index with the dataset if add_data_on_build == True, otherwise the index is left empty, and the extend method can be used to add new vectors to the index. | +| `conservative_memory_allocation` | `bool, default = True` | By default, the algorithm allocates more space than necessary for individual clusters (`list_data`). This allows to amortize the cost of memory allocation and reduce the number of data copies during repeated calls to `extend` (extending the database). To disable this behavior and use as little GPU memory for the database as possible, set this flat to `True`. | +| `max_train_points_per_pq_code` | `int, default = 256` | The max number of data points to use per PQ code during PQ codebook training. Using more data points per PQ code may increase the quality of PQ codebook but may also increase the build time. The parameter is applied to both PQ codebook generation methods, i.e., PER_SUBSPACE and PER_CLUSTER. In both cases, we will use pq_book_size * max_train_points_per_pq_code training points to train each codebook. | +| `codes_layout` | `string, default = "interleaved"` | Memory layout of the IVF-PQ list data. Valid values ["flat", "interleaved"]

- flat: Codes are stored contiguously, one vector's codes after another. - interleaved: Codes are interleaved for optimized search performance. This is the default and recommended for search workloads. | + +**Constructor** + +```python +def __init__(self, *, n_lists=1024, metric="sqeuclidean", metric_arg=2.0, kmeans_n_iters=20, kmeans_trainset_fraction=0.5, pq_bits=8, pq_dim=0, codebook_kind="subspace", force_random_rotation=False, add_data_on_build=True, conservative_memory_allocation=False, max_train_points_per_pq_code=256, codes_layout="interleaved") +``` + +**Members** + +| Name | Kind | Source | +| --- | --- | --- | +| `get_handle` | method | `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:174` | +| `metric` | property | `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:178` | +| `metric_arg` | property | `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:182` | +| `add_data_on_build` | property | `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:186` | +| `n_lists` | property | `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:190` | +| `kmeans_n_iters` | property | `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:194` | +| `kmeans_trainset_fraction` | property | `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:198` | +| `pq_bits` | property | `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:202` | +| `pq_dim` | property | `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:206` | +| `codebook_kind` | property | `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:210` | +| `force_random_rotation` | property | `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:214` | +| `add_data_on_build` | property | `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:218` | +| `conservative_memory_allocation` | property | `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:222` | +| `max_train_points_per_pq_code` | property | `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:226` | +| `codes_layout` | property | `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:230` | +| `get_handle` | method | `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:236` | + +### get_handle + +```python +def get_handle(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:174`_ + +### metric + +```python +def metric(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:178`_ + +### metric_arg + +```python +def metric_arg(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:182`_ + +### add_data_on_build + +```python +def add_data_on_build(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:186`_ + +### n_lists + +```python +def n_lists(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:190`_ + +### kmeans_n_iters + +```python +def kmeans_n_iters(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:194`_ + +### kmeans_trainset_fraction + +```python +def kmeans_trainset_fraction(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:198`_ + +### pq_bits + +```python +def pq_bits(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:202`_ + +### pq_dim + +```python +def pq_dim(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:206`_ + +### codebook_kind + +```python +def codebook_kind(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:210`_ + +### force_random_rotation + +```python +def force_random_rotation(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:214`_ + +### add_data_on_build + +```python +def add_data_on_build(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:218`_ + +### conservative_memory_allocation + +```python +def conservative_memory_allocation(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:222`_ + +### max_train_points_per_pq_code + +```python +def max_train_points_per_pq_code(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:226`_ + +### codes_layout + +```python +def codes_layout(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:230`_ + +### get_handle + +```python +def get_handle(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:236`_ + +_Source: `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:40`_ + +## SearchParams + +```python +cdef class SearchParams +``` + +Supplemental parameters to search IVF-Pq index + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `n_probes` | `int` | The number of clusters to search. | +| `lut_dtype` | `default = np.float32` | Data type of look up table to be created dynamically at search time. The use of low-precision types reduces the amount of shared memory required at search time, so fast shared memory kernels can be used even for datasets with large dimansionality. Note that the recall is slightly degraded when low-precision type is selected. Possible values [np.float32, np.float16, np.uint8] | +| `internal_distance_dtype` | `default = np.float32` | Storage data type for distance/similarity computation. Possible values [np.float32, np.float16] | +| `coarse_search_dtype` | `default = np.float32` | [Experimental] The data type to use as the GEMM element type when searching the clusters to probe. Possible values: [np.float32, np.float16, np.int8]. - Legacy default: np.float32 - Recommended for performance: np.float16 (half) - Experimental/low-precision: np.int8 | +| `max_internal_batch_size` | `default = 4096` | Set the internal batch size to improve GPU utilization at the cost of larger memory footprint. | + +**Constructor** + +```python +def __init__(self, *, n_probes=20, lut_dtype=np.float32, internal_distance_dtype=np.float32, coarse_search_dtype=np.float32, max_internal_batch_size=4096) +``` + +**Members** + +| Name | Kind | Source | +| --- | --- | --- | +| `get_handle` | method | `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:716` | +| `n_probes` | property | `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:720` | +| `lut_dtype` | property | `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:724` | +| `internal_distance_dtype` | property | `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:728` | +| `coarse_search_dtype` | property | `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:732` | +| `max_internal_batch_size` | property | `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:736` | +| `get_handle` | method | `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:739` | + +### get_handle + +```python +def get_handle(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:716`_ + +### n_probes + +```python +def n_probes(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:720`_ + +### lut_dtype + +```python +def lut_dtype(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:724`_ + +### internal_distance_dtype + +```python +def internal_distance_dtype(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:728`_ + +### coarse_search_dtype + +```python +def coarse_search_dtype(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:732`_ + +### max_internal_batch_size + +```python +def max_internal_batch_size(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:736`_ + +### get_handle + +```python +def get_handle(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:739`_ + +_Source: `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:667`_ + +## build + +`@auto_sync_resources` + +```python +def build(IndexParams index_params, dataset, resources=None) +``` + +Build the IvfPq index from the dataset for efficient search. + +The input dataset array can be either CUDA array interface compliant matrix +or an array interface compliant matrix in host memory. + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `index_params` | `cuvs.neighbors.ivf_pq.IndexParams` | Parameters on how to build the index | +| `dataset` | `Array interface compliant matrix shape (n_samples, dim)` | Supported dtype [float32, float16, int8, uint8] | +| `resources` | `cuvs.common.Resources, optional` | | + +**Returns** + +| Name | Type | Description | +| --- | --- | --- | +| `index` | `cuvs.neighbors.ivf_pq.Index` | | + +**Examples** + +```python +>>> import cupy as cp +>>> from cuvs.neighbors import ivf_pq +>>> n_samples = 50000 +>>> n_features = 50 +>>> n_queries = 1000 +>>> k = 10 +>>> dataset = cp.random.random_sample((n_samples, n_features), +... dtype=cp.float32) +>>> build_params = ivf_pq.IndexParams(metric="sqeuclidean") +>>> index = ivf_pq.build(build_params, dataset) +>>> distances, neighbors = ivf_pq.search(ivf_pq.SearchParams(), +... index, dataset, +... k) +>>> distances = cp.asarray(distances) +>>> neighbors = cp.asarray(neighbors) +``` + +_Source: `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:477`_ + +## build_precomputed + +`@auto_sync_resources` + +```python +def build_precomputed(IndexParams index_params, uint32_t dim, pq_centers, centers, centers_rot, rotation_matrix, resources=None) +``` + +Build a view-type IVF-PQ index from precomputed centroids and codebook. + +This function creates a non-owning index that stores a reference to the provided device data. +All parameters must be provided with correct extents. The caller is responsible for ensuring +the lifetime of the input data exceeds the lifetime of the returned index. + +The index_params must be consistent with the provided matrices. Specifically: +- index_params.codebook_kind determines the expected shape of pq_centers +- index_params.metric will be stored in the index +- index_params.conservative_memory_allocation will be stored in the index + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `index_params` | `cuvs.neighbors.ivf_pq.IndexParams` | Parameters that must be consistent with the provided matrices | +| `dim` | `int` | Dimensionality of the input data | +| `pq_centers` | `CUDA array interface compliant tensor` | PQ codebook on device memory with required shape: - codebook_kind "subspace": [pq_dim, pq_len, pq_book_size] - codebook_kind "cluster": [n_lists, pq_len, pq_book_size] Supported dtype: float32 | +| `centers` | `CUDA array interface compliant matrix` | Cluster centers in the original space [n_lists, dim_ext] where dim_ext = round_up(dim + 1, 8). Supported dtype: float32 | +| `centers_rot` | `CUDA array interface compliant matrix` | Rotated cluster centers [n_lists, rot_dim] where rot_dim = pq_len * pq_dim. Supported dtype: float32 | +| `rotation_matrix` | `CUDA array interface compliant matrix` | Transform matrix (original space -> rotated padded space) [rot_dim, dim]. Supported dtype: float32 | +| `resources` | `cuvs.common.Resources, optional` | | + +**Returns** + +| Name | Type | Description | +| --- | --- | --- | +| `index` | `cuvs.neighbors.ivf_pq.Index` | | + +**Examples** + +```python +>>> import cupy as cp +>>> from cuvs.neighbors import ivf_pq +>>> n_lists = 100 +>>> dim = 128 +>>> pq_dim = 16 +>>> pq_bits = 8 +>>> pq_len = (dim + pq_dim - 1) // pq_dim # ceil division +>>> pq_book_size = 1 << pq_bits +>>> rot_dim = pq_len * pq_dim +>>> dim_ext = ((dim + 1 + 7) // 8) * 8 # round_up(dim + 1, 8) +>>> +>>> # Prepare precomputed matrices (example with random data) +>>> pq_centers = cp.random.random((pq_dim, pq_len, pq_book_size), +... dtype=cp.float32) +>>> centers = cp.random.random((n_lists, dim_ext), dtype=cp.float32) +>>> centers_rot = cp.random.random((n_lists, rot_dim), dtype=cp.float32) +>>> rotation_matrix = cp.random.random((rot_dim, dim), dtype=cp.float32) +>>> +>>> # Build index from precomputed data +>>> build_params = ivf_pq.IndexParams(n_lists=n_lists, pq_dim=pq_dim, +... pq_bits=pq_bits, +... codebook_kind="subspace") +>>> index = ivf_pq.build_precomputed(build_params, dim, pq_centers, +... centers, centers_rot, rotation_matrix) +``` + +_Source: `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:543`_ + +## extend + +`@auto_sync_resources` + +```python +def extend(Index index, new_vectors, new_indices, resources=None) +``` + +Extend an existing index with new vectors. + +The input array can be either CUDA array interface compliant matrix or +array interface compliant matrix in host memory. + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `index` | `ivf_pq.Index` | Trained ivf_pq object. | +| `new_vectors` | `array interface compliant matrix shape (n_samples, dim)` | Supported dtype [float, int8, uint8] | +| `new_indices` | `array interface compliant vector shape (n_samples)` | Supported dtype [int64] | +| `resources` | `cuvs.common.Resources, optional` | | + +**Returns** + +| Name | Type | Description | +| --- | --- | --- | +| `index` | `cuvs.neighbors.ivf_pq.Index` | | + +**Examples** + +```python +>>> import cupy as cp +>>> from cuvs.neighbors import ivf_pq +>>> n_samples = 50000 +>>> n_features = 50 +>>> n_queries = 1000 +>>> dataset = cp.random.random_sample((n_samples, n_features), +... dtype=cp.float32) +>>> index = ivf_pq.build(ivf_pq.IndexParams(), dataset) +>>> n_rows = 100 +>>> more_data = cp.random.random_sample((n_rows, n_features), +... dtype=cp.float32) +>>> indices = n_samples + cp.arange(n_rows, dtype=cp.int64) +>>> index = ivf_pq.extend(index, more_data, indices) +>>> # Search using the built index +>>> queries = cp.random.random_sample((n_queries, n_features), +... dtype=cp.float32) +>>> distances, neighbors = ivf_pq.search(ivf_pq.SearchParams(), +... index, queries, +... k=10) +``` + +_Source: `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:913`_ + +## load + +`@auto_sync_resources` + +```python +def load(filename, resources=None) +``` + +Loads index from file. + +Saving / loading the index is experimental. The serialization format is +subject to change, therefore loading an index saved with a previous +version of cuvs is not guaranteed to work. + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `filename` | `string` | Name of the file. | +| `resources` | `cuvs.common.Resources, optional` | | + +**Returns** + +| Name | Type | Description | +| --- | --- | --- | +| `index` | `Index` | | + +_Source: `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:880`_ + +## save + +`@auto_sync_resources` + +```python +def save(filename, Index index, bool include_dataset=True, resources=None) +``` + +Saves the index to a file. + +Saving / loading the index is experimental. The serialization format is +subject to change. + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `filename` | `string` | Name of the file. | +| `index` | `Index` | Trained IVF-PQ index. | +| `resources` | `cuvs.common.Resources, optional` | | + +**Examples** + +```python +>>> import cupy as cp +>>> from cuvs.neighbors import ivf_pq +>>> n_samples = 50000 +>>> n_features = 50 +>>> dataset = cp.random.random_sample((n_samples, n_features), +... dtype=cp.float32) +>>> # Build index +>>> index = ivf_pq.build(ivf_pq.IndexParams(), dataset) +>>> # Serialize and deserialize the ivf_pq index built +>>> ivf_pq.save("my_index.bin", index) +>>> index_loaded = ivf_pq.load("my_index.bin") +``` + +_Source: `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:843`_ + +## search + +`@auto_sync_resources` +`@auto_convert_output` + +```python +def search(SearchParams search_params, Index index, queries, k, neighbors=None, distances=None, resources=None) +``` + +Find the k nearest neighbors for each query. + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `search_params` | `cuvs.neighbors.ivf_pq.SearchParams` | Parameters on how to search the index | +| `index` | `cuvs.neighbors.ivf_pq.Index` | Trained IvfPq index. | +| `queries` | `CUDA array interface compliant matrix shape (n_samples, dim)` | Supported dtype [float, int8, uint8] | +| `k` | `int` | The number of neighbors. | +| `neighbors` | `Optional CUDA array interface compliant matrix shape` | (n_queries, k), dtype int64_t. If supplied, neighbor indices will be written here in-place. (default None) | +| `distances` | `Optional CUDA array interface compliant matrix shape` | (n_queries, k) If supplied, the distances to the neighbors will be written here in-place. (default None) | +| `resources` | `cuvs.common.Resources, optional` | | + +**Examples** + +```python +>>> import cupy as cp +>>> from cuvs.neighbors import ivf_pq +>>> n_samples = 50000 +>>> n_features = 50 +>>> n_queries = 1000 +>>> dataset = cp.random.random_sample((n_samples, n_features), +... dtype=cp.float32) +>>> # Build the index +>>> index = ivf_pq.build(ivf_pq.IndexParams(), dataset) +>>> +>>> # Search using the built index +>>> queries = cp.random.random_sample((n_queries, n_features), +... dtype=cp.float32) +>>> k = 10 +>>> search_params = ivf_pq.SearchParams(n_probes=20) +>>> +>>> distances, neighbors = ivf_pq.search(search_params, index, queries, +... k) +``` + +_Source: `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:745`_ + +## transform + +`@auto_sync_resources` + +```python +def transform(Index index, input_dataset, output_labels=None, output_dataset=None, resources=None) +``` + +Transform a dataset by applying pq-encoding to the vectors. + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `index` | `ivf_pq.Index` | Trained ivf_pq object. | +| `input_dataset` | `array interface compliant matrix shape (n_samples, dim)` | Supported dtype [float] | +| `new_indices` | `Optional array interface compliant vector shape (n_samples)` | Supported dtype [uint32] | +| `output_dataset` | `Optional array interface compliant matrix shape (n_samples, pq_dim)` | Supported dtype [uint8] | +| `resources` | `cuvs.common.Resources, optional` | | + +**Returns** + +| Name | Type | Description | +| --- | --- | --- | +| `output_labels`, `output_dataset` | | The cluster that each point in the dataset belongs to, and the transformed dataset | + +_Source: `python/cuvs/cuvs/neighbors/ivf_pq/ivf_pq.pyx:987`_ diff --git a/fern/pages/python_api/python-api-neighbors-mg-cagra.md b/fern/pages/python_api/python-api-neighbors-mg-cagra.md new file mode 100644 index 0000000000..9ed3321944 --- /dev/null +++ b/fern/pages/python_api/python-api-neighbors-mg-cagra.md @@ -0,0 +1,418 @@ +--- +slug: api-reference/python-api-neighbors-mg-cagra +--- + +# Multi-GPU Cagra + +_Python module: `cuvs.neighbors.mg.cagra`_ + +## Index + +```python +cdef class Index +``` + +Multi-GPU CAGRA index object. Stores the trained multi-GPU CAGRA index +state which can be used to perform nearest neighbors searches across +multiple GPUs. + +**Members** + +| Name | Kind | Source | +| --- | --- | --- | +| `trained` | property | `python/cuvs/cuvs/neighbors/mg/cagra/cagra.pyx:126` | + +### trained + +```python +def trained(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/mg/cagra/cagra.pyx:126`_ + +_Source: `python/cuvs/cuvs/neighbors/mg/cagra/cagra.pyx:106`_ + +## IndexParams + +```python +cdef class IndexParams(SingleGpuIndexParams) +``` + +Parameters to build multi-GPU CAGRA index for efficient search. +Extends single-GPU IndexParams with multi-GPU specific parameters. + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `distribution_mode` | `str, default = "sharded"` | Distribution mode for multi-GPU setup. Valid values: ["replicated", "sharded"] | +| `**kwargs` | `Additional parameters passed to single-GPU IndexParams` | | + +**Note** + +CAGRA currently only supports "sqeuclidean" and "inner_product" metrics. + +**Constructor** + +```python +def __init__(self, *, distribution_mode="sharded", **kwargs) +``` + +**Members** + +| Name | Kind | Source | +| --- | --- | --- | +| `get_handle` | method | `python/cuvs/cuvs/neighbors/mg/cagra/cagra.pyx:97` | +| `distribution_mode` | property | `python/cuvs/cuvs/neighbors/mg/cagra/cagra.pyx:101` | + +### get_handle + +```python +def get_handle(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/mg/cagra/cagra.pyx:97`_ + +### distribution_mode + +```python +def distribution_mode(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/mg/cagra/cagra.pyx:101`_ + +_Source: `python/cuvs/cuvs/neighbors/mg/cagra/cagra.pyx:53`_ + +## SearchParams + +```python +cdef class SearchParams(SingleGpuSearchParams) +``` + +Parameters to search multi-GPU CAGRA index. + +**Constructor** + +```python +def __init__(self, *, search_mode="load_balancer", merge_mode="merge_on_root_rank", n_rows_per_batch=1000, **kwargs) +``` + +**Members** + +| Name | Kind | Source | +| --- | --- | --- | +| `get_handle` | method | `python/cuvs/cuvs/neighbors/mg/cagra/cagra.pyx:222` | +| `search_mode` | property | `python/cuvs/cuvs/neighbors/mg/cagra/cagra.pyx:226` | +| `search_mode` | method | `python/cuvs/cuvs/neighbors/mg/cagra/cagra.pyx:232` | +| `merge_mode` | property | `python/cuvs/cuvs/neighbors/mg/cagra/cagra.pyx:243` | +| `merge_mode` | method | `python/cuvs/cuvs/neighbors/mg/cagra/cagra.pyx:249` | +| `n_rows_per_batch` | property | `python/cuvs/cuvs/neighbors/mg/cagra/cagra.pyx:260` | +| `n_rows_per_batch` | method | `python/cuvs/cuvs/neighbors/mg/cagra/cagra.pyx:265` | + +### get_handle + +```python +def get_handle(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/mg/cagra/cagra.pyx:222`_ + +### search_mode + +```python +def search_mode(self) +``` + +Get the search mode for multi-GPU search. + +_Source: `python/cuvs/cuvs/neighbors/mg/cagra/cagra.pyx:226`_ + +### search_mode + +```python +def search_mode(self, value) +``` + +Set the search mode for multi-GPU search. + +_Source: `python/cuvs/cuvs/neighbors/mg/cagra/cagra.pyx:232`_ + +### merge_mode + +```python +def merge_mode(self) +``` + +Get the merge mode for multi-GPU search. + +_Source: `python/cuvs/cuvs/neighbors/mg/cagra/cagra.pyx:243`_ + +### merge_mode + +```python +def merge_mode(self, value) +``` + +Set the merge mode for multi-GPU search. + +_Source: `python/cuvs/cuvs/neighbors/mg/cagra/cagra.pyx:249`_ + +### n_rows_per_batch + +```python +def n_rows_per_batch(self) +``` + +Get the number of rows per batch for multi-GPU search. + +_Source: `python/cuvs/cuvs/neighbors/mg/cagra/cagra.pyx:260`_ + +### n_rows_per_batch + +```python +def n_rows_per_batch(self, value) +``` + +Set the number of rows per batch for multi-GPU search. + +_Source: `python/cuvs/cuvs/neighbors/mg/cagra/cagra.pyx:265`_ + +_Source: `python/cuvs/cuvs/neighbors/mg/cagra/cagra.pyx:191`_ + +## build + +`@auto_sync_multi_gpu_resources` + +```python +def build(IndexParams index_params, dataset, resources=None) +``` + +Build the multi-GPU CAGRA index from the dataset for efficient search. + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `index_params` | `cuvs.neighbors.cagra.IndexParams` | | +| `dataset` | `Array interface compliant matrix shape (n_samples, dim)` | Supported dtype [float32, float16, int8, uint8] **IMPORTANT**: For multi-GPU CAGRA, the dataset MUST be in host memory (CPU). If using CuPy/device arrays, transfer to host with array.get() or cp.asnumpy(array). | +| `resources` | `cuvs.common.Resources, optional` | | + +**Returns** + +| Name | Type | Description | +| --- | --- | --- | +| `index` | `cuvs.neighbors.cagra.Index` | | + +**Examples** + +```python +>>> import numpy as np +>>> from cuvs.neighbors.mg import cagra +>>> n_samples = 50000 +>>> n_features = 50 +>>> n_queries = 1000 +>>> k = 10 +>>> # For multi-GPU CAGRA, use host (NumPy) arrays +>>> dataset = np.random.random_sample((n_samples, n_features)).astype( +... np.float32) +>>> build_params = cagra.IndexParams(metric="sqeuclidean") +>>> index = cagra.build(build_params, dataset) +>>> distances, neighbors = cagra.search(cagra.SearchParams(), +... index, dataset, k) +>>> # Results are already in host memory (NumPy arrays) +``` + +_Source: `python/cuvs/cuvs/neighbors/mg/cagra/cagra.pyx:131`_ + +## extend + +`@auto_sync_multi_gpu_resources` + +```python +def extend(Index index, new_vectors, new_indices=None, resources=None) +``` + +Extend the multi-GPU CAGRA index with new vectors. + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `index` | `cuvs.neighbors.cagra.Index` | | +| `new_vectors` | `Array interface compliant matrix shape (n_new_vectors, dim)` | Supported dtype [float32, float16, int8, uint8] **IMPORTANT**: For multi-GPU CAGRA, new_vectors MUST be in host memory (CPU). If using CuPy/device arrays, transfer to host with array.get() or cp.asnumpy(array). | +| `new_indices` | `Array interface compliant matrix shape (n_new_vectors,), optional` | If provided, these indices will be used for the new vectors. If not provided, indices will be automatically assigned. **IMPORTANT**: Must be in host memory (CPU) for multi-GPU CAGRA. Expected dtype: uint32 | +| `resources` | `cuvs.common.Resources, optional` | | + +**Examples** + +```python +>>> import numpy as np +>>> from cuvs.neighbors.mg import cagra +>>> n_samples = 50000 +>>> n_features = 50 +>>> n_new_vectors = 1000 +>>> # For multi-GPU CAGRA, use host (NumPy) arrays +>>> dataset = np.random.random_sample((n_samples, n_features)).astype( +... np.float32) +>>> new_vectors = np.random.random_sample( +... (n_new_vectors, n_features)).astype(np.float32) +>>> new_indices = np.arange(n_samples, n_samples + n_new_vectors, +... dtype=np.uint32) +>>> build_params = cagra.IndexParams(metric="sqeuclidean") +>>> index = cagra.build(build_params, dataset) +>>> cagra.extend(index, new_vectors, new_indices) # doctest: +SKIP +``` + +_Source: `python/cuvs/cuvs/neighbors/mg/cagra/cagra.pyx:385`_ + +## search + +`@auto_sync_multi_gpu_resources` +`@auto_convert_output` + +```python +def search(SearchParams search_params, Index index, queries, k, neighbors=None, distances=None, resources=None) +``` + +Search the multi-GPU CAGRA index for the k-nearest neighbors of each query. + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `search_params` | `cuvs.neighbors.cagra.SearchParams` | | +| `index` | `cuvs.neighbors.cagra.Index` | | +| `queries` | `Array interface compliant matrix shape (n_queries, dim)` | Supported dtype [float32, float16, int8, uint8] **IMPORTANT**: For multi-GPU CAGRA, queries MUST be in host memory (CPU). If using CuPy/device arrays, transfer to host with array.get() or cp.asnumpy(array). | +| `k` | `int` | The number of neighbors to search for each query. | +| `neighbors` | `Array interface compliant matrix shape (n_queries, k), optional` | If provided, this array will be filled with the indices of the k-nearest neighbors. If not provided, a new host array will be allocated. **IMPORTANT**: Must be in host memory (CPU) for multi-GPU CAGRA. Expected dtype: int64 | +| `distances` | `Array interface compliant matrix shape (n_queries, k), optional` | If provided, this array will be filled with the distances to the k-nearest neighbors. If not provided, a new host array will be allocated. **IMPORTANT**: Must be in host memory (CPU) for multi-GPU CAGRA. | +| `resources` | `cuvs.common.Resources, optional` | | + +**Returns** + +| Name | Type | Description | +| --- | --- | --- | +| `distances` | `numpy.ndarray` | The distances to the k-nearest neighbors for each query (in host memory). | +| `neighbors` | `numpy.ndarray` | The indices of the k-nearest neighbors for each query (in host memory). | + +**Examples** + +```python +>>> import numpy as np +>>> from cuvs.neighbors.mg import cagra +>>> n_samples = 50000 +>>> n_features = 50 +>>> n_queries = 1000 +>>> k = 10 +>>> # For multi-GPU CAGRA, use host (NumPy) arrays +>>> dataset = np.random.random_sample((n_samples, n_features)).astype( +... np.float32) +>>> queries = np.random.random_sample((n_queries, n_features)).astype( +... np.float32) +>>> build_params = cagra.IndexParams(metric="sqeuclidean") +>>> index = cagra.build(build_params, dataset) +>>> distances, neighbors = cagra.search(cagra.SearchParams(), +... index, queries, k) +>>> # Results are already in host memory (NumPy arrays) +``` + +_Source: `python/cuvs/cuvs/neighbors/mg/cagra/cagra.pyx:274`_ + +## save + +`@auto_sync_multi_gpu_resources` + +```python +def save(Index index, filename, resources=None) +``` + +Serialize the multi-GPU CAGRA index to a file. + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `index` | `cuvs.neighbors.cagra.Index` | | +| `filename` | `str` | The filename to serialize the index to. | +| `resources` | `cuvs.common.Resources, optional` | | + +**Examples** + +```python +>>> import numpy as np +>>> from cuvs.neighbors.mg import cagra +>>> n_samples = 50000 +>>> n_features = 50 +>>> # For multi-GPU CAGRA, use host (NumPy) arrays +>>> dataset = np.random.random_sample((n_samples, n_features)).astype( +... np.float32) +>>> build_params = cagra.IndexParams(metric="sqeuclidean") +>>> index = cagra.build(build_params, dataset) +>>> cagra.save(index, "index.bin") +``` + +_Source: `python/cuvs/cuvs/neighbors/mg/cagra/cagra.pyx:458`_ + +## load + +`@auto_sync_multi_gpu_resources` + +```python +def load(filename, resources=None) +``` + +Deserialize the multi-GPU CAGRA index from a file. + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `filename` | `str` | The filename to deserialize the index from. | +| `resources` | `cuvs.common.Resources, optional` | | + +**Returns** + +| Name | Type | Description | +| --- | --- | --- | +| `index` | `Index` | The deserialized index. | + +**Examples** + +```python +>>> from cuvs.neighbors.mg import cagra +>>> index = cagra.load("index.bin") # doctest: +SKIP +``` + +_Source: `python/cuvs/cuvs/neighbors/mg/cagra/cagra.pyx:496`_ + +## distribute + +`@auto_sync_multi_gpu_resources` + +```python +def distribute(filename, resources=None) +``` + +Distribute a single-GPU CAGRA index across multiple GPUs from a file. + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `filename` | `str` | The filename to distribute the index from. | +| `resources` | `cuvs.common.Resources, optional` | | + +**Returns** + +| Name | Type | Description | +| --- | --- | --- | +| `index` | `Index` | The distributed index. | + +**Examples** + +```python +>>> from cuvs.neighbors.mg import cagra +>>> index = cagra.distribute("single_gpu_index.bin") # doctest: +SKIP +``` + +_Source: `python/cuvs/cuvs/neighbors/mg/cagra/cagra.pyx:530`_ diff --git a/fern/pages/python_api/python-api-neighbors-mg-ivf-flat.md b/fern/pages/python_api/python-api-neighbors-mg-ivf-flat.md new file mode 100644 index 0000000000..1c2c474856 --- /dev/null +++ b/fern/pages/python_api/python-api-neighbors-mg-ivf-flat.md @@ -0,0 +1,416 @@ +--- +slug: api-reference/python-api-neighbors-mg-ivf-flat +--- + +# Multi-GPU IVF Flat + +_Python module: `cuvs.neighbors.mg.ivf_flat`_ + +## Index + +```python +cdef class Index +``` + +Multi-GPU IVF-Flat index object. Stores the trained multi-GPU IVF-Flat +index state which can be used to perform nearest neighbors searches +across multiple GPUs. + +**Members** + +| Name | Kind | Source | +| --- | --- | --- | +| `trained` | property | `python/cuvs/cuvs/neighbors/mg/ivf_flat/ivf_flat.pyx:125` | + +### trained + +```python +def trained(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/mg/ivf_flat/ivf_flat.pyx:125`_ + +_Source: `python/cuvs/cuvs/neighbors/mg/ivf_flat/ivf_flat.pyx:105`_ + +## IndexParams + +```python +cdef class IndexParams(SingleGpuIndexParams) +``` + +Parameters to build multi-GPU IVF-Flat index for efficient search. +Extends single-GPU IndexParams with multi-GPU specific parameters. + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `distribution_mode` | `str, default = "sharded"` | Distribution mode for multi-GPU setup. Valid values: ["replicated", "sharded"] | +| `**kwargs` | `Additional parameters passed to single-GPU IndexParams` | | + +**Constructor** + +```python +def __init__(self, *, distribution_mode="sharded", **kwargs) +``` + +**Members** + +| Name | Kind | Source | +| --- | --- | --- | +| `get_handle` | method | `python/cuvs/cuvs/neighbors/mg/ivf_flat/ivf_flat.pyx:96` | +| `distribution_mode` | property | `python/cuvs/cuvs/neighbors/mg/ivf_flat/ivf_flat.pyx:100` | + +### get_handle + +```python +def get_handle(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/mg/ivf_flat/ivf_flat.pyx:96`_ + +### distribution_mode + +```python +def distribution_mode(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/mg/ivf_flat/ivf_flat.pyx:100`_ + +_Source: `python/cuvs/cuvs/neighbors/mg/ivf_flat/ivf_flat.pyx:56`_ + +## SearchParams + +```python +cdef class SearchParams(SingleGpuSearchParams) +``` + +Parameters to search multi-GPU IVF-Flat index. + +**Constructor** + +```python +def __init__(self, *, n_probes=1, search_mode="load_balancer", merge_mode="merge_on_root_rank", n_rows_per_batch=1000, **kwargs) +``` + +**Members** + +| Name | Kind | Source | +| --- | --- | --- | +| `get_handle` | method | `python/cuvs/cuvs/neighbors/mg/ivf_flat/ivf_flat.pyx:223` | +| `search_mode` | property | `python/cuvs/cuvs/neighbors/mg/ivf_flat/ivf_flat.pyx:227` | +| `search_mode` | method | `python/cuvs/cuvs/neighbors/mg/ivf_flat/ivf_flat.pyx:233` | +| `merge_mode` | property | `python/cuvs/cuvs/neighbors/mg/ivf_flat/ivf_flat.pyx:244` | +| `merge_mode` | method | `python/cuvs/cuvs/neighbors/mg/ivf_flat/ivf_flat.pyx:250` | +| `n_rows_per_batch` | property | `python/cuvs/cuvs/neighbors/mg/ivf_flat/ivf_flat.pyx:261` | +| `n_rows_per_batch` | method | `python/cuvs/cuvs/neighbors/mg/ivf_flat/ivf_flat.pyx:266` | + +### get_handle + +```python +def get_handle(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/mg/ivf_flat/ivf_flat.pyx:223`_ + +### search_mode + +```python +def search_mode(self) +``` + +Get the search mode for multi-GPU search. + +_Source: `python/cuvs/cuvs/neighbors/mg/ivf_flat/ivf_flat.pyx:227`_ + +### search_mode + +```python +def search_mode(self, value) +``` + +Set the search mode for multi-GPU search. + +_Source: `python/cuvs/cuvs/neighbors/mg/ivf_flat/ivf_flat.pyx:233`_ + +### merge_mode + +```python +def merge_mode(self) +``` + +Get the merge mode for multi-GPU search. + +_Source: `python/cuvs/cuvs/neighbors/mg/ivf_flat/ivf_flat.pyx:244`_ + +### merge_mode + +```python +def merge_mode(self, value) +``` + +Set the merge mode for multi-GPU search. + +_Source: `python/cuvs/cuvs/neighbors/mg/ivf_flat/ivf_flat.pyx:250`_ + +### n_rows_per_batch + +```python +def n_rows_per_batch(self) +``` + +Get the number of rows per batch for multi-GPU search. + +_Source: `python/cuvs/cuvs/neighbors/mg/ivf_flat/ivf_flat.pyx:261`_ + +### n_rows_per_batch + +```python +def n_rows_per_batch(self, value) +``` + +Set the number of rows per batch for multi-GPU search. + +_Source: `python/cuvs/cuvs/neighbors/mg/ivf_flat/ivf_flat.pyx:266`_ + +_Source: `python/cuvs/cuvs/neighbors/mg/ivf_flat/ivf_flat.pyx:192`_ + +## build + +`@auto_sync_multi_gpu_resources` + +```python +def build(IndexParams index_params, dataset, resources=None) +``` + +Build the multi-GPU IVF-Flat index from the dataset for efficient search. + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `index_params` | `cuvs.neighbors.ivf_flat.IndexParams` | | +| `dataset` | `Array interface compliant matrix shape (n_samples, dim)` | Supported dtype [float32, float16, int8, uint8] **IMPORTANT**: For multi-GPU IVF-Flat, the dataset MUST be in host memory (CPU). If using CuPy/device arrays, transfer to host with array.get() or cp.asnumpy(array). | +| `resources` | `cuvs.common.Resources, optional` | | + +**Returns** + +| Name | Type | Description | +| --- | --- | --- | +| `index` | `cuvs.neighbors.ivf_flat.Index` | | + +**Examples** + +```python +>>> import numpy as np +>>> from cuvs.neighbors.mg import ivf_flat +>>> n_samples = 50000 +>>> n_features = 50 +>>> n_queries = 1000 +>>> k = 10 +>>> # For multi-GPU IVF-Flat, use host (NumPy) arrays +>>> dataset = np.random.random_sample((n_samples, n_features)).astype( +... np.float32) +>>> build_params = ivf_flat.IndexParams(metric="sqeuclidean") +>>> index = ivf_flat.build(build_params, dataset) +>>> distances, neighbors = ivf_flat.search( +... ivf_flat.SearchParams(), +... index, dataset, k) +>>> # Results are already in host memory (NumPy arrays) +``` + +_Source: `python/cuvs/cuvs/neighbors/mg/ivf_flat/ivf_flat.pyx:130`_ + +## extend + +`@auto_sync_multi_gpu_resources` + +```python +def extend(Index index, new_vectors, new_indices=None, resources=None) +``` + +Extend the multi-GPU IVF-Flat index with new vectors. + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `index` | `cuvs.neighbors.ivf_flat.Index` | | +| `new_vectors` | `Array interface compliant matrix shape (n_new_vectors, dim)` | Supported dtype [float32, float16, int8, uint8] **IMPORTANT**: For multi-GPU IVF-Flat, new_vectors MUST be in host memory (CPU). If using CuPy/device arrays, transfer to host with array.get() or cp.asnumpy(array). | +| `new_indices` | `Array interface compliant matrix shape (n_new_vectors,)` | , optional If provided, these indices will be used for the new vectors. If not provided, indices will be automatically assigned. **IMPORTANT**: Must be in host memory (CPU) for multi-GPU IVF-Flat. | +| `resources` | `cuvs.common.Resources, optional` | | + +**Examples** + +```python +>>> import numpy as np +>>> from cuvs.neighbors.mg import ivf_flat +>>> n_samples = 50000 +>>> n_features = 50 +>>> n_new_vectors = 1000 +>>> # For multi-GPU IVF-Flat, use host (NumPy) arrays +>>> dataset = np.random.random_sample((n_samples, n_features)).astype( +... np.float32) +>>> new_vectors = np.random.random_sample( +... (n_new_vectors, n_features)).astype(np.float32) +>>> new_indices = np.arange(n_samples, n_new_vectors, dtype=np.int64) +>>> build_params = ivf_flat.IndexParams(metric="sqeuclidean") +>>> index = ivf_flat.build(build_params, dataset) +>>> ivf_flat.extend(index, new_vectors, new_indices) +``` + +_Source: `python/cuvs/cuvs/neighbors/mg/ivf_flat/ivf_flat.pyx:387`_ + +## search + +`@auto_sync_multi_gpu_resources` +`@auto_convert_output` + +```python +def search(SearchParams search_params, Index index, queries, k, neighbors=None, distances=None, resources=None) +``` + +Search the multi-GPU IVF-Flat index for the k-nearest neighbors +of each query. + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `search_params` | `cuvs.neighbors.ivf_flat.SearchParams` | | +| `index` | `cuvs.neighbors.ivf_flat.Index` | | +| `queries` | `Array interface compliant matrix shape (n_queries, dim)` | Supported dtype [float32, float16, int8, uint8] **IMPORTANT**: For multi-GPU IVF-Flat, queries MUST be in host memory (CPU). If using CuPy/device arrays, transfer to host with array.get() or cp.asnumpy(array). | +| `k` | `int` | The number of neighbors to search for each query. | +| `neighbors` | `Array interface compliant matrix shape (n_queries, k), optional` | If provided, this array will be filled with the indices of the k-nearest neighbors. If not provided, a new host array will be allocated. **IMPORTANT**: Must be in host memory (CPU) for multi-GPU IVF-Flat. | +| `distances` | `Array interface compliant matrix shape (n_queries, k), optional` | If provided, this array will be filled with the distances to the k-nearest neighbors. If not provided, a new host array will be allocated. **IMPORTANT**: Must be in host memory (CPU) for multi-GPU IVF-Flat. | +| `resources` | `cuvs.common.Resources, optional` | | + +**Returns** + +| Name | Type | Description | +| --- | --- | --- | +| `distances` | `numpy.ndarray` | The distances to the k-nearest neighbors for each query (in host memory). | +| `neighbors` | `numpy.ndarray` | The indices of the k-nearest neighbors for each query (in host memory). | + +**Examples** + +```python +>>> import numpy as np +>>> from cuvs.neighbors.mg import ivf_flat +>>> n_samples = 50000 +>>> n_features = 50 +>>> n_queries = 1000 +>>> k = 10 +>>> # For multi-GPU IVF-Flat, use host (NumPy) arrays +>>> dataset = np.random.random_sample((n_samples, n_features)).astype( +... np.float32) +>>> queries = np.random.random_sample((n_queries, n_features)).astype( +... np.float32) +>>> build_params = ivf_flat.IndexParams(metric="sqeuclidean") +>>> index = ivf_flat.build(build_params, dataset) +>>> distances, neighbors = ivf_flat.search( +... ivf_flat.SearchParams(), +... index, queries, k) +>>> # Results are already in host memory (NumPy arrays) +``` + +_Source: `python/cuvs/cuvs/neighbors/mg/ivf_flat/ivf_flat.pyx:275`_ + +## save + +`@auto_sync_multi_gpu_resources` + +```python +def save(Index index, filename, resources=None) +``` + +Serialize the multi-GPU IVF-Flat index to a file. + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `index` | `cuvs.neighbors.ivf_flat.Index` | | +| `filename` | `str` | The filename to serialize the index to. | +| `resources` | `cuvs.common.Resources, optional` | | + +**Examples** + +```python +>>> import numpy as np +>>> from cuvs.neighbors.mg import ivf_flat +>>> n_samples = 50000 +>>> n_features = 50 +>>> # For multi-GPU IVF-Flat, use host (NumPy) arrays +>>> dataset = np.random.random_sample((n_samples, n_features)).astype( +... np.float32) +>>> build_params = ivf_flat.IndexParams(metric="sqeuclidean") +>>> index = ivf_flat.build(build_params, dataset) +>>> ivf_flat.save(index, "index.bin") +``` + +_Source: `python/cuvs/cuvs/neighbors/mg/ivf_flat/ivf_flat.pyx:459`_ + +## load + +`@auto_sync_multi_gpu_resources` + +```python +def load(filename, resources=None) +``` + +Deserialize the multi-GPU IVF-Flat index from a file. + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `filename` | `str` | The filename to deserialize the index from. | +| `resources` | `cuvs.common.Resources, optional` | | + +**Returns** + +| Name | Type | Description | +| --- | --- | --- | +| `index` | `Index` | The deserialized index. | + +**Examples** + +```python +>>> from cuvs.neighbors.mg import ivf_flat +>>> index = ivf_flat.load("index.bin") # doctest: +SKIP +``` + +_Source: `python/cuvs/cuvs/neighbors/mg/ivf_flat/ivf_flat.pyx:498`_ + +## distribute + +`@auto_sync_multi_gpu_resources` + +```python +def distribute(filename, resources=None) +``` + +Distribute a single-GPU IVF-Flat index across multiple GPUs from a file. + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `filename` | `str` | The filename to distribute the index from. | +| `resources` | `cuvs.common.Resources, optional` | | + +**Returns** + +| Name | Type | Description | +| --- | --- | --- | +| `index` | `Index` | The distributed index. | + +**Examples** + +```python +>>> from cuvs.neighbors.mg import ivf_flat +>>> index = ivf_flat.distribute("single_gpu_index.bin") # doctest: +SKIP +``` + +_Source: `python/cuvs/cuvs/neighbors/mg/ivf_flat/ivf_flat.pyx:533`_ diff --git a/fern/pages/python_api/python-api-neighbors-mg-ivf-pq.md b/fern/pages/python_api/python-api-neighbors-mg-ivf-pq.md new file mode 100644 index 0000000000..a1bb4d9b01 --- /dev/null +++ b/fern/pages/python_api/python-api-neighbors-mg-ivf-pq.md @@ -0,0 +1,415 @@ +--- +slug: api-reference/python-api-neighbors-mg-ivf-pq +--- + +# Multi-GPU IVF PQ + +_Python module: `cuvs.neighbors.mg.ivf_pq`_ + +## Index + +```python +cdef class Index +``` + +Multi-GPU IVF-PQ index object. Stores the trained multi-GPU IVF-PQ +index state which can be used to perform nearest neighbors searches +across multiple GPUs. + +**Members** + +| Name | Kind | Source | +| --- | --- | --- | +| `trained` | property | `python/cuvs/cuvs/neighbors/mg/ivf_pq/ivf_pq.pyx:125` | + +### trained + +```python +def trained(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/mg/ivf_pq/ivf_pq.pyx:125`_ + +_Source: `python/cuvs/cuvs/neighbors/mg/ivf_pq/ivf_pq.pyx:105`_ + +## IndexParams + +```python +cdef class IndexParams(SingleGpuIndexParams) +``` + +Parameters to build multi-GPU IVF-PQ index for efficient search. +Extends single-GPU IndexParams with multi-GPU specific parameters. + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `distribution_mode` | `str, default = "sharded"` | Distribution mode for multi-GPU setup. Valid values: ["replicated", "sharded"] | +| `**kwargs` | `Additional parameters passed to single-GPU IndexParams` | | + +**Constructor** + +```python +def __init__(self, *, distribution_mode="sharded", **kwargs) +``` + +**Members** + +| Name | Kind | Source | +| --- | --- | --- | +| `get_handle` | method | `python/cuvs/cuvs/neighbors/mg/ivf_pq/ivf_pq.pyx:96` | +| `distribution_mode` | property | `python/cuvs/cuvs/neighbors/mg/ivf_pq/ivf_pq.pyx:100` | + +### get_handle + +```python +def get_handle(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/mg/ivf_pq/ivf_pq.pyx:96`_ + +### distribution_mode + +```python +def distribution_mode(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/mg/ivf_pq/ivf_pq.pyx:100`_ + +_Source: `python/cuvs/cuvs/neighbors/mg/ivf_pq/ivf_pq.pyx:56`_ + +## SearchParams + +```python +cdef class SearchParams(SingleGpuSearchParams) +``` + +Parameters to search multi-GPU IVF-PQ index. + +**Constructor** + +```python +def __init__(self, *, n_probes=20, search_mode="load_balancer", merge_mode="merge_on_root_rank", n_rows_per_batch=1000, **kwargs) +``` + +**Members** + +| Name | Kind | Source | +| --- | --- | --- | +| `get_handle` | method | `python/cuvs/cuvs/neighbors/mg/ivf_pq/ivf_pq.pyx:224` | +| `search_mode` | property | `python/cuvs/cuvs/neighbors/mg/ivf_pq/ivf_pq.pyx:228` | +| `search_mode` | method | `python/cuvs/cuvs/neighbors/mg/ivf_pq/ivf_pq.pyx:234` | +| `merge_mode` | property | `python/cuvs/cuvs/neighbors/mg/ivf_pq/ivf_pq.pyx:245` | +| `merge_mode` | method | `python/cuvs/cuvs/neighbors/mg/ivf_pq/ivf_pq.pyx:251` | +| `n_rows_per_batch` | property | `python/cuvs/cuvs/neighbors/mg/ivf_pq/ivf_pq.pyx:262` | +| `n_rows_per_batch` | method | `python/cuvs/cuvs/neighbors/mg/ivf_pq/ivf_pq.pyx:267` | + +### get_handle + +```python +def get_handle(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/mg/ivf_pq/ivf_pq.pyx:224`_ + +### search_mode + +```python +def search_mode(self) +``` + +Get the search mode for multi-GPU search. + +_Source: `python/cuvs/cuvs/neighbors/mg/ivf_pq/ivf_pq.pyx:228`_ + +### search_mode + +```python +def search_mode(self, value) +``` + +Set the search mode for multi-GPU search. + +_Source: `python/cuvs/cuvs/neighbors/mg/ivf_pq/ivf_pq.pyx:234`_ + +### merge_mode + +```python +def merge_mode(self) +``` + +Get the merge mode for multi-GPU search. + +_Source: `python/cuvs/cuvs/neighbors/mg/ivf_pq/ivf_pq.pyx:245`_ + +### merge_mode + +```python +def merge_mode(self, value) +``` + +Set the merge mode for multi-GPU search. + +_Source: `python/cuvs/cuvs/neighbors/mg/ivf_pq/ivf_pq.pyx:251`_ + +### n_rows_per_batch + +```python +def n_rows_per_batch(self) +``` + +Get the number of rows per batch for multi-GPU search. + +_Source: `python/cuvs/cuvs/neighbors/mg/ivf_pq/ivf_pq.pyx:262`_ + +### n_rows_per_batch + +```python +def n_rows_per_batch(self, value) +``` + +Set the number of rows per batch for multi-GPU search. + +_Source: `python/cuvs/cuvs/neighbors/mg/ivf_pq/ivf_pq.pyx:267`_ + +_Source: `python/cuvs/cuvs/neighbors/mg/ivf_pq/ivf_pq.pyx:193`_ + +## build + +`@auto_sync_multi_gpu_resources` + +```python +def build(IndexParams index_params, dataset, resources=None) +``` + +Build the multi-GPU IVF-PQ index from the dataset for efficient search. + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `index_params` | `cuvs.neighbors.ivf_pq.IndexParams` | | +| `dataset` | `Array interface compliant matrix shape (n_samples, dim)` | Supported dtype [float32, float16, int8, uint8] **IMPORTANT**: For multi-GPU IVF-PQ, the dataset MUST be in host memory (CPU). If using CuPy/device arrays, transfer to host with array.get() or cp.asnumpy(array). | +| `resources` | `cuvs.common.Resources, optional` | | + +**Returns** + +| Name | Type | Description | +| --- | --- | --- | +| `index` | `cuvs.neighbors.ivf_pq.Index` | | + +**Examples** + +```python +>>> import numpy as np +>>> from cuvs.neighbors.mg import ivf_pq +>>> n_samples = 50000 +>>> n_features = 50 +>>> n_queries = 1000 +>>> k = 10 +>>> # For multi-GPU IVF-PQ, use host (NumPy) arrays +>>> dataset = np.random.random_sample((n_samples, n_features)).astype( +... np.float32) +>>> build_params = ivf_pq.IndexParams(metric="sqeuclidean") +>>> index = ivf_pq.build(build_params, dataset) +>>> distances, neighbors = ivf_pq.search( +... ivf_pq.SearchParams(), +... index, dataset, k) +>>> # Results are already in host memory (NumPy arrays) +``` + +_Source: `python/cuvs/cuvs/neighbors/mg/ivf_pq/ivf_pq.pyx:130`_ + +## extend + +`@auto_sync_multi_gpu_resources` + +```python +def extend(Index index, new_vectors, new_indices=None, resources=None) +``` + +Extend the multi-GPU IVF-PQ index with new vectors. + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `index` | `cuvs.neighbors.ivf_pq.Index` | | +| `new_vectors` | `Array interface compliant matrix shape (n_new_vectors, dim)` | Supported dtype [float32, float16, int8, uint8] **IMPORTANT**: For multi-GPU IVF-PQ, new_vectors MUST be in host memory (CPU). If using CuPy/device arrays, transfer to host with array.get() or cp.asnumpy(array). | +| `new_indices` | `Array interface compliant matrix shape (n_new_vectors,)` | , optional If provided, these indices will be used for the new vectors. If not provided, indices will be automatically assigned. **IMPORTANT**: Must be in host memory (CPU) for multi-GPU IVF-PQ. | +| `resources` | `cuvs.common.Resources, optional` | | + +**Examples** + +```python +>>> import numpy as np +>>> from cuvs.neighbors.mg import ivf_pq +>>> n_samples = 50000 +>>> n_features = 50 +>>> n_new_vectors = 1000 +>>> # For multi-GPU IVF-PQ, use host (NumPy) arrays +>>> dataset = np.random.random_sample((n_samples, n_features)).astype( +... np.float32) +>>> new_vectors = np.random.random_sample( +... (n_new_vectors, n_features)).astype(np.float32) +>>> new_indices = np.arange(n_samples, n_new_vectors, dtype=np.int64) +>>> build_params = ivf_pq.IndexParams(metric="sqeuclidean") +>>> index = ivf_pq.build(build_params, dataset) +>>> ivf_pq.extend(index, new_vectors, new_indices) +``` + +_Source: `python/cuvs/cuvs/neighbors/mg/ivf_pq/ivf_pq.pyx:386`_ + +## search + +`@auto_sync_multi_gpu_resources` +`@auto_convert_output` + +```python +def search(SearchParams search_params, Index index, queries, k, neighbors=None, distances=None, resources=None) +``` + +Search the multi-GPU IVF-PQ index for the k-nearest neighbors +of each query. + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `search_params` | `cuvs.neighbors.ivf_pq.SearchParams` | | +| `index` | `cuvs.neighbors.ivf_pq.Index` | | +| `queries` | `Array interface compliant matrix shape (n_queries, dim)` | Supported dtype [float32, float16, int8, uint8] **IMPORTANT**: For multi-GPU IVF-PQ, queries MUST be in host memory (CPU). If using CuPy/device arrays, transfer to host with array.get() or cp.asnumpy(array). | +| `k` | `int` | The number of neighbors to search for each query. | +| `neighbors` | `Array interface compliant matrix shape (n_queries, k), optional` | If provided, this array will be filled with the indices of the k-nearest neighbors. If not provided, a new host array will be allocated. **IMPORTANT**: Must be in host memory (CPU) for multi-GPU IVF-PQ. | +| `distances` | `Array interface compliant matrix shape (n_queries, k), optional` | If provided, this array will be filled with the distances to the k-nearest neighbors. If not provided, a new host array will be allocated. **IMPORTANT**: Must be in host memory (CPU) for multi-GPU IVF-PQ. | +| `resources` | `cuvs.common.Resources, optional` | | + +**Returns** + +| Name | Type | Description | +| --- | --- | --- | +| `distances` | `numpy.ndarray` | The distances to the k-nearest neighbors for each query (in host memory). | +| `neighbors` | `numpy.ndarray` | The indices of the k-nearest neighbors for each query (in host memory). | + +**Examples** + +```python +>>> import numpy as np +>>> from cuvs.neighbors.mg import ivf_pq +>>> n_samples = 50000 +>>> n_features = 50 +>>> n_queries = 1000 +>>> k = 10 +>>> # For multi-GPU IVF-PQ, use host (NumPy) arrays +>>> dataset = np.random.random_sample((n_samples, n_features)).astype( +... np.float32) +>>> queries = np.random.random_sample((n_queries, n_features)).astype( +... np.float32) +>>> build_params = ivf_pq.IndexParams(metric="sqeuclidean") +>>> index = ivf_pq.build(build_params, dataset) +>>> distances, neighbors = ivf_pq.search(ivf_pq.SearchParams(), +... index, queries, k) +>>> # Results are already in host memory (NumPy arrays) +``` + +_Source: `python/cuvs/cuvs/neighbors/mg/ivf_pq/ivf_pq.pyx:276`_ + +## save + +`@auto_sync_multi_gpu_resources` + +```python +def save(Index index, filename, resources=None) +``` + +Serialize the multi-GPU IVF-PQ index to a file. + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `index` | `cuvs.neighbors.ivf_pq.Index` | | +| `filename` | `str` | The filename to serialize the index to. | +| `resources` | `cuvs.common.Resources, optional` | | + +**Examples** + +```python +>>> import numpy as np +>>> from cuvs.neighbors.mg import ivf_pq +>>> n_samples = 50000 +>>> n_features = 50 +>>> # For multi-GPU IVF-PQ, use host (NumPy) arrays +>>> dataset = np.random.random_sample((n_samples, n_features)).astype( +... np.float32) +>>> build_params = ivf_pq.IndexParams(metric="sqeuclidean") +>>> index = ivf_pq.build(build_params, dataset) +>>> ivf_pq.save(index, "index.bin") +``` + +_Source: `python/cuvs/cuvs/neighbors/mg/ivf_pq/ivf_pq.pyx:459`_ + +## load + +`@auto_sync_multi_gpu_resources` + +```python +def load(filename, resources=None) +``` + +Deserialize the multi-GPU IVF-PQ index from a file. + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `filename` | `str` | The filename to deserialize the index from. | +| `resources` | `cuvs.common.Resources, optional` | | + +**Returns** + +| Name | Type | Description | +| --- | --- | --- | +| `index` | `Index` | The deserialized index. | + +**Examples** + +```python +>>> from cuvs.neighbors.mg import ivf_pq +>>> index = ivf_pq.load("index.bin") # doctest: +SKIP +``` + +_Source: `python/cuvs/cuvs/neighbors/mg/ivf_pq/ivf_pq.pyx:497`_ + +## distribute + +`@auto_sync_multi_gpu_resources` + +```python +def distribute(filename, resources=None) +``` + +Distribute a single-GPU IVF-PQ index across multiple GPUs from a file. + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `filename` | `str` | The filename to distribute the index from. | +| `resources` | `cuvs.common.Resources, optional` | | + +**Returns** + +| Name | Type | Description | +| --- | --- | --- | +| `index` | `Index` | The distributed index. | + +**Examples** + +```python +>>> from cuvs.neighbors.mg import ivf_pq +>>> index = ivf_pq.distribute("single_gpu_index.bin") # doctest: +SKIP +``` + +_Source: `python/cuvs/cuvs/neighbors/mg/ivf_pq/ivf_pq.pyx:531`_ diff --git a/fern/pages/python_api/python-api-neighbors-nn-descent.md b/fern/pages/python_api/python-api-neighbors-nn-descent.md new file mode 100644 index 0000000000..fe52b6a46b --- /dev/null +++ b/fern/pages/python_api/python-api-neighbors-nn-descent.md @@ -0,0 +1,192 @@ +--- +slug: api-reference/python-api-neighbors-nn-descent +--- + +# NN Descent + +_Python module: `cuvs.neighbors.nn_descent`_ + +## Index + +```python +cdef class Index +``` + +NN-Descent index object. This object stores the trained NN-Descent index, +which can be used to get the NN-Descent graph and distances after +building + +**Members** + +| Name | Kind | Source | +| --- | --- | --- | +| `trained` | property | `python/cuvs/cuvs/neighbors/nn_descent/nn_descent.pyx:165` | +| `graph` | property | `python/cuvs/cuvs/neighbors/nn_descent/nn_descent.pyx:169` | +| `distances` | property | `python/cuvs/cuvs/neighbors/nn_descent/nn_descent.pyx:173` | + +### trained + +```python +def trained(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/nn_descent/nn_descent.pyx:165`_ + +### graph + +```python +def graph(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/nn_descent/nn_descent.pyx:169`_ + +### distances + +```python +def distances(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/nn_descent/nn_descent.pyx:173`_ + +_Source: `python/cuvs/cuvs/neighbors/nn_descent/nn_descent.pyx:143`_ + +## IndexParams + +```python +cdef class IndexParams +``` + +Parameters to build NN-Descent Index + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `metric` | `str, default = "sqeuclidean"` | String denoting the metric type. Supported metrics are `l2`, `euclidean`, `sqeuclidean`, `inner_product`, `cosine`, and `bitwise_hamming` (`bitwise_hamming` is for int8 and uint8 data types only) | +| `graph_degree` | `int` | For an input dataset of dimensions (N, D), determines the final dimensions of the all-neighbors knn graph which turns out to be of dimensions (N, graph_degree) | +| `intermediate_graph_degree` | `int` | Internally, nn-descent builds an all-neighbors knn graph of dimensions (N, intermediate_graph_degree) before selecting the final `graph_degree` neighbors. It's recommended that `intermediate_graph_degree` >= 1.5 * graph_degree | +| `max_iterations` | `int` | The number of iterations that nn-descent will refine the graph for. More iterations produce a better quality graph at cost of performance | +| `termination_threshold` | `float` | The delta at which nn-descent will terminate its iterations | +| `return_distances` | `bool` | Whether to return distances array | +| `dist_comp_dtype` | `str, default = "auto"` | Dtype to use for distance computation. Supported dtypes are `auto`, `fp32`, and `fp16` `auto` automatically determines the best dtype for distance computation based on the dataset dimensions. `fp32` uses fp32 distance computation for better precision at the cost of performance and memory usage. This option is only valid when data type is fp32. `fp16` uses fp16 distance computation for better performance and memory usage at the cost of precision. | + +**Constructor** + +```python +def __init__(self, *, metric=None, metric_arg=None, graph_degree=None, intermediate_graph_degree=None, max_iterations=None, termination_threshold=None, return_distances=None, dist_comp_dtype="auto" ) +``` + +**Members** + +| Name | Kind | Source | +| --- | --- | --- | +| `metric` | property | `python/cuvs/cuvs/neighbors/nn_descent/nn_descent.pyx:116` | +| `metric_arg` | property | `python/cuvs/cuvs/neighbors/nn_descent/nn_descent.pyx:120` | +| `graph_degree` | property | `python/cuvs/cuvs/neighbors/nn_descent/nn_descent.pyx:124` | +| `intermediate_graph_degree` | property | `python/cuvs/cuvs/neighbors/nn_descent/nn_descent.pyx:128` | +| `max_iterations` | property | `python/cuvs/cuvs/neighbors/nn_descent/nn_descent.pyx:132` | +| `termination_threshold` | property | `python/cuvs/cuvs/neighbors/nn_descent/nn_descent.pyx:136` | +| `get_handle` | method | `python/cuvs/cuvs/neighbors/nn_descent/nn_descent.pyx:139` | + +### metric + +```python +def metric(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/nn_descent/nn_descent.pyx:116`_ + +### metric_arg + +```python +def metric_arg(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/nn_descent/nn_descent.pyx:120`_ + +### graph_degree + +```python +def graph_degree(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/nn_descent/nn_descent.pyx:124`_ + +### intermediate_graph_degree + +```python +def intermediate_graph_degree(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/nn_descent/nn_descent.pyx:128`_ + +### max_iterations + +```python +def max_iterations(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/nn_descent/nn_descent.pyx:132`_ + +### termination_threshold + +```python +def termination_threshold(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/nn_descent/nn_descent.pyx:136`_ + +### get_handle + +```python +def get_handle(self) +``` + +Get a pointer to the underlying C object. + +_Source: `python/cuvs/cuvs/neighbors/nn_descent/nn_descent.pyx:139`_ + +_Source: `python/cuvs/cuvs/neighbors/nn_descent/nn_descent.pyx:39`_ + +## build + +`@auto_sync_resources` + +```python +def build(IndexParams index_params, dataset, graph=None, resources=None) +``` + +Build KNN graph from the dataset + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `index_params` | `cuvs.neighbors.nn_descent.IndexParams` | | +| `dataset` | `Array interface compliant matrix, on either host or device memory` | Supported dtype [float, int8, uint8] | +| `graph` | `Optional host matrix for storing output graph` | | +| `resources` | `cuvs.common.Resources, optional` | | + +**Returns** + +| Name | Type | Description | +| --- | --- | --- | +| `index` | `cuvs.neighbors.nn_descent.Index` | | + +**Examples** + +```python +>>> import cupy as cp +>>> from cuvs.neighbors import nn_descent +>>> n_samples = 50000 +>>> n_features = 50 +>>> n_queries = 1000 +>>> k = 10 +>>> dataset = cp.random.random_sample((n_samples, n_features), +... dtype=cp.float32) +>>> build_params = nn_descent.IndexParams(metric="sqeuclidean") +>>> index = nn_descent.build(build_params, dataset) +>>> graph = index.graph +``` + +_Source: `python/cuvs/cuvs/neighbors/nn_descent/nn_descent.pyx:210`_ diff --git a/fern/pages/python_api/python-api-neighbors-tiered-index.md b/fern/pages/python_api/python-api-neighbors-tiered-index.md new file mode 100644 index 0000000000..8aa3e1f415 --- /dev/null +++ b/fern/pages/python_api/python-api-neighbors-tiered-index.md @@ -0,0 +1,249 @@ +--- +slug: api-reference/python-api-neighbors-tiered-index +--- + +# Tiered Index + +_Python module: `cuvs.neighbors.tiered_index`_ + +## Index + +```python +cdef class Index +``` + +Tiered Index object. + +**Members** + +| Name | Kind | Source | +| --- | --- | --- | +| `trained` | property | `python/cuvs/cuvs/neighbors/tiered_index/tiered_index.pyx:159` | + +### trained + +```python +def trained(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/tiered_index/tiered_index.pyx:159`_ + +_Source: `python/cuvs/cuvs/neighbors/tiered_index/tiered_index.pyx:143`_ + +## IndexParams + +```python +cdef class IndexParams +``` + +Parameters to build index for Tiered Index nearest neighbor search + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `metric` | `str, default = "sqeuclidean"` | String denoting the metric type. Valid values for metric: ["sqeuclidean", "inner_product", "euclidean", "cosine"], where - sqeuclidean is the euclidean distance without the square root operation, i.e.: distance(a,b) = \\sum_i (a_i - b_i)^2, - euclidean is the euclidean distance - inner product distance is defined as distance(a, b) = \\sum_i a_i * b_i. - cosine distance is defined as distance(a, b) = 1 - \\sum_i a_i * b_i / ( \|\|a\|\|_2 * \|\|b\|\|_2). | +| `algo` | `str, default = "cagra"` | The algorithm to use for the ANN portion of the tiered index | +| `upstream_params` | `object, optional` | The IndexParams for the upstream ANN object to use (ie the Cagra IndexParams for cagra etc) | +| `min_ann_rows` | `int` | The minimum number of rows necessary to create an ann index | +| `create_ann_index_on_extend` | `bool` | Whether or not to create a new ann index on extend, if the number of rows in the incremental (bfknn) portion is above min_ann_rows | + +**Constructor** + +```python +def __init__(self, *, metric="sqeuclidean", algo="cagra", upstream_params=None, min_ann_rows=None, create_ann_index_on_extend=None,) +``` + +**Members** + +| Name | Kind | Source | +| --- | --- | --- | +| `metric` | property | `python/cuvs/cuvs/neighbors/tiered_index/tiered_index.pyx:124` | +| `algo` | property | `python/cuvs/cuvs/neighbors/tiered_index/tiered_index.pyx:128` | +| `min_ann_rows` | property | `python/cuvs/cuvs/neighbors/tiered_index/tiered_index.pyx:132` | +| `create_ann_index_on_extend` | property | `python/cuvs/cuvs/neighbors/tiered_index/tiered_index.pyx:136` | +| `upstream_params` | property | `python/cuvs/cuvs/neighbors/tiered_index/tiered_index.pyx:140` | + +### metric + +```python +def metric(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/tiered_index/tiered_index.pyx:124`_ + +### algo + +```python +def algo(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/tiered_index/tiered_index.pyx:128`_ + +### min_ann_rows + +```python +def min_ann_rows(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/tiered_index/tiered_index.pyx:132`_ + +### create_ann_index_on_extend + +```python +def create_ann_index_on_extend(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/tiered_index/tiered_index.pyx:136`_ + +### upstream_params + +```python +def upstream_params(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/tiered_index/tiered_index.pyx:140`_ + +_Source: `python/cuvs/cuvs/neighbors/tiered_index/tiered_index.pyx:48`_ + +## build + +`@auto_sync_resources` + +```python +def build(IndexParams index_params, dataset, resources=None) +``` + +Build the Tiered index from the dataset for efficient search. + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `index_params` | `cuvs.neighbors.tiered_index.IndexParams` | | +| `dataset` | `CUDA array interface compliant matrix shape (n_samples, dim)` | Supported dtype [float32] | +| `resources` | `cuvs.common.Resources, optional` | | + +**Returns** + +| Name | Type | Description | +| --- | --- | --- | +| `index` | `cuvs.neighbors.tiered_index.Index` | | + +**Examples** + +```python +>>> import cupy as cp +>>> from cuvs.neighbors import cagra, tiered_index +>>> n_samples = 50000 +>>> n_features = 50 +>>> n_queries = 1000 +>>> k = 10 +>>> dataset = cp.random.random_sample((n_samples, n_features), +... dtype=cp.float32) +>>> build_params = tiered_index.IndexParams(metric="sqeuclidean", +... algo="cagra") +>>> index = tiered_index.build(build_params, dataset) +>>> distances, neighbors = tiered_index.search(cagra.SearchParams(), +... index, dataset, k) +>>> distances = cp.asarray(distances) +>>> neighbors = cp.asarray(neighbors) +``` + +_Source: `python/cuvs/cuvs/neighbors/tiered_index/tiered_index.pyx:164`_ + +## extend + +`@auto_sync_resources` + +```python +def extend(Index index, new_vectors, resources=None) +``` + +Extend an existing index with new vectors. + +The input array can be either CUDA array interface compliant matrix or +array interface compliant matrix in host memory. + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `index` | `tiered_index.Index` | Trained tiered_index object. | +| `new_vectors` | `array interface compliant matrix shape (n_samples, dim)` | Supported dtype [float32] | +| `resources` | `cuvs.common.Resources, optional` | | + +**Returns** + +| Name | Type | Description | +| --- | --- | --- | +| `index` | `cuvs.neighbors.tiered_index.Index` | | + +**Examples** + +```python +>>> import cupy as cp +>>> from cuvs.neighbors import tiered_index +>>> n_samples = 50000 +>>> n_features = 50 +>>> n_queries = 1000 +>>> dataset = cp.random.random_sample((n_samples, n_features), +... dtype=cp.float32) +>>> index = tiered_index.build(tiered_index.IndexParams(), dataset) +>>> n_rows = 100 +>>> more_data = cp.random.random_sample((n_rows, n_features), +... dtype=cp.float32) +>>> index = tiered_index.extend(index, more_data) +``` + +_Source: `python/cuvs/cuvs/neighbors/tiered_index/tiered_index.pyx:326`_ + +## search + +`@auto_sync_resources` +`@auto_convert_output` + +```python +def search(search_params, Index index, queries, k, neighbors=None, distances=None, resources=None, filter=None) +``` + +Find the k nearest neighbors for each query. + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `search_params` | `SearchParams for the upstream ANN index` | | +| `index` | `cuvs.neighbors.tiered_index.Index` | Trained Tiered index. | +| `queries` | `CUDA array interface compliant matrix shape (n_samples, dim)` | Supported dtype [float32] | +| `k` | `int` | The number of neighbors. | +| `neighbors` | `Optional CUDA array interface compliant matrix shape` | (n_queries, k), dtype int64_t. If supplied, neighbor indices will be written here in-place. (default None) | +| `distances` | `Optional CUDA array interface compliant matrix shape` | (n_queries, k) If supplied, the distances to the neighbors will be written here in-place. (default None) | +| `filter` | `Optional cuvs.neighbors.cuvsFilter can be used to filter` | neighbors based on a given bitset. (default None) | +| `resources` | `cuvs.common.Resources, optional` | | + +**Examples** + +```python +>>> import cupy as cp +>>> from cuvs.neighbors import cagra, tiered_index +>>> n_samples = 50000 +>>> n_features = 50 +>>> n_queries = 1000 +>>> dataset = cp.random.random_sample((n_samples, n_features), +... dtype=cp.float32) +>>> # Build the index +>>> index = tiered_index.build(tiered_index.IndexParams(algo="cagra"), +... dataset) +>>> +>>> # Search using the built index +>>> queries = cp.random.random_sample((n_queries, n_features), +... dtype=cp.float32) +>>> k = 10 +>>> search_params = cagra.SearchParams() +>>> +>>> distances, neighbors = tiered_index.search(search_params, index, +... queries, k) +``` + +_Source: `python/cuvs/cuvs/neighbors/tiered_index/tiered_index.pyx:223`_ diff --git a/fern/pages/python_api/python-api-neighbors-vamana.md b/fern/pages/python_api/python-api-neighbors-vamana.md new file mode 100644 index 0000000000..02381432a7 --- /dev/null +++ b/fern/pages/python_api/python-api-neighbors-vamana.md @@ -0,0 +1,239 @@ +--- +slug: api-reference/python-api-neighbors-vamana +--- + +# Vamana + +_Python module: `cuvs.neighbors.vamana`_ + +## Index + +```python +cdef class Index +``` + +Vamana index object. This object stores the trained Vamana index state +which can be used to perform nearest neighbors searches. + +**Members** + +| Name | Kind | Source | +| --- | --- | --- | +| `trained` | property | `python/cuvs/cuvs/neighbors/vamana/vamana.pyx:49` | + +### trained + +```python +def trained(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/vamana/vamana.pyx:49`_ + +_Source: `python/cuvs/cuvs/neighbors/vamana/vamana.pyx:34`_ + +## IndexParams + +```python +cdef class IndexParams +``` + +Parameters for building a Vamana index + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `metric` | `str, default="sqeuclidean"` | String denoting the metric type. Supported metrics include: - "sqeuclidean" - "l2" | +| `graph_degree` | `int, default=32` | Maximum degree of graph; corresponds to the R parameter of Vamana algorithm in the literature. | +| `visited_size` | `int, default=64` | Maximum number of visited nodes per search during Vamana algorithm. Loosely corresponds to the L parameter in the literature. | +| `vamana_iters` | `float, default=1` | Number of Vamana vector insertion iterations (each iteration inserts all vectors). | +| `alpha` | `float, default=1.2` | Alpha for pruning parameter. Used to determine how aggressive the pruning will be. | +| `max_fraction` | `float, default=0.06` | Maximum fraction of dataset inserted per batch. Larger max batch decreases graph quality, but improves speed. | +| `batch_base` | `float, default=2.0` | Base of growth rate of batch sizes. | +| `queue_size` | `int, default=127` | Size of candidate queue structure - should be (2^x)-1. | +| `reverse_batchsize` | `int, default=1000000` | Max batchsize of reverse edge processing (reduces memory footprint). | + +**Constructor** + +```python +def __init__(self, *, metric="sqeuclidean", graph_degree=32, visited_size=64, vamana_iters=1, alpha=1.2, max_fraction=0.06, batch_base=2.0, queue_size=127, reverse_batchsize=1000000) +``` + +**Members** + +| Name | Kind | Source | +| --- | --- | --- | +| `metric` | property | `python/cuvs/cuvs/neighbors/vamana/vamana.pyx:122` | +| `graph_degree` | property | `python/cuvs/cuvs/neighbors/vamana/vamana.pyx:126` | +| `visited_size` | property | `python/cuvs/cuvs/neighbors/vamana/vamana.pyx:130` | +| `vamana_iters` | property | `python/cuvs/cuvs/neighbors/vamana/vamana.pyx:134` | +| `alpha` | property | `python/cuvs/cuvs/neighbors/vamana/vamana.pyx:138` | +| `max_fraction` | property | `python/cuvs/cuvs/neighbors/vamana/vamana.pyx:142` | +| `batch_base` | property | `python/cuvs/cuvs/neighbors/vamana/vamana.pyx:146` | +| `queue_size` | property | `python/cuvs/cuvs/neighbors/vamana/vamana.pyx:150` | +| `reverse_batchsize` | property | `python/cuvs/cuvs/neighbors/vamana/vamana.pyx:154` | + +### metric + +```python +def metric(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/vamana/vamana.pyx:122`_ + +### graph_degree + +```python +def graph_degree(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/vamana/vamana.pyx:126`_ + +### visited_size + +```python +def visited_size(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/vamana/vamana.pyx:130`_ + +### vamana_iters + +```python +def vamana_iters(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/vamana/vamana.pyx:134`_ + +### alpha + +```python +def alpha(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/vamana/vamana.pyx:138`_ + +### max_fraction + +```python +def max_fraction(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/vamana/vamana.pyx:142`_ + +### batch_base + +```python +def batch_base(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/vamana/vamana.pyx:146`_ + +### queue_size + +```python +def queue_size(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/vamana/vamana.pyx:150`_ + +### reverse_batchsize + +```python +def reverse_batchsize(self) +``` + +_Source: `python/cuvs/cuvs/neighbors/vamana/vamana.pyx:154`_ + +_Source: `python/cuvs/cuvs/neighbors/vamana/vamana.pyx:58`_ + +## build + +`@auto_sync_resources` + +```python +def build(IndexParams index_params, dataset, resources=None) +``` + +Build the Vamana index from the dataset for efficient search. + +The build utilities the Vamana insertion-based algorithm to create +the graph. The algorithm starts with an empty graph and iteratively +inserts batches of nodes. Each batch involves performing a greedy +search for each vector to be inserted, and inserting it with edges to +all nodes traversed during the search. Reverse edges are also inserted +and robustPrune is applied to improve graph quality. The index_params +struct controls the degree of the final graph. + +The following distance metrics are supported: +- L2Expanded + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `index_params` | `IndexParams object` | | +| `dataset` | `CUDA array interface compliant matrix shape (n_samples, dim)` | Supported dtype [float, int8, uint8] | +| `resources` | `cuvs.common.Resources, optional` | | + +**Returns** + +| Name | Type | Description | +| --- | --- | --- | +| `index` | `cuvs.vamana.Index` | | + +**Examples** + +```python +>>> import cupy as cp +>>> from cuvs.neighbors import vamana +>>> n_samples = 50000 +>>> n_features = 50 +>>> dataset = cp.random.random_sample((n_samples, n_features), +... dtype=cp.float32) +>>> build_params = vamana.IndexParams(metric="sqeuclidean") +>>> index = vamana.build(build_params, dataset) +>>> # Serialize index to file for later use with CPU DiskANN +>>> vamana.save("my_index.bin", index) +``` + +_Source: `python/cuvs/cuvs/neighbors/vamana/vamana.pyx:159`_ + +## save + +`@auto_sync_resources` + +```python +def save(filename, Index index, bool include_dataset=True, resources=None) +``` + +Saves the index to a file. + +Matches the file format used by the DiskANN open-source repository, +allowing cross-compatibility. + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `filename` | `string` | Name of the file. | +| `index` | `Index` | Trained Vamana index. | +| `include_dataset` | `bool` | Whether or not to write out the dataset along with the index. Including the dataset in the serialized index will use extra disk space, and might not be desired if you already have a copy of the dataset on disk. | +| `resources` | `cuvs.common.Resources, optional` | | + +**Examples** + +```python +>>> import cupy as cp +>>> from cuvs.neighbors import vamana +>>> n_samples = 50000 +>>> n_features = 50 +>>> dataset = cp.random.random_sample((n_samples, n_features), +... dtype=cp.float32) +>>> # Build index +>>> index = vamana.build(vamana.IndexParams(), dataset) +>>> # Serialize and save the vamana index +>>> vamana.save("my_index.bin", index) +``` + +_Source: `python/cuvs/cuvs/neighbors/vamana/vamana.pyx:228`_ diff --git a/fern/pages/python_api/python-api-neighbors.md b/fern/pages/python_api/python-api-neighbors.md new file mode 100644 index 0000000000..4fac2b8918 --- /dev/null +++ b/fern/pages/python_api/python-api-neighbors.md @@ -0,0 +1,69 @@ +--- +slug: api-reference/python-api-neighbors +--- + +# Neighbors + +_Python module: `cuvs.neighbors`_ + +## refine + +`@auto_sync_resources` +`@auto_convert_output` + +```python +def refine(dataset, queries, candidates, k=None, metric="sqeuclidean", indices=None, distances=None, resources=None) +``` + +Refine nearest neighbor search. + +Refinement is an operation that follows an approximate NN search. The +approximate search has already selected n_candidates neighbor candidates +for each query. We narrow it down to k neighbors. For each query, we +calculate the exact distance between the query and its n_candidates +neighbor candidate, and select the k nearest ones. + +Input arrays can be either CUDA array interface compliant matrices or +array interface compliant matrices in host memory. All array must be in +the same memory space. + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `dataset` | `array interface compliant matrix, shape (n_samples, dim)` | Supported dtype [float32, int8, uint8, float16] | +| `queries` | `array interface compliant matrix, shape (n_queries, dim)` | Supported dtype [float32, int8, uint8, float16] | +| `candidates` | `array interface compliant matrix, shape (n_queries, k0)` | Supported dtype int64 | +| `k` | `int` | Number of neighbors to search (k <= k0). Optional if indices or distances arrays are given (in which case their second dimension is k). | +| `metric` | `str` | Name of distance metric to use, default ="sqeuclidean" | +| `indices` | `Optional array interface compliant matrix shape (n_queries, k).` | If supplied, neighbor indices will be written here in-place. (default None). Supported dtype int64. | +| `distances` | `Optional array interface compliant matrix shape (n_queries, k).` | If supplied, neighbor indices will be written here in-place. (default None) Supported dtype float. | +| `resources` | `cuvs.common.Resources, optional` | | + +**Examples** + +```python +>>> import cupy as cp +>>> from cuvs.common import Resources +>>> from cuvs.neighbors import ivf_pq, refine +>>> n_samples = 50000 +>>> n_features = 50 +>>> n_queries = 1000 +>>> dataset = cp.random.random_sample((n_samples, n_features), +... dtype=cp.float32) +>>> resources = Resources() +>>> index_params = ivf_pq.IndexParams(n_lists=1024, +... metric="sqeuclidean", +... pq_dim=10) +>>> index = ivf_pq.build(index_params, dataset, resources=resources) +>>> # Search using the built index +>>> queries = cp.random.random_sample((n_queries, n_features), +... dtype=cp.float32) +>>> k = 40 +>>> _, candidates = ivf_pq.search(ivf_pq.SearchParams(), index, +... queries, k, resources=resources) +>>> k = 10 +>>> distances, neighbors = refine(dataset, queries, candidates, k) +``` + +_Source: `python/cuvs/cuvs/neighbors/refine.pyx:34`_ diff --git a/fern/pages/python_api/python-api-preprocessing-pca.md b/fern/pages/python_api/python-api-preprocessing-pca.md new file mode 100644 index 0000000000..7c17d0fdd0 --- /dev/null +++ b/fern/pages/python_api/python-api-preprocessing-pca.md @@ -0,0 +1,264 @@ +--- +slug: api-reference/python-api-preprocessing-pca +--- + +# PCA + +_Python module: `cuvs.preprocessing.pca`_ + +## Params + +```python +cdef class Params +``` + +Parameters for PCA decomposition. + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `n_components` | `int` | Number of principal components to keep (default: 1). | +| `copy` | `bool` | If False, data passed to fit are overwritten and running fit(X) then transform(X) will not yield the expected results; use fit_transform(X) instead (default: True). | +| `whiten` | `bool` | When True the component vectors are multiplied by the square root of n_samples and divided by the singular values to ensure uncorrelated outputs with unit component-wise variances (default: False). | +| `algorithm` | `str` | Solver algorithm. One of ``"cov_eig_dq"`` (divide-and-conquer) or ``"cov_eig_jacobi"`` (Jacobi) (default: ``"cov_eig_dq"``). | +| `tol` | `float` | Tolerance for singular values, used by the Jacobi solver (default: 0.0). | +| `n_iterations` | `int` | Number of iterations for the Jacobi solver (default: 15). | + +**Constructor** + +```python +def __init__(self, *, n_components=None, copy=None, whiten=None, algorithm=None, tol=None, n_iterations=None) +``` + +**Members** + +| Name | Kind | Source | +| --- | --- | --- | +| `n_components` | property | `python/cuvs/cuvs/preprocessing/pca/pca.pyx:82` | +| `copy` | property | `python/cuvs/cuvs/preprocessing/pca/pca.pyx:86` | +| `whiten` | property | `python/cuvs/cuvs/preprocessing/pca/pca.pyx:90` | +| `algorithm` | property | `python/cuvs/cuvs/preprocessing/pca/pca.pyx:94` | +| `tol` | property | `python/cuvs/cuvs/preprocessing/pca/pca.pyx:98` | +| `n_iterations` | property | `python/cuvs/cuvs/preprocessing/pca/pca.pyx:102` | + +### n_components + +```python +def n_components(self) +``` + +_Source: `python/cuvs/cuvs/preprocessing/pca/pca.pyx:82`_ + +### copy + +```python +def copy(self) +``` + +_Source: `python/cuvs/cuvs/preprocessing/pca/pca.pyx:86`_ + +### whiten + +```python +def whiten(self) +``` + +_Source: `python/cuvs/cuvs/preprocessing/pca/pca.pyx:90`_ + +### algorithm + +```python +def algorithm(self) +``` + +_Source: `python/cuvs/cuvs/preprocessing/pca/pca.pyx:94`_ + +### tol + +```python +def tol(self) +``` + +_Source: `python/cuvs/cuvs/preprocessing/pca/pca.pyx:98`_ + +### n_iterations + +```python +def n_iterations(self) +``` + +_Source: `python/cuvs/cuvs/preprocessing/pca/pca.pyx:102`_ + +_Source: `python/cuvs/cuvs/preprocessing/pca/pca.pyx:31`_ + +## fit + +`@auto_sync_resources` + +```python +def fit(Params params, X, resources=None) +``` + +Compute PCA (fit only). + +Computes the principal components, explained variances, singular +values, and column means from the input data. + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `params` | `Params` | PCA parameters. ``params.copy`` should be True if you intend to reuse *X* after this call. | +| `X` | `device array-like, shape (n_samples, n_features), float32` | Input data (will be converted to col-major device memory). | +| `resources` | `cuvs.common.Resources, optional` | | + +**Returns** + +FitOutput +Named tuple with fields: ``components``, ``explained_var``, +``explained_var_ratio``, ``singular_vals``, ``mu``, +``noise_vars``. + +**Examples** + +```python +>>> import cupy as cp +>>> from cuvs.preprocessing import pca +>>> X = cp.random.random_sample((500, 32), dtype=cp.float32) +>>> params = pca.Params(n_components=8, copy=True) +>>> result = pca.fit(params, X) +>>> result.components.shape +(8, 32) +``` + +_Source: `python/cuvs/cuvs/preprocessing/pca/pca.pyx:127`_ + +## fit_transform + +`@auto_sync_resources` + +```python +def fit_transform(Params params, X, resources=None) +``` + +Compute PCA and transform the input data in a single operation. + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `params` | `Params` | PCA parameters. | +| `X` | `device array-like, shape (n_samples, n_features), float32` | Input data (will be converted to col-major device memory). | +| `resources` | `cuvs.common.Resources, optional` | | + +**Returns** + +FitTransformOutput +Named tuple with fields: ``trans_input``, ``components``, +``explained_var``, ``explained_var_ratio``, ``singular_vals``, +``mu``, ``noise_vars``. + +**Examples** + +```python +>>> import cupy as cp +>>> from cuvs.preprocessing import pca +>>> X = cp.random.random_sample((500, 32), dtype=cp.float32) +>>> params = pca.Params(n_components=8) +>>> result = pca.fit_transform(params, X) +>>> result.trans_input.shape +(500, 8) +``` + +_Source: `python/cuvs/cuvs/preprocessing/pca/pca.pyx:200`_ + +## inverse_transform + +`@auto_sync_resources` +`@auto_convert_output` + +```python +def inverse_transform(Params params, trans_input, components, singular_vals, mu, output=None, resources=None) +``` + +Transform data from the PCA eigenspace back to the original space. + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `params` | `Params` | PCA parameters (must match those used during fit). | +| `trans_input` | `device array-like, shape (n_samples, n_components)` | Transformed data from transform or fit_transform. | +| `components` | `device array-like, shape (n_components, n_features)` | Principal components from a prior fit. | +| `singular_vals` | `device array-like, shape (n_components,)` | Singular values from a prior fit. | +| `mu` | `device array-like, shape (n_features,)` | Column means from a prior fit. | +| `output` | `optional device array, shape (n_samples, n_features)` | Pre-allocated output buffer (col-major, float32). | +| `resources` | `cuvs.common.Resources, optional` | | + +**Returns** + +| Name | Type | Description | +| --- | --- | --- | +| `output` | `device array, shape (n_samples, n_features)` | Reconstructed data. | + +**Examples** + +```python +>>> import cupy as cp +>>> from cuvs.preprocessing import pca +>>> X = cp.random.random_sample((500, 32), dtype=cp.float32) +>>> params = pca.Params(n_components=8) +>>> result = pca.fit_transform(params, X) +>>> reconstructed = pca.inverse_transform( +... params, result.trans_input, result.components, +... result.singular_vals, result.mu) +``` + +_Source: `python/cuvs/cuvs/preprocessing/pca/pca.pyx:353`_ + +## transform + +`@auto_sync_resources` +`@auto_convert_output` + +```python +def transform(Params params, X, components, singular_vals, mu, trans_input=None, resources=None) +``` + +Transform data into the PCA eigenspace. + +Uses previously computed principal components from fit or +fit_transform. + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `params` | `Params` | PCA parameters (must match those used during fit). | +| `X` | `device array-like, shape (n_samples, n_features), float32` | Data to transform. | +| `components` | `device array-like, shape (n_components, n_features)` | Principal components from a prior fit. | +| `singular_vals` | `device array-like, shape (n_components,)` | Singular values from a prior fit. | +| `mu` | `device array-like, shape (n_features,)` | Column means from a prior fit. | +| `trans_input` | `optional device array, shape (n_samples, n_components)` | Pre-allocated output buffer (col-major, float32). | +| `resources` | `cuvs.common.Resources, optional` | | + +**Returns** + +| Name | Type | Description | +| --- | --- | --- | +| `trans_input` | `device array, shape (n_samples, n_components)` | | + +**Examples** + +```python +>>> import cupy as cp +>>> from cuvs.preprocessing import pca +>>> X = cp.random.random_sample((500, 32), dtype=cp.float32) +>>> params = pca.Params(n_components=8, copy=True) +>>> result = pca.fit(params, X) +>>> transformed = pca.transform(params, X, result.components, +... result.singular_vals, result.mu) +``` + +_Source: `python/cuvs/cuvs/preprocessing/pca/pca.pyx:275`_ diff --git a/fern/pages/python_api/python-api-preprocessing-quantize-binary.md b/fern/pages/python_api/python-api-preprocessing-quantize-binary.md new file mode 100644 index 0000000000..93eaf22791 --- /dev/null +++ b/fern/pages/python_api/python-api-preprocessing-quantize-binary.md @@ -0,0 +1,56 @@ +--- +slug: api-reference/python-api-preprocessing-quantize-binary +--- + +# Binary + +_Python module: `cuvs.preprocessing.quantize.binary`_ + +## transform + +`@auto_sync_resources` +`@auto_convert_output` + +```python +def transform(dataset, output=None, resources=None) +``` + +Applies binary quantization transform to given dataset + +This applies binary quantization to a dataset, changing any positive +values to a bitwise 1. This is useful for searching with the +BitwiseHamming distance type. + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `dataset` | `row major host or device dataset to transform` | | +| `output` | `optional preallocated output memory, on host or device memory` | | +| `resources` | `cuvs.common.Resources, optional` | | + +**Returns** + +| Name | Type | Description | +| --- | --- | --- | +| `output` | `transformed dataset quantized into a uint8` | | + +**Examples** + +```python +>>> import cupy as cp +>>> from cuvs.preprocessing.quantize import binary +>>> from cuvs.neighbors import cagra +>>> n_samples = 50000 +>>> n_features = 50 +>>> dataset = cp.random.standard_normal((n_samples, n_features), +... dtype=cp.float32) +>>> transformed = binary.transform(dataset) +>>> +>>> # build a cagra index on the binarized data +>>> params = cagra.IndexParams(metric="bitwise_hamming", +... build_algo="iterative_cagra_search") +>>> idx = cagra.build(params, transformed) +``` + +_Source: `python/cuvs/cuvs/preprocessing/quantize/binary/binary.pyx:21`_ diff --git a/fern/pages/python_api/python-api-preprocessing-quantize-pq.md b/fern/pages/python_api/python-api-preprocessing-quantize-pq.md new file mode 100644 index 0000000000..070b2ddb16 --- /dev/null +++ b/fern/pages/python_api/python-api-preprocessing-quantize-pq.md @@ -0,0 +1,330 @@ +--- +slug: api-reference/python-api-preprocessing-quantize-pq +--- + +# PQ + +_Python module: `cuvs.preprocessing.quantize.pq`_ + +## Quantizer + +```python +cdef class Quantizer +``` + +Defines and stores Product Quantizer upon training + +The quantization is performed by a linear mapping of an interval in the +float data type to the full range of the quantized int type. + +**Members** + +| Name | Kind | Source | +| --- | --- | --- | +| `pq_bits` | property | `python/cuvs/cuvs/preprocessing/quantize/pq/pq.pyx:139` | +| `pq_dim` | property | `python/cuvs/cuvs/preprocessing/quantize/pq/pq.pyx:145` | +| `pq_codebook` | property | `python/cuvs/cuvs/preprocessing/quantize/pq/pq.pyx:151` | +| `vq_codebook` | property | `python/cuvs/cuvs/preprocessing/quantize/pq/pq.pyx:164` | +| `encoded_dim` | property | `python/cuvs/cuvs/preprocessing/quantize/pq/pq.pyx:177` | +| `use_vq` | property | `python/cuvs/cuvs/preprocessing/quantize/pq/pq.pyx:187` | + +### pq_bits + +```python +def pq_bits(self) +``` + +_Source: `python/cuvs/cuvs/preprocessing/quantize/pq/pq.pyx:139`_ + +### pq_dim + +```python +def pq_dim(self) +``` + +_Source: `python/cuvs/cuvs/preprocessing/quantize/pq/pq.pyx:145`_ + +### pq_codebook + +```python +def pq_codebook(self) +``` + +Returns the PQ codebook + +_Source: `python/cuvs/cuvs/preprocessing/quantize/pq/pq.pyx:151`_ + +### vq_codebook + +```python +def vq_codebook(self) +``` + +Returns the VQ codebook + +_Source: `python/cuvs/cuvs/preprocessing/quantize/pq/pq.pyx:164`_ + +### encoded_dim + +```python +def encoded_dim(self) +``` + +Returns the encoded dimension of the quantized dataset + +_Source: `python/cuvs/cuvs/preprocessing/quantize/pq/pq.pyx:177`_ + +### use_vq + +```python +def use_vq(self) +``` + +_Source: `python/cuvs/cuvs/preprocessing/quantize/pq/pq.pyx:187`_ + +_Source: `python/cuvs/cuvs/preprocessing/quantize/pq/pq.pyx:123`_ + +## QuantizerParams + +```python +cdef class QuantizerParams +``` + +Parameters for product quantization + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `pq_bits` | `int` | specifies the bit length of the vector element after compression by PQ possible values: within [4, 16] | +| `pq_dim` | `int` | specifies the dimensionality of the vector after compression by PQ | +| `use_subspaces` | `bool` | specifies whether to use subspaces for product quantization (PQ). When true, one PQ codebook is used for each subspace. Otherwise, a single PQ codebook is used. | +| `use_vq` | `bool` | specifies whether to use Vector Quantization (KMeans) before product quantization (PQ). | +| `vq_n_centers` | `int` | specifies the number of centers for the vector quantizer. When zero, an optimal value is selected using a heuristic. When one, only product quantization is used. | +| `kmeans_n_iters` | `int` | specifies the number of iterations searching for kmeans centers | +| `pq_kmeans_type` | `str` | specifies the type of kmeans algorithm to use for PQ training possible values: "kmeans", "kmeans_balanced" | +| `max_train_points_per_pq_code` | `int` | specifies the max number of data points to use per PQ code during PQ codebook training. Using more data points per PQ code may increase the quality of PQ codebook but may also increase the build time. | +| `max_train_points_per_vq_cluster` | `int` | specifies the max number of data points to use per VQ cluster. | + +**Constructor** + +```python +def __init__(self, *, pq_bits=8, pq_dim=0, use_subspaces=True, use_vq=False, vq_n_centers=0, kmeans_n_iters=25, pq_kmeans_type="kmeans_balanced", max_train_points_per_pq_code=256, max_train_points_per_vq_cluster=1024) +``` + +**Members** + +| Name | Kind | Source | +| --- | --- | --- | +| `pq_bits` | property | `python/cuvs/cuvs/preprocessing/quantize/pq/pq.pyx:87` | +| `pq_dim` | property | `python/cuvs/cuvs/preprocessing/quantize/pq/pq.pyx:91` | +| `vq_n_centers` | property | `python/cuvs/cuvs/preprocessing/quantize/pq/pq.pyx:95` | +| `kmeans_n_iters` | property | `python/cuvs/cuvs/preprocessing/quantize/pq/pq.pyx:99` | +| `pq_kmeans_type` | property | `python/cuvs/cuvs/preprocessing/quantize/pq/pq.pyx:103` | +| `max_train_points_per_pq_code` | property | `python/cuvs/cuvs/preprocessing/quantize/pq/pq.pyx:107` | +| `max_train_points_per_vq_cluster` | property | `python/cuvs/cuvs/preprocessing/quantize/pq/pq.pyx:111` | +| `use_vq` | property | `python/cuvs/cuvs/preprocessing/quantize/pq/pq.pyx:115` | +| `use_subspaces` | property | `python/cuvs/cuvs/preprocessing/quantize/pq/pq.pyx:119` | + +### pq_bits + +```python +def pq_bits(self) +``` + +_Source: `python/cuvs/cuvs/preprocessing/quantize/pq/pq.pyx:87`_ + +### pq_dim + +```python +def pq_dim(self) +``` + +_Source: `python/cuvs/cuvs/preprocessing/quantize/pq/pq.pyx:91`_ + +### vq_n_centers + +```python +def vq_n_centers(self) +``` + +_Source: `python/cuvs/cuvs/preprocessing/quantize/pq/pq.pyx:95`_ + +### kmeans_n_iters + +```python +def kmeans_n_iters(self) +``` + +_Source: `python/cuvs/cuvs/preprocessing/quantize/pq/pq.pyx:99`_ + +### pq_kmeans_type + +```python +def pq_kmeans_type(self) +``` + +_Source: `python/cuvs/cuvs/preprocessing/quantize/pq/pq.pyx:103`_ + +### max_train_points_per_pq_code + +```python +def max_train_points_per_pq_code(self) +``` + +_Source: `python/cuvs/cuvs/preprocessing/quantize/pq/pq.pyx:107`_ + +### max_train_points_per_vq_cluster + +```python +def max_train_points_per_vq_cluster(self) +``` + +_Source: `python/cuvs/cuvs/preprocessing/quantize/pq/pq.pyx:111`_ + +### use_vq + +```python +def use_vq(self) +``` + +_Source: `python/cuvs/cuvs/preprocessing/quantize/pq/pq.pyx:115`_ + +### use_subspaces + +```python +def use_subspaces(self) +``` + +_Source: `python/cuvs/cuvs/preprocessing/quantize/pq/pq.pyx:119`_ + +_Source: `python/cuvs/cuvs/preprocessing/quantize/pq/pq.pyx:25`_ + +## build + +`@auto_sync_resources` + +```python +def build(QuantizerParams params, dataset, resources=None) +``` + +Builds a Product Quantizer to be used later for quantizing +the dataset. + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `params` | `QuantizerParams object` | | +| `dataset` | `row major dataset on host or device memory. FP32` | | +| `resources` | `cuvs.common.Resources, optional` | | + +**Returns** + +| Name | Type | Description | +| --- | --- | --- | +| `quantizer` | `cuvs.preprocessing.quantize.pq.Quantizer` | | + +**Examples** + +```python +>>> import cupy as cp +>>> from cuvs.preprocessing.quantize import pq +>>> n_samples = 5000 +>>> n_features = 64 +>>> dataset = cp.random.random_sample((n_samples, n_features), +... dtype=cp.float32) +>>> params = pq.QuantizerParams(pq_bits=8, pq_dim=16) +>>> quantizer = pq.build(params, dataset) +>>> transformed, _ = pq.transform(quantizer, dataset) +``` + +_Source: `python/cuvs/cuvs/preprocessing/quantize/pq/pq.pyx:198`_ + +## transform + +`@auto_sync_resources` +`@auto_convert_output` + +```python +def transform(Quantizer quantizer, dataset, codes_output=None, vq_labels=None, resources=None) +``` + +Applies Product Quantization transform to given dataset + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `quantizer` | `trained Quantizer object` | | +| `dataset` | `row major dataset on host or device memory. FP32` | | +| `codes_output` | `optional preallocated output memory, on device memory` | | +| `vq_labels` | `optional preallocated output memory for VQ labels, on device memory` | | +| `resources` | `cuvs.common.Resources, optional` | | + +**Returns** + +| Name | Type | Description | +| --- | --- | --- | +| `codes_output` | `transformed dataset quantized into a uint8` | | +| `vq_labels` | `VQ labels when VQ is used, None otherwise` | | + +**Examples** + +```python +>>> import cupy as cp +>>> from cuvs.preprocessing.quantize import pq +>>> n_samples = 5000 +>>> n_features = 64 +>>> dataset = cp.random.random_sample((n_samples, n_features), +... dtype=cp.float32) +>>> params = pq.QuantizerParams(pq_bits=8, pq_dim=16) +>>> quantizer = pq.build(params, dataset) +>>> transformed, _ = pq.transform(quantizer, dataset) +``` + +_Source: `python/cuvs/cuvs/preprocessing/quantize/pq/pq.pyx:247`_ + +## inverse_transform + +`@auto_sync_resources` +`@auto_convert_output` + +```python +def inverse_transform(Quantizer quantizer, codes, output=None, vq_labels=None, resources=None) +``` + +Applies Product Quantization inverse transform to given codes + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `quantizer` | `trained Quantizer object` | | +| `codes` | `row major device codes to inverse transform. uint8` | | +| `output` | `optional preallocated output memory, on device memory` | | +| `vq_labels` | `optional VQ labels when VQ is used, on device memory` | | +| `resources` | `cuvs.common.Resources, optional` | | + +**Returns** + +| Name | Type | Description | +| --- | --- | --- | +| `output` | `Original dataset reconstructed from quantized codes` | | + +**Examples** + +```python +>>> import cupy as cp +>>> from cuvs.preprocessing.quantize import pq +>>> n_samples = 5000 +>>> n_features = 64 +>>> dataset = cp.random.random_sample((n_samples, n_features), +... dtype=cp.float32) +>>> params = pq.QuantizerParams(pq_bits=8, pq_dim=16, use_vq=True) +>>> quantizer = pq.build(params, dataset) +>>> transformed, vq_labels = pq.transform(quantizer, dataset) +>>> reconstructed = pq.inverse_transform(quantizer, transformed, vq_labels=vq_labels) +``` + +_Source: `python/cuvs/cuvs/preprocessing/quantize/pq/pq.pyx:314`_ diff --git a/fern/pages/python_api/python-api-preprocessing-quantize-scalar.md b/fern/pages/python_api/python-api-preprocessing-quantize-scalar.md new file mode 100644 index 0000000000..70d39a3a1d --- /dev/null +++ b/fern/pages/python_api/python-api-preprocessing-quantize-scalar.md @@ -0,0 +1,192 @@ +--- +slug: api-reference/python-api-preprocessing-quantize-scalar +--- + +# Scalar + +_Python module: `cuvs.preprocessing.quantize.scalar`_ + +## Quantizer + +```python +cdef class Quantizer +``` + +Defines and stores scalar for quantisation upon training + +The quantization is performed by a linear mapping of an interval in the +float data type to the full range of the quantized int type. + +**Members** + +| Name | Kind | Source | +| --- | --- | --- | +| `min` | property | `python/cuvs/cuvs/preprocessing/quantize/scalar/scalar.pyx:63` | +| `max` | property | `python/cuvs/cuvs/preprocessing/quantize/scalar/scalar.pyx:67` | + +### min + +```python +def min(self) +``` + +_Source: `python/cuvs/cuvs/preprocessing/quantize/scalar/scalar.pyx:63`_ + +### max + +```python +def max(self) +``` + +_Source: `python/cuvs/cuvs/preprocessing/quantize/scalar/scalar.pyx:67`_ + +_Source: `python/cuvs/cuvs/preprocessing/quantize/scalar/scalar.pyx:47`_ + +## QuantizerParams + +```python +cdef class QuantizerParams +``` + +Parameters for scalar quantization + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `quantile` | `float` | specifies how many outliers at top & bottom will be ignored needs to be within range of (0, 1] | + +**Constructor** + +```python +def __init__(self, *, quantile=None) +``` + +**Members** + +| Name | Kind | Source | +| --- | --- | --- | +| `quantile` | property | `python/cuvs/cuvs/preprocessing/quantize/scalar/scalar.pyx:43` | + +### quantile + +```python +def quantile(self) +``` + +_Source: `python/cuvs/cuvs/preprocessing/quantize/scalar/scalar.pyx:43`_ + +_Source: `python/cuvs/cuvs/preprocessing/quantize/scalar/scalar.pyx:19`_ + +## inverse_transform + +`@auto_sync_resources` +`@auto_convert_output` + +```python +def inverse_transform(Quantizer quantizer, dataset, output=None, resources=None) +``` + +Perform inverse quantization step on previously quantized dataset + +Note that depending on the chosen data types train dataset the conversion +is not lossless. + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `quantizer` | `trained Quantizer object` | | +| `dataset` | `row major host or device dataset to transform` | | +| `output` | `optional preallocated output memory, on host or device` | | +| `resources` | `cuvs.common.Resources, optional` | | + +**Returns** + +| Name | Type | Description | +| --- | --- | --- | +| `output` | `transformed dataset with scalar quantization reversed` | | + +_Source: `python/cuvs/cuvs/preprocessing/quantize/scalar/scalar.pyx:186`_ + +## train + +`@auto_sync_resources` + +```python +def train(QuantizerParams params, dataset, resources=None) +``` + +Initializes a scalar quantizer to be used later for quantizing the dataset. + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `params` | `QuantizerParams object` | | +| `dataset` | `row major host or device dataset` | | +| `resources` | `cuvs.common.Resources, optional` | | + +**Returns** + +| Name | Type | Description | +| --- | --- | --- | +| `quantizer` | `cuvs.preprocessing.quantize.scalar.Quantizer` | | + +**Examples** + +```python +>>> import cupy as cp +>>> from cuvs.preprocessing.quantize import scalar +>>> n_samples = 50000 +>>> n_features = 50 +>>> dataset = cp.random.random_sample((n_samples, n_features), +... dtype=cp.float32) +>>> params = scalar.QuantizerParams(quantile=0.99) +>>> quantizer = scalar.train(params, dataset) +>>> transformed = scalar.transform(quantizer, dataset) +``` + +_Source: `python/cuvs/cuvs/preprocessing/quantize/scalar/scalar.pyx:75`_ + +## transform + +`@auto_sync_resources` +`@auto_convert_output` + +```python +def transform(Quantizer quantizer, dataset, output=None, resources=None) +``` + +Applies quantization transform to given dataset + +**Parameters** + +| Name | Type | Description | +| --- | --- | --- | +| `quantizer` | `trained Quantizer object` | | +| `dataset` | `row major host or device dataset to transform` | | +| `output` | `optional preallocated output memory, on host or device memory` | | +| `resources` | `cuvs.common.Resources, optional` | | + +**Returns** + +| Name | Type | Description | +| --- | --- | --- | +| `output` | `transformed dataset quantized into a int8` | | + +**Examples** + +```python +>>> import cupy as cp +>>> from cuvs.preprocessing.quantize import scalar +>>> n_samples = 50000 +>>> n_features = 50 +>>> dataset = cp.random.random_sample((n_samples, n_features), +... dtype=cp.float32) +>>> params = scalar.QuantizerParams(quantile=0.99) +>>> quantizer = scalar.train(params, dataset) +>>> transformed = scalar.transform(quantizer, dataset) +``` + +_Source: `python/cuvs/cuvs/preprocessing/quantize/scalar/scalar.pyx:125`_ diff --git a/fern/pages/rust_api/index.md b/fern/pages/rust_api/index.md new file mode 100644 index 0000000000..da1dd32d44 --- /dev/null +++ b/fern/pages/rust_api/index.md @@ -0,0 +1,40 @@ +# Rust API Documentation + +These pages are generated from the Rust crate sources under `rust/cuvs/src`. + +## Cluster + +- [`cuvs::cluster`](/api-reference/rust-api-cuvs-cluster) +- [`cuvs::cluster::kmeans`](/api-reference/rust-api-cuvs-cluster-kmeans) +- [`cuvs::cluster::kmeans::params`](/api-reference/rust-api-cuvs-cluster-kmeans-params) + +## Core + +- [`cuvs`](/api-reference/rust-api-cuvs) +- [`cuvs::dlpack`](/api-reference/rust-api-cuvs-dlpack) +- [`cuvs::error`](/api-reference/rust-api-cuvs-error) +- [`cuvs::resources`](/api-reference/rust-api-cuvs-resources) + +## Distance + +- [`cuvs::distance`](/api-reference/rust-api-cuvs-distance) +- [`cuvs::distance_type`](/api-reference/rust-api-cuvs-distance-type) + +## Nearest Neighbors + +- [`cuvs::brute_force`](/api-reference/rust-api-cuvs-brute-force) +- [`cuvs::cagra`](/api-reference/rust-api-cuvs-cagra) +- [`cuvs::cagra::index`](/api-reference/rust-api-cuvs-cagra-index) +- [`cuvs::cagra::index_params`](/api-reference/rust-api-cuvs-cagra-index-params) +- [`cuvs::cagra::search_params`](/api-reference/rust-api-cuvs-cagra-search-params) +- [`cuvs::ivf_flat`](/api-reference/rust-api-cuvs-ivf-flat) +- [`cuvs::ivf_flat::index`](/api-reference/rust-api-cuvs-ivf-flat-index) +- [`cuvs::ivf_flat::index_params`](/api-reference/rust-api-cuvs-ivf-flat-index-params) +- [`cuvs::ivf_flat::search_params`](/api-reference/rust-api-cuvs-ivf-flat-search-params) +- [`cuvs::ivf_pq`](/api-reference/rust-api-cuvs-ivf-pq) +- [`cuvs::ivf_pq::index`](/api-reference/rust-api-cuvs-ivf-pq-index) +- [`cuvs::ivf_pq::index_params`](/api-reference/rust-api-cuvs-ivf-pq-index-params) +- [`cuvs::ivf_pq::search_params`](/api-reference/rust-api-cuvs-ivf-pq-search-params) +- [`cuvs::vamana`](/api-reference/rust-api-cuvs-vamana) +- [`cuvs::vamana::index`](/api-reference/rust-api-cuvs-vamana-index) +- [`cuvs::vamana::index_params`](/api-reference/rust-api-cuvs-vamana-index-params) diff --git a/fern/pages/rust_api/rust-api-cuvs-brute-force.md b/fern/pages/rust_api/rust-api-cuvs-brute-force.md new file mode 100644 index 0000000000..47dd8a5f5c --- /dev/null +++ b/fern/pages/rust_api/rust-api-cuvs-brute-force.md @@ -0,0 +1,85 @@ +--- +slug: api-reference/rust-api-cuvs-brute-force +--- + +# Brute Force Module + +_Rust module: `cuvs::brute_force`_ + +_Source: `rust/cuvs/src/brute_force.rs`_ + +Brute Force KNN + +## Index + +```rust +#[derive(Debug)] +pub struct Index(ffi::cuvsBruteForceIndex_t); +``` + +Brute Force KNN Index + +**Methods** + +| Name | Source | +| --- | --- | +| `build` | `rust/cuvs/src/brute_force.rs:27` | +| `new` | `rust/cuvs/src/brute_force.rs:48` | +| `search` | `rust/cuvs/src/brute_force.rs:64` | + +### build + +```rust +pub fn build>( +res: &Resources, +metric: DistanceType, +metric_arg: Option, +dataset: T, +) -> Result { ... } +``` + +Builds a new Brute Force KNN Index from the dataset for efficient search. + +#### Arguments + +* `res` - Resources to use +* `metric` - DistanceType to use for building the index +* `metric_arg` - Optional value of `p` for Minkowski distances +* `dataset` - A row-major matrix on either the host or device to index + +_Source: `rust/cuvs/src/brute_force.rs:27`_ + +### new + +```rust +pub fn new() -> Result { ... } +``` + +Creates a new empty index + +_Source: `rust/cuvs/src/brute_force.rs:48`_ + +### search + +```rust +pub fn search( +&self, +res: &Resources, +queries: &ManagedTensor, +neighbors: &ManagedTensor, +distances: &ManagedTensor, +) -> Result<()> { ... } +``` + +Perform a Nearest Neighbors search on the Index + +#### Arguments + +* `res` - Resources to use +* `queries` - A matrix in device memory to query for +* `neighbors` - Matrix in device memory that receives the indices of the nearest neighbors +* `distances` - Matrix in device memory that receives the distances of the nearest neighbors + +_Source: `rust/cuvs/src/brute_force.rs:64`_ + +_Source: `rust/cuvs/src/brute_force.rs:16`_ diff --git a/fern/pages/rust_api/rust-api-cuvs-cagra-index-params.md b/fern/pages/rust_api/rust-api-cuvs-cagra-index-params.md new file mode 100644 index 0000000000..c830345193 --- /dev/null +++ b/fern/pages/rust_api/rust-api-cuvs-cagra-index-params.md @@ -0,0 +1,197 @@ +--- +slug: api-reference/rust-api-cuvs-cagra-index-params +--- + +# Cagra Index Params Module + +_Rust module: `cuvs::cagra::index_params`_ + +_Source: `rust/cuvs/src/cagra/index_params.rs`_ + +## BuildAlgo + +```rust +pub type BuildAlgo = ffi::cuvsCagraGraphBuildAlgo; +``` + +_Source: `rust/cuvs/src/cagra/index_params.rs:10`_ + +## CompressionParams + +```rust +pub struct CompressionParams(pub ffi::cuvsCagraCompressionParams_t); +``` + +Supplemental parameters to build CAGRA Index + +**Methods** + +| Name | Source | +| --- | --- | +| `new` | `rust/cuvs/src/cagra/index_params.rs:17` | +| `set_pq_bits` | `rust/cuvs/src/cagra/index_params.rs:26` | +| `set_pq_dim` | `rust/cuvs/src/cagra/index_params.rs:35` | +| `set_vq_n_centers` | `rust/cuvs/src/cagra/index_params.rs:44` | +| `set_kmeans_n_iters` | `rust/cuvs/src/cagra/index_params.rs:53` | +| `set_vq_kmeans_trainset_fraction` | `rust/cuvs/src/cagra/index_params.rs:62` | +| `set_pq_kmeans_trainset_fraction` | `rust/cuvs/src/cagra/index_params.rs:74` | + +### new + +```rust +pub fn new() -> Result { ... } +``` + +Returns a new CompressionParams + +_Source: `rust/cuvs/src/cagra/index_params.rs:17`_ + +### set_pq_bits + +```rust +pub fn set_pq_bits(self, pq_bits: u32) -> CompressionParams { ... } +``` + +The bit length of the vector element after compression by PQ. + +_Source: `rust/cuvs/src/cagra/index_params.rs:26`_ + +### set_pq_dim + +```rust +pub fn set_pq_dim(self, pq_dim: u32) -> CompressionParams { ... } +``` + +The dimensionality of the vector after compression by PQ. When zero, +an optimal value is selected using a heuristic. + +_Source: `rust/cuvs/src/cagra/index_params.rs:35`_ + +### set_vq_n_centers + +```rust +pub fn set_vq_n_centers(self, vq_n_centers: u32) -> CompressionParams { ... } +``` + +Vector Quantization (VQ) codebook size - number of "coarse cluster +centers". When zero, an optimal value is selected using a heuristic. + +_Source: `rust/cuvs/src/cagra/index_params.rs:44`_ + +### set_kmeans_n_iters + +```rust +pub fn set_kmeans_n_iters(self, kmeans_n_iters: u32) -> CompressionParams { ... } +``` + +The number of iterations searching for kmeans centers (both VQ & PQ +phases). + +_Source: `rust/cuvs/src/cagra/index_params.rs:53`_ + +### set_vq_kmeans_trainset_fraction + +```rust +pub fn set_vq_kmeans_trainset_fraction( +self, +vq_kmeans_trainset_fraction: f64, +) -> CompressionParams { ... } +``` + +The fraction of data to use during iterative kmeans building (VQ +phase). When zero, an optimal value is selected using a heuristic. + +_Source: `rust/cuvs/src/cagra/index_params.rs:62`_ + +### set_pq_kmeans_trainset_fraction + +```rust +pub fn set_pq_kmeans_trainset_fraction( +self, +pq_kmeans_trainset_fraction: f64, +) -> CompressionParams { ... } +``` + +The fraction of data to use during iterative kmeans building (PQ +phase). When zero, an optimal value is selected using a heuristic. + +_Source: `rust/cuvs/src/cagra/index_params.rs:74`_ + +_Source: `rust/cuvs/src/cagra/index_params.rs:13`_ + +## IndexParams + +```rust +pub struct IndexParams(pub ffi::cuvsCagraIndexParams_t, Option); +``` + +**Methods** + +| Name | Source | +| --- | --- | +| `new` | `rust/cuvs/src/cagra/index_params.rs:89` | +| `set_intermediate_graph_degree` | `rust/cuvs/src/cagra/index_params.rs:98` | +| `set_graph_degree` | `rust/cuvs/src/cagra/index_params.rs:106` | +| `set_build_algo` | `rust/cuvs/src/cagra/index_params.rs:114` | +| `set_nn_descent_niter` | `rust/cuvs/src/cagra/index_params.rs:122` | +| `set_compression` | `rust/cuvs/src/cagra/index_params.rs:129` | + +### new + +```rust +pub fn new() -> Result { ... } +``` + +Returns a new IndexParams + +_Source: `rust/cuvs/src/cagra/index_params.rs:89`_ + +### set_intermediate_graph_degree + +```rust +pub fn set_intermediate_graph_degree(self, intermediate_graph_degree: usize) -> IndexParams { ... } +``` + +Degree of input graph for pruning + +_Source: `rust/cuvs/src/cagra/index_params.rs:98`_ + +### set_graph_degree + +```rust +pub fn set_graph_degree(self, graph_degree: usize) -> IndexParams { ... } +``` + +Degree of output graph + +_Source: `rust/cuvs/src/cagra/index_params.rs:106`_ + +### set_build_algo + +```rust +pub fn set_build_algo(self, build_algo: BuildAlgo) -> IndexParams { ... } +``` + +ANN algorithm to build knn graph + +_Source: `rust/cuvs/src/cagra/index_params.rs:114`_ + +### set_nn_descent_niter + +```rust +pub fn set_nn_descent_niter(self, nn_descent_niter: usize) -> IndexParams { ... } +``` + +Number of iterations to run if building with NN_DESCENT + +_Source: `rust/cuvs/src/cagra/index_params.rs:122`_ + +### set_compression + +```rust +pub fn set_compression(mut self, compression: CompressionParams) -> IndexParams { ... } +``` + +_Source: `rust/cuvs/src/cagra/index_params.rs:129`_ + +_Source: `rust/cuvs/src/cagra/index_params.rs:85`_ diff --git a/fern/pages/rust_api/rust-api-cuvs-cagra-index.md b/fern/pages/rust_api/rust-api-cuvs-cagra-index.md new file mode 100644 index 0000000000..2d2182cb89 --- /dev/null +++ b/fern/pages/rust_api/rust-api-cuvs-cagra-index.md @@ -0,0 +1,179 @@ +--- +slug: api-reference/rust-api-cuvs-cagra-index +--- + +# Cagra Index Module + +_Rust module: `cuvs::cagra::index`_ + +_Source: `rust/cuvs/src/cagra/index.rs`_ + +## Index + +```rust +#[derive(Debug)] +pub struct Index(ffi::cuvsCagraIndex_t); +``` + +CAGRA ANN Index + +**Methods** + +| Name | Source | +| --- | --- | +| `build` | `rust/cuvs/src/cagra/index.rs:38` | +| `new` | `rust/cuvs/src/cagra/index.rs:57` | +| `search` | `rust/cuvs/src/cagra/index.rs:74` | +| `search_with_filter` | `rust/cuvs/src/cagra/index.rs:115` | +| `serialize` | `rust/cuvs/src/cagra/index.rs:151` | +| `serialize_to_hnswlib` | `rust/cuvs/src/cagra/index.rs:179` | +| `deserialize` | `rust/cuvs/src/cagra/index.rs:198` | + +### build + +```rust +pub fn build>( +res: &Resources, +params: &IndexParams, +dataset: T, +) -> Result { ... } +``` + +Builds a new Index from the dataset for efficient search. + +#### Arguments + +* `res` - Resources to use +* `params` - Parameters for building the index +* `dataset` - A row-major matrix on either the host or device to index + +_Source: `rust/cuvs/src/cagra/index.rs:38`_ + +### new + +```rust +pub fn new() -> Result { ... } +``` + +Creates a new empty index + +_Source: `rust/cuvs/src/cagra/index.rs:57`_ + +### search + +```rust +pub fn search( +&self, +res: &Resources, +params: &SearchParams, +queries: &ManagedTensor, +neighbors: &ManagedTensor, +distances: &ManagedTensor, +) -> Result<()> { ... } +``` + +Perform a Approximate Nearest Neighbors search on the Index + +#### Arguments + +* `res` - Resources to use +* `params` - Parameters to use in searching the index +* `queries` - A matrix in device memory to query for +* `neighbors` - Matrix in device memory that receives the indices of the nearest neighbors +* `distances` - Matrix in device memory that receives the distances of the nearest neighbors + +_Source: `rust/cuvs/src/cagra/index.rs:74`_ + +### search_with_filter + +```rust +pub fn search_with_filter( +&self, +res: &Resources, +params: &SearchParams, +queries: &ManagedTensor, +neighbors: &ManagedTensor, +distances: &ManagedTensor, +bitset: &ManagedTensor, +) -> Result<()> { ... } +``` + +Perform a filtered Approximate Nearest Neighbors search on the Index + +Like [`search`](Self::search), but accepts a bitset filter to exclude +vectors during graph traversal. Filtered vectors are never visited, +giving better recall than post-filtering. + +#### Arguments + +* `res` - Resources to use +* `params` - Parameters to use in searching the index +* `queries` - A matrix in device memory to query for +* `neighbors` - Matrix in device memory that receives the indices of the nearest neighbors +* `distances` - Matrix in device memory that receives the distances of the nearest neighbors +* `bitset` - A 1-D `uint32` device tensor with `ceil(n_rows / 32)` elements. +Each bit corresponds to a dataset row: bit 1 = include, bit 0 = exclude. + +_Source: `rust/cuvs/src/cagra/index.rs:115`_ + +### serialize + +```rust +pub fn serialize>( +&self, +res: &Resources, +filename: P, +include_dataset: bool, +) -> Result<()> { ... } +``` + +Save the CAGRA index to file. + +Experimental, both the API and the serialization format are subject to change. + +#### Arguments + +* `res` - Resources to use +* `filename` - The file path for saving the index +* `include_dataset` - Whether to write out the dataset to the file + +_Source: `rust/cuvs/src/cagra/index.rs:151`_ + +### serialize_to_hnswlib + +```rust +pub fn serialize_to_hnswlib>(&self, res: &Resources, filename: P) -> Result<()> { ... } +``` + +Save the CAGRA index to file in hnswlib format. + +NOTE: The saved index can only be read by the hnswlib wrapper in cuVS, +as the serialization format is not compatible with the original hnswlib. + +Experimental, both the API and the serialization format are subject to change. + +#### Arguments + +* `res` - Resources to use +* `filename` - The file path for saving the index + +_Source: `rust/cuvs/src/cagra/index.rs:179`_ + +### deserialize + +```rust +pub fn deserialize>(res: &Resources, filename: P) -> Result { ... } +``` + +Load a CAGRA index from file. + +Experimental, both the API and the serialization format are subject to change. + +#### Arguments + +* `res` - Resources to use +* `filename` - The path of the file that stores the index + +_Source: `rust/cuvs/src/cagra/index.rs:198`_ + +_Source: `rust/cuvs/src/cagra/index.rs:17`_ diff --git a/fern/pages/rust_api/rust-api-cuvs-cagra-search-params.md b/fern/pages/rust_api/rust-api-cuvs-cagra-search-params.md new file mode 100644 index 0000000000..5cb67003c2 --- /dev/null +++ b/fern/pages/rust_api/rust-api-cuvs-cagra-search-params.md @@ -0,0 +1,185 @@ +--- +slug: api-reference/rust-api-cuvs-cagra-search-params +--- + +# Cagra Search Params Module + +_Rust module: `cuvs::cagra::search_params`_ + +_Source: `rust/cuvs/src/cagra/search_params.rs`_ + +## SearchAlgo + +```rust +pub type SearchAlgo = ffi::cuvsCagraSearchAlgo; +``` + +_Source: `rust/cuvs/src/cagra/search_params.rs:10`_ + +## HashMode + +```rust +pub type HashMode = ffi::cuvsCagraHashMode; +``` + +_Source: `rust/cuvs/src/cagra/search_params.rs:11`_ + +## SearchParams + +```rust +pub struct SearchParams(pub ffi::cuvsCagraSearchParams_t); +``` + +Supplemental parameters to search CAGRA index + +**Methods** + +| Name | Source | +| --- | --- | +| `new` | `rust/cuvs/src/cagra/search_params.rs:18` | +| `set_max_queries` | `rust/cuvs/src/cagra/search_params.rs:27` | +| `set_itopk_size` | `rust/cuvs/src/cagra/search_params.rs:37` | +| `set_max_iterations` | `rust/cuvs/src/cagra/search_params.rs:45` | +| `set_algo` | `rust/cuvs/src/cagra/search_params.rs:53` | +| `set_team_size` | `rust/cuvs/src/cagra/search_params.rs:61` | +| `set_min_iterations` | `rust/cuvs/src/cagra/search_params.rs:69` | +| `set_thread_block_size` | `rust/cuvs/src/cagra/search_params.rs:77` | +| `set_hashmap_mode` | `rust/cuvs/src/cagra/search_params.rs:85` | +| `set_hashmap_min_bitlen` | `rust/cuvs/src/cagra/search_params.rs:93` | +| `set_hashmap_max_fill_rate` | `rust/cuvs/src/cagra/search_params.rs:101` | +| `set_num_random_samplings` | `rust/cuvs/src/cagra/search_params.rs:109` | +| `set_rand_xor_mask` | `rust/cuvs/src/cagra/search_params.rs:117` | + +### new + +```rust +pub fn new() -> Result { ... } +``` + +Returns a new SearchParams object + +_Source: `rust/cuvs/src/cagra/search_params.rs:18`_ + +### set_max_queries + +```rust +pub fn set_max_queries(self, max_queries: usize) -> SearchParams { ... } +``` + +Maximum number of queries to search at the same time (batch size). Auto select when 0 + +_Source: `rust/cuvs/src/cagra/search_params.rs:27`_ + +### set_itopk_size + +```rust +pub fn set_itopk_size(self, itopk_size: usize) -> SearchParams { ... } +``` + +Number of intermediate search results retained during the search. +This is the main knob to adjust trade off between accuracy and search speed. +Higher values improve the search accuracy + +_Source: `rust/cuvs/src/cagra/search_params.rs:37`_ + +### set_max_iterations + +```rust +pub fn set_max_iterations(self, max_iterations: usize) -> SearchParams { ... } +``` + +Upper limit of search iterations. Auto select when 0. + +_Source: `rust/cuvs/src/cagra/search_params.rs:45`_ + +### set_algo + +```rust +pub fn set_algo(self, algo: SearchAlgo) -> SearchParams { ... } +``` + +Which search implementation to use. + +_Source: `rust/cuvs/src/cagra/search_params.rs:53`_ + +### set_team_size + +```rust +pub fn set_team_size(self, team_size: usize) -> SearchParams { ... } +``` + +Number of threads used to calculate a single distance. 4, 8, 16, or 32. + +_Source: `rust/cuvs/src/cagra/search_params.rs:61`_ + +### set_min_iterations + +```rust +pub fn set_min_iterations(self, min_iterations: usize) -> SearchParams { ... } +``` + +Lower limit of search iterations. + +_Source: `rust/cuvs/src/cagra/search_params.rs:69`_ + +### set_thread_block_size + +```rust +pub fn set_thread_block_size(self, thread_block_size: usize) -> SearchParams { ... } +``` + +Thread block size. 0, 64, 128, 256, 512, 1024. Auto selection when 0. + +_Source: `rust/cuvs/src/cagra/search_params.rs:77`_ + +### set_hashmap_mode + +```rust +pub fn set_hashmap_mode(self, hashmap_mode: HashMode) -> SearchParams { ... } +``` + +Hashmap type. Auto selection when AUTO. + +_Source: `rust/cuvs/src/cagra/search_params.rs:85`_ + +### set_hashmap_min_bitlen + +```rust +pub fn set_hashmap_min_bitlen(self, hashmap_min_bitlen: usize) -> SearchParams { ... } +``` + +Lower limit of hashmap bit length. More than 8. + +_Source: `rust/cuvs/src/cagra/search_params.rs:93`_ + +### set_hashmap_max_fill_rate + +```rust +pub fn set_hashmap_max_fill_rate(self, hashmap_max_fill_rate: f32) -> SearchParams { ... } +``` + +Upper limit of hashmap fill rate. More than 0.1, less than 0.9. + +_Source: `rust/cuvs/src/cagra/search_params.rs:101`_ + +### set_num_random_samplings + +```rust +pub fn set_num_random_samplings(self, num_random_samplings: u32) -> SearchParams { ... } +``` + +Number of iterations of initial random seed node selection. 1 or more. + +_Source: `rust/cuvs/src/cagra/search_params.rs:109`_ + +### set_rand_xor_mask + +```rust +pub fn set_rand_xor_mask(self, rand_xor_mask: u64) -> SearchParams { ... } +``` + +Bit mask used for initial random seed node selection. + +_Source: `rust/cuvs/src/cagra/search_params.rs:117`_ + +_Source: `rust/cuvs/src/cagra/search_params.rs:14`_ diff --git a/fern/pages/rust_api/rust-api-cuvs-cagra.md b/fern/pages/rust_api/rust-api-cuvs-cagra.md new file mode 100644 index 0000000000..2b70758c3b --- /dev/null +++ b/fern/pages/rust_api/rust-api-cuvs-cagra.md @@ -0,0 +1,119 @@ +--- +slug: api-reference/rust-api-cuvs-cagra +--- + +# Cagra Module + +_Rust module: `cuvs::cagra`_ + +_Source: `rust/cuvs/src/cagra/mod.rs`_ + +CAGRA is a graph-based nearest neighbors implementation with state-of-the art +query performance for both small- and large-batch sized search. + +Example: +``` + +use cuvs::cagra::{Index, IndexParams, SearchParams}; +use cuvs::{ManagedTensor, Resources, Result}; + +use ndarray::s; +use ndarray_rand::rand_distr::Uniform; +use ndarray_rand::RandomExt; + +fn cagra_example() -> Result<()> { +let res = Resources::new()?; + +// Create a new random dataset to index +let n_datapoints = 65536; +let n_features = 512; +let dataset = +ndarray::Array::::random((n_datapoints, n_features), Uniform::new(0., 1.0)); + +// build the cagra index +let build_params = IndexParams::new()?; +let index = Index::build(&res, &build_params, &dataset)?; +println!( +"Indexed {}x{} datapoints into cagra index", +n_datapoints, n_features +); + +// use the first 4 points from the dataset as queries : will test that we get them back +// as their own nearest neighbor +let n_queries = 4; +let queries = dataset.slice(s![0..n_queries, ..]); + +let k = 10; + +// CAGRA search API requires queries and outputs to be on device memory +// copy query data over, and allocate new device memory for the distances/ neighbors +// outputs +let queries = ManagedTensor::from(&queries).to_device(&res)?; +let mut neighbors_host = ndarray::Array::::zeros((n_queries, k)); +let neighbors = ManagedTensor::from(&neighbors_host).to_device(&res)?; + +let mut distances_host = ndarray::Array::::zeros((n_queries, k)); +let distances = ManagedTensor::from(&distances_host).to_device(&res)?; + +let search_params = SearchParams::new()?; + +index.search(&res, &search_params, &queries, &neighbors, &distances)?; + +// Copy back to host memory +distances.to_host(&res, &mut distances_host)?; +neighbors.to_host(&res, &mut neighbors_host)?; + +// nearest neighbors should be themselves, since queries are from the +// dataset +println!("Neighbors {:?}", neighbors_host); +println!("Distances {:?}", distances_host); +Ok(()) +} +``` + +Serialization example: +```no_run +use cuvs::cagra::{Index, IndexParams}; +use cuvs::{Resources, Result}; + +fn serialize_example() -> Result<()> { +let res = Resources::new()?; + +// Build an index (using some dataset) +let build_params = IndexParams::new()?; +// let index = Index::build(&res, &build_params, &dataset)?; + +// Save the index to disk (including the dataset) +// index.serialize(&res, "/path/to/index.bin", true)?; + +// Later, load the index from disk +let loaded_index = Index::deserialize(&res, "/path/to/index.bin")?; + +// The loaded index can be used for search just like the original +Ok(()) +} +``` + +## index::Index + +```rust +pub use index::Index; +``` + +_Source: `rust/cuvs/src/cagra/mod.rs:96`_ + +## index_params:: \{ ... \} + +```rust +pub use index_params:: { ... } +``` + +_Source: `rust/cuvs/src/cagra/mod.rs:97`_ + +## search_params:: \{ ... \} + +```rust +pub use search_params:: { ... } +``` + +_Source: `rust/cuvs/src/cagra/mod.rs:98`_ diff --git a/fern/pages/rust_api/rust-api-cuvs-cluster-kmeans-params.md b/fern/pages/rust_api/rust-api-cuvs-cluster-kmeans-params.md new file mode 100644 index 0000000000..b8d0175af3 --- /dev/null +++ b/fern/pages/rust_api/rust-api-cuvs-cluster-kmeans-params.md @@ -0,0 +1,141 @@ +--- +slug: api-reference/rust-api-cuvs-cluster-kmeans-params +--- + +# Cluster Kmeans Params Module + +_Rust module: `cuvs::cluster::kmeans::params`_ + +_Source: `rust/cuvs/src/cluster/kmeans/params.rs`_ + +## Params + +```rust +pub struct Params(pub ffi::cuvsKMeansParams_t); +``` + +**Methods** + +| Name | Source | +| --- | --- | +| `new` | `rust/cuvs/src/cluster/kmeans/params.rs:15` | +| `set_metric` | `rust/cuvs/src/cluster/kmeans/params.rs:24` | +| `set_n_clusters` | `rust/cuvs/src/cluster/kmeans/params.rs:32` | +| `set_max_iter` | `rust/cuvs/src/cluster/kmeans/params.rs:40` | +| `set_tol` | `rust/cuvs/src/cluster/kmeans/params.rs:48` | +| `set_n_init` | `rust/cuvs/src/cluster/kmeans/params.rs:56` | +| `set_oversampling_factor` | `rust/cuvs/src/cluster/kmeans/params.rs:64` | +| `set_batch_samples` | `rust/cuvs/src/cluster/kmeans/params.rs:77` | +| `set_batch_centroids` | `rust/cuvs/src/cluster/kmeans/params.rs:84` | +| `set_hierarchical` | `rust/cuvs/src/cluster/kmeans/params.rs:92` | +| `set_hierarchical_n_iters` | `rust/cuvs/src/cluster/kmeans/params.rs:100` | + +### new + +```rust +pub fn new() -> Result { ... } +``` + +Returns a new Params + +_Source: `rust/cuvs/src/cluster/kmeans/params.rs:15`_ + +### set_metric + +```rust +pub fn set_metric(self, metric: DistanceType) -> Params { ... } +``` + +DistanceType to use for fitting kmeans + +_Source: `rust/cuvs/src/cluster/kmeans/params.rs:24`_ + +### set_n_clusters + +```rust +pub fn set_n_clusters(self, n_clusters: i32) -> Params { ... } +``` + +The number of clusters to form as well as the number of centroids to generate (default:8). + +_Source: `rust/cuvs/src/cluster/kmeans/params.rs:32`_ + +### set_max_iter + +```rust +pub fn set_max_iter(self, max_iter: i32) -> Params { ... } +``` + +Maximum number of iterations of the k-means algorithm for a single run. + +_Source: `rust/cuvs/src/cluster/kmeans/params.rs:40`_ + +### set_tol + +```rust +pub fn set_tol(self, tol: f64) -> Params { ... } +``` + +Relative tolerance with regards to inertia to declare convergence. + +_Source: `rust/cuvs/src/cluster/kmeans/params.rs:48`_ + +### set_n_init + +```rust +pub fn set_n_init(self, n_init: i32) -> Params { ... } +``` + +Number of instance k-means algorithm will be run with different seeds. + +_Source: `rust/cuvs/src/cluster/kmeans/params.rs:56`_ + +### set_oversampling_factor + +```rust +pub fn set_oversampling_factor(self, oversampling_factor: f64) -> Params { ... } +``` + +Oversampling factor for use in the k-means\|\| algorithm + +_Source: `rust/cuvs/src/cluster/kmeans/params.rs:64`_ + +### set_batch_samples + +```rust +pub fn set_batch_samples(self, batch_samples: i32) -> Params { ... } +``` + +_Source: `rust/cuvs/src/cluster/kmeans/params.rs:77`_ + +### set_batch_centroids + +```rust +pub fn set_batch_centroids(self, batch_centroids: i32) -> Params { ... } +``` + +if 0 then batch_centroids = n_clusters + +_Source: `rust/cuvs/src/cluster/kmeans/params.rs:84`_ + +### set_hierarchical + +```rust +pub fn set_hierarchical(self, hierarchical: bool) -> Params { ... } +``` + +Whether to use hierarchical (balanced) kmeans or not + +_Source: `rust/cuvs/src/cluster/kmeans/params.rs:92`_ + +### set_hierarchical_n_iters + +```rust +pub fn set_hierarchical_n_iters(self, hierarchical_n_iters: i32) -> Params { ... } +``` + +For hierarchical k-means , defines the number of training iterations + +_Source: `rust/cuvs/src/cluster/kmeans/params.rs:100`_ + +_Source: `rust/cuvs/src/cluster/kmeans/params.rs:11`_ diff --git a/fern/pages/rust_api/rust-api-cuvs-cluster-kmeans.md b/fern/pages/rust_api/rust-api-cuvs-cluster-kmeans.md new file mode 100644 index 0000000000..4a3b75fa15 --- /dev/null +++ b/fern/pages/rust_api/rust-api-cuvs-cluster-kmeans.md @@ -0,0 +1,117 @@ +--- +slug: api-reference/rust-api-cuvs-cluster-kmeans +--- + +# Cluster Kmeans Module + +_Rust module: `cuvs::cluster::kmeans`_ + +_Source: `rust/cuvs/src/cluster/kmeans/mod.rs`_ + +Kmeans clustering API's + +Example: +``` + +use cuvs::cluster::kmeans; +use cuvs::{ManagedTensor, Resources, Result}; + +use ndarray_rand::rand_distr::Uniform; +use ndarray_rand::RandomExt; + +fn kmeans_example() -> Result<()> { +let res = Resources::new()?; + +// Create a new random dataset to index +let n_datapoints = 65536; +let n_features = 512; +let n_clusters = 8; +let dataset = +ndarray::Array::::random((n_datapoints, n_features), Uniform::new(0., 1.0)); +let dataset = ManagedTensor::from(&dataset).to_device(&res)?; + +let centroids_host = ndarray::Array::::zeros((n_clusters, n_features)); +let mut centroids = ManagedTensor::from(¢roids_host).to_device(&res)?; + +// find the centroids with the kmeans index +let kmeans_params = kmeans::Params::new()?.set_n_clusters(n_clusters as i32); +let (inertia, n_iter) = kmeans::fit(&res, &kmeans_params, &dataset, &None, &mut centroids)?; +Ok(()) +} +``` + +## params::Params + +```rust +pub use params::Params; +``` + +_Source: `rust/cuvs/src/cluster/kmeans/mod.rs:40`_ + +## fit + +```rust +pub fn fit( +res: &Resources, +params: &Params, +x: &ManagedTensor, +sample_weight: &Option, +centroids: &mut ManagedTensor, +) -> Result<(f64, i32)> { ... } +``` + +Find clusters with the k-means algorithm + +#### Arguments + +* `res` - Resources to use +* `params` - Parameters to use to fit KMeans model +* `x` - A matrix in device memory - shape (m, k) +* `sample_weight` - Optional device matrix shape (n_clusters, 1) +* `centroids` - Output device matrix, that has the centroids for each cluster +shape (n_clusters, k) + +_Source: `rust/cuvs/src/cluster/kmeans/mod.rs:56`_ + +## predict + +```rust +pub fn predict( +res: &Resources, +params: &Params, +x: &ManagedTensor, +sample_weight: &Option, +centroids: &ManagedTensor, +labels: &mut ManagedTensor, +normalize_weight: bool, +) -> Result { ... } +``` + +Predict clusters with the k-means algorithm + +#### Arguments + +* `res` - Resources to use +* `params` - Parameters to use to fit KMeans model +* `x` - Input matrix in device memory - shape (m, k) +* `sample_weight` - Optional device matrix shape (n_clusters, 1) +* `centroids` - Centroids calculated by fit in device memory, shape (n_clusters, k) +* `labels` - preallocated CUDA array interface matrix shape (m, 1) to hold the output labels +* `normalize_weight` - whether or not to normalize the weights + +_Source: `rust/cuvs/src/cluster/kmeans/mod.rs:95`_ + +## cluster_cost + +```rust +pub fn cluster_cost(res: &Resources, x: &ManagedTensor, centroids: &ManagedTensor) -> Result { ... } +``` + +Compute cluster cost given an input matrix and existing centroids +#### Arguments + +* `res` - Resources to use +* `x` - Input matrix in device memory - shape (m, k) +* `centroids` - Centroids calculated by fit in device memory, shape (n_clusters, k) + +_Source: `rust/cuvs/src/cluster/kmeans/mod.rs:131`_ diff --git a/fern/pages/rust_api/rust-api-cuvs-cluster.md b/fern/pages/rust_api/rust-api-cuvs-cluster.md new file mode 100644 index 0000000000..2a7f536ecd --- /dev/null +++ b/fern/pages/rust_api/rust-api-cuvs-cluster.md @@ -0,0 +1,17 @@ +--- +slug: api-reference/rust-api-cuvs-cluster +--- + +# Cluster Module + +_Rust module: `cuvs::cluster`_ + +_Source: `rust/cuvs/src/cluster/mod.rs`_ + +## kmeans + +```rust +pub mod kmeans; +``` + +_Source: `rust/cuvs/src/cluster/mod.rs:6`_ diff --git a/fern/pages/rust_api/rust-api-cuvs-distance-type.md b/fern/pages/rust_api/rust-api-cuvs-distance-type.md new file mode 100644 index 0000000000..e6750a0d02 --- /dev/null +++ b/fern/pages/rust_api/rust-api-cuvs-distance-type.md @@ -0,0 +1,17 @@ +--- +slug: api-reference/rust-api-cuvs-distance-type +--- + +# Distance Type Module + +_Rust module: `cuvs::distance_type`_ + +_Source: `rust/cuvs/src/distance_type.rs`_ + +## DistanceType + +```rust +pub type DistanceType = ffi::cuvsDistanceType; +``` + +_Source: `rust/cuvs/src/distance_type.rs:6`_ diff --git a/fern/pages/rust_api/rust-api-cuvs-distance.md b/fern/pages/rust_api/rust-api-cuvs-distance.md new file mode 100644 index 0000000000..64ae480b23 --- /dev/null +++ b/fern/pages/rust_api/rust-api-cuvs-distance.md @@ -0,0 +1,35 @@ +--- +slug: api-reference/rust-api-cuvs-distance +--- + +# Distance Module + +_Rust module: `cuvs::distance`_ + +_Source: `rust/cuvs/src/distance/mod.rs`_ + +## pairwise_distance + +```rust +pub fn pairwise_distance( +res: &Resources, +x: &ManagedTensor, +y: &ManagedTensor, +distances: &ManagedTensor, +metric: DistanceType, +metric_arg: Option, +) -> Result<()> { ... } +``` + +Compute pairwise distances between X and Y + +#### Arguments + +* `res` - Resources to use +* `x` - A matrix in device memory - shape (m, k) +* `y` - A matrix in device memory - shape (n, k) +* `distances` - A matrix in device memory that receives the output distances - shape (m, n) +* `metric` - DistanceType to use for building the index +* `metric_arg` - Optional value of `p` for Minkowski distances + +_Source: `rust/cuvs/src/distance/mod.rs:21`_ diff --git a/fern/pages/rust_api/rust-api-cuvs-dlpack.md b/fern/pages/rust_api/rust-api-cuvs-dlpack.md new file mode 100644 index 0000000000..d559e403e1 --- /dev/null +++ b/fern/pages/rust_api/rust-api-cuvs-dlpack.md @@ -0,0 +1,74 @@ +--- +slug: api-reference/rust-api-cuvs-dlpack +--- + +# Dlpack Module + +_Rust module: `cuvs::dlpack`_ + +_Source: `rust/cuvs/src/dlpack.rs`_ + +## ManagedTensor + +```rust +#[derive(Debug)] +pub struct ManagedTensor(ffi::DLManagedTensor); +``` + +ManagedTensor is a wrapper around a dlpack DLManagedTensor object. +This lets you pass matrices in device or host memory into cuvs. + +**Methods** + +| Name | Source | +| --- | --- | +| `as_ptr` | `rust/cuvs/src/dlpack.rs:21` | +| `to_device` | `rust/cuvs/src/dlpack.rs:27` | +| `to_host` | `rust/cuvs/src/dlpack.rs:53` | + +### as_ptr + +```rust +pub fn as_ptr(&self) -> *mut ffi::DLManagedTensor { ... } +``` + +_Source: `rust/cuvs/src/dlpack.rs:21`_ + +### to_device + +```rust +pub fn to_device(&self, res: &Resources) -> Result { ... } +``` + +Creates a new ManagedTensor on the current GPU device, and copies +the data into it. + +_Source: `rust/cuvs/src/dlpack.rs:27`_ + +### to_host + +```rust +pub fn to_host< +T: IntoDtype, +S: ndarray::RawData + ndarray::RawDataMut, +D: ndarray::Dimension, +>( +&self, +res: &Resources, +arr: &mut ndarray::ArrayBase, +) -> Result<()> { ... } +``` + +Copies data from device memory into host memory + +_Source: `rust/cuvs/src/dlpack.rs:53`_ + +_Source: `rust/cuvs/src/dlpack.rs:14`_ + +## IntoDtype + +```rust +pub trait IntoDtype { ... } +``` + +_Source: `rust/cuvs/src/dlpack.rs:16`_ diff --git a/fern/pages/rust_api/rust-api-cuvs-error.md b/fern/pages/rust_api/rust-api-cuvs-error.md new file mode 100644 index 0000000000..5c133eee3b --- /dev/null +++ b/fern/pages/rust_api/rust-api-cuvs-error.md @@ -0,0 +1,53 @@ +--- +slug: api-reference/rust-api-cuvs-error +--- + +# Error Module + +_Rust module: `cuvs::error`_ + +_Source: `rust/cuvs/src/error.rs`_ + +## CuvsError + +```rust +#[derive(Debug, Clone)] +pub struct CuvsError { ... } +``` + +_Source: `rust/cuvs/src/error.rs:9`_ + +## Error + +```rust +#[derive(Debug, Clone)] +pub enum Error { ... } +``` + +_Source: `rust/cuvs/src/error.rs:15`_ + +## Result + +```rust +pub type Result = std::result::Result; +``` + +_Source: `rust/cuvs/src/error.rs:26`_ + +## check_cuvs + +```rust +pub fn check_cuvs(err: ffi::cuvsError_t) -> Result<()> { ... } +``` + +Simple wrapper to convert a cuvsError_t into a Result + +_Source: `rust/cuvs/src/error.rs:45`_ + +## check_cuda + +```rust +pub fn check_cuda(err: ffi::cudaError_t) -> Result<()> { ... } +``` + +_Source: `rust/cuvs/src/error.rs:61`_ diff --git a/fern/pages/rust_api/rust-api-cuvs-ivf-flat-index-params.md b/fern/pages/rust_api/rust-api-cuvs-ivf-flat-index-params.md new file mode 100644 index 0000000000..0cd3847d69 --- /dev/null +++ b/fern/pages/rust_api/rust-api-cuvs-ivf-flat-index-params.md @@ -0,0 +1,104 @@ +--- +slug: api-reference/rust-api-cuvs-ivf-flat-index-params +--- + +# Ivf Flat Index Params Module + +_Rust module: `cuvs::ivf_flat::index_params`_ + +_Source: `rust/cuvs/src/ivf_flat/index_params.rs`_ + +## IndexParams + +```rust +pub struct IndexParams(pub ffi::cuvsIvfFlatIndexParams_t); +``` + +**Methods** + +| Name | Source | +| --- | --- | +| `new` | `rust/cuvs/src/ivf_flat/index_params.rs:15` | +| `set_n_lists` | `rust/cuvs/src/ivf_flat/index_params.rs:24` | +| `set_metric` | `rust/cuvs/src/ivf_flat/index_params.rs:32` | +| `set_metric_arg` | `rust/cuvs/src/ivf_flat/index_params.rs:40` | +| `set_kmeans_n_iters` | `rust/cuvs/src/ivf_flat/index_params.rs:47` | +| `set_kmeans_trainset_fraction` | `rust/cuvs/src/ivf_flat/index_params.rs:57` | +| `set_add_data_on_build` | `rust/cuvs/src/ivf_flat/index_params.rs:68` | + +### new + +```rust +pub fn new() -> Result { ... } +``` + +Returns a new IndexParams + +_Source: `rust/cuvs/src/ivf_flat/index_params.rs:15`_ + +### set_n_lists + +```rust +pub fn set_n_lists(self, n_lists: u32) -> IndexParams { ... } +``` + +The number of clusters used in the coarse quantizer. + +_Source: `rust/cuvs/src/ivf_flat/index_params.rs:24`_ + +### set_metric + +```rust +pub fn set_metric(self, metric: DistanceType) -> IndexParams { ... } +``` + +DistanceType to use for building the index + +_Source: `rust/cuvs/src/ivf_flat/index_params.rs:32`_ + +### set_metric_arg + +```rust +pub fn set_metric_arg(self, metric_arg: f32) -> IndexParams { ... } +``` + +The number of iterations searching for kmeans centers during index building. + +_Source: `rust/cuvs/src/ivf_flat/index_params.rs:40`_ + +### set_kmeans_n_iters + +```rust +pub fn set_kmeans_n_iters(self, kmeans_n_iters: u32) -> IndexParams { ... } +``` + +The number of iterations searching for kmeans centers during index building. + +_Source: `rust/cuvs/src/ivf_flat/index_params.rs:47`_ + +### set_kmeans_trainset_fraction + +```rust +pub fn set_kmeans_trainset_fraction(self, kmeans_trainset_fraction: f64) -> IndexParams { ... } +``` + +If kmeans_trainset_fraction is less than 1, then the dataset is +subsampled, and only n_samples * kmeans_trainset_fraction rows +are used for training. + +_Source: `rust/cuvs/src/ivf_flat/index_params.rs:57`_ + +### set_add_data_on_build + +```rust +pub fn set_add_data_on_build(self, add_data_on_build: bool) -> IndexParams { ... } +``` + +After training the coarse and fine quantizers, we will populate +the index with the dataset if add_data_on_build == true, otherwise +the index is left empty, and the extend method can be used +to add new vectors to the index. + +_Source: `rust/cuvs/src/ivf_flat/index_params.rs:68`_ + +_Source: `rust/cuvs/src/ivf_flat/index_params.rs:11`_ diff --git a/fern/pages/rust_api/rust-api-cuvs-ivf-flat-index.md b/fern/pages/rust_api/rust-api-cuvs-ivf-flat-index.md new file mode 100644 index 0000000000..a9cb7d4095 --- /dev/null +++ b/fern/pages/rust_api/rust-api-cuvs-ivf-flat-index.md @@ -0,0 +1,83 @@ +--- +slug: api-reference/rust-api-cuvs-ivf-flat-index +--- + +# Ivf Flat Index Module + +_Rust module: `cuvs::ivf_flat::index`_ + +_Source: `rust/cuvs/src/ivf_flat/index.rs`_ + +## Index + +```rust +#[derive(Debug)] +pub struct Index(ffi::cuvsIvfFlatIndex_t); +``` + +Ivf-Flat ANN Index + +**Methods** + +| Name | Source | +| --- | --- | +| `build` | `rust/cuvs/src/ivf_flat/index.rs:25` | +| `new` | `rust/cuvs/src/ivf_flat/index.rs:44` | +| `search` | `rust/cuvs/src/ivf_flat/index.rs:61` | + +### build + +```rust +pub fn build>( +res: &Resources, +params: &IndexParams, +dataset: T, +) -> Result { ... } +``` + +Builds a new Index from the dataset for efficient search. + +#### Arguments + +* `res` - Resources to use +* `params` - Parameters for building the index +* `dataset` - A row-major matrix on either the host or device to index + +_Source: `rust/cuvs/src/ivf_flat/index.rs:25`_ + +### new + +```rust +pub fn new() -> Result { ... } +``` + +Creates a new empty index + +_Source: `rust/cuvs/src/ivf_flat/index.rs:44`_ + +### search + +```rust +pub fn search( +&self, +res: &Resources, +params: &SearchParams, +queries: &ManagedTensor, +neighbors: &ManagedTensor, +distances: &ManagedTensor, +) -> Result<()> { ... } +``` + +Perform a Approximate Nearest Neighbors search on the Index + +#### Arguments + +* `res` - Resources to use +* `params` - Parameters to use in searching the index +* `queries` - A matrix in device memory to query for +* `neighbors` - Matrix in device memory that receives the indices of the nearest neighbors +* `distances` - Matrix in device memory that receives the distances of the nearest neighbors + +_Source: `rust/cuvs/src/ivf_flat/index.rs:61`_ + +_Source: `rust/cuvs/src/ivf_flat/index.rs:15`_ diff --git a/fern/pages/rust_api/rust-api-cuvs-ivf-flat-search-params.md b/fern/pages/rust_api/rust-api-cuvs-ivf-flat-search-params.md new file mode 100644 index 0000000000..c484a73cdb --- /dev/null +++ b/fern/pages/rust_api/rust-api-cuvs-ivf-flat-search-params.md @@ -0,0 +1,46 @@ +--- +slug: api-reference/rust-api-cuvs-ivf-flat-search-params +--- + +# Ivf Flat Search Params Module + +_Rust module: `cuvs::ivf_flat::search_params`_ + +_Source: `rust/cuvs/src/ivf_flat/search_params.rs`_ + +## SearchParams + +```rust +pub struct SearchParams(pub ffi::cuvsIvfFlatSearchParams_t); +``` + +Supplemental parameters to search IvfFlat index + +**Methods** + +| Name | Source | +| --- | --- | +| `new` | `rust/cuvs/src/ivf_flat/search_params.rs:15` | +| `set_n_probes` | `rust/cuvs/src/ivf_flat/search_params.rs:24` | + +### new + +```rust +pub fn new() -> Result { ... } +``` + +Returns a new SearchParams object + +_Source: `rust/cuvs/src/ivf_flat/search_params.rs:15`_ + +### set_n_probes + +```rust +pub fn set_n_probes(self, n_probes: u32) -> SearchParams { ... } +``` + +Supplemental parameters to search IVF-Flat index + +_Source: `rust/cuvs/src/ivf_flat/search_params.rs:24`_ + +_Source: `rust/cuvs/src/ivf_flat/search_params.rs:11`_ diff --git a/fern/pages/rust_api/rust-api-cuvs-ivf-flat.md b/fern/pages/rust_api/rust-api-cuvs-ivf-flat.md new file mode 100644 index 0000000000..b34e3ba369 --- /dev/null +++ b/fern/pages/rust_api/rust-api-cuvs-ivf-flat.md @@ -0,0 +1,97 @@ +--- +slug: api-reference/rust-api-cuvs-ivf-flat +--- + +# Ivf Flat Module + +_Rust module: `cuvs::ivf_flat`_ + +_Source: `rust/cuvs/src/ivf_flat/mod.rs`_ + +The IVF-Flat method is an ANN algorithm. It uses an inverted file index (IVF) with +unmodified (that is, flat) vectors. This algorithm provides simple knobs to reduce +the overall search space and to trade-off accuracy for speed. + +Example: +``` + +use cuvs::ivf_flat::{Index, IndexParams, SearchParams}; +use cuvs::{ManagedTensor, Resources, Result}; + +use ndarray::s; +use ndarray_rand::rand_distr::Uniform; +use ndarray_rand::RandomExt; + +fn ivf_flat_example() -> Result<()> { +let res = Resources::new()?; + +// Create a new random dataset to index +let n_datapoints = 65536; +let n_features = 512; +let dataset = +ndarray::Array::::random((n_datapoints, n_features), Uniform::new(0., 1.0)); + +// build the ivf-flat index +let build_params = IndexParams::new()?; +let index = Index::build(&res, &build_params, &dataset)?; +println!( +"Indexed {}x{} datapoints into ivf-flat index", +n_datapoints, n_features +); + +// use the first 4 points from the dataset as queries : will test that we get them back +// as their own nearest neighbor +let n_queries = 4; +let queries = dataset.slice(s![0..n_queries, ..]); + +let k = 10; + +// Ivf-Flat search API requires queries and outputs to be on device memory +// copy query data over, and allocate new device memory for the distances/ neighbors +// outputs +let queries = ManagedTensor::from(&queries).to_device(&res)?; +let mut neighbors_host = ndarray::Array::::zeros((n_queries, k)); +let neighbors = ManagedTensor::from(&neighbors_host).to_device(&res)?; + +let mut distances_host = ndarray::Array::::zeros((n_queries, k)); +let distances = ManagedTensor::from(&distances_host).to_device(&res)?; + +let search_params = SearchParams::new()?; + +index.search(&res, &search_params, &queries, &neighbors, &distances)?; + +// Copy back to host memory +distances.to_host(&res, &mut distances_host)?; +neighbors.to_host(&res, &mut neighbors_host)?; + +// nearest neighbors should be themselves, since queries are from the +// dataset +println!("Neighbors {:?}", neighbors_host); +println!("Distances {:?}", distances_host); +Ok(()) +} +``` + +## index::Index + +```rust +pub use index::Index; +``` + +_Source: `rust/cuvs/src/ivf_flat/mod.rs:74`_ + +## index_params::IndexParams + +```rust +pub use index_params::IndexParams; +``` + +_Source: `rust/cuvs/src/ivf_flat/mod.rs:75`_ + +## search_params::SearchParams + +```rust +pub use search_params::SearchParams; +``` + +_Source: `rust/cuvs/src/ivf_flat/mod.rs:76`_ diff --git a/fern/pages/rust_api/rust-api-cuvs-ivf-pq-index-params.md b/fern/pages/rust_api/rust-api-cuvs-ivf-pq-index-params.md new file mode 100644 index 0000000000..efc03e7136 --- /dev/null +++ b/fern/pages/rust_api/rust-api-cuvs-ivf-pq-index-params.md @@ -0,0 +1,209 @@ +--- +slug: api-reference/rust-api-cuvs-ivf-pq-index-params +--- + +# Ivf Pq Index Params Module + +_Rust module: `cuvs::ivf_pq::index_params`_ + +_Source: `rust/cuvs/src/ivf_pq/index_params.rs`_ + +## ffi::cuvsIvfPqCodebookGen + +```rust +pub use ffi::cuvsIvfPqCodebookGen; +``` + +_Source: `rust/cuvs/src/ivf_pq/index_params.rs:11`_ + +## ffi::cuvsIvfPqListLayout + +```rust +pub use ffi::cuvsIvfPqListLayout; +``` + +_Source: `rust/cuvs/src/ivf_pq/index_params.rs:12`_ + +## IndexParams + +```rust +pub struct IndexParams(pub ffi::cuvsIvfPqIndexParams_t); +``` + +**Methods** + +| Name | Source | +| --- | --- | +| `new` | `rust/cuvs/src/ivf_pq/index_params.rs:18` | +| `set_n_lists` | `rust/cuvs/src/ivf_pq/index_params.rs:27` | +| `set_metric` | `rust/cuvs/src/ivf_pq/index_params.rs:35` | +| `set_metric_arg` | `rust/cuvs/src/ivf_pq/index_params.rs:43` | +| `set_kmeans_n_iters` | `rust/cuvs/src/ivf_pq/index_params.rs:51` | +| `set_kmeans_trainset_fraction` | `rust/cuvs/src/ivf_pq/index_params.rs:61` | +| `set_pq_bits` | `rust/cuvs/src/ivf_pq/index_params.rs:69` | +| `set_pq_dim` | `rust/cuvs/src/ivf_pq/index_params.rs:85` | +| `set_codebook_kind` | `rust/cuvs/src/ivf_pq/index_params.rs:92` | +| `set_codes_layout` | `rust/cuvs/src/ivf_pq/index_params.rs:103` | +| `set_force_random_rotation` | `rust/cuvs/src/ivf_pq/index_params.rs:121` | +| `set_max_train_points_per_pq_code` | `rust/cuvs/src/ivf_pq/index_params.rs:133` | +| `set_add_data_on_build` | `rust/cuvs/src/ivf_pq/index_params.rs:144` | + +### new + +```rust +pub fn new() -> Result { ... } +``` + +Returns a new IndexParams + +_Source: `rust/cuvs/src/ivf_pq/index_params.rs:18`_ + +### set_n_lists + +```rust +pub fn set_n_lists(self, n_lists: u32) -> IndexParams { ... } +``` + +The number of clusters used in the coarse quantizer. + +_Source: `rust/cuvs/src/ivf_pq/index_params.rs:27`_ + +### set_metric + +```rust +pub fn set_metric(self, metric: DistanceType) -> IndexParams { ... } +``` + +DistanceType to use for building the index + +_Source: `rust/cuvs/src/ivf_pq/index_params.rs:35`_ + +### set_metric_arg + +```rust +pub fn set_metric_arg(self, metric_arg: f32) -> IndexParams { ... } +``` + +The number of iterations searching for kmeans centers during index building. + +_Source: `rust/cuvs/src/ivf_pq/index_params.rs:43`_ + +### set_kmeans_n_iters + +```rust +pub fn set_kmeans_n_iters(self, kmeans_n_iters: u32) -> IndexParams { ... } +``` + +The number of iterations searching for kmeans centers during index building. + +_Source: `rust/cuvs/src/ivf_pq/index_params.rs:51`_ + +### set_kmeans_trainset_fraction + +```rust +pub fn set_kmeans_trainset_fraction(self, kmeans_trainset_fraction: f64) -> IndexParams { ... } +``` + +If kmeans_trainset_fraction is less than 1, then the dataset is +subsampled, and only n_samples * kmeans_trainset_fraction rows +are used for training. + +_Source: `rust/cuvs/src/ivf_pq/index_params.rs:61`_ + +### set_pq_bits + +```rust +pub fn set_pq_bits(self, pq_bits: u32) -> IndexParams { ... } +``` + +The bit length of the vector element after quantization. + +_Source: `rust/cuvs/src/ivf_pq/index_params.rs:69`_ + +### set_pq_dim + +```rust +pub fn set_pq_dim(self, pq_dim: u32) -> IndexParams { ... } +``` + +The dimensionality of a the vector after product quantization. +When zero, an optimal value is selected using a heuristic. Note +pq_dim * pq_bits must be a multiple of 8. Hint: a smaller 'pq_dim' +results in a smaller index size and better search performance, but +lower recall. If 'pq_bits' is 8, 'pq_dim' can be set to any number, +but multiple of 8 are desirable for good performance. If 'pq_bits' +is not 8, 'pq_dim' should be a multiple of 8. For good performance, +it is desirable that 'pq_dim' is a multiple of 32. Ideally, +'pq_dim' should be also a divisor of the dataset dim. + +_Source: `rust/cuvs/src/ivf_pq/index_params.rs:85`_ + +### set_codebook_kind + +```rust +pub fn set_codebook_kind(self, codebook_kind: cuvsIvfPqCodebookGen) -> IndexParams { ... } +``` + +_Source: `rust/cuvs/src/ivf_pq/index_params.rs:92`_ + +### set_codes_layout + +```rust +pub fn set_codes_layout(self, codes_layout: cuvsIvfPqListLayout) -> IndexParams { ... } +``` + +Memory layout of the IVF-PQ list data. +- FLAT: Codes are stored contiguously, one vector's codes after another. +- INTERLEAVED: Codes are interleaved for optimized search performance. +This is the default and recommended for search workloads. + +_Source: `rust/cuvs/src/ivf_pq/index_params.rs:103`_ + +### set_force_random_rotation + +```rust +pub fn set_force_random_rotation(self, force_random_rotation: bool) -> IndexParams { ... } +``` + +Apply a random rotation matrix on the input data and queries even +if `dim % pq_dim == 0`. Note: if `dim` is not multiple of `pq_dim`, +a random rotation is always applied to the input data and queries +to transform the working space from `dim` to `rot_dim`, which may +be slightly larger than the original space and and is a multiple +of `pq_dim` (`rot_dim % pq_dim == 0`). However, this transform is +not necessary when `dim` is multiple of `pq_dim` (`dim == rot_dim`, +hence no need in adding "extra" data columns / features). By +default, if `dim == rot_dim`, the rotation transform is +initialized with the identity matrix. When +`force_random_rotation == True`, a random orthogonal transform + +_Source: `rust/cuvs/src/ivf_pq/index_params.rs:121`_ + +### set_max_train_points_per_pq_code + +```rust +pub fn set_max_train_points_per_pq_code(self, max_pq_points: u32) -> IndexParams { ... } +``` + +The max number of data points to use per PQ code during PQ codebook training. Using more data +points per PQ code may increase the quality of PQ codebook but may also increase the build +time. The parameter is applied to both PQ codebook generation methods, i.e., PER_SUBSPACE and +PER_CLUSTER. In both cases, we will use `pq_book_size * max_train_points_per_pq_code` training +points to train each codebook. + +_Source: `rust/cuvs/src/ivf_pq/index_params.rs:133`_ + +### set_add_data_on_build + +```rust +pub fn set_add_data_on_build(self, add_data_on_build: bool) -> IndexParams { ... } +``` + +After training the coarse and fine quantizers, we will populate +the index with the dataset if add_data_on_build == true, otherwise +the index is left empty, and the extend method can be used +to add new vectors to the index. + +_Source: `rust/cuvs/src/ivf_pq/index_params.rs:144`_ + +_Source: `rust/cuvs/src/ivf_pq/index_params.rs:14`_ diff --git a/fern/pages/rust_api/rust-api-cuvs-ivf-pq-index.md b/fern/pages/rust_api/rust-api-cuvs-ivf-pq-index.md new file mode 100644 index 0000000000..f6aa32f175 --- /dev/null +++ b/fern/pages/rust_api/rust-api-cuvs-ivf-pq-index.md @@ -0,0 +1,83 @@ +--- +slug: api-reference/rust-api-cuvs-ivf-pq-index +--- + +# Ivf Pq Index Module + +_Rust module: `cuvs::ivf_pq::index`_ + +_Source: `rust/cuvs/src/ivf_pq/index.rs`_ + +## Index + +```rust +#[derive(Debug)] +pub struct Index(ffi::cuvsIvfPqIndex_t); +``` + +Ivf-Pq ANN Index + +**Methods** + +| Name | Source | +| --- | --- | +| `build` | `rust/cuvs/src/ivf_pq/index.rs:25` | +| `new` | `rust/cuvs/src/ivf_pq/index.rs:44` | +| `search` | `rust/cuvs/src/ivf_pq/index.rs:61` | + +### build + +```rust +pub fn build>( +res: &Resources, +params: &IndexParams, +dataset: T, +) -> Result { ... } +``` + +Builds a new Index from the dataset for efficient search. + +#### Arguments + +* `res` - Resources to use +* `params` - Parameters for building the index +* `dataset` - A row-major matrix on either the host or device to index + +_Source: `rust/cuvs/src/ivf_pq/index.rs:25`_ + +### new + +```rust +pub fn new() -> Result { ... } +``` + +Creates a new empty index + +_Source: `rust/cuvs/src/ivf_pq/index.rs:44`_ + +### search + +```rust +pub fn search( +&self, +res: &Resources, +params: &SearchParams, +queries: &ManagedTensor, +neighbors: &ManagedTensor, +distances: &ManagedTensor, +) -> Result<()> { ... } +``` + +Perform a Approximate Nearest Neighbors search on the Index + +#### Arguments + +* `res` - Resources to use +* `params` - Parameters to use in searching the index +* `queries` - A matrix in device memory to query for +* `neighbors` - Matrix in device memory that receives the indices of the nearest neighbors +* `distances` - Matrix in device memory that receives the distances of the nearest neighbors + +_Source: `rust/cuvs/src/ivf_pq/index.rs:61`_ + +_Source: `rust/cuvs/src/ivf_pq/index.rs:15`_ diff --git a/fern/pages/rust_api/rust-api-cuvs-ivf-pq-search-params.md b/fern/pages/rust_api/rust-api-cuvs-ivf-pq-search-params.md new file mode 100644 index 0000000000..28ba1c5fc3 --- /dev/null +++ b/fern/pages/rust_api/rust-api-cuvs-ivf-pq-search-params.md @@ -0,0 +1,84 @@ +--- +slug: api-reference/rust-api-cuvs-ivf-pq-search-params +--- + +# Ivf Pq Search Params Module + +_Rust module: `cuvs::ivf_pq::search_params`_ + +_Source: `rust/cuvs/src/ivf_pq/search_params.rs`_ + +## ffi::cudaDataType_t + +```rust +pub use ffi::cudaDataType_t; +``` + +_Source: `rust/cuvs/src/ivf_pq/search_params.rs:10`_ + +## SearchParams + +```rust +pub struct SearchParams(pub ffi::cuvsIvfPqSearchParams_t); +``` + +Supplemental parameters to search IvfPq index + +**Methods** + +| Name | Source | +| --- | --- | +| `new` | `rust/cuvs/src/ivf_pq/search_params.rs:17` | +| `set_n_probes` | `rust/cuvs/src/ivf_pq/search_params.rs:26` | +| `set_lut_dtype` | `rust/cuvs/src/ivf_pq/search_params.rs:39` | +| `set_internal_distance_dtype` | `rust/cuvs/src/ivf_pq/search_params.rs:47` | + +### new + +```rust +pub fn new() -> Result { ... } +``` + +Returns a new SearchParams object + +_Source: `rust/cuvs/src/ivf_pq/search_params.rs:17`_ + +### set_n_probes + +```rust +pub fn set_n_probes(self, n_probes: u32) -> SearchParams { ... } +``` + +The number of clusters to search. + +_Source: `rust/cuvs/src/ivf_pq/search_params.rs:26`_ + +### set_lut_dtype + +```rust +pub fn set_lut_dtype(self, lut_dtype: cudaDataType_t) -> SearchParams { ... } +``` + +Data type of look up table to be created dynamically at search +time. The use of low-precision types reduces the amount of shared +memory required at search time, so fast shared memory kernels can +be used even for datasets with large dimansionality. Note that +the recall is slightly degraded when low-precision type is +selected. + +_Source: `rust/cuvs/src/ivf_pq/search_params.rs:39`_ + +### set_internal_distance_dtype + +```rust +pub fn set_internal_distance_dtype( +self, +internal_distance_dtype: cudaDataType_t, +) -> SearchParams { ... } +``` + +Storage data type for distance/similarity computation. + +_Source: `rust/cuvs/src/ivf_pq/search_params.rs:47`_ + +_Source: `rust/cuvs/src/ivf_pq/search_params.rs:13`_ diff --git a/fern/pages/rust_api/rust-api-cuvs-ivf-pq.md b/fern/pages/rust_api/rust-api-cuvs-ivf-pq.md new file mode 100644 index 0000000000..08c4d2195e --- /dev/null +++ b/fern/pages/rust_api/rust-api-cuvs-ivf-pq.md @@ -0,0 +1,95 @@ +--- +slug: api-reference/rust-api-cuvs-ivf-pq +--- + +# Ivf Pq Module + +_Rust module: `cuvs::ivf_pq`_ + +_Source: `rust/cuvs/src/ivf_pq/mod.rs`_ + +Inverted File Product Quantization + +Example: +``` + +use cuvs::ivf_pq::{Index, IndexParams, SearchParams}; +use cuvs::{ManagedTensor, Resources, Result}; + +use ndarray::s; +use ndarray_rand::rand_distr::Uniform; +use ndarray_rand::RandomExt; + +fn ivf_pq_example() -> Result<()> { +let res = Resources::new()?; + +// Create a new random dataset to index +let n_datapoints = 65536; +let n_features = 512; +let dataset = +ndarray::Array::::random((n_datapoints, n_features), Uniform::new(0., 1.0)); + +// build the ivf-pq index +let build_params = IndexParams::new()?; +let index = Index::build(&res, &build_params, &dataset)?; +println!( +"Indexed {}x{} datapoints into ivf-pq index", +n_datapoints, n_features +); + +// use the first 4 points from the dataset as queries : will test that we get them back +// as their own nearest neighbor +let n_queries = 4; +let queries = dataset.slice(s![0..n_queries, ..]); + +let k = 10; + +// Ivf-Pq search API requires queries and outputs to be on device memory +// copy query data over, and allocate new device memory for the distances/ neighbors +// outputs +let queries = ManagedTensor::from(&queries).to_device(&res)?; +let mut neighbors_host = ndarray::Array::::zeros((n_queries, k)); +let neighbors = ManagedTensor::from(&neighbors_host).to_device(&res)?; + +let mut distances_host = ndarray::Array::::zeros((n_queries, k)); +let distances = ManagedTensor::from(&distances_host).to_device(&res)?; + +let search_params = SearchParams::new()?; + +index.search(&res, &search_params, &queries, &neighbors, &distances)?; + +// Copy back to host memory +distances.to_host(&res, &mut distances_host)?; +neighbors.to_host(&res, &mut neighbors_host)?; + +// nearest neighbors should be themselves, since queries are from the +// dataset +println!("Neighbors {:?}", neighbors_host); +println!("Distances {:?}", distances_host); +Ok(()) +} +``` + +## index::Index + +```rust +pub use index::Index; +``` + +_Source: `rust/cuvs/src/ivf_pq/mod.rs:71`_ + +## index_params::IndexParams + +```rust +pub use index_params::IndexParams; +``` + +_Source: `rust/cuvs/src/ivf_pq/mod.rs:72`_ + +## search_params::SearchParams + +```rust +pub use search_params::SearchParams; +``` + +_Source: `rust/cuvs/src/ivf_pq/mod.rs:73`_ diff --git a/fern/pages/rust_api/rust-api-cuvs-resources.md b/fern/pages/rust_api/rust-api-cuvs-resources.md new file mode 100644 index 0000000000..cee265f1c0 --- /dev/null +++ b/fern/pages/rust_api/rust-api-cuvs-resources.md @@ -0,0 +1,71 @@ +--- +slug: api-reference/rust-api-cuvs-resources +--- + +# Resources Module + +_Rust module: `cuvs::resources`_ + +_Source: `rust/cuvs/src/resources.rs`_ + +## Resources + +```rust +#[derive(Debug)] +pub struct Resources(pub ffi::cuvsResources_t); +``` + +Resources are objects that are shared between function calls, +and includes things like CUDA streams, cuBLAS handles and other +resources that are expensive to create. + +**Methods** + +| Name | Source | +| --- | --- | +| `new` | `rust/cuvs/src/resources.rs:17` | +| `set_cuda_stream` | `rust/cuvs/src/resources.rs:26` | +| `get_cuda_stream` | `rust/cuvs/src/resources.rs:31` | +| `sync_stream` | `rust/cuvs/src/resources.rs:40` | + +### new + +```rust +pub fn new() -> Result { ... } +``` + +Returns a new Resources object + +_Source: `rust/cuvs/src/resources.rs:17`_ + +### set_cuda_stream + +```rust +pub fn set_cuda_stream(&self, stream: ffi::cudaStream_t) -> Result<()> { ... } +``` + +Sets the current cuda stream + +_Source: `rust/cuvs/src/resources.rs:26`_ + +### get_cuda_stream + +```rust +pub fn get_cuda_stream(&self) -> Result { ... } +``` + +Gets the current cuda stream + +_Source: `rust/cuvs/src/resources.rs:31`_ + +### sync_stream + +```rust +pub fn sync_stream(&self) -> Result<()> { ... } +``` + +Syncs the current cuda stream + +_Source: `rust/cuvs/src/resources.rs:40`_ + +_Source: `rust/cuvs/src/resources.rs:13`_ diff --git a/fern/pages/rust_api/rust-api-cuvs-vamana-index-params.md b/fern/pages/rust_api/rust-api-cuvs-vamana-index-params.md new file mode 100644 index 0000000000..d4675c112a --- /dev/null +++ b/fern/pages/rust_api/rust-api-cuvs-vamana-index-params.md @@ -0,0 +1,135 @@ +--- +slug: api-reference/rust-api-cuvs-vamana-index-params +--- + +# Vamana Index Params Module + +_Rust module: `cuvs::vamana::index_params`_ + +_Source: `rust/cuvs/src/vamana/index_params.rs`_ + +## IndexParams + +```rust +pub struct IndexParams(pub ffi::cuvsVamanaIndexParams_t); +``` + +**Methods** + +| Name | Source | +| --- | --- | +| `new` | `rust/cuvs/src/vamana/index_params.rs:15` | +| `set_metric` | `rust/cuvs/src/vamana/index_params.rs:24` | +| `set_graph_degree` | `rust/cuvs/src/vamana/index_params.rs:33` | +| `set_visited_size` | `rust/cuvs/src/vamana/index_params.rs:42` | +| `set_vamana_iters` | `rust/cuvs/src/vamana/index_params.rs:50` | +| `set_alpha` | `rust/cuvs/src/vamana/index_params.rs:58` | +| `set_max_fraction` | `rust/cuvs/src/vamana/index_params.rs:67` | +| `set_batch_base` | `rust/cuvs/src/vamana/index_params.rs:75` | +| `set_queue_size` | `rust/cuvs/src/vamana/index_params.rs:83` | +| `set_reverse_batchsize` | `rust/cuvs/src/vamana/index_params.rs:91` | + +### new + +```rust +pub fn new() -> Result { ... } +``` + +Returns a new IndexParams + +_Source: `rust/cuvs/src/vamana/index_params.rs:15`_ + +### set_metric + +```rust +pub fn set_metric(self, metric: DistanceType) -> IndexParams { ... } +``` + +DistanceType to use for building the index + +_Source: `rust/cuvs/src/vamana/index_params.rs:24`_ + +### set_graph_degree + +```rust +pub fn set_graph_degree(self, graph_degree: u32) -> IndexParams { ... } +``` + +Maximum degree of output graph corresponds to the R parameter in the original Vamana +literature. + +_Source: `rust/cuvs/src/vamana/index_params.rs:33`_ + +### set_visited_size + +```rust +pub fn set_visited_size(self, visited_size: u32) -> IndexParams { ... } +``` + +Maximum number of visited nodes per search corresponds to the L parameter in the Vamana +literature + +_Source: `rust/cuvs/src/vamana/index_params.rs:42`_ + +### set_vamana_iters + +```rust +pub fn set_vamana_iters(self, vamana_iters: f32) -> IndexParams { ... } +``` + +Number of Vamana vector insertion iterations (each iteration inserts all vectors). + +_Source: `rust/cuvs/src/vamana/index_params.rs:50`_ + +### set_alpha + +```rust +pub fn set_alpha(self, alpha: f32) -> IndexParams { ... } +``` + +Alpha for pruning parameter + +_Source: `rust/cuvs/src/vamana/index_params.rs:58`_ + +### set_max_fraction + +```rust +pub fn set_max_fraction(self, max_fraction: f32) -> IndexParams { ... } +``` + +Maximum fraction of dataset inserted per batch. +Larger max batch decreases graph quality, but improves speed + +_Source: `rust/cuvs/src/vamana/index_params.rs:67`_ + +### set_batch_base + +```rust +pub fn set_batch_base(self, batch_base: f32) -> IndexParams { ... } +``` + +Base of growth rate of batch sizes + +_Source: `rust/cuvs/src/vamana/index_params.rs:75`_ + +### set_queue_size + +```rust +pub fn set_queue_size(self, queue_size: u32) -> IndexParams { ... } +``` + +Size of candidate queue structure - should be (2^x)-1 + +_Source: `rust/cuvs/src/vamana/index_params.rs:83`_ + +### set_reverse_batchsize + +```rust +pub fn set_reverse_batchsize(self, reverse_batchsize: u32) -> IndexParams { ... } +``` + +Max batchsize of reverse edge processing (reduces memory footprint) + +_Source: `rust/cuvs/src/vamana/index_params.rs:91`_ + +_Source: `rust/cuvs/src/vamana/index_params.rs:11`_ diff --git a/fern/pages/rust_api/rust-api-cuvs-vamana-index.md b/fern/pages/rust_api/rust-api-cuvs-vamana-index.md new file mode 100644 index 0000000000..757fdf2978 --- /dev/null +++ b/fern/pages/rust_api/rust-api-cuvs-vamana-index.md @@ -0,0 +1,85 @@ +--- +slug: api-reference/rust-api-cuvs-vamana-index +--- + +# Vamana Index Module + +_Rust module: `cuvs::vamana::index`_ + +_Source: `rust/cuvs/src/vamana/index.rs`_ + +## Index + +```rust +#[derive(Debug)] +pub struct Index(ffi::cuvsVamanaIndex_t); +``` + +Vamana ANN Index + +**Methods** + +| Name | Source | +| --- | --- | +| `build` | `rust/cuvs/src/vamana/index.rs:33` | +| `new` | `rust/cuvs/src/vamana/index.rs:52` | +| `serialize` | `rust/cuvs/src/vamana/index.rs:71` | + +### build + +```rust +pub fn build>( +res: &Resources, +params: &IndexParams, +dataset: T, +) -> Result { ... } +``` + +Builds Vamana Index for efficient DiskANN search + +The build uses the Vamana insertion-based algorithm to create the graph. The algorithm +starts with an empty graph and iteratively inserts batches of nodes. Each batch involves +performing a greedy search for each vector to be inserted, and inserting it with edges to +all nodes traversed during the search. Reverse edges are also inserted and robustPrune is applied +to improve graph quality. The index_params struct controls the degree of the final graph. + + +#### Arguments + +* `res` - Resources to use +* `params` - Parameters for building the index +* `dataset` - A row-major matrix on either the host or device to index + +_Source: `rust/cuvs/src/vamana/index.rs:33`_ + +### new + +```rust +pub fn new() -> Result { ... } +``` + +Creates a new empty index + +_Source: `rust/cuvs/src/vamana/index.rs:52`_ + +### serialize + +```rust +pub fn serialize(self, res: &Resources, filename: &str, include_dataset: bool) -> Result<()> { ... } +``` + +Save Vamana index to file + +Matches the file format used by the DiskANN open-source repository, allowing cross-compatibility. + +Serialized Index is to be used by the DiskANN open-source repository for graph search. + +#### Arguments + +* `res` - Resources to use +* `filename` - The file prefix for where the index is sazved +* `include_dataset` - whether to include the dataset in the serialized index + +_Source: `rust/cuvs/src/vamana/index.rs:71`_ + +_Source: `rust/cuvs/src/vamana/index.rs:16`_ diff --git a/fern/pages/rust_api/rust-api-cuvs-vamana.md b/fern/pages/rust_api/rust-api-cuvs-vamana.md new file mode 100644 index 0000000000..4bff7c0c79 --- /dev/null +++ b/fern/pages/rust_api/rust-api-cuvs-vamana.md @@ -0,0 +1,27 @@ +--- +slug: api-reference/rust-api-cuvs-vamana +--- + +# Vamana Module + +_Rust module: `cuvs::vamana`_ + +_Source: `rust/cuvs/src/vamana/mod.rs`_ + +Vamana + +## index::Index + +```rust +pub use index::Index; +``` + +_Source: `rust/cuvs/src/vamana/mod.rs:10`_ + +## index_params::IndexParams + +```rust +pub use index_params::IndexParams; +``` + +_Source: `rust/cuvs/src/vamana/mod.rs:11`_ diff --git a/fern/pages/rust_api/rust-api-cuvs.md b/fern/pages/rust_api/rust-api-cuvs.md new file mode 100644 index 0000000000..9f144b274b --- /dev/null +++ b/fern/pages/rust_api/rust-api-cuvs.md @@ -0,0 +1,102 @@ +--- +slug: api-reference/rust-api-cuvs +--- + +# cuVS Rust Crate + +_Rust module: `cuvs`_ + +_Source: `rust/cuvs/src/lib.rs`_ + +cuVS: Rust bindings for Vector Search on the GPU + +This crate provides Rust bindings for cuVS, allowing you to run +approximate nearest neighbors search on the GPU. + +## brute_force + +```rust +pub mod brute_force; +``` + +_Source: `rust/cuvs/src/lib.rs:10`_ + +## cagra + +```rust +pub mod cagra; +``` + +_Source: `rust/cuvs/src/lib.rs:11`_ + +## cluster + +```rust +pub mod cluster; +``` + +_Source: `rust/cuvs/src/lib.rs:12`_ + +## distance + +```rust +pub mod distance; +``` + +_Source: `rust/cuvs/src/lib.rs:13`_ + +## distance_type + +```rust +pub mod distance_type; +``` + +_Source: `rust/cuvs/src/lib.rs:14`_ + +## ivf_flat + +```rust +pub mod ivf_flat; +``` + +_Source: `rust/cuvs/src/lib.rs:17`_ + +## ivf_pq + +```rust +pub mod ivf_pq; +``` + +_Source: `rust/cuvs/src/lib.rs:18`_ + +## vamana + +```rust +pub mod vamana; +``` + +_Source: `rust/cuvs/src/lib.rs:20`_ + +## dlpack::ManagedTensor + +```rust +pub use dlpack::ManagedTensor; +``` + +_Source: `rust/cuvs/src/lib.rs:22`_ + +## error:: \{ ... \} + +```rust +pub use error:: { ... } +``` + +_Source: `rust/cuvs/src/lib.rs:23`_ + +## resources::Resources + +```rust +pub use resources::Resources; +``` + +_Source: `rust/cuvs/src/lib.rs:24`_ diff --git a/docs/source/tuning_guide.rst b/fern/pages/tuning_guide.md similarity index 70% rename from docs/source/tuning_guide.rst rename to fern/pages/tuning_guide.md index fd54fc42ae..905e96180f 100644 --- a/docs/source/tuning_guide.rst +++ b/fern/pages/tuning_guide.md @@ -1,23 +1,18 @@ -~~~~~~~~~~~~~~~~~~~~~~ -Automated tuning Guide -~~~~~~~~~~~~~~~~~~~~~~ +# Automated tuning Guide -Introduction -============ +## Introduction -A Method for tuning and evaluating Vector Search Indexes At Scale in Locally Indexed Vector Databases. For more information on the differences between locally and globally indexed vector databases, please see :doc:`this guide `. The goal of this guide is to give users a scalable and effective approach for tuning a vector search index, no matter how large. Evaluation of a vector search index “model” that measures recall in proportion to build time so that it penalizes the recall when the build time is really high (should ultimately optimize for finding a lower build time and higher recall). +A Method for tuning and evaluating Vector Search Indexes At Scale in Locally Indexed Vector Databases. For more information on the differences between locally and globally indexed vector databases, please see [this guide](vector_databases_vs_vector_search.md). The goal of this guide is to give users a scalable and effective approach for tuning a vector search index, no matter how large. Evaluation of a vector search index “model” that measures recall in proportion to build time so that it penalizes the recall when the build time is really high (should ultimately optimize for finding a lower build time and higher recall). -For more information on the various different types of vector search indexes, please see our :doc:`guide to choosing vector search indexes ` +For more information on the various different types of vector search indexes, please see our [guide to choosing vector search indexes](choosing_and_configuring_indexes.md) -Why automated tuning? -===================== +## Why automated tuning? -As much as 75% of users have told us they will not be able to tune a vector database beyond one or two simple knobs and we suggest that an ideal “knob” would be to balance training time and search time with search quality. The more time, the higher the quality, and the more needed to find an acceptable search performance. Even the 25% of users that want to tune are still asking for simple tools for doing so. These users also ask for some simple guidelines for setting tuning parameters, like :doc:`this guide `. +As much as 75% of users have told us they will not be able to tune a vector database beyond one or two simple knobs and we suggest that an ideal “knob” would be to balance training time and search time with search quality. The more time, the higher the quality, and the more needed to find an acceptable search performance. Even the 25% of users that want to tune are still asking for simple tools for doing so. These users also ask for some simple guidelines for setting tuning parameters, like [this guide](neighbors/neighbors.md). -Since vector search indexes are more closely related to machine learning models than traditional databases indexes, one option for easing the parameter tuning burden is to use hyper-parameter optimization tools like `Ray Tune `_ and `Optuna `_. to verify this. +Since vector search indexes are more closely related to machine learning models than traditional databases indexes, one option for easing the parameter tuning burden is to use hyper-parameter optimization tools like [Ray Tune](https://medium.com/rapids-ai/30x-faster-hyperparameter-search-with-raytune-and-rapids-403013fbefc5) and [Optuna](https://docs.rapids.ai/deployment/stable/examples/rapids-optuna-hpo/notebook/). to verify this. -How to tune? -============ +## How to tune? But how would this work when we have an index that's massively large- like 1TB? @@ -27,30 +22,28 @@ Because many databases use this sub-sampling trick, it's possible to perform an GPUs are naturally great at performing massively parallel tasks, especially when they are largely independent tasks, such as training and evaluating models with different hyper-parameter settings in parallel. Hyper-parameter optimization also lends itself well to distributed processing, such as multi-node multi-GPU operation. -Steps to achieve automated tuning -================================= +## Steps to achieve automated tuning More formally, an automated parameter tuning workflow with monte-carlo cross-validation looks something like this: -#. Ingest a large dataset into the vector database of your choice +1. Ingest a large dataset into the vector database of your choice -#. Choose an index size based on number of vectors. This should usually align with the average number of vectors the database will end up putting in a single ANN sub-index model. +1. Choose an index size based on number of vectors. This should usually align with the average number of vectors the database will end up putting in a single ANN sub-index model. -#. Uniformly random sample the number of vectors specified above from the database for a training set. This is often accomplished by generating some number of random (unique) numbers up to the dataset size. +1. Uniformly random sample the number of vectors specified above from the database for a training set. This is often accomplished by generating some number of random (unique) numbers up to the dataset size. -#. Uniformly sample some number of vectors for a test set and do this again for an evaluation set. 1-10% of the vectors in the training set. +1. Uniformly sample some number of vectors for a test set and do this again for an evaluation set. 1-10% of the vectors in the training set. -#. Use the test set to compute ground truth on the vectors from prior step against all vectors in the training set. +1. Use the test set to compute ground truth on the vectors from prior step against all vectors in the training set. -#. Start the HPO tuning process for the training set, using the test vectors for the query set. It's important to make sure your HPO is multi-objective and optimizes for: a) low build time, b) high throughput or low latency search (depending on needs), and c) acceptable recall. +1. Start the HPO tuning process for the training set, using the test vectors for the query set. It's important to make sure your HPO is multi-objective and optimizes for: a) low build time, b) high throughput or low latency search (depending on needs), and c) acceptable recall. -#. Use the evaluation dataset to test that the optimal hyper-parameters generalize to unseen points that were not used in the optimization process. +1. Use the evaluation dataset to test that the optimal hyper-parameters generalize to unseen points that were not used in the optimization process. -#. Optionally, the above steps multiple times on different uniform sub-samplings. Optimal parameters can then be combined over the multiple monte-carlo optimization iterations. For example, many hyper-parameters can simply be averaged but care might need to be taken for other parameters. +1. Optionally, the above steps multiple times on different uniform sub-samplings. Optimal parameters can then be combined over the multiple monte-carlo optimization iterations. For example, many hyper-parameters can simply be averaged but care might need to be taken for other parameters. -#. Create a new index in the database using the ideal params from above that meet the target constraints (e.g. build vs search vs quality) +1. Create a new index in the database using the ideal params from above that meet the target constraints (e.g. build vs search vs quality) -Conclusion -========== +## Conclusion By the end of this process, you should have a set of parameters that meet your target constraints while demonstrating how well the optimal hyper-parameters generalize across the dataset. The major benefit to this approach is that it breaks a potentially unbounded dataset size down into manageable chunks and accelerates tuning on those chunks. We see this process as a major value add for vector search on the GPU. diff --git a/docs/source/vector_databases_vs_vector_search.rst b/fern/pages/vector_databases_vs_vector_search.md similarity index 90% rename from docs/source/vector_databases_vs_vector_search.rst rename to fern/pages/vector_databases_vs_vector_search.md index 5c43ee5508..75a6e606c1 100644 --- a/docs/source/vector_databases_vs_vector_search.rst +++ b/fern/pages/vector_databases_vs_vector_search.md @@ -1,13 +1,10 @@ -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Vector search indexes vs vector databases -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Vector search indexes vs vector databases -This guide provides information on the differences between vector search indexes and fully-fledged vector databases. For more information on selecting and configuring vector search indexes, please refer to our :doc:`guide on choosing and configuring indexes ` +This guide provides information on the differences between vector search indexes and fully-fledged vector databases. For more information on selecting and configuring vector search indexes, please refer to our [guide on choosing and configuring indexes](choosing_and_configuring_indexes.md) One of the primary differences between vector database indexes and traditional database indexes is that vector search often uses approximations to trade-off accuracy of the results for speed. Because of this, while many mature databases offer mechanisms to tune their indexes and achieve better performance, vector database indexes can return completely garbage results if they aren’t tuned for a reasonable level of search quality in addition to performance tuning. This is because vector database indexes are more closely related to machine learning models than they are to traditional database indexes. -What are the differences between vector databases and vector search indexes? -============================================================================ +## What are the differences between vector databases and vector search indexes? Vector search in and of itself refers to the objective of finding the closest vectors in an index around a given set of query vectors. At the lowest level, vector search indexes are just machine learning models, which have a build, search, and recall performance that can be traded off, depending on the algorithm and various hyper-parameters. @@ -19,8 +16,7 @@ So what does all this mean to you? Sometimes a simple standalone vector search i FAISS and cuVS are examples of standalone vector search libraries, which again are more closely related to machine learning libraries than to fully-fledged databases. Milvus is an example of a special-purpose vector database and Elastic, MongoDB, and OpenSearch are examples of general-purpose databases that have added vector search capabilities. -How is vector search used by vector databases? -============================================== +## How is vector search used by vector databases? Within the context of vector databases, there are two primary ways in which vector search indexes are used and it’s important to understand which you are working with because it can have an effect on the behavior of the parameters with respect to the data. @@ -28,16 +24,13 @@ Many vector search algorithms improve scalability while reducing the number of d This leads us to two core architectural designs that we encounter in vector databases: -Locally partitioned vector search indexes ------------------------------------------ +### Locally partitioned vector search indexes Most databases follow this design, and vectors are often first written to a write-ahead log for durability. After some number of vectors are written, the write-ahead logs become immutable and may be merged with other write-ahead logs before eventually being converted to a new vector search index. The search is generally done over each locally partitioned index and the results combined. When setting hyperparameters, only the local vector search indexes need to be considered, though the same hyperparameters are going to be used across all of the local partitions. So, for example, if you’ve ingested 100M vectors but each partition only contains about 10M vectors, the size of the index only needs to consider its local 10M vectors. Details like number of vectors in the index are important, for example, when setting the number of clusters in an IVF-based (inverted file index) method, as I’ll cover below. - -Globally partitioned vector search indexes ------------------------------------------- +### Globally partitioned vector search indexes Some special-purpose vector databases follow this design, such as Yahoo’s Vespa and Google’s Spanner. A global index is trained to partition the entire database’s vectors up front as soon as there are enough vectors to do so (usually these databases are at a large enough scale that a significant number of vectors are bootstrapped initially and so it avoids the cold start problem). Ingested vectors are first run through the global index (clustering, for example, but tree- and graph-based methods have also been used) to determine which partition they belong to and the vectors are then (sent to, and) written directly to that partition. The individual partitions can contain a graph, tree, or a simple IVF list. These types of indexes have been able to scale to hundreds of billions to trillions of vectors, and since the partitions are themselves often implicitly based on neighborhoods, rather than being based on uniformly random distributed vectors like the locally partitioned architectures, the partitions can be grouped together or intentionally separated to support localized searches or load balancing, depending upon the needs of the system. @@ -47,11 +40,10 @@ Of course, the two approaches outlined above can also be used together (e.g. tra A challenge with GPUs in vector databases today is that the resulting vector indexes are expected to fit into the memory of available GPUs for fast search. That is to say, there doesn’t exist today an efficient mechanism for offloading or swapping GPU indexes so they can be cached from disk or host memory, for example. We are working on mechanisms to do this, and to also utilize technologies like GPUDirect Storage and GPUDirect RDMA to improve the IO performance further. -Tuning and hyperparameter optimization -====================================== +## Tuning and hyperparameter optimization Unfortunately, for large datasets, doing a hyper-parameter optimization on the whole dataset is not always feasible and this is actually where the locally partitioned vector search indexes have an advantage because you can think of each smaller segment of the larger index as a uniform random sample of the total vectors in the dataset. This means that it is possible to perform a hyperparameter optimization on the smaller subsets and find reasonably acceptable parameters that should generalize fairly well to the entire dataset. Generally this hyperparameter optimization will require computing a ground truth on the subset with an exact method like brute-force and then using it to evaluate several searches on randomly sampled vectors. Full hyper-parameter optimization may also not always be necessary- for example, once you have built a ground truth dataset on a subset, many times you can start by building an index with the default build parameters and then playing around with different search parameters until you get the desired quality and search performance. For massive indexes that might be multiple terabytes, you could also take this subsampling of, say, 10M vectors, train an index and then tune the search parameters from there. While there might be a small margin of error, the chosen build/search parameters should generalize fairly well for the databases that build locally partitioned indexes. -Refer to our :doc:`tuning guide ` for more information and examples on how to efficiently and automatically tune your vector search indexes based on your needs. +Refer to our [tuning guide](tuning_guide.md) for more information and examples on how to efficiently and automatically tune your vector search indexes based on your needs. diff --git a/fern/pages/working_with_ann_indexes.md b/fern/pages/working_with_ann_indexes.md new file mode 100644 index 0000000000..540303e26e --- /dev/null +++ b/fern/pages/working_with_ann_indexes.md @@ -0,0 +1,8 @@ +# Working with ANN Indexes + +## Pages + +- [Working with ANN Indexes in C](working_with_ann_indexes_c.md) +- [Working with ANN Indexes in C++](working_with_ann_indexes_cpp.md) +- [Working with ANN Indexes in Python](working_with_ann_indexes_python.md) +- [Working with ANN Indexes in Rust](working_with_ann_indexes_rust.md) diff --git a/fern/pages/working_with_ann_indexes_c.md b/fern/pages/working_with_ann_indexes_c.md new file mode 100644 index 0000000000..2e63e37aac --- /dev/null +++ b/fern/pages/working_with_ann_indexes_c.md @@ -0,0 +1,58 @@ +# Working with ANN Indexes in C + +- [Building an index](#building-an-index) +- [Searching an index](#searching-an-index) + +## Building an index + +```c +#include + +cuvsResources_t res; +cuvsCagraIndexParams_t index_params; +cuvsCagraIndex_t index; + +DLManagedTensor *dataset; + +// populate tensor with data +load_dataset(dataset); + +cuvsResourcesCreate(&res); +cuvsCagraIndexParamsCreate(&index_params); +cuvsCagraIndexCreate(&index); + +cuvsCagraBuild(res, index_params, dataset, index); + +cuvsCagraIndexDestroy(index); +cuvsCagraIndexParamsDestroy(index_params); +cuvsResourcesDestroy(res); +``` + +## Searching an index + +```c +#include + +cuvsResources_t res; +cuvsCagraSearchParams_t search_params; +cuvsCagraIndex_t index; + +// ... build index ... + +DLManagedTensor *queries; + +DLManagedTensor *neighbors; +DLManagedTensor *distances; + +// populate tensor with data +load_queries(queries); + +cuvsResourcesCreate(&res); +cuvsCagraSearchParamsCreate(&index_params); + +cuvsCagraSearch(res, search_params, index, queries, neighbors, distances); + +cuvsCagraIndexDestroy(index); +cuvsCagraIndexParamsDestroy(index_params); +cuvsResourcesDestroy(res); +``` diff --git a/fern/pages/working_with_ann_indexes_cpp.md b/fern/pages/working_with_ann_indexes_cpp.md new file mode 100644 index 0000000000..b23efcb264 --- /dev/null +++ b/fern/pages/working_with_ann_indexes_cpp.md @@ -0,0 +1,39 @@ +# Working with ANN Indexes in C++ + +- [Building an index](#building-an-index) +- [Searching an index](#searching-an-index) + +## Building an index + +```c++ +#include + +using namespace cuvs::neighbors; + +raft::device_matrix_view dataset = load_dataset(); +raft::device_resources res; + +cagra::index_params index_params; + +auto index = cagra::build(res, index_params, dataset); +``` + +## Searching an index + +```c++ +#include + +using namespace cuvs::neighbors; +cagra::index index; + +// ... build index ... + +raft::device_matrix_view queries = load_queries(); +raft::device_matrix_view neighbors = make_device_matrix_view(n_queries, k); +raft::device_matrix_view distances = make_device_matrix_view(n_queries, k); +raft::device_resources res; + +cagra::search_params search_params; + +cagra::search(res, search_params, index, queries, neighbors, distances); +``` diff --git a/fern/pages/working_with_ann_indexes_python.md b/fern/pages/working_with_ann_indexes_python.md new file mode 100644 index 0000000000..f4c5ae92b0 --- /dev/null +++ b/fern/pages/working_with_ann_indexes_python.md @@ -0,0 +1,29 @@ +# Working with ANN Indexes in Python + +- [Building an index](#building-an-index) +- [Searching an index](#searching-an-index) + +## Building an index + +```python +from cuvs.neighbors import cagra + +dataset = load_data() +index_params = cagra.IndexParams() + +index = cagra.build(build_params, dataset) +``` + +## Searching an index + +```python +from cuvs.neighbors import cagra + +queries = load_queries() + +search_params = cagra.SearchParams() + +index = // ... build index ... + +neighbors, distances = cagra.search(search_params, index, queries, k) +``` diff --git a/fern/pages/working_with_ann_indexes_rust.md b/fern/pages/working_with_ann_indexes_rust.md new file mode 100644 index 0000000000..f824d94768 --- /dev/null +++ b/fern/pages/working_with_ann_indexes_rust.md @@ -0,0 +1,60 @@ +# Working with ANN Indexes in Rust + +- [Building and Searching an index](#building-and-searching-an-index) + +## Building and Searching an index + +```rust +use cuvs::cagra::{Index, IndexParams}; +use cuvs::{Resources, Result}; + +use ndarray_rand::rand_distr::Uniform; +use ndarray_rand::RandomExt; + +/// Example showing how to index and search data with CAGRA +fn cagra_example() -> Result<()> { + let res = Resources::new()?; + + // Create a new random dataset to index + let n_datapoints = 65536; + let n_features = 512; + let dataset = + ndarray::Array::::random((n_datapoints, n_features), Uniform::new(0., 1.0)); + + // build the cagra index + let build_params = IndexParams::new()?; + let index = Index::build(&res, &build_params, &dataset)?; + + // use the first 4 points from the dataset as queries : will test that we get them back + // as their own nearest neighbor + let n_queries = 4; + let queries = dataset.slice(s![0..n_queries, ..]); + + let k = 10; + + // CAGRA search API requires queries and outputs to be on device memory + // copy query data over, and allocate new device memory for the distances/ neighbors + // outputs + let queries = ManagedTensor::from(&queries).to_device(&res)?; + let mut neighbors_host = ndarray::Array::::zeros((n_queries, k)); + let neighbors = ManagedTensor::from(&neighbors_host).to_device(&res)?; + + let mut distances_host = ndarray::Array::::zeros((n_queries, k)); + let distances = ManagedTensor::from(&distances_host).to_device(&res)?; + + let search_params = SearchParams::new()?; + + index.search(&res, &search_params, &queries, &neighbors, &distances)?; + + // Copy back to host memory + distances.to_host(&res, &mut distances_host)?; + neighbors.to_host(&res, &mut neighbors_host)?; + + // nearest neighbors should be themselves, since queries are from the + // dataset + println!("Neighbors {:?}", neighbors_host); + println!("Distances {:?}", distances_host); + + Ok(()) +} +``` diff --git a/fern/scripts/generate_api_reference.py b/fern/scripts/generate_api_reference.py new file mode 100755 index 0000000000..2e2f6647da --- /dev/null +++ b/fern/scripts/generate_api_reference.py @@ -0,0 +1,2755 @@ +#!/usr/bin/env python3 +# SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION. +# SPDX-License-Identifier: Apache-2.0 + +"""Generate Fern API reference pages from cuVS source code. + +The generator intentionally does not import ``cuvs`` or compile native code. +It reads the original C/C++ headers, Cython/Python sources, and Java sources +directly so the Fern reference can be refreshed in lightweight docs jobs. +""" + +from __future__ import annotations + +from collections import defaultdict +from dataclasses import dataclass, field +import ast +import re +import shutil +import textwrap +from pathlib import Path +from typing import Iterable + + +REPO_DIR = Path(__file__).resolve().parents[2] +FERN_PAGES = REPO_DIR / "fern" / "pages" +PYTHON_DIR = REPO_DIR / "python" / "cuvs" / "cuvs" +RUST_SOURCE_DIR = REPO_DIR / "rust" / "cuvs" / "src" +GO_SOURCE_DIR = REPO_DIR / "go" +NATIVE_HEADER_DIRS = [REPO_DIR / "c" / "include", REPO_DIR / "cpp" / "include"] +JAVA_SOURCE_DIRS = [ + REPO_DIR / "java" / "cuvs-java" / "src" / "main" / "java", + REPO_DIR / "java" / "cuvs-java" / "src" / "main" / "java22", +] +API_NAV_SECTIONS = [ + ("C API Documentation", "c_api", "c-api-documentation", "C API", "c-api"), + ("Cpp API Documentation", "cpp_api", "cpp-api-documentation", "C++ API", "cpp-api"), + ("Python API Documentation", "python_api", "python-api-documentation", "Python API", "python-api"), + ("Java API Documentation", "java_api", "java-api-documentation", "Java API", "java-api"), + ("Rust API Documentation", "rust_api", "rust-api-documentation", "Rust API", "rust-api"), + ("Go API Documentation", "go_api", "go-api-documentation", "Go API", "go-api"), +] + +COMMENT_RE = re.compile(r"/\*\*.*?\*/|(?:///[^\n]*(?:\n|$))+", re.DOTALL) +DOXYGEN_COMMAND_RE = re.compile(r"[@\\](\w+)\b") +PUBLIC_JAVA_TYPE_RE = re.compile( + r"\bpublic\s+(?:abstract\s+|final\s+|sealed\s+|non-sealed\s+)?" + r"(?Pclass|interface|enum|record)\s+(?P[A-Za-z_]\w*)" +) +SPHINX_ROLE_RE = re.compile( + r"(?[^`]+)`" +) + + +@dataclass +class DoxygenParam: + name: str + description: str = "" + direction: str = "" + + +@dataclass +class FunctionParam: + name: str + c_type: str + default: str = "" + + +@dataclass +class DoxygenEntry: + kind: str + name: str + signature: str + summary: str = "" + details: list[str] = field(default_factory=list) + params: list[DoxygenParam] = field(default_factory=list) + tparams: list[DoxygenParam] = field(default_factory=list) + returns: str = "" + source: str = "" + line: int = 0 + code_blocks: list[tuple[str, list[str]]] = field(default_factory=list) + + +@dataclass +class DoxygenGroup: + name: str + title: str = "" + entries: list[DoxygenEntry] = field(default_factory=list) + + +@dataclass +class NativePage: + slug: str + title: str + source: str + groups: list[DoxygenGroup] = field(default_factory=list) + + +@dataclass +class PythonSymbol: + name: str + kind: str + signature: str + doc: str + source: str + line: int + decorators: list[str] = field(default_factory=list) + members: list["PythonSymbol"] = field(default_factory=list) + value: str = "" + + +@dataclass +class PythonPage: + module: str + title: str + slug: str + symbols: list[PythonSymbol] + + +@dataclass +class JavaDoc: + summary: str = "" + params: list[DoxygenParam] = field(default_factory=list) + returns: str = "" + throws: list[DoxygenParam] = field(default_factory=list) + + +@dataclass +class JavaMember: + name: str + signature: str + doc: JavaDoc + line: int + + +@dataclass +class JavaClass: + package: str + name: str + kind: str + signature: str + doc: JavaDoc + source: str + line: int + members: list[JavaMember] = field(default_factory=list) + + +@dataclass +class RustItem: + name: str + kind: str + signature: str + doc: str + source: str + line: int + attributes: list[str] = field(default_factory=list) + members: list["RustItem"] = field(default_factory=list) + + +@dataclass +class RustPage: + module: str + title: str + slug: str + source: str + module_doc: str + items: list[RustItem] + + +@dataclass +class GoItem: + name: str + kind: str + signature: str + doc: str + source: str + line: int + receiver: str = "" + + +@dataclass +class GoPage: + package: str + title: str + slug: str + sources: list[str] + items: list[GoItem] + + +class DoxygenHeaderIndex: + def __init__(self) -> None: + self.groups: dict[str, DoxygenGroup] = {} + self.structs: dict[str, DoxygenEntry] = {} + self.enums: dict[str, DoxygenEntry] = {} + self.short_structs: dict[str, DoxygenEntry] = {} + self.short_enums: dict[str, DoxygenEntry] = {} + + @classmethod + def build(cls, header_dirs: Iterable[Path]) -> "DoxygenHeaderIndex": + index = cls() + for root in header_dirs: + for path in sorted(root.rglob("*")): + if path.suffix in {".h", ".hpp", ".cuh"}: + index._parse_header(path) + return index + + def _parse_header(self, path: Path) -> None: + text = path.read_text(encoding="utf-8") + rel_path = path.relative_to(REPO_DIR).as_posix() + current_groups: list[str] = [] + + for match in COMMENT_RE.finditer(text): + raw_comment = match.group(0) + if raw_comment.lstrip().startswith("///<"): + continue + + comment = clean_doxygen_comment(raw_comment) + if not comment.strip(): + continue + + group_command = find_doxygen_command(comment, "defgroup") + group_kind = "defgroup" + if group_command is None: + group_command = find_doxygen_command(comment, "addtogroup") + group_kind = "addtogroup" + + group_name = "" + if group_command: + group_name, group_title = split_command_payload(group_command) + group = self.groups.setdefault(group_name, DoxygenGroup(group_name)) + if group_kind == "defgroup" and group_title: + group.title = group_title + + closes_group = bool(re.search(r"(^|\s)[@\\]}", comment)) + opens_group = bool(re.search(r"(^|\s)[@\\]{", comment)) + explicit_groups = re.findall(r"[@\\]ingroup\s+([\w:.-]+)", comment) + candidate_groups = list(dict.fromkeys([*explicit_groups, *current_groups])) + + if not group_command and not closes_group: + declaration, decl_line = read_declaration_after(text, match.end()) + if declaration: + entry = parse_doxygen_entry(comment, declaration, rel_path, decl_line) + if entry.kind == "member": + continue + self._qualify_function(entry, text[: match.start()]) + for candidate in candidate_groups: + self.groups.setdefault(candidate, DoxygenGroup(candidate)).entries.append(entry) + self._index_compound(entry, text[: match.start()]) + + if group_command and opens_group and group_name: + current_groups.append(group_name) + if not next_non_whitespace_is_comment(text, match.end()): + declaration, decl_line = read_declaration_after(text, match.end()) + if declaration: + entry = parse_doxygen_entry(comment, declaration, rel_path, decl_line) + self._qualify_function(entry, text[: match.start()]) + if not entry.summary and self.groups[group_name].title: + entry.summary = self.groups[group_name].title + self.groups[group_name].entries.append(entry) + self._index_compound(entry, text[: match.start()]) + if closes_group and current_groups: + current_groups.pop() + + def _index_compound(self, entry: DoxygenEntry, prefix: str) -> None: + namespace = infer_namespace(prefix) + struct_name = parse_struct_name(entry.signature) + if struct_name: + fq_name = f"{namespace}::{struct_name}" if namespace else struct_name + entry.kind = "struct" + entry.name = fq_name + self.structs[fq_name] = entry + self.short_structs.setdefault(struct_name, entry) + + enum_name = parse_enum_name(entry.signature) + if enum_name: + fq_name = enum_name + if namespace and "::" not in enum_name: + fq_name = f"{namespace}::{enum_name}" + entry.kind = "enum" + entry.name = fq_name + self.enums[fq_name] = entry + self.short_enums.setdefault(enum_name.split("::")[-1], entry) + + def _qualify_function(self, entry: DoxygenEntry, prefix: str) -> None: + if entry.kind != "function" or "::" in entry.name: + return + namespace = infer_namespace(prefix) + if namespace: + entry.name = f"{namespace}::{entry.name}" + + +def main() -> int: + remove_old_api_pages() + native_index = DoxygenHeaderIndex.build(NATIVE_HEADER_DIRS) + generate_native_api_pages(native_index, "c") + generate_native_api_pages(native_index, "cpp") + generate_python_api_pages() + generate_java_api_pages() + generate_rust_api_pages() + generate_go_api_pages() + update_api_navigation() + return 0 + + +def remove_old_api_pages() -> None: + for path in [ + FERN_PAGES / "c_api", + FERN_PAGES / "cpp_api", + FERN_PAGES / "python_api", + FERN_PAGES / "java_api", + FERN_PAGES / "rust_api", + FERN_PAGES / "go_api", + ]: + if path.exists(): + shutil.rmtree(path) + for path in [ + FERN_PAGES / "c_api.md", + FERN_PAGES / "cpp_api.md", + FERN_PAGES / "python_api.md", + FERN_PAGES / "rust_api.md", + FERN_PAGES / "go_api.md", + ]: + if path.exists(): + path.unlink() + + +def generate_native_api_pages(index: DoxygenHeaderIndex, api: str) -> None: + out_dir = FERN_PAGES / f"{api}_api" + out_dir.mkdir(parents=True, exist_ok=True) + pages = collect_native_pages(index, api) + title = "C API Documentation" if api == "c" else "C++ API Documentation" + directory = f"{api}_api" + + index_lines = [ + f"# {title}", + "", + "These pages are generated from the documented public headers in the cuVS source tree.", + "", + ] + for page in pages: + index_lines.append(f"- [{page.title}]({api_doc_url(directory, page.slug)})") + write_page(out_dir / "index.md", index_lines) + + language = "c" if api == "c" else "cpp" + for page in pages: + lines = [ + *api_frontmatter(api_page_route(directory, page.slug)), + f"# {page.title}", + "", + f"_Source header: `{page.source}`_", + "", + ] + for group in page.groups: + lines.extend(render_native_group(group, language)) + lines.append("") + write_page(out_dir / f"{api_page_route(directory, page.slug)}.md", lines) + + +def collect_native_pages(index: DoxygenHeaderIndex, api: str) -> list[NativePage]: + prefix = "c/include/" if api == "c" else "cpp/include/" + pages: dict[str, NativePage] = {} + + for group in index.groups.values(): + entries = [entry for entry in group.entries if entry.source.startswith(prefix)] + if not entries: + continue + source = sorted({entry.source for entry in entries})[0] + slug = native_page_slug(source) + page = pages.setdefault(slug, NativePage(slug, native_page_title(source), source)) + copied = DoxygenGroup(group.name, group.title, sorted(entries, key=lambda entry: entry.line)) + page.groups.append(copied) + + ordered = sorted(pages.values(), key=lambda page: (page.source, page.title)) + for page in ordered: + page.groups.sort(key=lambda group: min((entry.line for entry in group.entries), default=0)) + return ordered + + +def render_native_group(group: DoxygenGroup, language: str) -> list[str]: + lines = [f"## {heading_text(group.title or group.name)}", ""] + if group.name: + lines.extend([f"_Doxygen group: `{group.name}`_", ""]) + + for entry in group.entries: + if entry.kind == "function": + lines.extend(render_native_function(entry, language)) + elif entry.kind in {"struct", "enum"}: + lines.extend(render_native_compound(entry, language)) + else: + lines.extend(render_native_member(entry, language)) + lines.append("") + return trim_blank_lines(lines) + + +def render_native_function(entry: DoxygenEntry, language: str) -> list[str]: + signature = normalize_signature(entry.signature) + lines = [f"### {heading_text(entry.name)}", ""] + if entry.summary: + lines.extend([escape_text(entry.summary), ""]) + lines.extend([f"```{language}", signature, "```", ""]) + + if entry.details: + lines.extend([escape_text(" ".join(line for line in entry.details if line.strip())), ""]) + + if entry.tparams: + lines.extend(["**Template Parameters**", ""]) + lines.extend(render_param_table( + [{"name": param.name, "type": "", "description": param.description} for param in entry.tparams], + include_direction=False, + )) + lines.append("") + + params = parse_function_params(signature) + documented_params = {param.name: param for param in entry.params} + rows = [] + for param in params: + documented = documented_params.get(param.name) + rows.append( + { + "name": param.name, + "direction": documented.direction if documented else "", + "type": param.c_type, + "description": documented.description if documented else "", + "default": param.default, + } + ) + if rows: + lines.extend(["**Parameters**", ""]) + lines.extend(render_param_table(rows, include_direction=True)) + lines.append("") + + return_type = parse_return_type(signature) + if return_type: + lines.extend(["**Returns**", "", f"`{escape_code(return_type)}`"]) + if entry.returns: + lines.extend(["", escape_text(entry.returns)]) + lines.append("") + + lines.extend([source_line(entry), ""]) + return trim_blank_lines(lines) + + +def render_native_compound(entry: DoxygenEntry, language: str) -> list[str]: + lines = [f"### {heading_text(entry.name)}", ""] + if entry.summary: + lines.extend([escape_text(entry.summary), ""]) + if entry.details: + lines.extend([escape_text(" ".join(line for line in entry.details if line.strip())), ""]) + lines.extend([f"```{language}", compact_compound_signature(entry.signature), "```", ""]) + + if entry.kind == "enum": + values = parse_enum_values(entry.signature) + if values: + lines.extend(["**Values**", "", "| Name | Value |", "| --- | --- |"]) + for value in values: + lines.append( + f"| `{escape_code(value['name'])}` | `{escape_code(value.get('value', ''))}` |" + ) + lines.append("") + else: + members = parse_struct_members(entry) + if members: + lines.extend(["**Fields**", ""]) + rows = [] + for member in members: + rows.append( + { + "name": member.name, + "type": member_c_type(member), + "description": member.summary, + } + ) + lines.extend(render_param_table(rows, include_direction=False)) + lines.append("") + + lines.extend([source_line(entry), ""]) + return trim_blank_lines(lines) + + +def render_native_member(entry: DoxygenEntry, language: str) -> list[str]: + lines = [f"### {heading_text(entry.name)}", ""] + if entry.summary: + lines.extend([escape_text(entry.summary), ""]) + lines.extend([f"```{language}", normalize_signature(entry.signature), "```", ""]) + lines.extend([source_line(entry), ""]) + return trim_blank_lines(lines) + + +def generate_python_api_pages() -> None: + out_dir = FERN_PAGES / "python_api" + out_dir.mkdir(parents=True, exist_ok=True) + symbol_index = build_python_symbol_index() + pages = collect_python_pages(symbol_index) + + index_lines = [ + "# Python API Documentation", + "", + "These pages are generated from the Python and Cython sources under `python/cuvs/cuvs`.", + "", + ] + for group, group_pages in group_python_pages(pages).items(): + index_lines.extend([f"## {group}", ""]) + for page in group_pages: + index_lines.append(f"- [{page.title}]({api_doc_url('python_api', page.slug)})") + index_lines.append("") + write_page(out_dir / "index.md", index_lines) + + for page in pages: + lines = [ + *api_frontmatter(api_page_route("python_api", page.slug)), + f"# {page.title}", + "", + f"_Python module: `{page.module}`_", + "", + ] + for symbol in page.symbols: + lines.extend(render_python_symbol(symbol)) + lines.append("") + write_page(out_dir / f"{api_page_route('python_api', page.slug)}.md", lines) + + +def build_python_symbol_index() -> dict[str, dict[str, PythonSymbol]]: + index: dict[str, dict[str, PythonSymbol]] = defaultdict(dict) + for path in sorted(PYTHON_DIR.rglob("*")): + if path.suffix not in {".py", ".pyx"}: + continue + if "/tests/" in path.as_posix(): + continue + module = python_module_name(path) + for symbol in parse_python_source(path): + index[module][symbol.name] = symbol + return index + + +def collect_python_pages(symbol_index: dict[str, dict[str, PythonSymbol]]) -> list[PythonPage]: + pages: list[PythonPage] = [] + for init_path in sorted(PYTHON_DIR.rglob("__init__.py")): + module = python_module_name(init_path) + exports = read_python_exports(init_path) + if not exports: + continue + symbols = [] + for name in exports: + symbol = find_python_symbol(module, name, symbol_index) + if symbol is not None: + symbols.append(symbol) + if not symbols: + continue + pages.append(PythonPage(module, python_title(module), python_slug(module), symbols)) + + pages.sort(key=lambda page: (python_group(page.module), page.title)) + return pages + + +def find_python_symbol( + module: str, + name: str, + symbol_index: dict[str, dict[str, PythonSymbol]], +) -> PythonSymbol | None: + candidates = [candidate for candidate in symbol_index if candidate == module or candidate.startswith(f"{module}.")] + candidates.sort(key=lambda candidate: (candidate.count("."), candidate)) + for candidate in candidates: + if name in symbol_index[candidate]: + return symbol_index[candidate][name] + return None + + +def parse_python_source(path: Path) -> list[PythonSymbol]: + text = path.read_text(encoding="utf-8") + lines = text.splitlines() + symbols: list[PythonSymbol] = [] + pending_decorators: list[str] = [] + idx = 0 + while idx < len(lines): + raw_line = lines[idx] + stripped = raw_line.strip() + indent = indentation(raw_line) + if indent == 0 and stripped.startswith("@"): + pending_decorators.append(stripped) + idx += 1 + continue + + class_match = re.match(r"(?:cdef\s+)?class\s+([A-Za-z_]\w*)", stripped) + if indent == 0 and class_match: + signature, end_idx = collect_python_signature(lines, idx) + doc, _ = collect_python_docstring(lines, end_idx + 1) + members = collect_python_class_members(lines, end_idx + 1, indent, path) + symbols.append( + PythonSymbol( + name=class_match.group(1), + kind="class", + signature=signature.rstrip(":"), + doc=doc, + source=path.relative_to(REPO_DIR).as_posix(), + line=idx + 1, + decorators=pending_decorators, + members=members, + ) + ) + pending_decorators = [] + idx = end_idx + 1 + continue + + function_match = re.match(r"def\s+([A-Za-z_]\w*)", stripped) + if indent == 0 and function_match: + signature, end_idx = collect_python_signature(lines, idx) + doc, _ = collect_python_docstring(lines, end_idx + 1) + symbols.append( + PythonSymbol( + name=function_match.group(1), + kind="function", + signature=signature.rstrip(":"), + doc=doc, + source=path.relative_to(REPO_DIR).as_posix(), + line=idx + 1, + decorators=pending_decorators, + ) + ) + pending_decorators = [] + idx = end_idx + 1 + continue + + assignment_match = re.match(r"([A-Z][A-Z0-9_]+)\s*=", stripped) + if indent == 0 and assignment_match: + name = assignment_match.group(1) + value, end_idx = collect_python_assignment(lines, idx) + symbols.append( + PythonSymbol( + name=name, + kind="constant", + signature=name, + doc="", + source=path.relative_to(REPO_DIR).as_posix(), + line=idx + 1, + value=value, + ) + ) + idx = end_idx + 1 + continue + + if indent == 0 and stripped and not stripped.startswith("#"): + pending_decorators = [] + idx += 1 + return symbols + + +def collect_python_class_members( + lines: list[str], + start: int, + class_indent: int, + path: Path, +) -> list[PythonSymbol]: + members: list[PythonSymbol] = [] + decorators: list[str] = [] + idx = start + while idx < len(lines): + raw_line = lines[idx] + stripped = raw_line.strip() + indent = indentation(raw_line) + if stripped and indent <= class_indent and not stripped.startswith("@"): + break + if indent > class_indent and stripped.startswith("@"): + decorators.append(stripped) + idx += 1 + continue + method_match = re.match(r"def\s+([A-Za-z_]\w*)", stripped) + if indent > class_indent and method_match: + name = method_match.group(1) + signature, end_idx = collect_python_signature(lines, idx) + doc, _ = collect_python_docstring(lines, end_idx + 1) + if not name.startswith("_") or name == "__init__": + kind = "property" if "@property" in decorators else "method" + members.append( + PythonSymbol( + name=name, + kind=kind, + signature=signature.rstrip(":"), + doc=doc, + source=path.relative_to(REPO_DIR).as_posix(), + line=idx + 1, + decorators=decorators, + ) + ) + decorators = [] + idx = end_idx + 1 + continue + if stripped and indent <= class_indent: + decorators = [] + idx += 1 + return members + + +def render_python_symbol(symbol: PythonSymbol) -> list[str]: + lines = [f"## {heading_text(symbol.name)}", ""] + if symbol.kind == "constant": + lines.extend(["```python", symbol.value or symbol.name, "```", ""]) + lines.extend([f"_Source: `{symbol.source}:{symbol.line}`_", ""]) + return trim_blank_lines(lines) + + for decorator in symbol.decorators: + lines.append(f"`{decorator}`") + if symbol.decorators: + lines.append("") + lines.extend(["```python", symbol.signature, "```", ""]) + if symbol.doc: + lines.extend(render_doc_text(symbol.doc)) + lines.append("") + + init_member = next((member for member in symbol.members if member.name == "__init__"), None) + if init_member is not None: + lines.extend(["**Constructor**", "", "```python", init_member.signature, "```", ""]) + + visible_members = [member for member in symbol.members if member.name != "__init__"] + if visible_members: + lines.extend(["**Members**", "", "| Name | Kind | Source |", "| --- | --- | --- |"]) + for member in visible_members: + lines.append( + f"| `{escape_code(member.name)}` | {member.kind} | `{escape_code(f'{member.source}:{member.line}')}` |" + ) + lines.append("") + for member in visible_members: + lines.extend([f"### {heading_text(member.name)}", "", "```python", member.signature, "```", ""]) + if member.doc: + lines.extend(render_doc_text(member.doc)) + lines.append("") + lines.extend([f"_Source: `{member.source}:{member.line}`_", ""]) + + lines.extend([f"_Source: `{symbol.source}:{symbol.line}`_", ""]) + return trim_blank_lines(lines) + + +def generate_java_api_pages() -> None: + out_dir = FERN_PAGES / "java_api" + out_dir.mkdir(parents=True, exist_ok=True) + classes = collect_java_classes() + + index_lines = [ + "# Java API Documentation", + "", + "These pages are generated from the Java source files in `java/cuvs-java/src/main`.", + "", + ] + by_package: dict[str, list[JavaClass]] = defaultdict(list) + for klass in classes: + by_package[klass.package].append(klass) + for package in sorted(by_package): + index_lines.extend([f"## `{package}`", ""]) + for klass in sorted(by_package[package], key=lambda item: item.name): + index_lines.append(f"- [{klass.name}]({api_doc_url('java_api', java_slug(klass))})") + index_lines.append("") + write_page(out_dir / "index.md", index_lines) + + for klass in classes: + lines = [ + *api_frontmatter(api_page_route("java_api", java_slug(klass))), + f"# {klass.name}", + "", + f"_Java package: `{klass.package}`_", + "", + "```java", + klass.signature, + "```", + "", + ] + lines.extend(render_javadoc(klass.doc)) + if klass.doc.summary: + lines.append("") + if klass.members: + lines.extend(["## Public Members", ""]) + for member in klass.members: + lines.extend([f"### {heading_text(member.name)}", "", "```java", member.signature, "```", ""]) + lines.extend(render_javadoc(member.doc)) + if member.doc.summary or member.doc.params or member.doc.returns: + lines.append("") + lines.extend([f"_Source: `{klass.source}:{member.line}`_", ""]) + lines.extend([f"_Source: `{klass.source}:{klass.line}`_", ""]) + write_page(out_dir / f"{api_page_route('java_api', java_slug(klass))}.md", lines) + + +def collect_java_classes() -> list[JavaClass]: + classes: list[JavaClass] = [] + for root in JAVA_SOURCE_DIRS: + for path in sorted(root.rglob("*.java")): + if "internal" in path.relative_to(root).parts or path.name == "module-info.java": + continue + klass = parse_java_class(path) + if klass is not None: + classes.append(klass) + classes.sort(key=lambda item: (item.package, item.name)) + return classes + + +def parse_java_class(path: Path) -> JavaClass | None: + text = path.read_text(encoding="utf-8") + package_match = re.search(r"^\s*package\s+([\w.]+);", text, re.MULTILINE) + package = package_match.group(1) if package_match else "" + type_match = PUBLIC_JAVA_TYPE_RE.search(text) + if not type_match: + return None + signature, class_line = java_signature_at(text, type_match.start()) + doc = parse_javadoc(comment_before(text, type_match.start())) + klass = JavaClass( + package=package, + name=type_match.group("name"), + kind=type_match.group("kind"), + signature=signature, + doc=doc, + source=path.relative_to(REPO_DIR).as_posix(), + line=class_line, + ) + klass.members = parse_java_members(text, klass.name) + return klass + + +def parse_java_members(text: str, class_name: str) -> list[JavaMember]: + members: list[JavaMember] = [] + for match in COMMENT_RE.finditer(text): + signature, line = java_signature_at(text, match.end()) + if "(" not in signature: + continue + if re.search(r"\b(class|interface|enum|record)\b", signature): + continue + if re.search(r"\b(if|for|while|switch|catch)\s*\(", signature): + continue + name_match = re.search(r"([A-Za-z_]\w*)\s*\(", signature) + if not name_match: + continue + name = name_match.group(1) + doc = parse_javadoc(match.group(0)) + members.append(JavaMember(name=name, signature=signature, doc=doc, line=line)) + return members + + +def clean_doxygen_comment(raw: str) -> str: + if raw.lstrip().startswith("///"): + lines = [re.sub(r"^\s*/// ?", "", line) for line in raw.splitlines()] + else: + body = raw + body = re.sub(r"^\s*/\*\* ?", "", body) + body = re.sub(r"\*/\s*$", "", body) + lines = [re.sub(r"^\s*\* ?", "", line) for line in body.splitlines()] + return "\n".join(line.rstrip() for line in lines).strip() + + +def find_doxygen_command(comment: str, command: str) -> str | None: + match = re.search(rf"[@\\]{command}\s+(.+)", comment) + return match.group(1).strip() if match else None + + +def split_command_payload(payload: str) -> tuple[str, str]: + parts = payload.split(None, 1) + if not parts: + return "", "" + return parts[0], parts[1].strip() if len(parts) > 1 else "" + + +def read_declaration_after(text: str, offset: int) -> tuple[str, int]: + idx = offset + line_no = text.count("\n", 0, offset) + 1 + while idx < len(text): + line_end = text.find("\n", idx) + if line_end == -1: + line_end = len(text) + line = text[idx:line_end] + stripped = line.strip() + if ( + not stripped + or stripped.startswith("#") + or stripped in {"extern \"C\" {", "{", "}", "public:", "private:", "protected:"} + ): + idx = line_end + 1 + line_no += 1 + continue + if stripped.startswith(("//", "/*")): + return "", line_no + break + + declaration_start = idx + depth = {"(": 0, "[": 0, "{": 0, "<": 0} + saw_brace = False + next_newline = text.find("\n", declaration_start) + if next_newline == -1: + next_newline = len(text) + first_declaration_line = text[declaration_start:next_newline].strip() + is_compound = bool( + re.match(r"(?:template\s*<[^>]+>\s*)?(?:typedef\s+)?(?:struct|class|enum)\b", first_declaration_line) + ) + while idx < len(text): + if text.startswith("//", idx): + next_line = text.find("\n", idx) + if next_line == -1: + idx = len(text) + else: + idx = next_line + continue + if text.startswith("/*", idx): + end_comment = text.find("*/", idx + 2) + idx = len(text) if end_comment == -1 else end_comment + 2 + continue + char = text[idx] + update_depth(depth, char) + if char == "{": + saw_brace = True + if char == "}" and saw_brace and not depth["{"] and not is_compound: + idx += 1 + break + if char == ";" and structural_depth_is_zero(depth): + idx += 1 + break + if char == "," and not any(depth.values()) and not saw_brace: + idx += 1 + break + idx += 1 + + declaration = text[declaration_start:idx].strip() + declaration = re.sub(r"///<.*", "", declaration) + declaration = "\n".join(line.rstrip() for line in declaration.splitlines()).strip() + if is_simple_member_declaration(declaration): + declaration = declaration.splitlines()[0].rstrip(",") + return declaration, line_no + + +def structural_depth_is_zero(depth: dict[str, int]) -> bool: + return not depth["("] and not depth["["] and not depth["{"] + + +def next_non_whitespace_is_comment(text: str, offset: int) -> bool: + idx = offset + while idx < len(text) and text[idx].isspace(): + idx += 1 + return text.startswith("/**", idx) or text.startswith("///", idx) + + +def is_simple_member_declaration(declaration: str) -> bool: + first_line = declaration.splitlines()[0].strip() if declaration else "" + if not first_line or re.search(r"\b(?:struct|class|enum)\b", first_line): + return False + if "(" in first_line: + return False + return "\n" in declaration and "\n}" in declaration + + +def parse_doxygen_entry(comment: str, declaration: str, source: str, line: int) -> DoxygenEntry: + summary = "" + details: list[str] = [] + params: list[DoxygenParam] = [] + tparams: list[DoxygenParam] = [] + returns = "" + code_blocks: list[tuple[str, list[str]]] = [] + active_code: tuple[str, list[str]] | None = None + active_param: DoxygenParam | None = None + + for raw_line in comment.splitlines(): + line_text = raw_line.strip() + if active_code is not None: + if re.match(r"[@\\]endcode", line_text): + code_blocks.append(active_code) + active_code = None + else: + active_code[1].append(raw_line.rstrip()) + continue + + code_match = re.match(r"[@\\]code(?:\{\.?([\w+-]+)\})?", line_text) + if code_match: + active_code = (code_match.group(1) or "", []) + active_param = None + continue + + if re.match(r"[@\\](?:defgroup|ingroup|addtogroup)\b", line_text) or line_text in { + "@{", + "\\{", + "@}", + "\\}", + }: + active_param = None + continue + + brief = consume_command(line_text, "brief") + if brief is not None: + summary = append_sentence(summary, clean_doxygen_text(brief)) + active_param = None + continue + + param_match = re.match( + r"[@\\]param(?:\[(?P[^\]]+)\])?\s+(?P\w+)\s*(?P.*)", + line_text, + ) + if param_match: + active_param = DoxygenParam( + param_match.group("name"), + clean_doxygen_text(param_match.group("desc")), + param_match.group("direction") or "", + ) + params.append(active_param) + continue + + tparam_match = re.match(r"[@\\]tparam\s+(\w+)\s*(.*)", line_text) + if tparam_match: + active_param = DoxygenParam( + tparam_match.group(1), clean_doxygen_text(tparam_match.group(2)) + ) + tparams.append(active_param) + continue + + return_text = consume_command(line_text, "return") or consume_command(line_text, "returns") + if return_text is not None: + returns = append_sentence(returns, clean_doxygen_text(return_text)) + active_param = None + continue + + if line_text.startswith(("@", "\\")): + active_param = None + continue + + if active_param is not None and (raw_line.startswith((" ", "\t")) or not line_text): + active_param.description = append_sentence( + active_param.description, clean_doxygen_text(line_text) + ) + continue + + details.append(clean_doxygen_text(raw_line.rstrip())) + active_param = None + + if active_code is not None: + code_blocks.append(active_code) + + details = trim_blank_lines(details) + if not summary and details: + summary = details.pop(0).strip() + + kind = parse_doxygen_kind(declaration) + name = parse_member_name(declaration) if kind == "member" else parse_entry_name(declaration) + return DoxygenEntry( + kind=kind, + name=name, + signature=normalize_entry_signature(declaration, kind), + summary=summary, + details=details, + params=params, + tparams=tparams, + returns=returns, + source=source, + line=line, + code_blocks=code_blocks, + ) + + +def consume_command(line: str, command: str) -> str | None: + match = re.match(rf"[@\\]{command}\b\s*(.*)", line) + return match.group(1).strip() if match else None + + +def clean_doxygen_text(text: str) -> str: + text = text.strip() + text = re.sub(r"[@\\](?:p|c|a)\s+([\w:]+)", r"`\1`", text) + text = re.sub( + r"[@\\]ref\s+([\w:]+)(?:\s+\"([^\"]+)\")?", + lambda match: match.group(2) or f"`{match.group(1)}`", + text, + ) + text = text.replace("@copydoc", "") + return text.strip() + + +def append_sentence(existing: str, addition: str) -> str: + addition = addition.strip() + if not addition: + return existing + if not existing: + return addition + return f"{existing} {addition}" + + +def parse_doxygen_kind(declaration: str) -> str: + if re.search(r"^\s*(?:typedef\s+)?(?:struct|class)\s+\w+", declaration) and ( + "{" in declaration or declaration.lstrip().startswith("typedef") + ): + return "struct" + if re.search(r"^\s*(?:typedef\s+)?enum(?:\s+class)?\b", declaration) and "{" in declaration: + return "enum" + if "(" in declaration and ")" in declaration: + return "function" + return "member" + + +def parse_entry_name(declaration: str) -> str: + struct_name = parse_struct_name(declaration) + if struct_name: + return struct_name + enum_name = parse_enum_name(declaration) + if enum_name: + return enum_name + before_paren = declaration.split("(", 1)[0].strip() + if "(" in declaration and before_paren: + return before_paren.split()[-1].split("::")[-1].strip("*&") + declaration_lines = [line.strip() for line in declaration.splitlines() if line.strip()] + first_line = declaration_lines[0] if declaration_lines else "" + name_line = declaration_lines[-1] if len(declaration_lines) > 1 else first_line + token_match = re.match(r"\s*(?:[\w:<>,]+\s+)*([A-Za-z_]\w*)\s*(?:=|;|,|$)", name_line) + return token_match.group(1) if token_match else first_line.strip() + + +def parse_member_name(declaration: str) -> str: + declaration = declaration.strip().rstrip(";").split("=", 1)[0].strip() + _, name = split_param_name(declaration) + return name or declaration + + +def parse_struct_name(declaration: str) -> str | None: + match = re.search(r"^\s*(?:typedef\s+)?(?:struct|class)\s+([A-Za-z_]\w*)", declaration) + return match.group(1) if match else None + + +def parse_enum_name(declaration: str) -> str | None: + match = re.search(r"^\s*(?:typedef\s+)?enum(?:\s+class)?\s+([A-Za-z_]\w*)", declaration) + if match: + return match.group(1) + typedef_match = re.search(r"}\s*([A-Za-z_]\w*)\s*;", declaration, re.DOTALL) + return typedef_match.group(1) if typedef_match else None + + +def infer_namespace(prefix: str) -> str: + matches = list(re.finditer(r"\bnamespace\s+([A-Za-z_][\w:]*)(?:\s*=\s*[^;]+)?\s*{", prefix)) + if not matches: + return "" + return matches[-1].group(1) + + +def normalize_entry_signature(declaration: str, kind: str) -> str: + signature = normalize_signature(declaration) + if kind == "function" and "{" in signature: + signature = signature.split("{", 1)[0].rstrip() + if not signature.endswith(";"): + signature = f"{signature};" + return signature + + +def normalize_signature(declaration: str) -> str: + declaration = re.sub(r"\n\s+", "\n", declaration.strip()) + return "\n".join(line.rstrip() for line in declaration.splitlines()).strip() + + +def compact_compound_signature(signature: str) -> str: + first_line = signature.splitlines()[0] + if "{" in first_line: + prefix = signature.split("{", 1)[0].strip() + suffix = signature.rsplit("}", 1)[1].strip() if "}" in signature else "" + if suffix: + return f"{prefix} {{ ... }} {suffix}".strip() + return f"{prefix} {{ ... }};" + for line in signature.splitlines(): + if "{" in line: + return f"{first_line} {{ ... }};" + return first_line + + +def parse_function_params(signature: str) -> list[FunctionParam]: + params_text = function_params_text(signature) + if not params_text or params_text.strip() == "void": + return [] + params: list[FunctionParam] = [] + for idx, raw_param in enumerate(split_top_level(params_text, ","), start=1): + param = raw_param.strip() + if not param: + continue + default = "" + if "=" in param: + left, default = split_default(param) + param = left.strip() + default = default.strip() + c_type, name = split_param_name(param) + params.append(FunctionParam(name=name or f"arg{idx}", c_type=c_type or param, default=default)) + return params + + +def function_params_text(signature: str) -> str: + start = signature.find("(") + if start == -1: + return "" + depth = 0 + for idx in range(start, len(signature)): + char = signature[idx] + if char == "(": + depth += 1 + elif char == ")": + depth -= 1 + if depth == 0: + return signature[start + 1 : idx] + return "" + + +def split_default(param: str) -> tuple[str, str]: + depth = {"(": 0, "[": 0, "{": 0, "<": 0} + for idx, char in enumerate(param): + update_depth(depth, char) + if char == "=" and not any(depth.values()): + return param[:idx], param[idx + 1 :] + return param, "" + + +def split_param_name(param: str) -> tuple[str, str]: + param = re.sub(r"\s+", " ", param.strip()) + param = re.sub(r"\[[^\]]*\]\s*$", "", param) + match = re.search(r"([A-Za-z_]\w*)\s*$", param) + if not match: + return param, "" + name = match.group(1) + c_type = param[: match.start()].rstrip() + c_type = c_type.rstrip("*& ").strip() + suffix = param[: match.start()][len(c_type) :] + if suffix.strip(): + c_type = f"{c_type}{suffix.strip()}".strip() + if not c_type: + return param, "" + return c_type, name + + +def parse_return_type(signature: str) -> str: + if ")" in signature and "->" in signature.split(")", 1)[1]: + tail = signature.split(")", 1)[1] + return tail.split("->", 1)[1].strip().rstrip(";") + before_paren = signature.split("(", 1)[0] + before_paren = re.sub(r"template\s*<[^>]+>", "", before_paren, flags=re.DOTALL) + before_paren = " ".join(before_paren.split()) + if not before_paren: + return "void" + tokens = before_paren.split() + if len(tokens) <= 1: + return "void" + return " ".join(tokens[:-1]).strip() + + +def parse_struct_members(entry: DoxygenEntry) -> list[DoxygenEntry]: + members: list[DoxygenEntry] = [] + for match in COMMENT_RE.finditer(entry.signature): + comment = clean_doxygen_comment(match.group(0)) + declaration, line = read_declaration_after(entry.signature, match.end()) + if not declaration or declaration.startswith(("public:", "private:", "protected:")): + continue + member = parse_doxygen_entry(comment, declaration, entry.source, entry.line + line - 1) + member.kind = "member" + members.append(member) + members.extend(parse_plain_struct_members(entry, {member.name for member in members})) + return members + + +def parse_plain_struct_members(entry: DoxygenEntry, existing_names: set[str]) -> list[DoxygenEntry]: + body = compound_body(entry.signature) + if not body: + return [] + members: list[DoxygenEntry] = [] + last_member: DoxygenEntry | None = None + pending_declaration = "" + pending_comment = "" + for raw_line in body.splitlines(): + stripped = raw_line.strip() + if not stripped or stripped in {"public:", "private:", "protected:"}: + continue + if stripped.startswith("//"): + continue + if stripped.startswith(("*", "/*", "*/")): + continue + declaration, inline_comment = split_inline_comment(raw_line) + declaration = re.sub(r"/\*.*?\*/", "", declaration).strip() + if not declaration and not pending_declaration: + continue + pending_declaration = f"{pending_declaration} {declaration}".strip() + pending_comment = append_sentence(pending_comment, clean_doxygen_text(inline_comment)) + if ";" not in pending_declaration: + continue + declaration = pending_declaration.split(";", 1)[0].rstrip(",").strip() + inline_comment = pending_comment + pending_declaration = "" + pending_comment = "" + if not declaration or "(" in declaration: + continue + declaration = declaration.split("=", 1)[0].strip() + if not declaration or declaration.startswith(("using ", "typedef ", "static_assert")): + continue + c_type, name = split_param_name(declaration) + if not name or name in existing_names: + continue + member = DoxygenEntry( + kind="member", + name=name, + signature=c_type or declaration, + summary=clean_doxygen_text(inline_comment), + source=entry.source, + line=entry.line, + ) + members.append(member) + existing_names.add(name) + last_member = member + return members + + +def compound_body(signature: str) -> str: + start = signature.find("{") + end = signature.rfind("}") + if start == -1 or end == -1 or end <= start: + return "" + return signature[start + 1 : end] + + +def split_inline_comment(line: str) -> tuple[str, str]: + if "//" not in line: + return line, "" + declaration, comment = line.split("//", 1) + return declaration, comment.lstrip("/<").strip() + + +def member_c_type(member: DoxygenEntry) -> str: + declaration = member.signature.rstrip(";").split("=", 1)[0].strip() + c_type, _ = split_param_name(declaration) + return c_type or declaration + + +def parse_enum_values(signature: str) -> list[dict[str, str]]: + body_match = re.search(r"{(?P.*)}", signature, re.DOTALL) + if not body_match: + return [] + values: list[dict[str, str]] = [] + for raw_value in split_top_level(body_match.group("body"), ","): + cleaned = re.sub(r"/\*.*?\*/|//.*", "", raw_value, flags=re.DOTALL).strip() + if not cleaned: + continue + name, _, value = cleaned.partition("=") + enum_name = name.strip() + if re.match(r"^[A-Za-z_]\w*$", enum_name): + item = {"name": enum_name} + if value.strip(): + item["value"] = value.strip() + values.append(item) + return values + + +def collect_python_signature(lines: list[str], start: int) -> tuple[str, int]: + chunks: list[str] = [] + depth = 0 + idx = start + while idx < len(lines): + stripped = lines[idx].strip() + chunks.append(stripped) + depth += stripped.count("(") + stripped.count("[") + stripped.count("{") + depth -= stripped.count(")") + stripped.count("]") + stripped.count("}") + if stripped.endswith(":") and depth <= 0: + break + idx += 1 + return " ".join(chunks), idx + + +def collect_python_assignment(lines: list[str], start: int) -> tuple[str, int]: + chunks = [lines[start].strip()] + depth = chunks[0].count("{") + chunks[0].count("[") + chunks[0].count("(") + depth -= chunks[0].count("}") + chunks[0].count("]") + chunks[0].count(")") + idx = start + while depth > 0 and idx + 1 < len(lines): + idx += 1 + stripped = lines[idx].strip() + chunks.append(stripped) + depth += stripped.count("{") + stripped.count("[") + stripped.count("(") + depth -= stripped.count("}") + stripped.count("]") + stripped.count(")") + return "\n".join(chunks), idx + + +def collect_python_docstring(lines: list[str], start: int) -> tuple[str, int]: + idx = start + while idx < len(lines) and not lines[idx].strip(): + idx += 1 + if idx >= len(lines): + return "", idx + stripped = lines[idx].strip() + quote = None + for candidate in ('"""', "'''"): + if stripped.startswith(candidate): + quote = candidate + break + if quote is None: + return "", idx + + content: list[str] = [] + remainder = stripped[len(quote) :] + if quote in remainder: + content.append(remainder.split(quote, 1)[0]) + return clean_python_docstring("\n".join(content)), idx + if remainder: + content.append(remainder) + idx += 1 + while idx < len(lines): + line = lines[idx] + if quote in line: + content.append(line.split(quote, 1)[0]) + return clean_python_docstring("\n".join(content)), idx + content.append(line) + idx += 1 + return clean_python_docstring("\n".join(content)), idx + + +def clean_python_docstring(doc: str) -> str: + doc = textwrap.dedent(doc).strip() + doc = doc.replace("\\\n", "") + doc = doc.replace("{resources_docstring}", "resources : cuvs.common.Resources, optional") + return strip_sphinx_roles(doc) + + +def strip_sphinx_roles(value: str) -> str: + return SPHINX_ROLE_RE.sub(lambda match: sphinx_role_label(match.group("target")), value) + + +def sphinx_role_label(target: str) -> str: + target = target.strip() + if target.startswith("~"): + target = target[1:] + if "<" in target and target.endswith(">"): + label, _, destination = target.rpartition("<") + return (label.strip() or destination[:-1].strip()).strip() + return target + + +NUMPY_FIELD_SECTIONS = { + "attributes", + "keyword arguments", + "other parameters", + "parameters", + "raises", + "returns", + "warns", + "warnings", + "yields", +} +NUMPY_SECTION_UNDERLINE_RE = re.compile(r"^-{3,}\s*$") +NUMPY_FIELD_RE = re.compile(r"^(?P[A-Za-z_*][A-Za-z0-9_*,\s]*?)\s*:\s*(?P.*)$") + + +def render_doc_text(doc: str) -> list[str]: + preamble, sections = split_numpy_doc_sections(doc.splitlines()) + if not sections: + return render_doc_lines(doc.splitlines()) + + lines: list[str] = [] + if preamble: + lines.extend(render_doc_lines(preamble)) + lines.append("") + for title, section_lines in sections: + if lines and lines[-1] != "": + lines.append("") + if title.lower() in NUMPY_FIELD_SECTIONS: + lines.extend(render_numpy_field_section(title, section_lines)) + else: + lines.extend([f"**{heading_text(title)}**", ""]) + lines.extend(render_doc_lines(section_lines)) + lines.append("") + return trim_blank_lines(lines) + + +def split_numpy_doc_sections(raw_lines: list[str]) -> tuple[list[str], list[tuple[str, list[str]]]]: + preamble: list[str] = [] + sections: list[tuple[str, list[str]]] = [] + current_title: str | None = None + current_lines: list[str] = [] + idx = 0 + while idx < len(raw_lines): + line = raw_lines[idx] + if ( + idx + 1 < len(raw_lines) + and line.strip() + and NUMPY_SECTION_UNDERLINE_RE.match(raw_lines[idx + 1].strip()) + ): + if current_title is None: + preamble = current_lines + else: + sections.append((current_title, current_lines)) + current_title = line.strip() + current_lines = [] + idx += 2 + continue + current_lines.append(line) + idx += 1 + + if current_title is None: + return current_lines, [] + sections.append((current_title, current_lines)) + return preamble, sections + + +def render_numpy_field_section(title: str, raw_lines: list[str]) -> list[str]: + fields = parse_numpy_fields(raw_lines) + if not fields: + lines = [f"**{heading_text(title)}**", ""] + lines.extend(render_doc_lines(raw_lines)) + return trim_blank_lines(lines) + + lines = [ + f"**{heading_text(title)}**", + "", + "| Name | Type | Description |", + "| --- | --- | --- |", + ] + for field in fields: + name = render_numpy_field_names(field["name"]) + field_type = f"`{escape_code(field['type'])}`" if field["type"] else "" + description = render_table_description(field["description"]) + lines.append(f"| {name} | {field_type} | {description} |") + return lines + + +def parse_numpy_fields(raw_lines: list[str]) -> list[dict[str, str]]: + fields: list[dict[str, str]] = [] + current: dict[str, object] | None = None + for raw_line in dedent_doc_lines(raw_lines): + stripped = raw_line.strip() + field_match = NUMPY_FIELD_RE.match(stripped) if stripped and indentation(raw_line) == 0 else None + if field_match: + if current is not None: + fields.append(finish_numpy_field(current)) + current = { + "name": field_match.group("name").strip(), + "type": field_match.group("type").strip(), + "description": [], + } + continue + if current is None: + if stripped: + return [] + continue + description = current["description"] + assert isinstance(description, list) + if stripped and not description and numpy_type_needs_continuation(str(current["type"])): + current["type"] = f"{current['type']} {stripped}" + else: + description.append(stripped) + if current is not None: + fields.append(finish_numpy_field(current)) + return fields + + +def finish_numpy_field(field: dict[str, object]) -> dict[str, str]: + description = field["description"] + assert isinstance(description, list) + return { + "name": str(field["name"]), + "type": str(field["type"]), + "description": "\n".join(description).strip(), + } + + +def numpy_type_needs_continuation(value: str) -> bool: + value = value.strip() + if value.endswith(","): + return True + depth = {"(": 0, "[": 0, "{": 0, "<": 0} + for char in value: + update_depth(depth, char) + return any(depth.values()) + + +def render_numpy_field_names(value: str) -> str: + names = [part.strip() for part in value.split(",") if part.strip()] + if not names: + return "" + return ", ".join(f"`{escape_code(name)}`" for name in names) + + +def render_table_description(value: str) -> str: + paragraphs: list[str] = [] + current: list[str] = [] + for raw_line in value.splitlines(): + stripped = raw_line.strip() + if not stripped: + if current: + paragraphs.append(" ".join(current)) + current = [] + continue + current.append(stripped) + if current: + paragraphs.append(" ".join(current)) + return "

".join(escape_text(paragraph) for paragraph in paragraphs) + + +def render_doc_lines(raw_lines: list[str]) -> list[str]: + lines = [] + in_code = False + for raw_line in dedent_doc_lines(raw_lines): + line = raw_line.rstrip() + stripped = line.strip() + if stripped.startswith(">>>") or stripped.startswith("..."): + if not in_code: + lines.extend(["```python"]) + in_code = True + lines.append(stripped) + continue + if in_code and stripped: + lines.append(line) + continue + if in_code: + lines.append("```") + in_code = False + lines.append(escape_text(stripped)) + if in_code: + lines.append("```") + return trim_blank_lines(lines) + + +def dedent_doc_lines(raw_lines: list[str]) -> list[str]: + return textwrap.dedent("\n".join(raw_lines)).splitlines() + + +def read_python_exports(init_path: Path) -> list[str]: + try: + tree = ast.parse(init_path.read_text(encoding="utf-8")) + except SyntaxError: + return [] + for node in tree.body: + if isinstance(node, ast.Assign): + for target in node.targets: + if isinstance(target, ast.Name) and target.id == "__all__": + try: + value = ast.literal_eval(node.value) + except Exception: + return [] + return [item for item in value if isinstance(item, str)] + return [] + + +def python_module_name(path: Path) -> str: + rel = path.relative_to(PYTHON_DIR) + if rel.name == "__init__.py": + parts = rel.parent.parts + else: + parts = rel.with_suffix("").parts + return ".".join(("cuvs", *parts)) + + +def python_group(module: str) -> str: + if module.startswith("cuvs.cluster"): + return "Cluster" + if module.startswith("cuvs.distance"): + return "Distance" + if module.startswith("cuvs.neighbors.mg"): + return "Multi-GPU Neighbors" + if module.startswith("cuvs.neighbors"): + return "Nearest Neighbors" + if module.startswith("cuvs.preprocessing"): + return "Preprocessing" + if module.startswith("cuvs.common"): + return "Common" + return "Other" + + +def group_python_pages(pages: list[PythonPage]) -> dict[str, list[PythonPage]]: + grouped: dict[str, list[PythonPage]] = defaultdict(list) + for page in pages: + grouped[python_group(page.module)].append(page) + return dict(sorted(grouped.items())) + + +def python_title(module: str) -> str: + leaf = module.split(".")[-1] + title = humanize_slug(leaf.replace("_", "-")) + replacements = { + "Mg": "Multi-GPU", + "Ivf": "IVF", + "Pq": "PQ", + "Pca": "PCA", + "Hnsw": "HNSW", + "Nn": "NN", + } + for old, new in replacements.items(): + title = re.sub(rf"\b{old}\b", new, title) + if module.startswith("cuvs.neighbors.mg."): + title = f"Multi-GPU {title}" + return title + + +def python_slug(module: str) -> str: + return slugify(module.removeprefix("cuvs.")) + + +def java_signature_at(text: str, start: int) -> tuple[str, int]: + line = text.count("\n", 0, start) + 1 + idx = start + depth = {"(": 0, "[": 0, "{": 0, "<": 0} + while idx < len(text): + char = text[idx] + update_depth(depth, char) + if char in "{;" and not depth["("] and not depth["["]: + signature = text[start:idx].strip() + signature = re.sub(r"\s+", " ", signature) + return signature, line + idx += 1 + signature = text[start:].splitlines()[0].strip() + return re.sub(r"\s+", " ", signature), line + + +def comment_before(text: str, start: int) -> str: + prefix = text[:start].rstrip() + match = re.search(r"/\*\*.*?\*/\s*(?:@\w+(?:\([^)]*\))?\s*)*$", prefix, re.DOTALL) + return match.group(0) if match else "" + + +def parse_javadoc(raw: str) -> JavaDoc: + raw = raw.strip() + if not raw: + return JavaDoc() + comment_match = re.search(r"/\*\*(.*?)\*/", raw, re.DOTALL) + if not comment_match: + return JavaDoc() + body = comment_match.group(1) + lines = [re.sub(r"^\s*\* ?", "", line).rstrip() for line in body.splitlines()] + doc = JavaDoc() + summary_lines: list[str] = [] + active: DoxygenParam | None = None + active_kind = "" + for line in lines: + stripped = clean_javadoc_text(line.strip()) + if not stripped: + if active is None: + summary_lines.append("") + continue + param_match = re.match(r"@param\s+(\w+)\s*(.*)", stripped) + if param_match: + active = DoxygenParam(param_match.group(1), param_match.group(2).strip()) + doc.params.append(active) + active_kind = "param" + continue + throws_match = re.match(r"@throws\s+([\w.]+)\s*(.*)", stripped) + if throws_match: + active = DoxygenParam(throws_match.group(1), throws_match.group(2).strip()) + doc.throws.append(active) + active_kind = "throws" + continue + returns_match = re.match(r"@return\s*(.*)", stripped) + if returns_match: + doc.returns = returns_match.group(1).strip() + active = None + active_kind = "return" + continue + if stripped.startswith("@"): + active = None + active_kind = "" + continue + if active is not None and active_kind in {"param", "throws"}: + active.description = append_sentence(active.description, stripped) + elif active_kind == "return": + doc.returns = append_sentence(doc.returns, stripped) + else: + summary_lines.append(stripped) + doc.summary = "\n".join(trim_blank_lines(summary_lines)).strip() + return doc + + +def clean_javadoc_text(text: str) -> str: + text = re.sub(r"\{@code\s+([^}]+)\}", r"`\1`", text) + text = re.sub(r"\{@link\s+([^}\s]+)(?:\s+([^}]+))?\}", lambda m: m.group(2) or f"`{m.group(1)}`", text) + text = re.sub(r"]*>(.*?)
", r"\1", text) + text = re.sub(r"", "", text) + text = re.sub(r"<[^>]+>", "", text) + return text.strip() + + +def render_javadoc(doc: JavaDoc) -> list[str]: + lines: list[str] = [] + if doc.summary: + lines.extend(escape_text(line) for line in doc.summary.splitlines()) + lines.append("") + if doc.params: + lines.extend(["**Parameters**", "", "| Name | Description |", "| --- | --- |"]) + for param in doc.params: + lines.append(f"| `{escape_code(param.name)}` | {escape_text(param.description)} |") + lines.append("") + if doc.returns: + lines.extend(["**Returns**", "", escape_text(doc.returns), ""]) + if doc.throws: + lines.extend(["**Throws**", "", "| Type | Description |", "| --- | --- |"]) + for param in doc.throws: + lines.append(f"| `{escape_code(param.name)}` | {escape_text(param.description)} |") + lines.append("") + return trim_blank_lines(lines) + + +def generate_rust_api_pages() -> None: + out_dir = FERN_PAGES / "rust_api" + out_dir.mkdir(parents=True, exist_ok=True) + pages = collect_rust_pages() + + index_lines = [ + "# Rust API Documentation", + "", + "These pages are generated from the Rust crate sources under `rust/cuvs/src`.", + "", + ] + for group, group_pages in group_rust_pages(pages).items(): + index_lines.extend([f"## {group}", ""]) + for page in group_pages: + index_lines.append(f"- [`{page.module}`]({api_doc_url('rust_api', page.slug)})") + index_lines.append("") + write_page(out_dir / "index.md", index_lines) + + for page in pages: + lines = [ + *api_frontmatter(api_page_route("rust_api", page.slug)), + f"# {page.title}", + "", + f"_Rust module: `{page.module}`_", + "", + f"_Source: `{page.source}`_", + "", + ] + if page.module_doc: + lines.extend(render_markdown_doc(page.module_doc)) + lines.append("") + for item in page.items: + lines.extend(render_rust_item(item)) + lines.append("") + write_page(out_dir / f"{api_page_route('rust_api', page.slug)}.md", lines) + + +def collect_rust_pages() -> list[RustPage]: + pages: list[RustPage] = [] + for path in sorted(RUST_SOURCE_DIR.rglob("*.rs")): + if path.name.endswith("_test.rs"): + continue + page = parse_rust_page(path) + if page.module_doc or page.items: + pages.append(page) + pages.sort(key=lambda page: page.module) + return pages + + +def parse_rust_page(path: Path) -> RustPage: + lines = path.read_text(encoding="utf-8").splitlines() + module = rust_module_name(path) + items = parse_rust_top_level_items(lines, path) + items_by_name = {item.name: item for item in items if item.kind in {"struct", "enum", "trait"}} + + for impl_type, methods, impl_line in parse_rust_impl_methods(lines, path): + if not methods: + continue + target = items_by_name.get(impl_type) + if target is not None: + target.members.extend(methods) + else: + items.append( + RustItem( + name=f"impl {impl_type}", + kind="impl", + signature=f"impl {impl_type}", + doc="", + source=path.relative_to(REPO_DIR).as_posix(), + line=impl_line, + members=methods, + ) + ) + + return RustPage( + module=module, + title=rust_title(module), + slug=rust_slug(module), + source=path.relative_to(REPO_DIR).as_posix(), + module_doc=collect_rust_module_doc(lines), + items=items, + ) + + +def parse_rust_top_level_items(lines: list[str], path: Path) -> list[RustItem]: + items: list[RustItem] = [] + pending_doc: list[str] = [] + pending_attributes: list[str] = [] + idx = 0 + while idx < len(lines): + stripped = lines[idx].strip() + + if stripped.startswith("///"): + pending_doc.append(stripped.removeprefix("///").lstrip()) + idx += 1 + continue + if stripped.startswith("#["): + pending_attributes.append(stripped) + idx += 1 + continue + if stripped.startswith("impl"): + _, signature_end, has_block = collect_rust_signature(lines, idx) + pending_doc = [] + pending_attributes = [] + idx = skip_rust_block(lines, signature_end) + 1 if has_block else signature_end + 1 + continue + if is_public_rust_declaration(stripped): + signature, signature_end, has_block = collect_rust_signature(lines, idx) + kind, name = parse_rust_item_kind_name(signature) + if kind and name: + items.append( + RustItem( + name=name, + kind=kind, + signature=signature, + doc=clean_rust_doc(pending_doc), + source=path.relative_to(REPO_DIR).as_posix(), + line=idx + 1, + attributes=pending_attributes, + ) + ) + pending_doc = [] + pending_attributes = [] + idx = skip_rust_block(lines, signature_end) + 1 if has_block else signature_end + 1 + continue + if stripped and not stripped.startswith("//"): + pending_doc = [] + pending_attributes = [] + idx += 1 + return items + + +def parse_rust_impl_methods(lines: list[str], path: Path) -> list[tuple[str, list[RustItem], int]]: + impls: list[tuple[str, list[RustItem], int]] = [] + idx = 0 + while idx < len(lines): + stripped = lines[idx].strip() + if not stripped.startswith("impl"): + idx += 1 + continue + signature, signature_end, has_block = collect_rust_signature(lines, idx) + if not has_block: + idx = signature_end + 1 + continue + block_end = skip_rust_block(lines, signature_end) + impl_type = parse_rust_impl_type(signature) + if impl_type: + methods = parse_rust_methods_in_impl(lines, signature_end + 1, block_end, path) + impls.append((impl_type, methods, idx + 1)) + idx = block_end + 1 + return impls + + +def parse_rust_methods_in_impl( + lines: list[str], + start: int, + end: int, + path: Path, +) -> list[RustItem]: + methods: list[RustItem] = [] + pending_doc: list[str] = [] + pending_attributes: list[str] = [] + idx = start + depth = 1 + while idx < end: + stripped = lines[idx].strip() + if depth == 1 and stripped.startswith("///"): + pending_doc.append(stripped.removeprefix("///").lstrip()) + idx += 1 + continue + if depth == 1 and stripped.startswith("#["): + pending_attributes.append(stripped) + idx += 1 + continue + if depth == 1 and is_public_rust_function(stripped): + signature, signature_end, has_block = collect_rust_signature(lines, idx) + name = parse_rust_function_name(signature) + if name: + methods.append( + RustItem( + name=name, + kind="method", + signature=signature, + doc=clean_rust_doc(pending_doc), + source=path.relative_to(REPO_DIR).as_posix(), + line=idx + 1, + attributes=pending_attributes, + ) + ) + pending_doc = [] + pending_attributes = [] + idx = skip_rust_block(lines, signature_end) + 1 if has_block else signature_end + 1 + continue + if depth == 1 and stripped and not stripped.startswith("//"): + pending_doc = [] + pending_attributes = [] + depth += rust_brace_delta(lines[idx]) + idx += 1 + return methods + + +def collect_rust_module_doc(lines: list[str]) -> str: + doc: list[str] = [] + saw_module_doc = False + in_header_comment = False + for raw_line in lines: + stripped = raw_line.strip() + if stripped.startswith("/*"): + in_header_comment = True + if in_header_comment: + if stripped.endswith("*/"): + in_header_comment = False + continue + if stripped.startswith("//!"): + doc.append(stripped.removeprefix("//!").lstrip()) + saw_module_doc = True + continue + if not stripped and not saw_module_doc: + continue + if saw_module_doc and not stripped: + doc.append("") + continue + if saw_module_doc: + break + if stripped.startswith("//"): + continue + break + return clean_rust_doc(doc) + + +def is_public_rust_declaration(stripped: str) -> bool: + if not stripped.startswith("pub ") or stripped.startswith("pub(crate)"): + return False + return bool(re.match(r"pub\s+(?:unsafe\s+|async\s+)?(?:fn|struct|enum|trait|type|use|mod)\b", stripped)) + + +def is_public_rust_function(stripped: str) -> bool: + if not stripped.startswith("pub ") or stripped.startswith("pub(crate)"): + return False + return bool(re.match(r"pub\s+(?:unsafe\s+|async\s+)?fn\b", stripped)) + + +def collect_rust_signature(lines: list[str], start: int) -> tuple[str, int, bool]: + chunks: list[str] = [] + paren_depth = 0 + bracket_depth = 0 + angle_depth = 0 + idx = start + while idx < len(lines): + stripped = lines[idx].strip() + chunks.append(stripped) + for char_idx, char in enumerate(stripped): + if char == "(": + paren_depth += 1 + elif char == ")": + paren_depth = max(paren_depth - 1, 0) + elif char == "[": + bracket_depth += 1 + elif char == "]": + bracket_depth = max(bracket_depth - 1, 0) + elif char == "<": + angle_depth += 1 + elif char == ">": + angle_depth = max(angle_depth - 1, 0) + elif char in "{;" and paren_depth == 0 and bracket_depth == 0 and angle_depth == 0: + prefix = stripped[: char_idx + 1].rstrip() + chunks[-1] = prefix + signature = normalize_rust_signature("\n".join(chunks)) + return signature, idx, char == "{" + idx += 1 + return normalize_rust_signature("\n".join(chunks)), idx - 1, False + + +def normalize_rust_signature(signature: str) -> str: + signature = "\n".join(line.rstrip() for line in signature.splitlines()) + signature = re.sub(r"\s+\{$", " {", signature) + if signature.endswith("{"): + signature = f"{signature[:-1].rstrip()} {{ ... }}" + return signature.strip() + + +def skip_rust_block(lines: list[str], start: int) -> int: + depth = 0 + entered = False + idx = start + while idx < len(lines): + line = strip_rust_line_for_braces(lines[idx]) + for char in line: + if char == "{": + depth += 1 + entered = True + elif char == "}": + depth = max(depth - 1, 0) + if entered and depth == 0: + return idx + idx += 1 + return min(start, len(lines) - 1) + + +def rust_brace_delta(line: str) -> int: + clean = strip_rust_line_for_braces(line) + return clean.count("{") - clean.count("}") + + +def strip_rust_line_for_braces(line: str) -> str: + line = re.sub(r'"(?:\\.|[^"\\])*"', '""', line) + line = re.sub(r"'(?:\\.|[^'\\])'", "''", line) + return line.split("//", 1)[0] + + +def parse_rust_item_kind_name(signature: str) -> tuple[str, str]: + first_line = signature.splitlines()[0].strip() + match = re.match(r"pub\s+(?Pstruct|enum|trait|type|mod)\s+(?P[A-Za-z_]\w*)", first_line) + if match: + return match.group("kind"), match.group("name") + if re.match(r"pub\s+(?:unsafe\s+|async\s+)?fn\b", first_line): + return "function", parse_rust_function_name(signature) + use_match = re.match(r"pub\s+use\s+(.+?);?$", signature.replace("\n", " ")) + if use_match: + return "reexport", use_match.group(1).strip() + return "", "" + + +def parse_rust_function_name(signature: str) -> str: + match = re.search(r"\bfn\s+([A-Za-z_]\w*)", signature) + return match.group(1) if match else "" + + +def parse_rust_impl_type(signature: str) -> str: + signature = signature.split("{", 1)[0].replace("\n", " ").strip() + signature = re.sub(r"^impl\s*<[^>]+>\s*", "impl ", signature) + if " for " in signature: + candidate = signature.rsplit(" for ", 1)[1].strip() + else: + candidate = re.sub(r"^impl\s+", "", signature).strip() + candidate = re.sub(r"<.*", "", candidate).strip() + candidate = candidate.split("::")[-1].strip() + match = re.match(r"([A-Za-z_]\w*)", candidate) + return match.group(1) if match else "" + + +def clean_rust_doc(lines: list[str]) -> str: + return "\n".join(line.rstrip() for line in trim_blank_lines(lines)).strip() + + +def render_rust_item(item: RustItem) -> list[str]: + lines = [f"## {heading_text(item.name)}", ""] + signature_lines = [*item.attributes, item.signature] if item.attributes else [item.signature] + lines.extend(["```rust", "\n".join(signature_lines), "```", ""]) + if item.doc: + lines.extend(render_markdown_doc(item.doc)) + lines.append("") + if item.members: + lines.extend(["**Methods**", "", "| Name | Source |", "| --- | --- |"]) + for member in item.members: + lines.append(f"| `{escape_code(member.name)}` | `{escape_code(f'{member.source}:{member.line}')}` |") + lines.append("") + for member in item.members: + lines.extend([f"### {heading_text(member.name)}", ""]) + member_signature = [*member.attributes, member.signature] if member.attributes else [member.signature] + lines.extend(["```rust", "\n".join(member_signature), "```", ""]) + if member.doc: + lines.extend(render_markdown_doc(member.doc)) + lines.append("") + lines.extend([f"_Source: `{member.source}:{member.line}`_", ""]) + lines.extend([f"_Source: `{item.source}:{item.line}`_", ""]) + return trim_blank_lines(lines) + + +def group_rust_pages(pages: list[RustPage]) -> dict[str, list[RustPage]]: + grouped: dict[str, list[RustPage]] = defaultdict(list) + for page in pages: + grouped[rust_group(page.module)].append(page) + return dict(sorted(grouped.items())) + + +def rust_group(module: str) -> str: + if "::cluster" in module: + return "Cluster" + if "::distance" in module: + return "Distance" + if any(token in module for token in ("::brute_force", "::cagra", "::ivf_flat", "::ivf_pq", "::vamana")): + return "Nearest Neighbors" + return "Core" + + +def rust_module_name(path: Path) -> str: + rel = path.relative_to(RUST_SOURCE_DIR) + if rel.name == "lib.rs": + parts: tuple[str, ...] = () + elif rel.name == "mod.rs": + parts = rel.parent.parts + else: + parts = rel.with_suffix("").parts + return "::".join(("cuvs", *parts)) + + +def rust_title(module: str) -> str: + if module == "cuvs": + return "cuVS Rust Crate" + return f"{humanize_slug(module.removeprefix('cuvs::').replace('::', '-').replace('_', '-'))} Module" + + +def rust_slug(module: str) -> str: + return slugify(module.replace("::", "-")) + + +def generate_go_api_pages() -> None: + out_dir = FERN_PAGES / "go_api" + out_dir.mkdir(parents=True, exist_ok=True) + pages = collect_go_pages() + + index_lines = [ + "# Go API Documentation", + "", + "These pages are generated from the Go source files under `go`.", + "", + ] + for page in pages: + index_lines.append(f"- [`{page.package}`]({api_doc_url('go_api', page.slug)})") + write_page(out_dir / "index.md", index_lines) + + for page in pages: + lines = [ + *api_frontmatter(api_page_route("go_api", page.slug)), + f"# {page.title}", + "", + f"_Go package: `{page.package}`_", + "", + f"_Sources: `{escape_code(', '.join(page.sources))}`_", + "", + ] + for section, items in group_go_items(page.items).items(): + lines.extend([f"## {section}", ""]) + for item in items: + lines.extend(render_go_item(item)) + lines.append("") + write_page(out_dir / f"{api_page_route('go_api', page.slug)}.md", lines) + + +def collect_go_pages() -> list[GoPage]: + by_package: dict[str, list[GoItem]] = defaultdict(list) + sources: dict[str, set[str]] = defaultdict(set) + for path in sorted(GO_SOURCE_DIR.rglob("*.go")): + if path.name.endswith("_test.go"): + continue + package, items = parse_go_file(path) + if not package: + continue + by_package[package].extend(items) + sources[package].add(path.parent.relative_to(REPO_DIR).as_posix()) + + pages = [ + GoPage( + package=package, + title=f"{go_package_title(package)} Package", + slug=go_slug(package), + sources=sorted(sources[package]), + items=sorted(items, key=lambda item: (go_kind_order(item.kind), item.name, item.line)), + ) + for package, items in by_package.items() + if items + ] + pages.sort(key=lambda page: page.package) + return pages + + +def parse_go_file(path: Path) -> tuple[str, list[GoItem]]: + lines = path.read_text(encoding="utf-8").splitlines() + package = "" + items: list[GoItem] = [] + pending_doc: list[str] = [] + idx = 0 + while idx < len(lines): + stripped = lines[idx].strip() + if not package: + package_match = re.match(r"package\s+([A-Za-z_]\w*)", stripped) + if package_match: + package = package_match.group(1) + if stripped.startswith("//"): + pending_doc.append(stripped.removeprefix("//").lstrip()) + idx += 1 + continue + if stripped.startswith("/*"): + block, end_idx = collect_go_block_comment(lines, idx) + pending_doc.extend(block) + idx = end_idx + 1 + continue + if is_go_declaration(stripped): + signature, end_idx = collect_go_declaration(lines, idx) + kind, name, receiver = parse_go_item_kind_name(signature, pending_doc) + if name and is_go_exported_item(kind, name, signature): + items.append( + GoItem( + name=name, + kind=kind, + signature=signature, + doc=clean_go_doc(pending_doc), + source=path.relative_to(REPO_DIR).as_posix(), + line=idx + 1, + receiver=receiver, + ) + ) + pending_doc = [] + idx = end_idx + 1 + continue + if stripped: + pending_doc = [] + idx += 1 + return package, items + + +def collect_go_block_comment(lines: list[str], start: int) -> tuple[list[str], int]: + body: list[str] = [] + idx = start + while idx < len(lines): + line = lines[idx] + stripped = line.strip() + if idx == start: + stripped = stripped.removeprefix("/*") + if "*/" in stripped: + body.append(stripped.split("*/", 1)[0].strip(" *")) + return body, idx + body.append(stripped.strip(" *")) + idx += 1 + return body, idx - 1 + + +def is_go_declaration(stripped: str) -> bool: + return bool(re.match(r"(?:func|type|const|var)\b", stripped)) + + +def collect_go_declaration(lines: list[str], start: int) -> tuple[str, int]: + first = lines[start].strip() + if first.startswith("func "): + return collect_go_function_signature(lines, start) + if re.match(r"(?:const|var|type)\s*\(", first): + return collect_go_paren_block(lines, start) + if " struct {" in first or first.endswith(" struct {") or " interface {" in first: + signature, end_idx = collect_go_brace_block(lines, start) + return compact_go_type_signature(signature), end_idx + return first, start + + +def collect_go_function_signature(lines: list[str], start: int) -> tuple[str, int]: + chunks: list[str] = [] + paren_depth = 0 + bracket_depth = 0 + idx = start + while idx < len(lines): + stripped = lines[idx].strip() + chunks.append(stripped) + for char_idx, char in enumerate(stripped): + if char == "(": + paren_depth += 1 + elif char == ")": + paren_depth = max(paren_depth - 1, 0) + elif char == "[": + bracket_depth += 1 + elif char == "]": + bracket_depth = max(bracket_depth - 1, 0) + elif char == "{" and paren_depth == 0 and bracket_depth == 0: + chunks[-1] = stripped[:char_idx].rstrip() + return normalize_go_signature("\n".join(chunks)), idx + idx += 1 + return normalize_go_signature("\n".join(chunks)), idx - 1 + + +def collect_go_paren_block(lines: list[str], start: int) -> tuple[str, int]: + chunks = [] + depth = 0 + idx = start + while idx < len(lines): + line = lines[idx].rstrip() + chunks.append(line.strip()) + depth += line.count("(") - line.count(")") + if idx > start and depth <= 0: + break + idx += 1 + return "\n".join(chunks), idx + + +def collect_go_brace_block(lines: list[str], start: int) -> tuple[str, int]: + chunks = [] + depth = 0 + idx = start + while idx < len(lines): + line = lines[idx].rstrip() + chunks.append(line.strip()) + depth += line.count("{") - line.count("}") + if idx > start and depth <= 0: + break + idx += 1 + return "\n".join(chunks), idx + + +def compact_go_type_signature(signature: str) -> str: + first_line = signature.splitlines()[0] + if first_line.endswith("{"): + return f"{first_line[:-1].rstrip()} {{ ... }}" + return signature + + +def normalize_go_signature(signature: str) -> str: + return "\n".join(line.rstrip() for line in signature.splitlines()).strip() + + +def parse_go_item_kind_name(signature: str, doc_lines: list[str]) -> tuple[str, str, str]: + first_line = signature.splitlines()[0].strip() + func_match = re.match(r"func\s+(?:\((?P[^)]+)\)\s*)?(?P[A-Za-z_]\w*)", first_line) + if func_match: + receiver = go_receiver_type(func_match.group("receiver") or "") + name = func_match.group("name") + if receiver: + return "method", f"{receiver}.{name}", receiver + return "function", name, "" + type_match = re.match(r"type\s+(?P[A-Za-z_]\w*)", first_line) + if type_match: + return "type", type_match.group("name"), "" + var_match = re.match(r"var\s+(?P[A-Za-z_]\w*)", first_line) + if var_match: + return "variable", var_match.group("name"), "" + const_match = re.match(r"const\s+(?P[A-Za-z_]\w*)", first_line) + if const_match: + return "constant", const_match.group("name"), "" + if first_line == "const (": + return "constant", go_block_heading(doc_lines, go_block_export_name(signature, "Constants")), "" + if first_line == "var (": + return "variable", go_block_heading(doc_lines, go_block_export_name(signature, "Variables")), "" + return "", "", "" + + +def go_receiver_type(receiver: str) -> str: + receiver = receiver.strip() + if not receiver: + return "" + parts = receiver.split() + candidate = parts[-1] if parts else receiver + candidate = candidate.lstrip("*") + candidate = re.sub(r"\[.*", "", candidate) + return candidate + + +def go_block_heading(doc_lines: list[str], fallback: str) -> str: + doc = clean_go_doc(doc_lines) + first = doc.splitlines()[0] if doc else "" + if first and len(first) <= 64: + return humanize_slug(slugify(first)) + return fallback + + +def go_block_export_name(signature: str, fallback: str) -> str: + for line in signature.splitlines()[1:]: + match = re.match(r"([A-Z]\w*)\s+([A-Z]\w*)\b", line.strip()) + if match: + return f"{match.group(2)} {fallback}" + match = re.match(r"([A-Z]\w*)\b", line.strip()) + if match: + return f"{match.group(1)} {fallback}" + return fallback + + +def is_go_exported_item(kind: str, name: str, signature: str) -> bool: + if kind in {"constant", "variable"} and name in {"Constants", "Variables"}: + return go_block_has_exported_name(signature) + simple_name = name.split(".")[-1] + return bool(simple_name and simple_name[0].isupper()) + + +def go_block_has_exported_name(signature: str) -> bool: + for line in signature.splitlines()[1:]: + match = re.match(r"([A-Za-z_]\w*)", line.strip()) + if match and match.group(1)[0].isupper(): + return True + return False + + +def clean_go_doc(lines: list[str]) -> str: + return "\n".join(line.rstrip() for line in trim_blank_lines(lines)).strip() + + +def group_go_items(items: list[GoItem]) -> dict[str, list[GoItem]]: + labels = { + "constant": "Constants", + "variable": "Variables", + "type": "Types", + "function": "Functions", + "method": "Methods", + } + grouped: dict[str, list[GoItem]] = defaultdict(list) + for item in items: + grouped[labels.get(item.kind, "Other")].append(item) + return {labels[kind]: grouped[labels[kind]] for kind in ["constant", "variable", "type", "function", "method"] if grouped.get(labels[kind])} + + +def go_kind_order(kind: str) -> int: + return {"constant": 0, "variable": 1, "type": 2, "function": 3, "method": 4}.get(kind, 9) + + +def render_go_item(item: GoItem) -> list[str]: + lines = [f"### {heading_text(item.name)}", "", "```go", item.signature, "```", ""] + if item.doc: + lines.extend(render_markdown_doc(item.doc)) + lines.append("") + lines.extend([f"_Source: `{item.source}:{item.line}`_", ""]) + return trim_blank_lines(lines) + + +def go_package_title(package: str) -> str: + if package == "cuvs": + return "cuVS" + return humanize_slug(package.replace("_", "-")) + + +def go_slug(package: str) -> str: + return slugify(package) + + +def update_api_navigation() -> None: + docs_yml = REPO_DIR / "fern" / "docs.yml" + text = docs_yml.read_text(encoding="utf-8") + start_marker = ' - section: "API Reference"\n' + end_marker = ' - section: "Advanced Topics"\n' + start = text.find(start_marker) + end = text.find(end_marker, start) + if start == -1 or end == -1: + raise RuntimeError("Could not find API Reference navigation block in fern/docs.yml") + + lines = [ + ' - section: "API Reference"', + ' path: "./pages/api_docs.md"', + " contents:", + ] + for title, directory, _, _, _ in API_NAV_SECTIONS: + lines.extend( + [ + f' - section: "{title}"', + f' path: "./pages/{directory}/index.md"', + " contents:", + ] + ) + for slug in read_api_index_slugs(FERN_PAGES / directory / "index.md"): + lines.extend( + [ + f' - page: "{api_nav_page_title(directory, slug)}"', + f' path: "./pages/{directory}/{api_page_route(directory, slug)}.md"', + ] + ) + + replacement = "\n".join(lines) + "\n" + docs_yml.write_text(text[:start] + replacement + text[end:], encoding="utf-8") + print("Updated fern/docs.yml API Reference navigation") + + +def read_api_index_slugs(index_path: Path) -> list[str]: + slugs: list[str] = [] + route_prefix = api_route_prefix(index_path.parent.name) + for line in index_path.read_text(encoding="utf-8").splitlines(): + match = re.search(rf"\]\((?:\./|/api-reference/{re.escape(route_prefix)}-)([^)#]+)", line) + if match: + slugs.append(match.group(1).removesuffix(".md")) + return slugs + + +def api_doc_url(directory: str, slug: str) -> str: + return f"/api-reference/{api_page_route(directory, slug)}" + + +def api_page_route(directory: str, slug: str) -> str: + return f"{api_route_prefix(directory)}-{slug}" + + +def api_frontmatter(route: str) -> list[str]: + return ["---", f"slug: api-reference/{route}", "---", ""] + + +def api_nav_page_title(directory: str, slug: str) -> str: + return api_route_title(slug) + + +def api_section_route(directory: str) -> str: + for _, api_directory, route, _, _ in API_NAV_SECTIONS: + if api_directory == directory: + return route + raise ValueError(f"Unknown API docs directory: {directory}") + + +def api_title_prefix(directory: str) -> str: + for _, api_directory, _, title_prefix, _ in API_NAV_SECTIONS: + if api_directory == directory: + return title_prefix + raise ValueError(f"Unknown API docs directory: {directory}") + + +def api_route_prefix(directory: str) -> str: + for _, api_directory, _, _, route_prefix in API_NAV_SECTIONS: + if api_directory == directory: + return route_prefix + raise ValueError(f"Unknown API docs directory: {directory}") + + +def api_route_title(slug: str) -> str: + replacements = { + "api": "API", + "cpp": "C++", + "cuvs": "cuVS", + "gpu": "GPU", + "hnsw": "HNSW", + "ivf": "IVF", + "kmeans": "Kmeans", + "mg": "Multi GPU", + "nn": "NN", + "pca": "PCA", + "pq": "PQ", + "vq": "VQ", + } + words = [] + for word in slug.split("-"): + words.append(replacements.get(word, word.capitalize())) + return " ".join(words).replace('"', '\\"') + + +def render_markdown_doc(doc: str) -> list[str]: + lines: list[str] = [] + in_code = False + for raw_line in doc.splitlines(): + line = raw_line.rstrip() + if line.strip().startswith("```"): + lines.append(line) + in_code = not in_code + continue + if in_code: + lines.append(line) + else: + heading_match = re.match(r"^(#{1,6})\s+(.+)", line) + if heading_match: + level = min(len(heading_match.group(1)) + 3, 6) + lines.append(f"{'#' * level} {escape_text(heading_match.group(2))}") + else: + lines.append(escape_text(line)) + return trim_blank_lines(lines) + + +def source_line(entry: DoxygenEntry) -> str: + return f"_Source: `{entry.source}:{entry.line}`_" + + +def render_param_table(params: list[dict[str, str]], include_direction: bool) -> list[str]: + headers = ["Name"] + if include_direction: + headers.append("Direction") + headers.extend(["Type", "Description"]) + lines = ["| " + " | ".join(headers) + " |", "| " + " | ".join(["---"] * len(headers)) + " |"] + for param in params: + row = [f"`{escape_code(param.get('name', ''))}`"] + if include_direction: + row.append(escape_text(param.get("direction", ""))) + row.append(f"`{escape_code(param.get('type', ''))}`") + description = param.get("description", "") + if param.get("default"): + description = f"{description} Default: `{param['default']}`.".strip() + row.append(escape_text(description)) + lines.append("| " + " | ".join(row) + " |") + return lines + + +def native_page_slug(source: str) -> str: + source = re.sub(r"^(?:c|cpp)/include/cuvs/", "", source) + source = re.sub(r"\.(?:h|hpp|cuh)$", "", source) + return slugify(source) + + +def native_page_title(source: str) -> str: + source = re.sub(r"^(?:c|cpp)/include/cuvs/", "", source) + source = re.sub(r"\.(?:h|hpp|cuh)$", "", source) + parts = source.split("/") + leaf = parts[-1] + title = humanize_slug(leaf.replace("_", "-")) + replacements = { + "C Api": "C API", + "Ivf": "IVF", + "Pq": "PQ", + "Pca": "PCA", + "Hnsw": "HNSW", + "Nn": "NN", + "Mg": "Multi-GPU", + "Kmeans": "K-Means", + } + for old, new in replacements.items(): + title = title.replace(old, new) + if len(parts) > 1 and parts[-2] not in {"core"}: + category = humanize_slug(parts[-2].replace("_", "-")) + if title.lower() not in category.lower(): + title = f"{title}" + return title + + +def humanize_slug(value: str) -> str: + return " ".join(word.capitalize() for word in re.split(r"[-_/]+", value) if word) + + +def java_slug(klass: JavaClass) -> str: + return slugify(f"{klass.package}.{klass.name}") + + +def slugify(value: str) -> str: + return re.sub(r"[^a-z0-9]+", "-", value.lower()).strip("-") or "api" + + +def indentation(line: str) -> int: + return len(line) - len(line.lstrip(" ")) + + +def split_top_level(text: str, sep: str) -> list[str]: + chunks: list[str] = [] + depth = {"(": 0, "[": 0, "{": 0, "<": 0} + start = 0 + for idx, char in enumerate(text): + update_depth(depth, char) + if char == sep and not any(depth.values()): + chunks.append(text[start:idx]) + start = idx + 1 + chunks.append(text[start:]) + return chunks + + +def update_depth(depth: dict[str, int], char: str) -> None: + if char in "([{<": + depth[char] += 1 + elif char == ")": + depth["("] = max(depth["("] - 1, 0) + elif char == "]": + depth["["] = max(depth["["] - 1, 0) + elif char == "}": + depth["{"] = max(depth["{"] - 1, 0) + elif char == ">": + depth["<"] = max(depth["<"] - 1, 0) + + +def escape_code(value: str) -> str: + return str(value).replace("|", "\\|").replace("`", "\\`").replace("\n", " ") + + +def escape_text(value: str) -> str: + return ( + str(value) + .replace("|", "\\|") + .replace("<", "<") + .replace(">", ">") + .replace("{", "\\{") + .replace("}", "\\}") + .replace("\n", " ") + ) + + +def heading_text(value: str) -> str: + return escape_text(value).replace("`", "\\`").strip() or "API" + + +def trim_blank_lines(lines: list[str]) -> list[str]: + lines = list(lines) + while lines and not str(lines[0]).strip(): + lines.pop(0) + while lines and not str(lines[-1]).strip(): + lines.pop() + return lines + + +def write_page(path: Path, lines: list[str]) -> None: + path.parent.mkdir(parents=True, exist_ok=True) + path.write_text("\n".join(trim_blank_lines(lines)).rstrip() + "\n", encoding="utf-8") + print(f"Wrote {path.relative_to(REPO_DIR)}") + + +if __name__ == "__main__": + raise SystemExit(main()) From 82655fdcb4049242a287dff262307137e493f524 Mon Sep 17 00:00:00 2001 From: "Corey J. Nolet" Date: Thu, 7 May 2026 00:17:12 -0400 Subject: [PATCH 002/129] Fix docs style checks --- ci/release/update-version.sh | 2 +- fern/scripts/generate_api_reference.py | 728 ++++++++++++++++++++----- 2 files changed, 579 insertions(+), 151 deletions(-) diff --git a/ci/release/update-version.sh b/ci/release/update-version.sh index 25d3ffc4ef..ef8ac06d24 100755 --- a/ci/release/update-version.sh +++ b/ci/release/update-version.sh @@ -1,5 +1,5 @@ #!/bin/bash -# SPDX-FileCopyrightText: Copyright (c) 2020-2025, NVIDIA CORPORATION. +# SPDX-FileCopyrightText: Copyright (c) 2020-2026, NVIDIA CORPORATION. # SPDX-License-Identifier: Apache-2.0 ######################## # CUVS Version Updater # diff --git a/fern/scripts/generate_api_reference.py b/fern/scripts/generate_api_reference.py index 2e2f6647da..d8af2e8f5c 100755 --- a/fern/scripts/generate_api_reference.py +++ b/fern/scripts/generate_api_reference.py @@ -33,11 +33,41 @@ ] API_NAV_SECTIONS = [ ("C API Documentation", "c_api", "c-api-documentation", "C API", "c-api"), - ("Cpp API Documentation", "cpp_api", "cpp-api-documentation", "C++ API", "cpp-api"), - ("Python API Documentation", "python_api", "python-api-documentation", "Python API", "python-api"), - ("Java API Documentation", "java_api", "java-api-documentation", "Java API", "java-api"), - ("Rust API Documentation", "rust_api", "rust-api-documentation", "Rust API", "rust-api"), - ("Go API Documentation", "go_api", "go-api-documentation", "Go API", "go-api"), + ( + "Cpp API Documentation", + "cpp_api", + "cpp-api-documentation", + "C++ API", + "cpp-api", + ), + ( + "Python API Documentation", + "python_api", + "python-api-documentation", + "Python API", + "python-api", + ), + ( + "Java API Documentation", + "java_api", + "java-api-documentation", + "Java API", + "java-api", + ), + ( + "Rust API Documentation", + "rust_api", + "rust-api-documentation", + "Rust API", + "rust-api", + ), + ( + "Go API Documentation", + "go_api", + "go-api-documentation", + "Go API", + "go-api", + ), ] COMMENT_RE = re.compile(r"/\*\*.*?\*/|(?:///[^\n]*(?:\n|$))+", re.DOTALL) @@ -226,32 +256,46 @@ def _parse_header(self, path: Path) -> None: group_name = "" if group_command: group_name, group_title = split_command_payload(group_command) - group = self.groups.setdefault(group_name, DoxygenGroup(group_name)) + group = self.groups.setdefault( + group_name, DoxygenGroup(group_name) + ) if group_kind == "defgroup" and group_title: group.title = group_title closes_group = bool(re.search(r"(^|\s)[@\\]}", comment)) opens_group = bool(re.search(r"(^|\s)[@\\]{", comment)) explicit_groups = re.findall(r"[@\\]ingroup\s+([\w:.-]+)", comment) - candidate_groups = list(dict.fromkeys([*explicit_groups, *current_groups])) + candidate_groups = list( + dict.fromkeys([*explicit_groups, *current_groups]) + ) if not group_command and not closes_group: - declaration, decl_line = read_declaration_after(text, match.end()) + declaration, decl_line = read_declaration_after( + text, match.end() + ) if declaration: - entry = parse_doxygen_entry(comment, declaration, rel_path, decl_line) + entry = parse_doxygen_entry( + comment, declaration, rel_path, decl_line + ) if entry.kind == "member": continue self._qualify_function(entry, text[: match.start()]) for candidate in candidate_groups: - self.groups.setdefault(candidate, DoxygenGroup(candidate)).entries.append(entry) + self.groups.setdefault( + candidate, DoxygenGroup(candidate) + ).entries.append(entry) self._index_compound(entry, text[: match.start()]) if group_command and opens_group and group_name: current_groups.append(group_name) if not next_non_whitespace_is_comment(text, match.end()): - declaration, decl_line = read_declaration_after(text, match.end()) + declaration, decl_line = read_declaration_after( + text, match.end() + ) if declaration: - entry = parse_doxygen_entry(comment, declaration, rel_path, decl_line) + entry = parse_doxygen_entry( + comment, declaration, rel_path, decl_line + ) self._qualify_function(entry, text[: match.start()]) if not entry.summary and self.groups[group_name].title: entry.summary = self.groups[group_name].title @@ -264,7 +308,9 @@ def _index_compound(self, entry: DoxygenEntry, prefix: str) -> None: namespace = infer_namespace(prefix) struct_name = parse_struct_name(entry.signature) if struct_name: - fq_name = f"{namespace}::{struct_name}" if namespace else struct_name + fq_name = ( + f"{namespace}::{struct_name}" if namespace else struct_name + ) entry.kind = "struct" entry.name = fq_name self.structs[fq_name] = entry @@ -337,7 +383,9 @@ def generate_native_api_pages(index: DoxygenHeaderIndex, api: str) -> None: "", ] for page in pages: - index_lines.append(f"- [{page.title}]({api_doc_url(directory, page.slug)})") + index_lines.append( + f"- [{page.title}]({api_doc_url(directory, page.slug)})" + ) write_page(out_dir / "index.md", index_lines) language = "c" if api == "c" else "cpp" @@ -352,26 +400,44 @@ def generate_native_api_pages(index: DoxygenHeaderIndex, api: str) -> None: for group in page.groups: lines.extend(render_native_group(group, language)) lines.append("") - write_page(out_dir / f"{api_page_route(directory, page.slug)}.md", lines) + write_page( + out_dir / f"{api_page_route(directory, page.slug)}.md", lines + ) -def collect_native_pages(index: DoxygenHeaderIndex, api: str) -> list[NativePage]: +def collect_native_pages( + index: DoxygenHeaderIndex, api: str +) -> list[NativePage]: prefix = "c/include/" if api == "c" else "cpp/include/" pages: dict[str, NativePage] = {} for group in index.groups.values(): - entries = [entry for entry in group.entries if entry.source.startswith(prefix)] + entries = [ + entry for entry in group.entries if entry.source.startswith(prefix) + ] if not entries: continue source = sorted({entry.source for entry in entries})[0] slug = native_page_slug(source) - page = pages.setdefault(slug, NativePage(slug, native_page_title(source), source)) - copied = DoxygenGroup(group.name, group.title, sorted(entries, key=lambda entry: entry.line)) + page = pages.setdefault( + slug, NativePage(slug, native_page_title(source), source) + ) + copied = DoxygenGroup( + group.name, + group.title, + sorted(entries, key=lambda entry: entry.line), + ) page.groups.append(copied) - ordered = sorted(pages.values(), key=lambda page: (page.source, page.title)) + ordered = sorted( + pages.values(), key=lambda page: (page.source, page.title) + ) for page in ordered: - page.groups.sort(key=lambda group: min((entry.line for entry in group.entries), default=0)) + page.groups.sort( + key=lambda group: min( + (entry.line for entry in group.entries), default=0 + ) + ) return ordered @@ -399,14 +465,30 @@ def render_native_function(entry: DoxygenEntry, language: str) -> list[str]: lines.extend([f"```{language}", signature, "```", ""]) if entry.details: - lines.extend([escape_text(" ".join(line for line in entry.details if line.strip())), ""]) + lines.extend( + [ + escape_text( + " ".join(line for line in entry.details if line.strip()) + ), + "", + ] + ) if entry.tparams: lines.extend(["**Template Parameters**", ""]) - lines.extend(render_param_table( - [{"name": param.name, "type": "", "description": param.description} for param in entry.tparams], - include_direction=False, - )) + lines.extend( + render_param_table( + [ + { + "name": param.name, + "type": "", + "description": param.description, + } + for param in entry.tparams + ], + include_direction=False, + ) + ) lines.append("") params = parse_function_params(signature) @@ -444,13 +526,29 @@ def render_native_compound(entry: DoxygenEntry, language: str) -> list[str]: if entry.summary: lines.extend([escape_text(entry.summary), ""]) if entry.details: - lines.extend([escape_text(" ".join(line for line in entry.details if line.strip())), ""]) - lines.extend([f"```{language}", compact_compound_signature(entry.signature), "```", ""]) + lines.extend( + [ + escape_text( + " ".join(line for line in entry.details if line.strip()) + ), + "", + ] + ) + lines.extend( + [ + f"```{language}", + compact_compound_signature(entry.signature), + "```", + "", + ] + ) if entry.kind == "enum": values = parse_enum_values(entry.signature) if values: - lines.extend(["**Values**", "", "| Name | Value |", "| --- | --- |"]) + lines.extend( + ["**Values**", "", "| Name | Value |", "| --- | --- |"] + ) for value in values: lines.append( f"| `{escape_code(value['name'])}` | `{escape_code(value.get('value', ''))}` |" @@ -480,7 +578,9 @@ def render_native_member(entry: DoxygenEntry, language: str) -> list[str]: lines = [f"### {heading_text(entry.name)}", ""] if entry.summary: lines.extend([escape_text(entry.summary), ""]) - lines.extend([f"```{language}", normalize_signature(entry.signature), "```", ""]) + lines.extend( + [f"```{language}", normalize_signature(entry.signature), "```", ""] + ) lines.extend([source_line(entry), ""]) return trim_blank_lines(lines) @@ -500,7 +600,9 @@ def generate_python_api_pages() -> None: for group, group_pages in group_python_pages(pages).items(): index_lines.extend([f"## {group}", ""]) for page in group_pages: - index_lines.append(f"- [{page.title}]({api_doc_url('python_api', page.slug)})") + index_lines.append( + f"- [{page.title}]({api_doc_url('python_api', page.slug)})" + ) index_lines.append("") write_page(out_dir / "index.md", index_lines) @@ -515,7 +617,9 @@ def generate_python_api_pages() -> None: for symbol in page.symbols: lines.extend(render_python_symbol(symbol)) lines.append("") - write_page(out_dir / f"{api_page_route('python_api', page.slug)}.md", lines) + write_page( + out_dir / f"{api_page_route('python_api', page.slug)}.md", lines + ) def build_python_symbol_index() -> dict[str, dict[str, PythonSymbol]]: @@ -531,7 +635,9 @@ def build_python_symbol_index() -> dict[str, dict[str, PythonSymbol]]: return index -def collect_python_pages(symbol_index: dict[str, dict[str, PythonSymbol]]) -> list[PythonPage]: +def collect_python_pages( + symbol_index: dict[str, dict[str, PythonSymbol]], +) -> list[PythonPage]: pages: list[PythonPage] = [] for init_path in sorted(PYTHON_DIR.rglob("__init__.py")): module = python_module_name(init_path) @@ -545,7 +651,11 @@ def collect_python_pages(symbol_index: dict[str, dict[str, PythonSymbol]]) -> li symbols.append(symbol) if not symbols: continue - pages.append(PythonPage(module, python_title(module), python_slug(module), symbols)) + pages.append( + PythonPage( + module, python_title(module), python_slug(module), symbols + ) + ) pages.sort(key=lambda page: (python_group(page.module), page.title)) return pages @@ -556,7 +666,11 @@ def find_python_symbol( name: str, symbol_index: dict[str, dict[str, PythonSymbol]], ) -> PythonSymbol | None: - candidates = [candidate for candidate in symbol_index if candidate == module or candidate.startswith(f"{module}.")] + candidates = [ + candidate + for candidate in symbol_index + if candidate == module or candidate.startswith(f"{module}.") + ] candidates.sort(key=lambda candidate: (candidate.count("."), candidate)) for candidate in candidates: if name in symbol_index[candidate]: @@ -583,7 +697,9 @@ def parse_python_source(path: Path) -> list[PythonSymbol]: if indent == 0 and class_match: signature, end_idx = collect_python_signature(lines, idx) doc, _ = collect_python_docstring(lines, end_idx + 1) - members = collect_python_class_members(lines, end_idx + 1, indent, path) + members = collect_python_class_members( + lines, end_idx + 1, indent, path + ) symbols.append( PythonSymbol( name=class_match.group(1), @@ -656,7 +772,11 @@ def collect_python_class_members( raw_line = lines[idx] stripped = raw_line.strip() indent = indentation(raw_line) - if stripped and indent <= class_indent and not stripped.startswith("@"): + if ( + stripped + and indent <= class_indent + and not stripped.startswith("@") + ): break if indent > class_indent and stripped.startswith("@"): decorators.append(stripped) @@ -705,20 +825,50 @@ def render_python_symbol(symbol: PythonSymbol) -> list[str]: lines.extend(render_doc_text(symbol.doc)) lines.append("") - init_member = next((member for member in symbol.members if member.name == "__init__"), None) + init_member = next( + (member for member in symbol.members if member.name == "__init__"), + None, + ) if init_member is not None: - lines.extend(["**Constructor**", "", "```python", init_member.signature, "```", ""]) + lines.extend( + [ + "**Constructor**", + "", + "```python", + init_member.signature, + "```", + "", + ] + ) - visible_members = [member for member in symbol.members if member.name != "__init__"] + visible_members = [ + member for member in symbol.members if member.name != "__init__" + ] if visible_members: - lines.extend(["**Members**", "", "| Name | Kind | Source |", "| --- | --- | --- |"]) + lines.extend( + [ + "**Members**", + "", + "| Name | Kind | Source |", + "| --- | --- | --- |", + ] + ) for member in visible_members: lines.append( f"| `{escape_code(member.name)}` | {member.kind} | `{escape_code(f'{member.source}:{member.line}')}` |" ) lines.append("") for member in visible_members: - lines.extend([f"### {heading_text(member.name)}", "", "```python", member.signature, "```", ""]) + lines.extend( + [ + f"### {heading_text(member.name)}", + "", + "```python", + member.signature, + "```", + "", + ] + ) if member.doc: lines.extend(render_doc_text(member.doc)) lines.append("") @@ -745,7 +895,9 @@ def generate_java_api_pages() -> None: for package in sorted(by_package): index_lines.extend([f"## `{package}`", ""]) for klass in sorted(by_package[package], key=lambda item: item.name): - index_lines.append(f"- [{klass.name}]({api_doc_url('java_api', java_slug(klass))})") + index_lines.append( + f"- [{klass.name}]({api_doc_url('java_api', java_slug(klass))})" + ) index_lines.append("") write_page(out_dir / "index.md", index_lines) @@ -767,20 +919,39 @@ def generate_java_api_pages() -> None: if klass.members: lines.extend(["## Public Members", ""]) for member in klass.members: - lines.extend([f"### {heading_text(member.name)}", "", "```java", member.signature, "```", ""]) + lines.extend( + [ + f"### {heading_text(member.name)}", + "", + "```java", + member.signature, + "```", + "", + ] + ) lines.extend(render_javadoc(member.doc)) - if member.doc.summary or member.doc.params or member.doc.returns: + if ( + member.doc.summary + or member.doc.params + or member.doc.returns + ): lines.append("") lines.extend([f"_Source: `{klass.source}:{member.line}`_", ""]) lines.extend([f"_Source: `{klass.source}:{klass.line}`_", ""]) - write_page(out_dir / f"{api_page_route('java_api', java_slug(klass))}.md", lines) + write_page( + out_dir / f"{api_page_route('java_api', java_slug(klass))}.md", + lines, + ) def collect_java_classes() -> list[JavaClass]: classes: list[JavaClass] = [] for root in JAVA_SOURCE_DIRS: for path in sorted(root.rglob("*.java")): - if "internal" in path.relative_to(root).parts or path.name == "module-info.java": + if ( + "internal" in path.relative_to(root).parts + or path.name == "module-info.java" + ): continue klass = parse_java_class(path) if klass is not None: @@ -826,7 +997,9 @@ def parse_java_members(text: str, class_name: str) -> list[JavaMember]: continue name = name_match.group(1) doc = parse_javadoc(match.group(0)) - members.append(JavaMember(name=name, signature=signature, doc=doc, line=line)) + members.append( + JavaMember(name=name, signature=signature, doc=doc, line=line) + ) return members @@ -865,7 +1038,8 @@ def read_declaration_after(text: str, offset: int) -> tuple[str, int]: if ( not stripped or stripped.startswith("#") - or stripped in {"extern \"C\" {", "{", "}", "public:", "private:", "protected:"} + or stripped + in {'extern "C" {', "{", "}", "public:", "private:", "protected:"} ): idx = line_end + 1 line_no += 1 @@ -882,7 +1056,10 @@ def read_declaration_after(text: str, offset: int) -> tuple[str, int]: next_newline = len(text) first_declaration_line = text[declaration_start:next_newline].strip() is_compound = bool( - re.match(r"(?:template\s*<[^>]+>\s*)?(?:typedef\s+)?(?:struct|class|enum)\b", first_declaration_line) + re.match( + r"(?:template\s*<[^>]+>\s*)?(?:typedef\s+)?(?:struct|class|enum)\b", + first_declaration_line, + ) ) while idx < len(text): if text.startswith("//", idx): @@ -913,7 +1090,9 @@ def read_declaration_after(text: str, offset: int) -> tuple[str, int]: declaration = text[declaration_start:idx].strip() declaration = re.sub(r"///<.*", "", declaration) - declaration = "\n".join(line.rstrip() for line in declaration.splitlines()).strip() + declaration = "\n".join( + line.rstrip() for line in declaration.splitlines() + ).strip() if is_simple_member_declaration(declaration): declaration = declaration.splitlines()[0].rstrip(",") return declaration, line_no @@ -939,7 +1118,9 @@ def is_simple_member_declaration(declaration: str) -> bool: return "\n" in declaration and "\n}" in declaration -def parse_doxygen_entry(comment: str, declaration: str, source: str, line: int) -> DoxygenEntry: +def parse_doxygen_entry( + comment: str, declaration: str, source: str, line: int +) -> DoxygenEntry: summary = "" details: list[str] = [] params: list[DoxygenParam] = [] @@ -965,7 +1146,9 @@ def parse_doxygen_entry(comment: str, declaration: str, source: str, line: int) active_param = None continue - if re.match(r"[@\\](?:defgroup|ingroup|addtogroup)\b", line_text) or line_text in { + if re.match( + r"[@\\](?:defgroup|ingroup|addtogroup)\b", line_text + ) or line_text in { "@{", "\\{", "@}", @@ -996,12 +1179,15 @@ def parse_doxygen_entry(comment: str, declaration: str, source: str, line: int) tparam_match = re.match(r"[@\\]tparam\s+(\w+)\s*(.*)", line_text) if tparam_match: active_param = DoxygenParam( - tparam_match.group(1), clean_doxygen_text(tparam_match.group(2)) + tparam_match.group(1), + clean_doxygen_text(tparam_match.group(2)), ) tparams.append(active_param) continue - return_text = consume_command(line_text, "return") or consume_command(line_text, "returns") + return_text = consume_command(line_text, "return") or consume_command( + line_text, "returns" + ) if return_text is not None: returns = append_sentence(returns, clean_doxygen_text(return_text)) active_param = None @@ -1011,7 +1197,9 @@ def parse_doxygen_entry(comment: str, declaration: str, source: str, line: int) active_param = None continue - if active_param is not None and (raw_line.startswith((" ", "\t")) or not line_text): + if active_param is not None and ( + raw_line.startswith((" ", "\t")) or not line_text + ): active_param.description = append_sentence( active_param.description, clean_doxygen_text(line_text) ) @@ -1028,7 +1216,11 @@ def parse_doxygen_entry(comment: str, declaration: str, source: str, line: int) summary = details.pop(0).strip() kind = parse_doxygen_kind(declaration) - name = parse_member_name(declaration) if kind == "member" else parse_entry_name(declaration) + name = ( + parse_member_name(declaration) + if kind == "member" + else parse_entry_name(declaration) + ) return DoxygenEntry( kind=kind, name=name, @@ -1071,11 +1263,14 @@ def append_sentence(existing: str, addition: str) -> str: def parse_doxygen_kind(declaration: str) -> str: - if re.search(r"^\s*(?:typedef\s+)?(?:struct|class)\s+\w+", declaration) and ( - "{" in declaration or declaration.lstrip().startswith("typedef") - ): + if re.search( + r"^\s*(?:typedef\s+)?(?:struct|class)\s+\w+", declaration + ) and ("{" in declaration or declaration.lstrip().startswith("typedef")): return "struct" - if re.search(r"^\s*(?:typedef\s+)?enum(?:\s+class)?\b", declaration) and "{" in declaration: + if ( + re.search(r"^\s*(?:typedef\s+)?enum(?:\s+class)?\b", declaration) + and "{" in declaration + ): return "enum" if "(" in declaration and ")" in declaration: return "function" @@ -1092,10 +1287,16 @@ def parse_entry_name(declaration: str) -> str: before_paren = declaration.split("(", 1)[0].strip() if "(" in declaration and before_paren: return before_paren.split()[-1].split("::")[-1].strip("*&") - declaration_lines = [line.strip() for line in declaration.splitlines() if line.strip()] + declaration_lines = [ + line.strip() for line in declaration.splitlines() if line.strip() + ] first_line = declaration_lines[0] if declaration_lines else "" - name_line = declaration_lines[-1] if len(declaration_lines) > 1 else first_line - token_match = re.match(r"\s*(?:[\w:<>,]+\s+)*([A-Za-z_]\w*)\s*(?:=|;|,|$)", name_line) + name_line = ( + declaration_lines[-1] if len(declaration_lines) > 1 else first_line + ) + token_match = re.match( + r"\s*(?:[\w:<>,]+\s+)*([A-Za-z_]\w*)\s*(?:=|;|,|$)", name_line + ) return token_match.group(1) if token_match else first_line.strip() @@ -1106,20 +1307,30 @@ def parse_member_name(declaration: str) -> str: def parse_struct_name(declaration: str) -> str | None: - match = re.search(r"^\s*(?:typedef\s+)?(?:struct|class)\s+([A-Za-z_]\w*)", declaration) + match = re.search( + r"^\s*(?:typedef\s+)?(?:struct|class)\s+([A-Za-z_]\w*)", declaration + ) return match.group(1) if match else None def parse_enum_name(declaration: str) -> str | None: - match = re.search(r"^\s*(?:typedef\s+)?enum(?:\s+class)?\s+([A-Za-z_]\w*)", declaration) + match = re.search( + r"^\s*(?:typedef\s+)?enum(?:\s+class)?\s+([A-Za-z_]\w*)", declaration + ) if match: return match.group(1) - typedef_match = re.search(r"}\s*([A-Za-z_]\w*)\s*;", declaration, re.DOTALL) + typedef_match = re.search( + r"}\s*([A-Za-z_]\w*)\s*;", declaration, re.DOTALL + ) return typedef_match.group(1) if typedef_match else None def infer_namespace(prefix: str) -> str: - matches = list(re.finditer(r"\bnamespace\s+([A-Za-z_][\w:]*)(?:\s*=\s*[^;]+)?\s*{", prefix)) + matches = list( + re.finditer( + r"\bnamespace\s+([A-Za-z_][\w:]*)(?:\s*=\s*[^;]+)?\s*{", prefix + ) + ) if not matches: return "" return matches[-1].group(1) @@ -1136,14 +1347,18 @@ def normalize_entry_signature(declaration: str, kind: str) -> str: def normalize_signature(declaration: str) -> str: declaration = re.sub(r"\n\s+", "\n", declaration.strip()) - return "\n".join(line.rstrip() for line in declaration.splitlines()).strip() + return "\n".join( + line.rstrip() for line in declaration.splitlines() + ).strip() def compact_compound_signature(signature: str) -> str: first_line = signature.splitlines()[0] if "{" in first_line: prefix = signature.split("{", 1)[0].strip() - suffix = signature.rsplit("}", 1)[1].strip() if "}" in signature else "" + suffix = ( + signature.rsplit("}", 1)[1].strip() if "}" in signature else "" + ) if suffix: return f"{prefix} {{ ... }} {suffix}".strip() return f"{prefix} {{ ... }};" @@ -1158,7 +1373,9 @@ def parse_function_params(signature: str) -> list[FunctionParam]: if not params_text or params_text.strip() == "void": return [] params: list[FunctionParam] = [] - for idx, raw_param in enumerate(split_top_level(params_text, ","), start=1): + for idx, raw_param in enumerate( + split_top_level(params_text, ","), start=1 + ): param = raw_param.strip() if not param: continue @@ -1168,7 +1385,13 @@ def parse_function_params(signature: str) -> list[FunctionParam]: param = left.strip() default = default.strip() c_type, name = split_param_name(param) - params.append(FunctionParam(name=name or f"arg{idx}", c_type=c_type or param, default=default)) + params.append( + FunctionParam( + name=name or f"arg{idx}", + c_type=c_type or param, + default=default, + ) + ) return params @@ -1219,7 +1442,9 @@ def parse_return_type(signature: str) -> str: tail = signature.split(")", 1)[1] return tail.split("->", 1)[1].strip().rstrip(";") before_paren = signature.split("(", 1)[0] - before_paren = re.sub(r"template\s*<[^>]+>", "", before_paren, flags=re.DOTALL) + before_paren = re.sub( + r"template\s*<[^>]+>", "", before_paren, flags=re.DOTALL + ) before_paren = " ".join(before_paren.split()) if not before_paren: return "void" @@ -1233,22 +1458,31 @@ def parse_struct_members(entry: DoxygenEntry) -> list[DoxygenEntry]: members: list[DoxygenEntry] = [] for match in COMMENT_RE.finditer(entry.signature): comment = clean_doxygen_comment(match.group(0)) - declaration, line = read_declaration_after(entry.signature, match.end()) - if not declaration or declaration.startswith(("public:", "private:", "protected:")): + declaration, line = read_declaration_after( + entry.signature, match.end() + ) + if not declaration or declaration.startswith( + ("public:", "private:", "protected:") + ): continue - member = parse_doxygen_entry(comment, declaration, entry.source, entry.line + line - 1) + member = parse_doxygen_entry( + comment, declaration, entry.source, entry.line + line - 1 + ) member.kind = "member" members.append(member) - members.extend(parse_plain_struct_members(entry, {member.name for member in members})) + members.extend( + parse_plain_struct_members(entry, {member.name for member in members}) + ) return members -def parse_plain_struct_members(entry: DoxygenEntry, existing_names: set[str]) -> list[DoxygenEntry]: +def parse_plain_struct_members( + entry: DoxygenEntry, existing_names: set[str] +) -> list[DoxygenEntry]: body = compound_body(entry.signature) if not body: return [] members: list[DoxygenEntry] = [] - last_member: DoxygenEntry | None = None pending_declaration = "" pending_comment = "" for raw_line in body.splitlines(): @@ -1264,7 +1498,9 @@ def parse_plain_struct_members(entry: DoxygenEntry, existing_names: set[str]) -> if not declaration and not pending_declaration: continue pending_declaration = f"{pending_declaration} {declaration}".strip() - pending_comment = append_sentence(pending_comment, clean_doxygen_text(inline_comment)) + pending_comment = append_sentence( + pending_comment, clean_doxygen_text(inline_comment) + ) if ";" not in pending_declaration: continue declaration = pending_declaration.split(";", 1)[0].rstrip(",").strip() @@ -1274,7 +1510,9 @@ def parse_plain_struct_members(entry: DoxygenEntry, existing_names: set[str]) -> if not declaration or "(" in declaration: continue declaration = declaration.split("=", 1)[0].strip() - if not declaration or declaration.startswith(("using ", "typedef ", "static_assert")): + if not declaration or declaration.startswith( + ("using ", "typedef ", "static_assert") + ): continue c_type, name = split_param_name(declaration) if not name or name in existing_names: @@ -1289,7 +1527,6 @@ def parse_plain_struct_members(entry: DoxygenEntry, existing_names: set[str]) -> ) members.append(member) existing_names.add(name) - last_member = member return members @@ -1320,7 +1557,9 @@ def parse_enum_values(signature: str) -> list[dict[str, str]]: return [] values: list[dict[str, str]] = [] for raw_value in split_top_level(body_match.group("body"), ","): - cleaned = re.sub(r"/\*.*?\*/|//.*", "", raw_value, flags=re.DOTALL).strip() + cleaned = re.sub( + r"/\*.*?\*/|//.*", "", raw_value, flags=re.DOTALL + ).strip() if not cleaned: continue name, _, value = cleaned.partition("=") @@ -1340,8 +1579,12 @@ def collect_python_signature(lines: list[str], start: int) -> tuple[str, int]: while idx < len(lines): stripped = lines[idx].strip() chunks.append(stripped) - depth += stripped.count("(") + stripped.count("[") + stripped.count("{") - depth -= stripped.count(")") + stripped.count("]") + stripped.count("}") + depth += ( + stripped.count("(") + stripped.count("[") + stripped.count("{") + ) + depth -= ( + stripped.count(")") + stripped.count("]") + stripped.count("}") + ) if stripped.endswith(":") and depth <= 0: break idx += 1 @@ -1357,8 +1600,12 @@ def collect_python_assignment(lines: list[str], start: int) -> tuple[str, int]: idx += 1 stripped = lines[idx].strip() chunks.append(stripped) - depth += stripped.count("{") + stripped.count("[") + stripped.count("(") - depth -= stripped.count("}") + stripped.count("]") + stripped.count(")") + depth += ( + stripped.count("{") + stripped.count("[") + stripped.count("(") + ) + depth -= ( + stripped.count("}") + stripped.count("]") + stripped.count(")") + ) return "\n".join(chunks), idx @@ -1398,12 +1645,16 @@ def collect_python_docstring(lines: list[str], start: int) -> tuple[str, int]: def clean_python_docstring(doc: str) -> str: doc = textwrap.dedent(doc).strip() doc = doc.replace("\\\n", "") - doc = doc.replace("{resources_docstring}", "resources : cuvs.common.Resources, optional") + doc = doc.replace( + "{resources_docstring}", "resources : cuvs.common.Resources, optional" + ) return strip_sphinx_roles(doc) def strip_sphinx_roles(value: str) -> str: - return SPHINX_ROLE_RE.sub(lambda match: sphinx_role_label(match.group("target")), value) + return SPHINX_ROLE_RE.sub( + lambda match: sphinx_role_label(match.group("target")), value + ) def sphinx_role_label(target: str) -> str: @@ -1428,7 +1679,9 @@ def sphinx_role_label(target: str) -> str: "yields", } NUMPY_SECTION_UNDERLINE_RE = re.compile(r"^-{3,}\s*$") -NUMPY_FIELD_RE = re.compile(r"^(?P[A-Za-z_*][A-Za-z0-9_*,\s]*?)\s*:\s*(?P.*)$") +NUMPY_FIELD_RE = re.compile( + r"^(?P[A-Za-z_*][A-Za-z0-9_*,\s]*?)\s*:\s*(?P.*)$" +) def render_doc_text(doc: str) -> list[str]: @@ -1452,7 +1705,9 @@ def render_doc_text(doc: str) -> list[str]: return trim_blank_lines(lines) -def split_numpy_doc_sections(raw_lines: list[str]) -> tuple[list[str], list[tuple[str, list[str]]]]: +def split_numpy_doc_sections( + raw_lines: list[str], +) -> tuple[list[str], list[tuple[str, list[str]]]]: preamble: list[str] = [] sections: list[tuple[str, list[str]]] = [] current_title: str | None = None @@ -1495,10 +1750,12 @@ def render_numpy_field_section(title: str, raw_lines: list[str]) -> list[str]: "| Name | Type | Description |", "| --- | --- | --- |", ] - for field in fields: - name = render_numpy_field_names(field["name"]) - field_type = f"`{escape_code(field['type'])}`" if field["type"] else "" - description = render_table_description(field["description"]) + for doc_field in fields: + name = render_numpy_field_names(doc_field["name"]) + field_type = ( + f"`{escape_code(doc_field['type'])}`" if doc_field["type"] else "" + ) + description = render_table_description(doc_field["description"]) lines.append(f"| {name} | {field_type} | {description} |") return lines @@ -1508,7 +1765,11 @@ def parse_numpy_fields(raw_lines: list[str]) -> list[dict[str, str]]: current: dict[str, object] | None = None for raw_line in dedent_doc_lines(raw_lines): stripped = raw_line.strip() - field_match = NUMPY_FIELD_RE.match(stripped) if stripped and indentation(raw_line) == 0 else None + field_match = ( + NUMPY_FIELD_RE.match(stripped) + if stripped and indentation(raw_line) == 0 + else None + ) if field_match: if current is not None: fields.append(finish_numpy_field(current)) @@ -1524,7 +1785,11 @@ def parse_numpy_fields(raw_lines: list[str]) -> list[dict[str, str]]: continue description = current["description"] assert isinstance(description, list) - if stripped and not description and numpy_type_needs_continuation(str(current["type"])): + if ( + stripped + and not description + and numpy_type_needs_continuation(str(current["type"])) + ): current["type"] = f"{current['type']} {stripped}" else: description.append(stripped) @@ -1573,7 +1838,9 @@ def render_table_description(value: str) -> str: current.append(stripped) if current: paragraphs.append(" ".join(current)) - return "

".join(escape_text(paragraph) for paragraph in paragraphs) + return "

".join( + escape_text(paragraph) for paragraph in paragraphs + ) def render_doc_lines(raw_lines: list[str]) -> list[str]: @@ -1693,7 +1960,9 @@ def java_signature_at(text: str, start: int) -> tuple[str, int]: def comment_before(text: str, start: int) -> str: prefix = text[:start].rstrip() - match = re.search(r"/\*\*.*?\*/\s*(?:@\w+(?:\([^)]*\))?\s*)*$", prefix, re.DOTALL) + match = re.search( + r"/\*\*.*?\*/\s*(?:@\w+(?:\([^)]*\))?\s*)*$", prefix, re.DOTALL + ) return match.group(0) if match else "" @@ -1705,7 +1974,9 @@ def parse_javadoc(raw: str) -> JavaDoc: if not comment_match: return JavaDoc() body = comment_match.group(1) - lines = [re.sub(r"^\s*\* ?", "", line).rstrip() for line in body.splitlines()] + lines = [ + re.sub(r"^\s*\* ?", "", line).rstrip() for line in body.splitlines() + ] doc = JavaDoc() summary_lines: list[str] = [] active: DoxygenParam | None = None @@ -1718,13 +1989,17 @@ def parse_javadoc(raw: str) -> JavaDoc: continue param_match = re.match(r"@param\s+(\w+)\s*(.*)", stripped) if param_match: - active = DoxygenParam(param_match.group(1), param_match.group(2).strip()) + active = DoxygenParam( + param_match.group(1), param_match.group(2).strip() + ) doc.params.append(active) active_kind = "param" continue throws_match = re.match(r"@throws\s+([\w.]+)\s*(.*)", stripped) if throws_match: - active = DoxygenParam(throws_match.group(1), throws_match.group(2).strip()) + active = DoxygenParam( + throws_match.group(1), throws_match.group(2).strip() + ) doc.throws.append(active) active_kind = "throws" continue @@ -1750,7 +2025,11 @@ def parse_javadoc(raw: str) -> JavaDoc: def clean_javadoc_text(text: str) -> str: text = re.sub(r"\{@code\s+([^}]+)\}", r"`\1`", text) - text = re.sub(r"\{@link\s+([^}\s]+)(?:\s+([^}]+))?\}", lambda m: m.group(2) or f"`{m.group(1)}`", text) + text = re.sub( + r"\{@link\s+([^}\s]+)(?:\s+([^}]+))?\}", + lambda m: m.group(2) or f"`{m.group(1)}`", + text, + ) text = re.sub(r"]*>(.*?)", r"\1", text) text = re.sub(r"", "", text) text = re.sub(r"<[^>]+>", "", text) @@ -1763,16 +2042,24 @@ def render_javadoc(doc: JavaDoc) -> list[str]: lines.extend(escape_text(line) for line in doc.summary.splitlines()) lines.append("") if doc.params: - lines.extend(["**Parameters**", "", "| Name | Description |", "| --- | --- |"]) + lines.extend( + ["**Parameters**", "", "| Name | Description |", "| --- | --- |"] + ) for param in doc.params: - lines.append(f"| `{escape_code(param.name)}` | {escape_text(param.description)} |") + lines.append( + f"| `{escape_code(param.name)}` | {escape_text(param.description)} |" + ) lines.append("") if doc.returns: lines.extend(["**Returns**", "", escape_text(doc.returns), ""]) if doc.throws: - lines.extend(["**Throws**", "", "| Type | Description |", "| --- | --- |"]) + lines.extend( + ["**Throws**", "", "| Type | Description |", "| --- | --- |"] + ) for param in doc.throws: - lines.append(f"| `{escape_code(param.name)}` | {escape_text(param.description)} |") + lines.append( + f"| `{escape_code(param.name)}` | {escape_text(param.description)} |" + ) lines.append("") return trim_blank_lines(lines) @@ -1791,7 +2078,9 @@ def generate_rust_api_pages() -> None: for group, group_pages in group_rust_pages(pages).items(): index_lines.extend([f"## {group}", ""]) for page in group_pages: - index_lines.append(f"- [`{page.module}`]({api_doc_url('rust_api', page.slug)})") + index_lines.append( + f"- [`{page.module}`]({api_doc_url('rust_api', page.slug)})" + ) index_lines.append("") write_page(out_dir / "index.md", index_lines) @@ -1811,7 +2100,9 @@ def generate_rust_api_pages() -> None: for item in page.items: lines.extend(render_rust_item(item)) lines.append("") - write_page(out_dir / f"{api_page_route('rust_api', page.slug)}.md", lines) + write_page( + out_dir / f"{api_page_route('rust_api', page.slug)}.md", lines + ) def collect_rust_pages() -> list[RustPage]: @@ -1830,7 +2121,11 @@ def parse_rust_page(path: Path) -> RustPage: lines = path.read_text(encoding="utf-8").splitlines() module = rust_module_name(path) items = parse_rust_top_level_items(lines, path) - items_by_name = {item.name: item for item in items if item.kind in {"struct", "enum", "trait"}} + items_by_name = { + item.name: item + for item in items + if item.kind in {"struct", "enum", "trait"} + } for impl_type, methods, impl_line in parse_rust_impl_methods(lines, path): if not methods: @@ -1881,10 +2176,16 @@ def parse_rust_top_level_items(lines: list[str], path: Path) -> list[RustItem]: _, signature_end, has_block = collect_rust_signature(lines, idx) pending_doc = [] pending_attributes = [] - idx = skip_rust_block(lines, signature_end) + 1 if has_block else signature_end + 1 + idx = ( + skip_rust_block(lines, signature_end) + 1 + if has_block + else signature_end + 1 + ) continue if is_public_rust_declaration(stripped): - signature, signature_end, has_block = collect_rust_signature(lines, idx) + signature, signature_end, has_block = collect_rust_signature( + lines, idx + ) kind, name = parse_rust_item_kind_name(signature) if kind and name: items.append( @@ -1900,7 +2201,11 @@ def parse_rust_top_level_items(lines: list[str], path: Path) -> list[RustItem]: ) pending_doc = [] pending_attributes = [] - idx = skip_rust_block(lines, signature_end) + 1 if has_block else signature_end + 1 + idx = ( + skip_rust_block(lines, signature_end) + 1 + if has_block + else signature_end + 1 + ) continue if stripped and not stripped.startswith("//"): pending_doc = [] @@ -1909,7 +2214,9 @@ def parse_rust_top_level_items(lines: list[str], path: Path) -> list[RustItem]: return items -def parse_rust_impl_methods(lines: list[str], path: Path) -> list[tuple[str, list[RustItem], int]]: +def parse_rust_impl_methods( + lines: list[str], path: Path +) -> list[tuple[str, list[RustItem], int]]: impls: list[tuple[str, list[RustItem], int]] = [] idx = 0 while idx < len(lines): @@ -1917,14 +2224,18 @@ def parse_rust_impl_methods(lines: list[str], path: Path) -> list[tuple[str, lis if not stripped.startswith("impl"): idx += 1 continue - signature, signature_end, has_block = collect_rust_signature(lines, idx) + signature, signature_end, has_block = collect_rust_signature( + lines, idx + ) if not has_block: idx = signature_end + 1 continue block_end = skip_rust_block(lines, signature_end) impl_type = parse_rust_impl_type(signature) if impl_type: - methods = parse_rust_methods_in_impl(lines, signature_end + 1, block_end, path) + methods = parse_rust_methods_in_impl( + lines, signature_end + 1, block_end, path + ) impls.append((impl_type, methods, idx + 1)) idx = block_end + 1 return impls @@ -1952,7 +2263,9 @@ def parse_rust_methods_in_impl( idx += 1 continue if depth == 1 and is_public_rust_function(stripped): - signature, signature_end, has_block = collect_rust_signature(lines, idx) + signature, signature_end, has_block = collect_rust_signature( + lines, idx + ) name = parse_rust_function_name(signature) if name: methods.append( @@ -1968,7 +2281,11 @@ def parse_rust_methods_in_impl( ) pending_doc = [] pending_attributes = [] - idx = skip_rust_block(lines, signature_end) + 1 if has_block else signature_end + 1 + idx = ( + skip_rust_block(lines, signature_end) + 1 + if has_block + else signature_end + 1 + ) continue if depth == 1 and stripped and not stripped.startswith("//"): pending_doc = [] @@ -2010,7 +2327,12 @@ def collect_rust_module_doc(lines: list[str]) -> str: def is_public_rust_declaration(stripped: str) -> bool: if not stripped.startswith("pub ") or stripped.startswith("pub(crate)"): return False - return bool(re.match(r"pub\s+(?:unsafe\s+|async\s+)?(?:fn|struct|enum|trait|type|use|mod)\b", stripped)) + return bool( + re.match( + r"pub\s+(?:unsafe\s+|async\s+)?(?:fn|struct|enum|trait|type|use|mod)\b", + stripped, + ) + ) def is_public_rust_function(stripped: str) -> bool: @@ -2019,7 +2341,9 @@ def is_public_rust_function(stripped: str) -> bool: return bool(re.match(r"pub\s+(?:unsafe\s+|async\s+)?fn\b", stripped)) -def collect_rust_signature(lines: list[str], start: int) -> tuple[str, int, bool]: +def collect_rust_signature( + lines: list[str], start: int +) -> tuple[str, int, bool]: chunks: list[str] = [] paren_depth = 0 bracket_depth = 0 @@ -2041,7 +2365,12 @@ def collect_rust_signature(lines: list[str], start: int) -> tuple[str, int, bool angle_depth += 1 elif char == ">": angle_depth = max(angle_depth - 1, 0) - elif char in "{;" and paren_depth == 0 and bracket_depth == 0 and angle_depth == 0: + elif ( + char in "{;" + and paren_depth == 0 + and bracket_depth == 0 + and angle_depth == 0 + ): prefix = stripped[: char_idx + 1].rstrip() chunks[-1] = prefix signature = normalize_rust_signature("\n".join(chunks)) @@ -2089,7 +2418,10 @@ def strip_rust_line_for_braces(line: str) -> str: def parse_rust_item_kind_name(signature: str) -> tuple[str, str]: first_line = signature.splitlines()[0].strip() - match = re.match(r"pub\s+(?Pstruct|enum|trait|type|mod)\s+(?P[A-Za-z_]\w*)", first_line) + match = re.match( + r"pub\s+(?Pstruct|enum|trait|type|mod)\s+(?P[A-Za-z_]\w*)", + first_line, + ) if match: return match.group("kind"), match.group("name") if re.match(r"pub\s+(?:unsafe\s+|async\s+)?fn\b", first_line): @@ -2124,7 +2456,11 @@ def clean_rust_doc(lines: list[str]) -> str: def render_rust_item(item: RustItem) -> list[str]: lines = [f"## {heading_text(item.name)}", ""] - signature_lines = [*item.attributes, item.signature] if item.attributes else [item.signature] + signature_lines = ( + [*item.attributes, item.signature] + if item.attributes + else [item.signature] + ) lines.extend(["```rust", "\n".join(signature_lines), "```", ""]) if item.doc: lines.extend(render_markdown_doc(item.doc)) @@ -2132,11 +2468,17 @@ def render_rust_item(item: RustItem) -> list[str]: if item.members: lines.extend(["**Methods**", "", "| Name | Source |", "| --- | --- |"]) for member in item.members: - lines.append(f"| `{escape_code(member.name)}` | `{escape_code(f'{member.source}:{member.line}')}` |") + lines.append( + f"| `{escape_code(member.name)}` | `{escape_code(f'{member.source}:{member.line}')}` |" + ) lines.append("") for member in item.members: lines.extend([f"### {heading_text(member.name)}", ""]) - member_signature = [*member.attributes, member.signature] if member.attributes else [member.signature] + member_signature = ( + [*member.attributes, member.signature] + if member.attributes + else [member.signature] + ) lines.extend(["```rust", "\n".join(member_signature), "```", ""]) if member.doc: lines.extend(render_markdown_doc(member.doc)) @@ -2158,7 +2500,16 @@ def rust_group(module: str) -> str: return "Cluster" if "::distance" in module: return "Distance" - if any(token in module for token in ("::brute_force", "::cagra", "::ivf_flat", "::ivf_pq", "::vamana")): + if any( + token in module + for token in ( + "::brute_force", + "::cagra", + "::ivf_flat", + "::ivf_pq", + "::vamana", + ) + ): return "Nearest Neighbors" return "Core" @@ -2196,7 +2547,9 @@ def generate_go_api_pages() -> None: "", ] for page in pages: - index_lines.append(f"- [`{page.package}`]({api_doc_url('go_api', page.slug)})") + index_lines.append( + f"- [`{page.package}`]({api_doc_url('go_api', page.slug)})" + ) write_page(out_dir / "index.md", index_lines) for page in pages: @@ -2214,7 +2567,9 @@ def generate_go_api_pages() -> None: for item in items: lines.extend(render_go_item(item)) lines.append("") - write_page(out_dir / f"{api_page_route('go_api', page.slug)}.md", lines) + write_page( + out_dir / f"{api_page_route('go_api', page.slug)}.md", lines + ) def collect_go_pages() -> list[GoPage]: @@ -2235,7 +2590,14 @@ def collect_go_pages() -> list[GoPage]: title=f"{go_package_title(package)} Package", slug=go_slug(package), sources=sorted(sources[package]), - items=sorted(items, key=lambda item: (go_kind_order(item.kind), item.name, item.line)), + items=sorted( + items, + key=lambda item: ( + go_kind_order(item.kind), + item.name, + item.line, + ), + ), ) for package, items in by_package.items() if items @@ -2267,7 +2629,9 @@ def parse_go_file(path: Path) -> tuple[str, list[GoItem]]: continue if is_go_declaration(stripped): signature, end_idx = collect_go_declaration(lines, idx) - kind, name, receiver = parse_go_item_kind_name(signature, pending_doc) + kind, name, receiver = parse_go_item_kind_name( + signature, pending_doc + ) if name and is_go_exported_item(kind, name, signature): items.append( GoItem( @@ -2289,7 +2653,9 @@ def parse_go_file(path: Path) -> tuple[str, list[GoItem]]: return package, items -def collect_go_block_comment(lines: list[str], start: int) -> tuple[list[str], int]: +def collect_go_block_comment( + lines: list[str], start: int +) -> tuple[list[str], int]: body: list[str] = [] idx = start while idx < len(lines): @@ -2315,13 +2681,19 @@ def collect_go_declaration(lines: list[str], start: int) -> tuple[str, int]: return collect_go_function_signature(lines, start) if re.match(r"(?:const|var|type)\s*\(", first): return collect_go_paren_block(lines, start) - if " struct {" in first or first.endswith(" struct {") or " interface {" in first: + if ( + " struct {" in first + or first.endswith(" struct {") + or " interface {" in first + ): signature, end_idx = collect_go_brace_block(lines, start) return compact_go_type_signature(signature), end_idx return first, start -def collect_go_function_signature(lines: list[str], start: int) -> tuple[str, int]: +def collect_go_function_signature( + lines: list[str], start: int +) -> tuple[str, int]: chunks: list[str] = [] paren_depth = 0 bracket_depth = 0 @@ -2384,9 +2756,14 @@ def normalize_go_signature(signature: str) -> str: return "\n".join(line.rstrip() for line in signature.splitlines()).strip() -def parse_go_item_kind_name(signature: str, doc_lines: list[str]) -> tuple[str, str, str]: +def parse_go_item_kind_name( + signature: str, doc_lines: list[str] +) -> tuple[str, str, str]: first_line = signature.splitlines()[0].strip() - func_match = re.match(r"func\s+(?:\((?P[^)]+)\)\s*)?(?P[A-Za-z_]\w*)", first_line) + func_match = re.match( + r"func\s+(?:\((?P[^)]+)\)\s*)?(?P[A-Za-z_]\w*)", + first_line, + ) if func_match: receiver = go_receiver_type(func_match.group("receiver") or "") name = func_match.group("name") @@ -2403,9 +2780,21 @@ def parse_go_item_kind_name(signature: str, doc_lines: list[str]) -> tuple[str, if const_match: return "constant", const_match.group("name"), "" if first_line == "const (": - return "constant", go_block_heading(doc_lines, go_block_export_name(signature, "Constants")), "" + return ( + "constant", + go_block_heading( + doc_lines, go_block_export_name(signature, "Constants") + ), + "", + ) if first_line == "var (": - return "variable", go_block_heading(doc_lines, go_block_export_name(signature, "Variables")), "" + return ( + "variable", + go_block_heading( + doc_lines, go_block_export_name(signature, "Variables") + ), + "", + ) return "", "", "" @@ -2469,15 +2858,32 @@ def group_go_items(items: list[GoItem]) -> dict[str, list[GoItem]]: grouped: dict[str, list[GoItem]] = defaultdict(list) for item in items: grouped[labels.get(item.kind, "Other")].append(item) - return {labels[kind]: grouped[labels[kind]] for kind in ["constant", "variable", "type", "function", "method"] if grouped.get(labels[kind])} + return { + labels[kind]: grouped[labels[kind]] + for kind in ["constant", "variable", "type", "function", "method"] + if grouped.get(labels[kind]) + } def go_kind_order(kind: str) -> int: - return {"constant": 0, "variable": 1, "type": 2, "function": 3, "method": 4}.get(kind, 9) + return { + "constant": 0, + "variable": 1, + "type": 2, + "function": 3, + "method": 4, + }.get(kind, 9) def render_go_item(item: GoItem) -> list[str]: - lines = [f"### {heading_text(item.name)}", "", "```go", item.signature, "```", ""] + lines = [ + f"### {heading_text(item.name)}", + "", + "```go", + item.signature, + "```", + "", + ] if item.doc: lines.extend(render_markdown_doc(item.doc)) lines.append("") @@ -2503,7 +2909,9 @@ def update_api_navigation() -> None: start = text.find(start_marker) end = text.find(end_marker, start) if start == -1 or end == -1: - raise RuntimeError("Could not find API Reference navigation block in fern/docs.yml") + raise RuntimeError( + "Could not find API Reference navigation block in fern/docs.yml" + ) lines = [ ' - section: "API Reference"', @@ -2527,7 +2935,9 @@ def update_api_navigation() -> None: ) replacement = "\n".join(lines) + "\n" - docs_yml.write_text(text[:start] + replacement + text[end:], encoding="utf-8") + docs_yml.write_text( + text[:start] + replacement + text[end:], encoding="utf-8" + ) print("Updated fern/docs.yml API Reference navigation") @@ -2535,7 +2945,10 @@ def read_api_index_slugs(index_path: Path) -> list[str]: slugs: list[str] = [] route_prefix = api_route_prefix(index_path.parent.name) for line in index_path.read_text(encoding="utf-8").splitlines(): - match = re.search(rf"\]\((?:\./|/api-reference/{re.escape(route_prefix)}-)([^)#]+)", line) + match = re.search( + rf"\]\((?:\./|/api-reference/{re.escape(route_prefix)}-)([^)#]+)", + line, + ) if match: slugs.append(match.group(1).removesuffix(".md")) return slugs @@ -2614,7 +3027,9 @@ def render_markdown_doc(doc: str) -> list[str]: heading_match = re.match(r"^(#{1,6})\s+(.+)", line) if heading_match: level = min(len(heading_match.group(1)) + 3, 6) - lines.append(f"{'#' * level} {escape_text(heading_match.group(2))}") + lines.append( + f"{'#' * level} {escape_text(heading_match.group(2))}" + ) else: lines.append(escape_text(line)) return trim_blank_lines(lines) @@ -2624,12 +3039,17 @@ def source_line(entry: DoxygenEntry) -> str: return f"_Source: `{entry.source}:{entry.line}`_" -def render_param_table(params: list[dict[str, str]], include_direction: bool) -> list[str]: +def render_param_table( + params: list[dict[str, str]], include_direction: bool +) -> list[str]: headers = ["Name"] if include_direction: headers.append("Direction") headers.extend(["Type", "Description"]) - lines = ["| " + " | ".join(headers) + " |", "| " + " | ".join(["---"] * len(headers)) + " |"] + lines = [ + "| " + " | ".join(headers) + " |", + "| " + " | ".join(["---"] * len(headers)) + " |", + ] for param in params: row = [f"`{escape_code(param.get('name', ''))}`"] if include_direction: @@ -2637,7 +3057,9 @@ def render_param_table(params: list[dict[str, str]], include_direction: bool) -> row.append(f"`{escape_code(param.get('type', ''))}`") description = param.get("description", "") if param.get("default"): - description = f"{description} Default: `{param['default']}`.".strip() + description = ( + f"{description} Default: `{param['default']}`.".strip() + ) row.append(escape_text(description)) lines.append("| " + " | ".join(row) + " |") return lines @@ -2675,7 +3097,9 @@ def native_page_title(source: str) -> str: def humanize_slug(value: str) -> str: - return " ".join(word.capitalize() for word in re.split(r"[-_/]+", value) if word) + return " ".join( + word.capitalize() for word in re.split(r"[-_/]+", value) if word + ) def java_slug(klass: JavaClass) -> str: @@ -2717,7 +3141,9 @@ def update_depth(depth: dict[str, int], char: str) -> None: def escape_code(value: str) -> str: - return str(value).replace("|", "\\|").replace("`", "\\`").replace("\n", " ") + return ( + str(value).replace("|", "\\|").replace("`", "\\`").replace("\n", " ") + ) def escape_text(value: str) -> str: @@ -2747,7 +3173,9 @@ def trim_blank_lines(lines: list[str]) -> list[str]: def write_page(path: Path, lines: list[str]) -> None: path.parent.mkdir(parents=True, exist_ok=True) - path.write_text("\n".join(trim_blank_lines(lines)).rstrip() + "\n", encoding="utf-8") + path.write_text( + "\n".join(trim_blank_lines(lines)).rstrip() + "\n", encoding="utf-8" + ) print(f"Wrote {path.relative_to(REPO_DIR)}") From 16bb8f005762c5e0d601e106293f9bd93aea3c5f Mon Sep 17 00:00:00 2001 From: "Corey J. Nolet" Date: Thu, 7 May 2026 10:26:24 -0400 Subject: [PATCH 003/129] Fix developer guide build link --- fern/pages/developer_guide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fern/pages/developer_guide.md b/fern/pages/developer_guide.md index 5fa59609c4..40672f3f52 100644 --- a/fern/pages/developer_guide.md +++ b/fern/pages/developer_guide.md @@ -11,7 +11,7 @@ Please start by reading the [Contributor Guide](contributing.md). Developing features and fixing bugs for the RAFT library itself is straightforward and only requires building and installing the relevant RAFT artifacts. -The process for working on a CUDA/C++ feature which might span RAFT and one or more consuming libraries can vary slightly depending on whether the consuming project relies on a source build (as outlined in the [BUILD](BUILD.md#install_header_only_cpp) docs). In such a case, the option `CPM_raft_SOURCE=/path/to/raft/source` can be passed to the cmake of the consuming project in order to build the local RAFT from source. The PR with relevant changes to the consuming project can also pin the RAFT version temporarily by explicitly changing the `FORK` and `PINNED_TAG` arguments to the RAFT branch containing their changes when invoking `find_and_configure_raft`. The pin should be reverted after the change is merged to the RAFT project and before it is merged to the dependent project(s) downstream. +The process for working on a CUDA/C++ feature which might span RAFT and one or more consuming libraries can vary slightly depending on whether the consuming project relies on a source build (as outlined in the [build docs](build.md#using-cmake-directly)). In such a case, the option `CPM_raft_SOURCE=/path/to/raft/source` can be passed to the cmake of the consuming project in order to build the local RAFT from source. The PR with relevant changes to the consuming project can also pin the RAFT version temporarily by explicitly changing the `FORK` and `PINNED_TAG` arguments to the RAFT branch containing their changes when invoking `find_and_configure_raft`. The pin should be reverted after the change is merged to the RAFT project and before it is merged to the dependent project(s) downstream. If building a feature which spans projects and not using the source build in cmake, the RAFT changes (both C++ and Python) will need to be installed into the environment of the consuming project before they can be used. The ideal integration of RAFT into consuming projects will enable both the source build in the consuming project only for this case but also rely on a more stable packaging (such as conda packaging) otherwise. From 1cb8968a0300b3f3fcda33265974ce3ec36bbdb6 Mon Sep 17 00:00:00 2001 From: "Corey J. Nolet" Date: Thu, 7 May 2026 12:33:06 -0400 Subject: [PATCH 004/129] Collapse C++ overload quick links --- .../cpp_api/cpp-api-cluster-agglomerative.md | 2 +- fern/pages/cpp_api/cpp-api-cluster-kmeans.md | 56 ++++---- .../pages/cpp_api/cpp-api-cluster-spectral.md | 4 +- .../cpp_api/cpp-api-distance-distance.md | 14 +- .../cpp-api-neighbors-all-neighbors.md | 2 +- .../cpp_api/cpp-api-neighbors-brute-force.md | 38 +++--- fern/pages/cpp_api/cpp-api-neighbors-cagra.md | 88 ++++++------ .../pages/cpp_api/cpp-api-neighbors-common.md | 8 +- .../cpp-api-neighbors-dynamic-batching.md | 14 +- fern/pages/cpp_api/cpp-api-neighbors-hnsw.md | 36 ++--- .../cpp_api/cpp-api-neighbors-ivf-flat.md | 128 +++++++++--------- .../pages/cpp_api/cpp-api-neighbors-ivf-pq.md | 94 ++++++------- .../cpp_api/cpp-api-neighbors-nn-descent.md | 18 +-- .../pages/cpp_api/cpp-api-neighbors-refine.md | 18 +-- fern/pages/cpp_api/cpp-api-neighbors-scann.md | 2 +- .../pages/cpp_api/cpp-api-neighbors-vamana.md | 20 +-- .../cpp-api-preprocessing-quantize-binary.md | 30 ++-- .../cpp-api-preprocessing-quantize-pq.md | 6 +- .../cpp-api-preprocessing-quantize-scalar.md | 30 ++-- ...pp-api-preprocessing-spectral-embedding.md | 2 +- .../cpp_api/cpp-api-selection-select-k.md | 4 +- .../cpp_api/cpp-api-stats-silhouette-score.md | 4 +- fern/scripts/generate_api_reference.py | 28 +++- 23 files changed, 332 insertions(+), 314 deletions(-) diff --git a/fern/pages/cpp_api/cpp-api-cluster-agglomerative.md b/fern/pages/cpp_api/cpp-api-cluster-agglomerative.md index 58bc0cc11e..a779840249 100644 --- a/fern/pages/cpp_api/cpp-api-cluster-agglomerative.md +++ b/fern/pages/cpp_api/cpp-api-cluster-agglomerative.md @@ -143,7 +143,7 @@ std::optional> core_dists); _Source: `cpp/include/cuvs/cluster/agglomerative.hpp:188`_ -### linkage_graph_params::build_linkage +**Additional overload:** `linkage_graph_params::build_linkage` Given a dataset, builds the KNN graph, connects graph components and builds a linkage diff --git a/fern/pages/cpp_api/cpp-api-cluster-kmeans.md b/fern/pages/cpp_api/cpp-api-cluster-kmeans.md index 7bbb2a5187..c15c254cbe 100644 --- a/fern/pages/cpp_api/cpp-api-cluster-kmeans.md +++ b/fern/pages/cpp_api/cpp-api-cluster-kmeans.md @@ -113,7 +113,7 @@ TODO: Evaluate replacing the extent type with int64_t. Reference issue: https:// _Source: `cpp/include/cuvs/cluster/kmeans.hpp:217`_ -### cuvs::cluster::kmeans::fit +**Additional overload:** `cuvs::cluster::kmeans::fit` Find clusters with k-means algorithm using batched processing of host data. @@ -145,7 +145,7 @@ raft::host_scalar_view n_iter); _Source: `cpp/include/cuvs/cluster/kmeans.hpp:228`_ -### cuvs::cluster::kmeans::fit +**Additional overload:** `cuvs::cluster::kmeans::fit` Find clusters with k-means algorithm. @@ -179,7 +179,7 @@ Initial centroids are chosen with k-means++ algorithm. Empty clusters are reinit _Source: `cpp/include/cuvs/cluster/kmeans.hpp:278`_ -### cuvs::cluster::kmeans::fit +**Additional overload:** `cuvs::cluster::kmeans::fit` Find clusters with k-means algorithm. @@ -213,7 +213,7 @@ Initial centroids are chosen with k-means++ algorithm. Empty clusters are reinit _Source: `cpp/include/cuvs/cluster/kmeans.hpp:329`_ -### cuvs::cluster::kmeans::fit +**Additional overload:** `cuvs::cluster::kmeans::fit` Find clusters with k-means algorithm. @@ -247,7 +247,7 @@ Initial centroids are chosen with k-means++ algorithm. Empty clusters are reinit _Source: `cpp/include/cuvs/cluster/kmeans.hpp:379`_ -### cuvs::cluster::kmeans::fit +**Additional overload:** `cuvs::cluster::kmeans::fit` Find clusters with k-means algorithm. @@ -281,7 +281,7 @@ Initial centroids are chosen with k-means++ algorithm. Empty clusters are reinit _Source: `cpp/include/cuvs/cluster/kmeans.hpp:430`_ -### cuvs::cluster::kmeans::fit +**Additional overload:** `cuvs::cluster::kmeans::fit` Find clusters with k-means algorithm. @@ -315,7 +315,7 @@ Initial centroids are chosen with k-means++ algorithm. Empty clusters are reinit _Source: `cpp/include/cuvs/cluster/kmeans.hpp:480`_ -### cuvs::cluster::kmeans::fit +**Additional overload:** `cuvs::cluster::kmeans::fit` Find balanced clusters with k-means algorithm. @@ -343,7 +343,7 @@ std::optional> inertia = std::nullopt); _Source: `cpp/include/cuvs/cluster/kmeans.hpp:520`_ -### cuvs::cluster::kmeans::fit +**Additional overload:** `cuvs::cluster::kmeans::fit` Find balanced clusters with k-means algorithm. @@ -371,7 +371,7 @@ std::optional> inertia = std::nullopt); _Source: `cpp/include/cuvs/cluster/kmeans.hpp:557`_ -### cuvs::cluster::kmeans::fit +**Additional overload:** `cuvs::cluster::kmeans::fit` Find balanced clusters with k-means algorithm. @@ -399,7 +399,7 @@ std::optional> inertia = std::nullopt); _Source: `cpp/include/cuvs/cluster/kmeans.hpp:594`_ -### cuvs::cluster::kmeans::fit +**Additional overload:** `cuvs::cluster::kmeans::fit` Find balanced clusters with k-means algorithm. @@ -461,7 +461,7 @@ raft::host_scalar_view inertia); _Source: `cpp/include/cuvs/cluster/kmeans.hpp:686`_ -### cuvs::cluster::kmeans::predict +**Additional overload:** `cuvs::cluster::kmeans::predict` Predict the closest cluster each sample in X belongs to. @@ -495,7 +495,7 @@ raft::host_scalar_view inertia); _Source: `cpp/include/cuvs/cluster/kmeans.hpp:753`_ -### cuvs::cluster::kmeans::predict +**Additional overload:** `cuvs::cluster::kmeans::predict` Predict the closest cluster each sample in X belongs to. @@ -529,7 +529,7 @@ raft::host_scalar_view inertia); _Source: `cpp/include/cuvs/cluster/kmeans.hpp:811`_ -### cuvs::cluster::kmeans::predict +**Additional overload:** `cuvs::cluster::kmeans::predict` Predict the closest cluster each sample in X belongs to. @@ -563,7 +563,7 @@ raft::host_scalar_view inertia); _Source: `cpp/include/cuvs/cluster/kmeans.hpp:869`_ -### cuvs::cluster::kmeans::predict +**Additional overload:** `cuvs::cluster::kmeans::predict` Predict the closest cluster each sample in X belongs to. @@ -591,7 +591,7 @@ raft::device_vector_view labels); _Source: `cpp/include/cuvs/cluster/kmeans.hpp:916`_ -### cuvs::cluster::kmeans::predict +**Additional overload:** `cuvs::cluster::kmeans::predict` Predict the closest cluster each sample in X belongs to. @@ -619,7 +619,7 @@ raft::device_vector_view labels); _Source: `cpp/include/cuvs/cluster/kmeans.hpp:960`_ -### cuvs::cluster::kmeans::predict +**Additional overload:** `cuvs::cluster::kmeans::predict` Predict the closest cluster each sample in X belongs to. @@ -647,7 +647,7 @@ raft::device_vector_view labels); _Source: `cpp/include/cuvs/cluster/kmeans.hpp:1004`_ -### cuvs::cluster::kmeans::predict +**Additional overload:** `cuvs::cluster::kmeans::predict` Predict the closest cluster each sample in X belongs to. @@ -675,7 +675,7 @@ raft::device_vector_view labels); _Source: `cpp/include/cuvs/cluster/kmeans.hpp:1048`_ -### cuvs::cluster::kmeans::predict +**Additional overload:** `cuvs::cluster::kmeans::predict` Predict the closest cluster each sample in X belongs to. @@ -703,7 +703,7 @@ raft::device_vector_view labels); _Source: `cpp/include/cuvs/cluster/kmeans.hpp:1092`_ -### cuvs::cluster::kmeans::predict +**Additional overload:** `cuvs::cluster::kmeans::predict` Predict the closest cluster each sample in X belongs to. @@ -767,7 +767,7 @@ in the input. _Source: `cpp/include/cuvs/cluster/kmeans.hpp:1188`_ -### cuvs::cluster::kmeans::fit_predict +**Additional overload:** `cuvs::cluster::kmeans::fit_predict` Compute k-means clustering and predicts cluster index for each sample @@ -803,7 +803,7 @@ in the input. _Source: `cpp/include/cuvs/cluster/kmeans.hpp:1243`_ -### cuvs::cluster::kmeans::fit_predict +**Additional overload:** `cuvs::cluster::kmeans::fit_predict` Compute k-means clustering and predicts cluster index for each sample @@ -839,7 +839,7 @@ in the input. _Source: `cpp/include/cuvs/cluster/kmeans.hpp:1298`_ -### cuvs::cluster::kmeans::fit_predict +**Additional overload:** `cuvs::cluster::kmeans::fit_predict` Compute k-means clustering and predicts cluster index for each sample @@ -875,7 +875,7 @@ in the input. _Source: `cpp/include/cuvs/cluster/kmeans.hpp:1353`_ -### cuvs::cluster::kmeans::fit_predict +**Additional overload:** `cuvs::cluster::kmeans::fit_predict` Compute balanced k-means clustering and predicts cluster index for each sample @@ -905,7 +905,7 @@ in the input. _Source: `cpp/include/cuvs/cluster/kmeans.hpp:1400`_ -### cuvs::cluster::kmeans::fit_predict +**Additional overload:** `cuvs::cluster::kmeans::fit_predict` Compute balanced k-means clustering and predicts cluster index for each sample @@ -963,7 +963,7 @@ raft::device_matrix_view X_new); _Source: `cpp/include/cuvs/cluster/kmeans.hpp:1463`_ -### cuvs::cluster::kmeans::transform +**Additional overload:** `cuvs::cluster::kmeans::transform` Transform X to a cluster-distance space. @@ -1020,7 +1020,7 @@ std::optional> sample_weight = std::n _Source: `cpp/include/cuvs/cluster/kmeans.hpp:1503`_ -### cuvs::cluster::kmeans::cluster_cost +**Additional overload:** `cuvs::cluster::kmeans::cluster_cost` Compute cluster cost @@ -1049,7 +1049,7 @@ std::optional> sample_weight = std:: _Source: `cpp/include/cuvs/cluster/kmeans.hpp:1524`_ -### cuvs::cluster::kmeans::cluster_cost +**Additional overload:** `cuvs::cluster::kmeans::cluster_cost` Compute (optionally weighted) cluster cost @@ -1078,7 +1078,7 @@ std::optional> sample_weight = st _Source: `cpp/include/cuvs/cluster/kmeans.hpp:1545`_ -### cuvs::cluster::kmeans::cluster_cost +**Additional overload:** `cuvs::cluster::kmeans::cluster_cost` Compute (optionally weighted) cluster cost diff --git a/fern/pages/cpp_api/cpp-api-cluster-spectral.md b/fern/pages/cpp_api/cpp-api-cluster-spectral.md index 873cdab131..8965fe66af 100644 --- a/fern/pages/cpp_api/cpp-api-cluster-spectral.md +++ b/fern/pages/cpp_api/cpp-api-cluster-spectral.md @@ -63,7 +63,7 @@ n_clusters-1) _Source: `cpp/include/cuvs/cluster/spectral.hpp:84`_ -### cuvs::cluster::spectral::fit_predict +**Additional overload:** `cuvs::cluster::spectral::fit_predict` Perform spectral clustering on a connectivity graph @@ -91,7 +91,7 @@ n_clusters-1) _Source: `cpp/include/cuvs/cluster/spectral.hpp:122`_ -### cuvs::cluster::spectral::fit_predict +**Additional overload:** `cuvs::cluster::spectral::fit_predict` Perform spectral clustering on a dense dataset diff --git a/fern/pages/cpp_api/cpp-api-distance-distance.md b/fern/pages/cpp_api/cpp-api-distance-distance.md index 79bd8c7e77..350fcf0992 100644 --- a/fern/pages/cpp_api/cpp-api-distance-distance.md +++ b/fern/pages/cpp_api/cpp-api-distance-distance.md @@ -43,7 +43,7 @@ Note: Only contiguous row- or column-major layouts supported currently. Usage ex _Source: `cpp/include/cuvs/distance/distance.hpp:161`_ -### kernels::pairwise_distance +**Additional overload:** `kernels::pairwise_distance` Compute pairwise distances for two matrices @@ -76,7 +76,7 @@ Note: Only contiguous row- or column-major layouts supported currently. Usage ex _Source: `cpp/include/cuvs/distance/distance.hpp:205`_ -### kernels::pairwise_distance +**Additional overload:** `kernels::pairwise_distance` Compute pairwise distances for two matrices @@ -109,7 +109,7 @@ Note: Only contiguous row- or column-major layouts supported currently. Usage ex _Source: `cpp/include/cuvs/distance/distance.hpp:248`_ -### kernels::pairwise_distance +**Additional overload:** `kernels::pairwise_distance` Compute pairwise distances for two matrices @@ -142,7 +142,7 @@ Note: Only contiguous row- or column-major layouts supported currently. Usage ex _Source: `cpp/include/cuvs/distance/distance.hpp:292`_ -### kernels::pairwise_distance +**Additional overload:** `kernels::pairwise_distance` Compute pairwise distances for two matrices @@ -175,7 +175,7 @@ Note: Only contiguous row- or column-major layouts supported currently. Usage ex _Source: `cpp/include/cuvs/distance/distance.hpp:335`_ -### kernels::pairwise_distance +**Additional overload:** `kernels::pairwise_distance` Compute pairwise distances for two matrices @@ -208,7 +208,7 @@ Note: Only contiguous row- or column-major layouts supported currently. Usage ex _Source: `cpp/include/cuvs/distance/distance.hpp:378`_ -### kernels::pairwise_distance +**Additional overload:** `kernels::pairwise_distance` Compute sparse pairwise distances between x and y, using the provided @@ -240,7 +240,7 @@ input configuration and distance function. _Source: `cpp/include/cuvs/distance/distance.hpp:419`_ -### kernels::pairwise_distance +**Additional overload:** `kernels::pairwise_distance` Compute sparse pairwise distances between x and y, using the provided diff --git a/fern/pages/cpp_api/cpp-api-neighbors-all-neighbors.md b/fern/pages/cpp_api/cpp-api-neighbors-all-neighbors.md index 13879f0a16..9ce3bfada1 100644 --- a/fern/pages/cpp_api/cpp-api-neighbors-all-neighbors.md +++ b/fern/pages/cpp_api/cpp-api-neighbors-all-neighbors.md @@ -82,7 +82,7 @@ training vectors) Usage example: compute core_distances. If core_distances is gi _Source: `cpp/include/cuvs/neighbors/all_neighbors.hpp:126`_ -### cuvs::neighbors::all_neighbors::build +**Additional overload:** `cuvs::neighbors::all_neighbors::build` Builds an approximate all-neighbors knn graph (find nearest neighbors for all the training diff --git a/fern/pages/cpp_api/cpp-api-neighbors-brute-force.md b/fern/pages/cpp_api/cpp-api-neighbors-brute-force.md index b1696bb251..34003bf2bc 100644 --- a/fern/pages/cpp_api/cpp-api-neighbors-brute-force.md +++ b/fern/pages/cpp_api/cpp-api-neighbors-brute-force.md @@ -32,7 +32,7 @@ Constructs an empty index. This index will either need to be trained with `build _Source: `cpp/include/cuvs/neighbors/brute_force.hpp:54`_ -### cuvs::neighbors::brute_force::index +**Additional overload:** `cuvs::neighbors::brute_force::index` Construct a brute force index from dataset @@ -62,7 +62,7 @@ Constructs a brute force index from a dataset. This lets us precompute norms for _Source: `cpp/include/cuvs/neighbors/brute_force.hpp:63`_ -### cuvs::neighbors::brute_force::index +**Additional overload:** `cuvs::neighbors::brute_force::index` Construct a brute force index from dataset @@ -92,7 +92,7 @@ Constructs a brute force index from a dataset. This lets us precompute norms for _Source: `cpp/include/cuvs/neighbors/brute_force.hpp:76`_ -### cuvs::neighbors::brute_force::index +**Additional overload:** `cuvs::neighbors::brute_force::index` Construct a brute force index from dataset @@ -122,7 +122,7 @@ This class stores a non-owning reference to the dataset and norms. Having precom _Source: `cpp/include/cuvs/neighbors/brute_force.hpp:87`_ -### cuvs::neighbors::brute_force::index +**Additional overload:** `cuvs::neighbors::brute_force::index` Construct a brute force index from dataset @@ -152,7 +152,7 @@ Constructs a brute force index from a dataset. This lets us precompute norms for _Source: `cpp/include/cuvs/neighbors/brute_force.hpp:100`_ -### cuvs::neighbors::brute_force::index +**Additional overload:** `cuvs::neighbors::brute_force::index` Construct a brute force index from dataset @@ -204,7 +204,7 @@ raft::device_matrix_view dataset); _Source: `cpp/include/cuvs/neighbors/brute_force.hpp:120`_ -### cuvs::neighbors::brute_force::update_dataset +**Additional overload:** `cuvs::neighbors::brute_force::update_dataset` Replace the dataset with a new dataset. @@ -359,7 +359,7 @@ the constructed brute-force index _Source: `cpp/include/cuvs/neighbors/brute_force.hpp:191`_ -### cuvs::neighbors::brute_force::build +**Additional overload:** `cuvs::neighbors::brute_force::build` Build the index from the dataset for efficient search. @@ -386,7 +386,7 @@ the constructed brute-force index _Source: `cpp/include/cuvs/neighbors/brute_force.hpp:205`_ -### cuvs::neighbors::brute_force::build +**Additional overload:** `cuvs::neighbors::brute_force::build` Build the index from the dataset for efficient search. @@ -415,7 +415,7 @@ the constructed brute force index _Source: `cpp/include/cuvs/neighbors/brute_force.hpp:232`_ -### cuvs::neighbors::brute_force::build +**Additional overload:** `cuvs::neighbors::brute_force::build` Build the index from the dataset for efficient search. @@ -442,7 +442,7 @@ the constructed brute-force index _Source: `cpp/include/cuvs/neighbors/brute_force.hpp:246`_ -### cuvs::neighbors::brute_force::build +**Additional overload:** `cuvs::neighbors::brute_force::build` Build the index from the dataset for efficient search. @@ -471,7 +471,7 @@ the constructed brute force index _Source: `cpp/include/cuvs/neighbors/brute_force.hpp:272`_ -### cuvs::neighbors::brute_force::build +**Additional overload:** `cuvs::neighbors::brute_force::build` Build the index from the dataset for efficient search. @@ -530,7 +530,7 @@ T metric_arg); _Source: `cpp/include/cuvs/neighbors/brute_force.hpp:609`_ -### cuvs::neighbors::brute_force::metric +**Additional overload:** `cuvs::neighbors::brute_force::metric` Distance metric used for retrieval @@ -544,7 +544,7 @@ cuvs::distance::DistanceType metric() const noexcept; _Source: `cpp/include/cuvs/neighbors/brute_force.hpp:615`_ -### cuvs::neighbors::brute_force::metric_arg +**Additional overload:** `cuvs::neighbors::brute_force::metric_arg` Metric argument @@ -617,7 +617,7 @@ The serialization format can be subject to changes, therefore loading an index s _Source: `cpp/include/cuvs/neighbors/brute_force.hpp:724`_ -### cuvs::neighbors::brute_force::serialize +**Additional overload:** `cuvs::neighbors::brute_force::serialize` Save the index to file. @@ -651,7 +651,7 @@ The serialization format can be subject to changes, therefore loading an index s _Source: `cpp/include/cuvs/neighbors/brute_force.hpp:755`_ -### cuvs::neighbors::brute_force::serialize +**Additional overload:** `cuvs::neighbors::brute_force::serialize` Write the index to an output stream @@ -679,7 +679,7 @@ The serialization format can be subject to changes, therefore loading an index s _Source: `cpp/include/cuvs/neighbors/brute_force.hpp:783`_ -### cuvs::neighbors::brute_force::serialize +**Additional overload:** `cuvs::neighbors::brute_force::serialize` Write the index to an output stream @@ -733,7 +733,7 @@ The serialization format can be subject to changes, therefore loading an index s _Source: `cpp/include/cuvs/neighbors/brute_force.hpp:840`_ -### cuvs::neighbors::brute_force::deserialize +**Additional overload:** `cuvs::neighbors::brute_force::deserialize` Load index from file. @@ -759,7 +759,7 @@ The serialization format can be subject to changes, therefore loading an index s _Source: `cpp/include/cuvs/neighbors/brute_force.hpp:867`_ -### cuvs::neighbors::brute_force::deserialize +**Additional overload:** `cuvs::neighbors::brute_force::deserialize` Load index from input stream @@ -785,7 +785,7 @@ The serialization format can be subject to changes, therefore loading an index s _Source: `cpp/include/cuvs/neighbors/brute_force.hpp:894`_ -### cuvs::neighbors::brute_force::deserialize +**Additional overload:** `cuvs::neighbors::brute_force::deserialize` Load index from input stream diff --git a/fern/pages/cpp_api/cpp-api-neighbors-cagra.md b/fern/pages/cpp_api/cpp-api-neighbors-cagra.md index af3f3e2c49..efa76ebeef 100644 --- a/fern/pages/cpp_api/cpp-api-neighbors-cagra.md +++ b/fern/pages/cpp_api/cpp-api-neighbors-cagra.md @@ -302,7 +302,7 @@ index(const index&) = delete; _Source: `cpp/include/cuvs/neighbors/cagra.hpp:488`_ -### cuvs::neighbors::cagra::index +**Additional overload:** `cuvs::neighbors::cagra::index` Construct an empty index. @@ -325,7 +325,7 @@ cuvs::distance::DistanceType metric = cuvs::distance::DistanceType::L2Expanded) _Source: `cpp/include/cuvs/neighbors/cagra.hpp:496`_ -### cuvs::neighbors::cagra::index +**Additional overload:** `cuvs::neighbors::cagra::index` Construct an index from dataset and knn_graph arrays @@ -382,7 +382,7 @@ If the new dataset rows are aligned on 16 bytes, then only a reference is stored _Source: `cpp/include/cuvs/neighbors/cagra.hpp:597`_ -### cuvs::neighbors::cagra::update_dataset +**Additional overload:** `cuvs::neighbors::cagra::update_dataset` Set the dataset reference explicitly to a device matrix view with padding. @@ -404,7 +404,7 @@ raft::device_matrix_view dataset); _Source: `cpp/include/cuvs/neighbors/cagra.hpp:609`_ -### cuvs::neighbors::cagra::update_dataset +**Additional overload:** `cuvs::neighbors::cagra::update_dataset` Replace the dataset with a new dataset. @@ -428,7 +428,7 @@ We create a copy of the dataset on the device. The index manages the lifetime of _Source: `cpp/include/cuvs/neighbors/cagra.hpp:628`_ -### cuvs::neighbors::cagra::update_dataset +**Additional overload:** `cuvs::neighbors::cagra::update_dataset` Replace the dataset with a new dataset. It is expected that the same set of vectors are used @@ -478,7 +478,7 @@ Since the new graph is a device array, we store a reference to that, and it is t _Source: `cpp/include/cuvs/neighbors/cagra.hpp:677`_ -### cuvs::neighbors::cagra::update_graph +**Additional overload:** `cuvs::neighbors::cagra::update_graph` Replace the graph with a new graph. @@ -523,7 +523,7 @@ void update_source_indices(raft::device_vector&& source_ind _Source: `cpp/include/cuvs/neighbors/cagra.hpp:713`_ -### cuvs::neighbors::cagra::update_source_indices +**Additional overload:** `cuvs::neighbors::cagra::update_source_indices` Copy the provided source indices into the index. @@ -548,7 +548,7 @@ source_indices); _Source: `cpp/include/cuvs/neighbors/cagra.hpp:723`_ -### cuvs::neighbors::cagra::update_dataset +**Additional overload:** `cuvs::neighbors::cagra::update_dataset` Update the dataset from a disk file using a file descriptor. @@ -571,7 +571,7 @@ This method configures the index to use a disk-based dataset. The dataset file s _Source: `cpp/include/cuvs/neighbors/cagra.hpp:759`_ -### cuvs::neighbors::cagra::update_graph +**Additional overload:** `cuvs::neighbors::cagra::update_graph` Update the graph from a disk file using a file descriptor. @@ -650,7 +650,7 @@ the constructed cagra index _Source: `cpp/include/cuvs/neighbors/cagra.hpp:923`_ -### cuvs::neighbors::cagra::build +**Additional overload:** `cuvs::neighbors::cagra::build` Build the index from the dataset for efficient search. @@ -679,7 +679,7 @@ the constructed cagra index _Source: `cpp/include/cuvs/neighbors/cagra.hpp:962`_ -### cuvs::neighbors::cagra::build +**Additional overload:** `cuvs::neighbors::cagra::build` Build the index from the dataset for efficient search. @@ -708,7 +708,7 @@ the constructed cagra index _Source: `cpp/include/cuvs/neighbors/cagra.hpp:1001`_ -### cuvs::neighbors::cagra::build +**Additional overload:** `cuvs::neighbors::cagra::build` Build the index from the dataset for efficient search. @@ -737,7 +737,7 @@ the constructed cagra index _Source: `cpp/include/cuvs/neighbors/cagra.hpp:1039`_ -### cuvs::neighbors::cagra::build +**Additional overload:** `cuvs::neighbors::cagra::build` Build the index from the dataset for efficient search. @@ -766,7 +766,7 @@ the constructed cagra index _Source: `cpp/include/cuvs/neighbors/cagra.hpp:1079`_ -### cuvs::neighbors::cagra::build +**Additional overload:** `cuvs::neighbors::cagra::build` Build the index from the dataset for efficient search. @@ -795,7 +795,7 @@ the constructed cagra index _Source: `cpp/include/cuvs/neighbors/cagra.hpp:1120`_ -### cuvs::neighbors::cagra::build +**Additional overload:** `cuvs::neighbors::cagra::build` Build the index from the dataset for efficient search. @@ -824,7 +824,7 @@ the constructed cagra index _Source: `cpp/include/cuvs/neighbors/cagra.hpp:1161`_ -### cuvs::neighbors::cagra::build +**Additional overload:** `cuvs::neighbors::cagra::build` Build the index from the dataset for efficient search. @@ -891,7 +891,7 @@ Usage example: part. The data will be copied from the current index in this func _Source: `cpp/include/cuvs/neighbors/cagra.hpp:1244`_ -### cuvs::neighbors::cagra::extend +**Additional overload:** `cuvs::neighbors::cagra::extend` Add new vectors to a CAGRA index @@ -925,7 +925,7 @@ Usage example: part. The data will be copied from the current index in this func _Source: `cpp/include/cuvs/neighbors/cagra.hpp:1282`_ -### cuvs::neighbors::cagra::extend +**Additional overload:** `cuvs::neighbors::cagra::extend` Add new vectors to a CAGRA index @@ -959,7 +959,7 @@ Usage example: part. The data will be copied from the current index in this func _Source: `cpp/include/cuvs/neighbors/cagra.hpp:1320`_ -### cuvs::neighbors::cagra::extend +**Additional overload:** `cuvs::neighbors::cagra::extend` Add new vectors to a CAGRA index @@ -993,7 +993,7 @@ Usage example: part. The data will be copied from the current index in this func _Source: `cpp/include/cuvs/neighbors/cagra.hpp:1358`_ -### cuvs::neighbors::cagra::extend +**Additional overload:** `cuvs::neighbors::cagra::extend` Add new vectors to a CAGRA index @@ -1027,7 +1027,7 @@ Usage example: part. The data will be copied from the current index in this func _Source: `cpp/include/cuvs/neighbors/cagra.hpp:1396`_ -### cuvs::neighbors::cagra::extend +**Additional overload:** `cuvs::neighbors::cagra::extend` Add new vectors to a CAGRA index @@ -1061,7 +1061,7 @@ Usage example: part. The data will be copied from the current index in this func _Source: `cpp/include/cuvs/neighbors/cagra.hpp:1434`_ -### cuvs::neighbors::cagra::extend +**Additional overload:** `cuvs::neighbors::cagra::extend` Add new vectors to a CAGRA index @@ -1095,7 +1095,7 @@ Usage example: part. The data will be copied from the current index in this func _Source: `cpp/include/cuvs/neighbors/cagra.hpp:1472`_ -### cuvs::neighbors::cagra::extend +**Additional overload:** `cuvs::neighbors::cagra::extend` Add new vectors to a CAGRA index @@ -1208,7 +1208,7 @@ Experimental, both the API and the serialization format are subject to change. _Source: `cpp/include/cuvs/neighbors/cagra.hpp:1785`_ -### cuvs::neighbors::cagra::serialize +**Additional overload:** `cuvs::neighbors::cagra::serialize` Write the index to an output stream @@ -1236,7 +1236,7 @@ Experimental, both the API and the serialization format are subject to change. _Source: `cpp/include/cuvs/neighbors/cagra.hpp:1811`_ -### cuvs::neighbors::cagra::deserialize +**Additional overload:** `cuvs::neighbors::cagra::deserialize` Load index from input stream @@ -1262,7 +1262,7 @@ Experimental, both the API and the serialization format are subject to change. _Source: `cpp/include/cuvs/neighbors/cagra.hpp:1837`_ -### cuvs::neighbors::cagra::serialize +**Additional overload:** `cuvs::neighbors::cagra::serialize` Save the index to file. @@ -1290,7 +1290,7 @@ Experimental, both the API and the serialization format are subject to change. _Source: `cpp/include/cuvs/neighbors/cagra.hpp:1863`_ -### cuvs::neighbors::cagra::deserialize +**Additional overload:** `cuvs::neighbors::cagra::deserialize` Load index from file. @@ -1316,7 +1316,7 @@ Experimental, both the API and the serialization format are subject to change. _Source: `cpp/include/cuvs/neighbors/cagra.hpp:1890`_ -### cuvs::neighbors::cagra::serialize +**Additional overload:** `cuvs::neighbors::cagra::serialize` Write the index to an output stream @@ -1344,7 +1344,7 @@ Experimental, both the API and the serialization format are subject to change. _Source: `cpp/include/cuvs/neighbors/cagra.hpp:1916`_ -### cuvs::neighbors::cagra::deserialize +**Additional overload:** `cuvs::neighbors::cagra::deserialize` Load index from input stream @@ -1370,7 +1370,7 @@ Experimental, both the API and the serialization format are subject to change. _Source: `cpp/include/cuvs/neighbors/cagra.hpp:1942`_ -### cuvs::neighbors::cagra::serialize +**Additional overload:** `cuvs::neighbors::cagra::serialize` Save the index to file. @@ -1398,7 +1398,7 @@ Experimental, both the API and the serialization format are subject to change. _Source: `cpp/include/cuvs/neighbors/cagra.hpp:1968`_ -### cuvs::neighbors::cagra::deserialize +**Additional overload:** `cuvs::neighbors::cagra::deserialize` Load index from file. @@ -1424,7 +1424,7 @@ Experimental, both the API and the serialization format are subject to change. _Source: `cpp/include/cuvs/neighbors/cagra.hpp:1995`_ -### cuvs::neighbors::cagra::serialize +**Additional overload:** `cuvs::neighbors::cagra::serialize` Write the index to an output stream @@ -1452,7 +1452,7 @@ Experimental, both the API and the serialization format are subject to change. _Source: `cpp/include/cuvs/neighbors/cagra.hpp:2021`_ -### cuvs::neighbors::cagra::deserialize +**Additional overload:** `cuvs::neighbors::cagra::deserialize` Load index from input stream @@ -1478,7 +1478,7 @@ Experimental, both the API and the serialization format are subject to change. _Source: `cpp/include/cuvs/neighbors/cagra.hpp:2047`_ -### cuvs::neighbors::cagra::serialize +**Additional overload:** `cuvs::neighbors::cagra::serialize` Save the index to file. @@ -1506,7 +1506,7 @@ Experimental, both the API and the serialization format are subject to change. _Source: `cpp/include/cuvs/neighbors/cagra.hpp:2073`_ -### cuvs::neighbors::cagra::deserialize +**Additional overload:** `cuvs::neighbors::cagra::deserialize` Load index from file. @@ -1532,7 +1532,7 @@ Experimental, both the API and the serialization format are subject to change. _Source: `cpp/include/cuvs/neighbors/cagra.hpp:2100`_ -### cuvs::neighbors::cagra::serialize +**Additional overload:** `cuvs::neighbors::cagra::serialize` Write the index to an output stream @@ -1560,7 +1560,7 @@ Experimental, both the API and the serialization format are subject to change. _Source: `cpp/include/cuvs/neighbors/cagra.hpp:2126`_ -### cuvs::neighbors::cagra::deserialize +**Additional overload:** `cuvs::neighbors::cagra::deserialize` Load index from input stream @@ -1616,7 +1616,7 @@ NOTE: The saved index can only be read by the hnswlib wrapper in cuVS, as the se _Source: `cpp/include/cuvs/neighbors/cagra.hpp:2182`_ -### cuvs::neighbors::cagra::serialize_to_hnswlib +**Additional overload:** `cuvs::neighbors::cagra::serialize_to_hnswlib` Save a CAGRA build index in hnswlib base-layer-only serialized format @@ -1646,7 +1646,7 @@ NOTE: The saved index can only be read by the hnswlib wrapper in cuVS, as the se _Source: `cpp/include/cuvs/neighbors/cagra.hpp:2216`_ -### cuvs::neighbors::cagra::serialize_to_hnswlib +**Additional overload:** `cuvs::neighbors::cagra::serialize_to_hnswlib` Write the CAGRA built index as a base layer HNSW index to an output stream @@ -1676,7 +1676,7 @@ NOTE: The saved index can only be read by the hnswlib wrapper in cuVS, as the se _Source: `cpp/include/cuvs/neighbors/cagra.hpp:2249`_ -### cuvs::neighbors::cagra::serialize_to_hnswlib +**Additional overload:** `cuvs::neighbors::cagra::serialize_to_hnswlib` Save a CAGRA build index in hnswlib base-layer-only serialized format @@ -1706,7 +1706,7 @@ NOTE: The saved index can only be read by the hnswlib wrapper in cuVS, as the se _Source: `cpp/include/cuvs/neighbors/cagra.hpp:2283`_ -### cuvs::neighbors::cagra::serialize_to_hnswlib +**Additional overload:** `cuvs::neighbors::cagra::serialize_to_hnswlib` Write the CAGRA built index as a base layer HNSW index to an output stream @@ -1736,7 +1736,7 @@ NOTE: The saved index can only be read by the hnswlib wrapper in cuVS, as the se _Source: `cpp/include/cuvs/neighbors/cagra.hpp:2316`_ -### cuvs::neighbors::cagra::serialize_to_hnswlib +**Additional overload:** `cuvs::neighbors::cagra::serialize_to_hnswlib` Save a CAGRA build index in hnswlib base-layer-only serialized format @@ -1766,7 +1766,7 @@ NOTE: The saved index can only be read by the hnswlib wrapper in cuVS, as the se _Source: `cpp/include/cuvs/neighbors/cagra.hpp:2350`_ -### cuvs::neighbors::cagra::serialize_to_hnswlib +**Additional overload:** `cuvs::neighbors::cagra::serialize_to_hnswlib` Write the CAGRA built index as a base layer HNSW index to an output stream @@ -1796,7 +1796,7 @@ NOTE: The saved index can only be read by the hnswlib wrapper in cuVS, as the se _Source: `cpp/include/cuvs/neighbors/cagra.hpp:2383`_ -### cuvs::neighbors::cagra::serialize_to_hnswlib +**Additional overload:** `cuvs::neighbors::cagra::serialize_to_hnswlib` Save a CAGRA build index in hnswlib base-layer-only serialized format diff --git a/fern/pages/cpp_api/cpp-api-neighbors-common.md b/fern/pages/cpp_api/cpp-api-neighbors-common.md index 3ccf52b309..b65ece08a0 100644 --- a/fern/pages/cpp_api/cpp-api-neighbors-common.md +++ b/fern/pages/cpp_api/cpp-api-neighbors-common.md @@ -108,7 +108,7 @@ FilterType get_filter_type() const override; _Source: `cpp/include/cuvs/neighbors/common.hpp:520`_ -### filtering::operator +**Additional overload:** `filtering::operator` If the original filter takes three arguments, then don't modify the arguments. @@ -130,7 +130,7 @@ If the original filter takes two arguments, then we are using `inds_ptr_` to obt _Source: `cpp/include/cuvs/neighbors/common.hpp:544`_ -### filtering::operator +**Additional overload:** `filtering::operator` ```cpp inline _RAFT_HOST_DEVICE bool operator()( @@ -146,7 +146,7 @@ const uint32_t sample_ix) const; _Source: `cpp/include/cuvs/neighbors/common.hpp:571`_ -### filtering::get_filter_type +**Additional overload:** `filtering::get_filter_type` ```cpp FilterType get_filter_type() const override; @@ -176,7 +176,7 @@ _RAFT_HOST_DEVICE bitset_filter(const view_t bitset_for_filtering); _Source: `cpp/include/cuvs/neighbors/common.hpp:600`_ -### filtering::get_filter_type +**Additional overload:** `filtering::get_filter_type` ```cpp FilterType get_filter_type() const override; diff --git a/fern/pages/cpp_api/cpp-api-neighbors-dynamic-batching.md b/fern/pages/cpp_api/cpp-api-neighbors-dynamic-batching.md index 3cef4b847f..903cde1ed9 100644 --- a/fern/pages/cpp_api/cpp-api-neighbors-dynamic-batching.md +++ b/fern/pages/cpp_api/cpp-api-neighbors-dynamic-batching.md @@ -124,7 +124,7 @@ The search parameters of the upstream index and the optional filtering function _Source: `cpp/include/cuvs/neighbors/dynamic_batching.hpp:214`_ -### detail::search +**Additional overload:** `detail::search` ```cpp void search(raft::resources const& res, @@ -152,7 +152,7 @@ raft::device_matrix_view distances); _Source: `cpp/include/cuvs/neighbors/dynamic_batching.hpp:222`_ -### detail::search +**Additional overload:** `detail::search` ```cpp void search(raft::resources const& res, @@ -180,7 +180,7 @@ raft::device_matrix_view distances); _Source: `cpp/include/cuvs/neighbors/dynamic_batching.hpp:230`_ -### detail::search +**Additional overload:** `detail::search` ```cpp void search(raft::resources const& res, @@ -208,7 +208,7 @@ raft::device_matrix_view distances); _Source: `cpp/include/cuvs/neighbors/dynamic_batching.hpp:238`_ -### detail::search +**Additional overload:** `detail::search` ```cpp void search(raft::resources const& res, @@ -236,7 +236,7 @@ raft::device_matrix_view distances); _Source: `cpp/include/cuvs/neighbors/dynamic_batching.hpp:246`_ -### detail::search +**Additional overload:** `detail::search` ```cpp void search(raft::resources const& res, @@ -264,7 +264,7 @@ raft::device_matrix_view distances); _Source: `cpp/include/cuvs/neighbors/dynamic_batching.hpp:254`_ -### detail::search +**Additional overload:** `detail::search` ```cpp void search(raft::resources const& res, @@ -292,7 +292,7 @@ raft::device_matrix_view distances); _Source: `cpp/include/cuvs/neighbors/dynamic_batching.hpp:262`_ -### detail::search +**Additional overload:** `detail::search` ```cpp void search(raft::resources const& res, diff --git a/fern/pages/cpp_api/cpp-api-neighbors-hnsw.md b/fern/pages/cpp_api/cpp-api-neighbors-hnsw.md index 4deb5a274c..5d51207781 100644 --- a/fern/pages/cpp_api/cpp-api-neighbors-hnsw.md +++ b/fern/pages/cpp_api/cpp-api-neighbors-hnsw.md @@ -193,7 +193,7 @@ The resulting graph is compatible for HNSW search, but is not an exact equivalen _Source: `cpp/include/cuvs/neighbors/hnsw.hpp:254`_ -### cuvs::neighbors::hnsw::build +**Additional overload:** `cuvs::neighbors::hnsw::build` Build an HNSW index on the GPU @@ -220,7 +220,7 @@ The resulting graph is compatible for HNSW search, but is not an exact equivalen _Source: `cpp/include/cuvs/neighbors/hnsw.hpp:312`_ -### cuvs::neighbors::hnsw::build +**Additional overload:** `cuvs::neighbors::hnsw::build` Build an HNSW index on the GPU @@ -247,7 +247,7 @@ The resulting graph is compatible for HNSW search, but is not an exact equivalen _Source: `cpp/include/cuvs/neighbors/hnsw.hpp:370`_ -### cuvs::neighbors::hnsw::build +**Additional overload:** `cuvs::neighbors::hnsw::build` Build an HNSW index on the GPU @@ -308,7 +308,7 @@ NOTE: When `hnsw::index_params.hierarchy` is: 1. `NONE`: This method uses the fi _Source: `cpp/include/cuvs/neighbors/hnsw.hpp:471`_ -### cuvs::neighbors::hnsw::from_cagra +**Additional overload:** `cuvs::neighbors::hnsw::from_cagra` Construct an hnswlib index from a CAGRA index @@ -338,7 +338,7 @@ NOTE: When `hnsw::index_params.hierarchy` is: 1. `NONE`: This method uses the fi _Source: `cpp/include/cuvs/neighbors/hnsw.hpp:507`_ -### cuvs::neighbors::hnsw::from_cagra +**Additional overload:** `cuvs::neighbors::hnsw::from_cagra` Construct an hnswlib index from a CAGRA index @@ -368,7 +368,7 @@ NOTE: When `hnsw::index_params.hierarchy` is: 1. `NONE`: This method uses the fi _Source: `cpp/include/cuvs/neighbors/hnsw.hpp:543`_ -### cuvs::neighbors::hnsw::from_cagra +**Additional overload:** `cuvs::neighbors::hnsw::from_cagra` Construct an hnswlib index from a CAGRA index @@ -430,7 +430,7 @@ NOTE: The HNSW index can only be extended when the `hnsw::index_params.hierarchy _Source: `cpp/include/cuvs/neighbors/hnsw.hpp:624`_ -### cuvs::neighbors::hnsw::extend +**Additional overload:** `cuvs::neighbors::hnsw::extend` Add new vectors to an HNSW index @@ -458,7 +458,7 @@ NOTE: The HNSW index can only be extended when the `hnsw::index_params.hierarchy _Source: `cpp/include/cuvs/neighbors/hnsw.hpp:658`_ -### cuvs::neighbors::hnsw::extend +**Additional overload:** `cuvs::neighbors::hnsw::extend` Add new vectors to an HNSW index @@ -486,7 +486,7 @@ NOTE: The HNSW index can only be extended when the `hnsw::index_params.hierarchy _Source: `cpp/include/cuvs/neighbors/hnsw.hpp:692`_ -### cuvs::neighbors::hnsw::extend +**Additional overload:** `cuvs::neighbors::hnsw::extend` Add new vectors to an HNSW index @@ -571,7 +571,7 @@ NOTE: The HNSW index can only be searched by the hnswlib wrapper in cuVS when th _Source: `cpp/include/cuvs/neighbors/hnsw.hpp:794`_ -### cuvs::neighbors::hnsw::search +**Additional overload:** `cuvs::neighbors::hnsw::search` Search HNSW index constructed from a CAGRA index @@ -603,7 +603,7 @@ NOTE: The HNSW index can only be searched by the hnswlib wrapper in cuVS when th _Source: `cpp/include/cuvs/neighbors/hnsw.hpp:838`_ -### cuvs::neighbors::hnsw::search +**Additional overload:** `cuvs::neighbors::hnsw::search` Search HNSWindex constructed from a CAGRA index @@ -635,7 +635,7 @@ NOTE: The HNSW index can only be searched by the hnswlib wrapper in cuVS when th _Source: `cpp/include/cuvs/neighbors/hnsw.hpp:882`_ -### cuvs::neighbors::hnsw::search +**Additional overload:** `cuvs::neighbors::hnsw::search` Search HNSW index constructed from a CAGRA index @@ -695,7 +695,7 @@ NOTE: When hierarchy is `NONE`, the saved hnswlib index is immutable and can onl _Source: `cpp/include/cuvs/neighbors/hnsw.hpp:969`_ -### cuvs::neighbors::hnsw::serialize +**Additional overload:** `cuvs::neighbors::hnsw::serialize` Serialize the HNSW index to file @@ -719,7 +719,7 @@ NOTE: When hierarchy is `NONE`, the saved hnswlib index is immutable and can onl _Source: `cpp/include/cuvs/neighbors/hnsw.hpp:998`_ -### cuvs::neighbors::hnsw::serialize +**Additional overload:** `cuvs::neighbors::hnsw::serialize` Serialize the HNSW index to file @@ -743,7 +743,7 @@ NOTE: When hierarchy is `NONE`, the saved hnswlib index is immutable and can onl _Source: `cpp/include/cuvs/neighbors/hnsw.hpp:1027`_ -### cuvs::neighbors::hnsw::serialize +**Additional overload:** `cuvs::neighbors::hnsw::serialize` Serialize the HNSW index to file @@ -799,7 +799,7 @@ NOTE: When hierarchy is `NONE`, the saved hnswlib index is immutable and can onl _Source: `cpp/include/cuvs/neighbors/hnsw.hpp:1094`_ -### cuvs::neighbors::hnsw::deserialize +**Additional overload:** `cuvs::neighbors::hnsw::deserialize` De-serialize a CAGRA index saved to a file as an hnswlib index @@ -831,7 +831,7 @@ NOTE: When hierarchy is `NONE`, the saved hnswlib index is immutable and can onl _Source: `cpp/include/cuvs/neighbors/hnsw.hpp:1137`_ -### cuvs::neighbors::hnsw::deserialize +**Additional overload:** `cuvs::neighbors::hnsw::deserialize` De-serialize a CAGRA index saved to a file as an hnswlib index @@ -863,7 +863,7 @@ NOTE: When hierarchy is `NONE`, the saved hnswlib index is immutable and can onl _Source: `cpp/include/cuvs/neighbors/hnsw.hpp:1180`_ -### cuvs::neighbors::hnsw::deserialize +**Additional overload:** `cuvs::neighbors::hnsw::deserialize` De-serialize a CAGRA index saved to a file as an hnswlib index diff --git a/fern/pages/cpp_api/cpp-api-neighbors-ivf-flat.md b/fern/pages/cpp_api/cpp-api-neighbors-ivf-flat.md index 49e49528f7..1c785daddf 100644 --- a/fern/pages/cpp_api/cpp-api-neighbors-ivf-flat.md +++ b/fern/pages/cpp_api/cpp-api-neighbors-ivf-flat.md @@ -73,7 +73,7 @@ Constructs an empty index. This index will either need to be trained with `build _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:154`_ -### cuvs::neighbors::ivf_flat::index +**Additional overload:** `cuvs::neighbors::ivf_flat::index` Construct an empty index. It needs to be trained and then populated. @@ -95,7 +95,7 @@ index(raft::resources const& res, const index_params& params, uint32_t dim); _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:157`_ -### cuvs::neighbors::ivf_flat::index +**Additional overload:** `cuvs::neighbors::ivf_flat::index` Construct an empty index. It needs to be trained and then populated. @@ -348,7 +348,7 @@ the constructed ivf-flat index _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:325`_ -### cuvs::neighbors::ivf_flat::build +**Additional overload:** `cuvs::neighbors::ivf_flat::build` Build the index from the dataset for efficient search. @@ -376,7 +376,7 @@ NB: Currently, the following distance metrics are supported: - L2Expanded - L2Un _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:355`_ -### cuvs::neighbors::ivf_flat::build +**Additional overload:** `cuvs::neighbors::ivf_flat::build` Build the index from the dataset for efficient search. @@ -405,7 +405,7 @@ the constructed ivf-flat index _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:384`_ -### cuvs::neighbors::ivf_flat::build +**Additional overload:** `cuvs::neighbors::ivf_flat::build` Build the index from the dataset for efficient search. @@ -433,7 +433,7 @@ NB: Currently, the following distance metrics are supported: - L2Expanded - L2Un _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:414`_ -### cuvs::neighbors::ivf_flat::build +**Additional overload:** `cuvs::neighbors::ivf_flat::build` Build the index from the dataset for efficient search. @@ -462,7 +462,7 @@ the constructed ivf-flat index _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:443`_ -### cuvs::neighbors::ivf_flat::build +**Additional overload:** `cuvs::neighbors::ivf_flat::build` Build the index from the dataset for efficient search. @@ -490,7 +490,7 @@ NB: Currently, the following distance metrics are supported: - L2Expanded - L2Un _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:473`_ -### cuvs::neighbors::ivf_flat::build +**Additional overload:** `cuvs::neighbors::ivf_flat::build` Build the index from the dataset for efficient search. @@ -519,7 +519,7 @@ the constructed ivf-flat index _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:502`_ -### cuvs::neighbors::ivf_flat::build +**Additional overload:** `cuvs::neighbors::ivf_flat::build` Build the index from the dataset for efficient search. @@ -547,7 +547,7 @@ NB: Currently, the following distance metrics are supported: - L2Expanded - L2Un _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:532`_ -### cuvs::neighbors::ivf_flat::build +**Additional overload:** `cuvs::neighbors::ivf_flat::build` Build the index from the dataset for efficient search. @@ -576,7 +576,7 @@ the constructed ivf-flat index _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:568`_ -### cuvs::neighbors::ivf_flat::build +**Additional overload:** `cuvs::neighbors::ivf_flat::build` Build the index from the dataset for efficient search. @@ -604,7 +604,7 @@ NB: Currently, the following distance metrics are supported: - L2Expanded - L2Un _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:605`_ -### cuvs::neighbors::ivf_flat::build +**Additional overload:** `cuvs::neighbors::ivf_flat::build` Build the index from the dataset for efficient search. @@ -633,7 +633,7 @@ the constructed ivf-flat index _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:641`_ -### cuvs::neighbors::ivf_flat::build +**Additional overload:** `cuvs::neighbors::ivf_flat::build` Build the index from the dataset for efficient search. @@ -661,7 +661,7 @@ NB: Currently, the following distance metrics are supported: - L2Expanded - L2Un _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:678`_ -### cuvs::neighbors::ivf_flat::build +**Additional overload:** `cuvs::neighbors::ivf_flat::build` Build the index from the dataset for efficient search. @@ -690,7 +690,7 @@ the constructed ivf-flat index _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:714`_ -### cuvs::neighbors::ivf_flat::build +**Additional overload:** `cuvs::neighbors::ivf_flat::build` Build the index from the dataset for efficient search. @@ -718,7 +718,7 @@ NB: Currently, the following distance metrics are supported: - L2Expanded - L2Un _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:751`_ -### cuvs::neighbors::ivf_flat::build +**Additional overload:** `cuvs::neighbors::ivf_flat::build` Build the index from the dataset for efficient search. @@ -747,7 +747,7 @@ the constructed ivf-flat index _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:787`_ -### cuvs::neighbors::ivf_flat::build +**Additional overload:** `cuvs::neighbors::ivf_flat::build` Build the index from the dataset for efficient search. @@ -810,7 +810,7 @@ the constructed extended ivf-flat index _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:866`_ -### cuvs::neighbors::ivf_flat::extend +**Additional overload:** `cuvs::neighbors::ivf_flat::extend` Extend the index in-place with the new data. @@ -838,7 +838,7 @@ Usage example: _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:896`_ -### cuvs::neighbors::ivf_flat::extend +**Additional overload:** `cuvs::neighbors::ivf_flat::extend` Build a new index containing the data of the original plus new extra vectors. @@ -869,7 +869,7 @@ the constructed extended ivf-flat index _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:930`_ -### cuvs::neighbors::ivf_flat::extend +**Additional overload:** `cuvs::neighbors::ivf_flat::extend` Extend the index in-place with the new data. @@ -897,7 +897,7 @@ Usage example: _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:960`_ -### cuvs::neighbors::ivf_flat::extend +**Additional overload:** `cuvs::neighbors::ivf_flat::extend` Build a new index containing the data of the original plus new extra vectors. @@ -928,7 +928,7 @@ the constructed extended ivf-flat index _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:994`_ -### cuvs::neighbors::ivf_flat::extend +**Additional overload:** `cuvs::neighbors::ivf_flat::extend` Extend the index in-place with the new data. @@ -956,7 +956,7 @@ Usage example: _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:1025`_ -### cuvs::neighbors::ivf_flat::extend +**Additional overload:** `cuvs::neighbors::ivf_flat::extend` Build a new index containing the data of the original plus new extra vectors. @@ -987,7 +987,7 @@ the constructed extended ivf-flat index _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:1059`_ -### cuvs::neighbors::ivf_flat::extend +**Additional overload:** `cuvs::neighbors::ivf_flat::extend` Extend the index in-place with the new data. @@ -1015,7 +1015,7 @@ Usage example: _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:1089`_ -### cuvs::neighbors::ivf_flat::extend +**Additional overload:** `cuvs::neighbors::ivf_flat::extend` Build a new index containing the data of the original plus new extra vectors. @@ -1046,7 +1046,7 @@ the constructed extended ivf-flat index _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:1129`_ -### cuvs::neighbors::ivf_flat::extend +**Additional overload:** `cuvs::neighbors::ivf_flat::extend` Extend the index in-place with the new data. @@ -1074,7 +1074,7 @@ Note, the user can set a stream pool in the input raft::resource with at least o _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:1165`_ -### cuvs::neighbors::ivf_flat::extend +**Additional overload:** `cuvs::neighbors::ivf_flat::extend` Build a new index containing the data of the original plus new extra vectors. @@ -1105,7 +1105,7 @@ the constructed extended ivf-flat index _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:1205`_ -### cuvs::neighbors::ivf_flat::extend +**Additional overload:** `cuvs::neighbors::ivf_flat::extend` Extend the index in-place with the new data. @@ -1133,7 +1133,7 @@ Note, the user can set a stream pool in the input raft::resource with at least o _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:1241`_ -### cuvs::neighbors::ivf_flat::extend +**Additional overload:** `cuvs::neighbors::ivf_flat::extend` Build a new index containing the data of the original plus new extra vectors. @@ -1164,7 +1164,7 @@ the constructed extended ivf-flat index _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:1281`_ -### cuvs::neighbors::ivf_flat::extend +**Additional overload:** `cuvs::neighbors::ivf_flat::extend` Extend the index in-place with the new data. @@ -1192,7 +1192,7 @@ Note, the user can set a stream pool in the input raft::resource with at least o _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:1317`_ -### cuvs::neighbors::ivf_flat::extend +**Additional overload:** `cuvs::neighbors::ivf_flat::extend` Build a new index containing the data of the original plus new extra vectors. @@ -1223,7 +1223,7 @@ the constructed extended ivf-flat index _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:1357`_ -### cuvs::neighbors::ivf_flat::extend +**Additional overload:** `cuvs::neighbors::ivf_flat::extend` Extend the index in-place with the new data. @@ -1307,7 +1307,7 @@ Experimental, both the API and the serialization format are subject to change. _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:1640`_ -### cuvs::neighbors::ivf_flat::serialize +**Additional overload:** `cuvs::neighbors::ivf_flat::serialize` Write the index to an output stream @@ -1333,7 +1333,7 @@ Experimental, both the API and the serialization format are subject to change. _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:1666`_ -### cuvs::neighbors::ivf_flat::deserialize +**Additional overload:** `cuvs::neighbors::ivf_flat::deserialize` Load index from input stream @@ -1359,7 +1359,7 @@ Experimental, both the API and the serialization format are subject to change. _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:1694`_ -### cuvs::neighbors::ivf_flat::serialize +**Additional overload:** `cuvs::neighbors::ivf_flat::serialize` Save the index to file. @@ -1385,7 +1385,7 @@ Experimental, both the API and the serialization format are subject to change. _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:1720`_ -### cuvs::neighbors::ivf_flat::deserialize +**Additional overload:** `cuvs::neighbors::ivf_flat::deserialize` Load index from file. @@ -1411,7 +1411,7 @@ Experimental, both the API and the serialization format are subject to change. _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:1748`_ -### cuvs::neighbors::ivf_flat::serialize +**Additional overload:** `cuvs::neighbors::ivf_flat::serialize` Write the index to an output stream @@ -1437,7 +1437,7 @@ Experimental, both the API and the serialization format are subject to change. _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:1774`_ -### cuvs::neighbors::ivf_flat::deserialize +**Additional overload:** `cuvs::neighbors::ivf_flat::deserialize` Load index from input stream @@ -1463,7 +1463,7 @@ Experimental, both the API and the serialization format are subject to change. _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:1802`_ -### cuvs::neighbors::ivf_flat::serialize +**Additional overload:** `cuvs::neighbors::ivf_flat::serialize` Save the index to file. @@ -1489,7 +1489,7 @@ Experimental, both the API and the serialization format are subject to change. _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:1828`_ -### cuvs::neighbors::ivf_flat::deserialize +**Additional overload:** `cuvs::neighbors::ivf_flat::deserialize` Load index from file. @@ -1515,7 +1515,7 @@ Experimental, both the API and the serialization format are subject to change. _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:1856`_ -### cuvs::neighbors::ivf_flat::serialize +**Additional overload:** `cuvs::neighbors::ivf_flat::serialize` Write the index to an output stream @@ -1541,7 +1541,7 @@ Experimental, both the API and the serialization format are subject to change. _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:1882`_ -### cuvs::neighbors::ivf_flat::deserialize +**Additional overload:** `cuvs::neighbors::ivf_flat::deserialize` Load index from input stream @@ -1567,7 +1567,7 @@ Experimental, both the API and the serialization format are subject to change. _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:1910`_ -### cuvs::neighbors::ivf_flat::serialize +**Additional overload:** `cuvs::neighbors::ivf_flat::serialize` Save the index to file. @@ -1593,7 +1593,7 @@ Experimental, both the API and the serialization format are subject to change. _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:1936`_ -### cuvs::neighbors::ivf_flat::deserialize +**Additional overload:** `cuvs::neighbors::ivf_flat::deserialize` Load index from file. @@ -1619,7 +1619,7 @@ Experimental, both the API and the serialization format are subject to change. _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:1964`_ -### cuvs::neighbors::ivf_flat::serialize +**Additional overload:** `cuvs::neighbors::ivf_flat::serialize` Write the index to an output stream @@ -1645,7 +1645,7 @@ Experimental, both the API and the serialization format are subject to change. _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:1990`_ -### cuvs::neighbors::ivf_flat::deserialize +**Additional overload:** `cuvs::neighbors::ivf_flat::deserialize` Load index from input stream @@ -1717,7 +1717,7 @@ NB: no memory allocation happens here; the list must fit the data (offset + n_ve _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:2508`_ -### codepacker::pack +**Additional overload:** `codepacker::pack` Write flat codes into an existing list by the given offset. @@ -1749,7 +1749,7 @@ NB: no memory allocation happens here; the list must fit the data (offset + n_ve _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:2538`_ -### codepacker::pack +**Additional overload:** `codepacker::pack` Write flat codes into an existing list by the given offset. @@ -1781,7 +1781,7 @@ NB: no memory allocation happens here; the list must fit the data (offset + n_ve _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:2568`_ -### codepacker::pack +**Additional overload:** `codepacker::pack` Write flat codes into an existing list by the given offset. @@ -1845,7 +1845,7 @@ starting at given `offset`. Usage example: _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:2631`_ -### codepacker::unpack +**Additional overload:** `codepacker::unpack` Unpack `n_take` consecutive records of a single list (cluster) in the compressed index @@ -1877,7 +1877,7 @@ starting at given `offset`. Usage example: _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:2664`_ -### codepacker::unpack +**Additional overload:** `codepacker::unpack` Unpack `n_take` consecutive records of a single list (cluster) in the compressed index @@ -1909,7 +1909,7 @@ starting at given `offset`. Usage example: _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:2696`_ -### codepacker::unpack +**Additional overload:** `codepacker::unpack` Unpack `n_take` consecutive records of a single list (cluster) in the compressed index @@ -1967,7 +1967,7 @@ in the list. This function interleaves the code and is intended to later copy th _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:2749`_ -### codepacker::pack_1 +**Additional overload:** `codepacker::pack_1` Write one flat code into a block by the given offset. The offset indicates the id of the record @@ -1993,7 +1993,7 @@ in the list. This function interleaves the code and is intended to later copy th _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:2763`_ -### codepacker::pack_1 +**Additional overload:** `codepacker::pack_1` Write one flat code into a block by the given offset. The offset indicates the id of the record @@ -2019,7 +2019,7 @@ in the list. This function interleaves the code and is intended to later copy th _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:2777`_ -### codepacker::pack_1 +**Additional overload:** `codepacker::pack_1` Write one flat code into a block by the given offset. The offset indicates the id of the record @@ -2072,7 +2072,7 @@ indicates the id of the record. This function fetches one flat code from an inte _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:2805`_ -### codepacker::unpack_1 +**Additional overload:** `codepacker::unpack_1` Unpack 1 record of a single list (cluster) in the index to fetch the flat code. The offset @@ -2098,7 +2098,7 @@ indicates the id of the record. This function fetches one flat code from an inte _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:2818`_ -### codepacker::unpack_1 +**Additional overload:** `codepacker::unpack_1` Unpack 1 record of a single list (cluster) in the index to fetch the flat code. The offset @@ -2125,7 +2125,7 @@ indicates the id of the record. This function fetches one flat code from an inte _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:2831`_ -### codepacker::unpack_1 +**Additional overload:** `codepacker::unpack_1` Unpack 1 record of a single list (cluster) in the index to fetch the flat code. The offset @@ -2175,7 +2175,7 @@ externally modifying the index without going through the build stage. The data a _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:2870`_ -### codepacker::reset_index +**Additional overload:** `codepacker::reset_index` Public helper API to reset the data and indices ptrs, and the list sizes. Useful for @@ -2198,7 +2198,7 @@ externally modifying the index without going through the build stage. The data a _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:2892`_ -### codepacker::reset_index +**Additional overload:** `codepacker::reset_index` Public helper API to reset the data and indices ptrs, and the list sizes. Useful for @@ -2221,7 +2221,7 @@ externally modifying the index without going through the build stage. The data a _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:2914`_ -### codepacker::reset_index +**Additional overload:** `codepacker::reset_index` Public helper API to reset the data and indices ptrs, and the list sizes. Useful for @@ -2267,7 +2267,7 @@ modified externally. Usage example: _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:2964`_ -### codepacker::recompute_internal_state +**Additional overload:** `codepacker::recompute_internal_state` Helper exposing the re-computation of list sizes and related arrays if IVF lists have been @@ -2290,7 +2290,7 @@ modified externally. Usage example: _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:2992`_ -### codepacker::recompute_internal_state +**Additional overload:** `codepacker::recompute_internal_state` Helper exposing the re-computation of list sizes and related arrays if IVF lists have been @@ -2313,7 +2313,7 @@ modified externally. Usage example: _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:3020`_ -### codepacker::recompute_internal_state +**Additional overload:** `codepacker::recompute_internal_state` Helper exposing the re-computation of list sizes and related arrays if IVF lists have been diff --git a/fern/pages/cpp_api/cpp-api-neighbors-ivf-pq.md b/fern/pages/cpp_api/cpp-api-neighbors-ivf-pq.md index ca70dd3a7e..6ca9e4be8c 100644 --- a/fern/pages/cpp_api/cpp-api-neighbors-ivf-pq.md +++ b/fern/pages/cpp_api/cpp-api-neighbors-ivf-pq.md @@ -106,7 +106,7 @@ Constructs an empty index. This index will either need to be trained with `build _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:493`_ -### cuvs::neighbors::ivf_pq::index +**Additional overload:** `cuvs::neighbors::ivf_pq::index` Construct an index with specified parameters. @@ -142,7 +142,7 @@ This constructor creates an owning index with the given parameters. _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:509`_ -### cuvs::neighbors::ivf_pq::index +**Additional overload:** `cuvs::neighbors::ivf_pq::index` Construct an index from index parameters. @@ -508,7 +508,7 @@ Usage example: _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:654`_ -### cuvs::neighbors::ivf_pq::index +**Additional overload:** `cuvs::neighbors::ivf_pq::index` Construct index from implementation pointer. @@ -563,7 +563,7 @@ the constructed ivf-pq index _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:699`_ -### cuvs::neighbors::ivf_pq::build +**Additional overload:** `cuvs::neighbors::ivf_pq::build` Build the index from the dataset for efficient search. @@ -591,7 +591,7 @@ NB: Currently, the following distance metrics are supported: - L2Expanded - L2Un _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:729`_ -### cuvs::neighbors::ivf_pq::build +**Additional overload:** `cuvs::neighbors::ivf_pq::build` Build the index from the dataset for efficient search. @@ -620,7 +620,7 @@ the constructed ivf-pq index _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:752`_ -### cuvs::neighbors::ivf_pq::build +**Additional overload:** `cuvs::neighbors::ivf_pq::build` Build the index from the dataset for efficient search. @@ -648,7 +648,7 @@ NB: Currently, the following distance metrics are supported: - L2Expanded - L2Un _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:782`_ -### cuvs::neighbors::ivf_pq::build +**Additional overload:** `cuvs::neighbors::ivf_pq::build` Build the index from the dataset for efficient search. @@ -677,7 +677,7 @@ the constructed ivf-pq index _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:804`_ -### cuvs::neighbors::ivf_pq::build +**Additional overload:** `cuvs::neighbors::ivf_pq::build` Build the index from the dataset for efficient search. @@ -705,7 +705,7 @@ NB: Currently, the following distance metrics are supported: - L2Expanded - L2Un _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:834`_ -### cuvs::neighbors::ivf_pq::build +**Additional overload:** `cuvs::neighbors::ivf_pq::build` Build the index from the dataset for efficient search. @@ -734,7 +734,7 @@ the constructed ivf-pq index _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:857`_ -### cuvs::neighbors::ivf_pq::build +**Additional overload:** `cuvs::neighbors::ivf_pq::build` Build the index from the dataset for efficient search. @@ -762,7 +762,7 @@ NB: Currently, the following distance metrics are supported: - L2Expanded - L2Un _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:887`_ -### cuvs::neighbors::ivf_pq::build +**Additional overload:** `cuvs::neighbors::ivf_pq::build` Build the index from the dataset for efficient search. @@ -791,7 +791,7 @@ the constructed ivf-pq index _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:916`_ -### cuvs::neighbors::ivf_pq::build +**Additional overload:** `cuvs::neighbors::ivf_pq::build` Build the index from the dataset for efficient search. @@ -819,7 +819,7 @@ NB: Currently, the following distance metrics are supported: - L2Expanded - L2Un _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:953`_ -### cuvs::neighbors::ivf_pq::build +**Additional overload:** `cuvs::neighbors::ivf_pq::build` Build the index from the dataset for efficient search. @@ -848,7 +848,7 @@ the constructed ivf-pq index _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:983`_ -### cuvs::neighbors::ivf_pq::build +**Additional overload:** `cuvs::neighbors::ivf_pq::build` Build the index from the dataset for efficient search. @@ -876,7 +876,7 @@ NB: Currently, the following distance metrics are supported: - L2Expanded - L2Un _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:1013`_ -### cuvs::neighbors::ivf_pq::build +**Additional overload:** `cuvs::neighbors::ivf_pq::build` Build the index from the dataset for efficient search. @@ -905,7 +905,7 @@ the constructed ivf-pq index _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:1036`_ -### cuvs::neighbors::ivf_pq::build +**Additional overload:** `cuvs::neighbors::ivf_pq::build` Build the index from the dataset for efficient search. @@ -933,7 +933,7 @@ NB: Currently, the following distance metrics are supported: - L2Expanded - L2Un _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:1073`_ -### cuvs::neighbors::ivf_pq::build +**Additional overload:** `cuvs::neighbors::ivf_pq::build` Build the index from the dataset for efficient search. @@ -962,7 +962,7 @@ the constructed ivf-pq index _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:1103`_ -### cuvs::neighbors::ivf_pq::build +**Additional overload:** `cuvs::neighbors::ivf_pq::build` Build the index from the dataset for efficient search. @@ -990,7 +990,7 @@ NB: Currently, the following distance metrics are supported: - L2Expanded - L2Un _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:1140`_ -### cuvs::neighbors::ivf_pq::build +**Additional overload:** `cuvs::neighbors::ivf_pq::build` Build a view-type IVF-PQ index from device memory centroids and codebook. @@ -1027,7 +1027,7 @@ A view-type ivf_pq index that references the provided data _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:1174`_ -### cuvs::neighbors::ivf_pq::build +**Additional overload:** `cuvs::neighbors::ivf_pq::build` Build an IVF-PQ index from device memory centroids and codebook. @@ -1063,7 +1063,7 @@ This function creates a non-owning index that references the provided device dat _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:1211`_ -### cuvs::neighbors::ivf_pq::build +**Additional overload:** `cuvs::neighbors::ivf_pq::build` Build an IVF-PQ index from host memory centroids and codebook (in-place). @@ -1097,7 +1097,7 @@ std::optional> ro _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:1231`_ -### cuvs::neighbors::ivf_pq::build +**Additional overload:** `cuvs::neighbors::ivf_pq::build` Build an IVF-PQ index from host memory centroids and codebook (in-place). @@ -1165,7 +1165,7 @@ Usage example: _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:1293`_ -### cuvs::neighbors::ivf_pq::extend +**Additional overload:** `cuvs::neighbors::ivf_pq::extend` Extend the index with the new data. @@ -1193,7 +1193,7 @@ Usage example: _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:1322`_ -### cuvs::neighbors::ivf_pq::extend +**Additional overload:** `cuvs::neighbors::ivf_pq::extend` Extend the index with the new data. @@ -1222,7 +1222,7 @@ Usage example: _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:1350`_ -### cuvs::neighbors::ivf_pq::extend +**Additional overload:** `cuvs::neighbors::ivf_pq::extend` Extend the index with the new data. @@ -1250,7 +1250,7 @@ Usage example: _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:1379`_ -### cuvs::neighbors::ivf_pq::extend +**Additional overload:** `cuvs::neighbors::ivf_pq::extend` Extend the index with the new data. @@ -1279,7 +1279,7 @@ Usage example: _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:1407`_ -### cuvs::neighbors::ivf_pq::extend +**Additional overload:** `cuvs::neighbors::ivf_pq::extend` Extend the index with the new data. @@ -1307,7 +1307,7 @@ Usage example: _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:1436`_ -### cuvs::neighbors::ivf_pq::extend +**Additional overload:** `cuvs::neighbors::ivf_pq::extend` Extend the index with the new data. @@ -1336,7 +1336,7 @@ Usage example: _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:1464`_ -### cuvs::neighbors::ivf_pq::extend +**Additional overload:** `cuvs::neighbors::ivf_pq::extend` Extend the index with the new data. @@ -1364,7 +1364,7 @@ Usage example: _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:1493`_ -### cuvs::neighbors::ivf_pq::extend +**Additional overload:** `cuvs::neighbors::ivf_pq::extend` Extend the index with the new data. @@ -1393,7 +1393,7 @@ Note, the user can set a stream pool in the input raft::resource with at least o _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:1527`_ -### cuvs::neighbors::ivf_pq::extend +**Additional overload:** `cuvs::neighbors::ivf_pq::extend` Extend the index with the new data. @@ -1421,7 +1421,7 @@ Note, the user can set a stream pool in the input raft::resource with at least o _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:1562`_ -### cuvs::neighbors::ivf_pq::extend +**Additional overload:** `cuvs::neighbors::ivf_pq::extend` Extend the index with the new data. @@ -1450,7 +1450,7 @@ Note, the user can set a stream pool in the input raft::resource with at least o _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:1596`_ -### cuvs::neighbors::ivf_pq::extend +**Additional overload:** `cuvs::neighbors::ivf_pq::extend` Extend the index with the new data. @@ -1478,7 +1478,7 @@ Note, the user can set a stream pool in the input raft::resource with at least o _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:1631`_ -### cuvs::neighbors::ivf_pq::extend +**Additional overload:** `cuvs::neighbors::ivf_pq::extend` Extend the index with the new data. @@ -1507,7 +1507,7 @@ Note, the user can set a stream pool in the input raft::resource with at least o _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:1665`_ -### cuvs::neighbors::ivf_pq::extend +**Additional overload:** `cuvs::neighbors::ivf_pq::extend` Extend the index with the new data. @@ -1535,7 +1535,7 @@ Note, the user can set a stream pool in the input raft::resource with at least o _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:1700`_ -### cuvs::neighbors::ivf_pq::extend +**Additional overload:** `cuvs::neighbors::ivf_pq::extend` Extend the index with the new data. @@ -1564,7 +1564,7 @@ Note, the user can set a stream pool in the input raft::resource with at least o _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:1734`_ -### cuvs::neighbors::ivf_pq::extend +**Additional overload:** `cuvs::neighbors::ivf_pq::extend` Extend the index with the new data. @@ -1626,7 +1626,7 @@ cluster ids (labels) for each vector in the input dataset index.pq_bits(), 8)]] _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:1981`_ -### cuvs::neighbors::ivf_pq::transform +**Additional overload:** `cuvs::neighbors::ivf_pq::transform` ```cpp void transform(raft::resources const& handle, @@ -1652,7 +1652,7 @@ raft::device_matrix_view output_dataset); _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:1987`_ -### cuvs::neighbors::ivf_pq::transform +**Additional overload:** `cuvs::neighbors::ivf_pq::transform` ```cpp void transform(raft::resources const& handle, @@ -1678,7 +1678,7 @@ raft::device_matrix_view output_dataset); _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:1993`_ -### cuvs::neighbors::ivf_pq::transform +**Additional overload:** `cuvs::neighbors::ivf_pq::transform` ```cpp void transform(raft::resources const& handle, @@ -1732,7 +1732,7 @@ const cuvs::neighbors::ivf_pq::index& index); _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:2031`_ -### cuvs::neighbors::ivf_pq::serialize +**Additional overload:** `cuvs::neighbors::ivf_pq::serialize` Save the index to file. @@ -1780,7 +1780,7 @@ cuvs::neighbors::ivf_pq::index* index); _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:2081`_ -### cuvs::neighbors::ivf_pq::deserialize +**Additional overload:** `cuvs::neighbors::ivf_pq::deserialize` Load index from file. @@ -2046,7 +2046,7 @@ starting at given `offset`, one code per byte (independently of pq_bits). Usage _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:2815`_ -### codepacker::unpack_list_data +**Additional overload:** `codepacker::unpack_list_data` Unpack a series of records of a single list (cluster) in the compressed index @@ -2138,7 +2138,7 @@ starting at given `offset`. Usage example: _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:2929`_ -### codepacker::reconstruct_list_data +**Additional overload:** `codepacker::reconstruct_list_data` Decode a series of records of a single list (cluster) in the compressed index @@ -2334,7 +2334,7 @@ This function takes cluster centers and pads them with their L2 norms to create _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:3176`_ -### codepacker::pad_centers_with_norms +**Additional overload:** `codepacker::pad_centers_with_norms` Pad cluster centers with their L2 norms for efficient GEMM operations. @@ -2414,7 +2414,7 @@ Usage example: _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:3228`_ -### codepacker::extract_centers +**Additional overload:** `codepacker::extract_centers` ```cpp void extract_centers(raft::resources const& res, @@ -2516,7 +2516,7 @@ This helper resizes an IVF list that uses the flat (non-interleaved) PQ code lay _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:3319`_ -### codepacker::resize_list +**Additional overload:** `codepacker::resize_list` Resize an IVF-PQ list with interleaved layout. diff --git a/fern/pages/cpp_api/cpp-api-neighbors-nn-descent.md b/fern/pages/cpp_api/cpp-api-neighbors-nn-descent.md index 5a9827d645..d442c26427 100644 --- a/fern/pages/cpp_api/cpp-api-neighbors-nn-descent.md +++ b/fern/pages/cpp_api/cpp-api-neighbors-nn-descent.md @@ -54,7 +54,7 @@ struct index_params : cuvs::neighbors::index_params { ... } ; _Source: `cpp/include/cuvs/neighbors/nn_descent.hpp:56`_ -### cuvs::neighbors::nn_descent::index_params +**Additional overload:** `cuvs::neighbors::nn_descent::index_params` Construct NN descent parameters for a specific kNN graph degree @@ -111,7 +111,7 @@ This constructor creates an nn-descent index which is a knn-graph in host memory _Source: `cpp/include/cuvs/neighbors/nn_descent.hpp:110`_ -### cuvs::neighbors::nn_descent::index +**Additional overload:** `cuvs::neighbors::nn_descent::index` Construct a new index object @@ -248,7 +248,7 @@ index<IdxT> index containing all-neighbors knn graph in host memory _Source: `cpp/include/cuvs/neighbors/nn_descent.hpp:244`_ -### cuvs::neighbors::nn_descent::build +**Additional overload:** `cuvs::neighbors::nn_descent::build` Build nn-descent Index with dataset in host memory @@ -286,7 +286,7 @@ index<IdxT> index containing all-neighbors knn graph in host memory _Source: `cpp/include/cuvs/neighbors/nn_descent.hpp:283`_ -### cuvs::neighbors::nn_descent::build +**Additional overload:** `cuvs::neighbors::nn_descent::build` Build nn-descent Index with dataset in device memory @@ -317,7 +317,7 @@ index<IdxT> index containing all-neighbors knn graph in host memory _Source: `cpp/include/cuvs/neighbors/nn_descent.hpp:320`_ -### cuvs::neighbors::nn_descent::build +**Additional overload:** `cuvs::neighbors::nn_descent::build` Build nn-descent Index with dataset in host memory @@ -355,7 +355,7 @@ index<IdxT> index containing all-neighbors knn graph in host memory _Source: `cpp/include/cuvs/neighbors/nn_descent.hpp:359`_ -### cuvs::neighbors::nn_descent::build +**Additional overload:** `cuvs::neighbors::nn_descent::build` Build nn-descent Index with dataset in device memory @@ -386,7 +386,7 @@ index<IdxT> index containing all-neighbors knn graph in host memory _Source: `cpp/include/cuvs/neighbors/nn_descent.hpp:397`_ -### cuvs::neighbors::nn_descent::build +**Additional overload:** `cuvs::neighbors::nn_descent::build` Build nn-descent Index with dataset in host memory @@ -424,7 +424,7 @@ index<IdxT> index containing all-neighbors knn graph in host memory _Source: `cpp/include/cuvs/neighbors/nn_descent.hpp:437`_ -### cuvs::neighbors::nn_descent::build +**Additional overload:** `cuvs::neighbors::nn_descent::build` Build nn-descent Index with dataset in device memory @@ -455,7 +455,7 @@ index<IdxT> index containing all-neighbors knn graph in host memory _Source: `cpp/include/cuvs/neighbors/nn_descent.hpp:475`_ -### cuvs::neighbors::nn_descent::build +**Additional overload:** `cuvs::neighbors::nn_descent::build` Build nn-descent Index with dataset in host memory diff --git a/fern/pages/cpp_api/cpp-api-neighbors-refine.md b/fern/pages/cpp_api/cpp-api-neighbors-refine.md index 1b1cd3cc60..aab22160b5 100644 --- a/fern/pages/cpp_api/cpp-api-neighbors-refine.md +++ b/fern/pages/cpp_api/cpp-api-neighbors-refine.md @@ -44,7 +44,7 @@ Refinement is an operation that follows an approximate NN search. The approximat _Source: `cpp/include/cuvs/neighbors/refine.hpp:60`_ -### cuvs::neighbors::refine +**Additional overload:** `cuvs::neighbors::refine` Refine nearest neighbor search. @@ -78,7 +78,7 @@ Refinement is an operation that follows an approximate NN search. The approximat _Source: `cpp/include/cuvs/neighbors/refine.hpp:105`_ -### cuvs::neighbors::refine +**Additional overload:** `cuvs::neighbors::refine` Refine nearest neighbor search. @@ -112,7 +112,7 @@ Refinement is an operation that follows an approximate NN search. The approximat _Source: `cpp/include/cuvs/neighbors/refine.hpp:150`_ -### cuvs::neighbors::refine +**Additional overload:** `cuvs::neighbors::refine` Refine nearest neighbor search. @@ -146,7 +146,7 @@ Refinement is an operation that follows an approximate NN search. The approximat _Source: `cpp/include/cuvs/neighbors/refine.hpp:195`_ -### cuvs::neighbors::refine +**Additional overload:** `cuvs::neighbors::refine` Refine nearest neighbor search. @@ -180,7 +180,7 @@ Refinement is an operation that follows an approximate NN search. The approximat _Source: `cpp/include/cuvs/neighbors/refine.hpp:240`_ -### cuvs::neighbors::refine +**Additional overload:** `cuvs::neighbors::refine` Refine nearest neighbor search. @@ -214,7 +214,7 @@ Refinement is an operation that follows an approximate NN search. The approximat _Source: `cpp/include/cuvs/neighbors/refine.hpp:285`_ -### cuvs::neighbors::refine +**Additional overload:** `cuvs::neighbors::refine` Refine nearest neighbor search. @@ -248,7 +248,7 @@ Refinement is an operation that follows an approximate NN search. The approximat _Source: `cpp/include/cuvs/neighbors/refine.hpp:330`_ -### cuvs::neighbors::refine +**Additional overload:** `cuvs::neighbors::refine` Refine nearest neighbor search. @@ -282,7 +282,7 @@ Refinement is an operation that follows an approximate NN search. The approximat _Source: `cpp/include/cuvs/neighbors/refine.hpp:375`_ -### cuvs::neighbors::refine +**Additional overload:** `cuvs::neighbors::refine` Refine nearest neighbor search. @@ -316,7 +316,7 @@ Refinement is an operation that follows an approximate NN search. The approximat _Source: `cpp/include/cuvs/neighbors/refine.hpp:420`_ -### cuvs::neighbors::refine +**Additional overload:** `cuvs::neighbors::refine` Refine nearest neighbor search. diff --git a/fern/pages/cpp_api/cpp-api-neighbors-scann.md b/fern/pages/cpp_api/cpp-api-neighbors-scann.md index 4d59c9d21f..03224235e4 100644 --- a/fern/pages/cpp_api/cpp-api-neighbors-scann.md +++ b/fern/pages/cpp_api/cpp-api-neighbors-scann.md @@ -141,7 +141,7 @@ _Source: `cpp/include/cuvs/neighbors/scann.hpp:316`_ _Doxygen group: `scann_cpp_serialize`_ -### cuvs::neighbors::experimental::scann::serialize +**Additional overload:** `cuvs::neighbors::experimental::scann::serialize` Save the index to files in a directory diff --git a/fern/pages/cpp_api/cpp-api-neighbors-vamana.md b/fern/pages/cpp_api/cpp-api-neighbors-vamana.md index 01f8992dbb..057362fdc2 100644 --- a/fern/pages/cpp_api/cpp-api-neighbors-vamana.md +++ b/fern/pages/cpp_api/cpp-api-neighbors-vamana.md @@ -172,7 +172,7 @@ index(const index&) = delete; _Source: `cpp/include/cuvs/neighbors/vamana.hpp:153`_ -### cuvs::neighbors::vamana::index +**Additional overload:** `cuvs::neighbors::vamana::index` Construct an empty index. @@ -195,7 +195,7 @@ cuvs::distance::DistanceType metric = cuvs::distance::DistanceType::L2Expanded) _Source: `cpp/include/cuvs/neighbors/vamana.hpp:161`_ -### cuvs::neighbors::vamana::index +**Additional overload:** `cuvs::neighbors::vamana::index` Construct an index from dataset and vamana graph @@ -250,7 +250,7 @@ Since the new graph is a device array, we store a reference to that, and it is t _Source: `cpp/include/cuvs/neighbors/vamana.hpp:201`_ -### cuvs::neighbors::vamana::update_graph +**Additional overload:** `cuvs::neighbors::vamana::update_graph` Replace the graph with a new graph. @@ -332,7 +332,7 @@ the constructed vamana index _Source: `cpp/include/cuvs/neighbors/vamana.hpp:305`_ -### cuvs::neighbors::vamana::build +**Additional overload:** `cuvs::neighbors::vamana::build` Build the index from the dataset for efficient DiskANN search. @@ -361,7 +361,7 @@ the constructed vamana index _Source: `cpp/include/cuvs/neighbors/vamana.hpp:339`_ -### cuvs::neighbors::vamana::build +**Additional overload:** `cuvs::neighbors::vamana::build` Build the index from the dataset for efficient DiskANN search. @@ -390,7 +390,7 @@ the constructed vamana index _Source: `cpp/include/cuvs/neighbors/vamana.hpp:373`_ -### cuvs::neighbors::vamana::build +**Additional overload:** `cuvs::neighbors::vamana::build` Build the index from the dataset for efficient DiskANN search. @@ -419,7 +419,7 @@ the constructed vamana index _Source: `cpp/include/cuvs/neighbors/vamana.hpp:407`_ -### cuvs::neighbors::vamana::build +**Additional overload:** `cuvs::neighbors::vamana::build` Build the index from the dataset for efficient DiskANN search. @@ -448,7 +448,7 @@ the constructed vamana index _Source: `cpp/include/cuvs/neighbors/vamana.hpp:441`_ -### cuvs::neighbors::vamana::build +**Additional overload:** `cuvs::neighbors::vamana::build` Build the index from the dataset for efficient DiskANN search. @@ -511,7 +511,7 @@ Matches the file format used by the DiskANN open-source repository, allowing cro _Source: `cpp/include/cuvs/neighbors/vamana.hpp:514`_ -### cuvs::neighbors::vamana::serialize +**Additional overload:** `cuvs::neighbors::vamana::serialize` Save the index to file. @@ -541,7 +541,7 @@ Matches the file format used by the DiskANN open-source repository, allowing cro _Source: `cpp/include/cuvs/neighbors/vamana.hpp:544`_ -### cuvs::neighbors::vamana::serialize +**Additional overload:** `cuvs::neighbors::vamana::serialize` Save the index to file. diff --git a/fern/pages/cpp_api/cpp-api-preprocessing-quantize-binary.md b/fern/pages/cpp_api/cpp-api-preprocessing-quantize-binary.md index 09b5c727a5..ba92c2508b 100644 --- a/fern/pages/cpp_api/cpp-api-preprocessing-quantize-binary.md +++ b/fern/pages/cpp_api/cpp-api-preprocessing-quantize-binary.md @@ -95,7 +95,7 @@ quantizer _Source: `cpp/include/cuvs/preprocessing/quantize/binary.hpp:73`_ -### cuvs::preprocessing::quantize::binary::train +**Additional overload:** `cuvs::preprocessing::quantize::binary::train` Initializes a binary quantizer to be used later for quantizing the dataset. @@ -151,7 +151,7 @@ set the corresponding bit to 1. Usage example: _Source: `cpp/include/cuvs/preprocessing/quantize/binary.hpp:119`_ -### cuvs::preprocessing::quantize::binary::transform +**Additional overload:** `cuvs::preprocessing::quantize::binary::transform` Applies binary quantization transform to given dataset. If a dataset element is positive, @@ -179,7 +179,7 @@ set the corresponding bit to 1. Usage example: _Source: `cpp/include/cuvs/preprocessing/quantize/binary.hpp:146`_ -### cuvs::preprocessing::quantize::binary::train +**Additional overload:** `cuvs::preprocessing::quantize::binary::train` Initializes a binary quantizer to be used later for quantizing the dataset. @@ -207,7 +207,7 @@ quantizer _Source: `cpp/include/cuvs/preprocessing/quantize/binary.hpp:167`_ -### cuvs::preprocessing::quantize::binary::train +**Additional overload:** `cuvs::preprocessing::quantize::binary::train` Initializes a binary quantizer to be used later for quantizing the dataset. @@ -235,7 +235,7 @@ quantizer _Source: `cpp/include/cuvs/preprocessing/quantize/binary.hpp:187`_ -### cuvs::preprocessing::quantize::binary::transform +**Additional overload:** `cuvs::preprocessing::quantize::binary::transform` Applies binary quantization transform to given dataset. If a dataset element is positive, @@ -263,7 +263,7 @@ set the corresponding bit to 1. Usage example: _Source: `cpp/include/cuvs/preprocessing/quantize/binary.hpp:215`_ -### cuvs::preprocessing::quantize::binary::transform +**Additional overload:** `cuvs::preprocessing::quantize::binary::transform` Applies binary quantization transform to given dataset. If a dataset element is positive, @@ -291,7 +291,7 @@ set the corresponding bit to 1. Usage example: _Source: `cpp/include/cuvs/preprocessing/quantize/binary.hpp:244`_ -### cuvs::preprocessing::quantize::binary::train +**Additional overload:** `cuvs::preprocessing::quantize::binary::train` Initializes a binary quantizer to be used later for quantizing the dataset. @@ -319,7 +319,7 @@ quantizer _Source: `cpp/include/cuvs/preprocessing/quantize/binary.hpp:265`_ -### cuvs::preprocessing::quantize::binary::train +**Additional overload:** `cuvs::preprocessing::quantize::binary::train` Initializes a binary quantizer to be used later for quantizing the dataset. @@ -347,7 +347,7 @@ quantizer _Source: `cpp/include/cuvs/preprocessing/quantize/binary.hpp:285`_ -### cuvs::preprocessing::quantize::binary::transform +**Additional overload:** `cuvs::preprocessing::quantize::binary::transform` Applies binary quantization transform to given dataset. @@ -375,7 +375,7 @@ Usage example: _Source: `cpp/include/cuvs/preprocessing/quantize/binary.hpp:312`_ -### cuvs::preprocessing::quantize::binary::transform +**Additional overload:** `cuvs::preprocessing::quantize::binary::transform` Applies binary quantization transform to given dataset. @@ -428,7 +428,7 @@ is positive, set the corresponding bit to 1. _Source: `cpp/include/cuvs/preprocessing/quantize/binary.hpp:354`_ -### cuvs::preprocessing::quantize::binary::[[deprecated +**Additional overload:** `cuvs::preprocessing::quantize::binary::[[deprecated` [deprecated] Applies binary quantization transform to given dataset. If a dataset element @@ -453,7 +453,7 @@ is positive, set the corresponding bit to 1. _Source: `cpp/include/cuvs/preprocessing/quantize/binary.hpp:368`_ -### cuvs::preprocessing::quantize::binary::[[deprecated +**Additional overload:** `cuvs::preprocessing::quantize::binary::[[deprecated` [deprecated] Applies binary quantization transform to given dataset. If a dataset element @@ -478,7 +478,7 @@ is positive, set the corresponding bit to 1. _Source: `cpp/include/cuvs/preprocessing/quantize/binary.hpp:382`_ -### cuvs::preprocessing::quantize::binary::[[deprecated +**Additional overload:** `cuvs::preprocessing::quantize::binary::[[deprecated` [deprecated] Applies binary quantization transform to given dataset. If a dataset element @@ -503,7 +503,7 @@ is positive, set the corresponding bit to 1. _Source: `cpp/include/cuvs/preprocessing/quantize/binary.hpp:396`_ -### cuvs::preprocessing::quantize::binary::[[deprecated +**Additional overload:** `cuvs::preprocessing::quantize::binary::[[deprecated` [deprecated] Applies binary quantization transform to given dataset. If a dataset element @@ -528,7 +528,7 @@ is positive, set the corresponding bit to 1. _Source: `cpp/include/cuvs/preprocessing/quantize/binary.hpp:410`_ -### cuvs::preprocessing::quantize::binary::[[deprecated +**Additional overload:** `cuvs::preprocessing::quantize::binary::[[deprecated` [deprecated] Applies binary quantization transform to given dataset. If a dataset element diff --git a/fern/pages/cpp_api/cpp-api-preprocessing-quantize-pq.md b/fern/pages/cpp_api/cpp-api-preprocessing-quantize-pq.md index c9a9aced13..5a6c49f02f 100644 --- a/fern/pages/cpp_api/cpp-api-preprocessing-quantize-pq.md +++ b/fern/pages/cpp_api/cpp-api-preprocessing-quantize-pq.md @@ -34,7 +34,7 @@ struct params { ... } ; _Source: `cpp/include/cuvs/preprocessing/quantize/pq.hpp:30`_ -### cuvs::preprocessing::quantize::pq::params +**Additional overload:** `cuvs::preprocessing::quantize::pq::params` Simplified constructor that will build an appropriate kmeans params object. @@ -100,7 +100,7 @@ quantizer _Source: `cpp/include/cuvs/preprocessing/quantize/pq.hpp:169`_ -### cuvs::preprocessing::quantize::pq::build +**Additional overload:** `cuvs::preprocessing::quantize::pq::build` ```cpp quantizer build(raft::resources const& res, @@ -152,7 +152,7 @@ Usage example: used, optional _Source: `cpp/include/cuvs/preprocessing/quantize/pq.hpp:201`_ -### cuvs::preprocessing::quantize::pq::transform +**Additional overload:** `cuvs::preprocessing::quantize::pq::transform` ```cpp void transform(raft::resources const& res, diff --git a/fern/pages/cpp_api/cpp-api-preprocessing-quantize-scalar.md b/fern/pages/cpp_api/cpp-api-preprocessing-quantize-scalar.md index 8a08820f37..cc631cd1af 100644 --- a/fern/pages/cpp_api/cpp-api-preprocessing-quantize-scalar.md +++ b/fern/pages/cpp_api/cpp-api-preprocessing-quantize-scalar.md @@ -54,7 +54,7 @@ quantizer _Source: `cpp/include/cuvs/preprocessing/quantize/scalar.hpp:67`_ -### cuvs::preprocessing::quantize::scalar::train +**Additional overload:** `cuvs::preprocessing::quantize::scalar::train` Initializes a scalar quantizer to be used later for quantizing the dataset. @@ -110,7 +110,7 @@ Usage example: _Source: `cpp/include/cuvs/preprocessing/quantize/scalar.hpp:110`_ -### cuvs::preprocessing::quantize::scalar::transform +**Additional overload:** `cuvs::preprocessing::quantize::scalar::transform` Applies quantization transform to given dataset @@ -166,7 +166,7 @@ Note that depending on the chosen data types train dataset the conversion is not _Source: `cpp/include/cuvs/preprocessing/quantize/scalar.hpp:161`_ -### cuvs::preprocessing::quantize::scalar::inverse_transform +**Additional overload:** `cuvs::preprocessing::quantize::scalar::inverse_transform` Perform inverse quantization step on previously quantized dataset @@ -194,7 +194,7 @@ Note that depending on the chosen data types train dataset the conversion is not _Source: `cpp/include/cuvs/preprocessing/quantize/scalar.hpp:187`_ -### cuvs::preprocessing::quantize::scalar::train +**Additional overload:** `cuvs::preprocessing::quantize::scalar::train` Initializes a scalar quantizer to be used later for quantizing the dataset. @@ -222,7 +222,7 @@ quantizer _Source: `cpp/include/cuvs/preprocessing/quantize/scalar.hpp:208`_ -### cuvs::preprocessing::quantize::scalar::train +**Additional overload:** `cuvs::preprocessing::quantize::scalar::train` Initializes a scalar quantizer to be used later for quantizing the dataset. @@ -250,7 +250,7 @@ quantizer _Source: `cpp/include/cuvs/preprocessing/quantize/scalar.hpp:228`_ -### cuvs::preprocessing::quantize::scalar::transform +**Additional overload:** `cuvs::preprocessing::quantize::scalar::transform` Applies quantization transform to given dataset @@ -278,7 +278,7 @@ Usage example: _Source: `cpp/include/cuvs/preprocessing/quantize/scalar.hpp:251`_ -### cuvs::preprocessing::quantize::scalar::transform +**Additional overload:** `cuvs::preprocessing::quantize::scalar::transform` Applies quantization transform to given dataset @@ -306,7 +306,7 @@ Usage example: _Source: `cpp/include/cuvs/preprocessing/quantize/scalar.hpp:275`_ -### cuvs::preprocessing::quantize::scalar::inverse_transform +**Additional overload:** `cuvs::preprocessing::quantize::scalar::inverse_transform` Perform inverse quantization step on previously quantized dataset @@ -334,7 +334,7 @@ Note that depending on the chosen data types train dataset the conversion is not _Source: `cpp/include/cuvs/preprocessing/quantize/scalar.hpp:301`_ -### cuvs::preprocessing::quantize::scalar::inverse_transform +**Additional overload:** `cuvs::preprocessing::quantize::scalar::inverse_transform` Perform inverse quantization step on previously quantized dataset @@ -362,7 +362,7 @@ Note that depending on the chosen data types train dataset the conversion is not _Source: `cpp/include/cuvs/preprocessing/quantize/scalar.hpp:327`_ -### cuvs::preprocessing::quantize::scalar::train +**Additional overload:** `cuvs::preprocessing::quantize::scalar::train` Initializes a scalar quantizer to be used later for quantizing the dataset. @@ -390,7 +390,7 @@ quantizer _Source: `cpp/include/cuvs/preprocessing/quantize/scalar.hpp:348`_ -### cuvs::preprocessing::quantize::scalar::train +**Additional overload:** `cuvs::preprocessing::quantize::scalar::train` Initializes a scalar quantizer to be used later for quantizing the dataset. @@ -418,7 +418,7 @@ quantizer _Source: `cpp/include/cuvs/preprocessing/quantize/scalar.hpp:368`_ -### cuvs::preprocessing::quantize::scalar::transform +**Additional overload:** `cuvs::preprocessing::quantize::scalar::transform` Applies quantization transform to given dataset @@ -446,7 +446,7 @@ Usage example: _Source: `cpp/include/cuvs/preprocessing/quantize/scalar.hpp:391`_ -### cuvs::preprocessing::quantize::scalar::transform +**Additional overload:** `cuvs::preprocessing::quantize::scalar::transform` Applies quantization transform to given dataset @@ -474,7 +474,7 @@ Usage example: _Source: `cpp/include/cuvs/preprocessing/quantize/scalar.hpp:415`_ -### cuvs::preprocessing::quantize::scalar::inverse_transform +**Additional overload:** `cuvs::preprocessing::quantize::scalar::inverse_transform` Perform inverse quantization step on previously quantized dataset @@ -502,7 +502,7 @@ Note that depending on the chosen data types train dataset the conversion is not _Source: `cpp/include/cuvs/preprocessing/quantize/scalar.hpp:441`_ -### cuvs::preprocessing::quantize::scalar::inverse_transform +**Additional overload:** `cuvs::preprocessing::quantize::scalar::inverse_transform` Perform inverse quantization step on previously quantized dataset diff --git a/fern/pages/cpp_api/cpp-api-preprocessing-spectral-embedding.md b/fern/pages/cpp_api/cpp-api-preprocessing-spectral-embedding.md index 778dcf8fb3..b809a7de49 100644 --- a/fern/pages/cpp_api/cpp-api-preprocessing-spectral-embedding.md +++ b/fern/pages/cpp_api/cpp-api-preprocessing-spectral-embedding.md @@ -38,7 +38,7 @@ This function computes the spectral embedding of the input dataset by: 1. Constr _Source: `cpp/include/cuvs/preprocessing/spectral_embedding.hpp:115`_ -### cuvs::preprocessing::spectral_embedding::transform +**Additional overload:** `cuvs::preprocessing::spectral_embedding::transform` Perform spectral embedding using a precomputed connectivity graph diff --git a/fern/pages/cpp_api/cpp-api-selection-select-k.md b/fern/pages/cpp_api/cpp-api-selection-select-k.md index 7957ae9c70..9cefd4b72e 100644 --- a/fern/pages/cpp_api/cpp-api-selection-select-k.md +++ b/fern/pages/cpp_api/cpp-api-selection-select-k.md @@ -49,7 +49,7 @@ If you think of the input data `in_val` as a row-major matrix with `len` columns _Source: `cpp/include/cuvs/selection/select_k.hpp:68`_ -### cuvs::selection::select_k +**Additional overload:** `cuvs::selection::select_k` Select k smallest or largest key/values from each row in the input data. @@ -88,7 +88,7 @@ If you think of the input data `in_val` as a row-major matrix with `len` columns _Source: `cpp/include/cuvs/selection/select_k.hpp:133`_ -### cuvs::selection::select_k +**Additional overload:** `cuvs::selection::select_k` Select k smallest or largest key/values from each row in the input data. diff --git a/fern/pages/cpp_api/cpp-api-stats-silhouette-score.md b/fern/pages/cpp_api/cpp-api-stats-silhouette-score.md index 45393cc4bb..c302f1ac5a 100644 --- a/fern/pages/cpp_api/cpp-api-stats-silhouette-score.md +++ b/fern/pages/cpp_api/cpp-api-stats-silhouette-score.md @@ -82,7 +82,7 @@ clusterings nRows) for every sample (length: nRows) the calculations _Source: `cpp/include/cuvs/stats/silhouette_score.hpp:54`_ -### stats::silhouette_score +**Additional overload:** `stats::silhouette_score` main function that returns the average silhouette score for a given set of data and its @@ -117,7 +117,7 @@ clusterings nRows) for every sample (length: nRows) the calculations _Source: `cpp/include/cuvs/stats/silhouette_score.hpp:77`_ -### stats::silhouette_score_batched +**Additional overload:** `stats::silhouette_score_batched` function that returns the average silhouette score for a given set of data and its diff --git a/fern/scripts/generate_api_reference.py b/fern/scripts/generate_api_reference.py index d8af2e8f5c..b52c60fa7d 100755 --- a/fern/scripts/generate_api_reference.py +++ b/fern/scripts/generate_api_reference.py @@ -397,8 +397,9 @@ def generate_native_api_pages(index: DoxygenHeaderIndex, api: str) -> None: f"_Source header: `{page.source}`_", "", ] + page_headings: set[str] = set() for group in page.groups: - lines.extend(render_native_group(group, language)) + lines.extend(render_native_group(group, language, page_headings)) lines.append("") write_page( out_dir / f"{api_page_route(directory, page.slug)}.md", lines @@ -441,25 +442,42 @@ def collect_native_pages( return ordered -def render_native_group(group: DoxygenGroup, language: str) -> list[str]: +def render_native_group( + group: DoxygenGroup, language: str, page_headings: set[str] | None = None +) -> list[str]: lines = [f"## {heading_text(group.title or group.name)}", ""] if group.name: lines.extend([f"_Doxygen group: `{group.name}`_", ""]) + if page_headings is None: + page_headings = set() for entry in group.entries: if entry.kind == "function": - lines.extend(render_native_function(entry, language)) + include_heading = entry.name not in page_headings + page_headings.add(entry.name) + lines.extend( + render_native_function( + entry, language, include_heading=include_heading + ) + ) elif entry.kind in {"struct", "enum"}: + page_headings.add(entry.name) lines.extend(render_native_compound(entry, language)) else: + page_headings.add(entry.name) lines.extend(render_native_member(entry, language)) lines.append("") return trim_blank_lines(lines) -def render_native_function(entry: DoxygenEntry, language: str) -> list[str]: +def render_native_function( + entry: DoxygenEntry, language: str, include_heading: bool = True +) -> list[str]: signature = normalize_signature(entry.signature) - lines = [f"### {heading_text(entry.name)}", ""] + if include_heading: + lines = [f"### {heading_text(entry.name)}", ""] + else: + lines = [f"**Additional overload:** `{escape_code(entry.name)}`", ""] if entry.summary: lines.extend([escape_text(entry.summary), ""]) lines.extend([f"```{language}", signature, "```", ""]) From c336b1fd4944790de3616623b849f68e5b5e5d4c Mon Sep 17 00:00:00 2001 From: "Corey J. Nolet" Date: Thu, 7 May 2026 12:53:30 -0400 Subject: [PATCH 005/129] Preserve Doxygen lists in API docs --- fern/pages/c_api/c-api-cluster-kmeans.md | 4 +- fern/pages/c_api/c-api-core-c-api.md | 8 +- .../c_api/c-api-neighbors-brute-force.md | 11 +- fern/pages/c_api/c-api-neighbors-cagra.md | 53 ++- fern/pages/c_api/c-api-neighbors-hnsw.md | 25 +- fern/pages/c_api/c-api-neighbors-ivf-flat.md | 12 +- fern/pages/c_api/c-api-neighbors-ivf-pq.md | 36 ++- .../pages/c_api/c-api-neighbors-nn-descent.md | 7 +- .../c_api/c-api-neighbors-tiered-index.md | 5 +- fern/pages/c_api/c-api-neighbors-vamana.md | 14 +- .../cpp_api/cpp-api-cluster-agglomerative.md | 8 +- fern/pages/cpp_api/cpp-api-cluster-kmeans.md | 11 +- .../pages/cpp_api/cpp-api-cluster-spectral.md | 4 +- .../cpp_api/cpp-api-distance-distance.md | 24 +- .../cpp-api-neighbors-all-neighbors.md | 12 +- .../cpp_api/cpp-api-neighbors-ball-cover.md | 4 +- .../cpp_api/cpp-api-neighbors-brute-force.md | 8 +- fern/pages/cpp_api/cpp-api-neighbors-cagra.md | 188 +++++++++-- .../cpp-api-neighbors-dynamic-batching.md | 6 +- .../cpp-api-neighbors-epsilon-neighborhood.md | 4 +- fern/pages/cpp_api/cpp-api-neighbors-hnsw.md | 138 ++++++-- .../cpp_api/cpp-api-neighbors-ivf-flat.md | 302 +++++++++++++++--- .../pages/cpp_api/cpp-api-neighbors-ivf-pq.md | 243 +++++++++++--- .../cpp_api/cpp-api-neighbors-nn-descent.md | 115 ++++++- .../pages/cpp_api/cpp-api-neighbors-refine.md | 60 +++- fern/pages/cpp_api/cpp-api-neighbors-scann.md | 8 +- .../pages/cpp_api/cpp-api-neighbors-vamana.md | 48 ++- .../cpp_api/cpp-api-preprocessing-pca.md | 4 +- .../cpp-api-preprocessing-quantize-binary.md | 16 +- .../cpp-api-preprocessing-quantize-pq.md | 8 +- .../cpp-api-preprocessing-quantize-scalar.md | 24 +- ...pp-api-preprocessing-spectral-embedding.md | 15 +- .../cpp_api/cpp-api-selection-select-k.md | 12 +- .../python-api-neighbors-brute-force.md | 2 +- .../python_api/python-api-neighbors-cagra.md | 8 +- .../python-api-neighbors-filters.md | 4 +- .../python_api/python-api-neighbors-hnsw.md | 4 +- .../python-api-neighbors-ivf-flat.md | 2 +- .../python_api/python-api-neighbors-ivf-pq.md | 8 +- .../python-api-neighbors-tiered-index.md | 2 +- .../python_api/python-api-neighbors-vamana.md | 2 +- fern/scripts/generate_api_reference.py | 123 +++++-- 42 files changed, 1307 insertions(+), 285 deletions(-) diff --git a/fern/pages/c_api/c-api-cluster-kmeans.md b/fern/pages/c_api/c-api-cluster-kmeans.md index e915e49df1..3a4497b3ec 100644 --- a/fern/pages/c_api/c-api-cluster-kmeans.md +++ b/fern/pages/c_api/c-api-cluster-kmeans.md @@ -135,7 +135,9 @@ double* inertia, int* n_iter); ``` -Initial centroids are chosen with k-means++ algorithm. Empty clusters are reinitialized by choosing new centroids with k-means++ algorithm. X may reside on either host (CPU) or device (GPU) memory. When X is on the host the data is streamed to the GPU in batches controlled by params->streaming_batch_size. +Initial centroids are chosen with k-means++ algorithm. Empty clusters are reinitialized by choosing new centroids with k-means++ algorithm. + +X may reside on either host (CPU) or device (GPU) memory. When X is on the host the data is streamed to the GPU in batches controlled by params->streaming_batch_size. **Parameters** diff --git a/fern/pages/c_api/c-api-core-c-api.md b/fern/pages/c_api/c-api-core-c-api.md index ce8274fee9..2bbc5bb304 100644 --- a/fern/pages/c_api/c-api-core-c-api.md +++ b/fern/pages/c_api/c-api-core-c-api.md @@ -423,7 +423,9 @@ int max_pool_size_percent, bool managed); ``` -bypass unnecessary synchronizations by allocating a chunk of device memory up front and carving that up for temporary memory allocations within algorithms. Be aware that this function will change the memory resource for the whole process and the new memory resource will be used until explicitly changed. available memory available memory +bypass unnecessary synchronizations by allocating a chunk of device memory up front and carving that up for temporary memory allocations within algorithms. Be aware that this function will change the memory resource for the whole process and the new memory resource will be used until explicitly changed. + +available memory available memory **Parameters** @@ -535,7 +537,9 @@ Copy a matrix cuvsError_t cuvsMatrixCopy(cuvsResources_t res, DLManagedTensor* src, DLManagedTensor* dst); ``` -This function copies a matrix from dst to src. This lets you copy a matrix from device memory to host memory (or vice versa), while accounting for differences in strides. Both src and dst must have the same shape and dtype, but can have different strides and device type. The memory for the output dst tensor must already be allocated and the tensor initialized. +This function copies a matrix from dst to src. This lets you copy a matrix from device memory to host memory (or vice versa), while accounting for differences in strides. + +Both src and dst must have the same shape and dtype, but can have different strides and device type. The memory for the output dst tensor must already be allocated and the tensor initialized. **Parameters** diff --git a/fern/pages/c_api/c-api-neighbors-brute-force.md b/fern/pages/c_api/c-api-neighbors-brute-force.md index a1f948ed2f..5aa8adf076 100644 --- a/fern/pages/c_api/c-api-neighbors-brute-force.md +++ b/fern/pages/c_api/c-api-neighbors-brute-force.md @@ -68,7 +68,10 @@ float metric_arg, cuvsBruteForceIndex_t index); ``` -`DLDeviceType` equal to `kDLCUDA`, `kDLCUDAHost`, `kDLCUDAManaged`, or `kDLCPU`. Also, acceptable underlying types are: 1. `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 32` 2. `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 16` +`DLDeviceType` equal to `kDLCUDA`, `kDLCUDAHost`, `kDLCUDAManaged`, or `kDLCPU`. Also, acceptable underlying types are: + +1. `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 32` +2. `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 16` **Parameters** @@ -105,7 +108,11 @@ DLManagedTensor* distances, cuvsFilter prefilter); ``` -`DLDeviceType` equal to `kDLCUDA`, `kDLCUDAHost`, `kDLCUDAManaged`. It is also important to note that the BRUTEFORCE index must have been built with the same type of `queries`, such that `index.dtype.code == queries.dl_tensor.dtype.code` Types for input are: 1. `queries`: `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 32` or `kDLDataType.bits = 16` 2. `neighbors`: `kDLDataType.code == kDLUInt` and `kDLDataType.bits = 32` 3. `distances`: `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 32` +`DLDeviceType` equal to `kDLCUDA`, `kDLCUDAHost`, `kDLCUDAManaged`. It is also important to note that the BRUTEFORCE index must have been built with the same type of `queries`, such that `index.dtype.code == queries.dl_tensor.dtype.code` Types for input are: + +1. `queries`: `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 32` or `kDLDataType.bits = 16` +2. `neighbors`: `kDLDataType.code == kDLUInt` and `kDLDataType.bits = 32` +3. `distances`: `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 32` **Parameters** diff --git a/fern/pages/c_api/c-api-neighbors-cagra.md b/fern/pages/c_api/c-api-neighbors-cagra.md index 38a2cb8882..cc6c181695 100644 --- a/fern/pages/c_api/c-api-neighbors-cagra.md +++ b/fern/pages/c_api/c-api-neighbors-cagra.md @@ -31,7 +31,9 @@ _Source: `c/include/cuvs/neighbors/cagra.h:29`_ A strategy for selecting the graph build parameters based on similar HNSW index -parameters. Define how cuvsCagraIndexParamsFromHnswParams should construct a graph to construct a graph that is to be converted to (used by) a CPU HNSW index. +parameters. + +Define how cuvsCagraIndexParamsFromHnswParams should construct a graph to construct a graph that is to be converted to (used by) a CPU HNSW index. ```c enum cuvsCagraHnswHeuristicType { ... } ; @@ -64,7 +66,11 @@ _Source: `c/include/cuvs/neighbors/cagra.h:82`_ Parameters for ACE (Augmented Core Extraction) graph build. -ACE enables building indexes for datasets too large to fit in GPU memory by: 1. Partitioning the dataset in core (closest) and augmented (second-closest) partitions using balanced k-means. 2. Building sub-indexes for each partition independently 3. Concatenating sub-graphs into a final unified index +ACE enables building indexes for datasets too large to fit in GPU memory by: + +1. Partitioning the dataset in core (closest) and augmented (second-closest) partitions using balanced k-means. +2. Building sub-indexes for each partition independently +3. Concatenating sub-graphs into a final unified index ```c struct cuvsAceParams { ... } ; @@ -348,7 +354,12 @@ DLManagedTensor* additional_dataset, cuvsCagraIndex_t index); ``` -`DLDeviceType` equal to `kDLCUDA`, `kDLCUDAHost`, `kDLCUDAManaged`, or `kDLCPU`. Also, acceptable underlying types are: 1. `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 32` 2. `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 16` 3. `kDLDataType.code == kDLInt` and `kDLDataType.bits = 8` 4. `kDLDataType.code == kDLUInt` and `kDLDataType.bits = 8` +`DLDeviceType` equal to `kDLCUDA`, `kDLCUDAHost`, `kDLCUDAManaged`, or `kDLCPU`. Also, acceptable underlying types are: + +1. `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 32` +2. `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 16` +3. `kDLDataType.code == kDLInt` and `kDLDataType.bits = 8` +4. `kDLDataType.code == kDLUInt` and `kDLDataType.bits = 8` **Parameters** @@ -606,7 +617,9 @@ Returns a view of the CAGRA dataset cuvsError_t cuvsCagraIndexGetDataset(cuvsCagraIndex_t index, DLManagedTensor* dataset); ``` -This function returns a non-owning view of the CAGRA dataset. The output will be referencing device memory that is directly used in CAGRA, without copying the dataset at all. This means that the output is only valid as long as the CAGRA index is alive, and once cuvsCagraIndexDestroy is called on the cagra index - the returned dataset view will be invalid. Note that the DLManagedTensor dataset returned will have an associated 'deleter' function that must be called when the dataset is no longer needed. This will free up host memory that stores the shape of the dataset view. +This function returns a non-owning view of the CAGRA dataset. The output will be referencing device memory that is directly used in CAGRA, without copying the dataset at all. This means that the output is only valid as long as the CAGRA index is alive, and once cuvsCagraIndexDestroy is called on the cagra index - the returned dataset view will be invalid. + +Note that the DLManagedTensor dataset returned will have an associated 'deleter' function that must be called when the dataset is no longer needed. This will free up host memory that stores the shape of the dataset view. **Parameters** @@ -631,7 +644,9 @@ Returns a view of the CAGRA graph cuvsError_t cuvsCagraIndexGetGraph(cuvsCagraIndex_t index, DLManagedTensor* graph); ``` -This function returns a non-owning view of the CAGRA graph. The output will be referencing device memory that is directly used in CAGRA, without copying the graph at all. This means that the output is only valid as long as the CAGRA index is alive, and once cuvsCagraIndexDestroy is called on the cagra index - the returned graph view will be invalid. Note that the DLManagedTensor graph returned will have an associated 'deleter' function that must be called when the graph is no longer needed. This will free up host memory that stores the metadata for the graph view. +This function returns a non-owning view of the CAGRA graph. The output will be referencing device memory that is directly used in CAGRA, without copying the graph at all. This means that the output is only valid as long as the CAGRA index is alive, and once cuvsCagraIndexDestroy is called on the cagra index - the returned graph view will be invalid. + +Note that the DLManagedTensor graph returned will have an associated 'deleter' function that must be called when the graph is no longer needed. This will free up host memory that stores the metadata for the graph view. **Parameters** @@ -663,7 +678,12 @@ DLManagedTensor* dataset, cuvsCagraIndex_t index); ``` -`DLDeviceType` equal to `kDLCUDA`, `kDLCUDAHost`, `kDLCUDAManaged`, or `kDLCPU`. Also, acceptable underlying types are: 1. `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 32` 2. `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 16` 3. `kDLDataType.code == kDLInt` and `kDLDataType.bits = 8` 4. `kDLDataType.code == kDLUInt` and `kDLDataType.bits = 8` +`DLDeviceType` equal to `kDLCUDA`, `kDLCUDAHost`, `kDLCUDAManaged`, or `kDLCPU`. Also, acceptable underlying types are: + +1. `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 32` +2. `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 16` +3. `kDLDataType.code == kDLInt` and `kDLDataType.bits = 8` +4. `kDLDataType.code == kDLUInt` and `kDLDataType.bits = 8` **Parameters** @@ -700,7 +720,11 @@ DLManagedTensor* distances, cuvsFilter filter); ``` -`DLDeviceType` equal to `kDLCUDA`, `kDLCUDAHost`, `kDLCUDAManaged`. It is also important to note that the CAGRA Index must have been built with the same type of `queries`, such that `index.dtype.code == queries.dl_tensor.dtype.code` Types for input are: 1. `queries`: a. `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 32` b. `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 16` c. `kDLDataType.code == kDLInt` and `kDLDataType.bits = 8` d. `kDLDataType.code == kDLUInt` and `kDLDataType.bits = 8` 2. `neighbors`: `kDLDataType.code == kDLUInt` and `kDLDataType.bits = 32` or `kDLDataType.code == kDLInt` and `kDLDataType.bits = 64` 3. `distances`: `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 32` +`DLDeviceType` equal to `kDLCUDA`, `kDLCUDAHost`, `kDLCUDAManaged`. It is also important to note that the CAGRA Index must have been built with the same type of `queries`, such that `index.dtype.code == queries.dl_tensor.dtype.code` Types for input are: + +1. `queries`: a. `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 32` b. `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 16` c. `kDLDataType.code == kDLInt` and `kDLDataType.bits = 8` d. `kDLDataType.code == kDLUInt` and `kDLDataType.bits = 8` +2. `neighbors`: `kDLDataType.code == kDLUInt` and `kDLDataType.bits = 32` or `kDLDataType.code == kDLInt` and `kDLDataType.bits = 64` +3. `distances`: `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 32` **Parameters** @@ -762,7 +786,9 @@ const char* filename, cuvsCagraIndex_t index); ``` -NOTE: The saved index can only be read by the hnswlib wrapper in cuVS, as the serialization format is not compatible with the original hnswlib. Experimental, both the API and the serialization format are subject to change. +NOTE: The saved index can only be read by the hnswlib wrapper in cuVS, as the serialization format is not compatible with the original hnswlib. + +Experimental, both the API and the serialization format are subject to change. **Parameters** @@ -847,7 +873,16 @@ cuvsFilter filter, cuvsCagraIndex_t output_index); ``` -All input indices must have been built with the same data type (`index.dtype`) and have the same dimensionality (`index.dims`). The merged index uses the output parameters specified in `cuvsCagraIndexParams`. Input indices must have: - `index.dtype.code` and `index.dtype.bits` matching across all indices. - Supported data types for indices: a. `kDLFloat` with `bits = 32` b. `kDLFloat` with `bits = 16` c. `kDLInt` with `bits = 8` d. `kDLUInt` with `bits = 8` The resulting output index will have the same data type as the input indices. Example: +All input indices must have been built with the same data type (`index.dtype`) and have the same dimensionality (`index.dims`). The merged index uses the output parameters specified in `cuvsCagraIndexParams`. + +Input indices must have: + +- `index.dtype.code` and `index.dtype.bits` matching across all indices. +- Supported data types for indices: a. `kDLFloat` with `bits = 32` b. `kDLFloat` with `bits = 16` c. `kDLInt` with `bits = 8` d. `kDLUInt` with `bits = 8` + +The resulting output index will have the same data type as the input indices. + +Example: **Parameters** diff --git a/fern/pages/c_api/c-api-neighbors-hnsw.md b/fern/pages/c_api/c-api-neighbors-hnsw.md index 3c3f472546..ff05f0976c 100644 --- a/fern/pages/c_api/c-api-neighbors-hnsw.md +++ b/fern/pages/c_api/c-api-neighbors-hnsw.md @@ -33,7 +33,11 @@ _Source: `c/include/cuvs/neighbors/hnsw.h:30`_ Parameters for ACE (Augmented Core Extraction) graph build for HNSW. -ACE enables building indexes for datasets too large to fit in GPU memory by: 1. Partitioning the dataset in core and augmented partitions using balanced k-means 2. Building sub-indexes for each partition independently 3. Concatenating sub-graphs into a final unified index +ACE enables building indexes for datasets too large to fit in GPU memory by: + +1. Partitioning the dataset in core and augmented partitions using balanced k-means +2. Building sub-indexes for each partition independently +3. Concatenating sub-graphs into a final unified index ```c struct cuvsHnswAceParams { ... } ; @@ -264,7 +268,10 @@ cuvsCagraIndex_t cagra_index, cuvsHnswIndex_t hnsw_index); ``` -NOTE: When hierarchy is: 1. `NONE`: This method uses the filesystem to write the CAGRA index in `/tmp/<random_number>.bin` before reading it as an hnswlib index, then deleting the temporary file. The returned index is immutable and can only be searched by the hnswlib wrapper in cuVS, as the format is not compatible with the original hnswlib. 2. `CPU`: The returned index is mutable and can be extended with additional vectors. The serialized index is also compatible with the original hnswlib library. +NOTE: When hierarchy is: + +1. `NONE`: This method uses the filesystem to write the CAGRA index in `/tmp/<random_number>.bin` before reading it as an hnswlib index, then deleting the temporary file. The returned index is immutable and can only be searched by the hnswlib wrapper in cuVS, as the format is not compatible with the original hnswlib. +2. `CPU`: The returned index is mutable and can be extended with additional vectors. The serialized index is also compatible with the original hnswlib library. **Parameters** @@ -298,7 +305,13 @@ DLManagedTensor* dataset, cuvsHnswIndex_t index); ``` -ACE enables building HNSW indexes for datasets too large to fit in GPU memory by: 1. Partitioning the dataset using balanced k-means into core and augmented partitions 2. Building sub-indexes for each partition independently 3. Concatenating sub-graphs into a final unified index NOTE: This function requires CUDA to be available at runtime. +ACE enables building HNSW indexes for datasets too large to fit in GPU memory by: + +1. Partitioning the dataset using balanced k-means into core and augmented partitions +2. Building sub-indexes for each partition independently +3. Concatenating sub-graphs into a final unified index + +NOTE: This function requires CUDA to be available at runtime. **Parameters** @@ -433,7 +446,11 @@ DLManagedTensor* neighbors, DLManagedTensor* distances); ``` -`DLDeviceType` equal to `kDLCPU`, `kDLCUDAHost`, or `kDLCUDAManaged`. It is also important to note that the HNSW Index must have been built with the same type of `queries`, such that `index.dtype.code == queries.dl_tensor.dtype.code` Supported types for input are: 1. `queries`: a. `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 32` b. `kDLDataType.code == kDLInt` and `kDLDataType.bits = 8` c. `kDLDataType.code == kDLUInt` and `kDLDataType.bits = 8` 2. `neighbors`: `kDLDataType.code == kDLUInt` and `kDLDataType.bits = 64` 3. `distances`: `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 32` NOTE: When hierarchy is `NONE`, the HNSW index can only be searched by the hnswlib wrapper in cuVS, as the format is not compatible with the original hnswlib. +`DLDeviceType` equal to `kDLCPU`, `kDLCUDAHost`, or `kDLCUDAManaged`. It is also important to note that the HNSW Index must have been built with the same type of `queries`, such that `index.dtype.code == queries.dl_tensor.dtype.code` Supported types for input are: + +1. `queries`: a. `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 32` b. `kDLDataType.code == kDLInt` and `kDLDataType.bits = 8` c. `kDLDataType.code == kDLUInt` and `kDLDataType.bits = 8` +2. `neighbors`: `kDLDataType.code == kDLUInt` and `kDLDataType.bits = 64` +3. `distances`: `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 32` NOTE: When hierarchy is `NONE`, the HNSW index can only be searched by the hnswlib wrapper in cuVS, as the format is not compatible with the original hnswlib. **Parameters** diff --git a/fern/pages/c_api/c-api-neighbors-ivf-flat.md b/fern/pages/c_api/c-api-neighbors-ivf-flat.md index 128e99d146..f2ebeb6813 100644 --- a/fern/pages/c_api/c-api-neighbors-ivf-flat.md +++ b/fern/pages/c_api/c-api-neighbors-ivf-flat.md @@ -267,7 +267,11 @@ DLManagedTensor* dataset, cuvsIvfFlatIndex_t index); ``` -`DLDeviceType` equal to `kDLCUDA`, `kDLCUDAHost`, `kDLCUDAManaged`, or `kDLCPU`. Also, acceptable underlying types are: 1. `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 32` 2. `kDLDataType.code == kDLInt` and `kDLDataType.bits = 8` 3. `kDLDataType.code == kDLUInt` and `kDLDataType.bits = 8` +`DLDeviceType` equal to `kDLCUDA`, `kDLCUDAHost`, `kDLCUDAManaged`, or `kDLCPU`. Also, acceptable underlying types are: + +1. `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 32` +2. `kDLDataType.code == kDLInt` and `kDLDataType.bits = 8` +3. `kDLDataType.code == kDLUInt` and `kDLDataType.bits = 8` **Parameters** @@ -304,7 +308,11 @@ DLManagedTensor* distances, cuvsFilter filter); ``` -`DLDeviceType` equal to `kDLCUDA`, `kDLCUDAHost`, `kDLCUDAManaged`. It is also important to note that the IVF-Flat Index must have been built with the same type of `queries`, such that `index.dtype.code == queries.dl_tensor.dtype.code` Types for input are: 1. `queries`: `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 32` 2. `neighbors`: `kDLDataType.code == kDLUInt` and `kDLDataType.bits = 32` 3. `distances`: `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 32` +`DLDeviceType` equal to `kDLCUDA`, `kDLCUDAHost`, `kDLCUDAManaged`. It is also important to note that the IVF-Flat Index must have been built with the same type of `queries`, such that `index.dtype.code == queries.dl_tensor.dtype.code` Types for input are: + +1. `queries`: `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 32` +2. `neighbors`: `kDLDataType.code == kDLUInt` and `kDLDataType.bits = 32` +3. `distances`: `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 32` **Parameters** diff --git a/fern/pages/c_api/c-api-neighbors-ivf-pq.md b/fern/pages/c_api/c-api-neighbors-ivf-pq.md index 955b877334..259301ba29 100644 --- a/fern/pages/c_api/c-api-neighbors-ivf-pq.md +++ b/fern/pages/c_api/c-api-neighbors-ivf-pq.md @@ -390,7 +390,9 @@ Get the padded cluster centers [n_lists, dim_ext] cuvsError_t cuvsIvfPqIndexGetCentersPadded(cuvsIvfPqIndex_t index, DLManagedTensor* centers); ``` -where dim_ext = round_up(dim + 1, 8) This returns the full padded centers as a contiguous array, suitable for use with cuvsIvfPqBuildPrecomputed. +where dim_ext = round_up(dim + 1, 8) + +This returns the full padded centers as a contiguous array, suitable for use with cuvsIvfPqBuildPrecomputed. **Parameters** @@ -415,7 +417,8 @@ Get the PQ cluster centers cuvsError_t cuvsIvfPqIndexGetPqCenters(cuvsIvfPqIndex_t index, DLManagedTensor* pq_centers); ``` -- CUVS_IVF_PQ_CODEBOOK_GEN_PER_SUBSPACE: [pq_dim , pq_len, pq_book_size] - CUVS_IVF_PQ_CODEBOOK_GEN_PER_CLUSTER: [n_lists, pq_len, pq_book_size] +- CUVS_IVF_PQ_CODEBOOK_GEN_PER_SUBSPACE: [pq_dim , pq_len, pq_book_size] +- CUVS_IVF_PQ_CODEBOOK_GEN_PER_CLUSTER: [n_lists, pq_len, pq_book_size] **Parameters** @@ -466,7 +469,9 @@ cuvsError_t cuvsIvfPqIndexGetRotationMatrix(cuvsIvfPqIndex_t index, DLManagedTensor* rotation_matrix); ``` -Transform matrix (original space -> rotated padded space) data +Transform matrix (original space -> rotated padded space) + +data **Parameters** @@ -577,7 +582,12 @@ DLManagedTensor* dataset, cuvsIvfPqIndex_t index); ``` -`DLDeviceType` equal to `kDLCUDA`, `kDLCUDAHost`, `kDLCUDAManaged`, or `kDLCPU`. Also, acceptable underlying types are: 1. `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 32` 2. `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 16` 3. `kDLDataType.code == kDLInt` and `kDLDataType.bits = 8` 4. `kDLDataType.code == kDLUInt` and `kDLDataType.bits = 8` +`DLDeviceType` equal to `kDLCUDA`, `kDLCUDAHost`, `kDLCUDAManaged`, or `kDLCPU`. Also, acceptable underlying types are: + +1. `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 32` +2. `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 16` +3. `kDLDataType.code == kDLInt` and `kDLDataType.bits = 8` +4. `kDLDataType.code == kDLUInt` and `kDLDataType.bits = 8` **Parameters** @@ -611,7 +621,15 @@ DLManagedTensor* rotation_matrix, cuvsIvfPqIndex_t index); ``` -This function creates a non-owning index that stores a reference to the provided device data. All parameters must be provided with correct extents. The caller is responsible for ensuring the lifetime of the input data exceeds the lifetime of the returned index. The index_params must be consistent with the provided matrices. Specifically: - index_params.codebook_kind determines the expected shape of pq_centers - index_params.metric will be stored in the index - index_params.conservative_memory_allocation will be stored in the index The function will verify consistency between index_params, dim, and the matrix extents. matrices) dim] +This function creates a non-owning index that stores a reference to the provided device data. All parameters must be provided with correct extents. The caller is responsible for ensuring the lifetime of the input data exceeds the lifetime of the returned index. + +The index_params must be consistent with the provided matrices. Specifically: + +- index_params.codebook_kind determines the expected shape of pq_centers +- index_params.metric will be stored in the index +- index_params.conservative_memory_allocation will be stored in the index The function will verify consistency between index_params, dim, and the matrix extents. + +matrices) dim] **Parameters** @@ -620,7 +638,7 @@ This function creates a non-owning index that stores a reference to the provided | `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | | `params` | in | `cuvsIvfPqIndexParams_t` | cuvsIvfPqIndexParams_t used to configure the index (must be consistent with | | `dim` | in | `uint32_t` | dimensionality of the input data | -| `pq_centers` | in | `DLManagedTensor*` | PQ codebook on device memory with required shape: - codebook_kind CUVS_IVF_PQ_CODEBOOK_GEN_PER_SUBSPACE: [pq_dim, pq_len, pq_book_size] - codebook_kind CUVS_IVF_PQ_CODEBOOK_GEN_PER_CLUSTER: [n_lists, pq_len, pq_book_size] | +| `pq_centers` | in | `DLManagedTensor*` | PQ codebook on device memory with required shape:
- codebook_kind CUVS_IVF_PQ_CODEBOOK_GEN_PER_SUBSPACE: [pq_dim, pq_len, pq_book_size]
- codebook_kind CUVS_IVF_PQ_CODEBOOK_GEN_PER_CLUSTER: [n_lists, pq_len, pq_book_size] | | `centers` | in | `DLManagedTensor*` | Cluster centers in the original space [n_lists, dim_ext] where dim_ext = round_up(dim + 1, 8) | | `centers_rot` | in | `DLManagedTensor*` | Rotated cluster centers [n_lists, rot_dim] where rot_dim = pq_len * pq_dim | | `rotation_matrix` | in | `DLManagedTensor*` | Transform matrix (original space -> rotated padded space) [rot_dim, | @@ -651,7 +669,11 @@ DLManagedTensor* neighbors, DLManagedTensor* distances); ``` -`DLDeviceType` equal to `kDLCUDA`, `kDLCUDAHost`, `kDLCUDAManaged`. It is also important to note that the IVF-PQ Index must have been built with the same type of `queries`, such that `index.dtype.code == queries.dl_tensor.dtype.code` Types for input are: 1. `queries`: `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 32` or `kDLDataType.bits = 16` 2. `neighbors`: `kDLDataType.code == kDLUInt` and `kDLDataType.bits = 32` 3. `distances`: `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 32` +`DLDeviceType` equal to `kDLCUDA`, `kDLCUDAHost`, `kDLCUDAManaged`. It is also important to note that the IVF-PQ Index must have been built with the same type of `queries`, such that `index.dtype.code == queries.dl_tensor.dtype.code` Types for input are: + +1. `queries`: `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 32` or `kDLDataType.bits = 16` +2. `neighbors`: `kDLDataType.code == kDLUInt` and `kDLDataType.bits = 32` +3. `distances`: `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 32` **Parameters** diff --git a/fern/pages/c_api/c-api-neighbors-nn-descent.md b/fern/pages/c_api/c-api-neighbors-nn-descent.md index 4bd0c04822..37825002b1 100644 --- a/fern/pages/c_api/c-api-neighbors-nn-descent.md +++ b/fern/pages/c_api/c-api-neighbors-nn-descent.md @@ -141,7 +141,12 @@ DLManagedTensor* graph, cuvsNNDescentIndex_t index); ``` -`DLDeviceType` equal to `kDLCUDA`, `kDLCUDAHost`, `kDLCUDAManaged`, or `kDLCPU`. Also, acceptable underlying types are: 1. `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 32` 2. `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 16` 3. `kDLDataType.code == kDLInt` and `kDLDataType.bits = 8` 4. `kDLDataType.code == kDLUInt` and `kDLDataType.bits = 8` +`DLDeviceType` equal to `kDLCUDA`, `kDLCUDAHost`, `kDLCUDAManaged`, or `kDLCPU`. Also, acceptable underlying types are: + +1. `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 32` +2. `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 16` +3. `kDLDataType.code == kDLInt` and `kDLDataType.bits = 8` +4. `kDLDataType.code == kDLUInt` and `kDLDataType.bits = 8` **Parameters** diff --git a/fern/pages/c_api/c-api-neighbors-tiered-index.md b/fern/pages/c_api/c-api-neighbors-tiered-index.md index 1920a97856..1e33618116 100644 --- a/fern/pages/c_api/c-api-neighbors-tiered-index.md +++ b/fern/pages/c_api/c-api-neighbors-tiered-index.md @@ -137,7 +137,10 @@ DLManagedTensor* dataset, cuvsTieredIndex_t index); ``` -`DLDeviceType` equal to `kDLCUDA`, `kDLCUDAHost`, `kDLCUDAManaged`, or `kDLCPU`. Also, acceptable underlying types are: 1. `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 32` 2. `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 16` +`DLDeviceType` equal to `kDLCUDA`, `kDLCUDAHost`, `kDLCUDAManaged`, or `kDLCPU`. Also, acceptable underlying types are: + +1. `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 32` +2. `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 16` **Parameters** diff --git a/fern/pages/c_api/c-api-neighbors-vamana.md b/fern/pages/c_api/c-api-neighbors-vamana.md index 4749767725..be9f596484 100644 --- a/fern/pages/c_api/c-api-neighbors-vamana.md +++ b/fern/pages/c_api/c-api-neighbors-vamana.md @@ -166,7 +166,15 @@ DLManagedTensor* dataset, cuvsVamanaIndex_t index); ``` -Build the index from the dataset for efficient DiskANN search. The build uses the Vamana insertion-based algorithm to create the graph. The algorithm starts with an empty graph and iteratively inserts batches of nodes. Each batch involves performing a greedy search for each vector to be inserted, and inserting it with edges to all nodes traversed during the search. Reverse edges are also inserted and robustPrune is applied to improve graph quality. The index_params struct controls the degree of the final graph. The following distance metrics are supported: - L2 Usage example: +Build the index from the dataset for efficient DiskANN search. + +The build uses the Vamana insertion-based algorithm to create the graph. The algorithm starts with an empty graph and iteratively inserts batches of nodes. Each batch involves performing a greedy search for each vector to be inserted, and inserting it with edges to all nodes traversed during the search. Reverse edges are also inserted and robustPrune is applied to improve graph quality. The index_params struct controls the degree of the final graph. + +The following distance metrics are supported: + +- L2 + +Usage example: **Parameters** @@ -200,7 +208,9 @@ cuvsVamanaIndex_t index, bool include_dataset); ``` -Matches the file format used by the DiskANN open-source repository, allowing cross-compatibility. Serialized Index is to be used by the DiskANN open-source repository for graph search. +Matches the file format used by the DiskANN open-source repository, allowing cross-compatibility. + +Serialized Index is to be used by the DiskANN open-source repository for graph search. **Parameters** diff --git a/fern/pages/cpp_api/cpp-api-cluster-agglomerative.md b/fern/pages/cpp_api/cpp-api-cluster-agglomerative.md index a779840249..01bfc70ee4 100644 --- a/fern/pages/cpp_api/cpp-api-cluster-agglomerative.md +++ b/fern/pages/cpp_api/cpp-api-cluster-agglomerative.md @@ -129,7 +129,7 @@ std::optional> core_dists); | --- | --- | --- | --- | | `handle` | in | `raft::resources const&` | raft handle for resource reuse | | `X` | in | `raft::device_matrix_view` | data points on device memory (size n_rows * d) | -| `linkage_graph_params` | in | `std::variant` | Parameters controlling how the KNN graph is built. This can be either: - distance_params: standard distance-based KNN graph construction for traditional agglomerative clustering. - mutual_reachability_params: parameters to compute a mutual reachability graph for density-aware hierarchical clustering (e.g. HDBSCAN). | +| `linkage_graph_params` | in | `std::variant` | Parameters controlling how the KNN graph is built. This can be either:
- distance_params: standard distance-based KNN graph construction for traditional agglomerative clustering.
- mutual_reachability_params: parameters to compute a mutual reachability graph for density-aware hierarchical clustering (e.g. HDBSCAN). | | `metric` | in | `cuvs::distance::DistanceType` | distance metric to use | | `out_mst` | out | `raft::device_coo_matrix_view` | output MST sorted by edge weights (size n_rows - 1) | | `dendrogram` | out | `raft::device_matrix_view` | output dendrogram (size [n_rows - 1] * 2) | @@ -169,7 +169,7 @@ std::optional> core_dists); | --- | --- | --- | --- | | `handle` | in | `raft::resources const&` | raft handle for resource reuse | | `X` | in | `raft::host_matrix_view` | data points on host memory (size n_rows * d) | -| `linkage_graph_params` | in | `std::variant` | Parameters controlling how the KNN graph is built. This can be either: - distance_params: standard distance-based KNN graph construction for traditional agglomerative clustering. - mutual_reachability_params: parameters to compute a mutual reachability graph for density-aware hierarchical clustering (e.g. HDBSCAN). | +| `linkage_graph_params` | in | `std::variant` | Parameters controlling how the KNN graph is built. This can be either:
- distance_params: standard distance-based KNN graph construction for traditional agglomerative clustering.
- mutual_reachability_params: parameters to compute a mutual reachability graph for density-aware hierarchical clustering (e.g. HDBSCAN). | | `metric` | in | `cuvs::distance::DistanceType` | distance metric to use | | `out_mst` | out | `raft::device_coo_matrix_view` | output MST sorted by edge weights (size n_rows - 1) | | `dendrogram` | out | `raft::device_matrix_view` | output dendrogram (size [n_rows - 1] * 2) | @@ -197,7 +197,9 @@ raft::device_vector_view out_delta, raft::device_vector_view out_size); ``` -This function takes a sorted MST (represented as edges with source, destination, and weights) and constructs a dendrogram (hierarchical clustering tree) on the host. nnz) +This function takes a sorted MST (represented as edges with source, destination, and weights) and constructs a dendrogram (hierarchical clustering tree) on the host. + +nnz) **Parameters** diff --git a/fern/pages/cpp_api/cpp-api-cluster-kmeans.md b/fern/pages/cpp_api/cpp-api-cluster-kmeans.md index c15c254cbe..e483225194 100644 --- a/fern/pages/cpp_api/cpp-api-cluster-kmeans.md +++ b/fern/pages/cpp_api/cpp-api-cluster-kmeans.md @@ -44,7 +44,12 @@ _Source: `cpp/include/cuvs/cluster/kmeans.hpp:34`_ Simple object to specify hyper-parameters to the balanced k-means algorithm. -The following metrics are currently supported in k-means balanced: - CosineExpanded - InnerProduct - L2Expanded - L2SqrtExpanded +The following metrics are currently supported in k-means balanced: + +- CosineExpanded +- InnerProduct +- L2Expanded +- L2SqrtExpanded ```cpp struct balanced_params : base_params { ... } ; @@ -93,7 +98,9 @@ raft::host_scalar_view inertia, raft::host_scalar_view n_iter); ``` -TODO: Evaluate replacing the extent type with int64_t. Reference issue: https://github.com/rapidsai/cuvs/issues/1961 This overload supports out-of-core computation where the dataset resides on the host. Data is processed in GPU-sized batches, streaming from host to device. The batch size is controlled by params.streaming_batch_size. +TODO: Evaluate replacing the extent type with int64_t. Reference issue: https://github.com/rapidsai/cuvs/issues/1961 + +This overload supports out-of-core computation where the dataset resides on the host. Data is processed in GPU-sized batches, streaming from host to device. The batch size is controlled by params.streaming_batch_size. **Parameters** diff --git a/fern/pages/cpp_api/cpp-api-cluster-spectral.md b/fern/pages/cpp_api/cpp-api-cluster-spectral.md index 8965fe66af..acd988c90d 100644 --- a/fern/pages/cpp_api/cpp-api-cluster-spectral.md +++ b/fern/pages/cpp_api/cpp-api-cluster-spectral.md @@ -102,7 +102,9 @@ raft::device_matrix_view dataset, raft::device_vector_view labels); ``` -This overload automatically constructs the connectivity graph from the input dataset using k-nearest neighbors. n_clusters-1) +This overload automatically constructs the connectivity graph from the input dataset using k-nearest neighbors. + +n_clusters-1) **Parameters** diff --git a/fern/pages/cpp_api/cpp-api-distance-distance.md b/fern/pages/cpp_api/cpp-api-distance-distance.md index 350fcf0992..c1aeade2b5 100644 --- a/fern/pages/cpp_api/cpp-api-distance-distance.md +++ b/fern/pages/cpp_api/cpp-api-distance-distance.md @@ -24,7 +24,9 @@ cuvs::distance::DistanceType metric, float metric_arg = 2.0f); ``` -Note: Only contiguous row- or column-major layouts supported currently. Usage example: +Note: Only contiguous row- or column-major layouts supported currently. + +Usage example: **Parameters** @@ -57,7 +59,9 @@ cuvs::distance::DistanceType metric, double metric_arg = 2.0f); ``` -Note: Only contiguous row- or column-major layouts supported currently. Usage example: +Note: Only contiguous row- or column-major layouts supported currently. + +Usage example: **Parameters** @@ -90,7 +94,9 @@ cuvs::distance::DistanceType metric, float metric_arg = 2.0f); ``` -Note: Only contiguous row- or column-major layouts supported currently. Usage example: +Note: Only contiguous row- or column-major layouts supported currently. + +Usage example: **Parameters** @@ -123,7 +129,9 @@ cuvs::distance::DistanceType metric, float metric_arg = 2.0f); ``` -Note: Only contiguous row- or column-major layouts supported currently. Usage example: +Note: Only contiguous row- or column-major layouts supported currently. + +Usage example: **Parameters** @@ -156,7 +164,9 @@ cuvs::distance::DistanceType metric, double metric_arg = 2.0f); ``` -Note: Only contiguous row- or column-major layouts supported currently. Usage example: +Note: Only contiguous row- or column-major layouts supported currently. + +Usage example: **Parameters** @@ -189,7 +199,9 @@ cuvs::distance::DistanceType metric, float metric_arg = 2.0f); ``` -Note: Only contiguous row- or column-major layouts supported currently. Usage example: +Note: Only contiguous row- or column-major layouts supported currently. + +Usage example: **Parameters** diff --git a/fern/pages/cpp_api/cpp-api-neighbors-all-neighbors.md b/fern/pages/cpp_api/cpp-api-neighbors-all-neighbors.md index 9ce3bfada1..abcb1849d4 100644 --- a/fern/pages/cpp_api/cpp-api-neighbors-all-neighbors.md +++ b/fern/pages/cpp_api/cpp-api-neighbors-all-neighbors.md @@ -62,7 +62,11 @@ std::optional> core_distance float alpha = 1.0); ``` -training vectors) Usage example: compute core_distances. If core_distances is given, the resulting indices and distances will be mutual reachability space. +training vectors) + +Usage example: + +compute core_distances. If core_distances is given, the resulting indices and distances will be mutual reachability space. **Parameters** @@ -97,7 +101,11 @@ std::optional> core_distance float alpha = 1.0); ``` -vectors) params.n_clusters should be 1 for data on device. To use a larger params.n_clusters for efficient device memory usage, put data on host RAM. Usage example: compute core_distances. If core_distances is given, the resulting indices and distances will be mutual reachability space. +vectors) params.n_clusters should be 1 for data on device. To use a larger params.n_clusters for efficient device memory usage, put data on host RAM. + +Usage example: + +compute core_distances. If core_distances is given, the resulting indices and distances will be mutual reachability space. **Parameters** diff --git a/fern/pages/cpp_api/cpp-api-neighbors-ball-cover.md b/fern/pages/cpp_api/cpp-api-neighbors-ball-cover.md index 9bc53fa9b3..e08c06c706 100644 --- a/fern/pages/cpp_api/cpp-api-neighbors-ball-cover.md +++ b/fern/pages/cpp_api/cpp-api-neighbors-ball-cover.md @@ -18,7 +18,9 @@ Builds and populates a previously unbuilt cuvs::neighbors::ball_cover::index void build(raft::resources const& handle, index& index); ``` -Usage example: cuvs::neighbors::ball_cover::index +Usage example: + +cuvs::neighbors::ball_cover::index **Parameters** diff --git a/fern/pages/cpp_api/cpp-api-neighbors-brute-force.md b/fern/pages/cpp_api/cpp-api-neighbors-brute-force.md index 34003bf2bc..bb15195473 100644 --- a/fern/pages/cpp_api/cpp-api-neighbors-brute-force.md +++ b/fern/pages/cpp_api/cpp-api-neighbors-brute-force.md @@ -594,7 +594,9 @@ const cuvs::neighbors::brute_force::index& index, bool include_dataset = true); ``` -The serialization format can be subject to changes, therefore loading an index saved with a previous version of cuvs is not guaranteed to work. output +The serialization format can be subject to changes, therefore loading an index saved with a previous version of cuvs is not guaranteed to work. + +output **Template Parameters** @@ -628,7 +630,9 @@ const cuvs::neighbors::brute_force::index& index, bool include_dataset = true); ``` -The serialization format can be subject to changes, therefore loading an index saved with a previous version of cuvs is not guaranteed to work. output +The serialization format can be subject to changes, therefore loading an index saved with a previous version of cuvs is not guaranteed to work. + +output **Template Parameters** diff --git a/fern/pages/cpp_api/cpp-api-neighbors-cagra.md b/fern/pages/cpp_api/cpp-api-neighbors-cagra.md index efa76ebeef..919965507d 100644 --- a/fern/pages/cpp_api/cpp-api-neighbors-cagra.md +++ b/fern/pages/cpp_api/cpp-api-neighbors-cagra.md @@ -38,7 +38,9 @@ _Source: `cpp/include/cuvs/neighbors/common.hpp:42`_ A strategy for selecting the graph build parameters based on similar HNSW index -parameters. Define how `cagra::index_params::from_hnsw_params` should construct a graph to construct a graph that is to be converted to (used by) a CPU HNSW index. +parameters. + +Define how `cagra::index_params::from_hnsw_params` should construct a graph to construct a graph that is to be converted to (used by) a CPU HNSW index. ```cpp enum class hnsw_heuristic_type : uint32_t { ... } ; @@ -59,7 +61,11 @@ hnsw_heuristic_type heuristic = hnsw_heuristic_type::SIMILAR_SEARCH_PERFOR cuvs::distance::DistanceType metric = cuvs::distance::DistanceType::L2Expanded); ``` -* IMPORTANT NOTE * The reference HNSW index and the corresponding from-CAGRA generated HNSW index will NOT produce exactly the same recalls and QPS for the same parameter `ef`. The graphs are different internally. Depending on the selected heuristics, the CAGRA-produced graph's QPS-Recall curve may be shifted along the curve right or left. See the heuristics descriptions for more details. Usage example: +* IMPORTANT NOTE * + +The reference HNSW index and the corresponding from-CAGRA generated HNSW index will NOT produce exactly the same recalls and QPS for the same parameter `ef`. The graphs are different internally. Depending on the selected heuristics, the CAGRA-produced graph's QPS-Recall curve may be shifted along the curve right or left. See the heuristics descriptions for more details. + +Usage example: **Parameters** @@ -341,7 +347,17 @@ graph_accessor> knn_graph) : cuvs::neighbors::index(), ``` -If the dataset and graph is already in GPU memory, then the index is just a thin wrapper around these that stores a non-owning a reference to the arrays. The constructor also accepts host arrays. In that case they are copied to the device, and the device arrays will be owned by the index. In case the dasates rows are not 16 bytes aligned, then we create a padded copy in device memory to ensure alignment for vectorized load. Usage examples: - Cagra index is normally created by the cagra::build In the above example, we have passed a host dataset to build. The returned index will own a device copy of the dataset and the knn_graph. In contrast, if we pass the dataset as a device_mdspan to build, then it will only store a reference to it. - Constructing index using existing knn-graph +If the dataset and graph is already in GPU memory, then the index is just a thin wrapper around these that stores a non-owning a reference to the arrays. + +The constructor also accepts host arrays. In that case they are copied to the device, and the device arrays will be owned by the index. + +In case the dasates rows are not 16 bytes aligned, then we create a padded copy in device memory to ensure alignment for vectorized load. + +Usage examples: + +- Cagra index is normally created by the cagra::build In the above example, we have passed a host dataset to build. The returned index will own a device copy of the dataset and the knn_graph. In contrast, if we pass the dataset as a device_mdspan to build, then it will only store a reference to it. + +- Constructing index using existing knn-graph **Parameters** @@ -367,7 +383,9 @@ void update_dataset(raft::resources const& res, raft::device_matrix_view dataset); ``` -If the new dataset rows are aligned on 16 bytes, then only a reference is stored to the dataset. It is the caller's responsibility to ensure that dataset stays alive as long as the index. It is expected that the same set of vectors are used for update_dataset and index build. Note: This will clear any precomputed dataset norms. +If the new dataset rows are aligned on 16 bytes, then only a reference is stored to the dataset. It is the caller's responsibility to ensure that dataset stays alive as long as the index. It is expected that the same set of vectors are used for update_dataset and index build. + +Note: This will clear any precomputed dataset norms. **Parameters** @@ -413,7 +431,9 @@ void update_dataset(raft::resources const& res, raft::host_matrix_view dataset); ``` -We create a copy of the dataset on the device. The index manages the lifetime of this copy. It is expected that the same set of vectors are used for update_dataset and index build. Note: This will clear any precomputed dataset norms. +We create a copy of the dataset on the device. The index manages the lifetime of this copy. It is expected that the same set of vectors are used for update_dataset and index build. + +Note: This will clear any precomputed dataset norms. **Parameters** @@ -438,7 +458,9 @@ auto update_dataset(raft::resources const& res, DatasetT&& dataset) -> std::enable_if_t, DatasetT>>; ``` -for update_dataset and index build. Note: This will clear any precomputed dataset norms. +for update_dataset and index build. + +Note: This will clear any precomputed dataset norms. **Parameters** @@ -632,7 +654,16 @@ raft::device_matrix_view dataset) -> cuvs::neighbors::cagra::index; ``` -The build consist of two steps: build an intermediate knn-graph, and optimize it to create the final graph. The index_params struct controls the node degree of these graphs. The following distance metrics are supported: - L2 - InnerProduct (currently only supported with IVF-PQ as the build algorithm) - CosineExpanded - L1 (currently only supported with NN-Descent and Iterative Search as the build algorithm) Usage example: +The build consist of two steps: build an intermediate knn-graph, and optimize it to create the final graph. The index_params struct controls the node degree of these graphs. + +The following distance metrics are supported: + +- L2 +- InnerProduct (currently only supported with IVF-PQ as the build algorithm) +- CosineExpanded +- L1 (currently only supported with NN-Descent and Iterative Search as the build algorithm) + +Usage example: **Parameters** @@ -661,7 +692,16 @@ raft::host_matrix_view dataset) -> cuvs::neighbors::cagra::index; ``` -The build consist of two steps: build an intermediate knn-graph, and optimize it to create the final graph. The index_params struct controls the node degree of these graphs. The following distance metrics are supported: - L2 - InnerProduct (currently only supported with IVF-PQ as the build algorithm) - CosineExpanded - L1 (currently only supported with NN-Descent and Iterative Search as the build algorithm) Usage example: +The build consist of two steps: build an intermediate knn-graph, and optimize it to create the final graph. The index_params struct controls the node degree of these graphs. + +The following distance metrics are supported: + +- L2 +- InnerProduct (currently only supported with IVF-PQ as the build algorithm) +- CosineExpanded +- L1 (currently only supported with NN-Descent and Iterative Search as the build algorithm) + +Usage example: **Parameters** @@ -690,7 +730,16 @@ raft::device_matrix_view dataset) -> cuvs::neighbors::cagra::index; ``` -The build consist of two steps: build an intermediate knn-graph, and optimize it to create the final graph. The index_params struct controls the node degree of these graphs. The following distance metrics are supported: - L2 - InnerProduct (currently only supported with IVF-PQ as the build algorithm) - CosineExpanded (dataset norms are computed as float regardless of input data type) - L1 (currently only supported with NN-Descent and Iterative Search as the build algorithm) Usage example: +The build consist of two steps: build an intermediate knn-graph, and optimize it to create the final graph. The index_params struct controls the node degree of these graphs. + +The following distance metrics are supported: + +- L2 +- InnerProduct (currently only supported with IVF-PQ as the build algorithm) +- CosineExpanded (dataset norms are computed as float regardless of input data type) +- L1 (currently only supported with NN-Descent and Iterative Search as the build algorithm) + +Usage example: **Parameters** @@ -719,7 +768,15 @@ raft::host_matrix_view dataset) -> cuvs::neighbors::cagra::index; ``` -The build consist of two steps: build an intermediate knn-graph, and optimize it to create the final graph. The index_params struct controls the node degree of these graphs. The following distance metrics are supported: - L2 - CosineExpanded (dataset norms are computed as float regardless of input data type) - L1 (currently only supported with NN-Descent and Iterative Search as the build algorithm) Usage example: +The build consist of two steps: build an intermediate knn-graph, and optimize it to create the final graph. The index_params struct controls the node degree of these graphs. + +The following distance metrics are supported: + +- L2 +- CosineExpanded (dataset norms are computed as float regardless of input data type) +- L1 (currently only supported with NN-Descent and Iterative Search as the build algorithm) + +Usage example: **Parameters** @@ -748,7 +805,16 @@ raft::device_matrix_view dataset) -> cuvs::neighbors::cagra::index; ``` -The build consist of two steps: build an intermediate knn-graph, and optimize it to create the final graph. The index_params struct controls the node degree of these graphs. The following distance metrics are supported: - L2 - CosineExpanded (dataset norms are computed as float regardless of input data type) - L1 (currently only supported with NN-Descent and Iterative Search as the build algorithm) - BitwiseHamming (currently only supported with NN-Descent and Iterative Search as the build algorithm, and only for int8_t and uint8_t data types) Usage example: +The build consist of two steps: build an intermediate knn-graph, and optimize it to create the final graph. The index_params struct controls the node degree of these graphs. + +The following distance metrics are supported: + +- L2 +- CosineExpanded (dataset norms are computed as float regardless of input data type) +- L1 (currently only supported with NN-Descent and Iterative Search as the build algorithm) +- BitwiseHamming (currently only supported with NN-Descent and Iterative Search as the build algorithm, and only for int8_t and uint8_t data types) + +Usage example: **Parameters** @@ -777,7 +843,17 @@ raft::host_matrix_view dataset) -> cuvs::neighbors::cagra::index; ``` -The build consist of two steps: build an intermediate knn-graph, and optimize it to create the final graph. The index_params struct controls the node degree of these graphs. The following distance metrics are supported: - L2 - InnerProduct (currently only supported with IVF-PQ as the build algorithm) - CosineExpanded (dataset norms are computed as float regardless of input data type) - L1 (currently only supported with NN-Descent and Iterative Search as the build algorithm) - BitwiseHamming (currently only supported with NN-Descent and Iterative Search as the build algorithm, and only for int8_t and uint8_t data types) Usage example: +The build consist of two steps: build an intermediate knn-graph, and optimize it to create the final graph. The index_params struct controls the node degree of these graphs. + +The following distance metrics are supported: + +- L2 +- InnerProduct (currently only supported with IVF-PQ as the build algorithm) +- CosineExpanded (dataset norms are computed as float regardless of input data type) +- L1 (currently only supported with NN-Descent and Iterative Search as the build algorithm) +- BitwiseHamming (currently only supported with NN-Descent and Iterative Search as the build algorithm, and only for int8_t and uint8_t data types) + +Usage example: **Parameters** @@ -806,7 +882,17 @@ raft::device_matrix_view dataset) -> cuvs::neighbors::cagra::index; ``` -The build consist of two steps: build an intermediate knn-graph, and optimize it to create the final graph. The index_params struct controls the node degree of these graphs. The following distance metrics are supported: - L2 - InnerProduct (currently only supported with IVF-PQ as the build algorithm) - CosineExpanded (dataset norms are computed as float regardless of input data type) - L1 (currently only supported with NN-Descent and Iterative Search as the build algorithm) - BitwiseHamming (currently only supported with NN-Descent and Iterative Search as the build algorithm, and only for int8_t and uint8_t data types) Usage example: +The build consist of two steps: build an intermediate knn-graph, and optimize it to create the final graph. The index_params struct controls the node degree of these graphs. + +The following distance metrics are supported: + +- L2 +- InnerProduct (currently only supported with IVF-PQ as the build algorithm) +- CosineExpanded (dataset norms are computed as float regardless of input data type) +- L1 (currently only supported with NN-Descent and Iterative Search as the build algorithm) +- BitwiseHamming (currently only supported with NN-Descent and Iterative Search as the build algorithm, and only for int8_t and uint8_t data types) + +Usage example: **Parameters** @@ -835,7 +921,17 @@ raft::host_matrix_view dataset) -> cuvs::neighbors::cagra::index; ``` -The build consist of two steps: build an intermediate knn-graph, and optimize it to create the final graph. The index_params struct controls the node degree of these graphs. The following distance metrics are supported: - L2 - InnerProduct (currently only supported with IVF-PQ as the build algorithm) - CosineExpanded (dataset norms are computed as float regardless of input data type) - L1 (currently only supported with NN-Descent and Iterative Search as the build algorithm) - BitwiseHamming (currently only supported with NN-Descent and Iterative Search as the build algorithm, and only for int8_t and uint8_t data types) Usage example: +The build consist of two steps: build an intermediate knn-graph, and optimize it to create the final graph. The index_params struct controls the node degree of these graphs. + +The following distance metrics are supported: + +- L2 +- InnerProduct (currently only supported with IVF-PQ as the build algorithm) +- CosineExpanded (dataset norms are computed as float regardless of input data type) +- L1 (currently only supported with NN-Descent and Iterative Search as the build algorithm) +- BitwiseHamming (currently only supported with NN-Descent and Iterative Search as the build algorithm, and only for int8_t and uint8_t data types) + +Usage example: **Parameters** @@ -872,7 +968,9 @@ new_dataset_buffer_view = std::optional> new_graph_buffer_view = std::nullopt); ``` -Usage example: part. The data will be copied from the current index in this function. The num rows must be the sum of the original and additional datasets, cols must be the dimension of the dataset, and the stride must be the same as the original index dataset. This view will be stored in the output index. It is the caller's responsibility to ensure that dataset stays alive as long as the index. This option is useful when users want to manage the memory space for the dataset themselves. The data will be copied from the current index in this function. The num rows must be the sum of the original and additional datasets and cols must be the graph degree. This view will be stored in the output index. It is the caller's responsibility to ensure that dataset stays alive as long as the index. This option is useful when users want to manage the memory space for the graph themselves. +Usage example: + +part. The data will be copied from the current index in this function. The num rows must be the sum of the original and additional datasets, cols must be the dimension of the dataset, and the stride must be the same as the original index dataset. This view will be stored in the output index. It is the caller's responsibility to ensure that dataset stays alive as long as the index. This option is useful when users want to manage the memory space for the dataset themselves. The data will be copied from the current index in this function. The num rows must be the sum of the original and additional datasets and cols must be the graph degree. This view will be stored in the output index. It is the caller's responsibility to ensure that dataset stays alive as long as the index. This option is useful when users want to manage the memory space for the graph themselves. **Parameters** @@ -906,7 +1004,9 @@ new_dataset_buffer_view = std::optional> new_graph_buffer_view = std::nullopt); ``` -Usage example: part. The data will be copied from the current index in this function. The num rows must be the sum of the original and additional datasets, cols must be the dimension of the dataset, and the stride must be the same as the original index dataset. This view will be stored in the output index. It is the caller's responsibility to ensure that dataset stays alive as long as the index. This option is useful when users want to manage the memory space for the dataset themselves. The data will be copied from the current index in this function. The num rows must be the sum of the original and additional datasets and cols must be the graph degree. This view will be stored in the output index. It is the caller's responsibility to ensure that dataset stays alive as long as the index. This option is useful when users want to manage the memory space for the graph themselves. +Usage example: + +part. The data will be copied from the current index in this function. The num rows must be the sum of the original and additional datasets, cols must be the dimension of the dataset, and the stride must be the same as the original index dataset. This view will be stored in the output index. It is the caller's responsibility to ensure that dataset stays alive as long as the index. This option is useful when users want to manage the memory space for the dataset themselves. The data will be copied from the current index in this function. The num rows must be the sum of the original and additional datasets and cols must be the graph degree. This view will be stored in the output index. It is the caller's responsibility to ensure that dataset stays alive as long as the index. This option is useful when users want to manage the memory space for the graph themselves. **Parameters** @@ -940,7 +1040,9 @@ new_dataset_buffer_view = std::optional> new_graph_buffer_view = std::nullopt); ``` -Usage example: part. The data will be copied from the current index in this function. The num rows must be the sum of the original and additional datasets, cols must be the dimension of the dataset, and the stride must be the same as the original index dataset. This view will be stored in the output index. It is the caller's responsibility to ensure that dataset stays alive as long as the index. This option is useful when users want to manage the memory space for the dataset themselves. The data will be copied from the current index in this function. The num rows must be the sum of the original and additional datasets and cols must be the graph degree. This view will be stored in the output index. It is the caller's responsibility to ensure that dataset stays alive as long as the index. This option is useful when users want to manage the memory space for the graph themselves. +Usage example: + +part. The data will be copied from the current index in this function. The num rows must be the sum of the original and additional datasets, cols must be the dimension of the dataset, and the stride must be the same as the original index dataset. This view will be stored in the output index. It is the caller's responsibility to ensure that dataset stays alive as long as the index. This option is useful when users want to manage the memory space for the dataset themselves. The data will be copied from the current index in this function. The num rows must be the sum of the original and additional datasets and cols must be the graph degree. This view will be stored in the output index. It is the caller's responsibility to ensure that dataset stays alive as long as the index. This option is useful when users want to manage the memory space for the graph themselves. **Parameters** @@ -974,7 +1076,9 @@ new_dataset_buffer_view = std::optional> new_graph_buffer_view = std::nullopt); ``` -Usage example: part. The data will be copied from the current index in this function. The num rows must be the sum of the original and additional datasets, cols must be the dimension of the dataset, and the stride must be the same as the original index dataset. This view will be stored in the output index. It is the caller's responsibility to ensure that dataset stays alive as long as the index. This option is useful when users want to manage the memory space for the dataset themselves. The data will be copied from the current index in this function. The num rows must be the sum of the original and additional datasets and cols must be the graph degree. This view will be stored in the output index. It is the caller's responsibility to ensure that dataset stays alive as long as the index. This option is useful when users want to manage the memory space for the graph themselves. +Usage example: + +part. The data will be copied from the current index in this function. The num rows must be the sum of the original and additional datasets, cols must be the dimension of the dataset, and the stride must be the same as the original index dataset. This view will be stored in the output index. It is the caller's responsibility to ensure that dataset stays alive as long as the index. This option is useful when users want to manage the memory space for the dataset themselves. The data will be copied from the current index in this function. The num rows must be the sum of the original and additional datasets and cols must be the graph degree. This view will be stored in the output index. It is the caller's responsibility to ensure that dataset stays alive as long as the index. This option is useful when users want to manage the memory space for the graph themselves. **Parameters** @@ -1008,7 +1112,9 @@ new_dataset_buffer_view = std::optional> new_graph_buffer_view = std::nullopt); ``` -Usage example: part. The data will be copied from the current index in this function. The num rows must be the sum of the original and additional datasets, cols must be the dimension of the dataset, and the stride must be the same as the original index dataset. This view will be stored in the output index. It is the caller's responsibility to ensure that dataset stays alive as long as the index. This option is useful when users want to manage the memory space for the dataset themselves. The data will be copied from the current index in this function. The num rows must be the sum of the original and additional datasets and cols must be the graph degree. This view will be stored in the output index. It is the caller's responsibility to ensure that dataset stays alive as long as the index. This option is useful when users want to manage the memory space for the graph themselves. +Usage example: + +part. The data will be copied from the current index in this function. The num rows must be the sum of the original and additional datasets, cols must be the dimension of the dataset, and the stride must be the same as the original index dataset. This view will be stored in the output index. It is the caller's responsibility to ensure that dataset stays alive as long as the index. This option is useful when users want to manage the memory space for the dataset themselves. The data will be copied from the current index in this function. The num rows must be the sum of the original and additional datasets and cols must be the graph degree. This view will be stored in the output index. It is the caller's responsibility to ensure that dataset stays alive as long as the index. This option is useful when users want to manage the memory space for the graph themselves. **Parameters** @@ -1042,7 +1148,9 @@ new_dataset_buffer_view = std::optional> new_graph_buffer_view = std::nullopt); ``` -Usage example: part. The data will be copied from the current index in this function. The num rows must be the sum of the original and additional datasets, cols must be the dimension of the dataset, and the stride must be the same as the original index dataset. This view will be stored in the output index. It is the caller's responsibility to ensure that dataset stays alive as long as the index. This option is useful when users want to manage the memory space for the dataset themselves. The data will be copied from the current index in this function. The num rows must be the sum of the original and additional datasets and cols must be the graph degree. This view will be stored in the output index. It is the caller's responsibility to ensure that dataset stays alive as long as the index. This option is useful when users want to manage the memory space for the graph themselves. +Usage example: + +part. The data will be copied from the current index in this function. The num rows must be the sum of the original and additional datasets, cols must be the dimension of the dataset, and the stride must be the same as the original index dataset. This view will be stored in the output index. It is the caller's responsibility to ensure that dataset stays alive as long as the index. This option is useful when users want to manage the memory space for the dataset themselves. The data will be copied from the current index in this function. The num rows must be the sum of the original and additional datasets and cols must be the graph degree. This view will be stored in the output index. It is the caller's responsibility to ensure that dataset stays alive as long as the index. This option is useful when users want to manage the memory space for the graph themselves. **Parameters** @@ -1076,7 +1184,9 @@ new_dataset_buffer_view = std::optional> new_graph_buffer_view = std::nullopt); ``` -Usage example: part. The data will be copied from the current index in this function. The num rows must be the sum of the original and additional datasets, cols must be the dimension of the dataset, and the stride must be the same as the original index dataset. This view will be stored in the output index. It is the caller's responsibility to ensure that dataset stays alive as long as the index. This option is useful when users want to manage the memory space for the dataset themselves. The data will be copied from the current index in this function. The num rows must be the sum of the original and additional datasets and cols must be the graph degree. This view will be stored in the output index. It is the caller's responsibility to ensure that dataset stays alive as long as the index. This option is useful when users want to manage the memory space for the graph themselves. +Usage example: + +part. The data will be copied from the current index in this function. The num rows must be the sum of the original and additional datasets, cols must be the dimension of the dataset, and the stride must be the same as the original index dataset. This view will be stored in the output index. It is the caller's responsibility to ensure that dataset stays alive as long as the index. This option is useful when users want to manage the memory space for the dataset themselves. The data will be copied from the current index in this function. The num rows must be the sum of the original and additional datasets and cols must be the graph degree. This view will be stored in the output index. It is the caller's responsibility to ensure that dataset stays alive as long as the index. This option is useful when users want to manage the memory space for the graph themselves. **Parameters** @@ -1110,7 +1220,9 @@ new_dataset_buffer_view = std::optional> new_graph_buffer_view = std::nullopt); ``` -Usage example: part. The data will be copied from the current index in this function. The num rows must be the sum of the original and additional datasets, cols must be the dimension of the dataset, and the stride must be the same as the original index dataset. This view will be stored in the output index. It is the caller's responsibility to ensure that dataset stays alive as long as the index. This option is useful when users want to manage the memory space for the dataset themselves. The data will be copied from the current index in this function. The num rows must be the sum of the original and additional datasets and cols must be the graph degree. This view will be stored in the output index. It is the caller's responsibility to ensure that dataset stays alive as long as the index. This option is useful when users want to manage the memory space for the graph themselves. +Usage example: + +part. The data will be copied from the current index in this function. The num rows must be the sum of the original and additional datasets, cols must be the dimension of the dataset, and the stride must be the same as the original index dataset. This view will be stored in the output index. It is the caller's responsibility to ensure that dataset stays alive as long as the index. This option is useful when users want to manage the memory space for the dataset themselves. The data will be copied from the current index in this function. The num rows must be the sum of the original and additional datasets and cols must be the graph degree. This view will be stored in the output index. It is the caller's responsibility to ensure that dataset stays alive as long as the index. This option is useful when users want to manage the memory space for the graph themselves. **Parameters** @@ -1599,7 +1711,9 @@ std::optional> dat std::nullopt); ``` -NOTE: The saved index can only be read by the hnswlib wrapper in cuVS, as the serialization format is not compatible with the original hnswlib. Experimental, both the API and the serialization format are subject to change. +NOTE: The saved index can only be read by the hnswlib wrapper in cuVS, as the serialization format is not compatible with the original hnswlib. + +Experimental, both the API and the serialization format are subject to change. **Parameters** @@ -1629,7 +1743,9 @@ std::optional> dat std::nullopt); ``` -NOTE: The saved index can only be read by the hnswlib wrapper in cuVS, as the serialization format is not compatible with the original hnswlib. Experimental, both the API and the serialization format are subject to change. +NOTE: The saved index can only be read by the hnswlib wrapper in cuVS, as the serialization format is not compatible with the original hnswlib. + +Experimental, both the API and the serialization format are subject to change. **Parameters** @@ -1659,7 +1775,9 @@ std::optional> data std::nullopt); ``` -NOTE: The saved index can only be read by the hnswlib wrapper in cuVS, as the serialization format is not compatible with the original hnswlib. Experimental, both the API and the serialization format are subject to change. +NOTE: The saved index can only be read by the hnswlib wrapper in cuVS, as the serialization format is not compatible with the original hnswlib. + +Experimental, both the API and the serialization format are subject to change. **Parameters** @@ -1689,7 +1807,9 @@ std::optional> data std::nullopt); ``` -NOTE: The saved index can only be read by the hnswlib wrapper in cuVS, as the serialization format is not compatible with the original hnswlib. Experimental, both the API and the serialization format are subject to change. +NOTE: The saved index can only be read by the hnswlib wrapper in cuVS, as the serialization format is not compatible with the original hnswlib. + +Experimental, both the API and the serialization format are subject to change. **Parameters** @@ -1719,7 +1839,9 @@ std::optional> da std::nullopt); ``` -NOTE: The saved index can only be read by the hnswlib wrapper in cuVS, as the serialization format is not compatible with the original hnswlib. Experimental, both the API and the serialization format are subject to change. +NOTE: The saved index can only be read by the hnswlib wrapper in cuVS, as the serialization format is not compatible with the original hnswlib. + +Experimental, both the API and the serialization format are subject to change. **Parameters** @@ -1749,7 +1871,9 @@ std::optional> da std::nullopt); ``` -NOTE: The saved index can only be read by the hnswlib wrapper in cuVS, as the serialization format is not compatible with the original hnswlib. Experimental, both the API and the serialization format are subject to change. +NOTE: The saved index can only be read by the hnswlib wrapper in cuVS, as the serialization format is not compatible with the original hnswlib. + +Experimental, both the API and the serialization format are subject to change. **Parameters** @@ -1779,7 +1903,9 @@ std::optional> d std::nullopt); ``` -NOTE: The saved index can only be read by the hnswlib wrapper in cuVS, as the serialization format is not compatible with the original hnswlib. Experimental, both the API and the serialization format are subject to change. +NOTE: The saved index can only be read by the hnswlib wrapper in cuVS, as the serialization format is not compatible with the original hnswlib. + +Experimental, both the API and the serialization format are subject to change. **Parameters** @@ -1809,7 +1935,9 @@ std::optional> d std::nullopt); ``` -NOTE: The saved index can only be read by the hnswlib wrapper in cuVS, as the serialization format is not compatible with the original hnswlib. Experimental, both the API and the serialization format are subject to change. +NOTE: The saved index can only be read by the hnswlib wrapper in cuVS, as the serialization format is not compatible with the original hnswlib. + +Experimental, both the API and the serialization format are subject to change. **Parameters** diff --git a/fern/pages/cpp_api/cpp-api-neighbors-dynamic-batching.md b/fern/pages/cpp_api/cpp-api-neighbors-dynamic-batching.md index 903cde1ed9..bb90f75ceb 100644 --- a/fern/pages/cpp_api/cpp-api-neighbors-dynamic-batching.md +++ b/fern/pages/cpp_api/cpp-api-neighbors-dynamic-batching.md @@ -105,7 +105,11 @@ raft::device_matrix_view neighbors, raft::device_matrix_view distances); ``` -The search parameters of the upstream index and the optional filtering function are configured at the dynamic batching index construction time. Like with many other indexes, the dynamic batching search has the stream-ordered semantics: the host function may return the control before the results are ready. Synchronize with the main CUDA stream in the given resource object to wait for arrival of the search results. Dynamic batching search is thread-safe: call the search function with copies of the same index in multiple threads to increase the occupancy of the batches. +The search parameters of the upstream index and the optional filtering function are configured at the dynamic batching index construction time. + +Like with many other indexes, the dynamic batching search has the stream-ordered semantics: the host function may return the control before the results are ready. Synchronize with the main CUDA stream in the given resource object to wait for arrival of the search results. + +Dynamic batching search is thread-safe: call the search function with copies of the same index in multiple threads to increase the occupancy of the batches. **Parameters** diff --git a/fern/pages/cpp_api/cpp-api-neighbors-epsilon-neighborhood.md b/fern/pages/cpp_api/cpp-api-neighbors-epsilon-neighborhood.md index bc7c5b8327..605028622e 100644 --- a/fern/pages/cpp_api/cpp-api-neighbors-epsilon-neighborhood.md +++ b/fern/pages/cpp_api/cpp-api-neighbors-epsilon-neighborhood.md @@ -25,7 +25,9 @@ value_t eps, cuvs::distance::DistanceType metric = cuvs::distance::DistanceType::L2Unexpanded); ``` -The epsilon neighbors is represented by a dense boolean adjacency matrix of size m * n and an array of degrees for each vertex, which can be used as a compressed sparse row (CSR) indptr array. Currently, only L2Unexpanded (L2-squared) distance metric is supported. Other metrics will throw an exception. +The epsilon neighbors is represented by a dense boolean adjacency matrix of size m * n and an array of degrees for each vertex, which can be used as a compressed sparse row (CSR) indptr array. + +Currently, only L2Unexpanded (L2-squared) distance metric is supported. Other metrics will throw an exception. **Template Parameters** diff --git a/fern/pages/cpp_api/cpp-api-neighbors-hnsw.md b/fern/pages/cpp_api/cpp-api-neighbors-hnsw.md index 5d51207781..d705aa2a3a 100644 --- a/fern/pages/cpp_api/cpp-api-neighbors-hnsw.md +++ b/fern/pages/cpp_api/cpp-api-neighbors-hnsw.md @@ -41,7 +41,11 @@ int ef_construction, cuvs::distance::DistanceType metric = cuvs::distance::DistanceType::L2Expanded); ``` -* IMPORTANT NOTE * The reference HNSW index and the corresponding from-CAGRA generated HNSW index will NOT produce the same recalls and QPS for the same parameter `ef`. The graphs are different internally. For the same `ef`, the from-CAGRA index likely has a slightly higher recall and slightly lower QPS. However, the Recall-QPS curves should be similar (i.e. the points are just shifted along the curve). Usage example: +* IMPORTANT NOTE * + +The reference HNSW index and the corresponding from-CAGRA generated HNSW index will NOT produce the same recalls and QPS for the same parameter `ef`. The graphs are different internally. For the same `ef`, the from-CAGRA index likely has a slightly higher recall and slightly lower QPS. However, the Recall-QPS curves should be similar (i.e. the points are just shifted along the curve). + +Usage example: **Parameters** @@ -177,7 +181,13 @@ const index_params& params, raft::host_matrix_view dataset); ``` -The resulting graph is compatible for HNSW search, but is not an exact equivalent of the graph built by the HNSW. The HNSW index construction parameters `M` and `ef_construction` are the main parameters to control the graph degree and graph quality. We have additional options that can be used to fine tune graph building on the GPU (see `cuvs::neighbors::cagra::index_params`). In case the index does not fit the host or GPU memory, we would use disk as temporary storage. In such cases it is important to set `ace_params.build_dir` to a fast disk with sufficient storage size. NOTE: This function requires CUDA headers to be available at compile time. Usage example: +The resulting graph is compatible for HNSW search, but is not an exact equivalent of the graph built by the HNSW. + +The HNSW index construction parameters `M` and `ef_construction` are the main parameters to control the graph degree and graph quality. We have additional options that can be used to fine tune graph building on the GPU (see `cuvs::neighbors::cagra::index_params`). In case the index does not fit the host or GPU memory, we would use disk as temporary storage. In such cases it is important to set `ace_params.build_dir` to a fast disk with sufficient storage size. + +NOTE: This function requires CUDA headers to be available at compile time. + +Usage example: **Parameters** @@ -204,7 +214,13 @@ const index_params& params, raft::host_matrix_view dataset); ``` -The resulting graph is compatible for HNSW search, but is not an exact equivalent of the graph built by the HNSW. The HNSW index construction parameters `M` and `ef_construction` are the main parameters to control the graph degree and graph quality. We have additional options that can be used to fine tune graph building on the GPU (see `cuvs::neighbors::cagra::index_params`). In case the index does not fit the host or GPU memory, we would use disk as temporary storage. In such cases it is important to set `ace_params.build_dir` to a fast disk with sufficient storage size. NOTE: This function requires CUDA headers to be available at compile time. Usage example: +The resulting graph is compatible for HNSW search, but is not an exact equivalent of the graph built by the HNSW. + +The HNSW index construction parameters `M` and `ef_construction` are the main parameters to control the graph degree and graph quality. We have additional options that can be used to fine tune graph building on the GPU (see `cuvs::neighbors::cagra::index_params`). In case the index does not fit the host or GPU memory, we would use disk as temporary storage. In such cases it is important to set `ace_params.build_dir` to a fast disk with sufficient storage size. + +NOTE: This function requires CUDA headers to be available at compile time. + +Usage example: **Parameters** @@ -231,7 +247,13 @@ const index_params& params, raft::host_matrix_view dataset); ``` -The resulting graph is compatible for HNSW search, but is not an exact equivalent of the graph built by the HNSW. The HNSW index construction parameters `M` and `ef_construction` are the main parameters to control the graph degree and graph quality. We have additional options that can be used to fine tune graph building on the GPU (see `cuvs::neighbors::cagra::index_params`). In case the index does not fit the host or GPU memory, we would use disk as temporary storage. In such cases it is important to set `ace_params.build_dir` to a fast disk with sufficient storage size. NOTE: This function requires CUDA headers to be available at compile time. Usage example: +The resulting graph is compatible for HNSW search, but is not an exact equivalent of the graph built by the HNSW. + +The HNSW index construction parameters `M` and `ef_construction` are the main parameters to control the graph degree and graph quality. We have additional options that can be used to fine tune graph building on the GPU (see `cuvs::neighbors::cagra::index_params`). In case the index does not fit the host or GPU memory, we would use disk as temporary storage. In such cases it is important to set `ace_params.build_dir` to a fast disk with sufficient storage size. + +NOTE: This function requires CUDA headers to be available at compile time. + +Usage example: **Parameters** @@ -258,7 +280,13 @@ const index_params& params, raft::host_matrix_view dataset); ``` -The resulting graph is compatible for HNSW search, but is not an exact equivalent of the graph built by the HNSW. The HNSW index construction parameters `M` and `ef_construction` are the main parameters to control the graph degree and graph quality. We have additional options that can be used to fine tune graph building on the GPU (see `cuvs::neighbors::cagra::index_params`). In case the index does not fit the host or GPU memory, we would use disk as temporary storage. In such cases it is important to set `ace_params.build_dir` to a fast disk with sufficient storage size. NOTE: This function requires CUDA headers to be available at compile time. Usage example: +The resulting graph is compatible for HNSW search, but is not an exact equivalent of the graph built by the HNSW. + +The HNSW index construction parameters `M` and `ef_construction` are the main parameters to control the graph degree and graph quality. We have additional options that can be used to fine tune graph building on the GPU (see `cuvs::neighbors::cagra::index_params`). In case the index does not fit the host or GPU memory, we would use disk as temporary storage. In such cases it is important to set `ace_params.build_dir` to a fast disk with sufficient storage size. + +NOTE: This function requires CUDA headers to be available at compile time. + +Usage example: **Parameters** @@ -291,7 +319,12 @@ std::optional> dat std::nullopt); ``` -NOTE: When `hnsw::index_params.hierarchy` is: 1. `NONE`: This method uses the filesystem to write the CAGRA index in `/tmp/<random_number>.bin` before reading it as an hnswlib index, then deleting the temporary file. The returned index is immutable and can only be searched by the hnswlib wrapper in cuVS, as the format is not compatible with the original hnswlib. 2. `CPU`: The returned index is mutable and can be extended with additional vectors. The serialized index is also compatible with the original hnswlib library. Usage example: +NOTE: When `hnsw::index_params.hierarchy` is: + +1. `NONE`: This method uses the filesystem to write the CAGRA index in `/tmp/<random_number>.bin` before reading it as an hnswlib index, then deleting the temporary file. The returned index is immutable and can only be searched by the hnswlib wrapper in cuVS, as the format is not compatible with the original hnswlib. +2. `CPU`: The returned index is mutable and can be extended with additional vectors. The serialized index is also compatible with the original hnswlib library. + +Usage example: **Parameters** @@ -321,7 +354,12 @@ std::optional> data std::nullopt); ``` -NOTE: When `hnsw::index_params.hierarchy` is: 1. `NONE`: This method uses the filesystem to write the CAGRA index in `/tmp/<random_number>.bin` before reading it as an hnswlib index, then deleting the temporary file. The returned index is immutable and can only be searched by the hnswlib wrapper in cuVS, as the format is not compatible with the original hnswlib. 2. `CPU`: The returned index is mutable and can be extended with additional vectors. The serialized index is also compatible with the original hnswlib library. Usage example: +NOTE: When `hnsw::index_params.hierarchy` is: + +1. `NONE`: This method uses the filesystem to write the CAGRA index in `/tmp/<random_number>.bin` before reading it as an hnswlib index, then deleting the temporary file. The returned index is immutable and can only be searched by the hnswlib wrapper in cuVS, as the format is not compatible with the original hnswlib. +2. `CPU`: The returned index is mutable and can be extended with additional vectors. The serialized index is also compatible with the original hnswlib library. + +Usage example: **Parameters** @@ -351,7 +389,12 @@ std::optional> d std::nullopt); ``` -NOTE: When `hnsw::index_params.hierarchy` is: 1. `NONE`: This method uses the filesystem to write the CAGRA index in `/tmp/<random_number>.bin` before reading it as an hnswlib index, then deleting the temporary file. The returned index is immutable and can only be searched by the hnswlib wrapper in cuVS, as the format is not compatible with the original hnswlib. 2. `CPU`: The returned index is mutable and can be extended with additional vectors. The serialized index is also compatible with the original hnswlib library. Usage example: +NOTE: When `hnsw::index_params.hierarchy` is: + +1. `NONE`: This method uses the filesystem to write the CAGRA index in `/tmp/<random_number>.bin` before reading it as an hnswlib index, then deleting the temporary file. The returned index is immutable and can only be searched by the hnswlib wrapper in cuVS, as the format is not compatible with the original hnswlib. +2. `CPU`: The returned index is mutable and can be extended with additional vectors. The serialized index is also compatible with the original hnswlib library. + +Usage example: **Parameters** @@ -381,7 +424,12 @@ std::optional> da std::nullopt); ``` -NOTE: When `hnsw::index_params.hierarchy` is: 1. `NONE`: This method uses the filesystem to write the CAGRA index in `/tmp/<random_number>.bin` before reading it as an hnswlib index, then deleting the temporary file. The returned index is immutable and can only be searched by the hnswlib wrapper in cuVS, as the format is not compatible with the original hnswlib. 2. `CPU`: The returned index is mutable and can be extended with additional vectors. The serialized index is also compatible with the original hnswlib library. Usage example: +NOTE: When `hnsw::index_params.hierarchy` is: + +1. `NONE`: This method uses the filesystem to write the CAGRA index in `/tmp/<random_number>.bin` before reading it as an hnswlib index, then deleting the temporary file. The returned index is immutable and can only be searched by the hnswlib wrapper in cuVS, as the format is not compatible with the original hnswlib. +2. `CPU`: The returned index is mutable and can be extended with additional vectors. The serialized index is also compatible with the original hnswlib library. + +Usage example: **Parameters** @@ -413,7 +461,9 @@ raft::host_matrix_view additional_dataset index& idx); ``` -NOTE: The HNSW index can only be extended when the `hnsw::index_params.hierarchy` is `CPU` when converting from a CAGRA index. Usage example: +NOTE: The HNSW index can only be extended when the `hnsw::index_params.hierarchy` is `CPU` when converting from a CAGRA index. + +Usage example: **Parameters** @@ -441,7 +491,9 @@ raft::host_matrix_view additional_dataset, index& idx); ``` -NOTE: The HNSW index can only be extended when the `hnsw::index_params.hierarchy` is `CPU` when converting from a CAGRA index. Usage example: +NOTE: The HNSW index can only be extended when the `hnsw::index_params.hierarchy` is `CPU` when converting from a CAGRA index. + +Usage example: **Parameters** @@ -469,7 +521,9 @@ raft::host_matrix_view additional_datas index& idx); ``` -NOTE: The HNSW index can only be extended when the `hnsw::index_params.hierarchy` is `CPU` when converting from a CAGRA index. Usage example: +NOTE: The HNSW index can only be extended when the `hnsw::index_params.hierarchy` is `CPU` when converting from a CAGRA index. + +Usage example: **Parameters** @@ -497,7 +551,9 @@ raft::host_matrix_view additional_datase index& idx); ``` -NOTE: The HNSW index can only be extended when the `hnsw::index_params.hierarchy` is `CPU` when converting from a CAGRA index. Usage example: +NOTE: The HNSW index can only be extended when the `hnsw::index_params.hierarchy` is `CPU` when converting from a CAGRA index. + +Usage example: **Parameters** @@ -552,7 +608,11 @@ raft::host_matrix_view neighbors, raft::host_matrix_view distances); ``` -NOTE: The HNSW index can only be searched by the hnswlib wrapper in cuVS when the hierarchy is `NONE`, as the format is not compatible with the original hnswlib. [n_queries, k] k] Usage example: +NOTE: The HNSW index can only be searched by the hnswlib wrapper in cuVS when the hierarchy is `NONE`, as the format is not compatible with the original hnswlib. + +[n_queries, k] k] + +Usage example: **Parameters** @@ -584,7 +644,11 @@ raft::host_matrix_view neighbors, raft::host_matrix_view distances); ``` -NOTE: The HNSW index can only be searched by the hnswlib wrapper in cuVS when the hierarchy is `NONE`, as the format is not compatible with the original hnswlib. [n_queries, k] k] Usage example: +NOTE: The HNSW index can only be searched by the hnswlib wrapper in cuVS when the hierarchy is `NONE`, as the format is not compatible with the original hnswlib. + +[n_queries, k] k] + +Usage example: **Parameters** @@ -616,7 +680,11 @@ raft::host_matrix_view neighbors, raft::host_matrix_view distances); ``` -NOTE: The HNSW index can only be searched by the hnswlib wrapper in cuVS when the hierarchy is `NONE`, as the format is not compatible with the original hnswlib. [n_queries, k] k] Usage example: +NOTE: The HNSW index can only be searched by the hnswlib wrapper in cuVS when the hierarchy is `NONE`, as the format is not compatible with the original hnswlib. + +[n_queries, k] k] + +Usage example: **Parameters** @@ -648,7 +716,11 @@ raft::host_matrix_view neighbors, raft::host_matrix_view distances); ``` -NOTE: The HNSW index can only be searched by the hnswlib wrapper in cuVS when the hierarchy is `NONE`, as the format is not compatible with the original hnswlib. [n_queries, k] k] Usage example: +NOTE: The HNSW index can only be searched by the hnswlib wrapper in cuVS when the hierarchy is `NONE`, as the format is not compatible with the original hnswlib. + +[n_queries, k] k] + +Usage example: **Parameters** @@ -679,7 +751,9 @@ Serialize the HNSW index to file void serialize(raft::resources const& res, const std::string& filename, const index& idx); ``` -NOTE: When hierarchy is `NONE`, the saved hnswlib index is immutable and can only be read by the hnswlib wrapper in cuVS, as the serialization format is not compatible with the original hnswlib. However, when hierarchy is `CPU`, the saved hnswlib index is compatible with the original hnswlib library. Usage example: +NOTE: When hierarchy is `NONE`, the saved hnswlib index is immutable and can only be read by the hnswlib wrapper in cuVS, as the serialization format is not compatible with the original hnswlib. However, when hierarchy is `CPU`, the saved hnswlib index is compatible with the original hnswlib library. + +Usage example: **Parameters** @@ -703,7 +777,9 @@ Serialize the HNSW index to file void serialize(raft::resources const& res, const std::string& filename, const index& idx); ``` -NOTE: When hierarchy is `NONE`, the saved hnswlib index is immutable and can only be read by the hnswlib wrapper in cuVS, as the serialization format is not compatible with the original hnswlib. However, when hierarchy is `CPU`, the saved hnswlib index is compatible with the original hnswlib library. Usage example: +NOTE: When hierarchy is `NONE`, the saved hnswlib index is immutable and can only be read by the hnswlib wrapper in cuVS, as the serialization format is not compatible with the original hnswlib. However, when hierarchy is `CPU`, the saved hnswlib index is compatible with the original hnswlib library. + +Usage example: **Parameters** @@ -727,7 +803,9 @@ Serialize the HNSW index to file void serialize(raft::resources const& res, const std::string& filename, const index& idx); ``` -NOTE: When hierarchy is `NONE`, the saved hnswlib index is immutable and can only be read by the hnswlib wrapper in cuVS, as the serialization format is not compatible with the original hnswlib. However, when hierarchy is `CPU`, the saved hnswlib index is compatible with the original hnswlib library. Usage example: +NOTE: When hierarchy is `NONE`, the saved hnswlib index is immutable and can only be read by the hnswlib wrapper in cuVS, as the serialization format is not compatible with the original hnswlib. However, when hierarchy is `CPU`, the saved hnswlib index is compatible with the original hnswlib library. + +Usage example: **Parameters** @@ -751,7 +829,9 @@ Serialize the HNSW index to file void serialize(raft::resources const& res, const std::string& filename, const index& idx); ``` -NOTE: When hierarchy is `NONE`, the saved hnswlib index is immutable and can only be read by the hnswlib wrapper in cuVS, as the serialization format is not compatible with the original hnswlib. However, when hierarchy is `CPU`, the saved hnswlib index is compatible with the original hnswlib library. Usage example: +NOTE: When hierarchy is `NONE`, the saved hnswlib index is immutable and can only be read by the hnswlib wrapper in cuVS, as the serialization format is not compatible with the original hnswlib. However, when hierarchy is `CPU`, the saved hnswlib index is compatible with the original hnswlib library. + +Usage example: **Parameters** @@ -780,7 +860,9 @@ cuvs::distance::DistanceType metric, index** index); ``` -NOTE: When hierarchy is `NONE`, the saved hnswlib index is immutable and can only be read by the hnswlib wrapper in cuVS, as the serialization format is not compatible with the original hnswlib. However, when hierarchy is `CPU`, the saved hnswlib index is compatible with the original hnswlib library. Usage example: +NOTE: When hierarchy is `NONE`, the saved hnswlib index is immutable and can only be read by the hnswlib wrapper in cuVS, as the serialization format is not compatible with the original hnswlib. However, when hierarchy is `CPU`, the saved hnswlib index is compatible with the original hnswlib library. + +Usage example: **Parameters** @@ -812,7 +894,9 @@ cuvs::distance::DistanceType metric, index** index); ``` -NOTE: When hierarchy is `NONE`, the saved hnswlib index is immutable and can only be read by the hnswlib wrapper in cuVS, as the serialization format is not compatible with the original hnswlib. However, when hierarchy is `CPU`, the saved hnswlib index is compatible with the original hnswlib library. Usage example: +NOTE: When hierarchy is `NONE`, the saved hnswlib index is immutable and can only be read by the hnswlib wrapper in cuVS, as the serialization format is not compatible with the original hnswlib. However, when hierarchy is `CPU`, the saved hnswlib index is compatible with the original hnswlib library. + +Usage example: **Parameters** @@ -844,7 +928,9 @@ cuvs::distance::DistanceType metric, index** index); ``` -NOTE: When hierarchy is `NONE`, the saved hnswlib index is immutable and can only be read by the hnswlib wrapper in cuVS, as the serialization format is not compatible with the original hnswlib. However, when hierarchy is `CPU`, the saved hnswlib index is compatible with the original hnswlib library. Usage example: +NOTE: When hierarchy is `NONE`, the saved hnswlib index is immutable and can only be read by the hnswlib wrapper in cuVS, as the serialization format is not compatible with the original hnswlib. However, when hierarchy is `CPU`, the saved hnswlib index is compatible with the original hnswlib library. + +Usage example: **Parameters** @@ -876,7 +962,9 @@ cuvs::distance::DistanceType metric, index** index); ``` -NOTE: When hierarchy is `NONE`, the saved hnswlib index is immutable and can only be read by the hnswlib wrapper in cuVS, as the serialization format is not compatible with the original hnswlib. However, when hierarchy is `CPU`, the saved hnswlib index is compatible with the original hnswlib library. Usage example: +NOTE: When hierarchy is `NONE`, the saved hnswlib index is immutable and can only be read by the hnswlib wrapper in cuVS, as the serialization format is not compatible with the original hnswlib. However, when hierarchy is `CPU`, the saved hnswlib index is compatible with the original hnswlib library. + +Usage example: **Parameters** diff --git a/fern/pages/cpp_api/cpp-api-neighbors-ivf-flat.md b/fern/pages/cpp_api/cpp-api-neighbors-ivf-flat.md index 1c785daddf..8b2896d7d4 100644 --- a/fern/pages/cpp_api/cpp-api-neighbors-ivf-flat.md +++ b/fern/pages/cpp_api/cpp-api-neighbors-ivf-flat.md @@ -221,7 +221,11 @@ Accumulated list sizes, sorted in descending order [n_lists + 1]. auto accum_sorted_sizes() noexcept -> raft::host_vector_view; ``` -The last value contains the total length of the index. The value at index zero is always zero. That is, the content of this span is as if the `list_sizes` was sorted and then accumulated. This span is used during search to estimate the maximum size of the workspace. +The last value contains the total length of the index. The value at index zero is always zero. + +That is, the content of this span is as if the `list_sizes` was sorted and then accumulated. + +This span is used during search to estimate the maximum size of the workspace. **Returns** @@ -330,7 +334,14 @@ raft::device_matrix_view dataset) -> cuvs::neighbors::ivf_flat::index; ``` -NB: Currently, the following distance metrics are supported: - L2Expanded - L2Unexpanded - InnerProduct - CosineExpanded Usage example: +NB: Currently, the following distance metrics are supported: + +- L2Expanded +- L2Unexpanded +- InnerProduct +- CosineExpanded + +Usage example: **Parameters** @@ -359,7 +370,14 @@ raft::device_matrix_view dataset, cuvs::neighbors::ivf_flat::index& idx); ``` -NB: Currently, the following distance metrics are supported: - L2Expanded - L2Unexpanded - InnerProduct - CosineExpanded Usage example: +NB: Currently, the following distance metrics are supported: + +- L2Expanded +- L2Unexpanded +- InnerProduct +- CosineExpanded + +Usage example: **Parameters** @@ -387,7 +405,14 @@ raft::device_matrix_view dataset) -> cuvs::neighbors::ivf_flat::index; ``` -NB: Currently, the following distance metrics are supported: - L2Expanded - L2Unexpanded - InnerProduct - CosineExpanded Usage example: +NB: Currently, the following distance metrics are supported: + +- L2Expanded +- L2Unexpanded +- InnerProduct +- CosineExpanded + +Usage example: **Parameters** @@ -416,7 +441,14 @@ raft::device_matrix_view dataset, cuvs::neighbors::ivf_flat::index& idx); ``` -NB: Currently, the following distance metrics are supported: - L2Expanded - L2Unexpanded - InnerProduct - CosineExpanded Usage example: +NB: Currently, the following distance metrics are supported: + +- L2Expanded +- L2Unexpanded +- InnerProduct +- CosineExpanded + +Usage example: **Parameters** @@ -444,7 +476,14 @@ raft::device_matrix_view dataset) -> cuvs::neighbors::ivf_flat::index; ``` -NB: Currently, the following distance metrics are supported: - L2Expanded - L2Unexpanded - InnerProduct - CosineExpanded Usage example: +NB: Currently, the following distance metrics are supported: + +- L2Expanded +- L2Unexpanded +- InnerProduct +- CosineExpanded + +Usage example: **Parameters** @@ -473,7 +512,14 @@ raft::device_matrix_view dataset, cuvs::neighbors::ivf_flat::index& idx); ``` -NB: Currently, the following distance metrics are supported: - L2Expanded - L2Unexpanded - InnerProduct - CosineExpanded Usage example: +NB: Currently, the following distance metrics are supported: + +- L2Expanded +- L2Unexpanded +- InnerProduct +- CosineExpanded + +Usage example: **Parameters** @@ -501,7 +547,14 @@ raft::device_matrix_view dataset) -> cuvs::neighbors::ivf_flat::index; ``` -NB: Currently, the following distance metrics are supported: - L2Expanded - L2Unexpanded - InnerProduct - CosineExpanded Usage example: +NB: Currently, the following distance metrics are supported: + +- L2Expanded +- L2Unexpanded +- InnerProduct +- CosineExpanded + +Usage example: **Parameters** @@ -530,7 +583,14 @@ raft::device_matrix_view dataset, cuvs::neighbors::ivf_flat::index& idx); ``` -NB: Currently, the following distance metrics are supported: - L2Expanded - L2Unexpanded - InnerProduct - CosineExpanded Usage example: +NB: Currently, the following distance metrics are supported: + +- L2Expanded +- L2Unexpanded +- InnerProduct +- CosineExpanded + +Usage example: **Parameters** @@ -558,7 +618,16 @@ raft::host_matrix_view dataset) -> cuvs::neighbors::ivf_flat::index; ``` -NB: Currently, the following distance metrics are supported: - L2Expanded - L2Unexpanded - InnerProduct - CosineExpanded Note, if index_params.add_data_on_build is set to true, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. Usage example: +NB: Currently, the following distance metrics are supported: + +- L2Expanded +- L2Unexpanded +- InnerProduct +- CosineExpanded + +Note, if index_params.add_data_on_build is set to true, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. + +Usage example: **Parameters** @@ -587,7 +656,16 @@ raft::host_matrix_view dataset, cuvs::neighbors::ivf_flat::index& idx); ``` -NB: Currently, the following distance metrics are supported: - L2Expanded - L2Unexpanded - InnerProduct - CosineExpanded Note, if index_params.add_data_on_build is set to true, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. Usage example: +NB: Currently, the following distance metrics are supported: + +- L2Expanded +- L2Unexpanded +- InnerProduct +- CosineExpanded + +Note, if index_params.add_data_on_build is set to true, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. + +Usage example: **Parameters** @@ -615,7 +693,16 @@ raft::host_matrix_view dataset) -> cuvs::neighbors::ivf_flat::index; ``` -NB: Currently, the following distance metrics are supported: - L2Expanded - L2Unexpanded - InnerProduct - CosineExpanded Note, if index_params.add_data_on_build is set to true, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. Usage example: +NB: Currently, the following distance metrics are supported: + +- L2Expanded +- L2Unexpanded +- InnerProduct +- CosineExpanded + +Note, if index_params.add_data_on_build is set to true, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. + +Usage example: **Parameters** @@ -644,7 +731,16 @@ raft::host_matrix_view dataset, cuvs::neighbors::ivf_flat::index& idx); ``` -NB: Currently, the following distance metrics are supported: - L2Expanded - L2Unexpanded - InnerProduct - CosineExpanded Note, if index_params.add_data_on_build is set to true, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. Usage example: +NB: Currently, the following distance metrics are supported: + +- L2Expanded +- L2Unexpanded +- InnerProduct +- CosineExpanded + +Note, if index_params.add_data_on_build is set to true, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. + +Usage example: **Parameters** @@ -672,7 +768,16 @@ raft::host_matrix_view dataset) -> cuvs::neighbors::ivf_flat::index; ``` -NB: Currently, the following distance metrics are supported: - L2Expanded - L2Unexpanded - InnerProduct - CosineExpanded Note, if index_params.add_data_on_build is set to true, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. Usage example: +NB: Currently, the following distance metrics are supported: + +- L2Expanded +- L2Unexpanded +- InnerProduct +- CosineExpanded + +Note, if index_params.add_data_on_build is set to true, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. + +Usage example: **Parameters** @@ -701,7 +806,16 @@ raft::host_matrix_view dataset, cuvs::neighbors::ivf_flat::index& idx); ``` -NB: Currently, the following distance metrics are supported: - L2Expanded - L2Unexpanded - InnerProduct - CosineExpanded Note, if index_params.add_data_on_build is set to true, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. Usage example: +NB: Currently, the following distance metrics are supported: + +- L2Expanded +- L2Unexpanded +- InnerProduct +- CosineExpanded + +Note, if index_params.add_data_on_build is set to true, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. + +Usage example: **Parameters** @@ -729,7 +843,16 @@ raft::host_matrix_view dataset) -> cuvs::neighbors::ivf_flat::index; ``` -NB: Currently, the following distance metrics are supported: - L2Expanded - L2Unexpanded - InnerProduct - CosineExpanded Note, if index_params.add_data_on_build is set to true, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. Usage example: +NB: Currently, the following distance metrics are supported: + +- L2Expanded +- L2Unexpanded +- InnerProduct +- CosineExpanded + +Note, if index_params.add_data_on_build is set to true, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. + +Usage example: **Parameters** @@ -758,7 +881,16 @@ raft::host_matrix_view dataset, cuvs::neighbors::ivf_flat::index& idx); ``` -NB: Currently, the following distance metrics are supported: - L2Expanded - L2Unexpanded - InnerProduct - CosineExpanded Note, if index_params.add_data_on_build is set to true, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. Usage example: +NB: Currently, the following distance metrics are supported: + +- L2Expanded +- L2Unexpanded +- InnerProduct +- CosineExpanded + +Note, if index_params.add_data_on_build is set to true, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. + +Usage example: **Parameters** @@ -791,7 +923,9 @@ const cuvs::neighbors::ivf_flat::index& idx) -> cuvs::neighbors::ivf_flat::index; ``` -Implementation note: The new data is clustered according to existing kmeans clusters, then the cluster centers are adjusted to match the newly labeled data. Usage example: +Implementation note: The new data is clustered according to existing kmeans clusters, then the cluster centers are adjusted to match the newly labeled data. + +Usage example: **Parameters** @@ -850,7 +984,9 @@ const cuvs::neighbors::ivf_flat::index& idx) -> cuvs::neighbors::ivf_flat::index; ``` -Implementation note: The new data is clustered according to existing kmeans clusters, then the cluster centers are adjusted to match the newly labeled data. Usage example: +Implementation note: The new data is clustered according to existing kmeans clusters, then the cluster centers are adjusted to match the newly labeled data. + +Usage example: **Parameters** @@ -909,7 +1045,9 @@ const cuvs::neighbors::ivf_flat::index& idx) -> cuvs::neighbors::ivf_flat::index; ``` -Implementation note: The new data is clustered according to existing kmeans clusters, then the cluster centers are adjusted to match the newly labeled data. Usage example: +Implementation note: The new data is clustered according to existing kmeans clusters, then the cluster centers are adjusted to match the newly labeled data. + +Usage example: **Parameters** @@ -968,7 +1106,9 @@ const cuvs::neighbors::ivf_flat::index& idx) -> cuvs::neighbors::ivf_flat::index; ``` -Implementation note: The new data is clustered according to existing kmeans clusters, then the cluster centers are adjusted to match the newly labeled data. Usage example: +Implementation note: The new data is clustered according to existing kmeans clusters, then the cluster centers are adjusted to match the newly labeled data. + +Usage example: **Parameters** @@ -1027,7 +1167,11 @@ const cuvs::neighbors::ivf_flat::index& idx) -> cuvs::neighbors::ivf_flat::index; ``` -Note, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. Implementation note: The new data is clustered according to existing kmeans clusters, then the cluster centers are adjusted to match the newly labeled data. Usage example: +Note, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. + +Implementation note: The new data is clustered according to existing kmeans clusters, then the cluster centers are adjusted to match the newly labeled data. + +Usage example: **Parameters** @@ -1057,7 +1201,9 @@ std::optional> new_indices, cuvs::neighbors::ivf_flat::index* idx); ``` -Note, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. Usage example: +Note, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. + +Usage example: **Parameters** @@ -1086,7 +1232,11 @@ const cuvs::neighbors::ivf_flat::index& idx) -> cuvs::neighbors::ivf_flat::index; ``` -Note, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. Implementation note: The new data is clustered according to existing kmeans clusters, then the cluster centers are adjusted to match the newly labeled data. Usage example: +Note, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. + +Implementation note: The new data is clustered according to existing kmeans clusters, then the cluster centers are adjusted to match the newly labeled data. + +Usage example: **Parameters** @@ -1116,7 +1266,9 @@ std::optional> new_indices, cuvs::neighbors::ivf_flat::index* idx); ``` -Note, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. Usage example: +Note, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. + +Usage example: **Parameters** @@ -1145,7 +1297,11 @@ const cuvs::neighbors::ivf_flat::index& idx) -> cuvs::neighbors::ivf_flat::index; ``` -Note, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. Implementation note: The new data is clustered according to existing kmeans clusters, then the cluster centers are adjusted to match the newly labeled data. Usage example: +Note, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. + +Implementation note: The new data is clustered according to existing kmeans clusters, then the cluster centers are adjusted to match the newly labeled data. + +Usage example: **Parameters** @@ -1175,7 +1331,9 @@ std::optional> new_indices, cuvs::neighbors::ivf_flat::index* idx); ``` -Note, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. Usage example: +Note, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. + +Usage example: **Parameters** @@ -1204,7 +1362,11 @@ const cuvs::neighbors::ivf_flat::index& idx) -> cuvs::neighbors::ivf_flat::index; ``` -Note, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. Implementation note: The new data is clustered according to existing kmeans clusters, then the cluster centers are adjusted to match the newly labeled data. Usage example: +Note, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. + +Implementation note: The new data is clustered according to existing kmeans clusters, then the cluster centers are adjusted to match the newly labeled data. + +Usage example: **Parameters** @@ -1234,7 +1396,9 @@ std::optional> new_indices, cuvs::neighbors::ivf_flat::index* idx); ``` -Note, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. Usage example: +Note, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. + +Usage example: **Parameters** @@ -1699,7 +1863,9 @@ typename list_spec::list_extents, raft::row_major> list_data); ``` -NB: no memory allocation happens here; the list must fit the data (offset + n_vec). Usage example: +NB: no memory allocation happens here; the list must fit the data (offset + n_vec). + +Usage example: **Parameters** @@ -1731,7 +1897,9 @@ typename list_spec::list_extents, raft::row_major> list_data); ``` -NB: no memory allocation happens here; the list must fit the data (offset + n_vec). Usage example: +NB: no memory allocation happens here; the list must fit the data (offset + n_vec). + +Usage example: **Parameters** @@ -1763,7 +1931,9 @@ typename list_spec::list_extents, raft::row_major> list_data); ``` -NB: no memory allocation happens here; the list must fit the data (offset + n_vec). Usage example: +NB: no memory allocation happens here; the list must fit the data (offset + n_vec). + +Usage example: **Parameters** @@ -1795,7 +1965,9 @@ typename list_spec::list_extents, raft::row_major> list_data); ``` -NB: no memory allocation happens here; the list must fit the data (offset + n_vec). Usage example: +NB: no memory allocation happens here; the list must fit the data (offset + n_vec). + +Usage example: **Parameters** @@ -1827,7 +1999,9 @@ uint32_t offset, raft::device_matrix_view codes); ``` -starting at given `offset`. Usage example: +starting at given `offset`. + +Usage example: **Parameters** @@ -1859,7 +2033,9 @@ uint32_t offset, raft::device_matrix_view codes); ``` -starting at given `offset`. Usage example: +starting at given `offset`. + +Usage example: **Parameters** @@ -1891,7 +2067,9 @@ uint32_t offset, raft::device_matrix_view codes); ``` -starting at given `offset`. Usage example: +starting at given `offset`. + +Usage example: **Parameters** @@ -1923,7 +2101,9 @@ uint32_t offset, raft::device_matrix_view codes); ``` -starting at given `offset`. Usage example: +starting at given `offset`. + +Usage example: **Parameters** @@ -2054,7 +2234,9 @@ Unpack 1 record of a single list (cluster) in the index to fetch the flat code. void unpack_1(const float* block, float* flat_code, uint32_t dim, uint32_t veclen, uint32_t offset); ``` -indicates the id of the record. This function fetches one flat code from an interleaved code. interleaved format. +indicates the id of the record. This function fetches one flat code from an interleaved code. + +interleaved format. **Parameters** @@ -2080,7 +2262,9 @@ Unpack 1 record of a single list (cluster) in the index to fetch the flat code. void unpack_1(const half* block, half* flat_code, uint32_t dim, uint32_t veclen, uint32_t offset); ``` -indicates the id of the record. This function fetches one flat code from an interleaved code. interleaved format. +indicates the id of the record. This function fetches one flat code from an interleaved code. + +interleaved format. **Parameters** @@ -2107,7 +2291,9 @@ void unpack_1( const int8_t* block, int8_t* flat_code, uint32_t dim, uint32_t veclen, uint32_t offset); ``` -indicates the id of the record. This function fetches one flat code from an interleaved code. interleaved format. +indicates the id of the record. This function fetches one flat code from an interleaved code. + +interleaved format. **Parameters** @@ -2134,7 +2320,9 @@ void unpack_1( const uint8_t* block, uint8_t* flat_code, uint32_t dim, uint32_t veclen, uint32_t offset); ``` -indicates the id of the record. This function fetches one flat code from an interleaved code. interleaved format. +indicates the id of the record. This function fetches one flat code from an interleaved code. + +interleaved format. **Parameters** @@ -2160,7 +2348,9 @@ Public helper API to reset the data and indices ptrs, and the list sizes. Useful void reset_index(const raft::resources& res, index* index); ``` -externally modifying the index without going through the build stage. The data and indices of the IVF lists will be lost. Usage example: +externally modifying the index without going through the build stage. The data and indices of the IVF lists will be lost. + +Usage example: **Parameters** @@ -2183,7 +2373,9 @@ Public helper API to reset the data and indices ptrs, and the list sizes. Useful void reset_index(const raft::resources& res, index* index); ``` -externally modifying the index without going through the build stage. The data and indices of the IVF lists will be lost. Usage example: +externally modifying the index without going through the build stage. The data and indices of the IVF lists will be lost. + +Usage example: **Parameters** @@ -2206,7 +2398,9 @@ Public helper API to reset the data and indices ptrs, and the list sizes. Useful void reset_index(const raft::resources& res, index* index); ``` -externally modifying the index without going through the build stage. The data and indices of the IVF lists will be lost. Usage example: +externally modifying the index without going through the build stage. The data and indices of the IVF lists will be lost. + +Usage example: **Parameters** @@ -2229,7 +2423,9 @@ Public helper API to reset the data and indices ptrs, and the list sizes. Useful void reset_index(const raft::resources& res, index* index); ``` -externally modifying the index without going through the build stage. The data and indices of the IVF lists will be lost. Usage example: +externally modifying the index without going through the build stage. The data and indices of the IVF lists will be lost. + +Usage example: **Parameters** @@ -2252,7 +2448,9 @@ Helper exposing the re-computation of list sizes and related arrays if IVF lists void recompute_internal_state(const raft::resources& res, index* index); ``` -modified externally. Usage example: +modified externally. + +Usage example: **Parameters** @@ -2275,7 +2473,9 @@ Helper exposing the re-computation of list sizes and related arrays if IVF lists void recompute_internal_state(const raft::resources& res, index* index); ``` -modified externally. Usage example: +modified externally. + +Usage example: **Parameters** @@ -2298,7 +2498,9 @@ Helper exposing the re-computation of list sizes and related arrays if IVF lists void recompute_internal_state(const raft::resources& res, index* index); ``` -modified externally. Usage example: +modified externally. + +Usage example: **Parameters** @@ -2321,7 +2523,9 @@ Helper exposing the re-computation of list sizes and related arrays if IVF lists void recompute_internal_state(const raft::resources& res, index* index); ``` -modified externally. Usage example: +modified externally. + +Usage example: **Parameters** diff --git a/fern/pages/cpp_api/cpp-api-neighbors-ivf-pq.md b/fern/pages/cpp_api/cpp-api-neighbors-ivf-pq.md index 6ca9e4be8c..7f48e247f6 100644 --- a/fern/pages/cpp_api/cpp-api-neighbors-ivf-pq.md +++ b/fern/pages/cpp_api/cpp-api-neighbors-ivf-pq.md @@ -361,7 +361,8 @@ raft::device_mdspan pq_centers const noexcept override; ``` -- codebook_gen::PER_SUBSPACE: [pq_dim , pq_len, pq_book_size] - codebook_gen::PER_CLUSTER: [n_lists, pq_len, pq_book_size] +- codebook_gen::PER_SUBSPACE: [pq_dim , pq_len, pq_book_size] +- codebook_gen::PER_CLUSTER: [n_lists, pq_len, pq_book_size] **Returns** @@ -434,7 +435,11 @@ Accumulated list sizes, sorted in descending order [n_lists + 1]. raft::host_vector_view accum_sorted_sizes() noexcept override; ``` -The last value contains the total length of the index. The value at index zero is always zero. That is, the content of this span is as if the `list_sizes` was sorted and then accumulated. This span is used during search to estimate the maximum size of the workspace. +The last value contains the total length of the index. The value at index zero is always zero. + +That is, the content of this span is as if the `list_sizes` was sorted and then accumulated. + +This span is used during search to estimate the maximum size of the workspace. **Returns** @@ -574,7 +579,14 @@ raft::device_matrix_view dataset, cuvs::neighbors::ivf_pq::index* idx); ``` -NB: Currently, the following distance metrics are supported: - L2Expanded - L2Unexpanded - InnerProduct - CosineExpanded Usage example: +NB: Currently, the following distance metrics are supported: + +- L2Expanded +- L2Unexpanded +- InnerProduct +- CosineExpanded + +Usage example: **Parameters** @@ -631,7 +643,14 @@ raft::device_matrix_view dataset, cuvs::neighbors::ivf_pq::index* idx); ``` -NB: Currently, the following distance metrics are supported: - L2Expanded - L2Unexpanded - InnerProduct - CosineExpanded Usage example: +NB: Currently, the following distance metrics are supported: + +- L2Expanded +- L2Unexpanded +- InnerProduct +- CosineExpanded + +Usage example: **Parameters** @@ -688,7 +707,14 @@ raft::device_matrix_view dataset, cuvs::neighbors::ivf_pq::index* idx); ``` -NB: Currently, the following distance metrics are supported: - L2Expanded - L2Unexpanded - InnerProduct - CosineExpanded Usage example: +NB: Currently, the following distance metrics are supported: + +- L2Expanded +- L2Unexpanded +- InnerProduct +- CosineExpanded + +Usage example: **Parameters** @@ -745,7 +771,14 @@ raft::device_matrix_view dataset, cuvs::neighbors::ivf_pq::index* idx); ``` -NB: Currently, the following distance metrics are supported: - L2Expanded - L2Unexpanded - InnerProduct - CosineExpanded Usage example: +NB: Currently, the following distance metrics are supported: + +- L2Expanded +- L2Unexpanded +- InnerProduct +- CosineExpanded + +Usage example: **Parameters** @@ -773,7 +806,9 @@ raft::host_matrix_view dataset) -> cuvs::neighbors::ivf_pq::index; ``` -Note, if index_params.add_data_on_build is set to true, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. Usage example: +Note, if index_params.add_data_on_build is set to true, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. + +Usage example: **Parameters** @@ -802,7 +837,16 @@ raft::host_matrix_view dataset, cuvs::neighbors::ivf_pq::index* idx); ``` -NB: Currently, the following distance metrics are supported: - L2Expanded - L2Unexpanded - InnerProduct - CosineExpanded Note, if index_params.add_data_on_build is set to true, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. Usage example: +NB: Currently, the following distance metrics are supported: + +- L2Expanded +- L2Unexpanded +- InnerProduct +- CosineExpanded + +Note, if index_params.add_data_on_build is set to true, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. + +Usage example: **Parameters** @@ -830,7 +874,9 @@ raft::host_matrix_view dataset) -> cuvs::neighbors::ivf_pq::index; ``` -Note, if index_params.add_data_on_build is set to true, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. Usage example: +Note, if index_params.add_data_on_build is set to true, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. + +Usage example: **Parameters** @@ -859,7 +905,14 @@ raft::host_matrix_view dataset, cuvs::neighbors::ivf_pq::index* idx); ``` -NB: Currently, the following distance metrics are supported: - L2Expanded - L2Unexpanded - InnerProduct - CosineExpanded Usage example: +NB: Currently, the following distance metrics are supported: + +- L2Expanded +- L2Unexpanded +- InnerProduct +- CosineExpanded + +Usage example: **Parameters** @@ -916,7 +969,16 @@ raft::host_matrix_view dataset, cuvs::neighbors::ivf_pq::index* idx); ``` -NB: Currently, the following distance metrics are supported: - L2Expanded - L2Unexpanded - InnerProduct - CosineExpanded Note, if index_params.add_data_on_build is set to true, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. Usage example: +NB: Currently, the following distance metrics are supported: + +- L2Expanded +- L2Unexpanded +- InnerProduct +- CosineExpanded + +Note, if index_params.add_data_on_build is set to true, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. + +Usage example: **Parameters** @@ -944,7 +1006,9 @@ raft::host_matrix_view dataset) -> cuvs::neighbors::ivf_pq::index; ``` -Note, if index_params.add_data_on_build is set to true, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. Usage example: +Note, if index_params.add_data_on_build is set to true, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. + +Usage example: **Parameters** @@ -973,7 +1037,16 @@ raft::host_matrix_view dataset, cuvs::neighbors::ivf_pq::index* idx); ``` -NB: Currently, the following distance metrics are supported: - L2Expanded - L2Unexpanded - InnerProduct - CosineExpanded Note, if index_params.add_data_on_build is set to true, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. Usage example: +NB: Currently, the following distance metrics are supported: + +- L2Expanded +- L2Unexpanded +- InnerProduct +- CosineExpanded + +Note, if index_params.add_data_on_build is set to true, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. + +Usage example: **Parameters** @@ -1005,7 +1078,15 @@ raft::device_matrix_view rotation_matrix -> cuvs::neighbors::ivf_pq::index; ``` -This function creates a non-owning index that stores a reference to the provided device data. All parameters must be provided with correct extents. The caller is responsible for ensuring the lifetime of the input data exceeds the lifetime of the returned index. The index_params must be consistent with the provided matrices. Specifically: - index_params.codebook_kind determines the expected shape of pq_centers - index_params.metric will be stored in the index - index_params.conservative_memory_allocation will be stored in the index The function will verify consistency between index_params, dim, and the matrix extents. dim] +This function creates a non-owning index that stores a reference to the provided device data. All parameters must be provided with correct extents. The caller is responsible for ensuring the lifetime of the input data exceeds the lifetime of the returned index. + +The index_params must be consistent with the provided matrices. Specifically: + +- index_params.codebook_kind determines the expected shape of pq_centers +- index_params.metric will be stored in the index +- index_params.conservative_memory_allocation will be stored in the index The function will verify consistency between index_params, dim, and the matrix extents. + +dim] **Parameters** @@ -1014,7 +1095,7 @@ This function creates a non-owning index that stores a reference to the provided | `handle` | in | `raft::resources const&` | raft resources handle | | `index_params` | in | `const cuvs::neighbors::ivf_pq::index_params&` | configure the index (metric, codebook_kind, etc.). Must be consistent with the provided matrices. | | `dim` | in | `const uint32_t` | dimensionality of the input data | -| `pq_centers` | in | `raft::device_mdspan, raft::row_major>` | PQ codebook on device memory with required extents: - codebook_gen::PER_SUBSPACE: [pq_dim, pq_len, pq_book_size] - codebook_gen::PER_CLUSTER: [n_lists, pq_len, pq_book_size] | +| `pq_centers` | in | `raft::device_mdspan, raft::row_major>` | PQ codebook on device memory with required extents:
- codebook_gen::PER_SUBSPACE: [pq_dim, pq_len, pq_book_size]
- codebook_gen::PER_CLUSTER: [n_lists, pq_len, pq_book_size] | | `centers` | in | `raft::device_matrix_view` | Cluster centers in the original space [n_lists, dim_ext] where dim_ext = round_up(dim + 1, 8) | | `centers_rot` | in | `raft::device_matrix_view` | Rotated cluster centers [n_lists, rot_dim] where rot_dim = pq_len * pq_dim | | `rotation_matrix` | in | `raft::device_matrix_view` | Transform matrix (original space -> rotated padded space) [rot_dim, | @@ -1042,7 +1123,15 @@ raft::device_matrix_view rotation_matrix cuvs::neighbors::ivf_pq::index* idx); ``` -This function creates a non-owning index that references the provided device data directly. All parameters must be provided with correct extents. The caller is responsible for ensuring the lifetime of the input data exceeds the lifetime of the returned index. The index_params must be consistent with the provided matrices. Specifically: - index_params.codebook_kind determines the expected shape of pq_centers - index_params.metric will be stored in the index - index_params.conservative_memory_allocation will be stored in the index The function will verify consistency between index_params, dim, and the matrix extents. dim] +This function creates a non-owning index that references the provided device data directly. All parameters must be provided with correct extents. The caller is responsible for ensuring the lifetime of the input data exceeds the lifetime of the returned index. + +The index_params must be consistent with the provided matrices. Specifically: + +- index_params.codebook_kind determines the expected shape of pq_centers +- index_params.metric will be stored in the index +- index_params.conservative_memory_allocation will be stored in the index The function will verify consistency between index_params, dim, and the matrix extents. + +dim] **Parameters** @@ -1051,7 +1140,7 @@ This function creates a non-owning index that references the provided device dat | `handle` | in | `raft::resources const&` | raft resources handle | | `index_params` | in | `const cuvs::neighbors::ivf_pq::index_params&` | configure the index (metric, codebook_kind, etc.). Must be consistent with the provided matrices. | | `dim` | in | `const uint32_t` | dimensionality of the input data | -| `pq_centers` | in | `raft::device_mdspan, raft::row_major>` | PQ codebook on device memory with required extents: - codebook_gen::PER_SUBSPACE: [pq_dim, pq_len, pq_book_size] - codebook_gen::PER_CLUSTER: [n_lists, pq_len, pq_book_size] | +| `pq_centers` | in | `raft::device_mdspan, raft::row_major>` | PQ codebook on device memory with required extents:
- codebook_gen::PER_SUBSPACE: [pq_dim, pq_len, pq_book_size]
- codebook_gen::PER_CLUSTER: [n_lists, pq_len, pq_book_size] | | `centers` | in | `raft::device_matrix_view` | Cluster centers in the original space [n_lists, dim_ext] where dim_ext = round_up(dim + 1, 8) | | `centers_rot` | in | `raft::device_matrix_view` | Rotated cluster centers [n_lists, rot_dim] where rot_dim = pq_len * pq_dim | | `rotation_matrix` | in | `raft::device_matrix_view` | Transform matrix (original space -> rotated padded space) [rot_dim, | @@ -1376,7 +1465,9 @@ const cuvs::neighbors::ivf_pq::index& idx) -> cuvs::neighbors::ivf_pq::index; ``` -Note, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. Usage example: +Note, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. + +Usage example: **Parameters** @@ -1404,7 +1495,9 @@ std::optional> new_indices, cuvs::neighbors::ivf_pq::index* idx); ``` -Note, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. Usage example: +Note, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. + +Usage example: **Parameters** @@ -1433,7 +1526,9 @@ const cuvs::neighbors::ivf_pq::index& idx) -> cuvs::neighbors::ivf_pq::index; ``` -Note, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. Usage example: +Note, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. + +Usage example: **Parameters** @@ -1461,7 +1556,9 @@ std::optional> new_indices, cuvs::neighbors::ivf_pq::index* idx); ``` -Note, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. Usage example: +Note, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. + +Usage example: **Parameters** @@ -1490,7 +1587,9 @@ const cuvs::neighbors::ivf_pq::index& idx) -> cuvs::neighbors::ivf_pq::index; ``` -Note, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. Usage example: +Note, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. + +Usage example: **Parameters** @@ -1518,7 +1617,9 @@ std::optional> new_indices, cuvs::neighbors::ivf_pq::index* idx); ``` -Note, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. Usage example: +Note, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. + +Usage example: **Parameters** @@ -1547,7 +1648,9 @@ const cuvs::neighbors::ivf_pq::index& idx) -> cuvs::neighbors::ivf_pq::index; ``` -Note, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. Usage example: +Note, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. + +Usage example: **Parameters** @@ -1575,7 +1678,9 @@ std::optional> new_indices, cuvs::neighbors::ivf_pq::index* idx); ``` -Note, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. Usage example: +Note, the user can set a stream pool in the input raft::resource with at least one stream to enable kernel and copy overlapping. + +Usage example: **Parameters** @@ -1832,7 +1937,11 @@ uint32_t offset, raft::device_matrix_view codes); ``` -starting at given `offset`. Bit compression is removed, which means output will have pq_dim dimensional vectors (one code per byte, instead of ceildiv(pq_dim * pq_bits, 8) bytes of pq codes). Usage example: +starting at given `offset`. + +Bit compression is removed, which means output will have pq_dim dimensional vectors (one code per byte, instead of ceildiv(pq_dim * pq_bits, 8) bytes of pq codes). + +Usage example: **Parameters** @@ -1866,7 +1975,9 @@ uint32_t pq_dim, uint8_t* codes); ``` -starting at given `offset`. The output codes of a single vector are contiguous, not expanded to one code per byte, which means the output has ceildiv(pq_dim * pq_bits, 8) bytes per PQ encoded vector. Usage example: +starting at given `offset`. The output codes of a single vector are contiguous, not expanded to one code per byte, which means the output has ceildiv(pq_dim * pq_bits, 8) bytes per PQ encoded vector. + +Usage example: **Parameters** @@ -1900,7 +2011,9 @@ list_spec_interleaved::list_extents, raft::row_major> list_data); ``` -NB: no memory allocation happens here; the list must fit the data (offset + n_vec). Usage example: +NB: no memory allocation happens here; the list must fit the data (offset + n_vec). + +Usage example: **Parameters** @@ -1934,7 +2047,11 @@ list_spec_interleaved::list_extents, raft::row_major> list_data); ``` -are contiguous (not expanded to one code per byte). NB: no memory allocation happens here; the list must fit the data (offset + n_rows records). Usage example: +are contiguous (not expanded to one code per byte). + +NB: no memory allocation happens here; the list must fit the data (offset + n_rows records). + +Usage example: **Parameters** @@ -1966,7 +2083,11 @@ uint32_t label, uint32_t offset); ``` -The list is identified by its label. NB: no memory allocation happens here; the list must fit the data (offset + n_vec). Usage example: +The list is identified by its label. + +NB: no memory allocation happens here; the list must fit the data (offset + n_vec). + +Usage example: **Parameters** @@ -1997,7 +2118,13 @@ uint32_t label, uint32_t offset); ``` -vectors are PQ encoded and not expanded to one code per byte. The list is identified by its label. NB: no memory allocation happens here; the list into which the vectors are packed must fit offset + n_rows rows. Usage example: +vectors are PQ encoded and not expanded to one code per byte. + +The list is identified by its label. + +NB: no memory allocation happens here; the list into which the vectors are packed must fit offset + n_rows rows. + +Usage example: **Parameters** @@ -2028,7 +2155,9 @@ uint32_t label, uint32_t offset); ``` -starting at given `offset`, one code per byte (independently of pq_bits). Usage example: +starting at given `offset`, one code per byte (independently of pq_bits). + +Usage example: **Parameters** @@ -2058,7 +2187,9 @@ raft::device_matrix_view out_codes, uint32_t label); ``` -by their in-list offsets, one code per byte (independently of pq_bits). Usage example: +by their in-list offsets, one code per byte (independently of pq_bits). + +Usage example: **Parameters** @@ -2089,7 +2220,9 @@ uint32_t label, uint32_t offset); ``` -compressed index starting at given `offset`, not expanded to one code per byte. Each code in the output buffer occupies ceildiv(index.pq_dim() * index.pq_bits(), 8) bytes. Usage example: +compressed index starting at given `offset`, not expanded to one code per byte. Each code in the output buffer occupies ceildiv(index.pq_dim() * index.pq_bits(), 8) bytes. + +Usage example: **Parameters** @@ -2120,7 +2253,9 @@ uint32_t label, uint32_t offset); ``` -starting at given `offset`. Usage example: +starting at given `offset`. + +Usage example: **Parameters** @@ -2150,7 +2285,9 @@ raft::device_matrix_view out_vectors, uint32_t label); ``` -by their in-list offsets. Usage example: +by their in-list offsets. + +Usage example: **Parameters** @@ -2181,7 +2318,9 @@ raft::device_vector_view new_indices, uint32_t label); ``` -encoding steps. Usage example: +encoding steps. + +Usage example: **Parameters** @@ -2212,7 +2351,11 @@ raft::device_vector_view new_indices, uint32_t label); ``` -encoding steps. Uses contiguous/packed codes format. This is similar to extend_list_with_codes but takes codes in contiguous packed format [n_rows, ceildiv(pq_dim * pq_bits, 8)] instead of unpacked format [n_rows, pq_dim]. This works correctly with any pq_bits value. Usage example: +encoding steps. Uses contiguous/packed codes format. + +This is similar to extend_list_with_codes but takes codes in contiguous packed format [n_rows, ceildiv(pq_dim * pq_bits, 8)] instead of unpacked format [n_rows, pq_dim]. This works correctly with any pq_bits value. + +Usage example: **Parameters** @@ -2242,7 +2385,9 @@ raft::device_vector_view new_indices, uint32_t label); ``` -step. Usage example: +step. + +Usage example: **Parameters** @@ -2292,7 +2437,9 @@ Public helper API to reset the data and indices ptrs, and the list sizes. Useful void reset_index(const raft::resources& res, index* index); ``` -externally modifying the index without going through the build stage. The data and indices of the IVF lists will be lost. Usage example: +externally modifying the index without going through the build stage. The data and indices of the IVF lists will be lost. + +Usage example: **Parameters** @@ -2444,7 +2591,9 @@ Helper exposing the re-computation of list sizes and related arrays if IVF lists void recompute_internal_state(const raft::resources& res, index* index); ``` -modified externally. Usage example: +modified externally. + +Usage example: **Parameters** @@ -2470,7 +2619,9 @@ raft::device_matrix_view rotation_matrix, bool force_random_rotation); ``` -This standalone helper generates a rotation matrix without requiring an index object. Users can call this to prepare a rotation matrix before building from precomputed data. Usage example: +This standalone helper generates a rotation matrix without requiring an index object. Users can call this to prepare a rotation matrix before building from precomputed data. + +Usage example: **Parameters** @@ -2498,7 +2649,9 @@ uint32_t new_used_size, uint32_t old_used_size); ``` -This helper resizes an IVF list that uses the flat (non-interleaved) PQ code layout. If the new size exceeds the current capacity, a new list is allocated and existing data is copied. The function handles the type casting internally. Usage example: +This helper resizes an IVF list that uses the flat (non-interleaved) PQ code layout. If the new size exceeds the current capacity, a new list is allocated and existing data is copied. The function handles the type casting internally. + +Usage example: **Parameters** @@ -2528,7 +2681,9 @@ uint32_t new_used_size, uint32_t old_used_size); ``` -This helper resizes an IVF list that uses the interleaved PQ code layout (default). If the new size exceeds the current capacity, a new list is allocated and existing data is copied. The function handles the type casting internally. Usage example: +This helper resizes an IVF list that uses the interleaved PQ code layout (default). If the new size exceeds the current capacity, a new list is allocated and existing data is copied. The function handles the type casting internally. + +Usage example: **Parameters** diff --git a/fern/pages/cpp_api/cpp-api-neighbors-nn-descent.md b/fern/pages/cpp_api/cpp-api-neighbors-nn-descent.md index d442c26427..e018db8a44 100644 --- a/fern/pages/cpp_api/cpp-api-neighbors-nn-descent.md +++ b/fern/pages/cpp_api/cpp-api-neighbors-nn-descent.md @@ -14,7 +14,9 @@ _Doxygen group: `nn_descent_cpp_index_params`_ Dtype to use for distance computation -- `AUTO`: Automatically determine the best dtype for distance computation based on the dataset dimensions. - `FP32`: Use fp32 distance computation for better precision at the cost of performance and memory usage. - `FP16`: Use fp16 distance computation. +- `AUTO`: Automatically determine the best dtype for distance computation based on the dataset dimensions. +- `FP32`: Use fp32 distance computation for better precision at the cost of performance and memory usage. +- `FP16`: Use fp16 distance computation. ```cpp enum class DIST_COMP_DTYPE { ... } ; @@ -34,7 +36,12 @@ _Source: `cpp/include/cuvs/neighbors/nn_descent.hpp:35`_ Parameters used to build an nn-descent index -- `graph_degree`: For an input dataset of dimensions (N, D), determines the final dimensions of the all-neighbors knn graph which turns out to be of dimensions (N, graph_degree) - `intermediate_graph_degree`: Internally, nn-descent builds an all-neighbors knn graph of dimensions (N, intermediate_graph_degree) before selecting the final `graph_degree` neighbors. It's recommended that `intermediate_graph_degree` >= 1.5 * graph_degree - `max_iterations`: The number of iterations that nn-descent will refine the graph for. More iterations produce a better quality graph at cost of performance - `termination_threshold`: The delta at which nn-descent will terminate its iterations - `return_distances`: Boolean to decide whether to return distances array - `dist_comp_dtype`: dtype to use for distance computation. Defaults to `AUTO` which automatically determines the best dtype for distance computation based on the dataset dimensions. Use `FP32` for better precision at the cost of performance and memory usage. This option is only valid when data type is fp32. Use `FP16` for better performance and memory usage at the cost of precision. +- `graph_degree`: For an input dataset of dimensions (N, D), determines the final dimensions of the all-neighbors knn graph which turns out to be of dimensions (N, graph_degree) +- `intermediate_graph_degree`: Internally, nn-descent builds an all-neighbors knn graph of dimensions (N, intermediate_graph_degree) before selecting the final `graph_degree` neighbors. It's recommended that `intermediate_graph_degree` >= 1.5 * graph_degree +- `max_iterations`: The number of iterations that nn-descent will refine the graph for. More iterations produce a better quality graph at cost of performance +- `termination_threshold`: The delta at which nn-descent will terminate its iterations +- `return_distances`: Boolean to decide whether to return distances array +- `dist_comp_dtype`: dtype to use for distance computation. Defaults to `AUTO` which automatically determines the best dtype for distance computation based on the dataset dimensions. Use `FP32` for better precision at the cost of performance and memory usage. This option is only valid when data type is fp32. Use `FP16` for better performance and memory usage at the cost of precision. ```cpp struct index_params : cuvs::neighbors::index_params { ... } ; @@ -124,7 +131,9 @@ cuvs::distance::DistanceType metric = cuvs::distance::DistanceType::L2Expanded) : cuvs::neighbors::index(), ``` -This constructor creates an nn-descent index using a user allocated host memory knn-graph. The type of the knn-graph is a dense raft::host_matrix and dimensions are (n_rows, n_cols). distances +This constructor creates an nn-descent index using a user allocated host memory knn-graph. The type of the knn-graph is a dense raft::host_matrix and dimensions are (n_rows, n_cols). + +distances **Parameters** @@ -229,7 +238,17 @@ std::optional> graph std::nullopt) -> cuvs::neighbors::nn_descent::index; ``` -The following distance metrics are supported: - L2Expanded - L2SqrtExpanded - CosineExpanded - InnerProduct - L1 Usage example: the output graph +The following distance metrics are supported: + +- L2Expanded +- L2SqrtExpanded +- CosineExpanded +- InnerProduct +- L1 + +Usage example: + +the output graph **Parameters** @@ -260,7 +279,17 @@ std::optional> graph std::nullopt) -> cuvs::neighbors::nn_descent::index; ``` -The following distance metrics are supported: - L2Expanded - L2SqrtExpanded - CosineExpanded - InnerProduct - L1 Usage example: the output graph +The following distance metrics are supported: + +- L2Expanded +- L2SqrtExpanded +- CosineExpanded +- InnerProduct +- L1 + +Usage example: + +the output graph **Template Parameters** @@ -298,7 +327,17 @@ std::optional> graph std::nullopt) -> cuvs::neighbors::nn_descent::index; ``` -The following distance metrics are supported: - L2Expanded - L2SqrtExpanded - CosineExpanded - InnerProduct - L1 Usage example: the output graph +The following distance metrics are supported: + +- L2Expanded +- L2SqrtExpanded +- CosineExpanded +- InnerProduct +- L1 + +Usage example: + +the output graph **Parameters** @@ -329,7 +368,17 @@ std::optional> graph std::nullopt) -> cuvs::neighbors::nn_descent::index; ``` -The following distance metrics are supported: - L2Expanded - L2SqrtExpanded - CosineExpanded - InnerProduct - L1 Usage example: the output graph +The following distance metrics are supported: + +- L2Expanded +- L2SqrtExpanded +- CosineExpanded +- InnerProduct +- L1 + +Usage example: + +the output graph **Template Parameters** @@ -367,7 +416,18 @@ std::optional> graph std::nullopt) -> cuvs::neighbors::nn_descent::index; ``` -The following distance metrics are supported: - L2Expanded - L2SqrtExpanded - CosineExpanded - InnerProduct - L1 - BitwiseHamming Usage example: the output graph +The following distance metrics are supported: + +- L2Expanded +- L2SqrtExpanded +- CosineExpanded +- InnerProduct +- L1 +- BitwiseHamming + +Usage example: + +the output graph **Parameters** @@ -398,7 +458,18 @@ std::optional> graph std::nullopt) -> cuvs::neighbors::nn_descent::index; ``` -The following distance metrics are supported: - L2Expanded - L2SqrtExpanded - CosineExpanded - InnerProduct - L1 - BitwiseHamming Usage example: the output graph +The following distance metrics are supported: + +- L2Expanded +- L2SqrtExpanded +- CosineExpanded +- InnerProduct +- L1 +- BitwiseHamming + +Usage example: + +the output graph **Template Parameters** @@ -436,7 +507,18 @@ std::optional> graph std::nullopt) -> cuvs::neighbors::nn_descent::index; ``` -The following distance metrics are supported: - L2Expanded - L2SqrtExpanded - CosineExpanded - InnerProduct - L1 - BitwiseHamming Usage example: the output graph +The following distance metrics are supported: + +- L2Expanded +- L2SqrtExpanded +- CosineExpanded +- InnerProduct +- L1 +- BitwiseHamming + +Usage example: + +the output graph **Parameters** @@ -467,7 +549,18 @@ std::optional> graph std::nullopt) -> cuvs::neighbors::nn_descent::index; ``` -The following distance metrics are supported: - L2Expanded - L2SqrtExpanded - CosineExpanded - InnerProduct - L1 - BitwiseHamming Usage example: the output graph +The following distance metrics are supported: + +- L2Expanded +- L2SqrtExpanded +- CosineExpanded +- InnerProduct +- L1 +- BitwiseHamming + +Usage example: + +the output graph **Template Parameters** diff --git a/fern/pages/cpp_api/cpp-api-neighbors-refine.md b/fern/pages/cpp_api/cpp-api-neighbors-refine.md index aab22160b5..681b5b7d04 100644 --- a/fern/pages/cpp_api/cpp-api-neighbors-refine.md +++ b/fern/pages/cpp_api/cpp-api-neighbors-refine.md @@ -24,7 +24,11 @@ raft::device_matrix_view distances, cuvs::distance::DistanceType metric = cuvs::distance::DistanceType::L2Unexpanded); ``` -Refinement is an operation that follows an approximate NN search. The approximate search has already selected n_candidates neighbor candidates for each query. We narrow it down to k neighbors. For each query, we calculate the exact distance between the query and its n_candidates neighbor candidate, and select the k nearest ones. The k nearest neighbors and distances are returned. Example usage +Refinement is an operation that follows an approximate NN search. The approximate search has already selected n_candidates neighbor candidates for each query. We narrow it down to k neighbors. For each query, we calculate the exact distance between the query and its n_candidates neighbor candidate, and select the k nearest ones. + +The k nearest neighbors and distances are returned. + +Example usage **Parameters** @@ -58,7 +62,11 @@ raft::device_matrix_view distances, cuvs::distance::DistanceType metric = cuvs::distance::DistanceType::L2Unexpanded); ``` -Refinement is an operation that follows an approximate NN search. The approximate search has already selected n_candidates neighbor candidates for each query. We narrow it down to k neighbors. For each query, we calculate the exact distance between the query and its n_candidates neighbor candidate, and select the k nearest ones. The k nearest neighbors and distances are returned. Example usage +Refinement is an operation that follows an approximate NN search. The approximate search has already selected n_candidates neighbor candidates for each query. We narrow it down to k neighbors. For each query, we calculate the exact distance between the query and its n_candidates neighbor candidate, and select the k nearest ones. + +The k nearest neighbors and distances are returned. + +Example usage **Parameters** @@ -92,7 +100,11 @@ raft::device_matrix_view distances, cuvs::distance::DistanceType metric = cuvs::distance::DistanceType::L2Unexpanded); ``` -Refinement is an operation that follows an approximate NN search. The approximate search has already selected n_candidates neighbor candidates for each query. We narrow it down to k neighbors. For each query, we calculate the exact distance between the query and its n_candidates neighbor candidate, and select the k nearest ones. The k nearest neighbors and distances are returned. Example usage +Refinement is an operation that follows an approximate NN search. The approximate search has already selected n_candidates neighbor candidates for each query. We narrow it down to k neighbors. For each query, we calculate the exact distance between the query and its n_candidates neighbor candidate, and select the k nearest ones. + +The k nearest neighbors and distances are returned. + +Example usage **Parameters** @@ -126,7 +138,11 @@ raft::device_matrix_view distances, cuvs::distance::DistanceType metric = cuvs::distance::DistanceType::L2Unexpanded); ``` -Refinement is an operation that follows an approximate NN search. The approximate search has already selected n_candidates neighbor candidates for each query. We narrow it down to k neighbors. For each query, we calculate the exact distance between the query and its n_candidates neighbor candidate, and select the k nearest ones. The k nearest neighbors and distances are returned. Example usage +Refinement is an operation that follows an approximate NN search. The approximate search has already selected n_candidates neighbor candidates for each query. We narrow it down to k neighbors. For each query, we calculate the exact distance between the query and its n_candidates neighbor candidate, and select the k nearest ones. + +The k nearest neighbors and distances are returned. + +Example usage **Parameters** @@ -160,7 +176,11 @@ raft::device_matrix_view distances, cuvs::distance::DistanceType metric = cuvs::distance::DistanceType::L2Unexpanded); ``` -Refinement is an operation that follows an approximate NN search. The approximate search has already selected n_candidates neighbor candidates for each query. We narrow it down to k neighbors. For each query, we calculate the exact distance between the query and its n_candidates neighbor candidate, and select the k nearest ones. The k nearest neighbors and distances are returned. Example usage +Refinement is an operation that follows an approximate NN search. The approximate search has already selected n_candidates neighbor candidates for each query. We narrow it down to k neighbors. For each query, we calculate the exact distance between the query and its n_candidates neighbor candidate, and select the k nearest ones. + +The k nearest neighbors and distances are returned. + +Example usage **Parameters** @@ -194,7 +214,11 @@ raft::host_matrix_view distances, cuvs::distance::DistanceType metric = cuvs::distance::DistanceType::L2Unexpanded); ``` -Refinement is an operation that follows an approximate NN search. The approximate search has already selected n_candidates neighbor candidates for each query. We narrow it down to k neighbors. For each query, we calculate the exact distance between the query and its n_candidates neighbor candidate, and select the k nearest ones. The k nearest neighbors and distances are returned. Example usage +Refinement is an operation that follows an approximate NN search. The approximate search has already selected n_candidates neighbor candidates for each query. We narrow it down to k neighbors. For each query, we calculate the exact distance between the query and its n_candidates neighbor candidate, and select the k nearest ones. + +The k nearest neighbors and distances are returned. + +Example usage **Parameters** @@ -228,7 +252,11 @@ raft::host_matrix_view distances, cuvs::distance::DistanceType metric = cuvs::distance::DistanceType::L2Unexpanded); ``` -Refinement is an operation that follows an approximate NN search. The approximate search has already selected n_candidates neighbor candidates for each query. We narrow it down to k neighbors. For each query, we calculate the exact distance between the query and its n_candidates neighbor candidate, and select the k nearest ones. The k nearest neighbors and distances are returned. Example usage +Refinement is an operation that follows an approximate NN search. The approximate search has already selected n_candidates neighbor candidates for each query. We narrow it down to k neighbors. For each query, we calculate the exact distance between the query and its n_candidates neighbor candidate, and select the k nearest ones. + +The k nearest neighbors and distances are returned. + +Example usage **Parameters** @@ -262,7 +290,11 @@ raft::host_matrix_view distances, cuvs::distance::DistanceType metric = cuvs::distance::DistanceType::L2Unexpanded); ``` -Refinement is an operation that follows an approximate NN search. The approximate search has already selected n_candidates neighbor candidates for each query. We narrow it down to k neighbors. For each query, we calculate the exact distance between the query and its n_candidates neighbor candidate, and select the k nearest ones. The k nearest neighbors and distances are returned. Example usage +Refinement is an operation that follows an approximate NN search. The approximate search has already selected n_candidates neighbor candidates for each query. We narrow it down to k neighbors. For each query, we calculate the exact distance between the query and its n_candidates neighbor candidate, and select the k nearest ones. + +The k nearest neighbors and distances are returned. + +Example usage **Parameters** @@ -296,7 +328,11 @@ raft::host_matrix_view distances, cuvs::distance::DistanceType metric = cuvs::distance::DistanceType::L2Unexpanded); ``` -Refinement is an operation that follows an approximate NN search. The approximate search has already selected n_candidates neighbor candidates for each query. We narrow it down to k neighbors. For each query, we calculate the exact distance between the query and its n_candidates neighbor candidate, and select the k nearest ones. The k nearest neighbors and distances are returned. Example usage +Refinement is an operation that follows an approximate NN search. The approximate search has already selected n_candidates neighbor candidates for each query. We narrow it down to k neighbors. For each query, we calculate the exact distance between the query and its n_candidates neighbor candidate, and select the k nearest ones. + +The k nearest neighbors and distances are returned. + +Example usage **Parameters** @@ -330,7 +366,11 @@ raft::host_matrix_view distances, cuvs::distance::DistanceType metric = cuvs::distance::DistanceType::L2Unexpanded); ``` -Refinement is an operation that follows an approximate NN search. The approximate search has already selected n_candidates neighbor candidates for each query. We narrow it down to k neighbors. For each query, we calculate the exact distance between the query and its n_candidates neighbor candidate, and select the k nearest ones. The k nearest neighbors and distances are returned. Example usage +Refinement is an operation that follows an approximate NN search. The approximate search has already selected n_candidates neighbor candidates for each query. We narrow it down to k neighbors. For each query, we calculate the exact distance between the query and its n_candidates neighbor candidate, and select the k nearest ones. + +The k nearest neighbors and distances are returned. + +Example usage **Parameters** diff --git a/fern/pages/cpp_api/cpp-api-neighbors-scann.md b/fern/pages/cpp_api/cpp-api-neighbors-scann.md index 03224235e4..941da0089b 100644 --- a/fern/pages/cpp_api/cpp-api-neighbors-scann.md +++ b/fern/pages/cpp_api/cpp-api-neighbors-scann.md @@ -121,7 +121,9 @@ const std::string& file_prefix, const cuvs::neighbors::experimental::scann::index& index); ``` -This serializes the index into a list of files for integration into OSS ScaNN for use with search NOTE: the implementation of ScaNN index build is EXPERIMENTAL and currently not subject to comprehensive, automated testing. Accuracy and performance are not guaranteed, and could diverge without warning. +This serializes the index into a list of files for integration into OSS ScaNN for use with search + +NOTE: the implementation of ScaNN index build is EXPERIMENTAL and currently not subject to comprehensive, automated testing. Accuracy and performance are not guaranteed, and could diverge without warning. **Parameters** @@ -151,7 +153,9 @@ const std::string& file_prefix, const cuvs::neighbors::experimental::scann::index& index); ``` -This serializes the index into a list of files for integration into OSS ScaNN for use with search NOTE: the implementation of ScaNN index build is EXPERIMENTAL and currently not subject to comprehensive, automated testing. Accuracy and performance are not guaranteed, and could diverge without warning. +This serializes the index into a list of files for integration into OSS ScaNN for use with search + +NOTE: the implementation of ScaNN index build is EXPERIMENTAL and currently not subject to comprehensive, automated testing. Accuracy and performance are not guaranteed, and could diverge without warning. **Parameters** diff --git a/fern/pages/cpp_api/cpp-api-neighbors-vamana.md b/fern/pages/cpp_api/cpp-api-neighbors-vamana.md index 057362fdc2..b5e5245a65 100644 --- a/fern/pages/cpp_api/cpp-api-neighbors-vamana.md +++ b/fern/pages/cpp_api/cpp-api-neighbors-vamana.md @@ -314,7 +314,13 @@ raft::device_matrix_view dataset) -> cuvs::neighbors::vamana::index; ``` -The build utilities the Vamana insertion-based algorithm to create the graph. The algorithm starts with an empty graph and iteratively iserts batches of nodes. Each batch involves performing a greedy search for each vector to be inserted, and inserting it with edges to all nodes traversed during the search. Reverse edges are also inserted and robustPrune is applied to improve graph quality. The index_params struct controls the degree of the final graph. The following distance metrics are supported: - L2 Usage example: +The build utilities the Vamana insertion-based algorithm to create the graph. The algorithm starts with an empty graph and iteratively iserts batches of nodes. Each batch involves performing a greedy search for each vector to be inserted, and inserting it with edges to all nodes traversed during the search. Reverse edges are also inserted and robustPrune is applied to improve graph quality. The index_params struct controls the degree of the final graph. + +The following distance metrics are supported: + +- L2 + +Usage example: **Parameters** @@ -343,7 +349,13 @@ raft::host_matrix_view dataset) -> cuvs::neighbors::vamana::index; ``` -The build utilities the Vamana insertion-based algorithm to create the graph. The algorithm starts with an empty graph and iteratively iserts batches of nodes. Each batch involves performing a greedy search for each vector to be inserted, and inserting it with edges to all nodes traversed during the search. Reverse edges are also inserted and robustPrune is applied to improve graph quality. The index_params struct controls the degree of the final graph. The following distance metrics are supported: - L2 Usage example: +The build utilities the Vamana insertion-based algorithm to create the graph. The algorithm starts with an empty graph and iteratively iserts batches of nodes. Each batch involves performing a greedy search for each vector to be inserted, and inserting it with edges to all nodes traversed during the search. Reverse edges are also inserted and robustPrune is applied to improve graph quality. The index_params struct controls the degree of the final graph. + +The following distance metrics are supported: + +- L2 + +Usage example: **Parameters** @@ -372,7 +384,13 @@ raft::device_matrix_view dataset) -> cuvs::neighbors::vamana::index; ``` -The build utilities the Vamana insertion-based algorithm to create the graph. The algorithm starts with an empty graph and iteratively iserts batches of nodes. Each batch involves performing a greedy search for each vector to be inserted, and inserting it with edges to all nodes traversed during the search. Reverse edges are also inserted and robustPrune is applied to improve graph quality. The index_params struct controls the degree of the final graph. The following distance metrics are supported: - L2 Usage example: +The build utilities the Vamana insertion-based algorithm to create the graph. The algorithm starts with an empty graph and iteratively iserts batches of nodes. Each batch involves performing a greedy search for each vector to be inserted, and inserting it with edges to all nodes traversed during the search. Reverse edges are also inserted and robustPrune is applied to improve graph quality. The index_params struct controls the degree of the final graph. + +The following distance metrics are supported: + +- L2 + +Usage example: **Parameters** @@ -401,7 +419,13 @@ raft::host_matrix_view dataset) -> cuvs::neighbors::vamana::index; ``` -The build utilities the Vamana insertion-based algorithm to create the graph. The algorithm starts with an empty graph and iteratively iserts batches of nodes. Each batch involves performing a greedy search for each vector to be inserted, and inserting it with edges to all nodes traversed during the search. Reverse edges are also inserted and robustPrune is applied to improve graph quality. The index_params struct controls the degree of the final graph. The following distance metrics are supported: - L2 Usage example: +The build utilities the Vamana insertion-based algorithm to create the graph. The algorithm starts with an empty graph and iteratively iserts batches of nodes. Each batch involves performing a greedy search for each vector to be inserted, and inserting it with edges to all nodes traversed during the search. Reverse edges are also inserted and robustPrune is applied to improve graph quality. The index_params struct controls the degree of the final graph. + +The following distance metrics are supported: + +- L2 + +Usage example: **Parameters** @@ -430,7 +454,13 @@ raft::device_matrix_view dataset) -> cuvs::neighbors::vamana::index; ``` -The build utilities the Vamana insertion-based algorithm to create the graph. The algorithm starts with an empty graph and iteratively iserts batches of nodes. Each batch involves performing a greedy search for each vector to be inserted, and inserting it with edges to all nodes traversed during the search. Reverse edges are also inserted and robustPrune is applied to improve graph quality. The index_params struct controls the degree of the final graph. The following distance metrics are supported: - L2 Usage example: +The build utilities the Vamana insertion-based algorithm to create the graph. The algorithm starts with an empty graph and iteratively iserts batches of nodes. Each batch involves performing a greedy search for each vector to be inserted, and inserting it with edges to all nodes traversed during the search. Reverse edges are also inserted and robustPrune is applied to improve graph quality. The index_params struct controls the degree of the final graph. + +The following distance metrics are supported: + +- L2 + +Usage example: **Parameters** @@ -459,7 +489,13 @@ raft::host_matrix_view dataset) -> cuvs::neighbors::vamana::index; ``` -The build utilities the Vamana insertion-based algorithm to create the graph. The algorithm starts with an empty graph and iteratively iserts batches of nodes. Each batch involves performing a greedy search for each vector to be inserted, and inserting it with edges to all nodes traversed during the search. Reverse edges are also inserted and robustPrune is applied to improve graph quality. The index_params struct controls the degree of the final graph. The following distance metrics are supported: - L2 Usage example: +The build utilities the Vamana insertion-based algorithm to create the graph. The algorithm starts with an empty graph and iteratively iserts batches of nodes. Each batch involves performing a greedy search for each vector to be inserted, and inserting it with edges to all nodes traversed during the search. Reverse edges are also inserted and robustPrune is applied to improve graph quality. The index_params struct controls the degree of the final graph. + +The following distance metrics are supported: + +- L2 + +Usage example: **Parameters** diff --git a/fern/pages/cpp_api/cpp-api-preprocessing-pca.md b/fern/pages/cpp_api/cpp-api-preprocessing-pca.md index 146f95dbb4..f0f6e1e1ce 100644 --- a/fern/pages/cpp_api/cpp-api-preprocessing-pca.md +++ b/fern/pages/cpp_api/cpp-api-preprocessing-pca.md @@ -106,7 +106,9 @@ raft::device_vector_view mu, raft::device_matrix_view trans_input); ``` -Transforms the input data into the eigenspace using previously computed principal components. (mean-centered then restored). +Transforms the input data into the eigenspace using previously computed principal components. + +(mean-centered then restored). **Parameters** diff --git a/fern/pages/cpp_api/cpp-api-preprocessing-quantize-binary.md b/fern/pages/cpp_api/cpp-api-preprocessing-quantize-binary.md index ba92c2508b..997c1fce85 100644 --- a/fern/pages/cpp_api/cpp-api-preprocessing-quantize-binary.md +++ b/fern/pages/cpp_api/cpp-api-preprocessing-quantize-binary.md @@ -134,7 +134,9 @@ raft::device_matrix_view dataset, raft::device_matrix_view out); ``` -set the corresponding bit to 1. Usage example: +set the corresponding bit to 1. + +Usage example: **Parameters** @@ -162,7 +164,9 @@ raft::host_matrix_view dataset, raft::host_matrix_view out); ``` -set the corresponding bit to 1. Usage example: +set the corresponding bit to 1. + +Usage example: **Parameters** @@ -246,7 +250,9 @@ raft::device_matrix_view dataset, raft::device_matrix_view out); ``` -set the corresponding bit to 1. Usage example: +set the corresponding bit to 1. + +Usage example: **Parameters** @@ -274,7 +280,9 @@ raft::host_matrix_view dataset, raft::host_matrix_view out); ``` -set the corresponding bit to 1. Usage example: +set the corresponding bit to 1. + +Usage example: **Parameters** diff --git a/fern/pages/cpp_api/cpp-api-preprocessing-quantize-pq.md b/fern/pages/cpp_api/cpp-api-preprocessing-quantize-pq.md index 5a6c49f02f..b22610185d 100644 --- a/fern/pages/cpp_api/cpp-api-preprocessing-quantize-pq.md +++ b/fern/pages/cpp_api/cpp-api-preprocessing-quantize-pq.md @@ -82,7 +82,9 @@ const params params, raft::device_matrix_view dataset); ``` -The use of a pool memory resource is recommended for more consistent training performance. Usage example: +The use of a pool memory resource is recommended for more consistent training performance. + +Usage example: **Parameters** @@ -134,7 +136,9 @@ raft::device_matrix_view codes_out, std::optional> vq_labels = std::nullopt); ``` -Usage example: used, optional +Usage example: + +used, optional **Parameters** diff --git a/fern/pages/cpp_api/cpp-api-preprocessing-quantize-scalar.md b/fern/pages/cpp_api/cpp-api-preprocessing-quantize-scalar.md index cc631cd1af..9a4f9e7201 100644 --- a/fern/pages/cpp_api/cpp-api-preprocessing-quantize-scalar.md +++ b/fern/pages/cpp_api/cpp-api-preprocessing-quantize-scalar.md @@ -149,7 +149,9 @@ raft::device_matrix_view dataset, raft::device_matrix_view out); ``` -Note that depending on the chosen data types train dataset the conversion is not lossless. Usage example: +Note that depending on the chosen data types train dataset the conversion is not lossless. + +Usage example: **Parameters** @@ -177,7 +179,9 @@ raft::host_matrix_view dataset, raft::host_matrix_view out); ``` -Note that depending on the chosen data types train dataset the conversion is not lossless. Usage example: +Note that depending on the chosen data types train dataset the conversion is not lossless. + +Usage example: **Parameters** @@ -317,7 +321,9 @@ raft::device_matrix_view dataset, raft::device_matrix_view out); ``` -Note that depending on the chosen data types train dataset the conversion is not lossless. Usage example: +Note that depending on the chosen data types train dataset the conversion is not lossless. + +Usage example: **Parameters** @@ -345,7 +351,9 @@ raft::host_matrix_view dataset, raft::host_matrix_view out); ``` -Note that depending on the chosen data types train dataset the conversion is not lossless. Usage example: +Note that depending on the chosen data types train dataset the conversion is not lossless. + +Usage example: **Parameters** @@ -485,7 +493,9 @@ raft::device_matrix_view dataset, raft::device_matrix_view out); ``` -Note that depending on the chosen data types train dataset the conversion is not lossless. Usage example: +Note that depending on the chosen data types train dataset the conversion is not lossless. + +Usage example: **Parameters** @@ -513,7 +523,9 @@ raft::host_matrix_view dataset, raft::host_matrix_view out); ``` -Note that depending on the chosen data types train dataset the conversion is not lossless. Usage example: +Note that depending on the chosen data types train dataset the conversion is not lossless. + +Usage example: **Parameters** diff --git a/fern/pages/cpp_api/cpp-api-preprocessing-spectral-embedding.md b/fern/pages/cpp_api/cpp-api-preprocessing-spectral-embedding.md index b809a7de49..e17993025f 100644 --- a/fern/pages/cpp_api/cpp-api-preprocessing-spectral-embedding.md +++ b/fern/pages/cpp_api/cpp-api-preprocessing-spectral-embedding.md @@ -21,7 +21,12 @@ raft::device_matrix_view dataset, raft::device_matrix_view embedding); ``` -This function computes the spectral embedding of the input dataset by: 1. Constructing a k-nearest neighbors graph from the input data 2. Computing the graph Laplacian (normalized or unnormalized) 3. Finding the eigenvectors corresponding to the smallest eigenvalues 4. Using these eigenvectors as the embedding coordinates +This function computes the spectral embedding of the input dataset by: + +1. Constructing a k-nearest neighbors graph from the input data +2. Computing the graph Laplacian (normalized or unnormalized) +3. Finding the eigenvectors corresponding to the smallest eigenvalues +4. Using these eigenvectors as the embedding coordinates **Parameters** @@ -49,7 +54,13 @@ raft::device_coo_matrix_view connectivity_graph, raft::device_matrix_view embedding); ``` -This function computes the spectral embedding from a precomputed sparse connectivity graph (e.g., from a k-NN search or custom similarity matrix). This is useful when you want to use a custom graph construction method or when you have a precomputed similarity/affinity matrix. The function: 1. Converts the COO matrix to the graph Laplacian 2. Computes eigenvectors of the Laplacian 3. Returns the eigenvectors as the embedding +This function computes the spectral embedding from a precomputed sparse connectivity graph (e.g., from a k-NN search or custom similarity matrix). This is useful when you want to use a custom graph construction method or when you have a precomputed similarity/affinity matrix. + +The function: + +1. Converts the COO matrix to the graph Laplacian +2. Computes eigenvectors of the Laplacian +3. Returns the eigenvectors as the embedding **Parameters** diff --git a/fern/pages/cpp_api/cpp-api-selection-select-k.md b/fern/pages/cpp_api/cpp-api-selection-select-k.md index 9cefd4b72e..19dcbd25f7 100644 --- a/fern/pages/cpp_api/cpp-api-selection-select-k.md +++ b/fern/pages/cpp_api/cpp-api-selection-select-k.md @@ -27,7 +27,9 @@ SelectAlgo algo = SelectAl std::optional> len_i = std::nullopt); ``` -If you think of the input data `in_val` as a row-major matrix with `len` columns and `batch_size` rows, then this function selects `k` smallest/largest values in each row and fills in the row-major matrix `out_val` of size (batch_size, k). Example usage +If you think of the input data `in_val` as a row-major matrix with `len` columns and `batch_size` rows, then this function selects `k` smallest/largest values in each row and fills in the row-major matrix `out_val` of size (batch_size, k). + +Example usage **Parameters** @@ -66,7 +68,9 @@ SelectAlgo algo = SelectA std::optional> len_i = std::nullopt); ``` -If you think of the input data `in_val` as a row-major matrix with `len` columns and `batch_size` rows, then this function selects `k` smallest/largest values in each row and fills in the row-major matrix `out_val` of size (batch_size, k). Example usage +If you think of the input data `in_val` as a row-major matrix with `len` columns and `batch_size` rows, then this function selects `k` smallest/largest values in each row and fills in the row-major matrix `out_val` of size (batch_size, k). + +Example usage **Parameters** @@ -105,7 +109,9 @@ SelectAlgo algo = SelectA std::optional> len_i = std::nullopt); ``` -If you think of the input data `in_val` as a row-major matrix with `len` columns and `batch_size` rows, then this function selects `k` smallest/largest values in each row and fills in the row-major matrix `out_val` of size (batch_size, k). Example usage +If you think of the input data `in_val` as a row-major matrix with `len` columns and `batch_size` rows, then this function selects `k` smallest/largest values in each row and fills in the row-major matrix `out_val` of size (batch_size, k). + +Example usage **Parameters** diff --git a/fern/pages/python_api/python-api-neighbors-brute-force.md b/fern/pages/python_api/python-api-neighbors-brute-force.md index 54f105871e..49d3aec993 100644 --- a/fern/pages/python_api/python-api-neighbors-brute-force.md +++ b/fern/pages/python_api/python-api-neighbors-brute-force.md @@ -95,7 +95,7 @@ Find the k nearest neighbors for each query. | `k` | `int` | The number of neighbors. | | `neighbors` | `Optional CUDA array interface compliant matrix shape` | (n_queries, k), dtype int64_t. If supplied, neighbor indices will be written here in-place. (default None) | | `distances` | `Optional CUDA array interface compliant matrix shape` | (n_queries, k) If supplied, the distances to the neighbors will be written here in-place. (default None) | -| `prefilter` | `Optional, cuvs.neighbors.cuvsFilter` | An optional filter to exclude certain query-neighbor pairs using a bitmap or bitset. The filter function should have a row-major layout with logical shape `(n_prefilter_rows, n_samples)`, where: - `n_prefilter_rows == n_queries` when using a bitmap filter. - `n_prefilter_rows == 1` when using a bitset prefilter. Each bit in `n_samples` determines whether `queries[i]` should be considered for distance computation with the index. (default None) | +| `prefilter` | `Optional, cuvs.neighbors.cuvsFilter` | An optional filter to exclude certain query-neighbor pairs using a bitmap or bitset. The filter function should have a row-major layout with logical shape `(n_prefilter_rows, n_samples)`, where:
- `n_prefilter_rows == n_queries` when using a bitmap filter.
- `n_prefilter_rows == 1` when using a bitset prefilter. Each bit in `n_samples` determines whether `queries[i]` should be considered for distance computation with the index. (default None) | | `resources` | `cuvs.common.Resources, optional` | | **Examples** diff --git a/fern/pages/python_api/python-api-neighbors-cagra.md b/fern/pages/python_api/python-api-neighbors-cagra.md index ec6bb8a628..1b2a0e1bab 100644 --- a/fern/pages/python_api/python-api-neighbors-cagra.md +++ b/fern/pages/python_api/python-api-neighbors-cagra.md @@ -315,10 +315,10 @@ Parameters to build index for CAGRA nearest neighbor search | Name | Type | Description | | --- | --- | --- | -| `metric` | `str, default = "sqeuclidean"` | String denoting the metric type, valid values for metric are ["sqeuclidean", "inner_product", "cosine"], where:

- sqeuclidean is the euclidean distance without the square root operation, i.e.: distance(a,b) = \\sum_i (a_i - b_i)^2 - inner_product distance is defined as distance(a, b) = \\sum_i a_i * b_i. - cosine distance is defined as distance(a, b) = 1 - \\sum_i a_i * b_i / ( \|\|a\|\|_2 * \|\|b\|\|_2). | +| `metric` | `str, default = "sqeuclidean"` | String denoting the metric type, valid values for metric are ["sqeuclidean", "inner_product", "cosine"], where:

- sqeuclidean is the euclidean distance without the square root operation, i.e.: distance(a,b) = \\sum_i (a_i - b_i)^2
- inner_product distance is defined as distance(a, b) = \\sum_i a_i * b_i.
- cosine distance is defined as distance(a, b) = 1 - \\sum_i a_i * b_i / ( \|\|a\|\|_2 * \|\|b\|\|_2). | | `intermediate_graph_degree` | `int, default = 128` | | | `graph_degree` | `int, default = 64` | | -| `build_algo` | `str, default = "ivf_pq"` | string denoting the graph building algorithm to use. Valid values for algo: ["ivf_pq", "nn_descent", "iterative_cagra_search", "ace"], where

- ivf_pq will use the IVF-PQ algorithm for building the knn graph - nn_descent (experimental) will use the NN-Descent algorithm for building the knn graph. It is expected to be generally faster than ivf_pq. - iterative_cagra_search will iteratively build the knn graph using CAGRA's search() and optimize() - ace will use ACE (Augmented Core Extraction) for building indices for datasets too large to fit in GPU memory | +| `build_algo` | `str, default = "ivf_pq"` | string denoting the graph building algorithm to use. Valid values for algo: ["ivf_pq", "nn_descent", "iterative_cagra_search", "ace"], where

- ivf_pq will use the IVF-PQ algorithm for building the knn graph
- nn_descent (experimental) will use the NN-Descent algorithm for building the knn graph. It is expected to be generally faster than ivf_pq.
- iterative_cagra_search will iteratively build the knn graph using CAGRA's search() and optimize()
- ace will use ACE (Augmented Core Extraction) for building indices for datasets too large to fit in GPU memory | | `compression` | `CompressionParams, optional` | If compression is desired should be a CompressionParams object. If None compression will be disabled. | | `ivf_pq_build_params` | `cuvs.neighbors.ivf_pq.IndexParams, optional` | Parameters for IVF-PQ algorithm. If provided, it will be used for building the graph. | | `ivf_pq_search_params` | `cuvs.neighbors.ivf_pq.SearchParams, optional` | Parameters for IVF-PQ search. If provided, it will be used for searching the graph. | @@ -416,12 +416,12 @@ CAGRA search parameters | `max_queries` | `int, default = 0` | Maximum number of queries to search at the same time (batch size). Auto select when 0. | | `itopk_size` | `int, default = 64` | Number of intermediate search results retained during the search. This is the main knob to adjust trade off between accuracy and search speed. Higher values improve the search accuracy. | | `max_iterations` | `int, default = 0` | Upper limit of search iterations. Auto select when 0. | -| `algo` | `str, default = "auto"` | String denoting the search algorithm to use Valid values for algo: ["auto", "single_cta", "multi_cta"], where:

- auto will automatically select the best value based on query size - single_cta is better when query contains larger number of vectors (e.g >10) - multi_cta is better when query contains only a few vectors | +| `algo` | `str, default = "auto"` | String denoting the search algorithm to use Valid values for algo: ["auto", "single_cta", "multi_cta"], where:

- auto will automatically select the best value based on query size
- single_cta is better when query contains larger number of vectors (e.g >10)
- multi_cta is better when query contains only a few vectors | | `team_size` | `int, default = 0` | Number of threads used to calculate a single distance. 4, 8, 16, or 32. | | `search_width` | `int, default = 1` | Number of graph nodes to select as the starting point for the search in each iteration. | | `min_iterations` | `int, default = 0` | Lower limit of search iterations. | | `thread_block_size` | `int, default = 0` | Thread block size. 0, 64, 128, 256, 512, 1024. Auto selection when 0. | -| `hashmap_mode` | `str, default = "auto"` | String denoting the type of hash map to use. It's usually better to allow the algorithm to select this value, Valid values for hashmap_mode: ["auto", "small", "hash"], where:

- auto will automatically select the best value based on algo - small will use the small shared memory hash table with resetting. - hash will use a single hash table in global memory. | +| `hashmap_mode` | `str, default = "auto"` | String denoting the type of hash map to use. It's usually better to allow the algorithm to select this value, Valid values for hashmap_mode: ["auto", "small", "hash"], where:

- auto will automatically select the best value based on algo
- small will use the small shared memory hash table with resetting.
- hash will use a single hash table in global memory. | | `hashmap_min_bitlen` | `int, default = 0` | Upper limit of hashmap fill rate. More than 0.1, less than 0.9. | | `hashmap_max_fill_rate` | `float, default = 0.5` | Upper limit of hashmap fill rate. More than 0.1, less than 0.9. | | `num_random_samplings` | `int, default = 1` | Number of iterations of initial random seed node selection. 1 or more. | diff --git a/fern/pages/python_api/python-api-neighbors-filters.md b/fern/pages/python_api/python-api-neighbors-filters.md index eedea7b127..af0d7a84c1 100644 --- a/fern/pages/python_api/python-api-neighbors-filters.md +++ b/fern/pages/python_api/python-api-neighbors-filters.md @@ -28,7 +28,7 @@ Create a pre-filter from an array with type of uint32. | Name | Type | Description | | --- | --- | --- | -| `bitmap` | `numpy.ndarray` | An array with type of `uint32` where each bit in the array corresponds to if a sample and query pair is greenlit (not filtered) or filtered. The array is row-major, meaning the bits are ordered by rows first. Each bit in a `uint32` element represents a different sample-query pair.

- Bit value of 1: The sample-query pair is greenlit (allowed). - Bit value of 0: The sample-query pair is filtered. | +| `bitmap` | `numpy.ndarray` | An array with type of `uint32` where each bit in the array corresponds to if a sample and query pair is greenlit (not filtered) or filtered. The array is row-major, meaning the bits are ordered by rows first. Each bit in a `uint32` element represents a different sample-query pair.

- Bit value of 1: The sample-query pair is greenlit (allowed).
- Bit value of 0: The sample-query pair is filtered. | **Returns** @@ -66,7 +66,7 @@ Create a pre-filter from an array with type of uint32. | Name | Type | Description | | --- | --- | --- | -| `bitset` | `numpy.ndarray` | An array with type of `uint32` where each bit in the array corresponds to if a sample is greenlit (not filtered) or filtered. Each bit in a `uint32` element represents a different sample of the dataset.

- Bit value of 1: The sample is greenlit (allowed). - Bit value of 0: The sample pair is filtered. | +| `bitset` | `numpy.ndarray` | An array with type of `uint32` where each bit in the array corresponds to if a sample is greenlit (not filtered) or filtered. Each bit in a `uint32` element represents a different sample of the dataset.

- Bit value of 1: The sample is greenlit (allowed).
- Bit value of 0: The sample pair is filtered. | **Returns** diff --git a/fern/pages/python_api/python-api-neighbors-hnsw.md b/fern/pages/python_api/python-api-neighbors-hnsw.md index d06de7b770..ba9d928782 100644 --- a/fern/pages/python_api/python-api-neighbors-hnsw.md +++ b/fern/pages/python_api/python-api-neighbors-hnsw.md @@ -98,7 +98,7 @@ Parameters to build index for HNSW nearest neighbor search | Name | Type | Description | | --- | --- | --- | -| `hierarchy` | `string, default = "gpu" (optional)` | The hierarchy of the HNSW index. Valid values are ["none", "cpu", "gpu"]. - "none": No hierarchy is built. - "cpu": Hierarchy is built using CPU. - "gpu": Hierarchy is built using GPU. | +| `hierarchy` | `string, default = "gpu" (optional)` | The hierarchy of the HNSW index. Valid values are ["none", "cpu", "gpu"].
- "none": No hierarchy is built.
- "cpu": Hierarchy is built using CPU.
- "gpu": Hierarchy is built using GPU. | | `ef_construction` | `int, default = 200 (optional)` | Maximum number of candidate list size used during construction when hierarchy is `cpu`. | | `num_threads` | `int, default = 0 (optional)` | Number of CPU threads used to increase construction parallelism when hierarchy is `cpu` or `gpu`. When the value is 0, the number of threads is automatically determined to the maximum number of threads available. NOTE: When hierarchy is `gpu`, while the majority of the work is done on the GPU, initialization of the HNSW index itself and some other work is parallelized with the help of CPU threads. | | `M` | `int, default = 32 (optional)` | HNSW M parameter: number of bi-directional links per node (used when building with ACE). graph_degree = m * 2, intermediate_graph_degree = m * 3. | @@ -411,7 +411,7 @@ version of cuVS is not guaranteed to work. | `filename` | `string` | Name of the file. | | `dim` | `int` | Dimensions of the training dataest | | `dtype` | `np.dtype of the saved index` | Valid values for dtype: [np.float32, np.byte, np.ubyte] | -| `metric` | `string denoting the metric type, default="sqeuclidean"` | Valid values for metric: ["sqeuclidean", "inner_product"], where - sqeuclidean is the euclidean distance without the square root operation, i.e.: distance(a,b) = \\sum_i (a_i - b_i)^2, - inner_product distance is defined as distance(a, b) = \\sum_i a_i * b_i. | +| `metric` | `string denoting the metric type, default="sqeuclidean"` | Valid values for metric: ["sqeuclidean", "inner_product"], where
- sqeuclidean is the euclidean distance without the square root operation, i.e.: distance(a,b) = \\sum_i (a_i - b_i)^2,
- inner_product distance is defined as distance(a, b) = \\sum_i a_i * b_i. | | `resources` | `cuvs.common.Resources, optional` | | **Returns** diff --git a/fern/pages/python_api/python-api-neighbors-ivf-flat.md b/fern/pages/python_api/python-api-neighbors-ivf-flat.md index 8be854a43a..69ec952663 100644 --- a/fern/pages/python_api/python-api-neighbors-ivf-flat.md +++ b/fern/pages/python_api/python-api-neighbors-ivf-flat.md @@ -78,7 +78,7 @@ Parameters to build index for IvfFlat nearest neighbor search | Name | Type | Description | | --- | --- | --- | | `n_lists` | `int, default = 1024` | The number of clusters used in the coarse quantizer. | -| `metric` | `str, default = "sqeuclidean"` | String denoting the metric type. Valid values for metric: ["sqeuclidean", "inner_product", "euclidean", "cosine"], where

- sqeuclidean is the euclidean distance without the square root operation, i.e.: distance(a,b) = \\sum_i (a_i - b_i)^2, - euclidean is the euclidean distance - inner product distance is defined as distance(a, b) = \\sum_i a_i * b_i. - cosine distance is defined as distance(a, b) = 1 - \\sum_i a_i * b_i / ( \|\|a\|\|_2 * \|\|b\|\|_2). | +| `metric` | `str, default = "sqeuclidean"` | String denoting the metric type. Valid values for metric: ["sqeuclidean", "inner_product", "euclidean", "cosine"], where

- sqeuclidean is the euclidean distance without the square root operation, i.e.: distance(a,b) = \\sum_i (a_i - b_i)^2,
- euclidean is the euclidean distance
- inner product distance is defined as distance(a, b) = \\sum_i a_i * b_i.
- cosine distance is defined as distance(a, b) = 1 - \\sum_i a_i * b_i / ( \|\|a\|\|_2 * \|\|b\|\|_2). | | `kmeans_n_iters` | `int, default = 20` | The number of iterations searching for kmeans centers during index building. The default setting is often fine, but this parameter can be decreased to improve training time wih larger trainset fractions (10M+ vectors) or increased for smaller trainset fractions (very small number of vectors) to improve recall. | | `kmeans_trainset_fraction` | `int, default = 0.5` | If kmeans_trainset_fraction is less than 1, then the dataset is subsampled, and only n_samples * kmeans_trainset_fraction rows are used for training. | | `add_data_on_build` | `bool, default = True` | After training the coarse and fine quantizers, we will populate the index with the dataset if add_data_on_build == True, otherwise the index is left empty, and the extend method can be used to add new vectors to the index. | diff --git a/fern/pages/python_api/python-api-neighbors-ivf-pq.md b/fern/pages/python_api/python-api-neighbors-ivf-pq.md index e7b1368169..464b6ec757 100644 --- a/fern/pages/python_api/python-api-neighbors-ivf-pq.md +++ b/fern/pages/python_api/python-api-neighbors-ivf-pq.md @@ -230,7 +230,7 @@ Parameters to build index for IvfPq nearest neighbor search | Name | Type | Description | | --- | --- | --- | | `n_lists` | `int, default = 1024` | The number of clusters used in the coarse quantizer. | -| `metric` | `str, default="sqeuclidean"` | String denoting the metric type. Valid values for metric: ["sqeuclidean", "inner_product", "euclidean", "cosine"], where:

- sqeuclidean is the euclidean distance without the square root operation, i.e.: distance(a,b) = \\sum_i (a_i - b_i)^2, - euclidean is the euclidean distance - inner product distance is defined as distance(a, b) = \\sum_i a_i * b_i. - cosine distance is defined as distance(a, b) = 1 - \\sum_i a_i * b_i / ( \|\|a\|\|_2 * \|\|b\|\|_2). | +| `metric` | `str, default="sqeuclidean"` | String denoting the metric type. Valid values for metric: ["sqeuclidean", "inner_product", "euclidean", "cosine"], where:

- sqeuclidean is the euclidean distance without the square root operation, i.e.: distance(a,b) = \\sum_i (a_i - b_i)^2,
- euclidean is the euclidean distance
- inner product distance is defined as distance(a, b) = \\sum_i a_i * b_i.
- cosine distance is defined as distance(a, b) = 1 - \\sum_i a_i * b_i / ( \|\|a\|\|_2 * \|\|b\|\|_2). | | `kmeans_n_iters` | `int, default = 20` | The number of iterations searching for kmeans centers during index building. | | `kmeans_trainset_fraction` | `int, default = 0.5` | If kmeans_trainset_fraction is less than 1, then the dataset is subsampled, and only n_samples * kmeans_trainset_fraction rows are used for training. | | `pq_bits` | `int, default = 8` | The bit length of the vector element after quantization. | @@ -240,7 +240,7 @@ Parameters to build index for IvfPq nearest neighbor search | `add_data_on_build` | `bool, default = True` | After training the coarse and fine quantizers, we will populate the index with the dataset if add_data_on_build == True, otherwise the index is left empty, and the extend method can be used to add new vectors to the index. | | `conservative_memory_allocation` | `bool, default = True` | By default, the algorithm allocates more space than necessary for individual clusters (`list_data`). This allows to amortize the cost of memory allocation and reduce the number of data copies during repeated calls to `extend` (extending the database). To disable this behavior and use as little GPU memory for the database as possible, set this flat to `True`. | | `max_train_points_per_pq_code` | `int, default = 256` | The max number of data points to use per PQ code during PQ codebook training. Using more data points per PQ code may increase the quality of PQ codebook but may also increase the build time. The parameter is applied to both PQ codebook generation methods, i.e., PER_SUBSPACE and PER_CLUSTER. In both cases, we will use pq_book_size * max_train_points_per_pq_code training points to train each codebook. | -| `codes_layout` | `string, default = "interleaved"` | Memory layout of the IVF-PQ list data. Valid values ["flat", "interleaved"]

- flat: Codes are stored contiguously, one vector's codes after another. - interleaved: Codes are interleaved for optimized search performance. This is the default and recommended for search workloads. | +| `codes_layout` | `string, default = "interleaved"` | Memory layout of the IVF-PQ list data. Valid values ["flat", "interleaved"]

- flat: Codes are stored contiguously, one vector's codes after another.
- interleaved: Codes are interleaved for optimized search performance. This is the default and recommended for search workloads. | **Constructor** @@ -414,7 +414,7 @@ Supplemental parameters to search IVF-Pq index | `n_probes` | `int` | The number of clusters to search. | | `lut_dtype` | `default = np.float32` | Data type of look up table to be created dynamically at search time. The use of low-precision types reduces the amount of shared memory required at search time, so fast shared memory kernels can be used even for datasets with large dimansionality. Note that the recall is slightly degraded when low-precision type is selected. Possible values [np.float32, np.float16, np.uint8] | | `internal_distance_dtype` | `default = np.float32` | Storage data type for distance/similarity computation. Possible values [np.float32, np.float16] | -| `coarse_search_dtype` | `default = np.float32` | [Experimental] The data type to use as the GEMM element type when searching the clusters to probe. Possible values: [np.float32, np.float16, np.int8]. - Legacy default: np.float32 - Recommended for performance: np.float16 (half) - Experimental/low-precision: np.int8 | +| `coarse_search_dtype` | `default = np.float32` | [Experimental] The data type to use as the GEMM element type when searching the clusters to probe. Possible values: [np.float32, np.float16, np.int8].
- Legacy default: np.float32
- Recommended for performance: np.float16 (half)
- Experimental/low-precision: np.int8 | | `max_internal_batch_size` | `default = 4096` | Set the internal batch size to improve GPU utilization at the cost of larger memory footprint. | **Constructor** @@ -567,7 +567,7 @@ The index_params must be consistent with the provided matrices. Specifically: | --- | --- | --- | | `index_params` | `cuvs.neighbors.ivf_pq.IndexParams` | Parameters that must be consistent with the provided matrices | | `dim` | `int` | Dimensionality of the input data | -| `pq_centers` | `CUDA array interface compliant tensor` | PQ codebook on device memory with required shape: - codebook_kind "subspace": [pq_dim, pq_len, pq_book_size] - codebook_kind "cluster": [n_lists, pq_len, pq_book_size] Supported dtype: float32 | +| `pq_centers` | `CUDA array interface compliant tensor` | PQ codebook on device memory with required shape:
- codebook_kind "subspace": [pq_dim, pq_len, pq_book_size]
- codebook_kind "cluster": [n_lists, pq_len, pq_book_size] Supported dtype: float32 | | `centers` | `CUDA array interface compliant matrix` | Cluster centers in the original space [n_lists, dim_ext] where dim_ext = round_up(dim + 1, 8). Supported dtype: float32 | | `centers_rot` | `CUDA array interface compliant matrix` | Rotated cluster centers [n_lists, rot_dim] where rot_dim = pq_len * pq_dim. Supported dtype: float32 | | `rotation_matrix` | `CUDA array interface compliant matrix` | Transform matrix (original space -> rotated padded space) [rot_dim, dim]. Supported dtype: float32 | diff --git a/fern/pages/python_api/python-api-neighbors-tiered-index.md b/fern/pages/python_api/python-api-neighbors-tiered-index.md index 8aa3e1f415..94fd094052 100644 --- a/fern/pages/python_api/python-api-neighbors-tiered-index.md +++ b/fern/pages/python_api/python-api-neighbors-tiered-index.md @@ -42,7 +42,7 @@ Parameters to build index for Tiered Index nearest neighbor search | Name | Type | Description | | --- | --- | --- | -| `metric` | `str, default = "sqeuclidean"` | String denoting the metric type. Valid values for metric: ["sqeuclidean", "inner_product", "euclidean", "cosine"], where - sqeuclidean is the euclidean distance without the square root operation, i.e.: distance(a,b) = \\sum_i (a_i - b_i)^2, - euclidean is the euclidean distance - inner product distance is defined as distance(a, b) = \\sum_i a_i * b_i. - cosine distance is defined as distance(a, b) = 1 - \\sum_i a_i * b_i / ( \|\|a\|\|_2 * \|\|b\|\|_2). | +| `metric` | `str, default = "sqeuclidean"` | String denoting the metric type. Valid values for metric: ["sqeuclidean", "inner_product", "euclidean", "cosine"], where
- sqeuclidean is the euclidean distance without the square root operation, i.e.: distance(a,b) = \\sum_i (a_i - b_i)^2,
- euclidean is the euclidean distance
- inner product distance is defined as distance(a, b) = \\sum_i a_i * b_i.
- cosine distance is defined as distance(a, b) = 1 - \\sum_i a_i * b_i / ( \|\|a\|\|_2 * \|\|b\|\|_2). | | `algo` | `str, default = "cagra"` | The algorithm to use for the ANN portion of the tiered index | | `upstream_params` | `object, optional` | The IndexParams for the upstream ANN object to use (ie the Cagra IndexParams for cagra etc) | | `min_ann_rows` | `int` | The minimum number of rows necessary to create an ann index | diff --git a/fern/pages/python_api/python-api-neighbors-vamana.md b/fern/pages/python_api/python-api-neighbors-vamana.md index 02381432a7..622f1ea015 100644 --- a/fern/pages/python_api/python-api-neighbors-vamana.md +++ b/fern/pages/python_api/python-api-neighbors-vamana.md @@ -43,7 +43,7 @@ Parameters for building a Vamana index | Name | Type | Description | | --- | --- | --- | -| `metric` | `str, default="sqeuclidean"` | String denoting the metric type. Supported metrics include: - "sqeuclidean" - "l2" | +| `metric` | `str, default="sqeuclidean"` | String denoting the metric type. Supported metrics include:
- "sqeuclidean"
- "l2" | | `graph_degree` | `int, default=32` | Maximum degree of graph; corresponds to the R parameter of Vamana algorithm in the literature. | | `visited_size` | `int, default=64` | Maximum number of visited nodes per search during Vamana algorithm. Loosely corresponds to the L parameter in the literature. | | `vamana_iters` | `float, default=1` | Number of Vamana vector insertion iterations (each iteration inserts all vectors). | diff --git a/fern/scripts/generate_api_reference.py b/fern/scripts/generate_api_reference.py index b52c60fa7d..e8c246c733 100755 --- a/fern/scripts/generate_api_reference.py +++ b/fern/scripts/generate_api_reference.py @@ -72,6 +72,7 @@ COMMENT_RE = re.compile(r"/\*\*.*?\*/|(?:///[^\n]*(?:\n|$))+", re.DOTALL) DOXYGEN_COMMAND_RE = re.compile(r"[@\\](\w+)\b") +DOXYGEN_LIST_ITEM_RE = re.compile(r"^(?:-\s+|\d+\.\s+)") PUBLIC_JAVA_TYPE_RE = re.compile( r"\bpublic\s+(?:abstract\s+|final\s+|sealed\s+|non-sealed\s+)?" r"(?Pclass|interface|enum|record)\s+(?P[A-Za-z_]\w*)" @@ -483,14 +484,8 @@ def render_native_function( lines.extend([f"```{language}", signature, "```", ""]) if entry.details: - lines.extend( - [ - escape_text( - " ".join(line for line in entry.details if line.strip()) - ), - "", - ] - ) + lines.extend(render_doxygen_details(entry.details)) + lines.append("") if entry.tparams: lines.extend(["**Template Parameters**", ""]) @@ -544,14 +539,8 @@ def render_native_compound(entry: DoxygenEntry, language: str) -> list[str]: if entry.summary: lines.extend([escape_text(entry.summary), ""]) if entry.details: - lines.extend( - [ - escape_text( - " ".join(line for line in entry.details if line.strip()) - ), - "", - ] - ) + lines.extend(render_doxygen_details(entry.details)) + lines.append("") lines.extend( [ f"```{language}", @@ -1218,7 +1207,7 @@ def parse_doxygen_entry( if active_param is not None and ( raw_line.startswith((" ", "\t")) or not line_text ): - active_param.description = append_sentence( + active_param.description = append_doxygen_line( active_param.description, clean_doxygen_text(line_text) ) continue @@ -1280,6 +1269,20 @@ def append_sentence(existing: str, addition: str) -> str: return f"{existing} {addition}" +def append_doxygen_line(existing: str, addition: str) -> str: + addition = addition.strip() + if not addition: + return existing + if not existing: + return addition + lines = existing.splitlines() + if DOXYGEN_LIST_ITEM_RE.match(addition): + lines.append(addition) + else: + lines[-1] = append_sentence(lines[-1], addition) + return "\n".join(lines) + + def parse_doxygen_kind(declaration: str) -> str: if re.search( r"^\s*(?:typedef\s+)?(?:struct|class)\s+\w+", declaration @@ -1844,21 +1847,93 @@ def render_numpy_field_names(value: str) -> str: def render_table_description(value: str) -> str: - paragraphs: list[str] = [] + paragraphs: list[list[str]] = [] current: list[str] = [] for raw_line in value.splitlines(): stripped = raw_line.strip() if not stripped: if current: - paragraphs.append(" ".join(current)) + paragraphs.append(current) current = [] continue current.append(stripped) if current: - paragraphs.append(" ".join(current)) - return "

".join( - escape_text(paragraph) for paragraph in paragraphs - ) + paragraphs.append(current) + + rendered: list[str] = [] + for paragraph in paragraphs: + normalized = normalize_description_lines(paragraph) + if any(DOXYGEN_LIST_ITEM_RE.match(line) for line in normalized): + rendered.append( + "
".join(escape_text(line) for line in normalized) + ) + else: + rendered.append(escape_text(" ".join(normalized))) + return "

".join(rendered) + + +def normalize_description_lines(raw_lines: list[str]) -> list[str]: + lines: list[str] = [] + paragraph: list[str] = [] + in_list = False + + for raw_line in raw_lines: + line = raw_line.strip() + if DOXYGEN_LIST_ITEM_RE.match(line): + if paragraph: + lines.append(" ".join(paragraph)) + paragraph = [] + lines.append(line) + in_list = True + continue + + if in_list and lines: + lines[-1] = append_sentence(lines[-1], line) + continue + + paragraph.append(line) + + if paragraph: + lines.append(" ".join(paragraph)) + return lines + + +def render_doxygen_details(raw_lines: list[str]) -> list[str]: + lines: list[str] = [] + paragraph: list[str] = [] + in_list = False + + def flush_paragraph() -> None: + nonlocal paragraph + if paragraph: + lines.append(escape_text(" ".join(paragraph))) + paragraph = [] + + for raw_line in raw_lines: + stripped = raw_line.strip() + if not stripped: + flush_paragraph() + if lines and lines[-1] != "": + lines.append("") + in_list = False + continue + + if DOXYGEN_LIST_ITEM_RE.match(stripped): + flush_paragraph() + if lines and lines[-1] != "" and not in_list: + lines.append("") + lines.append(escape_text(stripped)) + in_list = True + continue + + if in_list and lines and lines[-1] != "": + lines[-1] = f"{lines[-1]} {escape_text(stripped)}" + continue + + paragraph.append(stripped) + + flush_paragraph() + return trim_blank_lines(lines) def render_doc_lines(raw_lines: list[str]) -> list[str]: @@ -3078,7 +3153,7 @@ def render_param_table( description = ( f"{description} Default: `{param['default']}`.".strip() ) - row.append(escape_text(description)) + row.append(render_table_description(description)) lines.append("| " + " | ".join(row) + " |") return lines From e31b03ef454924bc38be916bd0b65d3b2dbe34df Mon Sep 17 00:00:00 2001 From: "Corey J. Nolet" Date: Thu, 7 May 2026 13:05:24 -0400 Subject: [PATCH 006/129] Fix native API fields tables --- fern/pages/c_api/c-api-cluster-kmeans.md | 6 +- fern/pages/c_api/c-api-neighbors-cagra.md | 34 +-- fern/pages/c_api/c-api-neighbors-hnsw.md | 10 +- fern/pages/c_api/c-api-neighbors-ivf-flat.md | 6 +- fern/pages/c_api/c-api-neighbors-ivf-pq.md | 24 +-- .../c_api/c-api-neighbors-tiered-index.md | 4 +- fern/pages/c_api/c-api-neighbors-vamana.md | 6 +- fern/pages/c_api/c-api-preprocessing-pca.md | 4 +- .../c-api-preprocessing-quantize-binary.md | 4 +- .../c_api/c-api-preprocessing-quantize-pq.md | 12 +- .../c-api-preprocessing-quantize-scalar.md | 6 - .../cpp_api/cpp-api-cluster-agglomerative.md | 8 +- fern/pages/cpp_api/cpp-api-cluster-kmeans.md | 11 +- .../pages/cpp_api/cpp-api-cluster-spectral.md | 2 +- .../cpp-api-neighbors-all-neighbors.md | 6 +- .../cpp_api/cpp-api-neighbors-brute-force.md | 7 - fern/pages/cpp_api/cpp-api-neighbors-cagra.md | 18 +- .../cpp-api-neighbors-dynamic-batching.md | 6 +- fern/pages/cpp_api/cpp-api-neighbors-hnsw.md | 6 +- .../pages/cpp_api/cpp-api-neighbors-ivf-pq.md | 8 +- .../cpp_api/cpp-api-neighbors-nn-descent.md | 34 +-- fern/pages/cpp_api/cpp-api-neighbors-scann.md | 2 +- .../pages/cpp_api/cpp-api-neighbors-vamana.md | 6 +- .../cpp-api-preprocessing-quantize-pq.md | 15 +- .../cpp-api-preprocessing-quantize-scalar.md | 2 +- fern/scripts/generate_api_reference.py | 199 ++++++++++++++---- 26 files changed, 266 insertions(+), 180 deletions(-) diff --git a/fern/pages/c_api/c-api-cluster-kmeans.md b/fern/pages/c_api/c-api-cluster-kmeans.md index 3a4497b3ec..65cd21ff4c 100644 --- a/fern/pages/c_api/c-api-cluster-kmeans.md +++ b/fern/pages/c_api/c-api-cluster-kmeans.md @@ -41,17 +41,17 @@ struct cuvsKMeansParams { ... } ; | Name | Type | Description | | --- | --- | --- | | `n_clusters` | `int` | The number of clusters to form as well as the number of centroids to generate (default:8). | -| `init` | `cuvsKMeansInitMethod` | Method for initialization, defaults to k-means++: | +| `init` | `cuvsKMeansInitMethod` | Method for initialization, defaults to k-means++:
- cuvsKMeansInitMethod::KMeansPlusPlus (k-means++): Use scalable k-means++ algorithm to select the initial cluster centers.
- cuvsKMeansInitMethod::Random (random): Choose 'n_clusters' observations (rows) at random from the input data for the initial centroids.
- cuvsKMeansInitMethod::Array (ndarray): Use 'centroids' as initial cluster centers. | | `max_iter` | `int` | Maximum number of iterations of the k-means algorithm for a single run. | | `tol` | `double` | Relative tolerance with regards to inertia to declare convergence. | | `n_init` | `int` | Number of instance k-means algorithm will be run with different seeds. | | `oversampling_factor` | `double` | Oversampling factor for use in the k-means\|\| algorithm | -| `batch_samples` | `int` | batch_samples and batch_centroids are used to tile 1NN computation which is | +| `batch_samples` | `int` | batch_samples and batch_centroids are used to tile 1NN computation which is useful to optimize/control the memory footprint Default tile is [batch_samples x n_clusters] i.e. when batch_centroids is 0 then don't tile the centroids | | `batch_centroids` | `int` | if 0 then batch_centroids = n_clusters | | `inertia_check` | `bool` | Check inertia during iterations for early convergence. | | `hierarchical` | `bool` | Whether to use hierarchical (balanced) kmeans or not | | `hierarchical_n_iters` | `int` | For hierarchical k-means , defines the number of training iterations | -| `streaming_batch_size` | `int64_t` | Number of samples to process per GPU batch for the batched (host-data) API. | +| `streaming_batch_size` | `int64_t` | Number of samples to process per GPU batch for the batched (host-data) API. When set to 0, defaults to n_samples (process all at once). | | `metric` | `cuvsDistanceType` | | _Source: `c/include/cuvs/cluster/kmeans.h:43`_ diff --git a/fern/pages/c_api/c-api-neighbors-cagra.md b/fern/pages/c_api/c-api-neighbors-cagra.md index cc6c181695..6648552fa9 100644 --- a/fern/pages/c_api/c-api-neighbors-cagra.md +++ b/fern/pages/c_api/c-api-neighbors-cagra.md @@ -53,12 +53,12 @@ struct cuvsCagraCompressionParams { ... } ; | Name | Type | Description | | --- | --- | --- | -| `pq_bits` | `uint32_t` | The bit length of the vector element after compression by PQ. | -| `pq_dim` | `uint32_t` | The dimensionality of the vector after compression by PQ. | -| `vq_n_centers` | `uint32_t` | Vector Quantization (VQ) codebook size - number of "coarse cluster centers". | +| `pq_bits` | `uint32_t` | The bit length of the vector element after compression by PQ. Possible values: [4, 5, 6, 7, 8]. Hint: the smaller the 'pq_bits', the smaller the index size and the better the search performance, but the lower the recall. | +| `pq_dim` | `uint32_t` | The dimensionality of the vector after compression by PQ. When zero, an optimal value is selected using a heuristic. TODO: at the moment `dim` must be a multiple `pq_dim`. | +| `vq_n_centers` | `uint32_t` | Vector Quantization (VQ) codebook size - number of "coarse cluster centers". When zero, an optimal value is selected using a heuristic. | | `kmeans_n_iters` | `uint32_t` | The number of iterations searching for kmeans centers (both VQ & PQ phases). | -| `vq_kmeans_trainset_fraction` | `double` | The fraction of data to use during iterative kmeans building (VQ phase). | -| `pq_kmeans_trainset_fraction` | `double` | The fraction of data to use during iterative kmeans building (PQ phase). | +| `vq_kmeans_trainset_fraction` | `double` | The fraction of data to use during iterative kmeans building (VQ phase). When zero, an optimal value is selected using a heuristic. | +| `pq_kmeans_trainset_fraction` | `double` | The fraction of data to use during iterative kmeans building (PQ phase). When zero, an optimal value is selected using a heuristic. | _Source: `c/include/cuvs/neighbors/cagra.h:82`_ @@ -80,12 +80,12 @@ struct cuvsAceParams { ... } ; | Name | Type | Description | | --- | --- | --- | -| `npartitions` | `size_t` | Number of partitions for ACE (Augmented Core Extraction) partitioned build. | -| `ef_construction` | `size_t` | The index quality for the ACE build. | -| `build_dir` | `const char*` | Directory to store ACE build artifacts (e.g., KNN graph, optimized graph). | -| `use_disk` | `bool` | Whether to use disk-based storage for ACE build. | -| `max_host_memory_gb` | `double` | Maximum host memory to use for ACE build in GiB. | -| `max_gpu_memory_gb` | `double` | Maximum GPU memory to use for ACE build in GiB. | +| `npartitions` | `size_t` | Number of partitions for ACE (Augmented Core Extraction) partitioned build. When set to 0 (default), the number of partitions is automatically derived based on available host and GPU memory to maximize partition size while ensuring the build fits in memory. Small values might improve recall but potentially degrade performance and increase memory usage. Partitions should not be too small to prevent issues in KNN graph construction. The partition size is on average 2 * (n_rows / npartitions) * dim * sizeof(T). 2 is because of the core and augmented vectors. Please account for imbalance in the partition sizes (up to 3x in our tests). If the specified number of partitions results in partitions that exceed available memory, the value will be automatically increased to fit memory constraints and a warning will be issued. | +| `ef_construction` | `size_t` | The index quality for the ACE build. Bigger values increase the index quality. At some point, increasing this will no longer improve the quality. | +| `build_dir` | `const char*` | Directory to store ACE build artifacts (e.g., KNN graph, optimized graph). Used when `use_disk` is true or when the graph does not fit in host and GPU memory. This should be the fastest disk in the system and hold enough space for twice the dataset, final graph, and label mapping. | +| `use_disk` | `bool` | Whether to use disk-based storage for ACE build. When true, enables disk-based operations for memory-efficient graph construction. | +| `max_host_memory_gb` | `double` | Maximum host memory to use for ACE build in GiB. When set to 0 (default), uses available host memory. When set to a positive value, limits host memory usage to the specified amount. Useful for testing or when running alongside other memory-intensive processes. | +| `max_gpu_memory_gb` | `double` | Maximum GPU memory to use for ACE build in GiB. When set to 0 (default), uses available GPU memory. When set to a positive value, limits GPU memory usage to the specified amount. Useful for testing or when running alongside other memory-intensive processes. | _Source: `c/include/cuvs/neighbors/cagra.h:136`_ @@ -106,8 +106,8 @@ struct cuvsCagraIndexParams { ... } ; | `graph_degree` | `size_t` | Degree of output graph. | | `build_algo` | `enum cuvsCagraGraphBuildAlgo` | ANN algorithm to build knn graph. | | `nn_descent_niter` | `size_t` | Number of Iterations to run if building with NN_DESCENT | -| `compression` | `cuvsCagraCompressionParams_t` | Optional: specify compression parameters if compression is desired. | -| `graph_build_params` | `void*` | Optional: specify graph build params based on build_algo | +| `compression` | `cuvsCagraCompressionParams_t` | Optional: specify compression parameters if compression is desired. NOTE: this is experimental new API, consider it unsafe. | +| `graph_build_params` | `void*` | Optional: specify graph build params based on build_algo
- IVF_PQ: cuvsIvfPqParams_t
- ACE: cuvsAceParams_t
- Others: nullptr | _Source: `c/include/cuvs/neighbors/cagra.h:201`_ @@ -295,7 +295,7 @@ struct cuvsCagraExtendParams { ... } ; | Name | Type | Description | | --- | --- | --- | -| `max_chunk_size` | `uint32_t` | The additional dataset is divided into chunks and added to the graph. This is the knob to | +| `max_chunk_size` | `uint32_t` | The additional dataset is divided into chunks and added to the graph. This is the knob to adjust the tradeoff between the recall and operation throughput. Large chunk sizes can result in high throughput, but use more working memory (O(max_chunk_size*degree^2)). This can also degrade recall because no edges are added between the nodes in the same chunk. Auto select when 0. | _Source: `c/include/cuvs/neighbors/cagra.h:312`_ @@ -432,11 +432,11 @@ struct cuvsCagraSearchParams { ... } ; | Name | Type | Description | | --- | --- | --- | | `max_queries` | `size_t` | Maximum number of queries to search at the same time (batch size). Auto select when 0. | -| `itopk_size` | `size_t` | Number of intermediate search results retained during the search. | +| `itopk_size` | `size_t` | Number of intermediate search results retained during the search. This is the main knob to adjust trade off between accuracy and search speed. Higher values improve the search accuracy. | | `max_iterations` | `size_t` | Upper limit of search iterations. Auto select when 0. | | `algo` | `enum cuvsCagraSearchAlgo` | Which search implementation to use. | | `team_size` | `size_t` | Number of threads used to calculate a single distance. 4, 8, 16, or 32. | -| `search_width` | `size_t` | Number of graph nodes to select as the starting point for the search in each iteration. aka | +| `search_width` | `size_t` | Number of graph nodes to select as the starting point for the search in each iteration. aka search width? | | `min_iterations` | `size_t` | Lower limit of search iterations. | | `thread_block_size` | `size_t` | Thread block size. 0, 64, 128, 256, 512, 1024. Auto selection when 0. | | `hashmap_mode` | `enum cuvsCagraHashMode` | Hashmap type. Auto selection when AUTO. | @@ -446,7 +446,7 @@ struct cuvsCagraSearchParams { ... } ; | `rand_xor_mask` | `uint64_t` | Bit mask used for initial random seed node selection. | | `persistent` | `bool` | Whether to use the persistent version of the kernel (only SINGLE_CTA is supported a.t.m.) | | `persistent_lifetime` | `float` | Persistent kernel: time in seconds before the kernel stops if no requests received. | -| `persistent_device_usage` | `float` | Set the fraction of maximum grid size used by persistent kernel. | +| `persistent_device_usage` | `float` | Set the fraction of maximum grid size used by persistent kernel. Value 1.0 means the kernel grid size is maximum possible for the selected device. The value must be greater than 0.0 and not greater than 1.0. One may need to run other kernels alongside this persistent kernel. This parameter can be used to reduce the grid size of the persistent kernel to leave a few SMs idle. Note: running any other work on GPU alongside with the persistent kernel makes the setup fragile.
- Running another kernel in another thread usually works, but no progress guaranteed
- Any CUDA allocations block the context (this issue may be obscured by using pools)
- Memory copies to not-pinned host memory may block the context Even when we know there are no other kernels working at the same time, setting kDeviceUsage to 1.0 surprisingly sometimes hurts performance. Proceed with care. If you suspect this is an issue, you can reduce this number to ~0.9 without a significant impact on the throughput. | _Source: `c/include/cuvs/neighbors/cagra.h:371`_ diff --git a/fern/pages/c_api/c-api-neighbors-hnsw.md b/fern/pages/c_api/c-api-neighbors-hnsw.md index ff05f0976c..a721b5b3b2 100644 --- a/fern/pages/c_api/c-api-neighbors-hnsw.md +++ b/fern/pages/c_api/c-api-neighbors-hnsw.md @@ -47,11 +47,11 @@ struct cuvsHnswAceParams { ... } ; | Name | Type | Description | | --- | --- | --- | -| `npartitions` | `size_t` | Number of partitions for ACE partitioned build. | -| `build_dir` | `const char*` | Directory to store ACE build artifacts (e.g., KNN graph, optimized graph). | -| `use_disk` | `bool` | Whether to use disk-based storage for ACE build. | -| `max_host_memory_gb` | `double` | Maximum host memory to use for ACE build in GiB. | -| `max_gpu_memory_gb` | `double` | Maximum GPU memory to use for ACE build in GiB. | +| `npartitions` | `size_t` | Number of partitions for ACE partitioned build. When set to 0 (default), the number of partitions is automatically derived based on available host and GPU memory to maximize partition size while ensuring the build fits in memory. Small values might improve recall but potentially degrade performance and increase memory usage. The partition size is on average 2 * (n_rows / npartitions) * dim * sizeof(T). 2 is because of the core and augmented vectors. Please account for imbalance in the partition sizes (up to 3x in our tests). If the specified number of partitions results in partitions that exceed available memory, the value will be automatically increased to fit memory constraints and a warning will be issued. | +| `build_dir` | `const char*` | Directory to store ACE build artifacts (e.g., KNN graph, optimized graph). Used when `use_disk` is true or when the graph does not fit in memory. | +| `use_disk` | `bool` | Whether to use disk-based storage for ACE build. When true, enables disk-based operations for memory-efficient graph construction. | +| `max_host_memory_gb` | `double` | Maximum host memory to use for ACE build in GiB. When set to 0 (default), uses available host memory. Useful for testing or when running alongside other memory-intensive processes. | +| `max_gpu_memory_gb` | `double` | Maximum GPU memory to use for ACE build in GiB. When set to 0 (default), uses available GPU memory. Useful for testing or when running alongside other memory-intensive processes. | _Source: `c/include/cuvs/neighbors/hnsw.h:46`_ diff --git a/fern/pages/c_api/c-api-neighbors-ivf-flat.md b/fern/pages/c_api/c-api-neighbors-ivf-flat.md index f2ebeb6813..e9382fbb09 100644 --- a/fern/pages/c_api/c-api-neighbors-ivf-flat.md +++ b/fern/pages/c_api/c-api-neighbors-ivf-flat.md @@ -24,12 +24,12 @@ struct cuvsIvfFlatIndexParams { ... } ; | --- | --- | --- | | `metric` | `cuvsDistanceType` | Distance type. | | `metric_arg` | `float` | The argument used by some distance metrics. | -| `add_data_on_build` | `bool` | Whether to add the dataset content to the index, i.e.: | +| `add_data_on_build` | `bool` | Whether to add the dataset content to the index, i.e.:
- `true` means the index is filled with the dataset vectors and ready to search after calling `build`.
- `false` means `build` only trains the underlying model (e.g. quantizer or clustering), but the index is left empty; you'd need to call `extend` on the index afterwards to populate it. | | `n_lists` | `uint32_t` | The number of inverted lists (clusters) | | `kmeans_n_iters` | `uint32_t` | The number of iterations searching for kmeans centers (index building). | | `kmeans_trainset_fraction` | `double` | The fraction of data to use during iterative kmeans building. | -| `adaptive_centers` | `bool` | By default (adaptive_centers = false), the cluster centers are trained in `ivf_flat::build`, | -| `conservative_memory_allocation` | `bool` | By default, the algorithm allocates more space than necessary for individual clusters | +| `adaptive_centers` | `bool` | By default (adaptive_centers = false), the cluster centers are trained in `ivf_flat::build`, and never modified in `ivf_flat::extend`. As a result, you may need to retrain the index from scratch after invoking (`ivf_flat::extend`) a few times with new data, the distribution of which is no longer representative of the original training set. The alternative behavior (adaptive_centers = true) is to update the cluster centers for new data when it is added. In this case, `index.centers()` are always exactly the centroids of the data in the corresponding clusters. The drawback of this behavior is that the centroids depend on the order of adding new data (through the classification of the added data); that is, `index.centers()` "drift" together with the changing distribution of the newly added data. | +| `conservative_memory_allocation` | `bool` | By default, the algorithm allocates more space than necessary for individual clusters (`list_data`). This allows to amortize the cost of memory allocation and reduce the number of data copies during repeated calls to `extend` (extending the database). The alternative is the conservative allocation behavior; when enabled, the algorithm always allocates the minimum amount of memory required to store the given number of records. Set this flag to `true` if you prefer to use as little GPU memory for the database as possible. | _Source: `c/include/cuvs/neighbors/ivf_flat.h:27`_ diff --git a/fern/pages/c_api/c-api-neighbors-ivf-pq.md b/fern/pages/c_api/c-api-neighbors-ivf-pq.md index 259301ba29..b9209c959a 100644 --- a/fern/pages/c_api/c-api-neighbors-ivf-pq.md +++ b/fern/pages/c_api/c-api-neighbors-ivf-pq.md @@ -58,17 +58,17 @@ struct cuvsIvfPqIndexParams { ... } ; | --- | --- | --- | | `metric` | `cuvsDistanceType` | Distance type. | | `metric_arg` | `float` | The argument used by some distance metrics. | -| `add_data_on_build` | `bool` | Whether to add the dataset content to the index, i.e.: | -| `n_lists` | `uint32_t` | The number of inverted lists (clusters) | +| `add_data_on_build` | `bool` | Whether to add the dataset content to the index, i.e.:
- `true` means the index is filled with the dataset vectors and ready to search after calling `build`.
- `false` means `build` only trains the underlying model (e.g. quantizer or clustering), but the index is left empty; you'd need to call `extend` on the index afterwards to populate it. | +| `n_lists` | `uint32_t` | The number of inverted lists (clusters) Hint: the number of vectors per cluster (`n_rows/n_lists`) should be approximately 1,000 to 10,000. | | `kmeans_n_iters` | `uint32_t` | The number of iterations searching for kmeans centers (index building). | | `kmeans_trainset_fraction` | `double` | The fraction of data to use during iterative kmeans building. | -| `pq_bits` | `uint32_t` | The bit length of the vector element after compression by PQ. | -| `pq_dim` | `uint32_t` | The dimensionality of the vector after compression by PQ. When zero, an optimal value is | +| `pq_bits` | `uint32_t` | The bit length of the vector element after compression by PQ. Possible values: [4, 5, 6, 7, 8]. Hint: the smaller the 'pq_bits', the smaller the index size and the better the search performance, but the lower the recall. | +| `pq_dim` | `uint32_t` | The dimensionality of the vector after compression by PQ. When zero, an optimal value is selected using a heuristic. NB: `pq_dim * pq_bits` must be a multiple of 8. Hint: a smaller 'pq_dim' results in a smaller index size and better search performance, but lower recall. If 'pq_bits' is 8, 'pq_dim' can be set to any number, but multiple of 8 are desirable for good performance. If 'pq_bits' is not 8, 'pq_dim' should be a multiple of 8. For good performance, it is desirable that 'pq_dim' is a multiple of 32. Ideally, 'pq_dim' should be also a divisor of the dataset dim. | | `codebook_kind` | `enum cuvsIvfPqCodebookGen` | How PQ codebooks are created. | -| `force_random_rotation` | `bool` | Apply a random rotation matrix on the input data and queries even if `dim % pq_dim == 0`. | -| `conservative_memory_allocation` | `bool` | By default, the algorithm allocates more space than necessary for individual clusters | -| `max_train_points_per_pq_code` | `uint32_t` | The max number of data points to use per PQ code during PQ codebook training. Using more data | -| `codes_layout` | `enum cuvsIvfPqListLayout` | Memory layout of the IVF-PQ list data. | +| `force_random_rotation` | `bool` | Apply a random rotation matrix on the input data and queries even if `dim % pq_dim == 0`. Note: if `dim` is not multiple of `pq_dim`, a random rotation is always applied to the input data and queries to transform the working space from `dim` to `rot_dim`, which may be slightly larger than the original space and and is a multiple of `pq_dim` (`rot_dim % pq_dim == 0`). However, this transform is not necessary when `dim` is multiple of `pq_dim` (`dim == rot_dim`, hence no need in adding "extra" data columns / features). By default, if `dim == rot_dim`, the rotation transform is initialized with the identity matrix. When `force_random_rotation == true`, a random orthogonal transform matrix is generated regardless of the values of `dim` and `pq_dim`. | +| `conservative_memory_allocation` | `bool` | By default, the algorithm allocates more space than necessary for individual clusters (`list_data`). This allows to amortize the cost of memory allocation and reduce the number of data copies during repeated calls to `extend` (extending the database). The alternative is the conservative allocation behavior; when enabled, the algorithm always allocates the minimum amount of memory required to store the given number of records. Set this flag to `true` if you prefer to use as little GPU memory for the database as possible. | +| `max_train_points_per_pq_code` | `uint32_t` | The max number of data points to use per PQ code during PQ codebook training. Using more data points per PQ code may increase the quality of PQ codebook but may also increase the build time. The parameter is applied to both PQ codebook generation methods, i.e., PER_SUBSPACE and PER_CLUSTER. In both cases, we will use `pq_book_size * max_train_points_per_pq_code` training points to train each codebook. | +| `codes_layout` | `enum cuvsIvfPqListLayout` | Memory layout of the IVF-PQ list data.
- CUVS_IVF_PQ_LIST_LAYOUT_FLAT: Codes are stored contiguously, one vector's codes after another.
- CUVS_IVF_PQ_LIST_LAYOUT_INTERLEAVED: Codes are interleaved for optimized search performance. This is the default and recommended for search workloads. | _Source: `c/include/cuvs/neighbors/ivf_pq.h:44`_ @@ -133,11 +133,11 @@ struct cuvsIvfPqSearchParams { ... } ; | Name | Type | Description | | --- | --- | --- | | `n_probes` | `uint32_t` | The number of clusters to search. | -| `lut_dtype` | `cudaDataType_t` | Data type of look up table to be created dynamically at search time. | -| `internal_distance_dtype` | `cudaDataType_t` | Storage data type for distance/similarity computed at search time. | -| `coarse_search_dtype` | `cudaDataType_t` | The data type to use as the GEMM element type when searching the clusters to probe. | +| `lut_dtype` | `cudaDataType_t` | Data type of look up table to be created dynamically at search time. Possible values: [CUDA_R_32F, CUDA_R_16F, CUDA_R_8U] The use of low-precision types reduces the amount of shared memory required at search time, so fast shared memory kernels can be used even for datasets with large dimansionality. Note that the recall is slightly degraded when low-precision type is selected. | +| `internal_distance_dtype` | `cudaDataType_t` | Storage data type for distance/similarity computed at search time. Possible values: [CUDA_R_16F, CUDA_R_32F] If the performance limiter at search time is device memory access, selecting FP16 will improve performance slightly. | +| `coarse_search_dtype` | `cudaDataType_t` | The data type to use as the GEMM element type when searching the clusters to probe. Possible values: [CUDA_R_8I, CUDA_R_16F, CUDA_R_32F].
- Legacy default: CUDA_R_32F (float)
- Recommended for performance: CUDA_R_16F (half)
- Experimental/low-precision: CUDA_R_8I (int8_t) (WARNING: int8_t variant degrades recall unless data is normalized and low-dimensional) | | `max_internal_batch_size` | `uint32_t` | Set the internal batch size to improve GPU utilization at the cost of larger memory footprint. | -| `preferred_shmem_carveout` | `double` | Preferred fraction of SM's unified memory / L1 cache to be used as shared memory. | +| `preferred_shmem_carveout` | `double` | Preferred fraction of SM's unified memory / L1 cache to be used as shared memory. Possible values: [0.0 - 1.0] as a fraction of the `sharedMemPerMultiprocessor`. One wants to increase the carveout to make sure a good GPU occupancy for the main search kernel, but not to keep it too high to leave some memory to be used as L1 cache. Note, this value is interpreted only as a hint. Moreover, a GPU usually allows only a fixed set of cache configurations, so the provided value is rounded up to the nearest configuration. Refer to the NVIDIA tuning guide for the target GPU architecture. Note, this is a low-level tuning parameter that can have drastic negative effects on the search performance if tweaked incorrectly. | _Source: `c/include/cuvs/neighbors/ivf_pq.h:165`_ diff --git a/fern/pages/c_api/c-api-neighbors-tiered-index.md b/fern/pages/c_api/c-api-neighbors-tiered-index.md index 1e33618116..39461843f0 100644 --- a/fern/pages/c_api/c-api-neighbors-tiered-index.md +++ b/fern/pages/c_api/c-api-neighbors-tiered-index.md @@ -70,8 +70,8 @@ struct cuvsTieredIndexParams { ... } ; | --- | --- | --- | | `metric` | `cuvsDistanceType` | Distance type. | | `algo` | `cuvsTieredIndexANNAlgo` | The type of ANN algorithm we are using | -| `min_ann_rows` | `int64_t` | The minimum number of rows necessary in the index to create an | -| `create_ann_index_on_extend` | `bool` | Whether or not to create a new ann index on extend, if the number | +| `min_ann_rows` | `int64_t` | The minimum number of rows necessary in the index to create an ann index | +| `create_ann_index_on_extend` | `bool` | Whether or not to create a new ann index on extend, if the number of rows in the incremental (bfknn) portion is above min_ann_rows | | `cagra_params` | `cuvsCagraIndexParams_t` | Optional parameters for building a cagra index | | `ivf_flat_params` | `cuvsIvfFlatIndexParams_t` | Optional parameters for building a ivf_flat index | | `ivf_pq_params` | `cuvsIvfPqIndexParams_t` | Optional parameters for building a ivf-pq index | diff --git a/fern/pages/c_api/c-api-neighbors-vamana.md b/fern/pages/c_api/c-api-neighbors-vamana.md index be9f596484..37792781ee 100644 --- a/fern/pages/c_api/c-api-neighbors-vamana.md +++ b/fern/pages/c_api/c-api-neighbors-vamana.md @@ -25,11 +25,11 @@ struct cuvsVamanaIndexParams { ... } ; | Name | Type | Description | | --- | --- | --- | | `metric` | `cuvsDistanceType` | Distance type. | -| `graph_degree` | `uint32_t` | Maximum degree of output graph corresponds to the R parameter in the original Vamana | -| `visited_size` | `uint32_t` | Maximum number of visited nodes per search corresponds to the L parameter in the Vamana | +| `graph_degree` | `uint32_t` | Maximum degree of output graph corresponds to the R parameter in the original Vamana literature. | +| `visited_size` | `uint32_t` | Maximum number of visited nodes per search corresponds to the L parameter in the Vamana literature * | | `vamana_iters` | `float` | Number of Vamana vector insertion iterations (each iteration inserts all vectors). | | `alpha` | `float` | Alpha for pruning parameter | -| `max_fraction` | `float` | Maximum fraction of dataset inserted per batch. * | +| `max_fraction` | `float` | Maximum fraction of dataset inserted per batch. * Larger max batch decreases graph quality, but improves speed | | `batch_base` | `float` | Base of growth rate of batch sizes * | | `queue_size` | `uint32_t` | Size of candidate queue structure - should be (2^x)-1 | | `reverse_batchsize` | `uint32_t` | Max batchsize of reverse edge processing (reduces memory footprint) | diff --git a/fern/pages/c_api/c-api-preprocessing-pca.md b/fern/pages/c_api/c-api-preprocessing-pca.md index 773f207dde..5439ef6033 100644 --- a/fern/pages/c_api/c-api-preprocessing-pca.md +++ b/fern/pages/c_api/c-api-preprocessing-pca.md @@ -40,8 +40,8 @@ struct cuvsPcaParams { ... } ; | Name | Type | Description | | --- | --- | --- | | `n_components` | `int` | Number of principal components to keep. | -| `copy` | `bool` | If false, data passed to fit are overwritten and running fit(X).transform(X) will | -| `whiten` | `bool` | When true the component vectors are multiplied by the square root of n_samples and then | +| `copy` | `bool` | If false, data passed to fit are overwritten and running fit(X).transform(X) will not yield the expected results; use fit_transform(X) instead. | +| `whiten` | `bool` | When true the component vectors are multiplied by the square root of n_samples and then divided by the singular values to ensure uncorrelated outputs with unit component-wise variances. | | `algorithm` | `enum cuvsPcaSolver` | Solver algorithm to use. | | `tol` | `float` | Tolerance for singular values (used by Jacobi solver). | | `n_iterations` | `int` | Number of iterations for the power method (Jacobi solver). | diff --git a/fern/pages/c_api/c-api-preprocessing-quantize-binary.md b/fern/pages/c_api/c-api-preprocessing-quantize-binary.md index 5e1655b031..5377ebc453 100644 --- a/fern/pages/c_api/c-api-preprocessing-quantize-binary.md +++ b/fern/pages/c_api/c-api-preprocessing-quantize-binary.md @@ -42,8 +42,8 @@ struct cuvsBinaryQuantizerParams { ... } ; | Name | Type | Description | | --- | --- | --- | -| `threshold` | `enum` | | -| `sampling_ratio` | `float` | | +| `threshold` | `/* * specifies the threshold to set a bit in cuvsBinaryQuantizerTransform */ enum` | | +| `sampling_ratio` | `/* * specifies the sampling ratio */` | | _Source: `c/include/cuvs/preprocessing/quantize/binary.h:35`_ diff --git a/fern/pages/c_api/c-api-preprocessing-quantize-pq.md b/fern/pages/c_api/c-api-preprocessing-quantize-pq.md index 791e7af240..3e61595e9c 100644 --- a/fern/pages/c_api/c-api-preprocessing-quantize-pq.md +++ b/fern/pages/c_api/c-api-preprocessing-quantize-pq.md @@ -22,14 +22,14 @@ struct cuvsProductQuantizerParams { ... } ; | Name | Type | Description | | --- | --- | --- | -| `pq_bits` | `uint32_t` | The bit length of the vector element after compression by PQ. | -| `pq_dim` | `uint32_t` | The dimensionality of the vector after compression by PQ. | -| `use_subspaces` | `bool` | Whether to use subspaces for product quantization (PQ). | -| `use_vq` | `bool` | Whether to use Vector Quantization (KMeans) before product quantization (PQ). | -| `vq_n_centers` | `uint32_t` | Vector Quantization (VQ) codebook size - number of "coarse cluster centers". | +| `pq_bits` | `uint32_t` | The bit length of the vector element after compression by PQ. Possible values: within [4, 16]. Hint: the smaller the 'pq_bits', the smaller the index size and the better the search performance, but the lower the recall. | +| `pq_dim` | `uint32_t` | The dimensionality of the vector after compression by PQ. When zero, an optimal value is selected using a heuristic. TODO: at the moment `dim` must be a multiple `pq_dim`. | +| `use_subspaces` | `bool` | Whether to use subspaces for product quantization (PQ). When true, one PQ codebook is used for each subspace. Otherwise, a single PQ codebook is used. | +| `use_vq` | `bool` | Whether to use Vector Quantization (KMeans) before product quantization (PQ). When true, VQ is used before PQ. When false, only product quantization is used. | +| `vq_n_centers` | `uint32_t` | Vector Quantization (VQ) codebook size - number of "coarse cluster centers". When zero, an optimal value is selected using a heuristic. When one, only product quantization is used. | | `kmeans_n_iters` | `uint32_t` | The number of iterations searching for kmeans centers (both VQ & PQ phases). | | `pq_kmeans_type` | `cuvsKMeansType` | The type of kmeans algorithm to use for PQ training. | -| `max_train_points_per_pq_code` | `uint32_t` | The max number of data points to use per PQ code during PQ codebook training. Using more data | +| `max_train_points_per_pq_code` | `uint32_t` | The max number of data points to use per PQ code during PQ codebook training. Using more data points per PQ code may increase the quality of PQ codebook but may also increase the build time. We will use `pq_n_centers * max_train_points_per_pq_code` training points to train each PQ codebook. | | `max_train_points_per_vq_cluster` | `uint32_t` | The max number of data points to use per VQ cluster. | _Source: `c/include/cuvs/preprocessing/quantize/pq.h:24`_ diff --git a/fern/pages/c_api/c-api-preprocessing-quantize-scalar.md b/fern/pages/c_api/c-api-preprocessing-quantize-scalar.md index 2dae942b6c..3bee4df133 100644 --- a/fern/pages/c_api/c-api-preprocessing-quantize-scalar.md +++ b/fern/pages/c_api/c-api-preprocessing-quantize-scalar.md @@ -18,12 +18,6 @@ Scalar quantizer parameters. struct cuvsScalarQuantizerParams { ... } ; ``` -**Fields** - -| Name | Type | Description | -| --- | --- | --- | -| `quantile` | `float` | | - _Source: `c/include/cuvs/preprocessing/quantize/scalar.h:23`_ ### cuvsScalarQuantizerParamsCreate diff --git a/fern/pages/cpp_api/cpp-api-cluster-agglomerative.md b/fern/pages/cpp_api/cpp-api-cluster-agglomerative.md index 01bfc70ee4..827cb7809f 100644 --- a/fern/pages/cpp_api/cpp-api-cluster-agglomerative.md +++ b/fern/pages/cpp_api/cpp-api-cluster-agglomerative.md @@ -80,8 +80,8 @@ struct distance_params { ... } ; | Name | Type | Description | | --- | --- | --- | -| `c` | `int` | a constant used when constructing linkage from knn graph. Allows the indirect control of k. | -| `dist_type` | `cuvs::cluster::agglomerative::Linkage` | strategy for constructing the linkage. PAIRWISE uses more memory but can be faster for smaller | +| `c` | `int` | a constant used when constructing linkage from knn graph. Allows the indirect control of k. The algorithm will set `k = log(n) + c` | +| `dist_type` | `cuvs::cluster::agglomerative::Linkage` | strategy for constructing the linkage. PAIRWISE uses more memory but can be faster for smaller datasets. KNN_GRAPH allows the memory usage to be controlled (using parameter c) | _Source: `cpp/include/cuvs/cluster/agglomerative.hpp:118`_ @@ -98,8 +98,8 @@ struct mutual_reachability_params { ... } ; | Name | Type | Description | | --- | --- | --- | | `min_samples` | `int` | this neighborhood will be selected for core distances. | -| `alpha` | `float` | weight applied when internal distance is chosen for mutual reachability (value of 1.0 disables | -| `cuvs::neighbors::all_neighbors::all_neighbors_params all_neighbors_params{ cuvs::neighbors::graph_build_params::brute_force_params{}}` | `cuvs::neighbors::all_neighbors::all_neighbors_params all_neighbors_params{ cuvs::neighbors::graph_build_params::brute_force_params{}}` | Parameters for building the mutual reachability graph using an underlying KNN algorithm. | +| `alpha` | `float` | weight applied when internal distance is chosen for mutual reachability (value of 1.0 disables the weighting) | +| `brute_force_params` | `cuvs::neighbors::all_neighbors::all_neighbors_params all_neighbors_params{ cuvs::neighbors::graph_build_params::` | Parameters for building the mutual reachability graph using an underlying KNN algorithm. The all-neighbors graph construction algorithm enables building the mutual reachability graph on datasets larger than device memory by:
1. Partitioning the dataset into overlapping clusters,
2. Computing local KNN graphs within each cluster, and
3. Merging the local graphs into a single global graph. Key fields:
- graph_build_params: Selects the KNN construction method (Brute Force or NN Descent) and controls algorithm-specific parameters.
- n_clusters: Number of partitions (batches) to split the data into. Larger `n_clusters` reduces memory usage but may reduce accuracy if `overlap_factor` is too low. Recommended starting value: `n_clusters = 4`. Increase progressively (4 → 8 → 16 ...) to reduce memory usage at the cost of some accuracy. This is independent of `overlap_factor` as long as `overlap_factor < n_clusters`.
- overlap_factor: Number of nearest clusters each data point is assigned to. Higher `overlap_factor` improves accuracy at the cost of memory and performance. Recommended starting value: `overlap_factor = 2`. Increase gradually (2 → 3 → 4 ...) for better accuracy with higher device memory usage.
- metric: Distance metric to use when computing nearest neighbors. | _Source: `cpp/include/cuvs/cluster/agglomerative.hpp:130`_ diff --git a/fern/pages/cpp_api/cpp-api-cluster-kmeans.md b/fern/pages/cpp_api/cpp-api-cluster-kmeans.md index e483225194..618f5a4721 100644 --- a/fern/pages/cpp_api/cpp-api-cluster-kmeans.md +++ b/fern/pages/cpp_api/cpp-api-cluster-kmeans.md @@ -22,21 +22,18 @@ struct params : base_params { ... } ; | Name | Type | Description | | --- | --- | --- | -| `KMeansPlusPlus,` | `KMeansPlusPlus,` | Sample the centroids using the kmeans++ strategy | -| `Random,` | `Random,` | Sample the centroids uniformly at random | -| `Array` | `Array` | User provides the array of initial centroids | | `n_clusters` | `int` | The number of clusters to form as well as the number of centroids to generate (default:8). | -| `init` | `InitMethod` | Method for initialization, defaults to k-means++: | +| `init` | `InitMethod` | Method for initialization, defaults to k-means++:
- InitMethod::KMeansPlusPlus (k-means++): Use scalable k-means++ algorithm to select the initial cluster centers.
- InitMethod::Random (random): Choose 'n_clusters' observations (rows) at random from the input data for the initial centroids.
- InitMethod::Array (ndarray): Use 'centroids' as initial cluster centers. | | `max_iter` | `int` | Maximum number of iterations of the k-means algorithm for a single run. | | `tol` | `double` | Relative tolerance with regards to inertia to declare convergence. | | `verbosity` | `rapids_logger::level_enum` | verbosity level. | -| `raft::random::RngState rng_state{0}` | `raft::random::RngState rng_state{0}` | Seed to the random number generator. | +| `rng_state` | `raft::random::RngState` | Seed to the random number generator. | | `n_init` | `int` | Number of instance k-means algorithm will be run with different seeds. | | `oversampling_factor` | `double` | Oversampling factor for use in the k-means\|\| algorithm | -| `batch_samples` | `int` | batch_samples and batch_centroids are used to tile 1NN computation which is | +| `batch_samples` | `int` | batch_samples and batch_centroids are used to tile 1NN computation which is useful to optimize/control the memory footprint Default tile is [batch_samples x n_clusters] i.e. when batch_centroids is 0 then don't tile the centroids NB: These parameters are unrelated to streaming_batch_size, which controls how many samples to transfer from host to device per batch when processing out-of-core data. | | `batch_centroids` | `int` | if 0 then batch_centroids = n_clusters | | `inertia_check` | `bool` | If true, check inertia during iterations for early convergence. | -| `streaming_batch_size` | `int64_t` | Number of samples to process per GPU batch when fitting with host data. | +| `streaming_batch_size` | `int64_t` | Number of samples to process per GPU batch when fitting with host data. When set to 0, defaults to n_samples (process all at once). Only used by the batched (host-data) code path and ignored by device-data overloads. Default: 0 (process all data at once). | _Source: `cpp/include/cuvs/cluster/kmeans.hpp:34`_ diff --git a/fern/pages/cpp_api/cpp-api-cluster-spectral.md b/fern/pages/cpp_api/cpp-api-cluster-spectral.md index acd988c90d..955c6330c7 100644 --- a/fern/pages/cpp_api/cpp-api-cluster-spectral.md +++ b/fern/pages/cpp_api/cpp-api-cluster-spectral.md @@ -27,7 +27,7 @@ struct params { ... } ; | `n_init` | `int` | Number of k-means runs with different centroid seeds | | `n_neighbors` | `int` | Number of nearest neighbors for constructing the connectivity graph | | `tolerance` | `float` | Tolerance for the eigenvalue solver | -| `raft::random::RngState rng_state{0}` | `raft::random::RngState rng_state{0}` | Random number generator state for reproducibility | +| `rng_state` | `raft::random::RngState` | Random number generator state for reproducibility | _Source: `cpp/include/cuvs/cluster/spectral.hpp:22`_ diff --git a/fern/pages/cpp_api/cpp-api-neighbors-all-neighbors.md b/fern/pages/cpp_api/cpp-api-neighbors-all-neighbors.md index abcb1849d4..5ddc069e2e 100644 --- a/fern/pages/cpp_api/cpp-api-neighbors-all-neighbors.md +++ b/fern/pages/cpp_api/cpp-api-neighbors-all-neighbors.md @@ -36,9 +36,9 @@ struct all_neighbors_params { ... } ; | Name | Type | Description | | --- | --- | --- | -| `graph_build_params` | `GraphBuildParams` | Parameters for knn graph building algorithm | -| `overlap_factor` | `size_t` | Number of nearest clusters each data point will be assigned to in the batching algorithm. | -| `n_clusters` | `size_t` | Number of total clusters (aka batches) to split the data into. If set to 1, algorithm creates | +| `graph_build_params` | `GraphBuildParams` | Parameters for knn graph building algorithm Approximate nearest neighbors methods or a brute force approach are supported to build the knn graph. Currently supported options are 'IVF-PQ', 'NN Descent', or 'Brute Force'. IVF-PQ is more accurate, but slower compared to NN Descent. Note that 'Brute Force' can also be approximate if n_clusters > 1. Set ivf_pq_params, nn_descent_params, or brute_force_params to select the graph build algorithm and control their parameters. | +| `overlap_factor` | `size_t` | Number of nearest clusters each data point will be assigned to in the batching algorithm. Start with `overlap_factor = 2` and gradually increase (2->3->4 ...) for better accuracy at the cost of device memory usage. | +| `n_clusters` | `size_t` | Number of total clusters (aka batches) to split the data into. If set to 1, algorithm creates an all-neighbors graph without batching. Start with `n_clusters = 4` and increase (4 → 8 → 16...) for less device memory usage at the cost of accuracy. This is independent from `overlap_factor` as long as `overlap_factor` < `n_clusters`. The ratio of `overlap_factor / n_clusters` determines device memory usage. Approximately `(overlap_factor / n_clusters) * num_rows_in_entire_data` number of rows will be put on device memory at once. E.g. between `(overlap_factor / n_clusters)` = 2/10 and 2/20, the latter will use less device memory. Larger `overlap_factor` results in better accuracy of the final all-neighbors knn graph. E.g. While using similar device memory, `(overlap_factor / n_clusters)` = 4/20 will have better accuracy than 2/10 at the cost of performance. | | `metric` | `cuvs::distance::DistanceType` | Metric used. | _Source: `cpp/include/cuvs/neighbors/all_neighbors.hpp:37`_ diff --git a/fern/pages/cpp_api/cpp-api-neighbors-brute-force.md b/fern/pages/cpp_api/cpp-api-neighbors-brute-force.md index bb15195473..6af771d611 100644 --- a/fern/pages/cpp_api/cpp-api-neighbors-brute-force.md +++ b/fern/pages/cpp_api/cpp-api-neighbors-brute-force.md @@ -570,13 +570,6 @@ Sparse Brute Force index search struct sparse_search_params { ... } ; ``` -**Fields** - -| Name | Type | Description | -| --- | --- | --- | -| `batch_size_index` | `int` | | -| `batch_size_query` | `int` | | - _Source: `cpp/include/cuvs/neighbors/brute_force.hpp:668`_ ## Bruteforce index serialize functions diff --git a/fern/pages/cpp_api/cpp-api-neighbors-cagra.md b/fern/pages/cpp_api/cpp-api-neighbors-cagra.md index 919965507d..ad573d328b 100644 --- a/fern/pages/cpp_api/cpp-api-neighbors-cagra.md +++ b/fern/pages/cpp_api/cpp-api-neighbors-cagra.md @@ -22,14 +22,14 @@ struct vpq_params { ... } ; | Name | Type | Description | | --- | --- | --- | -| `pq_bits` | `uint32_t` | The bit length of the vector element after compression by PQ. | -| `pq_dim` | `uint32_t` | The dimensionality of the vector after compression by PQ. | -| `vq_n_centers` | `uint32_t` | Vector Quantization (VQ) codebook size - number of "coarse cluster centers". | +| `pq_bits` | `uint32_t` | The bit length of the vector element after compression by PQ. Possible values: [4, 5, 6, 7, 8]. Hint: the smaller the 'pq_bits', the smaller the index size and the better the search performance, but the lower the recall. | +| `pq_dim` | `uint32_t` | The dimensionality of the vector after compression by PQ. When zero, an optimal value is selected using a heuristic. TODO: at the moment `dim` must be a multiple `pq_dim`. | +| `vq_n_centers` | `uint32_t` | Vector Quantization (VQ) codebook size - number of "coarse cluster centers". When zero, an optimal value is selected using a heuristic. | | `kmeans_n_iters` | `uint32_t` | The number of iterations searching for kmeans centers (both VQ & PQ phases). | -| `vq_kmeans_trainset_fraction` | `double` | The fraction of data to use during iterative kmeans building (VQ phase). | -| `pq_kmeans_trainset_fraction` | `double` | The fraction of data to use during iterative kmeans building (PQ phase). | -| `pq_kmeans_type` | `cuvs::cluster::kmeans::kmeans_type` | Type of k-means algorithm for PQ training. | -| `max_train_points_per_pq_code` | `uint32_t` | The max number of data points to use per PQ code during PQ codebook training. Using more data | +| `vq_kmeans_trainset_fraction` | `double` | The fraction of data to use during iterative kmeans building (VQ phase). When zero, an optimal value is selected using a heuristic. | +| `pq_kmeans_trainset_fraction` | `double` | The fraction of data to use during iterative kmeans building (PQ phase). When zero, an optimal value is selected using a heuristic. | +| `pq_kmeans_type` | `cuvs::cluster::kmeans::kmeans_type` | Type of k-means algorithm for PQ training. Balanced k-means tends to be faster than regular k-means for PQ training, for problem sets where the number of points per cluster are approximately equal. Regular k-means may be better for skewed cluster distributions. | +| `max_train_points_per_pq_code` | `uint32_t` | The max number of data points to use per PQ code during PQ codebook training. Using more data points per PQ code may increase the quality of PQ codebook but may also increase the build time. We will use `pq_n_centers * max_train_points_per_pq_code` training points to train each PQ codebook. | | `max_train_points_per_vq_cluster` | `uint32_t` | The max number of data points to use per VQ cluster during training. | _Source: `cpp/include/cuvs/neighbors/common.hpp:42`_ @@ -122,7 +122,7 @@ struct extend_params { ... } ; | Name | Type | Description | | --- | --- | --- | -| `max_chunk_size` | `uint32_t` | The additional dataset is divided into chunks and added to the graph. This is the knob to | +| `max_chunk_size` | `uint32_t` | The additional dataset is divided into chunks and added to the graph. This is the knob to adjust the tradeoff between the recall and operation throughput. Large chunk sizes can result in high throughput, but use more working memory (O(max_chunk_size*degree^2)). This can also degrade recall because no edges are added between the nodes in the same chunk. Auto select when 0. | _Source: `cpp/include/cuvs/neighbors/cagra.hpp:357`_ @@ -1245,7 +1245,7 @@ _Source: `cpp/include/cuvs/neighbors/cagra.hpp:1510`_ _Doxygen group: `cagra_cpp_index_search`_ -### sample_filter +### none_sample_filter Search ANN using the constructed index. diff --git a/fern/pages/cpp_api/cpp-api-neighbors-dynamic-batching.md b/fern/pages/cpp_api/cpp-api-neighbors-dynamic-batching.md index bb90f75ceb..a6444f8f57 100644 --- a/fern/pages/cpp_api/cpp-api-neighbors-dynamic-batching.md +++ b/fern/pages/cpp_api/cpp-api-neighbors-dynamic-batching.md @@ -24,8 +24,8 @@ struct index_params : cuvs::neighbors::index_params { ... } ; | --- | --- | --- | | `k` | `int64_t` | The number of neighbors to search is fixed at construction time. | | `max_batch_size` | `int64_t` | Maximum size of the batch to submit to the upstream index. | -| `n_queues` | `size_t` | The number of independent request queues. | -| `conservative_dispatch` | `bool` | By default (`conservative_dispatch = false`) the first CPU thread to commit a query to a batch | +| `n_queues` | `size_t` | The number of independent request queues. Each queue is associated with a unique CUDA stream and IO device buffers. If the number of concurrent requests is high, using multiple queues allows to fill-in data and prepare the batch while the other queue is busy. Moreover, the queues are submitted concurrently; this allows to better utilize the GPU by hiding the kernel launch latencies, which helps to improve the throughput. | +| `conservative_dispatch` | `bool` | By default (`conservative_dispatch = false`) the first CPU thread to commit a query to a batch dispatches the upstream search function as soon as possible (before the batch is full). In that case, it does not know the final batch size at the time of calling the upstream search and thus runs the upstream search with the maximum batch size every time, even if only one valid query is present in the batch. This reduces the latency at the cost of wasted GPU resources. The alternative behavaior (`conservative_dispatch = true`) is more conservative: the dispatcher thread starts the kernel that gathers input queries, but waits till the batch is full or the waiting time is exceeded. Only then it acquires the actual batch size and launches the upstream search. As a result, less GPU resources are wasted at the cost of exposing upstream search latency. *Rule of Thumb*: for a large `max_batch_size` set `conservative_dispatch = true`, otherwise keep it disabled. | _Source: `cpp/include/cuvs/neighbors/dynamic_batching.hpp:21`_ @@ -45,7 +45,7 @@ struct search_params : cuvs::neighbors::search_params { ... } ; | Name | Type | Description | | --- | --- | --- | -| `dispatch_timeout_ms` | `double` | How long a request can stay in the queue (milliseconds). | +| `dispatch_timeout_ms` | `double` | How long a request can stay in the queue (milliseconds). Note, this only affects the dispatch time and does not reflect full request latency; the latter depends on the upstream search parameters and the batch size. | _Source: `cpp/include/cuvs/neighbors/dynamic_batching.hpp:60`_ diff --git a/fern/pages/cpp_api/cpp-api-neighbors-hnsw.md b/fern/pages/cpp_api/cpp-api-neighbors-hnsw.md index d705aa2a3a..1dd18480d6 100644 --- a/fern/pages/cpp_api/cpp-api-neighbors-hnsw.md +++ b/fern/pages/cpp_api/cpp-api-neighbors-hnsw.md @@ -162,7 +162,7 @@ struct extend_params { ... } ; | Name | Type | Description | | --- | --- | --- | -| `num_threads` | `int` | Number of host threads to use to add additional vectors to the index. | +| `num_threads` | `int` | Number of host threads to use to add additional vectors to the index. Value of 0 automatically maximizes parallelism. | _Source: `cpp/include/cuvs/neighbors/hnsw.hpp:186`_ @@ -586,8 +586,8 @@ struct search_params : cuvs::neighbors::search_params { ... } ; | Name | Type | Description | | --- | --- | --- | -| `ef` | `int` | size of the candidate list | -| `num_threads` | `int` | number of host threads to use for concurrent searches. Value of 0 | +| `ef` | `int` | | +| `num_threads` | `int` | | _Source: `cpp/include/cuvs/neighbors/hnsw.hpp:740`_ diff --git a/fern/pages/cpp_api/cpp-api-neighbors-ivf-pq.md b/fern/pages/cpp_api/cpp-api-neighbors-ivf-pq.md index 7f48e247f6..a0c1b34bd4 100644 --- a/fern/pages/cpp_api/cpp-api-neighbors-ivf-pq.md +++ b/fern/pages/cpp_api/cpp-api-neighbors-ivf-pq.md @@ -72,10 +72,10 @@ struct search_params : cuvs::neighbors::search_params { ... } ; | Name | Type | Description | | --- | --- | --- | | `n_probes` | `uint32_t` | The number of clusters to search. | -| `lut_dtype` | `cudaDataType_t` | Data type of look up table to be created dynamically at search time. | -| `internal_distance_dtype` | `cudaDataType_t` | Storage data type for distance/similarity computed at search time. | -| `preferred_shmem_carveout` | `double` | Preferred fraction of SM's unified memory / L1 cache to be used as shared memory. | -| `coarse_search_dtype` | `cudaDataType_t` | [Experimental] The data type to use as the GEMM element type when searching the clusters to | +| `lut_dtype` | `cudaDataType_t` | Data type of look up table to be created dynamically at search time. Possible values: [CUDA_R_32F, CUDA_R_16F, CUDA_R_8U] The use of low-precision types reduces the amount of shared memory required at search time, so fast shared memory kernels can be used even for datasets with large dimansionality. Note that the recall is slightly degraded when low-precision type is selected. | +| `internal_distance_dtype` | `cudaDataType_t` | Storage data type for distance/similarity computed at search time. Possible values: [CUDA_R_16F, CUDA_R_32F] If the performance limiter at search time is device memory access, selecting FP16 will improve performance slightly. | +| `preferred_shmem_carveout` | `double` | Preferred fraction of SM's unified memory / L1 cache to be used as shared memory. Possible values: [0.0 - 1.0] as a fraction of the `sharedMemPerMultiprocessor`. One wants to increase the carveout to make sure a good GPU occupancy for the main search kernel, but not to keep it too high to leave some memory to be used as L1 cache. Note, this value is interpreted only as a hint. Moreover, a GPU usually allows only a fixed set of cache configurations, so the provided value is rounded up to the nearest configuration. Refer to the NVIDIA tuning guide for the target GPU architecture. Note, this is a low-level tuning parameter that can have drastic negative effects on the search performance if tweaked incorrectly. | +| `coarse_search_dtype` | `cudaDataType_t` | [Experimental] The data type to use as the GEMM element type when searching the clusters to probe. Possible values: [CUDA_R_8I, CUDA_R_16F, CUDA_R_32F].
- Legacy default: CUDA_R_32F (float)
- Recommended for performance: CUDA_R_16F (half)
- Experimental/low-precision: CUDA_R_8I (int8_t) (WARNING: int8_t variant degrades recall unless data is normalized and low-dimensional) | | `max_internal_batch_size` | `uint32_t` | Set the internal batch size to improve GPU utilization at the cost of larger memory footprint. | _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:157`_ diff --git a/fern/pages/cpp_api/cpp-api-neighbors-nn-descent.md b/fern/pages/cpp_api/cpp-api-neighbors-nn-descent.md index e018db8a44..b66e54eefd 100644 --- a/fern/pages/cpp_api/cpp-api-neighbors-nn-descent.md +++ b/fern/pages/cpp_api/cpp-api-neighbors-nn-descent.md @@ -14,21 +14,17 @@ _Doxygen group: `nn_descent_cpp_index_params`_ Dtype to use for distance computation -- `AUTO`: Automatically determine the best dtype for distance computation based on the dataset dimensions. -- `FP32`: Use fp32 distance computation for better precision at the cost of performance and memory usage. -- `FP16`: Use fp16 distance computation. - ```cpp enum class DIST_COMP_DTYPE { ... } ; ``` **Values** -| Name | Value | -| --- | --- | -| `AUTO` | `0` | -| `FP32` | `1` | -| `FP16` | `2` | +| Name | Value | Description | +| --- | --- | --- | +| `AUTO` | `0` | Automatically determine the best dtype for distance computation based on the dataset dimensions. | +| `FP32` | `1` | Use fp32 distance computation for better precision at the cost of performance and memory usage. | +| `FP16` | `2` | Use fp16 distance computation. | _Source: `cpp/include/cuvs/neighbors/nn_descent.hpp:35`_ @@ -36,13 +32,6 @@ _Source: `cpp/include/cuvs/neighbors/nn_descent.hpp:35`_ Parameters used to build an nn-descent index -- `graph_degree`: For an input dataset of dimensions (N, D), determines the final dimensions of the all-neighbors knn graph which turns out to be of dimensions (N, graph_degree) -- `intermediate_graph_degree`: Internally, nn-descent builds an all-neighbors knn graph of dimensions (N, intermediate_graph_degree) before selecting the final `graph_degree` neighbors. It's recommended that `intermediate_graph_degree` >= 1.5 * graph_degree -- `max_iterations`: The number of iterations that nn-descent will refine the graph for. More iterations produce a better quality graph at cost of performance -- `termination_threshold`: The delta at which nn-descent will terminate its iterations -- `return_distances`: Boolean to decide whether to return distances array -- `dist_comp_dtype`: dtype to use for distance computation. Defaults to `AUTO` which automatically determines the best dtype for distance computation based on the dataset dimensions. Use `FP32` for better precision at the cost of performance and memory usage. This option is only valid when data type is fp32. Use `FP16` for better performance and memory usage at the cost of precision. - ```cpp struct index_params : cuvs::neighbors::index_params { ... } ; ``` @@ -51,13 +40,12 @@ struct index_params : cuvs::neighbors::index_params { ... } ; | Name | Type | Description | | --- | --- | --- | -| `index_params` | `index_params(size_t` | Construct NN descent parameters for a specific kNN graph degree | -| `graph_degree` | `size_t` | | -| `intermediate_graph_degree` | `size_t` | | -| `max_iterations` | `size_t` | | -| `termination_threshold` | `float` | | -| `return_distances` | `bool` | | -| `dist_comp_dtype` | `DIST_COMP_DTYPE` | | +| `graph_degree` | `size_t` | For an input dataset of dimensions (N, D), determines the final dimensions of the all-neighbors knn graph which turns out to be of dimensions (N, graph_degree) | +| `intermediate_graph_degree` | `size_t` | Internally, nn-descent builds an all-neighbors knn graph of dimensions (N, intermediate_graph_degree) before selecting the final `graph_degree` neighbors. It's recommended that `intermediate_graph_degree` >= 1.5 * graph_degree | +| `max_iterations` | `size_t` | The number of iterations that nn-descent will refine the graph for. More iterations produce a better quality graph at cost of performance | +| `termination_threshold` | `float` | The delta at which nn-descent will terminate its iterations | +| `return_distances` | `bool` | Boolean to decide whether to return distances array | +| `dist_comp_dtype` | `DIST_COMP_DTYPE` | dtype to use for distance computation. Defaults to `AUTO` which automatically determines the best dtype for distance computation based on the dataset dimensions. Use `FP32` for better precision at the cost of performance and memory usage. This option is only valid when data type is fp32. Use `FP16` for better performance and memory usage at the cost of precision. | _Source: `cpp/include/cuvs/neighbors/nn_descent.hpp:56`_ diff --git a/fern/pages/cpp_api/cpp-api-neighbors-scann.md b/fern/pages/cpp_api/cpp-api-neighbors-scann.md index 941da0089b..488a7ffda4 100644 --- a/fern/pages/cpp_api/cpp-api-neighbors-scann.md +++ b/fern/pages/cpp_api/cpp-api-neighbors-scann.md @@ -32,7 +32,7 @@ struct index_params : cuvs::neighbors::index_params { ... } ; | `pq_n_rows_train` | `int64_t` | the number of rows for PQ training (internally capped to 100k) * | | `pq_train_iters` | `uint32_t` | the max number of iterations for PQ training * | | `reordering_bf16` | `bool` | whether to apply bf16 quantization of dataset vectors * | -| `reordering_noise_shaping_threshold` | `float` | Threshold T for computing AVQ eta = (dim - 1) ( T^2 / \|\| x \|\|^2) / ( 1 - T^2 / \|\| x \|\|^2) | +| `reordering_noise_shaping_threshold` | `float` | Threshold T for computing AVQ eta = (dim - 1) ( T^2 / \|\| x \|\|^2) / ( 1 - T^2 / \|\| x \|\|^2) When quantizing a vector x to x_q, AVQ minimizes the loss function L(x, x_q) = eta * \|\| r_para \|\|^2 + \|\| r_perp \|\|^2, where r = x - x_q, r_para = <r, x> * x / \|\| x \|\|^2, r_perp = r - r_para Compared to L2 loss, This produces an x_q which better approximates the dot product of a query vector with x If the threshold is NAN, AVQ is not performed during bfloat16 quant | _Source: `cpp/include/cuvs/neighbors/scann.hpp:36`_ diff --git a/fern/pages/cpp_api/cpp-api-neighbors-vamana.md b/fern/pages/cpp_api/cpp-api-neighbors-vamana.md index b5e5245a65..84472ca5d8 100644 --- a/fern/pages/cpp_api/cpp-api-neighbors-vamana.md +++ b/fern/pages/cpp_api/cpp-api-neighbors-vamana.md @@ -24,11 +24,11 @@ struct index_params : cuvs::neighbors::index_params { ... } ; | Name | Type | Description | | --- | --- | --- | -| `graph_degree` | `uint32_t` | Maximum degree of output graph corresponds to the R parameter in the original Vamana | -| `visited_size` | `uint32_t` | Maximum number of visited nodes per search corresponds to the L parameter in the Vamana | +| `graph_degree` | `uint32_t` | Maximum degree of output graph corresponds to the R parameter in the original Vamana literature. | +| `visited_size` | `uint32_t` | Maximum number of visited nodes per search corresponds to the L parameter in the Vamana literature * | | `vamana_iters` | `float` | Number of Vamana vector insertion iterations (each iteration inserts all vectors). | | `alpha` | `float` | Alpha for pruning parameter | -| `max_fraction` | `float` | Maximum fraction of dataset inserted per batch. * | +| `max_fraction` | `float` | Maximum fraction of dataset inserted per batch. * Larger max batch decreases graph quality, but improves speed | | `batch_base` | `float` | Base of growth rate of batch sizes * | | `queue_size` | `uint32_t` | Size of candidate queue structure - should be (2^x)-1 | | `reverse_batchsize` | `uint32_t` | Max batchsize of reverse edge processing (reduces memory footprint) | diff --git a/fern/pages/cpp_api/cpp-api-preprocessing-quantize-pq.md b/fern/pages/cpp_api/cpp-api-preprocessing-quantize-pq.md index b22610185d..003603fef3 100644 --- a/fern/pages/cpp_api/cpp-api-preprocessing-quantize-pq.md +++ b/fern/pages/cpp_api/cpp-api-preprocessing-quantize-pq.md @@ -22,14 +22,13 @@ struct params { ... } ; | Name | Type | Description | | --- | --- | --- | -| `params` | `params(uint32_t pq_bits, uint32_t pq_dim, bool use_subspaces, bool use_vq, uint32_t vq_n_centers, uint32_t kmeans_n_iters, cuvs::cluster::kmeans::kmeans_type` | Simplified constructor that will build an appropriate kmeans params object. | -| `pq_bits` | `uint32_t` | The bit length of the vector element after compression by PQ. | -| `pq_dim` | `uint32_t` | The dimensionality of the vector after compression by PQ. | -| `use_subspaces` | `bool` | Whether to use subspaces for product quantization (PQ). | -| `use_vq` | `bool` | Whether to use Vector Quantization (KMeans) before product quantization (PQ). | -| `vq_n_centers` | `uint32_t` | Vector Quantization (VQ) codebook size - number of "coarse cluster centers". | -| `kmeans_params` | `kmeans_params_variant` | K-means parameters for PQ codebook training. | -| `max_train_points_per_pq_code` | `uint32_t` | The max number of data points to use per PQ code during PQ codebook training. Using more data | +| `pq_bits` | `uint32_t` | The bit length of the vector element after compression by PQ. Possible value range: [4-16]. Hint: the smaller the 'pq_bits', the smaller the index size and the faster the fit/transform time, but the lower the recall. | +| `pq_dim` | `uint32_t` | The dimensionality of the vector after compression by PQ. When zero, dim / 4 is used as default. TODO: at the moment `dim` must be a multiple `pq_dim`. | +| `use_subspaces` | `bool` | Whether to use subspaces for product quantization (PQ). When true, one PQ codebook is used for each subspace. Otherwise, a single PQ codebook is used. | +| `use_vq` | `bool` | Whether to use Vector Quantization (KMeans) before product quantization (PQ). When true, VQ is used and PQ is trained on the residuals. | +| `vq_n_centers` | `uint32_t` | Vector Quantization (VQ) codebook size - number of "coarse cluster centers". When zero, an optimal value is selected using a heuristic. (sqrt(n_rows)) | +| `kmeans_params` | `kmeans_params_variant` | K-means parameters for PQ codebook training. Set to cuvs::cluster::kmeans::balanced_params for balanced k-means (default), or cuvs::cluster::kmeans::params for regular k-means. The active variant type selects the algorithm; balanced k-means tends to be faster for PQ training where cluster sizes are approximately equal. Only L2Expanded metric is supported. The number of clusters is always set to 1 << pq_bits. | +| `max_train_points_per_pq_code` | `uint32_t` | The max number of data points to use per PQ code during PQ codebook training. Using more data points per PQ code may increase the quality of PQ codebook but may also increase the build time. We will use `pq_n_centers * max_train_points_per_pq_code` training points to train each PQ codebook. | | `max_train_points_per_vq_cluster` | `uint32_t` | The max number of data points to use per VQ cluster during training. | _Source: `cpp/include/cuvs/preprocessing/quantize/pq.hpp:30`_ diff --git a/fern/pages/cpp_api/cpp-api-preprocessing-quantize-scalar.md b/fern/pages/cpp_api/cpp-api-preprocessing-quantize-scalar.md index 9a4f9e7201..b7b2410891 100644 --- a/fern/pages/cpp_api/cpp-api-preprocessing-quantize-scalar.md +++ b/fern/pages/cpp_api/cpp-api-preprocessing-quantize-scalar.md @@ -22,7 +22,7 @@ struct params { ... } ; | Name | Type | Description | | --- | --- | --- | -| `quantile` | `float` | Specifies how many outliers at top & bottom will be ignored. | +| `quantile` | `float` | Specifies how many outliers at top & bottom will be ignored. Needs to be within range of (0, 1]. | _Source: `cpp/include/cuvs/preprocessing/quantize/scalar.hpp:26`_ diff --git a/fern/scripts/generate_api_reference.py b/fern/scripts/generate_api_reference.py index e8c246c733..8182d9ed3a 100755 --- a/fern/scripts/generate_api_reference.py +++ b/fern/scripts/generate_api_reference.py @@ -73,6 +73,9 @@ COMMENT_RE = re.compile(r"/\*\*.*?\*/|(?:///[^\n]*(?:\n|$))+", re.DOTALL) DOXYGEN_COMMAND_RE = re.compile(r"[@\\](\w+)\b") DOXYGEN_LIST_ITEM_RE = re.compile(r"^(?:-\s+|\d+\.\s+)") +DOXYGEN_FIELD_LIST_ITEM_RE = re.compile( + r"^-\s+`?(?P[A-Za-z_]\w*)`?\s*:\s*(?P.*)" +) PUBLIC_JAVA_TYPE_RE = re.compile( r"\bpublic\s+(?:abstract\s+|final\s+|sealed\s+|non-sealed\s+)?" r"(?Pclass|interface|enum|record)\s+(?P[A-Za-z_]\w*)" @@ -538,8 +541,24 @@ def render_native_compound(entry: DoxygenEntry, language: str) -> list[str]: lines = [f"### {heading_text(entry.name)}", ""] if entry.summary: lines.extend([escape_text(entry.summary), ""]) - if entry.details: - lines.extend(render_doxygen_details(entry.details)) + + members: list[DoxygenEntry] = [] + values: list[dict[str, str]] = [] + field_descriptions: dict[str, str] = {} + details = entry.details + if entry.kind == "enum": + values = parse_enum_values(entry.signature) + field_descriptions, details = extract_field_descriptions( + entry.details, {value["name"] for value in values} + ) + else: + members = parse_struct_members(entry) + field_descriptions, details = extract_field_descriptions( + entry.details, {member.name for member in members} + ) + + if details: + lines.extend(render_doxygen_details(details)) lines.append("") lines.extend( [ @@ -551,18 +570,34 @@ def render_native_compound(entry: DoxygenEntry, language: str) -> list[str]: ) if entry.kind == "enum": - values = parse_enum_values(entry.signature) if values: - lines.extend( - ["**Values**", "", "| Name | Value |", "| --- | --- |"] - ) - for value in values: - lines.append( - f"| `{escape_code(value['name'])}` | `{escape_code(value.get('value', ''))}` |" + if field_descriptions: + lines.extend( + [ + "**Values**", + "", + "| Name | Value | Description |", + "| --- | --- | --- |", + ] ) + else: + lines.extend( + ["**Values**", "", "| Name | Value |", "| --- | --- |"] + ) + for value in values: + name = escape_code(value["name"]) + enum_value = escape_code(value.get("value", "")) + if field_descriptions: + description = render_table_description( + field_descriptions.get(value["name"], "") + ) + lines.append( + f"| `{name}` | `{enum_value}` | {description} |" + ) + else: + lines.append(f"| `{name}` | `{enum_value}` |") lines.append("") else: - members = parse_struct_members(entry) if members: lines.extend(["**Fields**", ""]) rows = [] @@ -571,7 +606,9 @@ def render_native_compound(entry: DoxygenEntry, language: str) -> list[str]: { "name": member.name, "type": member_c_type(member), - "description": member.summary, + "description": field_descriptions.get( + member.name, member_description(member) + ), } ) lines.extend(render_param_table(rows, include_direction=False)) @@ -1322,7 +1359,7 @@ def parse_entry_name(declaration: str) -> str: def parse_member_name(declaration: str) -> str: - declaration = declaration.strip().rstrip(";").split("=", 1)[0].strip() + declaration = strip_member_initializer(declaration) _, name = split_param_name(declaration) return name or declaration @@ -1478,6 +1515,8 @@ def parse_return_type(signature: str) -> str: def parse_struct_members(entry: DoxygenEntry) -> list[DoxygenEntry]: members: list[DoxygenEntry] = [] for match in COMMENT_RE.finditer(entry.signature): + if not is_top_level_compound_comment(entry.signature, match.start()): + continue comment = clean_doxygen_comment(match.group(0)) declaration, line = read_declaration_after( entry.signature, match.end() @@ -1486,6 +1525,8 @@ def parse_struct_members(entry: DoxygenEntry) -> list[DoxygenEntry]: ("public:", "private:", "protected:") ): continue + if parse_doxygen_kind(declaration) != "member": + continue member = parse_doxygen_entry( comment, declaration, entry.source, entry.line + line - 1 ) @@ -1504,35 +1545,20 @@ def parse_plain_struct_members( if not body: return [] members: list[DoxygenEntry] = [] - pending_declaration = "" - pending_comment = "" - for raw_line in body.splitlines(): - stripped = raw_line.strip() - if not stripped or stripped in {"public:", "private:", "protected:"}: - continue - if stripped.startswith("//"): - continue - if stripped.startswith(("*", "/*", "*/")): - continue - declaration, inline_comment = split_inline_comment(raw_line) - declaration = re.sub(r"/\*.*?\*/", "", declaration).strip() - if not declaration and not pending_declaration: - continue - pending_declaration = f"{pending_declaration} {declaration}".strip() - pending_comment = append_sentence( - pending_comment, clean_doxygen_text(inline_comment) - ) - if ";" not in pending_declaration: - continue - declaration = pending_declaration.split(";", 1)[0].rstrip(",").strip() - inline_comment = pending_comment - pending_declaration = "" - pending_comment = "" + for declaration in top_level_member_declarations(body): + declaration = strip_member_initializer(declaration) if not declaration or "(" in declaration: continue - declaration = declaration.split("=", 1)[0].strip() if not declaration or declaration.startswith( - ("using ", "typedef ", "static_assert") + ( + "enum ", + "friend ", + "static_assert", + "struct ", + "template ", + "typedef ", + "using ", + ) ): continue c_type, name = split_param_name(declaration) @@ -1542,7 +1568,7 @@ def parse_plain_struct_members( kind="member", name=name, signature=c_type or declaration, - summary=clean_doxygen_text(inline_comment), + summary="", source=entry.source, line=entry.line, ) @@ -1551,12 +1577,93 @@ def parse_plain_struct_members( return members +def is_top_level_compound_comment(signature: str, offset: int) -> bool: + bounds = compound_body_bounds(signature) + if bounds is None: + return False + body_start, body_end = bounds + if offset < body_start or offset >= body_end: + return False + depth = 0 + for char in signature[body_start:offset]: + if char == "{": + depth += 1 + elif char == "}": + depth = max(depth - 1, 0) + return depth == 0 + + +def top_level_member_declarations(body: str) -> list[str]: + text = COMMENT_RE.sub("", body) + text = re.sub(r"//.*", "", text) + declarations: list[str] = [] + current: list[str] = [] + depth = {"(": 0, "[": 0, "{": 0, "<": 0} + for char in text: + current.append(char) + update_depth(depth, char) + if char == ";" and not any(depth.values()): + declaration = "".join(current).strip().rstrip(";").strip() + if declaration: + declarations.append(" ".join(declaration.split())) + current = [] + return declarations + + +def extract_field_descriptions( + details: list[str], field_names: set[str] +) -> tuple[dict[str, str], list[str]]: + descriptions: dict[str, str] = {} + remaining: list[str] = [] + idx = 0 + while idx < len(details): + line = details[idx] + match = DOXYGEN_FIELD_LIST_ITEM_RE.match(line.strip()) + if match and match.group("name") in field_names: + name = match.group("name") + description = [match.group("description").strip()] + idx += 1 + while idx < len(details): + next_line = details[idx] + next_stripped = next_line.strip() + if not next_stripped or DOXYGEN_LIST_ITEM_RE.match( + next_stripped + ): + break + description.append(next_stripped) + idx += 1 + descriptions[name] = " ".join(part for part in description if part) + continue + remaining.append(line) + idx += 1 + return descriptions, trim_blank_lines(remaining) + + def compound_body(signature: str) -> str: + bounds = compound_body_bounds(signature) + if bounds is None: + return "" + start, end = bounds + return signature[start:end] + + +def compound_body_bounds(signature: str) -> tuple[int, int] | None: start = signature.find("{") end = signature.rfind("}") if start == -1 or end == -1 or end <= start: - return "" - return signature[start + 1 : end] + return None + return start + 1, end + + +def strip_member_initializer(declaration: str) -> str: + declaration = declaration.strip().rstrip(";") + declaration, _ = split_default(declaration) + declaration = declaration.strip() + if declaration.endswith("}") and "{" in declaration: + before_brace = declaration.rsplit("{", 1)[0].strip() + if re.search(r"\b[A-Za-z_]\w*$", before_brace): + return before_brace + return declaration def split_inline_comment(line: str) -> tuple[str, str]: @@ -1567,11 +1674,19 @@ def split_inline_comment(line: str) -> tuple[str, str]: def member_c_type(member: DoxygenEntry) -> str: - declaration = member.signature.rstrip(";").split("=", 1)[0].strip() + declaration = strip_member_initializer(member.signature) c_type, _ = split_param_name(declaration) return c_type or declaration +def member_description(member: DoxygenEntry) -> str: + lines = [] + if member.summary: + lines.append(member.summary) + lines.extend(member.details) + return "\n".join(line for line in lines if line.strip()) + + def parse_enum_values(signature: str) -> list[dict[str, str]]: body_match = re.search(r"{(?P.*)}", signature, re.DOTALL) if not body_match: From 331a4c9c606c423dc33ed3a5df975a7f644363d5 Mon Sep 17 00:00:00 2001 From: "Corey J. Nolet" Date: Thu, 7 May 2026 13:31:23 -0400 Subject: [PATCH 007/129] Link native API reference types --- fern/docs.yml | 6 + fern/pages/c_api/c-api-cluster-kmeans.md | 36 ++- fern/pages/c_api/c-api-core-c-api.md | 106 ++++--- fern/pages/c_api/c-api-distance-distance.md | 45 +++ .../c_api/c-api-distance-pairwise-distance.md | 7 +- .../c_api/c-api-neighbors-all-neighbors.md | 27 +- .../c_api/c-api-neighbors-brute-force.md | 60 ++-- fern/pages/c_api/c-api-neighbors-cagra.md | 203 ++++++++----- fern/pages/c_api/c-api-neighbors-common.md | 19 ++ fern/pages/c_api/c-api-neighbors-hnsw.md | 118 ++++--- fern/pages/c_api/c-api-neighbors-ivf-flat.md | 108 ++++--- fern/pages/c_api/c-api-neighbors-ivf-pq.md | 185 ++++++----- fern/pages/c_api/c-api-neighbors-mg-cagra.md | 108 ++++--- fern/pages/c_api/c-api-neighbors-mg-common.md | 3 + .../c_api/c-api-neighbors-mg-ivf-flat.md | 108 ++++--- fern/pages/c_api/c-api-neighbors-mg-ivf-pq.md | 108 ++++--- .../pages/c_api/c-api-neighbors-nn-descent.md | 73 ++++- fern/pages/c_api/c-api-neighbors-refine.md | 7 +- .../c_api/c-api-neighbors-tiered-index.md | 109 +++++-- fern/pages/c_api/c-api-neighbors-vamana.md | 62 ++-- fern/pages/c_api/c-api-preprocessing-pca.md | 42 +-- .../c-api-preprocessing-quantize-binary.md | 63 ++-- .../c_api/c-api-preprocessing-quantize-pq.md | 96 ++++-- .../c-api-preprocessing-quantize-scalar.md | 64 ++-- fern/pages/c_api/index.md | 1 + .../cpp_api/cpp-api-cluster-agglomerative.md | 22 +- fern/pages/cpp_api/cpp-api-cluster-kmeans.md | 86 ++++-- .../pages/cpp_api/cpp-api-cluster-spectral.md | 8 +- .../cpp_api/cpp-api-distance-distance.md | 107 ++++++- .../cpp-api-neighbors-all-neighbors.md | 11 +- .../cpp_api/cpp-api-neighbors-ball-cover.md | 1 + .../cpp_api/cpp-api-neighbors-brute-force.md | 30 +- fern/pages/cpp_api/cpp-api-neighbors-cagra.md | 91 ++++-- .../pages/cpp_api/cpp-api-neighbors-common.md | 18 +- .../cpp-api-neighbors-dynamic-batching.md | 22 +- .../cpp-api-neighbors-epsilon-neighborhood.md | 3 +- fern/pages/cpp_api/cpp-api-neighbors-hnsw.md | 43 ++- .../cpp_api/cpp-api-neighbors-ivf-flat.md | 49 ++- .../pages/cpp_api/cpp-api-neighbors-ivf-pq.md | 107 ++++++- .../cpp_api/cpp-api-neighbors-nn-descent.md | 35 ++- .../pages/cpp_api/cpp-api-neighbors-refine.md | 21 +- fern/pages/cpp_api/cpp-api-neighbors-scann.md | 10 +- .../pages/cpp_api/cpp-api-neighbors-vamana.md | 33 +- .../cpp_api/cpp-api-preprocessing-pca.md | 38 ++- .../cpp-api-preprocessing-quantize-binary.md | 20 +- .../cpp-api-preprocessing-quantize-pq.md | 27 +- .../cpp-api-preprocessing-quantize-scalar.md | 16 +- ...pp-api-preprocessing-spectral-embedding.md | 31 +- .../cpp_api/cpp-api-selection-select-k.md | 1 + .../cpp_api/cpp-api-stats-silhouette-score.md | 10 +- .../cpp-api-stats-trustworthiness-score.md | 3 +- .../cpp_api/cpp-api-util-cutlass-utils.md | 20 ++ fern/pages/cpp_api/cpp-api-util-file-io.md | 57 ++++ fern/pages/cpp_api/index.md | 2 + fern/scripts/generate_api_reference.py | 287 ++++++++++++++++-- 55 files changed, 2189 insertions(+), 784 deletions(-) create mode 100644 fern/pages/c_api/c-api-distance-distance.md create mode 100644 fern/pages/cpp_api/cpp-api-util-cutlass-utils.md create mode 100644 fern/pages/cpp_api/cpp-api-util-file-io.md diff --git a/fern/docs.yml b/fern/docs.yml index 1de259647c..d646e11f9a 100644 --- a/fern/docs.yml +++ b/fern/docs.yml @@ -105,6 +105,8 @@ navigation: path: "./pages/c_api/c-api-cluster-kmeans.md" - page: "Core C API" path: "./pages/c_api/c-api-core-c-api.md" + - page: "Distance Distance" + path: "./pages/c_api/c-api-distance-distance.md" - page: "Distance Pairwise Distance" path: "./pages/c_api/c-api-distance-pairwise-distance.md" - page: "Neighbors All Neighbors" @@ -200,6 +202,10 @@ navigation: path: "./pages/cpp_api/cpp-api-stats-silhouette-score.md" - page: "Stats Trustworthiness Score" path: "./pages/cpp_api/cpp-api-stats-trustworthiness-score.md" + - page: "Util Cutlass Utils" + path: "./pages/cpp_api/cpp-api-util-cutlass-utils.md" + - page: "Util File Io" + path: "./pages/cpp_api/cpp-api-util-file-io.md" - section: "Python API Documentation" path: "./pages/python_api/index.md" contents: diff --git a/fern/pages/c_api/c-api-cluster-kmeans.md b/fern/pages/c_api/c-api-cluster-kmeans.md index 65cd21ff4c..d6b322a985 100644 --- a/fern/pages/c_api/c-api-cluster-kmeans.md +++ b/fern/pages/c_api/c-api-cluster-kmeans.md @@ -10,6 +10,7 @@ _Source header: `c/include/cuvs/cluster/kmeans.h`_ _Doxygen group: `kmeans_c_params`_ + ### cuvsKMeansInitMethod k-means hyperparameters @@ -28,6 +29,7 @@ typedef enum { ... } cuvsKMeansInitMethod; _Source: `c/include/cuvs/cluster/kmeans.h:22`_ + ### cuvsKMeansParams Hyper-parameters for the kmeans algorithm @@ -41,7 +43,7 @@ struct cuvsKMeansParams { ... } ; | Name | Type | Description | | --- | --- | --- | | `n_clusters` | `int` | The number of clusters to form as well as the number of centroids to generate (default:8). | -| `init` | `cuvsKMeansInitMethod` | Method for initialization, defaults to k-means++:
- cuvsKMeansInitMethod::KMeansPlusPlus (k-means++): Use scalable k-means++ algorithm to select the initial cluster centers.
- cuvsKMeansInitMethod::Random (random): Choose 'n_clusters' observations (rows) at random from the input data for the initial centroids.
- cuvsKMeansInitMethod::Array (ndarray): Use 'centroids' as initial cluster centers. | +| `init` | [`cuvsKMeansInitMethod`](/api-reference/c-api-cluster-kmeans#cuvskmeansinitmethod) | Method for initialization, defaults to k-means++:
- cuvsKMeansInitMethod::KMeansPlusPlus (k-means++): Use scalable k-means++ algorithm to select the initial cluster centers.
- cuvsKMeansInitMethod::Random (random): Choose 'n_clusters' observations (rows) at random from the input data for the initial centroids.
- cuvsKMeansInitMethod::Array (ndarray): Use 'centroids' as initial cluster centers. | | `max_iter` | `int` | Maximum number of iterations of the k-means algorithm for a single run. | | `tol` | `double` | Relative tolerance with regards to inertia to declare convergence. | | `n_init` | `int` | Number of instance k-means algorithm will be run with different seeds. | @@ -52,10 +54,11 @@ struct cuvsKMeansParams { ... } ; | `hierarchical` | `bool` | Whether to use hierarchical (balanced) kmeans or not | | `hierarchical_n_iters` | `int` | For hierarchical k-means , defines the number of training iterations | | `streaming_batch_size` | `int64_t` | Number of samples to process per GPU batch for the batched (host-data) API. When set to 0, defaults to n_samples (process all at once). | -| `metric` | `cuvsDistanceType` | | +| `metric` | [`cuvsDistanceType`](/api-reference/c-api-distance-distance#cuvsdistancetype) | | _Source: `c/include/cuvs/cluster/kmeans.h:43`_ + ### cuvsKMeansParamsCreate Allocate KMeans params, and populate with default values @@ -68,16 +71,17 @@ cuvsError_t cuvsKMeansParamsCreate(cuvsKMeansParams_t* params); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `params` | in | `cuvsKMeansParams_t*` | cuvsKMeansParams_t to allocate | +| `params` | in | [`cuvsKMeansParams_t*`](/api-reference/c-api-cluster-kmeans#cuvskmeansparams) | cuvsKMeansParams_t to allocate | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/cluster/kmeans.h:122`_ + ### cuvsKMeansParamsDestroy De-allocate KMeans params @@ -90,16 +94,17 @@ cuvsError_t cuvsKMeansParamsDestroy(cuvsKMeansParams_t params); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `params` | in | `cuvsKMeansParams_t` | | +| `params` | in | [`cuvsKMeansParams_t`](/api-reference/c-api-cluster-kmeans#cuvskmeansparams) | | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/cluster/kmeans.h:130`_ + ### cuvsKMeansType Type of k-means algorithm. @@ -121,6 +126,7 @@ _Source: `c/include/cuvs/cluster/kmeans.h:135`_ _Doxygen group: `kmeans_c`_ + ### cuvsKMeansFit Find clusters with k-means algorithm. @@ -143,8 +149,8 @@ X may reside on either host (CPU) or device (GPU) memory. When X is on the host | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | opaque C handle | -| `params` | in | `cuvsKMeansParams_t` | Parameters for KMeans model. | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | opaque C handle | +| `params` | in | [`cuvsKMeansParams_t`](/api-reference/c-api-cluster-kmeans#cuvskmeansparams) | Parameters for KMeans model. | | `X` | in | `DLManagedTensor*` | Training instances to cluster. The data must be in row-major format. May be on host or device memory. [dim = n_samples x n_features] | | `sample_weight` | in | `DLManagedTensor*` | Optional weights for each observation in X. Must be on the same memory space as X. [len = n_samples] | | `centroids` | inout | `DLManagedTensor*` | [in] When init is InitMethod::Array, use centroids as the initial cluster centers. [out] The generated centroids from the kmeans algorithm are stored at the address pointed by 'centroids'. Must be on device. [dim = n_clusters x n_features] | @@ -153,10 +159,11 @@ X may reside on either host (CPU) or device (GPU) memory. When X is on the host **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) _Source: `c/include/cuvs/cluster/kmeans.h:176`_ + ### cuvsKMeansPredict Predict the closest cluster each sample in X belongs to. @@ -176,8 +183,8 @@ double* inertia); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | opaque C handle | -| `params` | in | `cuvsKMeansParams_t` | Parameters for KMeans model. | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | opaque C handle | +| `params` | in | [`cuvsKMeansParams_t`](/api-reference/c-api-cluster-kmeans#cuvskmeansparams) | Parameters for KMeans model. | | `X` | in | `DLManagedTensor*` | New data to predict. [dim = n_samples x n_features] | | `sample_weight` | in | `DLManagedTensor*` | Optional weights for each observation in X. [len = n_samples] | | `centroids` | in | `DLManagedTensor*` | Cluster centroids. The data must be in row-major format. [dim = n_clusters x n_features] | @@ -187,10 +194,11 @@ double* inertia); **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) _Source: `c/include/cuvs/cluster/kmeans.h:203`_ + ### cuvsKMeansClusterCost Compute cluster cost @@ -206,13 +214,13 @@ double* cost); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | opaque C handle | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | opaque C handle | | `X` | in | `DLManagedTensor*` | Training instances to cluster. The data must be in row-major format. [dim = n_samples x n_features] | | `centroids` | in | `DLManagedTensor*` | Cluster centroids. The data must be in row-major format. [dim = n_clusters x n_features] | | `cost` | out | `double*` | Resulting cluster cost | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) _Source: `c/include/cuvs/cluster/kmeans.h:225`_ diff --git a/fern/pages/c_api/c-api-core-c-api.md b/fern/pages/c_api/c-api-core-c-api.md index 2bbc5bb304..19020404ed 100644 --- a/fern/pages/c_api/c-api-core-c-api.md +++ b/fern/pages/c_api/c-api-core-c-api.md @@ -10,6 +10,7 @@ _Source header: `c/include/cuvs/core/c_api.h`_ _Doxygen group: `error_c`_ + ### cuvsError_t An enum denoting error statuses for function calls @@ -27,6 +28,7 @@ typedef enum { ... } cuvsError_t; _Source: `c/include/cuvs/core/c_api.h:25`_ + ### cuvsGetLastErrorText Returns a string describing the last seen error on this thread, or @@ -43,6 +45,7 @@ NULL if the last function succeeded. _Source: `c/include/cuvs/core/c_api.h:30`_ + ### cuvsSetLastErrorText Sets a string describing an error seen on the thread. Passing NULL @@ -69,6 +72,7 @@ _Source: `c/include/cuvs/core/c_api.h:36`_ _Doxygen group: `log_c`_ + ### cuvsLogLevel_t An enum denoting log levels @@ -91,6 +95,7 @@ typedef enum { ... } cuvsLogLevel_t; _Source: `c/include/cuvs/core/c_api.h:49`_ + ### cuvsGetLogLevel Returns the current log level @@ -101,10 +106,11 @@ cuvsLogLevel_t cuvsGetLogLevel(); **Returns** -`cuvsLogLevel_t` +[`cuvsLogLevel_t`](/api-reference/c-api-core-c-api#cuvsloglevel-t) _Source: `c/include/cuvs/core/c_api.h:61`_ + ### cuvsSetLogLevel Sets the log level @@ -117,7 +123,7 @@ void cuvsSetLogLevel(cuvsLogLevel_t); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `arg1` | | `cuvsLogLevel_t` | | +| `arg1` | | [`cuvsLogLevel_t`](/api-reference/c-api-core-c-api#cuvsloglevel-t) | | **Returns** @@ -129,6 +135,18 @@ _Source: `c/include/cuvs/core/c_api.h:65`_ _Doxygen group: `resources_c`_ + +### cuvsResources_t + +An opaque C handle for C++ type `raft::resources` + +```c +typedef uintptr_t cuvsResources_t; +``` + +_Source: `c/include/cuvs/core/c_api.h:78`_ + + ### cuvsResourcesCreate Create an Initialized opaque C handle for C++ type `raft::resources` @@ -141,16 +159,17 @@ cuvsError_t cuvsResourcesCreate(cuvsResources_t* res); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t*` | cuvsResources_t opaque C handle | +| `res` | in | [`cuvsResources_t*`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/core/c_api.h:86`_ + ### cuvsResourcesDestroy Destroy and de-allocate opaque C handle for C++ type `raft::resources` @@ -163,16 +182,17 @@ cuvsError_t cuvsResourcesDestroy(cuvsResources_t res); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/core/c_api.h:94`_ + ### cuvsStreamSet Set cudaStream_t on cuvsResources_t to queue CUDA kernels on APIs @@ -187,17 +207,18 @@ that accept a cuvsResources_t handle | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle | | `stream` | in | `cudaStream_t` | cudaStream_t stream to queue CUDA kernels | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/core/c_api.h:104`_ + ### cuvsStreamGet Get the cudaStream_t from a cuvsResources_t @@ -210,17 +231,18 @@ cuvsError_t cuvsStreamGet(cuvsResources_t res, cudaStream_t* stream); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle | | `stream` | out | `cudaStream_t*` | cudaStream_t stream to queue CUDA kernels | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/core/c_api.h:113`_ + ### cuvsStreamSync Syncs the current CUDA stream on the resources object @@ -233,16 +255,17 @@ cuvsError_t cuvsStreamSync(cuvsResources_t res); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/core/c_api.h:121`_ + ### cuvsDeviceIdGet Get the id of the device associated with this cuvsResources_t @@ -255,17 +278,18 @@ cuvsError_t cuvsDeviceIdGet(cuvsResources_t res, int* device_id); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle | | `device_id` | out | `int*` | int the id of the device associated with res | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/core/c_api.h:130`_ + ### cuvsMultiGpuResourcesCreate Create an Initialized opaque C handle for C++ type `raft::device_resources_snmg` @@ -280,16 +304,17 @@ for multi-GPU operations | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t*` | cuvsResources_t opaque C handle | +| `res` | in | [`cuvsResources_t*`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/core/c_api.h:139`_ + ### cuvsMultiGpuResourcesCreateWithDeviceIds Create an Initialized opaque C handle for C++ type `raft::device_resources_snmg` @@ -305,17 +330,18 @@ for multi-GPU operations with specific device IDs | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t*` | cuvsResources_t opaque C handle | +| `res` | in | [`cuvsResources_t*`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle | | `device_ids` | in | `DLManagedTensor*` | DLManagedTensor* containing device IDs to use | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/core/c_api.h:149`_ + ### cuvsMultiGpuResourcesDestroy Destroy and de-allocate opaque C handle for C++ type `raft::device_resources_snmg` @@ -328,16 +354,17 @@ cuvsError_t cuvsMultiGpuResourcesDestroy(cuvsResources_t res); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/core/c_api.h:158`_ + ### cuvsMultiGpuResourcesSetMemoryPool Set a memory pool on all devices managed by the multi-GPU resources @@ -350,12 +377,12 @@ cuvsError_t cuvsMultiGpuResourcesSetMemoryPool(cuvsResources_t res, int percent_ | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle for multi-GPU resources | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle for multi-GPU resources | | `percent_of_free_memory` | in | `int` | Percent of free memory to allocate for the pool | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t @@ -365,6 +392,7 @@ _Source: `c/include/cuvs/core/c_api.h:167`_ _Doxygen group: `memory_c`_ + ### cuvsRMMAlloc Allocates device memory using RMM @@ -377,18 +405,19 @@ cuvsError_t cuvsRMMAlloc(cuvsResources_t res, void** ptr, size_t bytes); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle | | `ptr` | out | `void**` | Pointer to allocated device memory | | `bytes` | in | `size_t` | Size in bytes to allocate | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/core/c_api.h:184`_ + ### cuvsRMMFree Deallocates device memory using RMM @@ -401,18 +430,19 @@ cuvsError_t cuvsRMMFree(cuvsResources_t res, void* ptr, size_t bytes); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle | | `ptr` | in | `void*` | Pointer to allocated device memory to free | | `bytes` | in | `size_t` | Size in bytes to allocate | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/core/c_api.h:194`_ + ### cuvsRMMPoolMemoryResourceEnable Switches the working memory resource to use the RMM pool memory resource, which will @@ -437,12 +467,13 @@ available memory available memory **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/core/c_api.h:210`_ + ### cuvsRMMMemoryResourceReset Resets the memory resource to use the default memory resource (cuda_memory_resource) @@ -453,12 +484,13 @@ cuvsError_t cuvsRMMMemoryResourceReset(); **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/core/c_api.h:217`_ + ### cuvsRMMHostAlloc Allocates pinned memory on the host using RMM @@ -476,12 +508,13 @@ cuvsError_t cuvsRMMHostAlloc(void** ptr, size_t bytes); **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/core/c_api.h:225`_ + ### cuvsRMMHostFree Deallocates pinned memory on the host using RMM @@ -499,12 +532,13 @@ cuvsError_t cuvsRMMHostFree(void* ptr, size_t bytes); **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/core/c_api.h:233`_ + ### cuvsVersionGet Get the version of the cuVS library @@ -523,12 +557,13 @@ cuvsError_t cuvsVersionGet(uint16_t* major, uint16_t* minor, uint16_t* patch); **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/core/c_api.h:242`_ + ### cuvsMatrixCopy Copy a matrix @@ -545,16 +580,17 @@ Both src and dst must have the same shape and dtype, but can have different stri | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle | | `src` | in | `DLManagedTensor*` | Pointer to DLManagedTensor to copy | | `dst` | out | `DLManagedTensor*` | Pointer to DLManagedTensor to receive copy of data | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) _Source: `c/include/cuvs/core/c_api.h:259`_ + ### cuvsMatrixSliceRows Slices rows from a matrix @@ -568,7 +604,7 @@ cuvsResources_t res, DLManagedTensor* src, int64_t start, int64_t end, DLManaged | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle | | `src` | in | `DLManagedTensor*` | Pointer to DLManagedTensor to copy | | `start` | in | `int64_t` | First row index to include in the output | | `end` | in | `int64_t` | Last row index to include in the output | @@ -576,6 +612,6 @@ cuvsResources_t res, DLManagedTensor* src, int64_t start, int64_t end, DLManaged **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) _Source: `c/include/cuvs/core/c_api.h:270`_ diff --git a/fern/pages/c_api/c-api-distance-distance.md b/fern/pages/c_api/c-api-distance-distance.md new file mode 100644 index 0000000000..bc3558e2cd --- /dev/null +++ b/fern/pages/c_api/c-api-distance-distance.md @@ -0,0 +1,45 @@ +--- +slug: api-reference/c-api-distance-distance +--- + +# Distance + +_Source header: `c/include/cuvs/distance/distance.h`_ + +## Types + + +### cuvsDistanceType + +enum to tell how to compute distance + +```c +typedef enum { ... } cuvsDistanceType; +``` + +**Values** + +| Name | Value | +| --- | --- | +| `L2Expanded` | `0` | +| `CosineExpanded` | `2` | +| `L1` | `3` | +| `L2Unexpanded` | `4` | +| `InnerProduct` | `6` | +| `Linf` | `7` | +| `Canberra` | `8` | +| `LpUnexpanded` | `9` | +| `CorrelationExpanded` | `10` | +| `JaccardExpanded` | `11` | +| `HellingerExpanded` | `12` | +| `Haversine` | `13` | +| `BrayCurtis` | `14` | +| `JensenShannon` | `15` | +| `HammingUnexpanded` | `16` | +| `KLDivergence` | `17` | +| `RusselRaoExpanded` | `18` | +| `DiceExpanded` | `19` | +| `BitwiseHamming` | `20` | +| `Precomputed` | `100` | + +_Source: `c/include/cuvs/distance/distance.h:12`_ diff --git a/fern/pages/c_api/c-api-distance-pairwise-distance.md b/fern/pages/c_api/c-api-distance-pairwise-distance.md index 7cf5a0d060..6a0f06ff86 100644 --- a/fern/pages/c_api/c-api-distance-pairwise-distance.md +++ b/fern/pages/c_api/c-api-distance-pairwise-distance.md @@ -10,6 +10,7 @@ _Source header: `c/include/cuvs/distance/pairwise_distance.h`_ _Doxygen group: `pairwise_distance_c`_ + ### cuvsPairwiseDistance Compute pairwise distances for two matrices @@ -29,15 +30,15 @@ Usage example: | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | cuvs resources object for managing expensive resources | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvs resources object for managing expensive resources | | `x` | in | `DLManagedTensor*` | first set of points (size n*k) | | `y` | in | `DLManagedTensor*` | second set of points (size m*k) | | `dist` | out | `DLManagedTensor*` | output distance matrix (size n*m) | -| `metric` | in | `cuvsDistanceType` | distance to evaluate | +| `metric` | in | [`cuvsDistanceType`](/api-reference/c-api-distance-distance#cuvsdistancetype) | distance to evaluate | | `metric_arg` | in | `float` | metric argument (used for Minkowski distance) | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) _Source: `c/include/cuvs/distance/pairwise_distance.h:48`_ diff --git a/fern/pages/c_api/c-api-neighbors-all-neighbors.md b/fern/pages/c_api/c-api-neighbors-all-neighbors.md index c6c2fa7b66..7e699f0a81 100644 --- a/fern/pages/c_api/c-api-neighbors-all-neighbors.md +++ b/fern/pages/c_api/c-api-neighbors-all-neighbors.md @@ -10,6 +10,7 @@ _Source header: `c/include/cuvs/neighbors/all_neighbors.h`_ _Doxygen group: `all_neighbors_c_params`_ + ### cuvsAllNeighborsAlgo Graph build algorithm selection. @@ -28,6 +29,7 @@ typedef enum { ... } cuvsAllNeighborsAlgo; _Source: `c/include/cuvs/neighbors/all_neighbors.h:38`_ + ### cuvsAllNeighborsIndexParams Parameters controlling SNMG all-neighbors build. @@ -40,15 +42,16 @@ struct cuvsAllNeighborsIndexParams { ... } ; | Name | Type | Description | | --- | --- | --- | -| `algo` | `cuvsAllNeighborsAlgo` | | +| `algo` | [`cuvsAllNeighborsAlgo`](/api-reference/c-api-neighbors-all-neighbors#cuvsallneighborsalgo) | | | `overlap_factor` | `size_t` | | | `n_clusters` | `size_t` | | -| `metric` | `cuvsDistanceType` | | -| `ivf_pq_params` | `cuvsIvfPqIndexParams_t` | | -| `nn_descent_params` | `cuvsNNDescentIndexParams_t` | | +| `metric` | [`cuvsDistanceType`](/api-reference/c-api-distance-distance#cuvsdistancetype) | | +| `ivf_pq_params` | [`cuvsIvfPqIndexParams_t`](/api-reference/c-api-neighbors-ivf-pq#cuvsivfpqindexparams) | | +| `nn_descent_params` | [`cuvsNNDescentIndexParams_t`](/api-reference/c-api-neighbors-nn-descent#cuvsnndescentindexparams) | | _Source: `c/include/cuvs/neighbors/all_neighbors.h:47`_ + ### cuvsAllNeighborsIndexParamsCreate Create a default all-neighbors index parameters struct. @@ -61,16 +64,17 @@ cuvsError_t cuvsAllNeighborsIndexParamsCreate(cuvsAllNeighborsIndexParams_t* ind | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `index_params` | out | `cuvsAllNeighborsIndexParams_t*` | Pointer to allocated index_params struct | +| `index_params` | out | [`cuvsAllNeighborsIndexParams_t*`](/api-reference/c-api-neighbors-all-neighbors#cuvsallneighborsindexparams) | Pointer to allocated index_params struct | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/neighbors/all_neighbors.h:70`_ + ### cuvsAllNeighborsIndexParamsDestroy Destroy an all-neighbors index parameters struct. @@ -83,11 +87,11 @@ cuvsError_t cuvsAllNeighborsIndexParamsDestroy(cuvsAllNeighborsIndexParams_t ind | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `index_params` | in | `cuvsAllNeighborsIndexParams_t` | Index parameters struct to destroy | +| `index_params` | in | [`cuvsAllNeighborsIndexParams_t`](/api-reference/c-api-neighbors-all-neighbors#cuvsallneighborsindexparams) | Index parameters struct to destroy | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t @@ -97,6 +101,7 @@ _Source: `c/include/cuvs/neighbors/all_neighbors.h:79`_ _Doxygen group: `all_neighbors_c_build`_ + ### cuvsAllNeighborsBuild Build an all-neighbors k-NN graph automatically detecting host vs device dataset. @@ -117,8 +122,8 @@ resources The function automatically detects whether the dataset is host-residen | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | Can be a SNMG multi-GPU resources (`cuvsResources_t`) or single-GPU | -| `params` | in | `cuvsAllNeighborsIndexParams_t` | Build parameters (see cuvsAllNeighborsIndexParams) | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | Can be a SNMG multi-GPU resources (`cuvsResources_t`) or single-GPU | +| `params` | in | [`cuvsAllNeighborsIndexParams_t`](/api-reference/c-api-neighbors-all-neighbors#cuvsallneighborsindexparams) | Build parameters (see cuvsAllNeighborsIndexParams) | | `dataset` | in | `DLManagedTensor*` | 2D tensor [num_rows x dim] on host or device (auto-detected) | | `indices` | out | `DLManagedTensor*` | 2D tensor [num_rows x k] on device (int64) | | `distances` | out | `DLManagedTensor*` | Optional 2D tensor [num_rows x k] on device (float32); can be NULL | @@ -127,6 +132,6 @@ resources The function automatically detects whether the dataset is host-residen **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) _Source: `c/include/cuvs/neighbors/all_neighbors.h:106`_ diff --git a/fern/pages/c_api/c-api-neighbors-brute-force.md b/fern/pages/c_api/c-api-neighbors-brute-force.md index 5aa8adf076..6f6850bc9c 100644 --- a/fern/pages/c_api/c-api-neighbors-brute-force.md +++ b/fern/pages/c_api/c-api-neighbors-brute-force.md @@ -10,6 +10,25 @@ _Source header: `c/include/cuvs/neighbors/brute_force.h`_ _Doxygen group: `bruteforce_c_index`_ + +### cuvsBruteForceIndex + +Struct to hold address of cuvs::neighbors::brute_force::index and its active trained dtype + +```c +typedef struct { ... } cuvsBruteForceIndex; +``` + +**Fields** + +| Name | Type | Description | +| --- | --- | --- | +| `addr` | `uintptr_t` | | +| `dtype` | `DLDataType` | | + +_Source: `c/include/cuvs/neighbors/brute_force.h:26`_ + + ### cuvsBruteForceIndexCreate Allocate BRUTEFORCE index @@ -22,16 +41,17 @@ cuvsError_t cuvsBruteForceIndexCreate(cuvsBruteForceIndex_t* index); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `index` | in | `cuvsBruteForceIndex_t*` | cuvsBruteForceIndex_t to allocate | +| `index` | in | [`cuvsBruteForceIndex_t*`](/api-reference/c-api-neighbors-brute-force#cuvsbruteforceindex) | cuvsBruteForceIndex_t to allocate | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/neighbors/brute_force.h:39`_ + ### cuvsBruteForceIndexDestroy De-allocate BRUTEFORCE index @@ -44,11 +64,11 @@ cuvsError_t cuvsBruteForceIndexDestroy(cuvsBruteForceIndex_t index); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `index` | in | `cuvsBruteForceIndex_t` | cuvsBruteForceIndex_t to de-allocate | +| `index` | in | [`cuvsBruteForceIndex_t`](/api-reference/c-api-neighbors-brute-force#cuvsbruteforceindex) | cuvsBruteForceIndex_t to de-allocate | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) _Source: `c/include/cuvs/neighbors/brute_force.h:46`_ @@ -56,6 +76,7 @@ _Source: `c/include/cuvs/neighbors/brute_force.h:46`_ _Doxygen group: `bruteforce_c_index_build`_ + ### cuvsBruteForceBuild Build a BRUTEFORCE index with a `DLManagedTensor` which has underlying @@ -77,15 +98,15 @@ cuvsBruteForceIndex_t index); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle | | `dataset` | in | `DLManagedTensor*` | DLManagedTensor* training dataset | -| `metric` | in | `cuvsDistanceType` | metric | +| `metric` | in | [`cuvsDistanceType`](/api-reference/c-api-distance-distance#cuvsdistancetype) | metric | | `metric_arg` | in | `float` | metric_arg | -| `index` | out | `cuvsBruteForceIndex_t` | cuvsBruteForceIndex_t Newly built BRUTEFORCE index | +| `index` | out | [`cuvsBruteForceIndex_t`](/api-reference/c-api-neighbors-brute-force#cuvsbruteforceindex) | cuvsBruteForceIndex_t Newly built BRUTEFORCE index | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t @@ -95,6 +116,7 @@ _Source: `c/include/cuvs/neighbors/brute_force.h:92`_ _Doxygen group: `bruteforce_c_index_search`_ + ### cuvsBruteForceSearch Search a BRUTEFORCE index with a `DLManagedTensor` which has underlying @@ -118,16 +140,16 @@ cuvsFilter prefilter); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | -| `index` | in | `cuvsBruteForceIndex_t` | cuvsBruteForceIndex which has been returned by `cuvsBruteForceBuild` | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle | +| `index` | in | [`cuvsBruteForceIndex_t`](/api-reference/c-api-neighbors-brute-force#cuvsbruteforceindex) | cuvsBruteForceIndex which has been returned by `cuvsBruteForceBuild` | | `queries` | in | `DLManagedTensor*` | DLManagedTensor* queries dataset to search | | `neighbors` | out | `DLManagedTensor*` | DLManagedTensor* output `k` neighbors for queries | | `distances` | out | `DLManagedTensor*` | DLManagedTensor* output `k` distances for queries | -| `prefilter` | in | `cuvsFilter` | cuvsFilter input prefilter that can be used to filter queries and neighbors based on the given bitmap. | +| `prefilter` | in | [`cuvsFilter`](/api-reference/c-api-neighbors-common#cuvsfilter) | cuvsFilter input prefilter that can be used to filter queries and neighbors based on the given bitmap. | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) _Source: `c/include/cuvs/neighbors/brute_force.h:148`_ @@ -135,6 +157,7 @@ _Source: `c/include/cuvs/neighbors/brute_force.h:148`_ _Doxygen group: `bruteforce_c_index_serialize`_ + ### cuvsBruteForceSerialize Save the index to file. @@ -151,16 +174,17 @@ The serialization format can be subject to changes, therefore loading an index s | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle | | `filename` | in | `const char*` | the file name for saving the index | -| `index` | in | `cuvsBruteForceIndex_t` | BRUTEFORCE index | +| `index` | in | [`cuvsBruteForceIndex_t`](/api-reference/c-api-neighbors-brute-force#cuvsbruteforceindex) | BRUTEFORCE index | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) _Source: `c/include/cuvs/neighbors/brute_force.h:184`_ + ### cuvsBruteForceDeserialize Load index from file. @@ -177,12 +201,12 @@ The serialization format can be subject to changes, therefore loading an index s | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle | | `filename` | in | `const char*` | the name of the file that stores the index | -| `index` | out | `cuvsBruteForceIndex_t` | BRUTEFORCE index loaded disk | +| `index` | out | [`cuvsBruteForceIndex_t`](/api-reference/c-api-neighbors-brute-force#cuvsbruteforceindex) | BRUTEFORCE index loaded disk | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) _Source: `c/include/cuvs/neighbors/brute_force.h:211`_ diff --git a/fern/pages/c_api/c-api-neighbors-cagra.md b/fern/pages/c_api/c-api-neighbors-cagra.md index 6648552fa9..2db7344aed 100644 --- a/fern/pages/c_api/c-api-neighbors-cagra.md +++ b/fern/pages/c_api/c-api-neighbors-cagra.md @@ -10,6 +10,7 @@ _Source header: `c/include/cuvs/neighbors/cagra.h`_ _Doxygen group: `cagra_c_index_params`_ + ### cuvsCagraGraphBuildAlgo Enum to denote which ANN algorithm is used to build CAGRA graph @@ -27,6 +28,7 @@ enum cuvsCagraGraphBuildAlgo { ... } ; _Source: `c/include/cuvs/neighbors/cagra.h:29`_ + ### cuvsCagraHnswHeuristicType A strategy for selecting the graph build parameters based on similar HNSW index @@ -41,6 +43,7 @@ enum cuvsCagraHnswHeuristicType { ... } ; _Source: `c/include/cuvs/neighbors/cagra.h:54`_ + ### cuvsCagraCompressionParams Parameters for VPQ compression. @@ -62,6 +65,7 @@ struct cuvsCagraCompressionParams { ... } ; _Source: `c/include/cuvs/neighbors/cagra.h:82`_ + ### cuvsAceParams Parameters for ACE (Augmented Core Extraction) graph build. @@ -89,6 +93,7 @@ struct cuvsAceParams { ... } ; _Source: `c/include/cuvs/neighbors/cagra.h:136`_ + ### cuvsCagraIndexParams Supplemental parameters to build CAGRA Index @@ -101,16 +106,17 @@ struct cuvsCagraIndexParams { ... } ; | Name | Type | Description | | --- | --- | --- | -| `metric` | `cuvsDistanceType` | Distance type. | +| `metric` | [`cuvsDistanceType`](/api-reference/c-api-distance-distance#cuvsdistancetype) | Distance type. | | `intermediate_graph_degree` | `size_t` | Degree of input graph for pruning. | | `graph_degree` | `size_t` | Degree of output graph. | -| `build_algo` | `enum cuvsCagraGraphBuildAlgo` | ANN algorithm to build knn graph. | +| `build_algo` | [`enum cuvsCagraGraphBuildAlgo`](/api-reference/c-api-neighbors-cagra#cuvscagragraphbuildalgo) | ANN algorithm to build knn graph. | | `nn_descent_niter` | `size_t` | Number of Iterations to run if building with NN_DESCENT | -| `compression` | `cuvsCagraCompressionParams_t` | Optional: specify compression parameters if compression is desired. NOTE: this is experimental new API, consider it unsafe. | +| `compression` | [`cuvsCagraCompressionParams_t`](/api-reference/c-api-neighbors-cagra#cuvscagracompressionparams) | Optional: specify compression parameters if compression is desired. NOTE: this is experimental new API, consider it unsafe. | | `graph_build_params` | `void*` | Optional: specify graph build params based on build_algo
- IVF_PQ: cuvsIvfPqParams_t
- ACE: cuvsAceParams_t
- Others: nullptr | _Source: `c/include/cuvs/neighbors/cagra.h:201`_ + ### cuvsCagraIndexParamsCreate Allocate CAGRA Index params, and populate with default values @@ -123,16 +129,17 @@ cuvsError_t cuvsCagraIndexParamsCreate(cuvsCagraIndexParams_t* params); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `params` | in | `cuvsCagraIndexParams_t*` | cuvsCagraIndexParams_t to allocate | +| `params` | in | [`cuvsCagraIndexParams_t*`](/api-reference/c-api-neighbors-cagra#cuvscagraindexparams) | cuvsCagraIndexParams_t to allocate | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/neighbors/cagra.h:235`_ + ### cuvsCagraIndexParamsDestroy De-allocate CAGRA Index params @@ -145,16 +152,17 @@ cuvsError_t cuvsCagraIndexParamsDestroy(cuvsCagraIndexParams_t params); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `params` | in | `cuvsCagraIndexParams_t` | | +| `params` | in | [`cuvsCagraIndexParams_t`](/api-reference/c-api-neighbors-cagra#cuvscagraindexparams) | | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/neighbors/cagra.h:243`_ + ### cuvsCagraCompressionParamsCreate Allocate CAGRA Compression params, and populate with default values @@ -167,16 +175,17 @@ cuvsError_t cuvsCagraCompressionParamsCreate(cuvsCagraCompressionParams_t* param | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `params` | in | `cuvsCagraCompressionParams_t*` | cuvsCagraCompressionParams_t to allocate | +| `params` | in | [`cuvsCagraCompressionParams_t*`](/api-reference/c-api-neighbors-cagra#cuvscagracompressionparams) | cuvsCagraCompressionParams_t to allocate | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/neighbors/cagra.h:251`_ + ### cuvsCagraCompressionParamsDestroy De-allocate CAGRA Compression params @@ -189,16 +198,17 @@ cuvsError_t cuvsCagraCompressionParamsDestroy(cuvsCagraCompressionParams_t param | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `params` | in | `cuvsCagraCompressionParams_t` | | +| `params` | in | [`cuvsCagraCompressionParams_t`](/api-reference/c-api-neighbors-cagra#cuvscagracompressionparams) | | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/neighbors/cagra.h:259`_ + ### cuvsAceParamsCreate Allocate ACE params, and populate with default values @@ -211,16 +221,17 @@ cuvsError_t cuvsAceParamsCreate(cuvsAceParams_t* params); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `params` | in | `cuvsAceParams_t*` | cuvsAceParams_t to allocate | +| `params` | in | [`cuvsAceParams_t*`](/api-reference/c-api-neighbors-cagra#cuvsaceparams) | cuvsAceParams_t to allocate | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/neighbors/cagra.h:267`_ + ### cuvsAceParamsDestroy De-allocate ACE params @@ -233,16 +244,17 @@ cuvsError_t cuvsAceParamsDestroy(cuvsAceParams_t params); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `params` | in | `cuvsAceParams_t` | | +| `params` | in | [`cuvsAceParams_t`](/api-reference/c-api-neighbors-cagra#cuvsaceparams) | | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/neighbors/cagra.h:275`_ + ### cuvsCagraIndexParamsFromHnswParams Create CAGRA index parameters similar to an HNSW index @@ -263,17 +275,17 @@ This factory function creates CAGRA parameters that yield a graph compatible wit | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `params` | out | `cuvsCagraIndexParams_t` | The CAGRA index params to populate | +| `params` | out | [`cuvsCagraIndexParams_t`](/api-reference/c-api-neighbors-cagra#cuvscagraindexparams) | The CAGRA index params to populate | | `n_rows` | in | `int64_t` | Number of rows in the dataset | | `dim` | in | `int64_t` | Number of dimensions in the dataset | | `M` | in | `int` | HNSW index parameter M | | `ef_construction` | in | `int` | HNSW index parameter ef_construction | -| `heuristic` | in | `enum cuvsCagraHnswHeuristicType` | Strategy for parameter selection | -| `metric` | in | `cuvsDistanceType` | Distance metric to use | +| `heuristic` | in | [`enum cuvsCagraHnswHeuristicType`](/api-reference/c-api-neighbors-cagra#cuvscagrahnswheuristictype) | Strategy for parameter selection | +| `metric` | in | [`cuvsDistanceType`](/api-reference/c-api-distance-distance#cuvsdistancetype) | Distance metric to use | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t @@ -283,6 +295,7 @@ _Source: `c/include/cuvs/neighbors/cagra.h:292`_ _Doxygen group: `cagra_c_extend_params`_ + ### cuvsCagraExtendParams Supplemental parameters to extend CAGRA Index @@ -299,6 +312,7 @@ struct cuvsCagraExtendParams { ... } ; _Source: `c/include/cuvs/neighbors/cagra.h:312`_ + ### cuvsCagraExtendParamsCreate Allocate CAGRA Extend params, and populate with default values @@ -311,16 +325,17 @@ cuvsError_t cuvsCagraExtendParamsCreate(cuvsCagraExtendParams_t* params); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `params` | in | `cuvsCagraExtendParams_t*` | cuvsCagraExtendParams_t to allocate | +| `params` | in | [`cuvsCagraExtendParams_t*`](/api-reference/c-api-neighbors-cagra#cuvscagraextendparams) | cuvsCagraExtendParams_t to allocate | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/neighbors/cagra.h:329`_ + ### cuvsCagraExtendParamsDestroy De-allocate CAGRA Extend params @@ -333,16 +348,17 @@ cuvsError_t cuvsCagraExtendParamsDestroy(cuvsCagraExtendParams_t params); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `params` | in | `cuvsCagraExtendParams_t` | | +| `params` | in | [`cuvsCagraExtendParams_t`](/api-reference/c-api-neighbors-cagra#cuvscagraextendparams) | | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/neighbors/cagra.h:337`_ + ### cuvsCagraExtend Extend a CAGRA index with a `DLManagedTensor` which has underlying @@ -365,14 +381,14 @@ cuvsCagraIndex_t index); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | -| `params` | in | `cuvsCagraExtendParams_t` | cuvsCagraExtendParams_t used to extend CAGRA index | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle | +| `params` | in | [`cuvsCagraExtendParams_t`](/api-reference/c-api-neighbors-cagra#cuvscagraextendparams) | cuvsCagraExtendParams_t used to extend CAGRA index | | `additional_dataset` | in | `DLManagedTensor*` | DLManagedTensor* additional dataset | -| `index` | in,out | `cuvsCagraIndex_t` | cuvsCagraIndex_t CAGRA index | +| `index` | in,out | [`cuvsCagraIndex_t`](/api-reference/c-api-neighbors-cagra#cuvscagraindex) | cuvsCagraIndex_t CAGRA index | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t @@ -382,6 +398,7 @@ _Source: `c/include/cuvs/neighbors/cagra.h:644`_ _Doxygen group: `cagra_c_search_params`_ + ### cuvsCagraSearchAlgo Enum to denote algorithm used to search CAGRA Index @@ -401,6 +418,7 @@ enum cuvsCagraSearchAlgo { ... } ; _Source: `c/include/cuvs/neighbors/cagra.h:352`_ + ### cuvsCagraHashMode Enum to denote Hash Mode used while searching CAGRA index @@ -419,6 +437,7 @@ enum cuvsCagraHashMode { ... } ; _Source: `c/include/cuvs/neighbors/cagra.h:365`_ + ### cuvsCagraSearchParams Supplemental parameters to search CAGRA index @@ -434,12 +453,12 @@ struct cuvsCagraSearchParams { ... } ; | `max_queries` | `size_t` | Maximum number of queries to search at the same time (batch size). Auto select when 0. | | `itopk_size` | `size_t` | Number of intermediate search results retained during the search. This is the main knob to adjust trade off between accuracy and search speed. Higher values improve the search accuracy. | | `max_iterations` | `size_t` | Upper limit of search iterations. Auto select when 0. | -| `algo` | `enum cuvsCagraSearchAlgo` | Which search implementation to use. | +| `algo` | [`enum cuvsCagraSearchAlgo`](/api-reference/c-api-neighbors-cagra#cuvscagrasearchalgo) | Which search implementation to use. | | `team_size` | `size_t` | Number of threads used to calculate a single distance. 4, 8, 16, or 32. | | `search_width` | `size_t` | Number of graph nodes to select as the starting point for the search in each iteration. aka search width? | | `min_iterations` | `size_t` | Lower limit of search iterations. | | `thread_block_size` | `size_t` | Thread block size. 0, 64, 128, 256, 512, 1024. Auto selection when 0. | -| `hashmap_mode` | `enum cuvsCagraHashMode` | Hashmap type. Auto selection when AUTO. | +| `hashmap_mode` | [`enum cuvsCagraHashMode`](/api-reference/c-api-neighbors-cagra#cuvscagrahashmode) | Hashmap type. Auto selection when AUTO. | | `hashmap_min_bitlen` | `size_t` | Lower limit of hashmap bit length. More than 8. | | `hashmap_max_fill_rate` | `float` | Upper limit of hashmap fill rate. More than 0.1, less than 0.9. | | `num_random_samplings` | `uint32_t` | Number of iterations of initial random seed node selection. 1 or more. | @@ -450,6 +469,7 @@ struct cuvsCagraSearchParams { ... } ; _Source: `c/include/cuvs/neighbors/cagra.h:371`_ + ### cuvsCagraSearchParamsCreate Allocate CAGRA search params, and populate with default values @@ -462,16 +482,17 @@ cuvsError_t cuvsCagraSearchParamsCreate(cuvsCagraSearchParams_t* params); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `params` | in | `cuvsCagraSearchParams_t*` | cuvsCagraSearchParams_t to allocate | +| `params` | in | [`cuvsCagraSearchParams_t*`](/api-reference/c-api-neighbors-cagra#cuvscagrasearchparams) | cuvsCagraSearchParams_t to allocate | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/neighbors/cagra.h:447`_ + ### cuvsCagraSearchParamsDestroy De-allocate CAGRA search params @@ -484,11 +505,11 @@ cuvsError_t cuvsCagraSearchParamsDestroy(cuvsCagraSearchParams_t params); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `params` | in | `cuvsCagraSearchParams_t` | | +| `params` | in | [`cuvsCagraSearchParams_t`](/api-reference/c-api-neighbors-cagra#cuvscagrasearchparams) | | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t @@ -498,6 +519,25 @@ _Source: `c/include/cuvs/neighbors/cagra.h:455`_ _Doxygen group: `cagra_c_index`_ + +### cuvsCagraIndex + +Struct to hold address of cuvs::neighbors::cagra::index and its active trained dtype + +```c +typedef struct { ... } cuvsCagraIndex; +``` + +**Fields** + +| Name | Type | Description | +| --- | --- | --- | +| `addr` | `uintptr_t` | | +| `dtype` | `DLDataType` | | + +_Source: `c/include/cuvs/neighbors/cagra.h:470`_ + + ### cuvsCagraIndexCreate Allocate CAGRA index @@ -510,16 +550,17 @@ cuvsError_t cuvsCagraIndexCreate(cuvsCagraIndex_t* index); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `index` | in | `cuvsCagraIndex_t*` | cuvsCagraIndex_t to allocate | +| `index` | in | [`cuvsCagraIndex_t*`](/api-reference/c-api-neighbors-cagra#cuvscagraindex) | cuvsCagraIndex_t to allocate | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cagraError_t _Source: `c/include/cuvs/neighbors/cagra.h:484`_ + ### cuvsCagraIndexDestroy De-allocate CAGRA index @@ -532,14 +573,15 @@ cuvsError_t cuvsCagraIndexDestroy(cuvsCagraIndex_t index); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `index` | in | `cuvsCagraIndex_t` | cuvsCagraIndex_t to de-allocate | +| `index` | in | [`cuvsCagraIndex_t`](/api-reference/c-api-neighbors-cagra#cuvscagraindex) | cuvsCagraIndex_t to de-allocate | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) _Source: `c/include/cuvs/neighbors/cagra.h:491`_ + ### cuvsCagraIndexGetDims Get dimension of the CAGRA index @@ -552,17 +594,18 @@ cuvsError_t cuvsCagraIndexGetDims(cuvsCagraIndex_t index, int64_t* dim); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `index` | in | `cuvsCagraIndex_t` | CAGRA index | +| `index` | in | [`cuvsCagraIndex_t`](/api-reference/c-api-neighbors-cagra#cuvscagraindex) | CAGRA index | | `dim` | out | `int64_t*` | return dimension of the index | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/neighbors/cagra.h:500`_ + ### cuvsCagraIndexGetSize Get size of the CAGRA index @@ -575,17 +618,18 @@ cuvsError_t cuvsCagraIndexGetSize(cuvsCagraIndex_t index, int64_t* size); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `index` | in | `cuvsCagraIndex_t` | CAGRA index | +| `index` | in | [`cuvsCagraIndex_t`](/api-reference/c-api-neighbors-cagra#cuvscagraindex) | CAGRA index | | `size` | out | `int64_t*` | return number of vectors in the index | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/neighbors/cagra.h:509`_ + ### cuvsCagraIndexGetGraphDegree Get graph degree of the CAGRA index @@ -598,17 +642,18 @@ cuvsError_t cuvsCagraIndexGetGraphDegree(cuvsCagraIndex_t index, int64_t* graph_ | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `index` | in | `cuvsCagraIndex_t` | CAGRA index | +| `index` | in | [`cuvsCagraIndex_t`](/api-reference/c-api-neighbors-cagra#cuvscagraindex) | CAGRA index | | `graph_degree` | out | `int64_t*` | return graph degree | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/neighbors/cagra.h:518`_ + ### cuvsCagraIndexGetDataset Returns a view of the CAGRA dataset @@ -625,17 +670,18 @@ Note that the DLManagedTensor dataset returned will have an associated 'deleter' | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `index` | in | `cuvsCagraIndex_t` | CAGRA index | +| `index` | in | [`cuvsCagraIndex_t`](/api-reference/c-api-neighbors-cagra#cuvscagraindex) | CAGRA index | | `dataset` | out | `DLManagedTensor*` | the dataset used in cagra | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/neighbors/cagra.h:539`_ + ### cuvsCagraIndexGetGraph Returns a view of the CAGRA graph @@ -652,12 +698,12 @@ Note that the DLManagedTensor graph returned will have an associated 'deleter' f | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `index` | in | `cuvsCagraIndex_t` | CAGRA index | +| `index` | in | [`cuvsCagraIndex_t`](/api-reference/c-api-neighbors-cagra#cuvscagraindex) | CAGRA index | | `graph` | out | `DLManagedTensor*` | the output knn graph. | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t @@ -667,6 +713,7 @@ _Source: `c/include/cuvs/neighbors/cagra.h:560`_ _Doxygen group: `cagra_c_index_build`_ + ### cuvsCagraBuild Build a CAGRA index with a `DLManagedTensor` which has underlying @@ -689,14 +736,14 @@ cuvsCagraIndex_t index); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | -| `params` | in | `cuvsCagraIndexParams_t` | cuvsCagraIndexParams_t used to build CAGRA index | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle | +| `params` | in | [`cuvsCagraIndexParams_t`](/api-reference/c-api-neighbors-cagra#cuvscagraindexparams) | cuvsCagraIndexParams_t used to build CAGRA index | | `dataset` | in | `DLManagedTensor*` | DLManagedTensor* training dataset | -| `index` | inout | `cuvsCagraIndex_t` | cuvsCagraIndex_t Newly built CAGRA index. This index needs to be already created with cuvsCagraIndexCreate. | +| `index` | inout | [`cuvsCagraIndex_t`](/api-reference/c-api-neighbors-cagra#cuvscagraindex) | cuvsCagraIndex_t Newly built CAGRA index. This index needs to be already created with cuvsCagraIndexCreate. | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t @@ -706,6 +753,7 @@ _Source: `c/include/cuvs/neighbors/cagra.h:615`_ _Doxygen group: `cagra_c_index_search`_ + ### cuvsCagraSearch Search a CAGRA index with a `DLManagedTensor` which has underlying @@ -730,17 +778,17 @@ cuvsFilter filter); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | -| `params` | in | `cuvsCagraSearchParams_t` | cuvsCagraSearchParams_t used to search CAGRA index | -| `index` | in | `cuvsCagraIndex_t` | cuvsCagraIndex which has been returned by `cuvsCagraBuild` | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle | +| `params` | in | [`cuvsCagraSearchParams_t`](/api-reference/c-api-neighbors-cagra#cuvscagrasearchparams) | cuvsCagraSearchParams_t used to search CAGRA index | +| `index` | in | [`cuvsCagraIndex_t`](/api-reference/c-api-neighbors-cagra#cuvscagraindex) | cuvsCagraIndex which has been returned by `cuvsCagraBuild` | | `queries` | in | `DLManagedTensor*` | DLManagedTensor* queries dataset to search | | `neighbors` | out | `DLManagedTensor*` | DLManagedTensor* output `k` neighbors for queries | | `distances` | out | `DLManagedTensor*` | DLManagedTensor* output `k` distances for queries | -| `filter` | in | `cuvsFilter` | cuvsFilter input filter that can be used to filter queries and neighbors based on the given bitset. | +| `filter` | in | [`cuvsFilter`](/api-reference/c-api-neighbors-common#cuvsfilter) | cuvsFilter input filter that can be used to filter queries and neighbors based on the given bitset. | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) _Source: `c/include/cuvs/neighbors/cagra.h:707`_ @@ -748,6 +796,7 @@ _Source: `c/include/cuvs/neighbors/cagra.h:707`_ _Doxygen group: `cagra_c_index_serialize`_ + ### cuvsCagraSerialize Save the index to file. @@ -765,17 +814,18 @@ Experimental, both the API and the serialization format are subject to change. | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle | | `filename` | in | `const char*` | the file name for saving the index | -| `index` | in | `cuvsCagraIndex_t` | CAGRA index | +| `index` | in | [`cuvsCagraIndex_t`](/api-reference/c-api-neighbors-cagra#cuvscagraindex) | CAGRA index | | `include_dataset` | in | `bool` | Whether or not to write out the dataset to the file. | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) _Source: `c/include/cuvs/neighbors/cagra.h:745`_ + ### cuvsCagraSerializeToHnswlib Save the CAGRA index to file in hnswlib format. @@ -794,16 +844,17 @@ Experimental, both the API and the serialization format are subject to change. | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle | | `filename` | in | `const char*` | the file name for saving the index | -| `index` | in | `cuvsCagraIndex_t` | CAGRA index | +| `index` | in | [`cuvsCagraIndex_t`](/api-reference/c-api-neighbors-cagra#cuvscagraindex) | CAGRA index | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) _Source: `c/include/cuvs/neighbors/cagra.h:774`_ + ### cuvsCagraDeserialize Load index from file. @@ -818,16 +869,17 @@ Experimental, both the API and the serialization format are subject to change. | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle | | `filename` | in | `const char*` | the name of the file that stores the index | -| `index` | inout | `cuvsCagraIndex_t` | cuvsCagraIndex_t CAGRA index loaded from disk. This index needs to be already created with cuvsCagraIndexCreate. | +| `index` | inout | [`cuvsCagraIndex_t`](/api-reference/c-api-neighbors-cagra#cuvscagraindex) | cuvsCagraIndex_t CAGRA index loaded from disk. This index needs to be already created with cuvsCagraIndexCreate. | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) _Source: `c/include/cuvs/neighbors/cagra.h:788`_ + ### cuvsCagraIndexFromArgs Load index from a dataset and graph @@ -844,15 +896,15 @@ cuvsCagraIndex_t index); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | -| `metric` | in | `cuvsDistanceType` | cuvsDistanceType to use in the index | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle | +| `metric` | in | [`cuvsDistanceType`](/api-reference/c-api-distance-distance#cuvsdistancetype) | cuvsDistanceType to use in the index | | `graph` | in | `DLManagedTensor*` | the knn graph to use, shape (size, graph_degree) | | `dataset` | in | `DLManagedTensor*` | the dataset to use, shape (size, dim) | -| `index` | inout | `cuvsCagraIndex_t` | cuvsCagraIndex_t CAGRA index populated with the graph and dataset. This index needs to be already created with cuvsCagraIndexCreate. | +| `index` | inout | [`cuvsCagraIndex_t`](/api-reference/c-api-neighbors-cagra#cuvscagraindex) | cuvsCagraIndex_t CAGRA index populated with the graph and dataset. This index needs to be already created with cuvsCagraIndexCreate. | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) _Source: `c/include/cuvs/neighbors/cagra.h:824`_ @@ -860,6 +912,7 @@ _Source: `c/include/cuvs/neighbors/cagra.h:824`_ _Doxygen group: `cagra_c_index_merge`_ + ### cuvsCagraMerge Merge multiple CAGRA indices into a single CAGRA index. @@ -888,15 +941,15 @@ Example: | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | -| `params` | in | `cuvsCagraIndexParams_t` | cuvsCagraIndexParams_t parameters controlling merge behavior | -| `indices` | in | `cuvsCagraIndex_t*` | Array of input cuvsCagraIndex_t handles to merge | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle | +| `params` | in | [`cuvsCagraIndexParams_t`](/api-reference/c-api-neighbors-cagra#cuvscagraindexparams) | cuvsCagraIndexParams_t parameters controlling merge behavior | +| `indices` | in | [`cuvsCagraIndex_t*`](/api-reference/c-api-neighbors-cagra#cuvscagraindex) | Array of input cuvsCagraIndex_t handles to merge | | `num_indices` | in | `size_t` | Number of input indices | -| `filter` | in | `cuvsFilter` | Filter that can be used to filter out vectors from the merged index | -| `output_index` | out | `cuvsCagraIndex_t` | Output handle that will store the merged index. Must be initialized using `cuvsCagraIndexCreate` before use. | +| `filter` | in | [`cuvsFilter`](/api-reference/c-api-neighbors-common#cuvsfilter) | Filter that can be used to filter out vectors from the merged index | +| `output_index` | out | [`cuvsCagraIndex_t`](/api-reference/c-api-neighbors-cagra#cuvscagraindex) | Output handle that will store the merged index. Must be initialized using `cuvsCagraIndexCreate` before use. | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) _Source: `c/include/cuvs/neighbors/cagra.h:891`_ diff --git a/fern/pages/c_api/c-api-neighbors-common.md b/fern/pages/c_api/c-api-neighbors-common.md index bf50bbfb1d..ac7a08c857 100644 --- a/fern/pages/c_api/c-api-neighbors-common.md +++ b/fern/pages/c_api/c-api-neighbors-common.md @@ -10,6 +10,7 @@ _Source header: `c/include/cuvs/neighbors/common.h`_ _Doxygen group: `filters`_ + ### cuvsFilterType Enum to denote filter type. @@ -28,10 +29,28 @@ enum cuvsFilterType { ... } ; _Source: `c/include/cuvs/neighbors/common.h:23`_ + +### cuvsFilter + +Struct to hold address of cuvs::neighbors::prefilter and its type + +```c +typedef struct { ... } cuvsFilter; +``` + +**Fields** + +| Name | Type | Description | +| --- | --- | --- | +| `addr` | `uintptr_t` | | + +_Source: `c/include/cuvs/neighbors/common.h:36`_ + ## Index Merge _Doxygen group: `index_merge`_ + ### cuvsMergeStrategy Strategy for merging indices. diff --git a/fern/pages/c_api/c-api-neighbors-hnsw.md b/fern/pages/c_api/c-api-neighbors-hnsw.md index a721b5b3b2..f51a771526 100644 --- a/fern/pages/c_api/c-api-neighbors-hnsw.md +++ b/fern/pages/c_api/c-api-neighbors-hnsw.md @@ -10,6 +10,7 @@ _Source header: `c/include/cuvs/neighbors/hnsw.h`_ _Doxygen group: `hnsw_c_index_params`_ + ### cuvsHnswHierarchy Hierarchy for HNSW index when converting from CAGRA index @@ -29,6 +30,7 @@ enum cuvsHnswHierarchy { ... } ; _Source: `c/include/cuvs/neighbors/hnsw.h:30`_ + ### cuvsHnswAceParams Parameters for ACE (Augmented Core Extraction) graph build for HNSW. @@ -55,6 +57,7 @@ struct cuvsHnswAceParams { ... } ; _Source: `c/include/cuvs/neighbors/hnsw.h:46`_ + ### cuvsHnswAceParamsCreate Allocate HNSW ACE params, and populate with default values @@ -67,16 +70,17 @@ cuvsError_t cuvsHnswAceParamsCreate(cuvsHnswAceParams_t* params); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `params` | in | `cuvsHnswAceParams_t*` | cuvsHnswAceParams_t to allocate | +| `params` | in | [`cuvsHnswAceParams_t*`](/api-reference/c-api-neighbors-hnsw#cuvshnswaceparams) | cuvsHnswAceParams_t to allocate | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/neighbors/hnsw.h:97`_ + ### cuvsHnswAceParamsDestroy De-allocate HNSW ACE params @@ -89,16 +93,17 @@ cuvsError_t cuvsHnswAceParamsDestroy(cuvsHnswAceParams_t params); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `params` | in | `cuvsHnswAceParams_t` | | +| `params` | in | [`cuvsHnswAceParams_t`](/api-reference/c-api-neighbors-hnsw#cuvshnswaceparams) | | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/neighbors/hnsw.h:105`_ + ### cuvsHnswIndexParamsCreate Allocate HNSW Index params, and populate with default values @@ -115,12 +120,13 @@ cuvsError_t cuvsHnswIndexParamsCreate(cuvsHnswIndexParams_t* params); **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/neighbors/hnsw.h:141`_ + ### cuvsHnswIndexParamsDestroy De-allocate HNSW Index params @@ -137,7 +143,7 @@ cuvsError_t cuvsHnswIndexParamsDestroy(cuvsHnswIndexParams_t params); **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t @@ -147,6 +153,25 @@ _Source: `c/include/cuvs/neighbors/hnsw.h:149`_ _Doxygen group: `hnsw_c_index`_ + +### cuvsHnswIndex + +Struct to hold address of cuvs::neighbors::Hnsw::index and its active trained dtype + +```c +typedef struct { ... } cuvsHnswIndex; +``` + +**Fields** + +| Name | Type | Description | +| --- | --- | --- | +| `addr` | `uintptr_t` | | +| `dtype` | `DLDataType` | | + +_Source: `c/include/cuvs/neighbors/hnsw.h:164`_ + + ### cuvsHnswIndexCreate Allocate HNSW index @@ -159,16 +184,17 @@ cuvsError_t cuvsHnswIndexCreate(cuvsHnswIndex_t* index); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `index` | in | `cuvsHnswIndex_t*` | cuvsHnswIndex_t to allocate | +| `index` | in | [`cuvsHnswIndex_t*`](/api-reference/c-api-neighbors-hnsw#cuvshnswindex) | cuvsHnswIndex_t to allocate | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) HnswError_t _Source: `c/include/cuvs/neighbors/hnsw.h:178`_ + ### cuvsHnswIndexDestroy De-allocate HNSW index @@ -181,11 +207,11 @@ cuvsError_t cuvsHnswIndexDestroy(cuvsHnswIndex_t index); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `index` | in | `cuvsHnswIndex_t` | cuvsHnswIndex_t to de-allocate | +| `index` | in | [`cuvsHnswIndex_t`](/api-reference/c-api-neighbors-hnsw#cuvshnswindex) | cuvsHnswIndex_t to de-allocate | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) _Source: `c/include/cuvs/neighbors/hnsw.h:185`_ @@ -193,6 +219,7 @@ _Source: `c/include/cuvs/neighbors/hnsw.h:185`_ _Doxygen group: `hnsw_c_extend_params`_ + ### cuvsHnswExtendParams Parameters for extending HNSW index @@ -209,6 +236,7 @@ struct cuvsHnswExtendParams { ... } ; _Source: `c/include/cuvs/neighbors/hnsw.h:196`_ + ### cuvsHnswExtendParamsCreate Allocate HNSW extend params, and populate with default values @@ -221,16 +249,17 @@ cuvsError_t cuvsHnswExtendParamsCreate(cuvsHnswExtendParams_t* params); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `params` | in | `cuvsHnswExtendParams_t*` | cuvsHnswExtendParams_t to allocate | +| `params` | in | [`cuvsHnswExtendParams_t*`](/api-reference/c-api-neighbors-hnsw#cuvshnswextendparams) | cuvsHnswExtendParams_t to allocate | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/neighbors/hnsw.h:209`_ + ### cuvsHnswExtendParamsDestroy De-allocate HNSW extend params @@ -243,11 +272,11 @@ cuvsError_t cuvsHnswExtendParamsDestroy(cuvsHnswExtendParams_t params); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `params` | in | `cuvsHnswExtendParams_t` | cuvsHnswExtendParams_t to de-allocate | +| `params` | in | [`cuvsHnswExtendParams_t`](/api-reference/c-api-neighbors-hnsw#cuvshnswextendparams) | cuvsHnswExtendParams_t to de-allocate | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t @@ -257,6 +286,7 @@ _Source: `c/include/cuvs/neighbors/hnsw.h:218`_ _Doxygen group: `hnsw_c_index_load`_ + ### cuvsHnswFromCagra Convert a CAGRA Index to an HNSW index. @@ -277,14 +307,14 @@ NOTE: When hierarchy is: | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle | | `params` | in | `cuvsHnswIndexParams_t` | cuvsHnswIndexParams_t used to load Hnsw index | -| `cagra_index` | in | `cuvsCagraIndex_t` | cuvsCagraIndex_t to convert to HNSW index | -| `hnsw_index` | out | `cuvsHnswIndex_t` | cuvsHnswIndex_t to return the HNSW index | +| `cagra_index` | in | [`cuvsCagraIndex_t`](/api-reference/c-api-neighbors-cagra#cuvscagraindex) | cuvsCagraIndex_t to convert to HNSW index | +| `hnsw_index` | out | [`cuvsHnswIndex_t`](/api-reference/c-api-neighbors-hnsw#cuvshnswindex) | cuvsHnswIndex_t to return the HNSW index | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t @@ -294,6 +324,7 @@ _Source: `c/include/cuvs/neighbors/hnsw.h:270`_ _Doxygen group: `hnsw_c_index_build`_ + ### cuvsHnswBuild Build an HNSW index using ACE (Augmented Core Extraction) algorithm. @@ -317,14 +348,14 @@ NOTE: This function requires CUDA to be available at runtime. | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle | | `params` | in | `cuvsHnswIndexParams_t` | cuvsHnswIndexParams_t with ACE parameters configured | | `dataset` | in | `DLManagedTensor*` | DLManagedTensor* host dataset to build index from | -| `index` | out | `cuvsHnswIndex_t` | cuvsHnswIndex_t to return the built HNSW index | +| `index` | out | [`cuvsHnswIndex_t`](/api-reference/c-api-neighbors-hnsw#cuvshnswindex) | cuvsHnswIndex_t to return the built HNSW index | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t @@ -334,6 +365,7 @@ _Source: `c/include/cuvs/neighbors/hnsw.h:347`_ _Doxygen group: `hnsw_c_index_extend`_ + ### cuvsHnswExtend Add new vectors to an HNSW index @@ -351,14 +383,14 @@ NOTE: The HNSW index can only be extended when the hierarchy is `CPU` when conve | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | -| `params` | in | `cuvsHnswExtendParams_t` | cuvsHnswExtendParams_t used to extend Hnsw index | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle | +| `params` | in | [`cuvsHnswExtendParams_t`](/api-reference/c-api-neighbors-hnsw#cuvshnswextendparams) | cuvsHnswExtendParams_t used to extend Hnsw index | | `additional_dataset` | in | `DLManagedTensor*` | DLManagedTensor* additional dataset to extend the index | -| `index` | inout | `cuvsHnswIndex_t` | cuvsHnswIndex_t to extend | +| `index` | inout | [`cuvsHnswIndex_t`](/api-reference/c-api-neighbors-hnsw#cuvshnswindex) | cuvsHnswIndex_t to extend | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t @@ -368,6 +400,7 @@ _Source: `c/include/cuvs/neighbors/hnsw.h:405`_ _Doxygen group: `hnsw_c_search_params`_ + ### cuvsHnswSearchParams C API for hnswlib wrapper search params @@ -385,6 +418,7 @@ struct cuvsHnswSearchParams { ... } ; _Source: `c/include/cuvs/neighbors/hnsw.h:419`_ + ### cuvsHnswSearchParamsCreate Allocate HNSW search params, and populate with default values @@ -397,16 +431,17 @@ cuvsError_t cuvsHnswSearchParamsCreate(cuvsHnswSearchParams_t* params); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `params` | in | `cuvsHnswSearchParams_t*` | cuvsHnswSearchParams_t to allocate | +| `params` | in | [`cuvsHnswSearchParams_t*`](/api-reference/c-api-neighbors-hnsw#cuvshnswsearchparams) | cuvsHnswSearchParams_t to allocate | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/neighbors/hnsw.h:432`_ + ### cuvsHnswSearchParamsDestroy De-allocate HNSW search params @@ -419,11 +454,11 @@ cuvsError_t cuvsHnswSearchParamsDestroy(cuvsHnswSearchParams_t params); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `params` | in | `cuvsHnswSearchParams_t` | cuvsHnswSearchParams_t to de-allocate | +| `params` | in | [`cuvsHnswSearchParams_t`](/api-reference/c-api-neighbors-hnsw#cuvshnswsearchparams) | cuvsHnswSearchParams_t to de-allocate | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t @@ -433,6 +468,7 @@ _Source: `c/include/cuvs/neighbors/hnsw.h:440`_ _Doxygen group: `hnsw_c_index_search`_ + ### cuvsHnswSearch Search a HNSW index with a `DLManagedTensor` which has underlying @@ -456,16 +492,16 @@ DLManagedTensor* distances); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | -| `params` | in | `cuvsHnswSearchParams_t` | cuvsHnswSearchParams_t used to search Hnsw index | -| `index` | in | `cuvsHnswIndex_t` | cuvsHnswIndex which has been returned by `cuvsHnswFromCagra` | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle | +| `params` | in | [`cuvsHnswSearchParams_t`](/api-reference/c-api-neighbors-hnsw#cuvshnswsearchparams) | cuvsHnswSearchParams_t used to search Hnsw index | +| `index` | in | [`cuvsHnswIndex_t`](/api-reference/c-api-neighbors-hnsw#cuvshnswindex) | cuvsHnswIndex which has been returned by `cuvsHnswFromCagra` | | `queries` | in | `DLManagedTensor*` | DLManagedTensor* queries dataset to search | | `neighbors` | out | `DLManagedTensor*` | DLManagedTensor* output `k` neighbors for queries | | `distances` | out | `DLManagedTensor*` | DLManagedTensor* output `k` distances for queries | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) _Source: `c/include/cuvs/neighbors/hnsw.h:499`_ @@ -473,6 +509,7 @@ _Source: `c/include/cuvs/neighbors/hnsw.h:499`_ _Doxygen group: `hnsw_c_index_serialize`_ + ### cuvsHnswSerialize Serialize a CAGRA index to a file as an hnswlib index @@ -487,18 +524,19 @@ NOTE: When hierarchy is `NONE`, the saved hnswlib index is immutable and can onl | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle | | `filename` | in | `const char*` | the name of the file to save the index | -| `index` | in | `cuvsHnswIndex_t` | cuvsHnswIndex_t to serialize | +| `index` | in | [`cuvsHnswIndex_t`](/api-reference/c-api-neighbors-hnsw#cuvshnswindex) | cuvsHnswIndex_t to serialize | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/neighbors/hnsw.h:554`_ + ### cuvsHnswDeserialize Load hnswlib index from file which was serialized from a HNSW index. @@ -518,15 +556,15 @@ NOTE: When hierarchy is `NONE`, the loaded hnswlib index is immutable, and only | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle | | `params` | in | `cuvsHnswIndexParams_t` | cuvsHnswIndexParams_t used to load Hnsw index | | `filename` | in | `const char*` | the name of the file that stores the index | | `dim` | in | `int` | the dimension of the vectors in the index | -| `metric` | in | `cuvsDistanceType` | the distance metric used to build the index | -| `index` | out | `cuvsHnswIndex_t` | HNSW index loaded disk | +| `metric` | in | [`cuvsDistanceType`](/api-reference/c-api-distance-distance#cuvsdistancetype) | the distance metric used to build the index | +| `index` | out | [`cuvsHnswIndex_t`](/api-reference/c-api-neighbors-hnsw#cuvshnswindex) | HNSW index loaded disk | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) _Source: `c/include/cuvs/neighbors/hnsw.h:592`_ diff --git a/fern/pages/c_api/c-api-neighbors-ivf-flat.md b/fern/pages/c_api/c-api-neighbors-ivf-flat.md index e9382fbb09..591dd311b3 100644 --- a/fern/pages/c_api/c-api-neighbors-ivf-flat.md +++ b/fern/pages/c_api/c-api-neighbors-ivf-flat.md @@ -10,6 +10,7 @@ _Source header: `c/include/cuvs/neighbors/ivf_flat.h`_ _Doxygen group: `ivf_flat_c_index_params`_ + ### cuvsIvfFlatIndexParams Supplemental parameters to build IVF-Flat Index @@ -22,7 +23,7 @@ struct cuvsIvfFlatIndexParams { ... } ; | Name | Type | Description | | --- | --- | --- | -| `metric` | `cuvsDistanceType` | Distance type. | +| `metric` | [`cuvsDistanceType`](/api-reference/c-api-distance-distance#cuvsdistancetype) | Distance type. | | `metric_arg` | `float` | The argument used by some distance metrics. | | `add_data_on_build` | `bool` | Whether to add the dataset content to the index, i.e.:
- `true` means the index is filled with the dataset vectors and ready to search after calling `build`.
- `false` means `build` only trains the underlying model (e.g. quantizer or clustering), but the index is left empty; you'd need to call `extend` on the index afterwards to populate it. | | `n_lists` | `uint32_t` | The number of inverted lists (clusters) | @@ -33,6 +34,7 @@ struct cuvsIvfFlatIndexParams { ... } ; _Source: `c/include/cuvs/neighbors/ivf_flat.h:27`_ + ### cuvsIvfFlatIndexParamsCreate Allocate IVF-Flat Index params, and populate with default values @@ -45,16 +47,17 @@ cuvsError_t cuvsIvfFlatIndexParamsCreate(cuvsIvfFlatIndexParams_t* index_params) | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `index_params` | in | `cuvsIvfFlatIndexParams_t*` | cuvsIvfFlatIndexParams_t to allocate | +| `index_params` | in | [`cuvsIvfFlatIndexParams_t*`](/api-reference/c-api-neighbors-ivf-flat#cuvsivfflatindexparams) | cuvsIvfFlatIndexParams_t to allocate | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/neighbors/ivf_flat.h:80`_ + ### cuvsIvfFlatIndexParamsDestroy De-allocate IVF-Flat Index params @@ -67,11 +70,11 @@ cuvsError_t cuvsIvfFlatIndexParamsDestroy(cuvsIvfFlatIndexParams_t index_params) | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `index_params` | in | `cuvsIvfFlatIndexParams_t` | | +| `index_params` | in | [`cuvsIvfFlatIndexParams_t`](/api-reference/c-api-neighbors-ivf-flat#cuvsivfflatindexparams) | | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t @@ -81,6 +84,7 @@ _Source: `c/include/cuvs/neighbors/ivf_flat.h:88`_ _Doxygen group: `ivf_flat_c_search_params`_ + ### cuvsIvfFlatSearchParams Supplemental parameters to search IVF-Flat index @@ -97,6 +101,7 @@ struct cuvsIvfFlatSearchParams { ... } ; _Source: `c/include/cuvs/neighbors/ivf_flat.h:101`_ + ### cuvsIvfFlatSearchParamsCreate Allocate IVF-Flat search params, and populate with default values @@ -109,16 +114,17 @@ cuvsError_t cuvsIvfFlatSearchParamsCreate(cuvsIvfFlatSearchParams_t* params); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `params` | in | `cuvsIvfFlatSearchParams_t*` | cuvsIvfFlatSearchParams_t to allocate | +| `params` | in | [`cuvsIvfFlatSearchParams_t*`](/api-reference/c-api-neighbors-ivf-flat#cuvsivfflatsearchparams) | cuvsIvfFlatSearchParams_t to allocate | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/neighbors/ivf_flat.h:114`_ + ### cuvsIvfFlatSearchParamsDestroy De-allocate IVF-Flat search params @@ -131,11 +137,11 @@ cuvsError_t cuvsIvfFlatSearchParamsDestroy(cuvsIvfFlatSearchParams_t params); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `params` | in | `cuvsIvfFlatSearchParams_t` | | +| `params` | in | [`cuvsIvfFlatSearchParams_t`](/api-reference/c-api-neighbors-ivf-flat#cuvsivfflatsearchparams) | | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t @@ -145,6 +151,25 @@ _Source: `c/include/cuvs/neighbors/ivf_flat.h:122`_ _Doxygen group: `ivf_flat_c_index`_ + +### cuvsIvfFlatIndex + +Struct to hold address of cuvs::neighbors::ivf_flat::index and its active trained dtype + +```c +typedef struct { ... } cuvsIvfFlatIndex; +``` + +**Fields** + +| Name | Type | Description | +| --- | --- | --- | +| `addr` | `uintptr_t` | | +| `dtype` | `DLDataType` | | + +_Source: `c/include/cuvs/neighbors/ivf_flat.h:135`_ + + ### cuvsIvfFlatIndexCreate Allocate IVF-Flat index @@ -157,16 +182,17 @@ cuvsError_t cuvsIvfFlatIndexCreate(cuvsIvfFlatIndex_t* index); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `index` | in | `cuvsIvfFlatIndex_t*` | cuvsIvfFlatIndex_t to allocate | +| `index` | in | [`cuvsIvfFlatIndex_t*`](/api-reference/c-api-neighbors-ivf-flat#cuvsivfflatindex) | cuvsIvfFlatIndex_t to allocate | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/neighbors/ivf_flat.h:148`_ + ### cuvsIvfFlatIndexDestroy De-allocate IVF-Flat index @@ -179,14 +205,15 @@ cuvsError_t cuvsIvfFlatIndexDestroy(cuvsIvfFlatIndex_t index); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `index` | in | `cuvsIvfFlatIndex_t` | cuvsIvfFlatIndex_t to de-allocate | +| `index` | in | [`cuvsIvfFlatIndex_t`](/api-reference/c-api-neighbors-ivf-flat#cuvsivfflatindex) | cuvsIvfFlatIndex_t to de-allocate | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) _Source: `c/include/cuvs/neighbors/ivf_flat.h:155`_ + ### cuvsIvfFlatIndexGetNLists Get the number of clusters/inverted lists @@ -199,15 +226,16 @@ cuvsError_t cuvsIvfFlatIndexGetNLists(cuvsIvfFlatIndex_t index, int64_t* n_lists | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `index` | | `cuvsIvfFlatIndex_t` | | +| `index` | | [`cuvsIvfFlatIndex_t`](/api-reference/c-api-neighbors-ivf-flat#cuvsivfflatindex) | | | `n_lists` | | `int64_t*` | | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) _Source: `c/include/cuvs/neighbors/ivf_flat.h:158`_ + ### cuvsIvfFlatIndexGetDim Get the dimensionality of the data @@ -220,15 +248,16 @@ cuvsError_t cuvsIvfFlatIndexGetDim(cuvsIvfFlatIndex_t index, int64_t* dim); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `index` | | `cuvsIvfFlatIndex_t` | | +| `index` | | [`cuvsIvfFlatIndex_t`](/api-reference/c-api-neighbors-ivf-flat#cuvsivfflatindex) | | | `dim` | | `int64_t*` | | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) _Source: `c/include/cuvs/neighbors/ivf_flat.h:161`_ + ### cuvsIvfFlatIndexGetCenters Get the cluster centers corresponding to the lists [n_lists, dim] @@ -241,12 +270,12 @@ cuvsError_t cuvsIvfFlatIndexGetCenters(cuvsIvfFlatIndex_t index, DLManagedTensor | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `index` | in | `cuvsIvfFlatIndex_t` | cuvsIvfFlatIndex_t Built Ivf-Flat Index | +| `index` | in | [`cuvsIvfFlatIndex_t`](/api-reference/c-api-neighbors-ivf-flat#cuvsivfflatindex) | cuvsIvfFlatIndex_t Built Ivf-Flat Index | | `centers` | out | `DLManagedTensor*` | Preallocated array on host or device memory to store output, [n_lists, dim] | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t @@ -256,6 +285,7 @@ _Source: `c/include/cuvs/neighbors/ivf_flat.h:170`_ _Doxygen group: `ivf_flat_c_index_build`_ + ### cuvsIvfFlatBuild Build a IVF-Flat index with a `DLManagedTensor` which has underlying @@ -277,14 +307,14 @@ cuvsIvfFlatIndex_t index); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | -| `index_params` | in | `cuvsIvfFlatIndexParams_t` | cuvsIvfFlatIndexParams_t used to build IVF-Flat index | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle | +| `index_params` | in | [`cuvsIvfFlatIndexParams_t`](/api-reference/c-api-neighbors-ivf-flat#cuvsivfflatindexparams) | cuvsIvfFlatIndexParams_t used to build IVF-Flat index | | `dataset` | in | `DLManagedTensor*` | DLManagedTensor* training dataset | -| `index` | out | `cuvsIvfFlatIndex_t` | cuvsIvfFlatIndex_t Newly built IVF-Flat index | +| `index` | out | [`cuvsIvfFlatIndex_t`](/api-reference/c-api-neighbors-ivf-flat#cuvsivfflatindex) | cuvsIvfFlatIndex_t Newly built IVF-Flat index | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t @@ -294,6 +324,7 @@ _Source: `c/include/cuvs/neighbors/ivf_flat.h:222`_ _Doxygen group: `ivf_flat_c_index_search`_ + ### cuvsIvfFlatSearch Search a IVF-Flat index with a `DLManagedTensor` which has underlying @@ -318,17 +349,17 @@ cuvsFilter filter); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | -| `search_params` | in | `cuvsIvfFlatSearchParams_t` | cuvsIvfFlatSearchParams_t used to search IVF-Flat index | -| `index` | in | `cuvsIvfFlatIndex_t` | ivfFlatIndex which has been returned by `ivfFlatBuild` | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle | +| `search_params` | in | [`cuvsIvfFlatSearchParams_t`](/api-reference/c-api-neighbors-ivf-flat#cuvsivfflatsearchparams) | cuvsIvfFlatSearchParams_t used to search IVF-Flat index | +| `index` | in | [`cuvsIvfFlatIndex_t`](/api-reference/c-api-neighbors-ivf-flat#cuvsivfflatindex) | ivfFlatIndex which has been returned by `ivfFlatBuild` | | `queries` | in | `DLManagedTensor*` | DLManagedTensor* queries dataset to search | | `neighbors` | out | `DLManagedTensor*` | DLManagedTensor* output `k` neighbors for queries | | `distances` | out | `DLManagedTensor*` | DLManagedTensor* output `k` distances for queries | -| `filter` | in | `cuvsFilter` | cuvsFilter input filter that can be used to filter queries and neighbors based on the given bitset. | +| `filter` | in | [`cuvsFilter`](/api-reference/c-api-neighbors-common#cuvsfilter) | cuvsFilter input filter that can be used to filter queries and neighbors based on the given bitset. | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) _Source: `c/include/cuvs/neighbors/ivf_flat.h:279`_ @@ -336,6 +367,7 @@ _Source: `c/include/cuvs/neighbors/ivf_flat.h:279`_ _Doxygen group: `ivf_flat_c_index_serialize`_ + ### cuvsIvfFlatSerialize Save the index to file. @@ -352,16 +384,17 @@ Experimental, both the API and the serialization format are subject to change. | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle | | `filename` | in | `const char*` | the file name for saving the index | -| `index` | in | `cuvsIvfFlatIndex_t` | IVF-Flat index | +| `index` | in | [`cuvsIvfFlatIndex_t`](/api-reference/c-api-neighbors-ivf-flat#cuvsivfflatindex) | IVF-Flat index | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) _Source: `c/include/cuvs/neighbors/ivf_flat.h:315`_ + ### cuvsIvfFlatDeserialize Load index from file. @@ -378,13 +411,13 @@ Experimental, both the API and the serialization format are subject to change. | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle | | `filename` | in | `const char*` | the name of the file that stores the index | -| `index` | out | `cuvsIvfFlatIndex_t` | IVF-Flat index loaded disk | +| `index` | out | [`cuvsIvfFlatIndex_t`](/api-reference/c-api-neighbors-ivf-flat#cuvsivfflatindex) | IVF-Flat index loaded disk | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) _Source: `c/include/cuvs/neighbors/ivf_flat.h:328`_ @@ -392,6 +425,7 @@ _Source: `c/include/cuvs/neighbors/ivf_flat.h:328`_ _Doxygen group: `ivf_flat_c_index_extend`_ + ### cuvsIvfFlatExtend Extend the index with the new data. @@ -407,14 +441,14 @@ cuvsIvfFlatIndex_t index); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle | | `new_vectors` | in | `DLManagedTensor*` | DLManagedTensor* the new vectors to add to the index | | `new_indices` | in | `DLManagedTensor*` | DLManagedTensor* vector of new indices for the new vectors | -| `index` | inout | `cuvsIvfFlatIndex_t` | IVF-Flat index to be extended | +| `index` | inout | [`cuvsIvfFlatIndex_t`](/api-reference/c-api-neighbors-ivf-flat#cuvsivfflatindex) | IVF-Flat index to be extended | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t diff --git a/fern/pages/c_api/c-api-neighbors-ivf-pq.md b/fern/pages/c_api/c-api-neighbors-ivf-pq.md index b9209c959a..fc7f8767b0 100644 --- a/fern/pages/c_api/c-api-neighbors-ivf-pq.md +++ b/fern/pages/c_api/c-api-neighbors-ivf-pq.md @@ -10,6 +10,7 @@ _Source header: `c/include/cuvs/neighbors/ivf_pq.h`_ _Doxygen group: `ivf_pq_c_index_params`_ + ### cuvsIvfPqCodebookGen A type for specifying how PQ codebooks are created @@ -27,6 +28,7 @@ enum cuvsIvfPqCodebookGen { ... } ; _Source: `c/include/cuvs/neighbors/ivf_pq.h:26`_ + ### cuvsIvfPqListLayout A type for specifying the memory layout of IVF-PQ list data @@ -44,6 +46,7 @@ enum cuvsIvfPqListLayout { ... } ; _Source: `c/include/cuvs/neighbors/ivf_pq.h:35`_ + ### cuvsIvfPqIndexParams Supplemental parameters to build IVF-PQ Index @@ -56,7 +59,7 @@ struct cuvsIvfPqIndexParams { ... } ; | Name | Type | Description | | --- | --- | --- | -| `metric` | `cuvsDistanceType` | Distance type. | +| `metric` | [`cuvsDistanceType`](/api-reference/c-api-distance-distance#cuvsdistancetype) | Distance type. | | `metric_arg` | `float` | The argument used by some distance metrics. | | `add_data_on_build` | `bool` | Whether to add the dataset content to the index, i.e.:
- `true` means the index is filled with the dataset vectors and ready to search after calling `build`.
- `false` means `build` only trains the underlying model (e.g. quantizer or clustering), but the index is left empty; you'd need to call `extend` on the index afterwards to populate it. | | `n_lists` | `uint32_t` | The number of inverted lists (clusters) Hint: the number of vectors per cluster (`n_rows/n_lists`) should be approximately 1,000 to 10,000. | @@ -64,14 +67,15 @@ struct cuvsIvfPqIndexParams { ... } ; | `kmeans_trainset_fraction` | `double` | The fraction of data to use during iterative kmeans building. | | `pq_bits` | `uint32_t` | The bit length of the vector element after compression by PQ. Possible values: [4, 5, 6, 7, 8]. Hint: the smaller the 'pq_bits', the smaller the index size and the better the search performance, but the lower the recall. | | `pq_dim` | `uint32_t` | The dimensionality of the vector after compression by PQ. When zero, an optimal value is selected using a heuristic. NB: `pq_dim * pq_bits` must be a multiple of 8. Hint: a smaller 'pq_dim' results in a smaller index size and better search performance, but lower recall. If 'pq_bits' is 8, 'pq_dim' can be set to any number, but multiple of 8 are desirable for good performance. If 'pq_bits' is not 8, 'pq_dim' should be a multiple of 8. For good performance, it is desirable that 'pq_dim' is a multiple of 32. Ideally, 'pq_dim' should be also a divisor of the dataset dim. | -| `codebook_kind` | `enum cuvsIvfPqCodebookGen` | How PQ codebooks are created. | +| `codebook_kind` | [`enum cuvsIvfPqCodebookGen`](/api-reference/c-api-neighbors-ivf-pq#cuvsivfpqcodebookgen) | How PQ codebooks are created. | | `force_random_rotation` | `bool` | Apply a random rotation matrix on the input data and queries even if `dim % pq_dim == 0`. Note: if `dim` is not multiple of `pq_dim`, a random rotation is always applied to the input data and queries to transform the working space from `dim` to `rot_dim`, which may be slightly larger than the original space and and is a multiple of `pq_dim` (`rot_dim % pq_dim == 0`). However, this transform is not necessary when `dim` is multiple of `pq_dim` (`dim == rot_dim`, hence no need in adding "extra" data columns / features). By default, if `dim == rot_dim`, the rotation transform is initialized with the identity matrix. When `force_random_rotation == true`, a random orthogonal transform matrix is generated regardless of the values of `dim` and `pq_dim`. | | `conservative_memory_allocation` | `bool` | By default, the algorithm allocates more space than necessary for individual clusters (`list_data`). This allows to amortize the cost of memory allocation and reduce the number of data copies during repeated calls to `extend` (extending the database). The alternative is the conservative allocation behavior; when enabled, the algorithm always allocates the minimum amount of memory required to store the given number of records. Set this flag to `true` if you prefer to use as little GPU memory for the database as possible. | | `max_train_points_per_pq_code` | `uint32_t` | The max number of data points to use per PQ code during PQ codebook training. Using more data points per PQ code may increase the quality of PQ codebook but may also increase the build time. The parameter is applied to both PQ codebook generation methods, i.e., PER_SUBSPACE and PER_CLUSTER. In both cases, we will use `pq_book_size * max_train_points_per_pq_code` training points to train each codebook. | -| `codes_layout` | `enum cuvsIvfPqListLayout` | Memory layout of the IVF-PQ list data.
- CUVS_IVF_PQ_LIST_LAYOUT_FLAT: Codes are stored contiguously, one vector's codes after another.
- CUVS_IVF_PQ_LIST_LAYOUT_INTERLEAVED: Codes are interleaved for optimized search performance. This is the default and recommended for search workloads. | +| `codes_layout` | [`enum cuvsIvfPqListLayout`](/api-reference/c-api-neighbors-ivf-pq#cuvsivfpqlistlayout) | Memory layout of the IVF-PQ list data.
- CUVS_IVF_PQ_LIST_LAYOUT_FLAT: Codes are stored contiguously, one vector's codes after another.
- CUVS_IVF_PQ_LIST_LAYOUT_INTERLEAVED: Codes are interleaved for optimized search performance. This is the default and recommended for search workloads. | _Source: `c/include/cuvs/neighbors/ivf_pq.h:44`_ + ### cuvsIvfPqIndexParamsCreate Allocate IVF-PQ Index params, and populate with default values @@ -84,16 +88,17 @@ cuvsError_t cuvsIvfPqIndexParamsCreate(cuvsIvfPqIndexParams_t* index_params); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `index_params` | in | `cuvsIvfPqIndexParams_t*` | cuvsIvfPqIndexParams_t to allocate | +| `index_params` | in | [`cuvsIvfPqIndexParams_t*`](/api-reference/c-api-neighbors-ivf-pq#cuvsivfpqindexparams) | cuvsIvfPqIndexParams_t to allocate | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/neighbors/ivf_pq.h:144`_ + ### cuvsIvfPqIndexParamsDestroy De-allocate IVF-PQ Index params @@ -106,11 +111,11 @@ cuvsError_t cuvsIvfPqIndexParamsDestroy(cuvsIvfPqIndexParams_t index_params); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `index_params` | in | `cuvsIvfPqIndexParams_t` | | +| `index_params` | in | [`cuvsIvfPqIndexParams_t`](/api-reference/c-api-neighbors-ivf-pq#cuvsivfpqindexparams) | | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t @@ -120,6 +125,7 @@ _Source: `c/include/cuvs/neighbors/ivf_pq.h:152`_ _Doxygen group: `ivf_pq_c_search_params`_ + ### cuvsIvfPqSearchParams Supplemental parameters to search IVF-PQ index @@ -141,6 +147,7 @@ struct cuvsIvfPqSearchParams { ... } ; _Source: `c/include/cuvs/neighbors/ivf_pq.h:165`_ + ### cuvsIvfPqSearchParamsCreate Allocate IVF-PQ search params, and populate with default values @@ -153,16 +160,17 @@ cuvsError_t cuvsIvfPqSearchParamsCreate(cuvsIvfPqSearchParams_t* params); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `params` | in | `cuvsIvfPqSearchParams_t*` | cuvsIvfPqSearchParams_t to allocate | +| `params` | in | [`cuvsIvfPqSearchParams_t*`](/api-reference/c-api-neighbors-ivf-pq#cuvsivfpqsearchparams) | cuvsIvfPqSearchParams_t to allocate | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/neighbors/ivf_pq.h:227`_ + ### cuvsIvfPqSearchParamsDestroy De-allocate IVF-PQ search params @@ -175,11 +183,11 @@ cuvsError_t cuvsIvfPqSearchParamsDestroy(cuvsIvfPqSearchParams_t params); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `params` | in | `cuvsIvfPqSearchParams_t` | | +| `params` | in | [`cuvsIvfPqSearchParams_t`](/api-reference/c-api-neighbors-ivf-pq#cuvsivfpqsearchparams) | | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t @@ -189,6 +197,25 @@ _Source: `c/include/cuvs/neighbors/ivf_pq.h:235`_ _Doxygen group: `ivf_pq_c_index`_ + +### cuvsIvfPqIndex + +Struct to hold address of cuvs::neighbors::ivf_pq::index and its active trained dtype + +```c +typedef struct { ... } cuvsIvfPqIndex; +``` + +**Fields** + +| Name | Type | Description | +| --- | --- | --- | +| `addr` | `uintptr_t` | | +| `dtype` | `DLDataType` | | + +_Source: `c/include/cuvs/neighbors/ivf_pq.h:248`_ + + ### cuvsIvfPqIndexCreate Allocate IVF-PQ index @@ -201,16 +228,17 @@ cuvsError_t cuvsIvfPqIndexCreate(cuvsIvfPqIndex_t* index); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `index` | in | `cuvsIvfPqIndex_t*` | cuvsIvfPqIndex_t to allocate | +| `index` | in | [`cuvsIvfPqIndex_t*`](/api-reference/c-api-neighbors-ivf-pq#cuvsivfpqindex) | cuvsIvfPqIndex_t to allocate | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/neighbors/ivf_pq.h:261`_ + ### cuvsIvfPqIndexDestroy De-allocate IVF-PQ index @@ -223,14 +251,15 @@ cuvsError_t cuvsIvfPqIndexDestroy(cuvsIvfPqIndex_t index); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `index` | in | `cuvsIvfPqIndex_t` | cuvsIvfPqIndex_t to de-allocate | +| `index` | in | [`cuvsIvfPqIndex_t`](/api-reference/c-api-neighbors-ivf-pq#cuvsivfpqindex) | cuvsIvfPqIndex_t to de-allocate | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) _Source: `c/include/cuvs/neighbors/ivf_pq.h:268`_ + ### cuvsIvfPqIndexGetNLists Get the number of clusters/inverted lists @@ -243,15 +272,16 @@ cuvsError_t cuvsIvfPqIndexGetNLists(cuvsIvfPqIndex_t index, int64_t* n_lists); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `index` | | `cuvsIvfPqIndex_t` | | +| `index` | | [`cuvsIvfPqIndex_t`](/api-reference/c-api-neighbors-ivf-pq#cuvsivfpqindex) | | | `n_lists` | | `int64_t*` | | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) _Source: `c/include/cuvs/neighbors/ivf_pq.h:271`_ + ### cuvsIvfPqIndexGetDim Get the dimensionality @@ -264,15 +294,16 @@ cuvsError_t cuvsIvfPqIndexGetDim(cuvsIvfPqIndex_t index, int64_t* dim); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `index` | | `cuvsIvfPqIndex_t` | | +| `index` | | [`cuvsIvfPqIndex_t`](/api-reference/c-api-neighbors-ivf-pq#cuvsivfpqindex) | | | `dim` | | `int64_t*` | | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) _Source: `c/include/cuvs/neighbors/ivf_pq.h:274`_ + ### cuvsIvfPqIndexGetSize Get the size of the index @@ -285,15 +316,16 @@ cuvsError_t cuvsIvfPqIndexGetSize(cuvsIvfPqIndex_t index, int64_t* size); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `index` | | `cuvsIvfPqIndex_t` | | +| `index` | | [`cuvsIvfPqIndex_t`](/api-reference/c-api-neighbors-ivf-pq#cuvsivfpqindex) | | | `size` | | `int64_t*` | | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) _Source: `c/include/cuvs/neighbors/ivf_pq.h:277`_ + ### cuvsIvfPqIndexGetPqDim Get the dimensionality of an encoded vector after compression by PQ. @@ -306,15 +338,16 @@ cuvsError_t cuvsIvfPqIndexGetPqDim(cuvsIvfPqIndex_t index, int64_t* pq_dim); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `index` | | `cuvsIvfPqIndex_t` | | +| `index` | | [`cuvsIvfPqIndex_t`](/api-reference/c-api-neighbors-ivf-pq#cuvsivfpqindex) | | | `pq_dim` | | `int64_t*` | | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) _Source: `c/include/cuvs/neighbors/ivf_pq.h:280`_ + ### cuvsIvfPqIndexGetPqBits Get the bit length of an encoded vector element after compression by PQ. @@ -327,15 +360,16 @@ cuvsError_t cuvsIvfPqIndexGetPqBits(cuvsIvfPqIndex_t index, int64_t* pq_bits); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `index` | | `cuvsIvfPqIndex_t` | | +| `index` | | [`cuvsIvfPqIndex_t`](/api-reference/c-api-neighbors-ivf-pq#cuvsivfpqindex) | | | `pq_bits` | | `int64_t*` | | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) _Source: `c/include/cuvs/neighbors/ivf_pq.h:283`_ + ### cuvsIvfPqIndexGetPqLen Get the Dimensionality of a subspace, i.e. the number of vector @@ -350,15 +384,16 @@ components mapped to a subspace | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `index` | | `cuvsIvfPqIndex_t` | | +| `index` | | [`cuvsIvfPqIndex_t`](/api-reference/c-api-neighbors-ivf-pq#cuvsivfpqindex) | | | `pq_len` | | `int64_t*` | | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) _Source: `c/include/cuvs/neighbors/ivf_pq.h:287`_ + ### cuvsIvfPqIndexGetCenters Get the cluster centers corresponding to the lists in the original space @@ -371,17 +406,18 @@ cuvsError_t cuvsIvfPqIndexGetCenters(cuvsIvfPqIndex_t index, DLManagedTensor* ce | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `index` | in | `cuvsIvfPqIndex_t` | cuvsIvfPqIndex_t Built Ivf-Pq index | +| `index` | in | [`cuvsIvfPqIndex_t`](/api-reference/c-api-neighbors-ivf-pq#cuvsivfpqindex) | cuvsIvfPqIndex_t Built Ivf-Pq index | | `centers` | out | `DLManagedTensor*` | Output tensor that will be populated with a non-owning view of the data | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/neighbors/ivf_pq.h:296`_ + ### cuvsIvfPqIndexGetCentersPadded Get the padded cluster centers [n_lists, dim_ext] @@ -398,17 +434,18 @@ This returns the full padded centers as a contiguous array, suitable for use wit | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `index` | in | `cuvsIvfPqIndex_t` | cuvsIvfPqIndex_t Built Ivf-Pq index | +| `index` | in | [`cuvsIvfPqIndex_t`](/api-reference/c-api-neighbors-ivf-pq#cuvsivfpqindex) | cuvsIvfPqIndex_t Built Ivf-Pq index | | `centers` | out | `DLManagedTensor*` | Output tensor that will be populated with a non-owning view of the data | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/neighbors/ivf_pq.h:309`_ + ### cuvsIvfPqIndexGetPqCenters Get the PQ cluster centers @@ -424,17 +461,18 @@ cuvsError_t cuvsIvfPqIndexGetPqCenters(cuvsIvfPqIndex_t index, DLManagedTensor* | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `index` | in | `cuvsIvfPqIndex_t` | cuvsIvfPqIndex_t Built Ivf-Pq index | +| `index` | in | [`cuvsIvfPqIndex_t`](/api-reference/c-api-neighbors-ivf-pq#cuvsivfpqindex) | cuvsIvfPqIndex_t Built Ivf-Pq index | | `pq_centers` | out | `DLManagedTensor*` | Output tensor that will be populated with a non-owning view of the data | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/neighbors/ivf_pq.h:321`_ + ### cuvsIvfPqIndexGetCentersRot Get the rotated cluster centers [n_lists, rot_dim] @@ -449,17 +487,18 @@ where rot_dim = pq_len * pq_dim | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `index` | in | `cuvsIvfPqIndex_t` | cuvsIvfPqIndex_t Built Ivf-Pq index | +| `index` | in | [`cuvsIvfPqIndex_t`](/api-reference/c-api-neighbors-ivf-pq#cuvsivfpqindex) | cuvsIvfPqIndex_t Built Ivf-Pq index | | `centers_rot` | out | `DLManagedTensor*` | Output tensor that will be populated with a non-owning view of the data | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/neighbors/ivf_pq.h:331`_ + ### cuvsIvfPqIndexGetRotationMatrix Get the rotation matrix [rot_dim, dim] @@ -477,17 +516,18 @@ data | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `index` | in | `cuvsIvfPqIndex_t` | cuvsIvfPqIndex_t Built Ivf-Pq index | +| `index` | in | [`cuvsIvfPqIndex_t`](/api-reference/c-api-neighbors-ivf-pq#cuvsivfpqindex) | cuvsIvfPqIndex_t Built Ivf-Pq index | | `rotation_matrix` | out | `DLManagedTensor*` | Output tensor that will be populated with a non-owning view of the | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/neighbors/ivf_pq.h:342`_ + ### cuvsIvfPqIndexGetListSizes Get the sizes of each list @@ -500,17 +540,18 @@ cuvsError_t cuvsIvfPqIndexGetListSizes(cuvsIvfPqIndex_t index, DLManagedTensor* | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `index` | in | `cuvsIvfPqIndex_t` | cuvsIvfPqIndex_t Built Ivf-Pq index | +| `index` | in | [`cuvsIvfPqIndex_t`](/api-reference/c-api-neighbors-ivf-pq#cuvsivfpqindex) | cuvsIvfPqIndex_t Built Ivf-Pq index | | `list_sizes` | out | `DLManagedTensor*` | Output tensor that will be populated with a non-owning view of the data | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/neighbors/ivf_pq.h:352`_ + ### cuvsIvfPqIndexUnpackContiguousListData Unpack `n_rows` consecutive PQ encoded vectors of a single list (cluster) in the @@ -529,18 +570,19 @@ compressed index starting at given `offset`, not expanded to one code per byte. | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | raft resource | -| `index` | in | `cuvsIvfPqIndex_t` | cuvsIvfPqIndex_t Built Ivf-Pq index | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | raft resource | +| `index` | in | [`cuvsIvfPqIndex_t`](/api-reference/c-api-neighbors-ivf-pq#cuvsivfpqindex) | cuvsIvfPqIndex_t Built Ivf-Pq index | | `out_codes` | out | `DLManagedTensor*` | the destination buffer [n_rows, ceildiv(index.pq_dim() * index.pq_bits(), 8)]. The length `n_rows` defines how many records to unpack, offset + n_rows must be smaller than or equal to the list size. This DLManagedTensor must already point to allocated device memory | | `label` | in | `uint32_t` | The id of the list (cluster) to decode. | | `offset` | in | `uint32_t` | How many records in the list to skip. | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) _Source: `c/include/cuvs/neighbors/ivf_pq.h:371`_ + ### cuvsIvfPqIndexGetListIndices Get the indices of each vector in a ivf-pq list @@ -555,13 +597,13 @@ DLManagedTensor* out_labels); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `index` | in | `cuvsIvfPqIndex_t` | cuvsIvfPqIndex_t Built Ivf-Pq index | +| `index` | in | [`cuvsIvfPqIndex_t`](/api-reference/c-api-neighbors-ivf-pq#cuvsivfpqindex) | cuvsIvfPqIndex_t Built Ivf-Pq index | | `label` | in | `uint32_t` | The id of the list (cluster) to decode. | | `out_labels` | out | `DLManagedTensor*` | output tensor that will be populated with a non-owning view of the data | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t @@ -571,6 +613,7 @@ _Source: `c/include/cuvs/neighbors/ivf_pq.h:386`_ _Doxygen group: `ivf_pq_c_index_build`_ + ### cuvsIvfPqBuild Build a IVF-PQ index with a `DLManagedTensor` which has underlying @@ -593,19 +636,20 @@ cuvsIvfPqIndex_t index); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | -| `params` | in | `cuvsIvfPqIndexParams_t` | cuvsIvfPqIndexParams_t used to build IVF-PQ index | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle | +| `params` | in | [`cuvsIvfPqIndexParams_t`](/api-reference/c-api-neighbors-ivf-pq#cuvsivfpqindexparams) | cuvsIvfPqIndexParams_t used to build IVF-PQ index | | `dataset` | in | `DLManagedTensor*` | DLManagedTensor* training dataset | -| `index` | out | `cuvsIvfPqIndex_t` | cuvsIvfPqIndex_t Newly built IVF-PQ index | +| `index` | out | [`cuvsIvfPqIndex_t`](/api-reference/c-api-neighbors-ivf-pq#cuvsivfpqindex) | cuvsIvfPqIndex_t Newly built IVF-PQ index | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/neighbors/ivf_pq.h:440`_ + ### cuvsIvfPqBuildPrecomputed Build a view-type IVF-PQ index from device memory precomputed centroids and codebook. @@ -635,18 +679,18 @@ matrices) dim] | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | -| `params` | in | `cuvsIvfPqIndexParams_t` | cuvsIvfPqIndexParams_t used to configure the index (must be consistent with | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle | +| `params` | in | [`cuvsIvfPqIndexParams_t`](/api-reference/c-api-neighbors-ivf-pq#cuvsivfpqindexparams) | cuvsIvfPqIndexParams_t used to configure the index (must be consistent with | | `dim` | in | `uint32_t` | dimensionality of the input data | | `pq_centers` | in | `DLManagedTensor*` | PQ codebook on device memory with required shape:
- codebook_kind CUVS_IVF_PQ_CODEBOOK_GEN_PER_SUBSPACE: [pq_dim, pq_len, pq_book_size]
- codebook_kind CUVS_IVF_PQ_CODEBOOK_GEN_PER_CLUSTER: [n_lists, pq_len, pq_book_size] | | `centers` | in | `DLManagedTensor*` | Cluster centers in the original space [n_lists, dim_ext] where dim_ext = round_up(dim + 1, 8) | | `centers_rot` | in | `DLManagedTensor*` | Rotated cluster centers [n_lists, rot_dim] where rot_dim = pq_len * pq_dim | | `rotation_matrix` | in | `DLManagedTensor*` | Transform matrix (original space -> rotated padded space) [rot_dim, | -| `index` | out | `cuvsIvfPqIndex_t` | cuvsIvfPqIndex_t Newly built view-type IVF-PQ index | +| `index` | out | [`cuvsIvfPqIndex_t`](/api-reference/c-api-neighbors-ivf-pq#cuvsivfpqindex) | cuvsIvfPqIndex_t Newly built view-type IVF-PQ index | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t @@ -656,6 +700,7 @@ _Source: `c/include/cuvs/neighbors/ivf_pq.h:474`_ _Doxygen group: `ivf_pq_c_index_search`_ + ### cuvsIvfPqSearch Search a IVF-PQ index with a `DLManagedTensor` which has underlying @@ -679,16 +724,16 @@ DLManagedTensor* distances); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | -| `search_params` | in | `cuvsIvfPqSearchParams_t` | cuvsIvfPqSearchParams_t used to search IVF-PQ index | -| `index` | in | `cuvsIvfPqIndex_t` | cuvsIvfPqIndex which has been returned by `cuvsIvfPqBuild` | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle | +| `search_params` | in | [`cuvsIvfPqSearchParams_t`](/api-reference/c-api-neighbors-ivf-pq#cuvsivfpqsearchparams) | cuvsIvfPqSearchParams_t used to search IVF-PQ index | +| `index` | in | [`cuvsIvfPqIndex_t`](/api-reference/c-api-neighbors-ivf-pq#cuvsivfpqindex) | cuvsIvfPqIndex which has been returned by `cuvsIvfPqBuild` | | `queries` | in | `DLManagedTensor*` | DLManagedTensor* queries dataset to search | | `neighbors` | out | `DLManagedTensor*` | DLManagedTensor* output `k` neighbors for queries | | `distances` | out | `DLManagedTensor*` | DLManagedTensor* output `k` distances for queries | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) _Source: `c/include/cuvs/neighbors/ivf_pq.h:534`_ @@ -696,6 +741,7 @@ _Source: `c/include/cuvs/neighbors/ivf_pq.h:534`_ _Doxygen group: `ivf_pq_c_index_serialize`_ + ### cuvsIvfPqSerialize Save the index to file. @@ -710,16 +756,17 @@ Experimental, both the API and the serialization format are subject to change. | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle | | `filename` | in | `const char*` | the file name for saving the index | -| `index` | in | `cuvsIvfPqIndex_t` | IVF-PQ index | +| `index` | in | [`cuvsIvfPqIndex_t`](/api-reference/c-api-neighbors-ivf-pq#cuvsivfpqindex) | IVF-PQ index | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) _Source: `c/include/cuvs/neighbors/ivf_pq.h:568`_ + ### cuvsIvfPqDeserialize Load index from file. @@ -734,13 +781,13 @@ Experimental, both the API and the serialization format are subject to change. | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle | | `filename` | in | `const char*` | the name of the file that stores the index | -| `index` | out | `cuvsIvfPqIndex_t` | IVF-PQ index loaded disk | +| `index` | out | [`cuvsIvfPqIndex_t`](/api-reference/c-api-neighbors-ivf-pq#cuvsivfpqindex) | IVF-PQ index loaded disk | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) _Source: `c/include/cuvs/neighbors/ivf_pq.h:579`_ @@ -748,6 +795,7 @@ _Source: `c/include/cuvs/neighbors/ivf_pq.h:579`_ _Doxygen group: `ivf_pq_c_index_extend`_ + ### cuvsIvfPqExtend Extend the index with the new data. @@ -763,14 +811,14 @@ cuvsIvfPqIndex_t index); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle | | `new_vectors` | in | `DLManagedTensor*` | DLManagedTensor* the new vectors to add to the index | | `new_indices` | in | `DLManagedTensor*` | DLManagedTensor* vector of new indices for the new vectors | -| `index` | inout | `cuvsIvfPqIndex_t` | IVF-PQ index to be extended | +| `index` | inout | [`cuvsIvfPqIndex_t`](/api-reference/c-api-neighbors-ivf-pq#cuvsivfpqindex) | IVF-PQ index to be extended | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t @@ -780,6 +828,7 @@ _Source: `c/include/cuvs/neighbors/ivf_pq.h:597`_ _Doxygen group: `ivf_pq_c_index_transform`_ + ### cuvsIvfPqTransform Transform the input data by applying pq-encoding @@ -796,15 +845,15 @@ DLManagedTensor* output_dataset); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | -| `index` | in | `cuvsIvfPqIndex_t` | IVF-PQ index | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle | +| `index` | in | [`cuvsIvfPqIndex_t`](/api-reference/c-api-neighbors-ivf-pq#cuvsivfpqindex) | IVF-PQ index | | `input_dataset` | in | `DLManagedTensor*` | DLManagedTensor* vectors to transform | | `output_labels` | out | `DLManagedTensor*` | DLManagedTensor* Vector of cluster labels for each vector in the input | | `output_dataset` | out | `DLManagedTensor*` | DLManagedTensor* input vectors after pq-encoding | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t diff --git a/fern/pages/c_api/c-api-neighbors-mg-cagra.md b/fern/pages/c_api/c-api-neighbors-mg-cagra.md index 5105d54da6..16a5a530f8 100644 --- a/fern/pages/c_api/c-api-neighbors-mg-cagra.md +++ b/fern/pages/c_api/c-api-neighbors-mg-cagra.md @@ -10,6 +10,7 @@ _Source header: `c/include/cuvs/neighbors/mg_cagra.h`_ _Doxygen group: `mg_cagra_c_index_params`_ + ### cuvsMultiGpuCagraIndexParams Multi-GPU parameters to build CAGRA Index @@ -24,11 +25,12 @@ struct cuvsMultiGpuCagraIndexParams { ... } ; | Name | Type | Description | | --- | --- | --- | -| `base_params` | `cuvsCagraIndexParams_t` | Base CAGRA index parameters | -| `mode` | `cuvsMultiGpuDistributionMode` | Distribution mode for multi-GPU setup | +| `base_params` | [`cuvsCagraIndexParams_t`](/api-reference/c-api-neighbors-cagra#cuvscagraindexparams) | Base CAGRA index parameters | +| `mode` | [`cuvsMultiGpuDistributionMode`](/api-reference/c-api-neighbors-mg-common#cuvsmultigpudistributionmode) | Distribution mode for multi-GPU setup | _Source: `c/include/cuvs/neighbors/mg_cagra.h:28`_ + ### cuvsMultiGpuCagraIndexParamsCreate Allocate Multi-GPU CAGRA Index params, and populate with default values @@ -41,16 +43,17 @@ cuvsError_t cuvsMultiGpuCagraIndexParamsCreate(cuvsMultiGpuCagraIndexParams_t* i | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `index_params` | in | `cuvsMultiGpuCagraIndexParams_t*` | cuvsMultiGpuCagraIndexParams_t to allocate | +| `index_params` | in | [`cuvsMultiGpuCagraIndexParams_t*`](/api-reference/c-api-neighbors-mg-cagra#cuvsmultigpucagraindexparams) | cuvsMultiGpuCagraIndexParams_t to allocate | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/neighbors/mg_cagra.h:43`_ + ### cuvsMultiGpuCagraIndexParamsDestroy De-allocate Multi-GPU CAGRA Index params @@ -63,11 +66,11 @@ cuvsError_t cuvsMultiGpuCagraIndexParamsDestroy(cuvsMultiGpuCagraIndexParams_t i | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `index_params` | in | `cuvsMultiGpuCagraIndexParams_t` | | +| `index_params` | in | [`cuvsMultiGpuCagraIndexParams_t`](/api-reference/c-api-neighbors-mg-cagra#cuvsmultigpucagraindexparams) | | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t @@ -77,6 +80,7 @@ _Source: `c/include/cuvs/neighbors/mg_cagra.h:51`_ _Doxygen group: `mg_cagra_c_search_params`_ + ### cuvsMultiGpuCagraSearchParams Multi-GPU parameters to search CAGRA index @@ -91,13 +95,14 @@ struct cuvsMultiGpuCagraSearchParams { ... } ; | Name | Type | Description | | --- | --- | --- | -| `base_params` | `cuvsCagraSearchParams_t` | Base CAGRA search parameters | -| `search_mode` | `cuvsMultiGpuReplicatedSearchMode` | Replicated search mode | -| `merge_mode` | `cuvsMultiGpuShardedMergeMode` | Sharded merge mode | +| `base_params` | [`cuvsCagraSearchParams_t`](/api-reference/c-api-neighbors-cagra#cuvscagrasearchparams) | Base CAGRA search parameters | +| `search_mode` | [`cuvsMultiGpuReplicatedSearchMode`](/api-reference/c-api-neighbors-mg-common#cuvsmultigpureplicatedsearchmode) | Replicated search mode | +| `merge_mode` | [`cuvsMultiGpuShardedMergeMode`](/api-reference/c-api-neighbors-mg-common#cuvsmultigpushardedmergemode) | Sharded merge mode | | `n_rows_per_batch` | `int64_t` | Number of rows per batch | _Source: `c/include/cuvs/neighbors/mg_cagra.h:67`_ + ### cuvsMultiGpuCagraSearchParamsCreate Allocate Multi-GPU CAGRA search params, and populate with default values @@ -110,16 +115,17 @@ cuvsError_t cuvsMultiGpuCagraSearchParamsCreate(cuvsMultiGpuCagraSearchParams_t* | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `params` | in | `cuvsMultiGpuCagraSearchParams_t*` | cuvsMultiGpuCagraSearchParams_t to allocate | +| `params` | in | [`cuvsMultiGpuCagraSearchParams_t*`](/api-reference/c-api-neighbors-mg-cagra#cuvsmultigpucagrasearchparams) | cuvsMultiGpuCagraSearchParams_t to allocate | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/neighbors/mg_cagra.h:86`_ + ### cuvsMultiGpuCagraSearchParamsDestroy De-allocate Multi-GPU CAGRA search params @@ -132,11 +138,11 @@ cuvsError_t cuvsMultiGpuCagraSearchParamsDestroy(cuvsMultiGpuCagraSearchParams_t | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `params` | in | `cuvsMultiGpuCagraSearchParams_t` | | +| `params` | in | [`cuvsMultiGpuCagraSearchParams_t`](/api-reference/c-api-neighbors-mg-cagra#cuvsmultigpucagrasearchparams) | | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t @@ -146,6 +152,27 @@ _Source: `c/include/cuvs/neighbors/mg_cagra.h:94`_ _Doxygen group: `mg_cagra_c_index`_ + +### cuvsMultiGpuCagraIndex + +Struct to hold address of cuvs::neighbors::mg_index<cagra::index> and its active trained + +dtype + +```c +typedef struct { ... } cuvsMultiGpuCagraIndex; +``` + +**Fields** + +| Name | Type | Description | +| --- | --- | --- | +| `addr` | `uintptr_t` | | +| `dtype` | `DLDataType` | | + +_Source: `c/include/cuvs/neighbors/mg_cagra.h:109`_ + + ### cuvsMultiGpuCagraIndexCreate Allocate Multi-GPU CAGRA index @@ -158,16 +185,17 @@ cuvsError_t cuvsMultiGpuCagraIndexCreate(cuvsMultiGpuCagraIndex_t* index); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `index` | in | `cuvsMultiGpuCagraIndex_t*` | cuvsMultiGpuCagraIndex_t to allocate | +| `index` | in | [`cuvsMultiGpuCagraIndex_t*`](/api-reference/c-api-neighbors-mg-cagra#cuvsmultigpucagraindex) | cuvsMultiGpuCagraIndex_t to allocate | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/neighbors/mg_cagra.h:122`_ + ### cuvsMultiGpuCagraIndexDestroy De-allocate Multi-GPU CAGRA index @@ -180,11 +208,11 @@ cuvsError_t cuvsMultiGpuCagraIndexDestroy(cuvsMultiGpuCagraIndex_t index); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `index` | in | `cuvsMultiGpuCagraIndex_t` | cuvsMultiGpuCagraIndex_t to de-allocate | +| `index` | in | [`cuvsMultiGpuCagraIndex_t`](/api-reference/c-api-neighbors-mg-cagra#cuvsmultigpucagraindex) | cuvsMultiGpuCagraIndex_t to de-allocate | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t @@ -194,6 +222,7 @@ _Source: `c/include/cuvs/neighbors/mg_cagra.h:130`_ _Doxygen group: `mg_cagra_c_index_build`_ + ### cuvsMultiGpuCagraBuild Build a Multi-GPU CAGRA index @@ -209,14 +238,14 @@ cuvsMultiGpuCagraIndex_t index); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | -| `params` | in | `cuvsMultiGpuCagraIndexParams_t` | Multi-GPU CAGRA index parameters | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle | +| `params` | in | [`cuvsMultiGpuCagraIndexParams_t`](/api-reference/c-api-neighbors-mg-cagra#cuvsmultigpucagraindexparams) | Multi-GPU CAGRA index parameters | | `dataset_tensor` | in | `DLManagedTensor*` | DLManagedTensor* training dataset | -| `index` | out | `cuvsMultiGpuCagraIndex_t` | Multi-GPU CAGRA index | +| `index` | out | [`cuvsMultiGpuCagraIndex_t`](/api-reference/c-api-neighbors-mg-cagra#cuvsmultigpucagraindex) | Multi-GPU CAGRA index | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t @@ -226,6 +255,7 @@ _Source: `c/include/cuvs/neighbors/mg_cagra.h:150`_ _Doxygen group: `mg_cagra_c_index_search`_ + ### cuvsMultiGpuCagraSearch Search a Multi-GPU CAGRA index @@ -243,16 +273,16 @@ DLManagedTensor* distances_tensor); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | -| `params` | in | `cuvsMultiGpuCagraSearchParams_t` | Multi-GPU CAGRA search parameters | -| `index` | in | `cuvsMultiGpuCagraIndex_t` | Multi-GPU CAGRA index | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle | +| `params` | in | [`cuvsMultiGpuCagraSearchParams_t`](/api-reference/c-api-neighbors-mg-cagra#cuvsmultigpucagrasearchparams) | Multi-GPU CAGRA search parameters | +| `index` | in | [`cuvsMultiGpuCagraIndex_t`](/api-reference/c-api-neighbors-mg-cagra#cuvsmultigpucagraindex) | Multi-GPU CAGRA index | | `queries_tensor` | in | `DLManagedTensor*` | DLManagedTensor* queries dataset | | `neighbors_tensor` | out | `DLManagedTensor*` | DLManagedTensor* output neighbors | | `distances_tensor` | out | `DLManagedTensor*` | DLManagedTensor* output distances | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t @@ -262,6 +292,7 @@ _Source: `c/include/cuvs/neighbors/mg_cagra.h:175`_ _Doxygen group: `mg_cagra_c_index_extend`_ + ### cuvsMultiGpuCagraExtend Extend a Multi-GPU CAGRA index @@ -277,14 +308,14 @@ DLManagedTensor* new_indices_tensor); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | -| `index` | in,out | `cuvsMultiGpuCagraIndex_t` | Multi-GPU CAGRA index to extend | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle | +| `index` | in,out | [`cuvsMultiGpuCagraIndex_t`](/api-reference/c-api-neighbors-mg-cagra#cuvsmultigpucagraindex) | Multi-GPU CAGRA index to extend | | `new_vectors_tensor` | in | `DLManagedTensor*` | DLManagedTensor* new vectors to add | | `new_indices_tensor` | in | `DLManagedTensor*` | DLManagedTensor* new indices (optional, can be NULL) | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t @@ -294,6 +325,7 @@ _Source: `c/include/cuvs/neighbors/mg_cagra.h:200`_ _Doxygen group: `mg_cagra_c_index_serialize`_ + ### cuvsMultiGpuCagraSerialize Serialize a Multi-GPU CAGRA index to file @@ -308,13 +340,13 @@ const char* filename); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | -| `index` | in | `cuvsMultiGpuCagraIndex_t` | Multi-GPU CAGRA index to serialize | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle | +| `index` | in | [`cuvsMultiGpuCagraIndex_t`](/api-reference/c-api-neighbors-mg-cagra#cuvsmultigpucagraindex) | Multi-GPU CAGRA index to serialize | | `filename` | in | `const char*` | Path to the output file | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t @@ -324,6 +356,7 @@ _Source: `c/include/cuvs/neighbors/mg_cagra.h:222`_ _Doxygen group: `mg_cagra_c_index_deserialize`_ + ### cuvsMultiGpuCagraDeserialize Deserialize a Multi-GPU CAGRA index from file @@ -338,13 +371,13 @@ cuvsMultiGpuCagraIndex_t index); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle | | `filename` | in | `const char*` | Path to the input file | -| `index` | out | `cuvsMultiGpuCagraIndex_t` | Multi-GPU CAGRA index | +| `index` | out | [`cuvsMultiGpuCagraIndex_t`](/api-reference/c-api-neighbors-mg-cagra#cuvsmultigpucagraindex) | Multi-GPU CAGRA index | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t @@ -354,6 +387,7 @@ _Source: `c/include/cuvs/neighbors/mg_cagra.h:243`_ _Doxygen group: `mg_cagra_c_index_distribute`_ + ### cuvsMultiGpuCagraDistribute Distribute a local CAGRA index to create a Multi-GPU index @@ -368,13 +402,13 @@ cuvsMultiGpuCagraIndex_t index); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle | | `filename` | in | `const char*` | Path to the local index file | -| `index` | out | `cuvsMultiGpuCagraIndex_t` | Multi-GPU CAGRA index | +| `index` | out | [`cuvsMultiGpuCagraIndex_t`](/api-reference/c-api-neighbors-mg-cagra#cuvsmultigpucagraindex) | Multi-GPU CAGRA index | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t diff --git a/fern/pages/c_api/c-api-neighbors-mg-common.md b/fern/pages/c_api/c-api-neighbors-mg-common.md index 9cb6eecbfd..cd4a19bfc9 100644 --- a/fern/pages/c_api/c-api-neighbors-mg-common.md +++ b/fern/pages/c_api/c-api-neighbors-mg-common.md @@ -10,6 +10,7 @@ _Source header: `c/include/cuvs/neighbors/mg_common.h`_ _Doxygen group: `mg_c_common_types`_ + ### cuvsMultiGpuDistributionMode Distribution mode for multi-GPU indexes @@ -20,6 +21,7 @@ typedef enum { ... } cuvsMultiGpuDistributionMode; _Source: `c/include/cuvs/neighbors/mg_common.h:22`_ + ### cuvsMultiGpuReplicatedSearchMode Search mode when using a replicated index @@ -37,6 +39,7 @@ typedef enum { ... } cuvsMultiGpuReplicatedSearchMode; _Source: `c/include/cuvs/neighbors/mg_common.h:32`_ + ### cuvsMultiGpuShardedMergeMode Merge mode when using a sharded index diff --git a/fern/pages/c_api/c-api-neighbors-mg-ivf-flat.md b/fern/pages/c_api/c-api-neighbors-mg-ivf-flat.md index de20351357..29432e05fe 100644 --- a/fern/pages/c_api/c-api-neighbors-mg-ivf-flat.md +++ b/fern/pages/c_api/c-api-neighbors-mg-ivf-flat.md @@ -10,6 +10,7 @@ _Source header: `c/include/cuvs/neighbors/mg_ivf_flat.h`_ _Doxygen group: `mg_ivf_flat_c_index_params`_ + ### cuvsMultiGpuIvfFlatIndexParams Multi-GPU parameters to build IVF-Flat Index @@ -24,11 +25,12 @@ struct cuvsMultiGpuIvfFlatIndexParams { ... } ; | Name | Type | Description | | --- | --- | --- | -| `base_params` | `cuvsIvfFlatIndexParams_t` | Base IVF-Flat index parameters | -| `mode` | `cuvsMultiGpuDistributionMode` | Distribution mode for multi-GPU setup | +| `base_params` | [`cuvsIvfFlatIndexParams_t`](/api-reference/c-api-neighbors-ivf-flat#cuvsivfflatindexparams) | Base IVF-Flat index parameters | +| `mode` | [`cuvsMultiGpuDistributionMode`](/api-reference/c-api-neighbors-mg-common#cuvsmultigpudistributionmode) | Distribution mode for multi-GPU setup | _Source: `c/include/cuvs/neighbors/mg_ivf_flat.h:28`_ + ### cuvsMultiGpuIvfFlatIndexParamsCreate Allocate Multi-GPU IVF-Flat Index params, and populate with default values @@ -41,16 +43,17 @@ cuvsError_t cuvsMultiGpuIvfFlatIndexParamsCreate(cuvsMultiGpuIvfFlatIndexParams_ | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `index_params` | in | `cuvsMultiGpuIvfFlatIndexParams_t*` | cuvsMultiGpuIvfFlatIndexParams_t to allocate | +| `index_params` | in | [`cuvsMultiGpuIvfFlatIndexParams_t*`](/api-reference/c-api-neighbors-mg-ivf-flat#cuvsmultigpuivfflatindexparams) | cuvsMultiGpuIvfFlatIndexParams_t to allocate | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/neighbors/mg_ivf_flat.h:43`_ + ### cuvsMultiGpuIvfFlatIndexParamsDestroy De-allocate Multi-GPU IVF-Flat Index params @@ -63,11 +66,11 @@ cuvsError_t cuvsMultiGpuIvfFlatIndexParamsDestroy(cuvsMultiGpuIvfFlatIndexParams | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `index_params` | in | `cuvsMultiGpuIvfFlatIndexParams_t` | | +| `index_params` | in | [`cuvsMultiGpuIvfFlatIndexParams_t`](/api-reference/c-api-neighbors-mg-ivf-flat#cuvsmultigpuivfflatindexparams) | | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t @@ -77,6 +80,7 @@ _Source: `c/include/cuvs/neighbors/mg_ivf_flat.h:51`_ _Doxygen group: `mg_ivf_flat_c_search_params`_ + ### cuvsMultiGpuIvfFlatSearchParams Multi-GPU parameters to search IVF-Flat index @@ -91,13 +95,14 @@ struct cuvsMultiGpuIvfFlatSearchParams { ... } ; | Name | Type | Description | | --- | --- | --- | -| `base_params` | `cuvsIvfFlatSearchParams_t` | Base IVF-Flat search parameters | -| `search_mode` | `cuvsMultiGpuReplicatedSearchMode` | Replicated search mode | -| `merge_mode` | `cuvsMultiGpuShardedMergeMode` | Sharded merge mode | +| `base_params` | [`cuvsIvfFlatSearchParams_t`](/api-reference/c-api-neighbors-ivf-flat#cuvsivfflatsearchparams) | Base IVF-Flat search parameters | +| `search_mode` | [`cuvsMultiGpuReplicatedSearchMode`](/api-reference/c-api-neighbors-mg-common#cuvsmultigpureplicatedsearchmode) | Replicated search mode | +| `merge_mode` | [`cuvsMultiGpuShardedMergeMode`](/api-reference/c-api-neighbors-mg-common#cuvsmultigpushardedmergemode) | Sharded merge mode | | `n_rows_per_batch` | `int64_t` | Number of rows per batch | _Source: `c/include/cuvs/neighbors/mg_ivf_flat.h:67`_ + ### cuvsMultiGpuIvfFlatSearchParamsCreate Allocate Multi-GPU IVF-Flat search params, and populate with default values @@ -110,16 +115,17 @@ cuvsError_t cuvsMultiGpuIvfFlatSearchParamsCreate(cuvsMultiGpuIvfFlatSearchParam | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `params` | in | `cuvsMultiGpuIvfFlatSearchParams_t*` | cuvsMultiGpuIvfFlatSearchParams_t to allocate | +| `params` | in | [`cuvsMultiGpuIvfFlatSearchParams_t*`](/api-reference/c-api-neighbors-mg-ivf-flat#cuvsmultigpuivfflatsearchparams) | cuvsMultiGpuIvfFlatSearchParams_t to allocate | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/neighbors/mg_ivf_flat.h:86`_ + ### cuvsMultiGpuIvfFlatSearchParamsDestroy De-allocate Multi-GPU IVF-Flat search params @@ -132,11 +138,11 @@ cuvsError_t cuvsMultiGpuIvfFlatSearchParamsDestroy(cuvsMultiGpuIvfFlatSearchPara | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `params` | in | `cuvsMultiGpuIvfFlatSearchParams_t` | | +| `params` | in | [`cuvsMultiGpuIvfFlatSearchParams_t`](/api-reference/c-api-neighbors-mg-ivf-flat#cuvsmultigpuivfflatsearchparams) | | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t @@ -146,6 +152,27 @@ _Source: `c/include/cuvs/neighbors/mg_ivf_flat.h:94`_ _Doxygen group: `mg_ivf_flat_c_index`_ + +### cuvsMultiGpuIvfFlatIndex + +Struct to hold address of cuvs::neighbors::mg_index<ivf_flat::index> and its active + +trained dtype + +```c +typedef struct { ... } cuvsMultiGpuIvfFlatIndex; +``` + +**Fields** + +| Name | Type | Description | +| --- | --- | --- | +| `addr` | `uintptr_t` | | +| `dtype` | `DLDataType` | | + +_Source: `c/include/cuvs/neighbors/mg_ivf_flat.h:109`_ + + ### cuvsMultiGpuIvfFlatIndexCreate Allocate Multi-GPU IVF-Flat index @@ -158,16 +185,17 @@ cuvsError_t cuvsMultiGpuIvfFlatIndexCreate(cuvsMultiGpuIvfFlatIndex_t* index); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `index` | in | `cuvsMultiGpuIvfFlatIndex_t*` | cuvsMultiGpuIvfFlatIndex_t to allocate | +| `index` | in | [`cuvsMultiGpuIvfFlatIndex_t*`](/api-reference/c-api-neighbors-mg-ivf-flat#cuvsmultigpuivfflatindex) | cuvsMultiGpuIvfFlatIndex_t to allocate | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/neighbors/mg_ivf_flat.h:122`_ + ### cuvsMultiGpuIvfFlatIndexDestroy De-allocate Multi-GPU IVF-Flat index @@ -180,11 +208,11 @@ cuvsError_t cuvsMultiGpuIvfFlatIndexDestroy(cuvsMultiGpuIvfFlatIndex_t index); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `index` | in | `cuvsMultiGpuIvfFlatIndex_t` | cuvsMultiGpuIvfFlatIndex_t to de-allocate | +| `index` | in | [`cuvsMultiGpuIvfFlatIndex_t`](/api-reference/c-api-neighbors-mg-ivf-flat#cuvsmultigpuivfflatindex) | cuvsMultiGpuIvfFlatIndex_t to de-allocate | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t @@ -194,6 +222,7 @@ _Source: `c/include/cuvs/neighbors/mg_ivf_flat.h:130`_ _Doxygen group: `mg_ivf_flat_c_index_build`_ + ### cuvsMultiGpuIvfFlatBuild Build a Multi-GPU IVF-Flat index @@ -209,14 +238,14 @@ cuvsMultiGpuIvfFlatIndex_t index); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | -| `params` | in | `cuvsMultiGpuIvfFlatIndexParams_t` | Multi-GPU IVF-Flat index parameters | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle | +| `params` | in | [`cuvsMultiGpuIvfFlatIndexParams_t`](/api-reference/c-api-neighbors-mg-ivf-flat#cuvsmultigpuivfflatindexparams) | Multi-GPU IVF-Flat index parameters | | `dataset_tensor` | in | `DLManagedTensor*` | DLManagedTensor* training dataset | -| `index` | out | `cuvsMultiGpuIvfFlatIndex_t` | Multi-GPU IVF-Flat index | +| `index` | out | [`cuvsMultiGpuIvfFlatIndex_t`](/api-reference/c-api-neighbors-mg-ivf-flat#cuvsmultigpuivfflatindex) | Multi-GPU IVF-Flat index | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t @@ -226,6 +255,7 @@ _Source: `c/include/cuvs/neighbors/mg_ivf_flat.h:150`_ _Doxygen group: `mg_ivf_flat_c_index_search`_ + ### cuvsMultiGpuIvfFlatSearch Search a Multi-GPU IVF-Flat index @@ -243,16 +273,16 @@ DLManagedTensor* distances_tensor); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | -| `params` | in | `cuvsMultiGpuIvfFlatSearchParams_t` | Multi-GPU IVF-Flat search parameters | -| `index` | in | `cuvsMultiGpuIvfFlatIndex_t` | Multi-GPU IVF-Flat index | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle | +| `params` | in | [`cuvsMultiGpuIvfFlatSearchParams_t`](/api-reference/c-api-neighbors-mg-ivf-flat#cuvsmultigpuivfflatsearchparams) | Multi-GPU IVF-Flat search parameters | +| `index` | in | [`cuvsMultiGpuIvfFlatIndex_t`](/api-reference/c-api-neighbors-mg-ivf-flat#cuvsmultigpuivfflatindex) | Multi-GPU IVF-Flat index | | `queries_tensor` | in | `DLManagedTensor*` | DLManagedTensor* queries dataset | | `neighbors_tensor` | out | `DLManagedTensor*` | DLManagedTensor* output neighbors | | `distances_tensor` | out | `DLManagedTensor*` | DLManagedTensor* output distances | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t @@ -262,6 +292,7 @@ _Source: `c/include/cuvs/neighbors/mg_ivf_flat.h:175`_ _Doxygen group: `mg_ivf_flat_c_index_extend`_ + ### cuvsMultiGpuIvfFlatExtend Extend a Multi-GPU IVF-Flat index @@ -277,14 +308,14 @@ DLManagedTensor* new_indices_tensor); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | -| `index` | in,out | `cuvsMultiGpuIvfFlatIndex_t` | Multi-GPU IVF-Flat index to extend | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle | +| `index` | in,out | [`cuvsMultiGpuIvfFlatIndex_t`](/api-reference/c-api-neighbors-mg-ivf-flat#cuvsmultigpuivfflatindex) | Multi-GPU IVF-Flat index to extend | | `new_vectors_tensor` | in | `DLManagedTensor*` | DLManagedTensor* new vectors to add | | `new_indices_tensor` | in | `DLManagedTensor*` | DLManagedTensor* new indices (optional, can be NULL) | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t @@ -294,6 +325,7 @@ _Source: `c/include/cuvs/neighbors/mg_ivf_flat.h:200`_ _Doxygen group: `mg_ivf_flat_c_index_serialize`_ + ### cuvsMultiGpuIvfFlatSerialize Serialize a Multi-GPU IVF-Flat index to file @@ -308,13 +340,13 @@ const char* filename); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | -| `index` | in | `cuvsMultiGpuIvfFlatIndex_t` | Multi-GPU IVF-Flat index to serialize | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle | +| `index` | in | [`cuvsMultiGpuIvfFlatIndex_t`](/api-reference/c-api-neighbors-mg-ivf-flat#cuvsmultigpuivfflatindex) | Multi-GPU IVF-Flat index to serialize | | `filename` | in | `const char*` | Path to the output file | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t @@ -324,6 +356,7 @@ _Source: `c/include/cuvs/neighbors/mg_ivf_flat.h:222`_ _Doxygen group: `mg_ivf_flat_c_index_deserialize`_ + ### cuvsMultiGpuIvfFlatDeserialize Deserialize a Multi-GPU IVF-Flat index from file @@ -338,13 +371,13 @@ cuvsMultiGpuIvfFlatIndex_t index); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle | | `filename` | in | `const char*` | Path to the input file | -| `index` | out | `cuvsMultiGpuIvfFlatIndex_t` | Multi-GPU IVF-Flat index | +| `index` | out | [`cuvsMultiGpuIvfFlatIndex_t`](/api-reference/c-api-neighbors-mg-ivf-flat#cuvsmultigpuivfflatindex) | Multi-GPU IVF-Flat index | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t @@ -354,6 +387,7 @@ _Source: `c/include/cuvs/neighbors/mg_ivf_flat.h:243`_ _Doxygen group: `mg_ivf_flat_c_index_distribute`_ + ### cuvsMultiGpuIvfFlatDistribute Distribute a local IVF-Flat index to create a Multi-GPU index @@ -368,13 +402,13 @@ cuvsMultiGpuIvfFlatIndex_t index); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle | | `filename` | in | `const char*` | Path to the local index file | -| `index` | out | `cuvsMultiGpuIvfFlatIndex_t` | Multi-GPU IVF-Flat index | +| `index` | out | [`cuvsMultiGpuIvfFlatIndex_t`](/api-reference/c-api-neighbors-mg-ivf-flat#cuvsmultigpuivfflatindex) | Multi-GPU IVF-Flat index | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t diff --git a/fern/pages/c_api/c-api-neighbors-mg-ivf-pq.md b/fern/pages/c_api/c-api-neighbors-mg-ivf-pq.md index bde7f3549f..2807bb9b77 100644 --- a/fern/pages/c_api/c-api-neighbors-mg-ivf-pq.md +++ b/fern/pages/c_api/c-api-neighbors-mg-ivf-pq.md @@ -10,6 +10,7 @@ _Source header: `c/include/cuvs/neighbors/mg_ivf_pq.h`_ _Doxygen group: `mg_ivf_pq_c_index_params`_ + ### cuvsMultiGpuIvfPqIndexParams Multi-GPU parameters to build IVF-PQ Index @@ -24,11 +25,12 @@ struct cuvsMultiGpuIvfPqIndexParams { ... } ; | Name | Type | Description | | --- | --- | --- | -| `base_params` | `cuvsIvfPqIndexParams_t` | Base IVF-PQ index parameters | -| `mode` | `cuvsMultiGpuDistributionMode` | Distribution mode for multi-GPU setup | +| `base_params` | [`cuvsIvfPqIndexParams_t`](/api-reference/c-api-neighbors-ivf-pq#cuvsivfpqindexparams) | Base IVF-PQ index parameters | +| `mode` | [`cuvsMultiGpuDistributionMode`](/api-reference/c-api-neighbors-mg-common#cuvsmultigpudistributionmode) | Distribution mode for multi-GPU setup | _Source: `c/include/cuvs/neighbors/mg_ivf_pq.h:28`_ + ### cuvsMultiGpuIvfPqIndexParamsCreate Allocate Multi-GPU IVF-PQ Index params, and populate with default values @@ -41,16 +43,17 @@ cuvsError_t cuvsMultiGpuIvfPqIndexParamsCreate(cuvsMultiGpuIvfPqIndexParams_t* i | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `index_params` | in | `cuvsMultiGpuIvfPqIndexParams_t*` | cuvsMultiGpuIvfPqIndexParams_t to allocate | +| `index_params` | in | [`cuvsMultiGpuIvfPqIndexParams_t*`](/api-reference/c-api-neighbors-mg-ivf-pq#cuvsmultigpuivfpqindexparams) | cuvsMultiGpuIvfPqIndexParams_t to allocate | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/neighbors/mg_ivf_pq.h:43`_ + ### cuvsMultiGpuIvfPqIndexParamsDestroy De-allocate Multi-GPU IVF-PQ Index params @@ -63,11 +66,11 @@ cuvsError_t cuvsMultiGpuIvfPqIndexParamsDestroy(cuvsMultiGpuIvfPqIndexParams_t i | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `index_params` | in | `cuvsMultiGpuIvfPqIndexParams_t` | | +| `index_params` | in | [`cuvsMultiGpuIvfPqIndexParams_t`](/api-reference/c-api-neighbors-mg-ivf-pq#cuvsmultigpuivfpqindexparams) | | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t @@ -77,6 +80,7 @@ _Source: `c/include/cuvs/neighbors/mg_ivf_pq.h:51`_ _Doxygen group: `mg_ivf_pq_c_search_params`_ + ### cuvsMultiGpuIvfPqSearchParams Multi-GPU parameters to search IVF-PQ index @@ -91,13 +95,14 @@ struct cuvsMultiGpuIvfPqSearchParams { ... } ; | Name | Type | Description | | --- | --- | --- | -| `base_params` | `cuvsIvfPqSearchParams_t` | Base IVF-PQ search parameters | -| `search_mode` | `cuvsMultiGpuReplicatedSearchMode` | Replicated search mode | -| `merge_mode` | `cuvsMultiGpuShardedMergeMode` | Sharded merge mode | +| `base_params` | [`cuvsIvfPqSearchParams_t`](/api-reference/c-api-neighbors-ivf-pq#cuvsivfpqsearchparams) | Base IVF-PQ search parameters | +| `search_mode` | [`cuvsMultiGpuReplicatedSearchMode`](/api-reference/c-api-neighbors-mg-common#cuvsmultigpureplicatedsearchmode) | Replicated search mode | +| `merge_mode` | [`cuvsMultiGpuShardedMergeMode`](/api-reference/c-api-neighbors-mg-common#cuvsmultigpushardedmergemode) | Sharded merge mode | | `n_rows_per_batch` | `int64_t` | Number of rows per batch | _Source: `c/include/cuvs/neighbors/mg_ivf_pq.h:67`_ + ### cuvsMultiGpuIvfPqSearchParamsCreate Allocate Multi-GPU IVF-PQ search params, and populate with default values @@ -110,16 +115,17 @@ cuvsError_t cuvsMultiGpuIvfPqSearchParamsCreate(cuvsMultiGpuIvfPqSearchParams_t* | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `params` | in | `cuvsMultiGpuIvfPqSearchParams_t*` | cuvsMultiGpuIvfPqSearchParams_t to allocate | +| `params` | in | [`cuvsMultiGpuIvfPqSearchParams_t*`](/api-reference/c-api-neighbors-mg-ivf-pq#cuvsmultigpuivfpqsearchparams) | cuvsMultiGpuIvfPqSearchParams_t to allocate | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/neighbors/mg_ivf_pq.h:86`_ + ### cuvsMultiGpuIvfPqSearchParamsDestroy De-allocate Multi-GPU IVF-PQ search params @@ -132,11 +138,11 @@ cuvsError_t cuvsMultiGpuIvfPqSearchParamsDestroy(cuvsMultiGpuIvfPqSearchParams_t | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `params` | in | `cuvsMultiGpuIvfPqSearchParams_t` | | +| `params` | in | [`cuvsMultiGpuIvfPqSearchParams_t`](/api-reference/c-api-neighbors-mg-ivf-pq#cuvsmultigpuivfpqsearchparams) | | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t @@ -146,6 +152,27 @@ _Source: `c/include/cuvs/neighbors/mg_ivf_pq.h:94`_ _Doxygen group: `mg_ivf_pq_c_index`_ + +### cuvsMultiGpuIvfPqIndex + +Struct to hold address of cuvs::neighbors::mg_index<ivf_pq::index> and its active trained + +dtype + +```c +typedef struct { ... } cuvsMultiGpuIvfPqIndex; +``` + +**Fields** + +| Name | Type | Description | +| --- | --- | --- | +| `addr` | `uintptr_t` | | +| `dtype` | `DLDataType` | | + +_Source: `c/include/cuvs/neighbors/mg_ivf_pq.h:109`_ + + ### cuvsMultiGpuIvfPqIndexCreate Allocate Multi-GPU IVF-PQ index @@ -158,16 +185,17 @@ cuvsError_t cuvsMultiGpuIvfPqIndexCreate(cuvsMultiGpuIvfPqIndex_t* index); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `index` | in | `cuvsMultiGpuIvfPqIndex_t*` | cuvsMultiGpuIvfPqIndex_t to allocate | +| `index` | in | [`cuvsMultiGpuIvfPqIndex_t*`](/api-reference/c-api-neighbors-mg-ivf-pq#cuvsmultigpuivfpqindex) | cuvsMultiGpuIvfPqIndex_t to allocate | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/neighbors/mg_ivf_pq.h:122`_ + ### cuvsMultiGpuIvfPqIndexDestroy De-allocate Multi-GPU IVF-PQ index @@ -180,11 +208,11 @@ cuvsError_t cuvsMultiGpuIvfPqIndexDestroy(cuvsMultiGpuIvfPqIndex_t index); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `index` | in | `cuvsMultiGpuIvfPqIndex_t` | cuvsMultiGpuIvfPqIndex_t to de-allocate | +| `index` | in | [`cuvsMultiGpuIvfPqIndex_t`](/api-reference/c-api-neighbors-mg-ivf-pq#cuvsmultigpuivfpqindex) | cuvsMultiGpuIvfPqIndex_t to de-allocate | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t @@ -194,6 +222,7 @@ _Source: `c/include/cuvs/neighbors/mg_ivf_pq.h:130`_ _Doxygen group: `mg_ivf_pq_c_index_build`_ + ### cuvsMultiGpuIvfPqBuild Build a Multi-GPU IVF-PQ index @@ -209,14 +238,14 @@ cuvsMultiGpuIvfPqIndex_t index); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | -| `params` | in | `cuvsMultiGpuIvfPqIndexParams_t` | Multi-GPU IVF-PQ index parameters | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle | +| `params` | in | [`cuvsMultiGpuIvfPqIndexParams_t`](/api-reference/c-api-neighbors-mg-ivf-pq#cuvsmultigpuivfpqindexparams) | Multi-GPU IVF-PQ index parameters | | `dataset_tensor` | in | `DLManagedTensor*` | DLManagedTensor* training dataset | -| `index` | out | `cuvsMultiGpuIvfPqIndex_t` | Multi-GPU IVF-PQ index | +| `index` | out | [`cuvsMultiGpuIvfPqIndex_t`](/api-reference/c-api-neighbors-mg-ivf-pq#cuvsmultigpuivfpqindex) | Multi-GPU IVF-PQ index | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t @@ -226,6 +255,7 @@ _Source: `c/include/cuvs/neighbors/mg_ivf_pq.h:150`_ _Doxygen group: `mg_ivf_pq_c_index_search`_ + ### cuvsMultiGpuIvfPqSearch Search a Multi-GPU IVF-PQ index @@ -243,16 +273,16 @@ DLManagedTensor* distances_tensor); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | -| `params` | in | `cuvsMultiGpuIvfPqSearchParams_t` | Multi-GPU IVF-PQ search parameters | -| `index` | in | `cuvsMultiGpuIvfPqIndex_t` | Multi-GPU IVF-PQ index | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle | +| `params` | in | [`cuvsMultiGpuIvfPqSearchParams_t`](/api-reference/c-api-neighbors-mg-ivf-pq#cuvsmultigpuivfpqsearchparams) | Multi-GPU IVF-PQ search parameters | +| `index` | in | [`cuvsMultiGpuIvfPqIndex_t`](/api-reference/c-api-neighbors-mg-ivf-pq#cuvsmultigpuivfpqindex) | Multi-GPU IVF-PQ index | | `queries_tensor` | in | `DLManagedTensor*` | DLManagedTensor* queries dataset | | `neighbors_tensor` | out | `DLManagedTensor*` | DLManagedTensor* output neighbors | | `distances_tensor` | out | `DLManagedTensor*` | DLManagedTensor* output distances | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t @@ -262,6 +292,7 @@ _Source: `c/include/cuvs/neighbors/mg_ivf_pq.h:175`_ _Doxygen group: `mg_ivf_pq_c_index_extend`_ + ### cuvsMultiGpuIvfPqExtend Extend a Multi-GPU IVF-PQ index @@ -277,14 +308,14 @@ DLManagedTensor* new_indices_tensor); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | -| `index` | in,out | `cuvsMultiGpuIvfPqIndex_t` | Multi-GPU IVF-PQ index to extend | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle | +| `index` | in,out | [`cuvsMultiGpuIvfPqIndex_t`](/api-reference/c-api-neighbors-mg-ivf-pq#cuvsmultigpuivfpqindex) | Multi-GPU IVF-PQ index to extend | | `new_vectors_tensor` | in | `DLManagedTensor*` | DLManagedTensor* new vectors to add | | `new_indices_tensor` | in | `DLManagedTensor*` | DLManagedTensor* new indices (optional, can be NULL) | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t @@ -294,6 +325,7 @@ _Source: `c/include/cuvs/neighbors/mg_ivf_pq.h:200`_ _Doxygen group: `mg_ivf_pq_c_index_serialize`_ + ### cuvsMultiGpuIvfPqSerialize Serialize a Multi-GPU IVF-PQ index to file @@ -308,13 +340,13 @@ const char* filename); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | -| `index` | in | `cuvsMultiGpuIvfPqIndex_t` | Multi-GPU IVF-PQ index to serialize | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle | +| `index` | in | [`cuvsMultiGpuIvfPqIndex_t`](/api-reference/c-api-neighbors-mg-ivf-pq#cuvsmultigpuivfpqindex) | Multi-GPU IVF-PQ index to serialize | | `filename` | in | `const char*` | Path to the output file | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t @@ -324,6 +356,7 @@ _Source: `c/include/cuvs/neighbors/mg_ivf_pq.h:222`_ _Doxygen group: `mg_ivf_pq_c_index_deserialize`_ + ### cuvsMultiGpuIvfPqDeserialize Deserialize a Multi-GPU IVF-PQ index from file @@ -338,13 +371,13 @@ cuvsMultiGpuIvfPqIndex_t index); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle | | `filename` | in | `const char*` | Path to the input file | -| `index` | out | `cuvsMultiGpuIvfPqIndex_t` | Multi-GPU IVF-PQ index | +| `index` | out | [`cuvsMultiGpuIvfPqIndex_t`](/api-reference/c-api-neighbors-mg-ivf-pq#cuvsmultigpuivfpqindex) | Multi-GPU IVF-PQ index | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t @@ -354,6 +387,7 @@ _Source: `c/include/cuvs/neighbors/mg_ivf_pq.h:243`_ _Doxygen group: `mg_ivf_pq_c_index_distribute`_ + ### cuvsMultiGpuIvfPqDistribute Distribute a local IVF-PQ index to create a Multi-GPU index @@ -368,13 +402,13 @@ cuvsMultiGpuIvfPqIndex_t index); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle | | `filename` | in | `const char*` | Path to the local index file | -| `index` | out | `cuvsMultiGpuIvfPqIndex_t` | Multi-GPU IVF-PQ index | +| `index` | out | [`cuvsMultiGpuIvfPqIndex_t`](/api-reference/c-api-neighbors-mg-ivf-pq#cuvsmultigpuivfpqindex) | Multi-GPU IVF-PQ index | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t diff --git a/fern/pages/c_api/c-api-neighbors-nn-descent.md b/fern/pages/c_api/c-api-neighbors-nn-descent.md index 37825002b1..916499051d 100644 --- a/fern/pages/c_api/c-api-neighbors-nn-descent.md +++ b/fern/pages/c_api/c-api-neighbors-nn-descent.md @@ -6,10 +6,32 @@ slug: api-reference/c-api-neighbors-nn-descent _Source header: `c/include/cuvs/neighbors/nn_descent.h`_ +## Types + + +### cuvsNNDescentDistCompDtype + +Dtype to use for distance computation + +```c +typedef enum { ... } cuvsNNDescentDistCompDtype; +``` + +**Values** + +| Name | Value | Description | +| --- | --- | --- | +| `NND_DIST_COMP_AUTO` | `0` | Automatically determine the best dtype for distance computation based on the dataset dimensions. | +| `NND_DIST_COMP_FP32` | `1` | Use fp32 distance computation for better precision at the cost of performance and memory usage. | +| `NND_DIST_COMP_FP16` | `2` | Use fp16 distance computation. | + +_Source: `c/include/cuvs/neighbors/nn_descent.h:24`_ + ## The nn-descent algorithm parameters. _Doxygen group: `nn_descent_c_index_params`_ + ### cuvsNNDescentIndexParams Parameters used to build an nn-descent index @@ -24,17 +46,18 @@ struct cuvsNNDescentIndexParams { ... } ; | Name | Type | Description | | --- | --- | --- | -| `metric` | `cuvsDistanceType` | | +| `metric` | [`cuvsDistanceType`](/api-reference/c-api-distance-distance#cuvsdistancetype) | | | `metric_arg` | `float` | | | `graph_degree` | `size_t` | | | `intermediate_graph_degree` | `size_t` | | | `max_iterations` | `size_t` | | | `termination_threshold` | `float` | | | `return_distances` | `bool` | | -| `dist_comp_dtype` | `cuvsNNDescentDistCompDtype` | | +| `dist_comp_dtype` | [`cuvsNNDescentDistCompDtype`](/api-reference/c-api-neighbors-nn-descent#cuvsnndescentdistcompdtype) | | _Source: `c/include/cuvs/neighbors/nn_descent.h:52`_ + ### cuvsNNDescentIndexParamsCreate Allocate NN-Descent Index params, and populate with default values @@ -47,16 +70,17 @@ cuvsError_t cuvsNNDescentIndexParamsCreate(cuvsNNDescentIndexParams_t* index_par | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `index_params` | in | `cuvsNNDescentIndexParams_t*` | cuvsNNDescentIndexParams_t to allocate | +| `index_params` | in | [`cuvsNNDescentIndexParams_t*`](/api-reference/c-api-neighbors-nn-descent#cuvsnndescentindexparams) | cuvsNNDescentIndexParams_t to allocate | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/neighbors/nn_descent.h:71`_ + ### cuvsNNDescentIndexParamsDestroy De-allocate NN-Descent Index params @@ -69,11 +93,11 @@ cuvsError_t cuvsNNDescentIndexParamsDestroy(cuvsNNDescentIndexParams_t index_par | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `index_params` | in | `cuvsNNDescentIndexParams_t` | | +| `index_params` | in | [`cuvsNNDescentIndexParams_t`](/api-reference/c-api-neighbors-nn-descent#cuvsnndescentindexparams) | | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t @@ -83,6 +107,25 @@ _Source: `c/include/cuvs/neighbors/nn_descent.h:79`_ _Doxygen group: `nn_descent_c_index`_ + +### cuvsNNDescentIndex + +Struct to hold address of cuvs::neighbors::nn_descent::index and its active trained dtype + +```c +typedef struct { ... } cuvsNNDescentIndex; +``` + +**Fields** + +| Name | Type | Description | +| --- | --- | --- | +| `addr` | `uintptr_t` | | +| `dtype` | `DLDataType` | | + +_Source: `c/include/cuvs/neighbors/nn_descent.h:92`_ + + ### cuvsNNDescentIndexCreate Allocate NN-Descent index @@ -95,16 +138,17 @@ cuvsError_t cuvsNNDescentIndexCreate(cuvsNNDescentIndex_t* index); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `index` | in | `cuvsNNDescentIndex_t*` | cuvsNNDescentIndex_t to allocate | +| `index` | in | [`cuvsNNDescentIndex_t*`](/api-reference/c-api-neighbors-nn-descent#cuvsnndescentindex) | cuvsNNDescentIndex_t to allocate | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/neighbors/nn_descent.h:105`_ + ### cuvsNNDescentIndexDestroy De-allocate NN-Descent index @@ -117,11 +161,11 @@ cuvsError_t cuvsNNDescentIndexDestroy(cuvsNNDescentIndex_t index); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `index` | in | `cuvsNNDescentIndex_t` | cuvsNNDescentIndex_t to de-allocate | +| `index` | in | [`cuvsNNDescentIndex_t`](/api-reference/c-api-neighbors-nn-descent#cuvsnndescentindex) | cuvsNNDescentIndex_t to de-allocate | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) _Source: `c/include/cuvs/neighbors/nn_descent.h:112`_ @@ -129,6 +173,7 @@ _Source: `c/include/cuvs/neighbors/nn_descent.h:112`_ _Doxygen group: `nn_descent_c_index_build`_ + ### cuvsNNDescentBuild Build a NN-Descent index with a `DLManagedTensor` which has underlying @@ -152,15 +197,15 @@ cuvsNNDescentIndex_t index); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | -| `index_params` | in | `cuvsNNDescentIndexParams_t` | cuvsNNDescentIndexParams_t used to build NN-Descent index | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle | +| `index_params` | in | [`cuvsNNDescentIndexParams_t`](/api-reference/c-api-neighbors-nn-descent#cuvsnndescentindexparams) | cuvsNNDescentIndexParams_t used to build NN-Descent index | | `dataset` | in | `DLManagedTensor*` | DLManagedTensor* training dataset on host or device memory | | `graph` | inout | `DLManagedTensor*` | Optional preallocated graph on host memory to store output | -| `index` | out | `cuvsNNDescentIndex_t` | cuvsNNDescentIndex_t Newly built NN-Descent index | +| `index` | out | [`cuvsNNDescentIndex_t`](/api-reference/c-api-neighbors-nn-descent#cuvsnndescentindex) | cuvsNNDescentIndex_t Newly built NN-Descent index | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t diff --git a/fern/pages/c_api/c-api-neighbors-refine.md b/fern/pages/c_api/c-api-neighbors-refine.md index 70bd403fd0..c73f45bfce 100644 --- a/fern/pages/c_api/c-api-neighbors-refine.md +++ b/fern/pages/c_api/c-api-neighbors-refine.md @@ -10,6 +10,7 @@ _Source header: `c/include/cuvs/neighbors/refine.h`_ _Doxygen group: `ann_refine_c`_ + ### cuvsRefine Refine nearest neighbor search. @@ -30,16 +31,16 @@ Refinement is an operation that follows an approximate NN search. The approximat | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle | | `dataset` | in | `DLManagedTensor*` | device matrix that stores the dataset [n_rows, dims] | | `queries` | in | `DLManagedTensor*` | device matrix of the queries [n_queris, dims] | | `candidates` | in | `DLManagedTensor*` | indices of candidate vectors [n_queries, n_candidates], where n_candidates >= k | -| `metric` | in | `cuvsDistanceType` | distance metric to use. Euclidean (L2) is used by default | +| `metric` | in | [`cuvsDistanceType`](/api-reference/c-api-distance-distance#cuvsdistancetype) | distance metric to use. Euclidean (L2) is used by default | | `indices` | out | `DLManagedTensor*` | device matrix that stores the refined indices [n_queries, k] | | `distances` | out | `DLManagedTensor*` | device matrix that stores the refined distances [n_queries, k] | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) _Source: `c/include/cuvs/neighbors/refine.h:37`_ diff --git a/fern/pages/c_api/c-api-neighbors-tiered-index.md b/fern/pages/c_api/c-api-neighbors-tiered-index.md index 39461843f0..7be0a86f73 100644 --- a/fern/pages/c_api/c-api-neighbors-tiered-index.md +++ b/fern/pages/c_api/c-api-neighbors-tiered-index.md @@ -6,10 +6,53 @@ slug: api-reference/c-api-neighbors-tiered-index _Source header: `c/include/cuvs/neighbors/tiered_index.h`_ +## Types + + +### cuvsTieredIndexANNAlgo + +Enum to hold which ANN algorithm is being used in the tiered index + +```c +typedef enum { ... } cuvsTieredIndexANNAlgo; +``` + +**Values** + +| Name | Value | +| --- | --- | +| `CUVS_TIERED_INDEX_ALGO_CAGRA` | `0` | +| `CUVS_TIERED_INDEX_ALGO_IVF_FLAT` | `1` | +| `CUVS_TIERED_INDEX_ALGO_IVF_PQ` | `2` | + +_Source: `c/include/cuvs/neighbors/tiered_index.h:24`_ + ## Tiered Index _Doxygen group: `tiered_index_c_index`_ + +### cuvsTieredIndex + +Struct to hold address of cuvs::neighbors::tiered_index::index and its active trained + +dtype + +```c +typedef struct { ... } cuvsTieredIndex; +``` + +**Fields** + +| Name | Type | Description | +| --- | --- | --- | +| `addr` | `uintptr_t` | | +| `dtype` | `DLDataType` | | +| `algo` | [`cuvsTieredIndexANNAlgo`](/api-reference/c-api-neighbors-tiered-index#cuvstieredindexannalgo) | | + +_Source: `c/include/cuvs/neighbors/tiered_index.h:39`_ + + ### cuvsTieredIndexCreate Allocate Tiered Index @@ -22,16 +65,17 @@ cuvsError_t cuvsTieredIndexCreate(cuvsTieredIndex_t* index); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `index` | in | `cuvsTieredIndex_t*` | cuvsTieredIndex_t to allocate | +| `index` | in | [`cuvsTieredIndex_t*`](/api-reference/c-api-neighbors-tiered-index#cuvstieredindex) | cuvsTieredIndex_t to allocate | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/neighbors/tiered_index.h:53`_ + ### cuvsTieredIndexDestroy De-allocate Tiered index @@ -44,11 +88,11 @@ cuvsError_t cuvsTieredIndexDestroy(cuvsTieredIndex_t index); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `index` | in | `cuvsTieredIndex_t` | cuvsTieredIndex_t to de-allocate | +| `index` | in | [`cuvsTieredIndex_t`](/api-reference/c-api-neighbors-tiered-index#cuvstieredindex) | cuvsTieredIndex_t to de-allocate | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) _Source: `c/include/cuvs/neighbors/tiered_index.h:60`_ @@ -56,6 +100,7 @@ _Source: `c/include/cuvs/neighbors/tiered_index.h:60`_ _Doxygen group: `tiered_c_index_params`_ + ### cuvsTieredIndexParams Supplemental parameters to build a TieredIndex @@ -68,16 +113,17 @@ struct cuvsTieredIndexParams { ... } ; | Name | Type | Description | | --- | --- | --- | -| `metric` | `cuvsDistanceType` | Distance type. | -| `algo` | `cuvsTieredIndexANNAlgo` | The type of ANN algorithm we are using | +| `metric` | [`cuvsDistanceType`](/api-reference/c-api-distance-distance#cuvsdistancetype) | Distance type. | +| `algo` | [`cuvsTieredIndexANNAlgo`](/api-reference/c-api-neighbors-tiered-index#cuvstieredindexannalgo) | The type of ANN algorithm we are using | | `min_ann_rows` | `int64_t` | The minimum number of rows necessary in the index to create an ann index | | `create_ann_index_on_extend` | `bool` | Whether or not to create a new ann index on extend, if the number of rows in the incremental (bfknn) portion is above min_ann_rows | -| `cagra_params` | `cuvsCagraIndexParams_t` | Optional parameters for building a cagra index | -| `ivf_flat_params` | `cuvsIvfFlatIndexParams_t` | Optional parameters for building a ivf_flat index | -| `ivf_pq_params` | `cuvsIvfPqIndexParams_t` | Optional parameters for building a ivf-pq index | +| `cagra_params` | [`cuvsCagraIndexParams_t`](/api-reference/c-api-neighbors-cagra#cuvscagraindexparams) | Optional parameters for building a cagra index | +| `ivf_flat_params` | [`cuvsIvfFlatIndexParams_t`](/api-reference/c-api-neighbors-ivf-flat#cuvsivfflatindexparams) | Optional parameters for building a ivf_flat index | +| `ivf_pq_params` | [`cuvsIvfPqIndexParams_t`](/api-reference/c-api-neighbors-ivf-pq#cuvsivfpqindexparams) | Optional parameters for building a ivf-pq index | _Source: `c/include/cuvs/neighbors/tiered_index.h:72`_ + ### cuvsTieredIndexParamsCreate Allocate Tiered Index Params and populate with default values @@ -90,16 +136,17 @@ cuvsError_t cuvsTieredIndexParamsCreate(cuvsTieredIndexParams_t* index_params); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `index_params` | in | `cuvsTieredIndexParams_t*` | cuvsTieredIndexParams_t to allocate | +| `index_params` | in | [`cuvsTieredIndexParams_t*`](/api-reference/c-api-neighbors-tiered-index#cuvstieredindexparams) | cuvsTieredIndexParams_t to allocate | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/neighbors/tiered_index.h:105`_ + ### cuvsTieredIndexParamsDestroy De-allocate Tiered Index params @@ -112,11 +159,11 @@ cuvsError_t cuvsTieredIndexParamsDestroy(cuvsTieredIndexParams_t index_params); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `index_params` | in | `cuvsTieredIndexParams_t` | | +| `index_params` | in | [`cuvsTieredIndexParams_t`](/api-reference/c-api-neighbors-tiered-index#cuvstieredindexparams) | | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t @@ -126,6 +173,7 @@ _Source: `c/include/cuvs/neighbors/tiered_index.h:113`_ _Doxygen group: `tieredindex_c_index_build`_ + ### cuvsTieredIndexBuild Build a TieredIndex index with a `DLManagedTensor` which has underlying @@ -146,14 +194,14 @@ cuvsTieredIndex_t index); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | -| `index_params` | in | `cuvsTieredIndexParams_t` | Index parameters to use when building the index | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle | +| `index_params` | in | [`cuvsTieredIndexParams_t`](/api-reference/c-api-neighbors-tiered-index#cuvstieredindexparams) | Index parameters to use when building the index | | `dataset` | in | `DLManagedTensor*` | DLManagedTensor* training dataset | -| `index` | out | `cuvsTieredIndex_t` | cuvsTieredIndex_t Newly built TieredIndex index | +| `index` | out | [`cuvsTieredIndex_t`](/api-reference/c-api-neighbors-tiered-index#cuvstieredindex) | cuvsTieredIndex_t Newly built TieredIndex index | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t @@ -163,6 +211,7 @@ _Source: `c/include/cuvs/neighbors/tiered_index.h:162`_ _Doxygen group: `tieredindex_c_index_search`_ + ### cuvsTieredIndexSearch Search a TieredIndex index with a `DLManagedTensor` @@ -183,17 +232,17 @@ cuvsCagraSearchParams_t, cuvsIvfFlatSearchParams_t, cuvsIvfPqSearchParams_t depe | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle | | `search_params` | in | `void*` | params used to the ANN index, should be one of | -| `index` | in | `cuvsTieredIndex_t` | cuvsTieredIndex which has been returned by `cuvsTieredIndexBuild` | +| `index` | in | [`cuvsTieredIndex_t`](/api-reference/c-api-neighbors-tiered-index#cuvstieredindex) | cuvsTieredIndex which has been returned by `cuvsTieredIndexBuild` | | `queries` | in | `DLManagedTensor*` | DLManagedTensor* queries dataset to search | | `neighbors` | out | `DLManagedTensor*` | DLManagedTensor* output `k` neighbors for queries | | `distances` | out | `DLManagedTensor*` | DLManagedTensor* output `k` distances for queries | -| `prefilter` | in | `cuvsFilter` | cuvsFilter input prefilter that can be used to filter queries and neighbors based on the given bitmap. | +| `prefilter` | in | [`cuvsFilter`](/api-reference/c-api-neighbors-common#cuvsfilter) | cuvsFilter input prefilter that can be used to filter queries and neighbors based on the given bitmap. | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) _Source: `c/include/cuvs/neighbors/tiered_index.h:212`_ @@ -201,6 +250,7 @@ _Source: `c/include/cuvs/neighbors/tiered_index.h:212`_ _Doxygen group: `tiered_c_index_extend`_ + ### cuvsTieredIndexExtend Extend the index with the new data. @@ -215,13 +265,13 @@ cuvsTieredIndex_t index); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle | | `new_vectors` | in | `DLManagedTensor*` | DLManagedTensor* the new vectors to add to the index | -| `index` | inout | `cuvsTieredIndex_t` | Tiered index to be extended | +| `index` | inout | [`cuvsTieredIndex_t`](/api-reference/c-api-neighbors-tiered-index#cuvstieredindex) | Tiered index to be extended | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t @@ -231,6 +281,7 @@ _Source: `c/include/cuvs/neighbors/tiered_index.h:235`_ _Doxygen group: `tiered_c_index_merge`_ + ### cuvsTieredIndexMerge Merge multiple indices together into a single index @@ -247,15 +298,15 @@ cuvsTieredIndex_t output_index); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | -| `index_params` | in | `cuvsTieredIndexParams_t` | Index parameters to use when merging | -| `indices` | in | `cuvsTieredIndex_t*` | pointers to indices to merge together | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle | +| `index_params` | in | [`cuvsTieredIndexParams_t`](/api-reference/c-api-neighbors-tiered-index#cuvstieredindexparams) | Index parameters to use when merging | +| `indices` | in | [`cuvsTieredIndex_t*`](/api-reference/c-api-neighbors-tiered-index#cuvstieredindex) | pointers to indices to merge together | | `num_indices` | in | `size_t` | the number of indices to merge | -| `output_index` | out | `cuvsTieredIndex_t` | the merged index | +| `output_index` | out | [`cuvsTieredIndex_t`](/api-reference/c-api-neighbors-tiered-index#cuvstieredindex) | the merged index | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t diff --git a/fern/pages/c_api/c-api-neighbors-vamana.md b/fern/pages/c_api/c-api-neighbors-vamana.md index 37792781ee..c2df69c0cb 100644 --- a/fern/pages/c_api/c-api-neighbors-vamana.md +++ b/fern/pages/c_api/c-api-neighbors-vamana.md @@ -10,6 +10,7 @@ _Source header: `c/include/cuvs/neighbors/vamana.h`_ _Doxygen group: `vamana_c_index_params`_ + ### cuvsVamanaIndexParams Supplemental parameters to build Vamana Index @@ -24,7 +25,7 @@ struct cuvsVamanaIndexParams { ... } ; | Name | Type | Description | | --- | --- | --- | -| `metric` | `cuvsDistanceType` | Distance type. | +| `metric` | [`cuvsDistanceType`](/api-reference/c-api-distance-distance#cuvsdistancetype) | Distance type. | | `graph_degree` | `uint32_t` | Maximum degree of output graph corresponds to the R parameter in the original Vamana literature. | | `visited_size` | `uint32_t` | Maximum number of visited nodes per search corresponds to the L parameter in the Vamana literature * | | `vamana_iters` | `float` | Number of Vamana vector insertion iterations (each iteration inserts all vectors). | @@ -36,6 +37,7 @@ struct cuvsVamanaIndexParams { ... } ; _Source: `c/include/cuvs/neighbors/vamana.h:37`_ + ### cuvsVamanaIndexParamsCreate Allocate Vamana Index params, and populate with default values @@ -48,16 +50,17 @@ cuvsError_t cuvsVamanaIndexParamsCreate(cuvsVamanaIndexParams_t* params); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `params` | in | `cuvsVamanaIndexParams_t*` | cuvsVamanaIndexParams_t to allocate | +| `params` | in | [`cuvsVamanaIndexParams_t*`](/api-reference/c-api-neighbors-vamana#cuvsvamanaindexparams) | cuvsVamanaIndexParams_t to allocate | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/neighbors/vamana.h:69`_ + ### cuvsVamanaIndexParamsDestroy De-allocate Vamana Index params @@ -70,11 +73,11 @@ cuvsError_t cuvsVamanaIndexParamsDestroy(cuvsVamanaIndexParams_t params); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `params` | in | `cuvsVamanaIndexParams_t` | cuvsVamanaIndexParams_t to de-allocate | +| `params` | in | [`cuvsVamanaIndexParams_t`](/api-reference/c-api-neighbors-vamana#cuvsvamanaindexparams) | cuvsVamanaIndexParams_t to de-allocate | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t @@ -84,6 +87,25 @@ _Source: `c/include/cuvs/neighbors/vamana.h:77`_ _Doxygen group: `vamana_c_index`_ + +### cuvsVamanaIndex + +Struct to hold address of cuvs::neighbors::vamana::index and its active trained dtype + +```c +typedef struct { ... } cuvsVamanaIndex; +``` + +**Fields** + +| Name | Type | Description | +| --- | --- | --- | +| `addr` | `uintptr_t` | | +| `dtype` | `DLDataType` | | + +_Source: `c/include/cuvs/neighbors/vamana.h:92`_ + + ### cuvsVamanaIndexCreate Allocate Vamana index @@ -96,16 +118,17 @@ cuvsError_t cuvsVamanaIndexCreate(cuvsVamanaIndex_t* index); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `index` | in | `cuvsVamanaIndex_t*` | cuvsVamanaIndex_t to allocate | +| `index` | in | [`cuvsVamanaIndex_t*`](/api-reference/c-api-neighbors-vamana#cuvsvamanaindex) | cuvsVamanaIndex_t to allocate | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/neighbors/vamana.h:106`_ + ### cuvsVamanaIndexDestroy De-allocate Vamana index @@ -118,16 +141,17 @@ cuvsError_t cuvsVamanaIndexDestroy(cuvsVamanaIndex_t index); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `index` | in | `cuvsVamanaIndex_t` | cuvsVamanaIndex_t to de-allocate | +| `index` | in | [`cuvsVamanaIndex_t`](/api-reference/c-api-neighbors-vamana#cuvsvamanaindex) | cuvsVamanaIndex_t to de-allocate | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/neighbors/vamana.h:114`_ + ### cuvsVamanaIndexGetDims Get the dimension of the index @@ -140,12 +164,12 @@ cuvsError_t cuvsVamanaIndexGetDims(cuvsVamanaIndex_t index, int* dim); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `index` | in | `cuvsVamanaIndex_t` | cuvsVamanaIndex_t to get dimension of | +| `index` | in | [`cuvsVamanaIndex_t`](/api-reference/c-api-neighbors-vamana#cuvsvamanaindex) | cuvsVamanaIndex_t to get dimension of | | `dim` | out | `int*` | pointer to dimension to set | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t @@ -155,6 +179,7 @@ _Source: `c/include/cuvs/neighbors/vamana.h:123`_ _Doxygen group: `vamana_c_index_build`_ + ### cuvsVamanaBuild Build Vamana index @@ -180,14 +205,14 @@ Usage example: | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | -| `params` | in | `cuvsVamanaIndexParams_t` | cuvsVamanaIndexParams_t used to build Vamana index | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle | +| `params` | in | [`cuvsVamanaIndexParams_t`](/api-reference/c-api-neighbors-vamana#cuvsvamanaindexparams) | cuvsVamanaIndexParams_t used to build Vamana index | | `dataset` | in | `DLManagedTensor*` | DLManagedTensor* training dataset | -| `index` | out | `cuvsVamanaIndex_t` | cuvsVamanaIndex_t Vamana index | +| `index` | out | [`cuvsVamanaIndex_t`](/api-reference/c-api-neighbors-vamana#cuvsvamanaindex) | cuvsVamanaIndex_t Vamana index | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t @@ -197,6 +222,7 @@ _Source: `c/include/cuvs/neighbors/vamana.h:169`_ _Doxygen group: `vamana_c_index_serialize`_ + ### cuvsVamanaSerialize Save Vamana index to file @@ -216,14 +242,14 @@ Serialized Index is to be used by the DiskANN open-source repository for graph s | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle | | `filename` | in | `const char*` | the file prefix for where the index is saved | -| `index` | in | `cuvsVamanaIndex_t` | cuvsVamanaIndex_t to serialize | +| `index` | in | [`cuvsVamanaIndex_t`](/api-reference/c-api-neighbors-vamana#cuvsvamanaindex) | cuvsVamanaIndex_t to serialize | | `include_dataset` | in | `bool` | whether to include the dataset in the serialized index | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t diff --git a/fern/pages/c_api/c-api-preprocessing-pca.md b/fern/pages/c_api/c-api-preprocessing-pca.md index 5439ef6033..21470d2375 100644 --- a/fern/pages/c_api/c-api-preprocessing-pca.md +++ b/fern/pages/c_api/c-api-preprocessing-pca.md @@ -10,6 +10,7 @@ _Source header: `c/include/cuvs/preprocessing/pca.h`_ _Doxygen group: `preprocessing_c_pca`_ + ### cuvsPcaSolver Solver algorithm for PCA eigen decomposition. @@ -27,6 +28,7 @@ enum cuvsPcaSolver { ... } ; _Source: `c/include/cuvs/preprocessing/pca.h:25`_ + ### cuvsPcaParams Parameters for PCA decomposition. @@ -42,12 +44,13 @@ struct cuvsPcaParams { ... } ; | `n_components` | `int` | Number of principal components to keep. | | `copy` | `bool` | If false, data passed to fit are overwritten and running fit(X).transform(X) will not yield the expected results; use fit_transform(X) instead. | | `whiten` | `bool` | When true the component vectors are multiplied by the square root of n_samples and then divided by the singular values to ensure uncorrelated outputs with unit component-wise variances. | -| `algorithm` | `enum cuvsPcaSolver` | Solver algorithm to use. | +| `algorithm` | [`enum cuvsPcaSolver`](/api-reference/c-api-preprocessing-pca#cuvspcasolver) | Solver algorithm to use. | | `tol` | `float` | Tolerance for singular values (used by Jacobi solver). | | `n_iterations` | `int` | Number of iterations for the power method (Jacobi solver). | _Source: `c/include/cuvs/preprocessing/pca.h:35`_ + ### cuvsPcaParamsCreate Allocate PCA params and populate with default values. @@ -60,16 +63,17 @@ cuvsError_t cuvsPcaParamsCreate(cuvsPcaParams_t* params); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `params` | out | `cuvsPcaParams_t*` | cuvsPcaParams_t to allocate | +| `params` | out | [`cuvsPcaParams_t*`](/api-reference/c-api-preprocessing-pca#cuvspcaparams) | cuvsPcaParams_t to allocate | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/preprocessing/pca.h:70`_ + ### cuvsPcaParamsDestroy De-allocate PCA params. @@ -82,16 +86,17 @@ cuvsError_t cuvsPcaParamsDestroy(cuvsPcaParams_t params); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `params` | in | `cuvsPcaParams_t` | cuvsPcaParams_t to de-allocate | +| `params` | in | [`cuvsPcaParams_t`](/api-reference/c-api-preprocessing-pca#cuvspcaparams) | cuvsPcaParams_t to de-allocate | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/preprocessing/pca.h:78`_ + ### cuvsPcaFit Perform PCA fit operation. @@ -115,8 +120,8 @@ Computes the principal components, explained variances, singular values, and col | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | -| `params` | in | `cuvsPcaParams_t` | PCA parameters | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle | +| `params` | in | [`cuvsPcaParams_t`](/api-reference/c-api-preprocessing-pca#cuvspcaparams) | PCA parameters | | `input` | inout | `DLManagedTensor*` | input data [n_rows x n_cols] (col-major, float32, device) | | `components` | out | `DLManagedTensor*` | principal components [n_components x n_cols] (col-major, float32, device) | | `explained_var` | out | `DLManagedTensor*` | explained variances [n_components] (float32, device) | @@ -128,12 +133,13 @@ Computes the principal components, explained variances, singular values, and col **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/preprocessing/pca.h:128`_ + ### cuvsPcaFitTransform Perform PCA fit and transform in a single operation. @@ -158,8 +164,8 @@ Computes the principal components and transforms the input data into the eigensp | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | -| `params` | in | `cuvsPcaParams_t` | PCA parameters | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle | +| `params` | in | [`cuvsPcaParams_t`](/api-reference/c-api-preprocessing-pca#cuvspcaparams) | PCA parameters | | `input` | inout | `DLManagedTensor*` | input data [n_rows x n_cols] (col-major, float32, device) | | `trans_input` | out | `DLManagedTensor*` | transformed data [n_rows x n_components] (col-major, float32, device) | | `components` | out | `DLManagedTensor*` | principal components [n_components x n_cols] (col-major, float32, device) | @@ -172,12 +178,13 @@ Computes the principal components and transforms the input data into the eigensp **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/preprocessing/pca.h:157`_ + ### cuvsPcaTransform Perform PCA transform operation. @@ -198,8 +205,8 @@ Transforms the input data into the eigenspace using previously computed principa | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | -| `params` | in | `cuvsPcaParams_t` | PCA parameters | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle | +| `params` | in | [`cuvsPcaParams_t`](/api-reference/c-api-preprocessing-pca#cuvspcaparams) | PCA parameters | | `input` | inout | `DLManagedTensor*` | data to transform [n_rows x n_cols] (col-major, float32, device) | | `components` | in | `DLManagedTensor*` | principal components [n_components x n_cols] (col-major, float32, device) | | `singular_vals` | in | `DLManagedTensor*` | singular values [n_components] (float32, device) | @@ -208,12 +215,13 @@ Transforms the input data into the eigenspace using previously computed principa **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/preprocessing/pca.h:183`_ + ### cuvsPcaInverseTransform Perform PCA inverse transform operation. @@ -234,8 +242,8 @@ Transforms data from the eigenspace back to the original space. | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | cuvsResources_t opaque C handle | -| `params` | in | `cuvsPcaParams_t` | PCA parameters | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle | +| `params` | in | [`cuvsPcaParams_t`](/api-reference/c-api-preprocessing-pca#cuvspcaparams) | PCA parameters | | `trans_input` | in | `DLManagedTensor*` | transformed data [n_rows x n_components] (col-major, float32, device) | | `components` | in | `DLManagedTensor*` | principal components [n_components x n_cols] (col-major, float32, device) | | `singular_vals` | in | `DLManagedTensor*` | singular values [n_components] (float32, device) | @@ -244,7 +252,7 @@ Transforms data from the eigenspace back to the original space. **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t diff --git a/fern/pages/c_api/c-api-preprocessing-quantize-binary.md b/fern/pages/c_api/c-api-preprocessing-quantize-binary.md index 5377ebc453..cea4f53736 100644 --- a/fern/pages/c_api/c-api-preprocessing-quantize-binary.md +++ b/fern/pages/c_api/c-api-preprocessing-quantize-binary.md @@ -10,6 +10,7 @@ _Source header: `c/include/cuvs/preprocessing/quantize/binary.h`_ _Doxygen group: `preprocessing_c_binary`_ + ### cuvsBinaryQuantizerThreshold In the cuvsBinaryQuantizerTransform function, a bit is set if the corresponding element in @@ -30,6 +31,7 @@ enum cuvsBinaryQuantizerThreshold { ... } ; _Source: `c/include/cuvs/preprocessing/quantize/binary.h:26`_ + ### cuvsBinaryQuantizerParams Binary quantizer parameters. @@ -47,6 +49,7 @@ struct cuvsBinaryQuantizerParams { ... } ; _Source: `c/include/cuvs/preprocessing/quantize/binary.h:35`_ + ### cuvsBinaryQuantizerParamsCreate Allocate Binary Quantizer params, and populate with default values @@ -59,16 +62,17 @@ cuvsError_t cuvsBinaryQuantizerParamsCreate(cuvsBinaryQuantizerParams_t* params) | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `params` | in | `cuvsBinaryQuantizerParams_t*` | cuvsBinaryQuantizerParams_t to allocate | +| `params` | in | [`cuvsBinaryQuantizerParams_t*`](/api-reference/c-api-preprocessing-quantize-binary#cuvsbinaryquantizerparams) | cuvsBinaryQuantizerParams_t to allocate | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/preprocessing/quantize/binary.h:55`_ + ### cuvsBinaryQuantizerParamsDestroy De-allocate Binary Quantizer params @@ -81,16 +85,37 @@ cuvsError_t cuvsBinaryQuantizerParamsDestroy(cuvsBinaryQuantizerParams_t params) | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `params` | in | `cuvsBinaryQuantizerParams_t` | | +| `params` | in | [`cuvsBinaryQuantizerParams_t`](/api-reference/c-api-preprocessing-quantize-binary#cuvsbinaryquantizerparams) | | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/preprocessing/quantize/binary.h:63`_ + +### cuvsBinaryQuantizer + +Defines and stores threshold for quantization upon training + +The quantization is performed by a linear mapping of an interval in the float data type to the full range of the quantized int type. + +```c +typedef struct { ... } cuvsBinaryQuantizer; +``` + +**Fields** + +| Name | Type | Description | +| --- | --- | --- | +| `addr` | `uintptr_t` | | +| `dtype` | `DLDataType` | | + +_Source: `c/include/cuvs/preprocessing/quantize/binary.h:71`_ + + ### cuvsBinaryQuantizerCreate Allocate Binary Quantizer and populate with default values @@ -103,16 +128,17 @@ cuvsError_t cuvsBinaryQuantizerCreate(cuvsBinaryQuantizer_t* quantizer); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `quantizer` | in | `cuvsBinaryQuantizer_t*` | cuvsBinaryQuantizer_t to allocate | +| `quantizer` | in | [`cuvsBinaryQuantizer_t*`](/api-reference/c-api-preprocessing-quantize-binary#cuvsbinaryquantizer) | cuvsBinaryQuantizer_t to allocate | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/preprocessing/quantize/binary.h:84`_ + ### cuvsBinaryQuantizerDestroy De-allocate Binary Quantizer @@ -125,16 +151,17 @@ cuvsError_t cuvsBinaryQuantizerDestroy(cuvsBinaryQuantizer_t quantizer); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `quantizer` | in | `cuvsBinaryQuantizer_t` | | +| `quantizer` | in | [`cuvsBinaryQuantizer_t`](/api-reference/c-api-preprocessing-quantize-binary#cuvsbinaryquantizer) | | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/preprocessing/quantize/binary.h:92`_ + ### cuvsBinaryQuantizerTrain Trains a binary quantizer to be used later for quantizing the dataset. @@ -150,17 +177,18 @@ cuvsBinaryQuantizer_t quantizer); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | raft resource | -| `params` | in | `cuvsBinaryQuantizerParams_t` | configure binary quantizer, e.g. threshold | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | raft resource | +| `params` | in | [`cuvsBinaryQuantizerParams_t`](/api-reference/c-api-preprocessing-quantize-binary#cuvsbinaryquantizerparams) | configure binary quantizer, e.g. threshold | | `dataset` | in | `DLManagedTensor*` | a row-major host or device matrix | -| `quantizer` | out | `cuvsBinaryQuantizer_t` | trained binary quantizer | +| `quantizer` | out | [`cuvsBinaryQuantizer_t`](/api-reference/c-api-preprocessing-quantize-binary#cuvsbinaryquantizer) | trained binary quantizer | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) _Source: `c/include/cuvs/preprocessing/quantize/binary.h:102`_ + ### cuvsBinaryQuantizerTransform Applies binary quantization transform to the given dataset @@ -177,16 +205,17 @@ This applies binary quantization to a dataset, changing any positive values to a | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | raft resource | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | raft resource | | `dataset` | in | `DLManagedTensor*` | a row-major host or device matrix to transform | | `out` | out | `DLManagedTensor*` | a row-major host or device matrix to store transformed data | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) _Source: `c/include/cuvs/preprocessing/quantize/binary.h:118`_ + ### cuvsBinaryQuantizerTransformWithParams Applies binary quantization transform to the given dataset @@ -204,13 +233,13 @@ This applies binary quantization to a dataset, changing any values that are larg | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | raft resource | -| `quantizer` | in | `cuvsBinaryQuantizer_t` | binary quantizer | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | raft resource | +| `quantizer` | in | [`cuvsBinaryQuantizer_t`](/api-reference/c-api-preprocessing-quantize-binary#cuvsbinaryquantizer) | binary quantizer | | `dataset` | in | `DLManagedTensor*` | a row-major host or device matrix to transform | | `out` | out | `DLManagedTensor*` | a row-major host or device matrix to store transformed data | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) _Source: `c/include/cuvs/preprocessing/quantize/binary.h:134`_ diff --git a/fern/pages/c_api/c-api-preprocessing-quantize-pq.md b/fern/pages/c_api/c-api-preprocessing-quantize-pq.md index 3e61595e9c..14af2b8394 100644 --- a/fern/pages/c_api/c-api-preprocessing-quantize-pq.md +++ b/fern/pages/c_api/c-api-preprocessing-quantize-pq.md @@ -10,6 +10,7 @@ _Source header: `c/include/cuvs/preprocessing/quantize/pq.h`_ _Doxygen group: `preprocessing_c_pq`_ + ### cuvsProductQuantizerParams Product quantizer parameters. @@ -28,12 +29,13 @@ struct cuvsProductQuantizerParams { ... } ; | `use_vq` | `bool` | Whether to use Vector Quantization (KMeans) before product quantization (PQ). When true, VQ is used before PQ. When false, only product quantization is used. | | `vq_n_centers` | `uint32_t` | Vector Quantization (VQ) codebook size - number of "coarse cluster centers". When zero, an optimal value is selected using a heuristic. When one, only product quantization is used. | | `kmeans_n_iters` | `uint32_t` | The number of iterations searching for kmeans centers (both VQ & PQ phases). | -| `pq_kmeans_type` | `cuvsKMeansType` | The type of kmeans algorithm to use for PQ training. | +| `pq_kmeans_type` | [`cuvsKMeansType`](/api-reference/c-api-cluster-kmeans#cuvskmeanstype) | The type of kmeans algorithm to use for PQ training. | | `max_train_points_per_pq_code` | `uint32_t` | The max number of data points to use per PQ code during PQ codebook training. Using more data points per PQ code may increase the quality of PQ codebook but may also increase the build time. We will use `pq_n_centers * max_train_points_per_pq_code` training points to train each PQ codebook. | | `max_train_points_per_vq_cluster` | `uint32_t` | The max number of data points to use per VQ cluster. | _Source: `c/include/cuvs/preprocessing/quantize/pq.h:24`_ + ### cuvsProductQuantizerParamsCreate Allocate Product Quantizer params, and populate with default values @@ -46,16 +48,17 @@ cuvsError_t cuvsProductQuantizerParamsCreate(cuvsProductQuantizerParams_t* param | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `params` | in | `cuvsProductQuantizerParams_t*` | cuvsProductQuantizerParams_t to allocate | +| `params` | in | [`cuvsProductQuantizerParams_t*`](/api-reference/c-api-preprocessing-quantize-pq#cuvsproductquantizerparams) | cuvsProductQuantizerParams_t to allocate | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/preprocessing/quantize/pq.h:85`_ + ### cuvsProductQuantizerParamsDestroy De-allocate Product Quantizer params @@ -68,16 +71,37 @@ cuvsError_t cuvsProductQuantizerParamsDestroy(cuvsProductQuantizerParams_t param | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `params` | in | `cuvsProductQuantizerParams_t` | | +| `params` | in | [`cuvsProductQuantizerParams_t`](/api-reference/c-api-preprocessing-quantize-pq#cuvsproductquantizerparams) | | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/preprocessing/quantize/pq.h:93`_ + +### cuvsProductQuantizer + +Defines and stores product quantizer upon training + +The quantization is performed by a linear mapping of an interval in the float data type to the full range of the quantized int type. + +```c +typedef struct { ... } cuvsProductQuantizer; +``` + +**Fields** + +| Name | Type | Description | +| --- | --- | --- | +| `addr` | `uintptr_t` | | +| `dtype` | `DLDataType` | | + +_Source: `c/include/cuvs/preprocessing/quantize/pq.h:101`_ + + ### cuvsProductQuantizerCreate Allocate Product Quantizer @@ -90,16 +114,17 @@ cuvsError_t cuvsProductQuantizerCreate(cuvsProductQuantizer_t* quantizer); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `quantizer` | in | `cuvsProductQuantizer_t*` | cuvsProductQuantizer_t to allocate | +| `quantizer` | in | [`cuvsProductQuantizer_t*`](/api-reference/c-api-preprocessing-quantize-pq#cuvsproductquantizer) | cuvsProductQuantizer_t to allocate | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/preprocessing/quantize/pq.h:114`_ + ### cuvsProductQuantizerDestroy De-allocate Product Quantizer @@ -112,16 +137,17 @@ cuvsError_t cuvsProductQuantizerDestroy(cuvsProductQuantizer_t quantizer); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `quantizer` | in | `cuvsProductQuantizer_t` | | +| `quantizer` | in | [`cuvsProductQuantizer_t`](/api-reference/c-api-preprocessing-quantize-pq#cuvsproductquantizer) | | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/preprocessing/quantize/pq.h:122`_ + ### cuvsProductQuantizerBuild Builds a product quantizer to be used later for quantizing the dataset. @@ -137,17 +163,18 @@ cuvsProductQuantizer_t quantizer); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | raft resource | -| `params` | in | `cuvsProductQuantizerParams_t` | Parameters for product quantizer training | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | raft resource | +| `params` | in | [`cuvsProductQuantizerParams_t`](/api-reference/c-api-preprocessing-quantize-pq#cuvsproductquantizerparams) | Parameters for product quantizer training | | `dataset` | in | `DLManagedTensor*` | a row-major host or device matrix | -| `quantizer` | out | `cuvsProductQuantizer_t` | trained product quantizer | +| `quantizer` | out | [`cuvsProductQuantizer_t`](/api-reference/c-api-preprocessing-quantize-pq#cuvsproductquantizer) | trained product quantizer | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) _Source: `c/include/cuvs/preprocessing/quantize/pq.h:132`_ + ### cuvsProductQuantizerTransform Applies product quantization transform to the given dataset @@ -166,18 +193,19 @@ This applies product quantization to a dataset. | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | raft resource | -| `quantizer` | in | `cuvsProductQuantizer_t` | product quantizer | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | raft resource | +| `quantizer` | in | [`cuvsProductQuantizer_t`](/api-reference/c-api-preprocessing-quantize-pq#cuvsproductquantizer) | product quantizer | | `dataset` | in | `DLManagedTensor*` | a row-major host or device matrix to transform | | `codes_out` | out | `DLManagedTensor*` | a row-major device matrix to store transformed data | | `vq_labels` | out | `DLManagedTensor*` | a device vector to store VQ labels. Optional, can be NULL. | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) _Source: `c/include/cuvs/preprocessing/quantize/pq.h:149`_ + ### cuvsProductQuantizerInverseTransform Applies product quantization inverse transform to the given quantized codes @@ -196,18 +224,19 @@ This applies product quantization inverse transform to the given quantized codes | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | raft resource | -| `quantizer` | in | `cuvsProductQuantizer_t` | product quantizer | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | raft resource | +| `quantizer` | in | [`cuvsProductQuantizer_t`](/api-reference/c-api-preprocessing-quantize-pq#cuvsproductquantizer) | product quantizer | | `pq_codes` | in | `DLManagedTensor*` | a row-major device matrix of quantized codes | | `out` | out | `DLManagedTensor*` | a row-major device matrix to store the original data | | `vq_labels` | out | `DLManagedTensor*` | a device vector containing the VQ labels when VQ is used. Optional, can be NULL. | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) _Source: `c/include/cuvs/preprocessing/quantize/pq.h:167`_ + ### cuvsProductQuantizerGetPqBits Get the bit length of the vector element after compression by PQ. @@ -220,15 +249,16 @@ cuvsError_t cuvsProductQuantizerGetPqBits(cuvsProductQuantizer_t quantizer, uint | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `quantizer` | in | `cuvsProductQuantizer_t` | product quantizer | +| `quantizer` | in | [`cuvsProductQuantizer_t`](/api-reference/c-api-preprocessing-quantize-pq#cuvsproductquantizer) | product quantizer | | `pq_bits` | out | `uint32_t*` | bit length of the vector element after compression by PQ | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) _Source: `c/include/cuvs/preprocessing/quantize/pq.h:179`_ + ### cuvsProductQuantizerGetPqDim Get the dimensionality of the vector after compression by PQ. @@ -241,15 +271,16 @@ cuvsError_t cuvsProductQuantizerGetPqDim(cuvsProductQuantizer_t quantizer, uint3 | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `quantizer` | in | `cuvsProductQuantizer_t` | product quantizer | +| `quantizer` | in | [`cuvsProductQuantizer_t`](/api-reference/c-api-preprocessing-quantize-pq#cuvsproductquantizer) | product quantizer | | `pq_dim` | out | `uint32_t*` | dimensionality of the vector after compression by PQ | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) _Source: `c/include/cuvs/preprocessing/quantize/pq.h:187`_ + ### cuvsProductQuantizerGetPqCodebook Get the PQ codebook. @@ -263,15 +294,16 @@ DLManagedTensor* pq_codebook); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `quantizer` | in | `cuvsProductQuantizer_t` | product quantizer | +| `quantizer` | in | [`cuvsProductQuantizer_t`](/api-reference/c-api-preprocessing-quantize-pq#cuvsproductquantizer) | product quantizer | | `pq_codebook` | out | `DLManagedTensor*` | PQ codebook | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) _Source: `c/include/cuvs/preprocessing/quantize/pq.h:195`_ + ### cuvsProductQuantizerGetVqCodebook Get the VQ codebook. @@ -285,15 +317,16 @@ DLManagedTensor* vq_codebook); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `quantizer` | in | `cuvsProductQuantizer_t` | product quantizer | +| `quantizer` | in | [`cuvsProductQuantizer_t`](/api-reference/c-api-preprocessing-quantize-pq#cuvsproductquantizer) | product quantizer | | `vq_codebook` | out | `DLManagedTensor*` | VQ codebook | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) _Source: `c/include/cuvs/preprocessing/quantize/pq.h:204`_ + ### cuvsProductQuantizerGetEncodedDim Get the encoded dimension of the quantized dataset. @@ -307,15 +340,16 @@ uint32_t* encoded_dim); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `quantizer` | in | `cuvsProductQuantizer_t` | product quantizer | +| `quantizer` | in | [`cuvsProductQuantizer_t`](/api-reference/c-api-preprocessing-quantize-pq#cuvsproductquantizer) | product quantizer | | `encoded_dim` | out | `uint32_t*` | encoded dimension of the quantized dataset | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) _Source: `c/include/cuvs/preprocessing/quantize/pq.h:212`_ + ### cuvsProductQuantizerGetUseVq Get whether VQ is used. @@ -328,11 +362,11 @@ cuvsError_t cuvsProductQuantizerGetUseVq(cuvsProductQuantizer_t quantizer, bool* | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `quantizer` | in | `cuvsProductQuantizer_t` | product quantizer | +| `quantizer` | in | [`cuvsProductQuantizer_t`](/api-reference/c-api-preprocessing-quantize-pq#cuvsproductquantizer) | product quantizer | | `use_vq` | out | `bool*` | whether VQ is used | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) _Source: `c/include/cuvs/preprocessing/quantize/pq.h:221`_ diff --git a/fern/pages/c_api/c-api-preprocessing-quantize-scalar.md b/fern/pages/c_api/c-api-preprocessing-quantize-scalar.md index 3bee4df133..4f7fdb4c98 100644 --- a/fern/pages/c_api/c-api-preprocessing-quantize-scalar.md +++ b/fern/pages/c_api/c-api-preprocessing-quantize-scalar.md @@ -10,6 +10,7 @@ _Source header: `c/include/cuvs/preprocessing/quantize/scalar.h`_ _Doxygen group: `preprocessing_c_scalar`_ + ### cuvsScalarQuantizerParams Scalar quantizer parameters. @@ -20,6 +21,7 @@ struct cuvsScalarQuantizerParams { ... } ; _Source: `c/include/cuvs/preprocessing/quantize/scalar.h:23`_ + ### cuvsScalarQuantizerParamsCreate Allocate Scalar Quantizer params, and populate with default values @@ -32,16 +34,17 @@ cuvsError_t cuvsScalarQuantizerParamsCreate(cuvsScalarQuantizerParams_t* params) | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `params` | in | `cuvsScalarQuantizerParams_t*` | cuvsScalarQuantizerParams_t to allocate | +| `params` | in | [`cuvsScalarQuantizerParams_t*`](/api-reference/c-api-preprocessing-quantize-scalar#cuvsscalarquantizerparams) | cuvsScalarQuantizerParams_t to allocate | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/preprocessing/quantize/scalar.h:39`_ + ### cuvsScalarQuantizerParamsDestroy De-allocate Scalar Quantizer params @@ -54,16 +57,37 @@ cuvsError_t cuvsScalarQuantizerParamsDestroy(cuvsScalarQuantizerParams_t params) | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `params` | in | `cuvsScalarQuantizerParams_t` | | +| `params` | in | [`cuvsScalarQuantizerParams_t`](/api-reference/c-api-preprocessing-quantize-scalar#cuvsscalarquantizerparams) | | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/preprocessing/quantize/scalar.h:47`_ + +### cuvsScalarQuantizer + +Defines and stores scalar for quantisation upon training + +The quantization is performed by a linear mapping of an interval in the float data type to the full range of the quantized int type. + +```c +typedef struct { ... } cuvsScalarQuantizer; +``` + +**Fields** + +| Name | Type | Description | +| --- | --- | --- | +| `min_` | `double` | | +| `max_` | `double` | | + +_Source: `c/include/cuvs/preprocessing/quantize/scalar.h:55`_ + + ### cuvsScalarQuantizerCreate Allocate Scalar Quantizer and populate with default values @@ -76,16 +100,17 @@ cuvsError_t cuvsScalarQuantizerCreate(cuvsScalarQuantizer_t* quantizer); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `quantizer` | in | `cuvsScalarQuantizer_t*` | cuvsScalarQuantizer_t to allocate | +| `quantizer` | in | [`cuvsScalarQuantizer_t*`](/api-reference/c-api-preprocessing-quantize-scalar#cuvsscalarquantizer) | cuvsScalarQuantizer_t to allocate | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/preprocessing/quantize/scalar.h:68`_ + ### cuvsScalarQuantizerDestroy De-allocate Scalar Quantizer @@ -98,16 +123,17 @@ cuvsError_t cuvsScalarQuantizerDestroy(cuvsScalarQuantizer_t quantizer); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `quantizer` | in | `cuvsScalarQuantizer_t` | | +| `quantizer` | in | [`cuvsScalarQuantizer_t`](/api-reference/c-api-preprocessing-quantize-scalar#cuvsscalarquantizer) | | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) cuvsError_t _Source: `c/include/cuvs/preprocessing/quantize/scalar.h:76`_ + ### cuvsScalarQuantizerTrain Trains a scalar quantizer to be used later for quantizing the dataset. @@ -123,17 +149,18 @@ cuvsScalarQuantizer_t quantizer); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | raft resource | -| `params` | in | `cuvsScalarQuantizerParams_t` | configure scalar quantizer, e.g. quantile | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | raft resource | +| `params` | in | [`cuvsScalarQuantizerParams_t`](/api-reference/c-api-preprocessing-quantize-scalar#cuvsscalarquantizerparams) | configure scalar quantizer, e.g. quantile | | `dataset` | in | `DLManagedTensor*` | a row-major host or device matrix | -| `quantizer` | out | `cuvsScalarQuantizer_t` | trained scalar quantizer | +| `quantizer` | out | [`cuvsScalarQuantizer_t`](/api-reference/c-api-preprocessing-quantize-scalar#cuvsscalarquantizer) | trained scalar quantizer | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) _Source: `c/include/cuvs/preprocessing/quantize/scalar.h:86`_ + ### cuvsScalarQuantizerTransform Applies quantization transform to given dataset @@ -149,17 +176,18 @@ DLManagedTensor* out); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | raft resource | -| `quantizer` | in | `cuvsScalarQuantizer_t` | a scalar quantizer | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | raft resource | +| `quantizer` | in | [`cuvsScalarQuantizer_t`](/api-reference/c-api-preprocessing-quantize-scalar#cuvsscalarquantizer) | a scalar quantizer | | `dataset` | in | `DLManagedTensor*` | a row-major host or device matrix to transform | | `out` | out | `DLManagedTensor*` | a row-major host or device matrix to store transformed data | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) _Source: `c/include/cuvs/preprocessing/quantize/scalar.h:99`_ + ### cuvsScalarQuantizerInverseTransform Perform inverse quantization step on previously quantized dataset @@ -177,13 +205,13 @@ Note that depending on the chosen data types train dataset the conversion is not | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `res` | in | `cuvsResources_t` | raft resource | -| `quantizer` | in | `cuvsScalarQuantizer_t` | a scalar quantizer | +| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | raft resource | +| `quantizer` | in | [`cuvsScalarQuantizer_t`](/api-reference/c-api-preprocessing-quantize-scalar#cuvsscalarquantizer) | a scalar quantizer | | `dataset` | in | `DLManagedTensor*` | a row-major host or device matrix | | `out` | out | `DLManagedTensor*` | a row-major host or device matrix | **Returns** -`cuvsError_t` +[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t) _Source: `c/include/cuvs/preprocessing/quantize/scalar.h:116`_ diff --git a/fern/pages/c_api/index.md b/fern/pages/c_api/index.md index 047b165ebb..61d672ba91 100644 --- a/fern/pages/c_api/index.md +++ b/fern/pages/c_api/index.md @@ -4,6 +4,7 @@ These pages are generated from the documented public headers in the cuVS source - [K-Means](/api-reference/c-api-cluster-kmeans) - [C API](/api-reference/c-api-core-c-api) +- [Distance](/api-reference/c-api-distance-distance) - [Pairwise Distance](/api-reference/c-api-distance-pairwise-distance) - [All Neighbors](/api-reference/c-api-neighbors-all-neighbors) - [Brute Force](/api-reference/c-api-neighbors-brute-force) diff --git a/fern/pages/cpp_api/cpp-api-cluster-agglomerative.md b/fern/pages/cpp_api/cpp-api-cluster-agglomerative.md index 827cb7809f..1c4271d63b 100644 --- a/fern/pages/cpp_api/cpp-api-cluster-agglomerative.md +++ b/fern/pages/cpp_api/cpp-api-cluster-agglomerative.md @@ -10,6 +10,7 @@ _Source header: `cpp/include/cuvs/cluster/agglomerative.hpp`_ _Doxygen group: `agglomerative_params`_ + ### cuvs::cluster::agglomerative::Linkage Determines the method for computing the minimum spanning tree (MST) @@ -31,6 +32,7 @@ _Source: `cpp/include/cuvs/cluster/agglomerative.hpp:30`_ _Doxygen group: `single_linkage`_ + ### cuvs::cluster::agglomerative::single_linkage Single-linkage clustering, capable of constructing a KNN graph to @@ -57,9 +59,9 @@ scale the algorithm beyond the n^2 memory consumption of implementations that us | `X` | in | `raft::device_matrix_view` | dense input matrix in row-major layout | | `dendrogram` | out | `raft::device_matrix_view` | output dendrogram (size [n_rows - 1] * 2) | | `labels` | out | `raft::device_vector_view` | output labels vector (size n_rows) | -| `metric` | in | `cuvs::distance::DistanceType` | distance metric to use when constructing connectivities graph | +| `metric` | in | [`cuvs::distance::DistanceType`](/api-reference/cpp-api-distance-distance#cuvs-distance-distancetype) | distance metric to use when constructing connectivities graph | | `n_clusters` | in | `size_t` | number of clusters to assign data samples | -| `linkage` | in | `cuvs::cluster::agglomerative::Linkage` | strategy for constructing the linkage. PAIRWISE uses more memory but can be faster for smaller datasets. KNN_GRAPH allows the memory usage to be controlled (using parameter c) at the expense of potentially additional minimum spanning tree iterations. Default: `cuvs::cluster::agglomerative::Linkage::KNN_GRAPH`. | +| `linkage` | in | [`cuvs::cluster::agglomerative::Linkage`](/api-reference/cpp-api-cluster-agglomerative#cuvs-cluster-agglomerative-linkage) | strategy for constructing the linkage. PAIRWISE uses more memory but can be faster for smaller datasets. KNN_GRAPH allows the memory usage to be controlled (using parameter c) at the expense of potentially additional minimum spanning tree iterations. Default: `cuvs::cluster::agglomerative::Linkage::KNN_GRAPH`. | | `c` | in | `std::optional` | a constant used when constructing linkage from knn graph. Allows the indirect control of k. The algorithm will set `k = log(n) + c` Default: `std::make_optional<int>(DEFAULT_CONST_C)`. | **Returns** @@ -68,6 +70,7 @@ scale the algorithm beyond the n^2 memory consumption of implementations that us _Source: `cpp/include/cuvs/cluster/agglomerative.hpp:104`_ + ### linkage_graph_params::distance_params Specialized parameters to build the KNN graph with regular distances @@ -81,10 +84,11 @@ struct distance_params { ... } ; | Name | Type | Description | | --- | --- | --- | | `c` | `int` | a constant used when constructing linkage from knn graph. Allows the indirect control of k. The algorithm will set `k = log(n) + c` | -| `dist_type` | `cuvs::cluster::agglomerative::Linkage` | strategy for constructing the linkage. PAIRWISE uses more memory but can be faster for smaller datasets. KNN_GRAPH allows the memory usage to be controlled (using parameter c) | +| `dist_type` | [`cuvs::cluster::agglomerative::Linkage`](/api-reference/cpp-api-cluster-agglomerative#cuvs-cluster-agglomerative-linkage) | strategy for constructing the linkage. PAIRWISE uses more memory but can be faster for smaller datasets. KNN_GRAPH allows the memory usage to be controlled (using parameter c) | _Source: `cpp/include/cuvs/cluster/agglomerative.hpp:118`_ + ### linkage_graph_params::mutual_reachability_params Specialized parameters to build the Mutual Reachability graph @@ -99,10 +103,11 @@ struct mutual_reachability_params { ... } ; | --- | --- | --- | | `min_samples` | `int` | this neighborhood will be selected for core distances. | | `alpha` | `float` | weight applied when internal distance is chosen for mutual reachability (value of 1.0 disables the weighting) | -| `brute_force_params` | `cuvs::neighbors::all_neighbors::all_neighbors_params all_neighbors_params{ cuvs::neighbors::graph_build_params::` | Parameters for building the mutual reachability graph using an underlying KNN algorithm. The all-neighbors graph construction algorithm enables building the mutual reachability graph on datasets larger than device memory by:
1. Partitioning the dataset into overlapping clusters,
2. Computing local KNN graphs within each cluster, and
3. Merging the local graphs into a single global graph. Key fields:
- graph_build_params: Selects the KNN construction method (Brute Force or NN Descent) and controls algorithm-specific parameters.
- n_clusters: Number of partitions (batches) to split the data into. Larger `n_clusters` reduces memory usage but may reduce accuracy if `overlap_factor` is too low. Recommended starting value: `n_clusters = 4`. Increase progressively (4 → 8 → 16 ...) to reduce memory usage at the cost of some accuracy. This is independent of `overlap_factor` as long as `overlap_factor < n_clusters`.
- overlap_factor: Number of nearest clusters each data point is assigned to. Higher `overlap_factor` improves accuracy at the cost of memory and performance. Recommended starting value: `overlap_factor = 2`. Increase gradually (2 → 3 → 4 ...) for better accuracy with higher device memory usage.
- metric: Distance metric to use when computing nearest neighbors. | +| `brute_force_params` | [`cuvs::neighbors::all_neighbors::all_neighbors_params all_neighbors_params{ cuvs::neighbors::graph_build_params::`](/api-reference/cpp-api-neighbors-all-neighbors#cuvs-neighbors-all-neighbors-all-neighbors-params) | Parameters for building the mutual reachability graph using an underlying KNN algorithm. The all-neighbors graph construction algorithm enables building the mutual reachability graph on datasets larger than device memory by:
1. Partitioning the dataset into overlapping clusters,
2. Computing local KNN graphs within each cluster, and
3. Merging the local graphs into a single global graph. Key fields:
- graph_build_params: Selects the KNN construction method (Brute Force or NN Descent) and controls algorithm-specific parameters.
- n_clusters: Number of partitions (batches) to split the data into. Larger `n_clusters` reduces memory usage but may reduce accuracy if `overlap_factor` is too low. Recommended starting value: `n_clusters = 4`. Increase progressively (4 → 8 → 16 ...) to reduce memory usage at the cost of some accuracy. This is independent of `overlap_factor` as long as `overlap_factor < n_clusters`.
- overlap_factor: Number of nearest clusters each data point is assigned to. Higher `overlap_factor` improves accuracy at the cost of memory and performance. Recommended starting value: `overlap_factor = 2`. Increase gradually (2 → 3 → 4 ...) for better accuracy with higher device memory usage.
- metric: Distance metric to use when computing nearest neighbors. | _Source: `cpp/include/cuvs/cluster/agglomerative.hpp:130`_ + ### linkage_graph_params::build_linkage Given a dataset, builds the KNN graph, connects graph components and builds a linkage @@ -129,8 +134,8 @@ std::optional> core_dists); | --- | --- | --- | --- | | `handle` | in | `raft::resources const&` | raft handle for resource reuse | | `X` | in | `raft::device_matrix_view` | data points on device memory (size n_rows * d) | -| `linkage_graph_params` | in | `std::variant` | Parameters controlling how the KNN graph is built. This can be either:
- distance_params: standard distance-based KNN graph construction for traditional agglomerative clustering.
- mutual_reachability_params: parameters to compute a mutual reachability graph for density-aware hierarchical clustering (e.g. HDBSCAN). | -| `metric` | in | `cuvs::distance::DistanceType` | distance metric to use | +| `linkage_graph_params` | in | [`std::variant`](/api-reference/cpp-api-cluster-agglomerative#linkage-graph-params-mutual-reachability-params) | Parameters controlling how the KNN graph is built. This can be either:
- distance_params: standard distance-based KNN graph construction for traditional agglomerative clustering.
- mutual_reachability_params: parameters to compute a mutual reachability graph for density-aware hierarchical clustering (e.g. HDBSCAN). | +| `metric` | in | [`cuvs::distance::DistanceType`](/api-reference/cpp-api-distance-distance#cuvs-distance-distancetype) | distance metric to use | | `out_mst` | out | `raft::device_coo_matrix_view` | output MST sorted by edge weights (size n_rows - 1) | | `dendrogram` | out | `raft::device_matrix_view` | output dendrogram (size [n_rows - 1] * 2) | | `out_distances` | out | `raft::device_vector_view` | distances for output | @@ -169,8 +174,8 @@ std::optional> core_dists); | --- | --- | --- | --- | | `handle` | in | `raft::resources const&` | raft handle for resource reuse | | `X` | in | `raft::host_matrix_view` | data points on host memory (size n_rows * d) | -| `linkage_graph_params` | in | `std::variant` | Parameters controlling how the KNN graph is built. This can be either:
- distance_params: standard distance-based KNN graph construction for traditional agglomerative clustering.
- mutual_reachability_params: parameters to compute a mutual reachability graph for density-aware hierarchical clustering (e.g. HDBSCAN). | -| `metric` | in | `cuvs::distance::DistanceType` | distance metric to use | +| `linkage_graph_params` | in | [`std::variant`](/api-reference/cpp-api-cluster-agglomerative#linkage-graph-params-mutual-reachability-params) | Parameters controlling how the KNN graph is built. This can be either:
- distance_params: standard distance-based KNN graph construction for traditional agglomerative clustering.
- mutual_reachability_params: parameters to compute a mutual reachability graph for density-aware hierarchical clustering (e.g. HDBSCAN). | +| `metric` | in | [`cuvs::distance::DistanceType`](/api-reference/cpp-api-distance-distance#cuvs-distance-distancetype) | distance metric to use | | `out_mst` | out | `raft::device_coo_matrix_view` | output MST sorted by edge weights (size n_rows - 1) | | `dendrogram` | out | `raft::device_matrix_view` | output dendrogram (size [n_rows - 1] * 2) | | `out_distances` | out | `raft::device_vector_view` | distances for output | @@ -183,6 +188,7 @@ std::optional> core_dists); _Source: `cpp/include/cuvs/cluster/agglomerative.hpp:219`_ + ### linkage_graph_params::build_dendrogram Build dendrogram from a Minimum Spanning Tree (MST). diff --git a/fern/pages/cpp_api/cpp-api-cluster-kmeans.md b/fern/pages/cpp_api/cpp-api-cluster-kmeans.md index 618f5a4721..89ca3f4508 100644 --- a/fern/pages/cpp_api/cpp-api-cluster-kmeans.md +++ b/fern/pages/cpp_api/cpp-api-cluster-kmeans.md @@ -6,10 +6,30 @@ slug: api-reference/cpp-api-cluster-kmeans _Source header: `cpp/include/cuvs/cluster/kmeans.hpp`_ +## Types + + +### cuvs::cluster::kmeans::base_params + +Base structure for parameters that are common to all k-means algorithms + +```cpp +struct base_params { ... } ; +``` + +**Fields** + +| Name | Type | Description | +| --- | --- | --- | +| `metric` | [`cuvs::distance::DistanceType`](/api-reference/cpp-api-distance-distance#cuvs-distance-distancetype) | Metric to use for distance computation. The supported metrics can vary per algorithm. | + +_Source: `cpp/include/cuvs/cluster/kmeans.hpp:19`_ + ## k-means hyperparameters _Doxygen group: `kmeans_params`_ + ### cuvs::cluster::kmeans::params Simple object to specify hyper-parameters to the kmeans algorithm. @@ -37,6 +57,7 @@ struct params : base_params { ... } ; _Source: `cpp/include/cuvs/cluster/kmeans.hpp:34`_ + ### cuvs::cluster::kmeans::balanced_params Simple object to specify hyper-parameters to the balanced k-means algorithm. @@ -60,6 +81,7 @@ struct balanced_params : base_params { ... } ; _Source: `cpp/include/cuvs/cluster/kmeans.hpp:139`_ + ### cuvs::cluster::kmeans::kmeans_type Type of k-means algorithm. @@ -81,6 +103,7 @@ _Source: `cpp/include/cuvs/cluster/kmeans.hpp:149`_ _Doxygen group: `kmeans`_ + ### cuvs::cluster::kmeans::fit Find clusters with k-means algorithm using batched processing of host data. @@ -104,7 +127,7 @@ This overload supports out-of-core computation where the dataset resides on the | Name | Direction | Type | Description | | --- | --- | --- | --- | | `handle` | in | `raft::resources const&` | The raft handle. | -| `params` | in | `const cuvs::cluster::kmeans::params&` | Parameters for KMeans model. Batch size is read from params.streaming_batch_size. | +| `params` | in | [`const cuvs::cluster::kmeans::params&`](/api-reference/cpp-api-cluster-kmeans#cuvs-cluster-kmeans-params) | Parameters for KMeans model. Batch size is read from params.streaming_batch_size. | | `X` | in | `raft::host_matrix_view` | Training instances on HOST memory. The data must be in row-major format. [dim = n_samples x n_features] | | `sample_weight` | in | `std::optional>` | Optional weights for each observation in X (on host). [len = n_samples] | | `centroids` | inout | `raft::device_matrix_view` | [in] When init is InitMethod::Array, use centroids as the initial cluster centers. [out] The generated centroids from the kmeans algorithm are stored at the address pointed by 'centroids'. [dim = n_clusters x n_features] | @@ -136,7 +159,7 @@ raft::host_scalar_view n_iter); | Name | Direction | Type | Description | | --- | --- | --- | --- | | `handle` | | `raft::resources const&` | | -| `params` | | `const cuvs::cluster::kmeans::params&` | | +| `params` | | [`const cuvs::cluster::kmeans::params&`](/api-reference/cpp-api-cluster-kmeans#cuvs-cluster-kmeans-params) | | | `X` | | `raft::host_matrix_view` | | | `sample_weight` | | `std::optional>` | | | `centroids` | | `raft::device_matrix_view` | | @@ -170,7 +193,7 @@ Initial centroids are chosen with k-means++ algorithm. Empty clusters are reinit | Name | Direction | Type | Description | | --- | --- | --- | --- | | `handle` | in | `raft::resources const&` | The raft handle. | -| `params` | in | `const cuvs::cluster::kmeans::params&` | Parameters for KMeans model. | +| `params` | in | [`const cuvs::cluster::kmeans::params&`](/api-reference/cpp-api-cluster-kmeans#cuvs-cluster-kmeans-params) | Parameters for KMeans model. | | `X` | in | `raft::device_matrix_view` | Training instances to cluster. The data must be in row-major format. [dim = n_samples x n_features] | | `sample_weight` | in | `std::optional>` | Optional weights for each observation in X. [len = n_samples] | | `centroids` | inout | `raft::device_matrix_view` | [in] When init is InitMethod::Array, use centroids as the initial cluster centers. [out] The generated centroids from the kmeans algorithm are stored at the address pointed by 'centroids'. [dim = n_clusters x n_features] | @@ -204,7 +227,7 @@ Initial centroids are chosen with k-means++ algorithm. Empty clusters are reinit | Name | Direction | Type | Description | | --- | --- | --- | --- | | `handle` | in | `raft::resources const&` | The raft handle. | -| `params` | in | `const cuvs::cluster::kmeans::params&` | Parameters for KMeans model. | +| `params` | in | [`const cuvs::cluster::kmeans::params&`](/api-reference/cpp-api-cluster-kmeans#cuvs-cluster-kmeans-params) | Parameters for KMeans model. | | `X` | in | `raft::device_matrix_view` | Training instances to cluster. The data must be in row-major format. [dim = n_samples x n_features] | | `sample_weight` | in | `std::optional>` | Optional weights for each observation in X. [len = n_samples] | | `centroids` | inout | `raft::device_matrix_view` | [in] When init is InitMethod::Array, use centroids as the initial cluster centers. [out] The generated centroids from the kmeans algorithm are stored at the address pointed by 'centroids'. [dim = n_clusters x n_features] | @@ -238,7 +261,7 @@ Initial centroids are chosen with k-means++ algorithm. Empty clusters are reinit | Name | Direction | Type | Description | | --- | --- | --- | --- | | `handle` | in | `raft::resources const&` | The raft handle. | -| `params` | in | `const cuvs::cluster::kmeans::params&` | Parameters for KMeans model. | +| `params` | in | [`const cuvs::cluster::kmeans::params&`](/api-reference/cpp-api-cluster-kmeans#cuvs-cluster-kmeans-params) | Parameters for KMeans model. | | `X` | in | `raft::device_matrix_view` | Training instances to cluster. The data must be in row-major format. [dim = n_samples x n_features] | | `sample_weight` | in | `std::optional>` | Optional weights for each observation in X. [len = n_samples] | | `centroids` | inout | `raft::device_matrix_view` | [in] When init is InitMethod::Array, use centroids as the initial cluster centers. [out] The generated centroids from the kmeans algorithm are stored at the address pointed by 'centroids'. [dim = n_clusters x n_features] | @@ -272,7 +295,7 @@ Initial centroids are chosen with k-means++ algorithm. Empty clusters are reinit | Name | Direction | Type | Description | | --- | --- | --- | --- | | `handle` | in | `raft::resources const&` | The raft handle. | -| `params` | in | `const cuvs::cluster::kmeans::params&` | Parameters for KMeans model. | +| `params` | in | [`const cuvs::cluster::kmeans::params&`](/api-reference/cpp-api-cluster-kmeans#cuvs-cluster-kmeans-params) | Parameters for KMeans model. | | `X` | in | `raft::device_matrix_view` | Training instances to cluster. The data must be in row-major format. [dim = n_samples x n_features] | | `sample_weight` | in | `std::optional>` | Optional weights for each observation in X. [len = n_samples] | | `centroids` | inout | `raft::device_matrix_view` | [in] When init is InitMethod::Array, use centroids as the initial cluster centers. [out] The generated centroids from the kmeans algorithm are stored at the address pointed by 'centroids'. [dim = n_clusters x n_features] | @@ -306,7 +329,7 @@ Initial centroids are chosen with k-means++ algorithm. Empty clusters are reinit | Name | Direction | Type | Description | | --- | --- | --- | --- | | `handle` | in | `raft::resources const&` | The raft handle. | -| `params` | in | `const cuvs::cluster::kmeans::params&` | Parameters for KMeans model. | +| `params` | in | [`const cuvs::cluster::kmeans::params&`](/api-reference/cpp-api-cluster-kmeans#cuvs-cluster-kmeans-params) | Parameters for KMeans model. | | `X` | in | `raft::device_matrix_view` | Training instances to cluster. The data must be in row-major format. [dim = n_samples x n_features] | | `sample_weight` | in | `std::optional>` | Optional weights for each observation in X. [len = n_samples] | | `centroids` | inout | `raft::device_matrix_view` | [in] When init is InitMethod::Array, use centroids as the initial cluster centers. [out] The generated centroids from the kmeans algorithm are stored at the address pointed by 'centroids'. [dim = n_clusters x n_features] | @@ -336,7 +359,7 @@ std::optional> inertia = std::nullopt); | Name | Direction | Type | Description | | --- | --- | --- | --- | | `handle` | in | `const raft::resources&` | The raft handle. | -| `params` | in | `cuvs::cluster::kmeans::balanced_params const&` | Parameters for KMeans model. | +| `params` | in | [`cuvs::cluster::kmeans::balanced_params const&`](/api-reference/cpp-api-cluster-kmeans#cuvs-cluster-kmeans-balanced-params) | Parameters for KMeans model. | | `X` | in | `raft::device_matrix_view` | Training instances to cluster. The data must be in row-major format. [dim = n_samples x n_features] | | `centroids` | out | `raft::device_matrix_view` | [out] The generated centroids from the kmeans algorithm are stored at the address pointed by 'centroids'. [dim = n_clusters x n_features] | | `inertia` | out | `std::optional>` | Sum of squared distances of samples to their closest cluster center. Default: `std::nullopt`. | @@ -364,7 +387,7 @@ std::optional> inertia = std::nullopt); | Name | Direction | Type | Description | | --- | --- | --- | --- | | `handle` | in | `const raft::resources&` | The raft handle. | -| `params` | in | `cuvs::cluster::kmeans::balanced_params const&` | Parameters for KMeans model. | +| `params` | in | [`cuvs::cluster::kmeans::balanced_params const&`](/api-reference/cpp-api-cluster-kmeans#cuvs-cluster-kmeans-balanced-params) | Parameters for KMeans model. | | `X` | in | `raft::device_matrix_view` | Training instances to cluster. The data must be in row-major format. [dim = n_samples x n_features] | | `centroids` | inout | `raft::device_matrix_view` | [out] The generated centroids from the kmeans algorithm are stored at the address pointed by 'centroids'. [dim = n_clusters x n_features] | | `inertia` | out | `std::optional>` | Sum of squared distances of samples to their closest cluster center. Default: `std::nullopt`. | @@ -392,7 +415,7 @@ std::optional> inertia = std::nullopt); | Name | Direction | Type | Description | | --- | --- | --- | --- | | `handle` | in | `const raft::resources&` | The raft handle. | -| `params` | in | `cuvs::cluster::kmeans::balanced_params const&` | Parameters for KMeans model. | +| `params` | in | [`cuvs::cluster::kmeans::balanced_params const&`](/api-reference/cpp-api-cluster-kmeans#cuvs-cluster-kmeans-balanced-params) | Parameters for KMeans model. | | `X` | in | `raft::device_matrix_view` | Training instances to cluster. The data must be in row-major format. [dim = n_samples x n_features] | | `centroids` | inout | `raft::device_matrix_view` | [out] The generated centroids from the kmeans algorithm are stored at the address pointed by 'centroids'. [dim = n_clusters x n_features] | | `inertia` | out | `std::optional>` | Sum of squared distances of samples to their closest cluster center. Default: `std::nullopt`. | @@ -420,7 +443,7 @@ std::optional> inertia = std::nullopt); | Name | Direction | Type | Description | | --- | --- | --- | --- | | `handle` | in | `const raft::resources&` | The raft handle. | -| `params` | in | `cuvs::cluster::kmeans::balanced_params const&` | Parameters for KMeans model. | +| `params` | in | [`cuvs::cluster::kmeans::balanced_params const&`](/api-reference/cpp-api-cluster-kmeans#cuvs-cluster-kmeans-balanced-params) | Parameters for KMeans model. | | `X` | in | `raft::device_matrix_view` | Training instances to cluster. The data must be in row-major format. [dim = n_samples x n_features] | | `centroids` | inout | `raft::device_matrix_view` | [out] The generated centroids from the kmeans algorithm are stored at the address pointed by 'centroids'. [dim = n_clusters x n_features] | | `inertia` | out | `std::optional>` | Sum of squared distances of samples to their closest cluster center. Default: `std::nullopt`. | @@ -431,6 +454,7 @@ std::optional> inertia = std::nullopt); _Source: `cpp/include/cuvs/cluster/kmeans.hpp:631`_ + ### cuvs::cluster::kmeans::predict Predict the closest cluster each sample in X belongs to. @@ -451,7 +475,7 @@ raft::host_scalar_view inertia); | Name | Direction | Type | Description | | --- | --- | --- | --- | | `handle` | in | `raft::resources const&` | The raft handle. | -| `params` | in | `const kmeans::params&` | Parameters for KMeans model. | +| `params` | in | [`const kmeans::params&`](/api-reference/cpp-api-cluster-kmeans#cuvs-cluster-kmeans-params) | Parameters for KMeans model. | | `X` | in | `raft::device_matrix_view` | New data to predict. [dim = n_samples x n_features] | | `sample_weight` | in | `std::optional>` | Optional weights for each observation in X. [len = n_samples] | | `centroids` | in | `raft::device_matrix_view` | Cluster centroids. The data must be in row-major format. [dim = n_clusters x n_features] | @@ -485,7 +509,7 @@ raft::host_scalar_view inertia); | Name | Direction | Type | Description | | --- | --- | --- | --- | | `handle` | in | `raft::resources const&` | The raft handle. | -| `params` | in | `const kmeans::params&` | Parameters for KMeans model. | +| `params` | in | [`const kmeans::params&`](/api-reference/cpp-api-cluster-kmeans#cuvs-cluster-kmeans-params) | Parameters for KMeans model. | | `X` | in | `raft::device_matrix_view` | New data to predict. [dim = n_samples x n_features] | | `sample_weight` | in | `std::optional>` | Optional weights for each observation in X. [len = n_samples] | | `centroids` | in | `raft::device_matrix_view` | Cluster centroids. The data must be in row-major format. [dim = n_clusters x n_features] | @@ -519,7 +543,7 @@ raft::host_scalar_view inertia); | Name | Direction | Type | Description | | --- | --- | --- | --- | | `handle` | in | `raft::resources const&` | The raft handle. | -| `params` | in | `const kmeans::params&` | Parameters for KMeans model. | +| `params` | in | [`const kmeans::params&`](/api-reference/cpp-api-cluster-kmeans#cuvs-cluster-kmeans-params) | Parameters for KMeans model. | | `X` | in | `raft::device_matrix_view` | New data to predict. [dim = n_samples x n_features] | | `sample_weight` | in | `std::optional>` | Optional weights for each observation in X. [len = n_samples] | | `centroids` | in | `raft::device_matrix_view` | Cluster centroids. The data must be in row-major format. [dim = n_clusters x n_features] | @@ -553,7 +577,7 @@ raft::host_scalar_view inertia); | Name | Direction | Type | Description | | --- | --- | --- | --- | | `handle` | in | `raft::resources const&` | The raft handle. | -| `params` | in | `const kmeans::params&` | Parameters for KMeans model. | +| `params` | in | [`const kmeans::params&`](/api-reference/cpp-api-cluster-kmeans#cuvs-cluster-kmeans-params) | Parameters for KMeans model. | | `X` | in | `raft::device_matrix_view` | New data to predict. [dim = n_samples x n_features] | | `sample_weight` | in | `std::optional>` | Optional weights for each observation in X. [len = n_samples] | | `centroids` | in | `raft::device_matrix_view` | Cluster centroids. The data must be in row-major format. [dim = n_clusters x n_features] | @@ -584,7 +608,7 @@ raft::device_vector_view labels); | Name | Direction | Type | Description | | --- | --- | --- | --- | | `handle` | in | `const raft::resources&` | The raft handle. | -| `params` | in | `cuvs::cluster::kmeans::balanced_params const&` | Parameters for KMeans model. | +| `params` | in | [`cuvs::cluster::kmeans::balanced_params const&`](/api-reference/cpp-api-cluster-kmeans#cuvs-cluster-kmeans-balanced-params) | Parameters for KMeans model. | | `X` | in | `raft::device_matrix_view` | New data to predict. [dim = n_samples x n_features] | | `centroids` | in | `raft::device_matrix_view` | Cluster centroids. The data must be in row-major format. [dim = n_clusters x n_features] | | `labels` | out | `raft::device_vector_view` | Index of the cluster each sample in X belongs to. [len = n_samples] | @@ -612,7 +636,7 @@ raft::device_vector_view labels); | Name | Direction | Type | Description | | --- | --- | --- | --- | | `handle` | in | `const raft::resources&` | The raft handle. | -| `params` | in | `cuvs::cluster::kmeans::balanced_params const&` | Parameters for KMeans model. | +| `params` | in | [`cuvs::cluster::kmeans::balanced_params const&`](/api-reference/cpp-api-cluster-kmeans#cuvs-cluster-kmeans-balanced-params) | Parameters for KMeans model. | | `X` | in | `raft::device_matrix_view` | New data to predict. [dim = n_samples x n_features] | | `centroids` | in | `raft::device_matrix_view` | Cluster centroids. The data must be in row-major format. [dim = n_clusters x n_features] | | `labels` | out | `raft::device_vector_view` | Index of the cluster each sample in X belongs to. [len = n_samples] | @@ -640,7 +664,7 @@ raft::device_vector_view labels); | Name | Direction | Type | Description | | --- | --- | --- | --- | | `handle` | in | `const raft::resources&` | The raft handle. | -| `params` | in | `cuvs::cluster::kmeans::balanced_params const&` | Parameters for KMeans model. | +| `params` | in | [`cuvs::cluster::kmeans::balanced_params const&`](/api-reference/cpp-api-cluster-kmeans#cuvs-cluster-kmeans-balanced-params) | Parameters for KMeans model. | | `X` | in | `raft::device_matrix_view` | New data to predict. [dim = n_samples x n_features] | | `centroids` | in | `raft::device_matrix_view` | Cluster centroids. The data must be in row-major format. [dim = n_clusters x n_features] | | `labels` | out | `raft::device_vector_view` | Index of the cluster each sample in X belongs to. [len = n_samples] | @@ -668,7 +692,7 @@ raft::device_vector_view labels); | Name | Direction | Type | Description | | --- | --- | --- | --- | | `handle` | in | `const raft::resources&` | The raft handle. | -| `params` | in | `cuvs::cluster::kmeans::balanced_params const&` | Parameters for KMeans model. | +| `params` | in | [`cuvs::cluster::kmeans::balanced_params const&`](/api-reference/cpp-api-cluster-kmeans#cuvs-cluster-kmeans-balanced-params) | Parameters for KMeans model. | | `X` | in | `raft::device_matrix_view` | New data to predict. [dim = n_samples x n_features] | | `centroids` | in | `raft::device_matrix_view` | Cluster centroids. The data must be in row-major format. [dim = n_clusters x n_features] | | `labels` | out | `raft::device_vector_view` | Index of the cluster each sample in X belongs to. [len = n_samples] | @@ -696,7 +720,7 @@ raft::device_vector_view labels); | Name | Direction | Type | Description | | --- | --- | --- | --- | | `handle` | in | `const raft::resources&` | The raft handle. | -| `params` | in | `cuvs::cluster::kmeans::balanced_params const&` | Parameters for KMeans model. | +| `params` | in | [`cuvs::cluster::kmeans::balanced_params const&`](/api-reference/cpp-api-cluster-kmeans#cuvs-cluster-kmeans-balanced-params) | Parameters for KMeans model. | | `X` | in | `raft::device_matrix_view` | New data to predict. [dim = n_samples x n_features] | | `centroids` | in | `raft::device_matrix_view` | Cluster centroids. The data must be in row-major format. [dim = n_clusters x n_features] | | `labels` | out | `raft::device_vector_view` | Index of the cluster each sample in X belongs to. [len = n_samples] | @@ -724,7 +748,7 @@ raft::device_vector_view labels); | Name | Direction | Type | Description | | --- | --- | --- | --- | | `handle` | in | `const raft::resources&` | The raft handle. | -| `params` | in | `cuvs::cluster::kmeans::balanced_params const&` | Parameters for KMeans model. | +| `params` | in | [`cuvs::cluster::kmeans::balanced_params const&`](/api-reference/cpp-api-cluster-kmeans#cuvs-cluster-kmeans-balanced-params) | Parameters for KMeans model. | | `X` | in | `raft::device_matrix_view` | New data to predict. [dim = n_samples x n_features] | | `centroids` | in | `raft::device_matrix_view` | Cluster centroids. The data must be in row-major format. [dim = n_clusters x n_features] | | `labels` | out | `raft::device_vector_view` | Index of the cluster each sample in X belongs to. [len = n_samples] | @@ -735,6 +759,7 @@ raft::device_vector_view labels); _Source: `cpp/include/cuvs/cluster/kmeans.hpp:1136`_ + ### cuvs::cluster::kmeans::fit_predict Compute k-means clustering and predicts cluster index for each sample @@ -757,7 +782,7 @@ in the input. | Name | Direction | Type | Description | | --- | --- | --- | --- | | `handle` | in | `raft::resources const&` | The raft handle. | -| `params` | in | `const kmeans::params&` | Parameters for KMeans model. | +| `params` | in | [`const kmeans::params&`](/api-reference/cpp-api-cluster-kmeans#cuvs-cluster-kmeans-params) | Parameters for KMeans model. | | `X` | in | `raft::device_matrix_view` | Training instances to cluster. The data must be in row-major format. [dim = n_samples x n_features] | | `sample_weight` | in | `std::optional>` | Optional weights for each observation in X. [len = n_samples] | | `centroids` | inout | `std::optional>` | Optional [in] When init is InitMethod::Array, use centroids as the initial cluster centers [out] The generated centroids from the kmeans algorithm are stored at the address pointed by 'centroids'. [dim = n_clusters x n_features] | @@ -793,7 +818,7 @@ in the input. | Name | Direction | Type | Description | | --- | --- | --- | --- | | `handle` | in | `raft::resources const&` | The raft handle. | -| `params` | in | `const kmeans::params&` | Parameters for KMeans model. | +| `params` | in | [`const kmeans::params&`](/api-reference/cpp-api-cluster-kmeans#cuvs-cluster-kmeans-params) | Parameters for KMeans model. | | `X` | in | `raft::device_matrix_view` | Training instances to cluster. The data must be in row-major format. [dim = n_samples x n_features] | | `sample_weight` | in | `std::optional>` | Optional weights for each observation in X. [len = n_samples] | | `centroids` | inout | `std::optional>` | Optional [in] When init is InitMethod::Array, use centroids as the initial cluster centers [out] The generated centroids from the kmeans algorithm are stored at the address pointed by 'centroids'. [dim = n_clusters x n_features] | @@ -829,7 +854,7 @@ in the input. | Name | Direction | Type | Description | | --- | --- | --- | --- | | `handle` | in | `raft::resources const&` | The raft handle. | -| `params` | in | `const kmeans::params&` | Parameters for KMeans model. | +| `params` | in | [`const kmeans::params&`](/api-reference/cpp-api-cluster-kmeans#cuvs-cluster-kmeans-params) | Parameters for KMeans model. | | `X` | in | `raft::device_matrix_view` | Training instances to cluster. The data must be in row-major format. [dim = n_samples x n_features] | | `sample_weight` | in | `std::optional>` | Optional weights for each observation in X. [len = n_samples] | | `centroids` | inout | `std::optional>` | Optional [in] When init is InitMethod::Array, use centroids as the initial cluster centers [out] The generated centroids from the kmeans algorithm are stored at the address pointed by 'centroids'. [dim = n_clusters x n_features] | @@ -865,7 +890,7 @@ in the input. | Name | Direction | Type | Description | | --- | --- | --- | --- | | `handle` | in | `raft::resources const&` | The raft handle. | -| `params` | in | `const kmeans::params&` | Parameters for KMeans model. | +| `params` | in | [`const kmeans::params&`](/api-reference/cpp-api-cluster-kmeans#cuvs-cluster-kmeans-params) | Parameters for KMeans model. | | `X` | in | `raft::device_matrix_view` | Training instances to cluster. The data must be in row-major format. [dim = n_samples x n_features] | | `sample_weight` | in | `std::optional>` | Optional weights for each observation in X. [len = n_samples] | | `centroids` | inout | `std::optional>` | Optional [in] When init is InitMethod::Array, use centroids as the initial cluster centers [out] The generated centroids from the kmeans algorithm are stored at the address pointed by 'centroids'. [dim = n_clusters x n_features] | @@ -898,7 +923,7 @@ in the input. | Name | Direction | Type | Description | | --- | --- | --- | --- | | `handle` | in | `const raft::resources&` | The raft handle. | -| `params` | in | `cuvs::cluster::kmeans::balanced_params const&` | Parameters for KMeans model. | +| `params` | in | [`cuvs::cluster::kmeans::balanced_params const&`](/api-reference/cpp-api-cluster-kmeans#cuvs-cluster-kmeans-balanced-params) | Parameters for KMeans model. | | `X` | in | `raft::device_matrix_view` | Training instances to cluster. The data must be in row-major format. [dim = n_samples x n_features] | | `centroids` | inout | `raft::device_matrix_view` | Optional [in] When init is InitMethod::Array, use centroids as the initial cluster centers [out] The generated centroids from the kmeans algorithm are stored at the address pointed by 'centroids'. [dim = n_clusters x n_features] | | `labels` | out | `raft::device_vector_view` | Index of the cluster each sample in X belongs to. [len = n_samples] | @@ -928,7 +953,7 @@ in the input. | Name | Direction | Type | Description | | --- | --- | --- | --- | | `handle` | in | `const raft::resources&` | The raft handle. | -| `params` | in | `cuvs::cluster::kmeans::balanced_params const&` | Parameters for KMeans model. | +| `params` | in | [`cuvs::cluster::kmeans::balanced_params const&`](/api-reference/cpp-api-cluster-kmeans#cuvs-cluster-kmeans-balanced-params) | Parameters for KMeans model. | | `X` | in | `raft::device_matrix_view` | Training instances to cluster. The data must be in row-major format. [dim = n_samples x n_features] | | `centroids` | inout | `raft::device_matrix_view` | Optional [in] When init is InitMethod::Array, use centroids as the initial cluster centers [out] The generated centroids from the kmeans algorithm are stored at the address pointed by 'centroids'. [dim = n_clusters x n_features] | | `labels` | out | `raft::device_vector_view` | Index of the cluster each sample in X belongs to. [len = n_samples] | @@ -939,6 +964,7 @@ in the input. _Source: `cpp/include/cuvs/cluster/kmeans.hpp:1444`_ + ### cuvs::cluster::kmeans::transform Transform X to a cluster-distance space. @@ -956,7 +982,7 @@ raft::device_matrix_view X_new); | Name | Direction | Type | Description | | --- | --- | --- | --- | | `handle` | in | `raft::resources const&` | The raft handle. | -| `params` | in | `const kmeans::params&` | Parameters for KMeans model. | +| `params` | in | [`const kmeans::params&`](/api-reference/cpp-api-cluster-kmeans#cuvs-cluster-kmeans-params) | Parameters for KMeans model. | | `X` | in | `raft::device_matrix_view` | Training instances to cluster. The data must be in row-major format [dim = n_samples x n_features] | | `centroids` | in | `raft::device_matrix_view` | Cluster centroids. The data must be in row-major format. [dim = n_clusters x n_features] | | `X_new` | out | `raft::device_matrix_view` | X transformed in the new space. [dim = n_samples x n_features] | @@ -984,7 +1010,7 @@ raft::device_matrix_view X_new); | Name | Direction | Type | Description | | --- | --- | --- | --- | | `handle` | in | `raft::resources const&` | The raft handle. | -| `params` | in | `const kmeans::params&` | Parameters for KMeans model. | +| `params` | in | [`const kmeans::params&`](/api-reference/cpp-api-cluster-kmeans#cuvs-cluster-kmeans-params) | Parameters for KMeans model. | | `X` | in | `raft::device_matrix_view` | Training instances to cluster. The data must be in row-major format [dim = n_samples x n_features] | | `centroids` | in | `raft::device_matrix_view` | Cluster centroids. The data must be in row-major format. [dim = n_clusters x n_features] | | `X_new` | out | `raft::device_matrix_view` | X transformed in the new space. [dim = n_samples x n_features] | @@ -995,6 +1021,7 @@ raft::device_matrix_view X_new); _Source: `cpp/include/cuvs/cluster/kmeans.hpp:1482`_ + ### cuvs::cluster::kmeans::cluster_cost Compute (optionally weighted) cluster cost @@ -1115,6 +1142,7 @@ _Source: `cpp/include/cuvs/cluster/kmeans.hpp:1566`_ _Doxygen group: `kmeans_helpers`_ + ### helpers::find_k Automatically find the optimal value of k using a binary search. diff --git a/fern/pages/cpp_api/cpp-api-cluster-spectral.md b/fern/pages/cpp_api/cpp-api-cluster-spectral.md index 955c6330c7..792614bc5a 100644 --- a/fern/pages/cpp_api/cpp-api-cluster-spectral.md +++ b/fern/pages/cpp_api/cpp-api-cluster-spectral.md @@ -10,6 +10,7 @@ _Source header: `cpp/include/cuvs/cluster/spectral.hpp`_ _Doxygen group: `spectral_params`_ + ### cuvs::cluster::spectral::params Parameters for spectral clustering @@ -35,6 +36,7 @@ _Source: `cpp/include/cuvs/cluster/spectral.hpp:22`_ _Doxygen group: `spectral`_ + ### cuvs::cluster::spectral::fit_predict Perform spectral clustering on a connectivity graph @@ -53,7 +55,7 @@ n_clusters-1) | Name | Direction | Type | Description | | --- | --- | --- | --- | | `handle` | in | `raft::resources const&` | RAFT resource handle | -| `config` | in | `params` | Spectral clustering parameters | +| `config` | in | [`params`](/api-reference/cpp-api-cluster-spectral#cuvs-cluster-spectral-params) | Spectral clustering parameters | | `connectivity_graph` | in | `raft::device_coo_matrix_view` | Sparse COO matrix representing connectivity between data points | | `labels` | out | `raft::device_vector_view` | Device vector of size n_samples to store cluster assignments (0 to | @@ -81,7 +83,7 @@ n_clusters-1) | Name | Direction | Type | Description | | --- | --- | --- | --- | | `handle` | in | `raft::resources const&` | RAFT resource handle | -| `config` | in | `params` | Spectral clustering parameters | +| `config` | in | [`params`](/api-reference/cpp-api-cluster-spectral#cuvs-cluster-spectral-params) | Spectral clustering parameters | | `connectivity_graph` | in | `raft::device_coo_matrix_view` | Sparse COO matrix representing connectivity between data points | | `labels` | out | `raft::device_vector_view` | Device vector of size n_samples to store cluster assignments (0 to | @@ -111,7 +113,7 @@ n_clusters-1) | Name | Direction | Type | Description | | --- | --- | --- | --- | | `handle` | in | `raft::resources const&` | RAFT resource handle | -| `config` | in | `params` | Spectral clustering parameters | +| `config` | in | [`params`](/api-reference/cpp-api-cluster-spectral#cuvs-cluster-spectral-params) | Spectral clustering parameters | | `dataset` | in | `raft::device_matrix_view` | Dense row-major matrix of shape (n_samples, n_features) | | `labels` | out | `raft::device_vector_view` | Device vector of size n_samples to store cluster assignments (0 to | diff --git a/fern/pages/cpp_api/cpp-api-distance-distance.md b/fern/pages/cpp_api/cpp-api-distance-distance.md index c1aeade2b5..741f239a3d 100644 --- a/fern/pages/cpp_api/cpp-api-distance-distance.md +++ b/fern/pages/cpp_api/cpp-api-distance-distance.md @@ -6,10 +6,101 @@ slug: api-reference/cpp-api-distance-distance _Source header: `cpp/include/cuvs/distance/distance.hpp`_ +## Types + + +### cuvs::distance::DistanceType + +enum to tell how to compute distance + +```cpp +enum class DistanceType : int { ... } ; +``` + +**Values** + +| Name | Value | +| --- | --- | +| `L2Expanded` | `0` | +| `CosineExpanded` | `2` | +| `L1` | `3` | +| `L2Unexpanded` | `4` | +| `InnerProduct` | `6` | +| `Linf` | `7` | +| `Canberra` | `8` | +| `LpUnexpanded` | `9` | +| `CorrelationExpanded` | `10` | +| `JaccardExpanded` | `11` | +| `HellingerExpanded` | `12` | +| `Haversine` | `13` | +| `BrayCurtis` | `14` | +| `JensenShannon` | `15` | +| `HammingUnexpanded` | `16` | +| `KLDivergence` | `17` | +| `RusselRaoExpanded` | `18` | +| `DiceExpanded` | `19` | +| `BitwiseHamming` | `20` | +| `Precomputed` | `100` | +| `CustomUDF` | `101` | + +_Source: `cpp/include/cuvs/distance/distance.hpp:17`_ + + +### cuvs::distance::DensityKernelType + +Density kernel type for Kernel Density Estimation. + +These are the smoothing kernels used in KDE — distinct from the dot-product kernels (RBF, Polynomial, etc.) in cuvs::distance::kernels used by SVMs. + +```cpp +enum class DensityKernelType : int { ... } ; +``` + +**Values** + +| Name | Value | +| --- | --- | +| `Gaussian` | `0` | +| `Tophat` | `1` | +| `Epanechnikov` | `2` | +| `Exponential` | `3` | +| `Linear` | `4` | +| `Cosine` | `5` | + +_Source: `cpp/include/cuvs/distance/distance.hpp:91`_ + + +### kernels::KernelParams + +Parameters for kernel matrices. + +The following kernels are implemented: + +- LINEAR \f[ K(x_1,x_2) = <x_1,x_2>, \f] where \f$< , >\f$ is the dot product +- POLYNOMIAL \f[ K(x_1, x_2) = (\gamma <x_1,x_2> + \mathrm\{coef0\})^\mathrm\{degree\} \f] +- RBF \f[ K(x_1, x_2) = \exp(- \gamma \|x_1-x_2\|^2) \f] +- TANH \f[ K(x_1, x_2) = \tanh(\gamma <x_1,x_2> + \mathrm\{coef0\}) \f] + +```cpp +struct KernelParams { ... } ; +``` + +**Fields** + +| Name | Type | Description | +| --- | --- | --- | +| `kernel` | `KernelType` | | +| `degree` | `int` | | +| `gamma` | `double` | | +| `coef0` | `double` | | + +_Source: `cpp/include/cuvs/distance/distance.hpp:111`_ + ## Pairwise Distances API _Doxygen group: `pairwise_distance`_ + ### kernels::pairwise_distance Compute pairwise distances for two matrices @@ -36,7 +127,7 @@ Usage example: | `x` | in | `raft::device_matrix_view const` | first set of points (size n*k) | | `y` | in | `raft::device_matrix_view const` | second set of points (size m*k) | | `dist` | out | `raft::device_matrix_view` | output distance matrix (size n*m) | -| `metric` | in | `cuvs::distance::DistanceType` | distance to evaluate | +| `metric` | in | [`cuvs::distance::DistanceType`](/api-reference/cpp-api-distance-distance#cuvs-distance-distancetype) | distance to evaluate | | `metric_arg` | in | `float` | metric argument (used for Minkowski distance) Default: `2.0f`. | **Returns** @@ -71,7 +162,7 @@ Usage example: | `x` | in | `raft::device_matrix_view const` | first set of points (size n*k) | | `y` | in | `raft::device_matrix_view const` | second set of points (size m*k) | | `dist` | out | `raft::device_matrix_view` | output distance matrix (size n*m) | -| `metric` | in | `cuvs::distance::DistanceType` | distance to evaluate | +| `metric` | in | [`cuvs::distance::DistanceType`](/api-reference/cpp-api-distance-distance#cuvs-distance-distancetype) | distance to evaluate | | `metric_arg` | in | `double` | metric argument (used for Minkowski distance) Default: `2.0f`. | **Returns** @@ -106,7 +197,7 @@ Usage example: | `x` | in | `raft::device_matrix_view const` | first set of points (size n*k) | | `y` | in | `raft::device_matrix_view const` | second set of points (size m*k) | | `dist` | out | `raft::device_matrix_view` | output distance matrix (size n*m) | -| `metric` | in | `cuvs::distance::DistanceType` | distance to evaluate | +| `metric` | in | [`cuvs::distance::DistanceType`](/api-reference/cpp-api-distance-distance#cuvs-distance-distancetype) | distance to evaluate | | `metric_arg` | in | `float` | metric argument (used for Minkowski distance) Default: `2.0f`. | **Returns** @@ -141,7 +232,7 @@ Usage example: | `x` | in | `raft::device_matrix_view const` | first set of points (size n*k) | | `y` | in | `raft::device_matrix_view const` | second set of points (size m*k) | | `dist` | out | `raft::device_matrix_view` | output distance matrix (size n*m) | -| `metric` | in | `cuvs::distance::DistanceType` | distance to evaluate | +| `metric` | in | [`cuvs::distance::DistanceType`](/api-reference/cpp-api-distance-distance#cuvs-distance-distancetype) | distance to evaluate | | `metric_arg` | in | `float` | metric argument (used for Minkowski distance) Default: `2.0f`. | **Returns** @@ -176,7 +267,7 @@ Usage example: | `x` | in | `raft::device_matrix_view const` | first set of points (size n*k) | | `y` | in | `raft::device_matrix_view const` | second set of points (size m*k) | | `dist` | out | `raft::device_matrix_view` | output distance matrix (size n*m) | -| `metric` | in | `cuvs::distance::DistanceType` | distance to evaluate | +| `metric` | in | [`cuvs::distance::DistanceType`](/api-reference/cpp-api-distance-distance#cuvs-distance-distancetype) | distance to evaluate | | `metric_arg` | in | `double` | metric argument (used for Minkowski distance) Default: `2.0f`. | **Returns** @@ -211,7 +302,7 @@ Usage example: | `x` | in | `raft::device_matrix_view const` | first set of points (size n*k) | | `y` | in | `raft::device_matrix_view const` | second set of points (size m*k) | | `dist` | out | `raft::device_matrix_view` | output distance matrix (size n*m) | -| `metric` | in | `cuvs::distance::DistanceType` | distance to evaluate | +| `metric` | in | [`cuvs::distance::DistanceType`](/api-reference/cpp-api-distance-distance#cuvs-distance-distancetype) | distance to evaluate | | `metric_arg` | in | `float` | metric argument (used for Minkowski distance) Default: `2.0f`. | **Returns** @@ -243,7 +334,7 @@ input configuration and distance function. | `x` | in | `raft::device_csr_matrix_view` | raft::device_csr_matrix_view | | `y` | in | `raft::device_csr_matrix_view` | raft::device_csr_matrix_view | | `dist` | out | `raft::device_matrix_view` | raft::device_matrix_view dense matrix | -| `metric` | in | `cuvs::distance::DistanceType` | distance metric to use | +| `metric` | in | [`cuvs::distance::DistanceType`](/api-reference/cpp-api-distance-distance#cuvs-distance-distancetype) | distance metric to use | | `metric_arg` | in | `float` | metric argument (used for Minkowski distance) Default: `2.0f`. | **Returns** @@ -275,7 +366,7 @@ input configuration and distance function. | `x` | in | `raft::device_csr_matrix_view` | raft::device_csr_matrix_view | | `y` | in | `raft::device_csr_matrix_view` | raft::device_csr_matrix_view | | `dist` | out | `raft::device_matrix_view` | raft::device_matrix_view dense matrix | -| `metric` | in | `cuvs::distance::DistanceType` | distance metric to use | +| `metric` | in | [`cuvs::distance::DistanceType`](/api-reference/cpp-api-distance-distance#cuvs-distance-distancetype) | distance metric to use | | `metric_arg` | in | `float` | metric argument (used for Minkowski distance) Default: `2.0f`. | **Returns** diff --git a/fern/pages/cpp_api/cpp-api-neighbors-all-neighbors.md b/fern/pages/cpp_api/cpp-api-neighbors-all-neighbors.md index 5ddc069e2e..a7dce2d886 100644 --- a/fern/pages/cpp_api/cpp-api-neighbors-all-neighbors.md +++ b/fern/pages/cpp_api/cpp-api-neighbors-all-neighbors.md @@ -10,6 +10,7 @@ _Source header: `cpp/include/cuvs/neighbors/all_neighbors.hpp`_ _Doxygen group: `all_neighbors_cpp_params`_ + ### GraphBuildParams The all-neighbors algorithm parameters. @@ -22,6 +23,7 @@ graph_build_params::brute_force_params>; _Source: `cpp/include/cuvs/neighbors/all_neighbors.hpp:22`_ + ### cuvs::neighbors::all_neighbors::all_neighbors_params Parameters used to build an all-neighbors graph (find nearest neighbors for all the @@ -36,10 +38,10 @@ struct all_neighbors_params { ... } ; | Name | Type | Description | | --- | --- | --- | -| `graph_build_params` | `GraphBuildParams` | Parameters for knn graph building algorithm Approximate nearest neighbors methods or a brute force approach are supported to build the knn graph. Currently supported options are 'IVF-PQ', 'NN Descent', or 'Brute Force'. IVF-PQ is more accurate, but slower compared to NN Descent. Note that 'Brute Force' can also be approximate if n_clusters > 1. Set ivf_pq_params, nn_descent_params, or brute_force_params to select the graph build algorithm and control their parameters. | +| `graph_build_params` | [`GraphBuildParams`](/api-reference/cpp-api-neighbors-all-neighbors#graphbuildparams) | Parameters for knn graph building algorithm Approximate nearest neighbors methods or a brute force approach are supported to build the knn graph. Currently supported options are 'IVF-PQ', 'NN Descent', or 'Brute Force'. IVF-PQ is more accurate, but slower compared to NN Descent. Note that 'Brute Force' can also be approximate if n_clusters > 1. Set ivf_pq_params, nn_descent_params, or brute_force_params to select the graph build algorithm and control their parameters. | | `overlap_factor` | `size_t` | Number of nearest clusters each data point will be assigned to in the batching algorithm. Start with `overlap_factor = 2` and gradually increase (2->3->4 ...) for better accuracy at the cost of device memory usage. | | `n_clusters` | `size_t` | Number of total clusters (aka batches) to split the data into. If set to 1, algorithm creates an all-neighbors graph without batching. Start with `n_clusters = 4` and increase (4 → 8 → 16...) for less device memory usage at the cost of accuracy. This is independent from `overlap_factor` as long as `overlap_factor` < `n_clusters`. The ratio of `overlap_factor / n_clusters` determines device memory usage. Approximately `(overlap_factor / n_clusters) * num_rows_in_entire_data` number of rows will be put on device memory at once. E.g. between `(overlap_factor / n_clusters)` = 2/10 and 2/20, the latter will use less device memory. Larger `overlap_factor` results in better accuracy of the final all-neighbors knn graph. E.g. While using similar device memory, `(overlap_factor / n_clusters)` = 4/20 will have better accuracy than 2/10 at the cost of performance. | -| `metric` | `cuvs::distance::DistanceType` | Metric used. | +| `metric` | [`cuvs::distance::DistanceType`](/api-reference/cpp-api-distance-distance#cuvs-distance-distancetype) | Metric used. | _Source: `cpp/include/cuvs/neighbors/all_neighbors.hpp:37`_ @@ -47,6 +49,7 @@ _Source: `cpp/include/cuvs/neighbors/all_neighbors.hpp:37`_ _Doxygen group: `all_neighbors_cpp_build`_ + ### cuvs::neighbors::all_neighbors::build Builds an approximate all-neighbors knn graph (find nearest neighbors for all the @@ -73,7 +76,7 @@ compute core_distances. If core_distances is given, the resulting indices and di | Name | Direction | Type | Description | | --- | --- | --- | --- | | `handle` | in | `const raft::resources&` | raft::resources is an object managing resources | -| `params` | in | `const all_neighbors_params&` | an instance of all_neighbors::all_neighbors_params that are parameters to build all-neighbors knn graph | +| `params` | in | [`const all_neighbors_params&`](/api-reference/cpp-api-neighbors-all-neighbors#cuvs-neighbors-all-neighbors-all-neighbors-params) | an instance of all_neighbors::all_neighbors_params that are parameters to build all-neighbors knn graph | | `dataset` | in | `raft::host_matrix_view` | raft::host_matrix_view input dataset expected to be located in host memory | | `indices` | out | `raft::device_matrix_view` | nearest neighbor indices of shape [n_row x k] | | `distances` | out | `std::optional>` | nearest neighbor distances [n_row x k] Default: `std::nullopt`. | @@ -112,7 +115,7 @@ compute core_distances. If core_distances is given, the resulting indices and di | Name | Direction | Type | Description | | --- | --- | --- | --- | | `handle` | in | `const raft::resources&` | raft::resources is an object managing resources | -| `params` | in | `const all_neighbors_params&` | an instance of all_neighbors::all_neighbors_params that are parameters to build all-neighbors knn graph | +| `params` | in | [`const all_neighbors_params&`](/api-reference/cpp-api-neighbors-all-neighbors#cuvs-neighbors-all-neighbors-all-neighbors-params) | an instance of all_neighbors::all_neighbors_params that are parameters to build all-neighbors knn graph | | `dataset` | in | `raft::device_matrix_view` | raft::device_matrix_view input dataset expected to be located in device memory | | `indices` | out | `raft::device_matrix_view` | nearest neighbor indices of shape [n_row x k] | | `distances` | out | `std::optional>` | nearest neighbor distances [n_row x k] Default: `std::nullopt`. | diff --git a/fern/pages/cpp_api/cpp-api-neighbors-ball-cover.md b/fern/pages/cpp_api/cpp-api-neighbors-ball-cover.md index e08c06c706..ea2edb0fc9 100644 --- a/fern/pages/cpp_api/cpp-api-neighbors-ball-cover.md +++ b/fern/pages/cpp_api/cpp-api-neighbors-ball-cover.md @@ -10,6 +10,7 @@ _Source header: `cpp/include/cuvs/neighbors/ball_cover.hpp`_ _Doxygen group: `random_ball_cover`_ + ### cuvs::neighbors::ball_cover::build Builds and populates a previously unbuilt cuvs::neighbors::ball_cover::index diff --git a/fern/pages/cpp_api/cpp-api-neighbors-brute-force.md b/fern/pages/cpp_api/cpp-api-neighbors-brute-force.md index 6af771d611..0e56f231aa 100644 --- a/fern/pages/cpp_api/cpp-api-neighbors-brute-force.md +++ b/fern/pages/cpp_api/cpp-api-neighbors-brute-force.md @@ -10,6 +10,7 @@ _Source header: `cpp/include/cuvs/neighbors/brute_force.hpp`_ _Doxygen group: `bruteforce_cpp_index`_ + ### cuvs::neighbors::brute_force::index Construct an empty index. @@ -53,7 +54,7 @@ Constructs a brute force index from a dataset. This lets us precompute norms for | `res` | | `raft::resources const&` | | | `dataset_view` | | `raft::host_matrix_view` | | | `norms` | | `std::optional>&&` | | -| `metric` | | `cuvs::distance::DistanceType` | | +| `metric` | | [`cuvs::distance::DistanceType`](/api-reference/cpp-api-distance-distance#cuvs-distance-distancetype) | | | `metric_arg` | | `DistT` | Default: `0.0`. | **Returns** @@ -83,7 +84,7 @@ Constructs a brute force index from a dataset. This lets us precompute norms for | `res` | | `raft::resources const&` | | | `dataset_view` | | `raft::device_matrix_view` | | | `norms` | | `std::optional>&&` | | -| `metric` | | `cuvs::distance::DistanceType` | | +| `metric` | | [`cuvs::distance::DistanceType`](/api-reference/cpp-api-distance-distance#cuvs-distance-distancetype) | | | `metric_arg` | | `DistT` | Default: `0.0`. | **Returns** @@ -113,7 +114,7 @@ This class stores a non-owning reference to the dataset and norms. Having precom | `res` | | `raft::resources const&` | | | `dataset_view` | | `raft::device_matrix_view` | | | `norms_view` | | `std::optional>` | | -| `metric` | | `cuvs::distance::DistanceType` | | +| `metric` | | [`cuvs::distance::DistanceType`](/api-reference/cpp-api-distance-distance#cuvs-distance-distancetype) | | | `metric_arg` | | `DistT` | Default: `0.0`. | **Returns** @@ -143,7 +144,7 @@ Constructs a brute force index from a dataset. This lets us precompute norms for | `res` | | `raft::resources const&` | | | `dataset_view` | | `raft::device_matrix_view` | | | `norms` | | `std::optional>&&` | | -| `metric` | | `cuvs::distance::DistanceType` | | +| `metric` | | [`cuvs::distance::DistanceType`](/api-reference/cpp-api-distance-distance#cuvs-distance-distancetype) | | | `metric_arg` | | `DistT` | Default: `0.0`. | **Returns** @@ -173,7 +174,7 @@ This class stores a non-owning reference to the dataset and norms, with the data | `res` | | `raft::resources const&` | | | `dataset_view` | | `raft::device_matrix_view` | | | `norms_view` | | `std::optional>` | | -| `metric` | | `cuvs::distance::DistanceType` | | +| `metric` | | [`cuvs::distance::DistanceType`](/api-reference/cpp-api-distance-distance#cuvs-distance-distancetype) | | | `metric_arg` | | `DistT` | Default: `0.0`. | **Returns** @@ -182,6 +183,7 @@ This class stores a non-owning reference to the dataset and norms, with the data _Source: `cpp/include/cuvs/neighbors/brute_force.hpp:111`_ + ### cuvs::neighbors::brute_force::update_dataset Replace the dataset with a new dataset. @@ -228,6 +230,7 @@ We create a copy of the dataset on the device. The index manages the lifetime of _Source: `cpp/include/cuvs/neighbors/brute_force.hpp:128`_ + ### cuvs::neighbors::brute_force::metric Distance metric used for retrieval @@ -238,10 +241,11 @@ cuvs::distance::DistanceType metric() const noexcept; **Returns** -`cuvs::distance::DistanceType` +[`cuvs::distance::DistanceType`](/api-reference/cpp-api-distance-distance#cuvs-distance-distancetype) _Source: `cpp/include/cuvs/neighbors/brute_force.hpp:132`_ + ### cuvs::neighbors::brute_force::metric_arg Metric argument @@ -256,6 +260,7 @@ DistT metric_arg() const noexcept; _Source: `cpp/include/cuvs/neighbors/brute_force.hpp:135`_ + ### cuvs::neighbors::brute_force::size Total length of the index (number of vectors). @@ -270,6 +275,7 @@ size_t size() const noexcept; _Source: `cpp/include/cuvs/neighbors/brute_force.hpp:138`_ + ### cuvs::neighbors::brute_force::dim Dimensionality of the data. @@ -284,6 +290,7 @@ size_t dim() const noexcept; _Source: `cpp/include/cuvs/neighbors/brute_force.hpp:141`_ + ### cuvs::neighbors::brute_force::dataset Dataset [size, dim] @@ -298,6 +305,7 @@ raft::device_matrix_view dataset() const noex _Source: `cpp/include/cuvs/neighbors/brute_force.hpp:144`_ + ### cuvs::neighbors::brute_force::norms Dataset norms @@ -312,6 +320,7 @@ raft::device_vector_view norms() const; _Source: `cpp/include/cuvs/neighbors/brute_force.hpp:150`_ + ### cuvs::neighbors::brute_force::has_norms Whether ot not this index has dataset norms @@ -330,6 +339,7 @@ _Source: `cpp/include/cuvs/neighbors/brute_force.hpp:156`_ _Doxygen group: `bruteforce_cpp_index_build`_ + ### cuvs::neighbors::brute_force::build Build the index from the dataset for efficient search. @@ -504,6 +514,7 @@ _Source: `cpp/include/cuvs/neighbors/brute_force.hpp:298`_ _Doxygen group: `sparse_bruteforce_cpp_index`_ + ### cuvs::neighbors::brute_force::sparse_index Construct a sparse brute force sparse_index from dataset @@ -521,7 +532,7 @@ T metric_arg); | --- | --- | --- | --- | | `res` | | `raft::resources const&` | | | `dataset` | | `raft::device_csr_matrix_view` | | -| `metric` | | `cuvs::distance::DistanceType` | | +| `metric` | | [`cuvs::distance::DistanceType`](/api-reference/cpp-api-distance-distance#cuvs-distance-distancetype) | | | `metric_arg` | | `T` | | **Returns** @@ -540,7 +551,7 @@ cuvs::distance::DistanceType metric() const noexcept; **Returns** -`cuvs::distance::DistanceType` +[`cuvs::distance::DistanceType`](/api-reference/cpp-api-distance-distance#cuvs-distance-distancetype) _Source: `cpp/include/cuvs/neighbors/brute_force.hpp:615`_ @@ -562,6 +573,7 @@ _Source: `cpp/include/cuvs/neighbors/brute_force.hpp:618`_ _Doxygen group: `sparse_bruteforce_cpp_index_search`_ + ### cuvs::neighbors::brute_force::sparse_search_params Sparse Brute Force index search @@ -576,6 +588,7 @@ _Source: `cpp/include/cuvs/neighbors/brute_force.hpp:668`_ _Doxygen group: `bruteforce_cpp_index_serialize`_ + ### cuvs::neighbors::brute_force::serialize Save the index to file. @@ -704,6 +717,7 @@ The serialization format can be subject to changes, therefore loading an index s _Source: `cpp/include/cuvs/neighbors/brute_force.hpp:811`_ + ### cuvs::neighbors::brute_force::deserialize Load index from file. diff --git a/fern/pages/cpp_api/cpp-api-neighbors-cagra.md b/fern/pages/cpp_api/cpp-api-neighbors-cagra.md index ad573d328b..fa2e9cb22e 100644 --- a/fern/pages/cpp_api/cpp-api-neighbors-cagra.md +++ b/fern/pages/cpp_api/cpp-api-neighbors-cagra.md @@ -6,10 +6,35 @@ slug: api-reference/cpp-api-neighbors-cagra _Source header: `cpp/include/cuvs/neighbors/cagra.hpp`_ +## Types + + +### cuvs::neighbors::graph_build_params::ace_params + +Specialized parameters for ACE (Augmented Core Extraction) graph build + +```cpp +struct ace_params { ... } ; +``` + +**Fields** + +| Name | Type | Description | +| --- | --- | --- | +| `npartitions` | `size_t` | Number of partitions for ACE (Augmented Core Extraction) partitioned build. When set to 0 (default), the number of partitions is automatically derived based on available host and GPU memory to maximize partition size while ensuring the build fits in memory. Small values might improve recall but potentially degrade performance and increase memory usage. Partitions should not be too small to prevent issues in KNN graph construction. The partition size is on average 2 * (n_rows / npartitions) * dim * sizeof(T). 2 is because of the core and augmented vectors. Please account for imbalance in the partition sizes (up to 3x in our tests). If the specified number of partitions results in partitions that exceed available memory, the value will be automatically increased to fit memory constraints and a warning will be issued. | +| `ef_construction` | `size_t` | The index quality for the ACE build. Bigger values increase the index quality. At some point, increasing this will no longer improve the quality. | +| `build_dir` | `std::string` | Directory to store ACE build artifacts (e.g., KNN graph, optimized graph). Used when `use_disk` is true or when the graph does not fit in host and GPU memory. This should be the fastest disk in the system and hold enough space for twice the dataset, final graph, and label mapping. | +| `use_disk` | `bool` | Whether to use disk-based storage for ACE build. When true, enables disk-based operations for memory-efficient graph construction. | +| `max_host_memory_gb` | `double` | Maximum host memory to use for ACE build in GiB. When set to 0 (default), uses available host memory. When set to a positive value, limits host memory usage to the specified amount. Useful for testing or when running alongside other memory-intensive processes. | +| `max_gpu_memory_gb` | `double` | Maximum GPU memory to use for ACE build in GiB. When set to 0 (default), uses available GPU memory. When set to a positive value, limits GPU memory usage to the specified amount. Useful for testing or when running alongside other memory-intensive processes. | + +_Source: `cpp/include/cuvs/neighbors/cagra.hpp:37`_ + ## CAGRA index build parameters _Doxygen group: `cagra_cpp_index_params`_ + ### cuvs::neighbors::vpq_params Parameters for VPQ compression. @@ -28,12 +53,13 @@ struct vpq_params { ... } ; | `kmeans_n_iters` | `uint32_t` | The number of iterations searching for kmeans centers (both VQ & PQ phases). | | `vq_kmeans_trainset_fraction` | `double` | The fraction of data to use during iterative kmeans building (VQ phase). When zero, an optimal value is selected using a heuristic. | | `pq_kmeans_trainset_fraction` | `double` | The fraction of data to use during iterative kmeans building (PQ phase). When zero, an optimal value is selected using a heuristic. | -| `pq_kmeans_type` | `cuvs::cluster::kmeans::kmeans_type` | Type of k-means algorithm for PQ training. Balanced k-means tends to be faster than regular k-means for PQ training, for problem sets where the number of points per cluster are approximately equal. Regular k-means may be better for skewed cluster distributions. | +| `pq_kmeans_type` | [`cuvs::cluster::kmeans::kmeans_type`](/api-reference/cpp-api-cluster-kmeans#cuvs-cluster-kmeans-kmeans-type) | Type of k-means algorithm for PQ training. Balanced k-means tends to be faster than regular k-means for PQ training, for problem sets where the number of points per cluster are approximately equal. Regular k-means may be better for skewed cluster distributions. | | `max_train_points_per_pq_code` | `uint32_t` | The max number of data points to use per PQ code during PQ codebook training. Using more data points per PQ code may increase the quality of PQ codebook but may also increase the build time. We will use `pq_n_centers * max_train_points_per_pq_code` training points to train each PQ codebook. | | `max_train_points_per_vq_cluster` | `uint32_t` | The max number of data points to use per VQ cluster during training. | _Source: `cpp/include/cuvs/neighbors/common.hpp:42`_ + ### cuvs::neighbors::cagra::hnsw_heuristic_type A strategy for selecting the graph build parameters based on similar HNSW index @@ -48,6 +74,7 @@ enum class hnsw_heuristic_type : uint32_t { ... } ; _Source: `cpp/include/cuvs/neighbors/cagra.hpp:115`_ + ### cuvs::neighbors::cagra::from_hnsw_params Create a CAGRA index parameters compatible with HNSW index @@ -74,8 +101,8 @@ Usage example: | `dataset` | | `raft::matrix_extent` | The shape of the input dataset | | `M` | | `int` | HNSW index parameter M | | `ef_construction` | | `int` | HNSW index parameter ef_construction | -| `heuristic` | | `hnsw_heuristic_type` | The heuristic to use for selecting the graph build parameters Default: `hnsw_heuristic_type::SIMILAR_SEARCH_PERFORMANCE`. | -| `metric` | | `cuvs::distance::DistanceType` | The distance metric to search Default: `cuvs::distance::DistanceType::L2Expanded`. | +| `heuristic` | | [`hnsw_heuristic_type`](/api-reference/cpp-api-neighbors-cagra#cuvs-neighbors-cagra-hnsw-heuristic-type) | The heuristic to use for selecting the graph build parameters Default: `hnsw_heuristic_type::SIMILAR_SEARCH_PERFORMANCE`. | +| `metric` | | [`cuvs::distance::DistanceType`](/api-reference/cpp-api-distance-distance#cuvs-distance-distancetype) | The distance metric to search Default: `cuvs::distance::DistanceType::L2Expanded`. | **Returns** @@ -87,6 +114,7 @@ _Source: `cpp/include/cuvs/neighbors/cagra.hpp:245`_ _Doxygen group: `cagra_cpp_search_params`_ + ### cuvs::neighbors::cagra::search_algo CAGRA index search parameters @@ -110,6 +138,7 @@ _Source: `cpp/include/cuvs/neighbors/cagra.hpp:262`_ _Doxygen group: `cagra_cpp_extend_params`_ + ### cuvs::neighbors::cagra::extend_params CAGRA index extend parameters @@ -130,6 +159,7 @@ _Source: `cpp/include/cuvs/neighbors/cagra.hpp:357`_ _Doxygen group: `cagra_cpp_index`_ + ### cuvs::neighbors::cagra::metric Distance metric used for clustering. @@ -140,10 +170,11 @@ Distance metric used for clustering. **Returns** -`cuvs::distance::DistanceType` +[`cuvs::distance::DistanceType`](/api-reference/cpp-api-distance-distance#cuvs-distance-distancetype) _Source: `cpp/include/cuvs/neighbors/cagra.hpp:401`_ + ### cuvs::neighbors::cagra::size Total length of the index (number of vectors). @@ -158,6 +189,7 @@ Total length of the index (number of vectors). _Source: `cpp/include/cuvs/neighbors/cagra.hpp:407`_ + ### cuvs::neighbors::cagra::dim Dimensionality of the data. @@ -172,6 +204,7 @@ Dimensionality of the data. _Source: `cpp/include/cuvs/neighbors/cagra.hpp:415`_ + ### cuvs::neighbors::cagra::graph_degree Graph degree @@ -186,6 +219,7 @@ Graph degree _Source: `cpp/include/cuvs/neighbors/cagra.hpp:420`_ + ### cuvs::neighbors::cagra::data Dataset [size, dim] @@ -200,6 +234,7 @@ Dataset [size, dim] _Source: `cpp/include/cuvs/neighbors/cagra.hpp:435`_ + ### cuvs::neighbors::cagra::graph neighborhood graph [size, graph-degree] @@ -215,6 +250,7 @@ neighborhood graph [size, graph-degree] _Source: `cpp/include/cuvs/neighbors/cagra.hpp:441`_ + ### cuvs::neighbors::cagra::source_indices Mapping from internal graph node indices to the original user-provided indices. @@ -230,6 +266,7 @@ Mapping from internal graph node indices to the original user-provided indices. _Source: `cpp/include/cuvs/neighbors/cagra.hpp:448`_ + ### cuvs::neighbors::cagra::dataset_fd Get the dataset file descriptor (for disk-backed index) @@ -241,10 +278,11 @@ Get the dataset file descriptor (for disk-backed index) **Returns** -`const std::optional&` +[`const std::optional&`](/api-reference/cpp-api-util-file-io#cuvs-util-file-descriptor) _Source: `cpp/include/cuvs/neighbors/cagra.hpp:458`_ + ### cuvs::neighbors::cagra::graph_fd Get the graph file descriptor (for disk-backed index) @@ -256,10 +294,11 @@ Get the graph file descriptor (for disk-backed index) **Returns** -`const std::optional&` +[`const std::optional&`](/api-reference/cpp-api-util-file-io#cuvs-util-file-descriptor) _Source: `cpp/include/cuvs/neighbors/cagra.hpp:465`_ + ### cuvs::neighbors::cagra::mapping_fd Get the mapping file descriptor (for disk-backed index) @@ -271,10 +310,11 @@ Get the mapping file descriptor (for disk-backed index) **Returns** -`const std::optional&` +[`const std::optional&`](/api-reference/cpp-api-util-file-io#cuvs-util-file-descriptor) _Source: `cpp/include/cuvs/neighbors/cagra.hpp:472`_ + ### cuvs::neighbors::cagra::dataset_norms Dataset norms for cosine distance [size] @@ -290,6 +330,7 @@ Dataset norms for cosine distance [size] _Source: `cpp/include/cuvs/neighbors/cagra.hpp:479`_ + ### cuvs::neighbors::cagra::index ```cpp @@ -323,7 +364,7 @@ cuvs::distance::DistanceType metric = cuvs::distance::DistanceType::L2Expanded) | Name | Direction | Type | Description | | --- | --- | --- | --- | | `res` | | `raft::resources const&` | | -| `metric` | | `cuvs::distance::DistanceType` | Default: `cuvs::distance::DistanceType::L2Expanded`. | +| `metric` | | [`cuvs::distance::DistanceType`](/api-reference/cpp-api-distance-distance#cuvs-distance-distancetype) | Default: `cuvs::distance::DistanceType::L2Expanded`. | **Returns** @@ -364,7 +405,7 @@ Usage examples: | Name | Direction | Type | Description | | --- | --- | --- | --- | | `res` | | `raft::resources const&` | | -| `metric` | | `cuvs::distance::DistanceType` | | +| `metric` | | [`cuvs::distance::DistanceType`](/api-reference/cpp-api-distance-distance#cuvs-distance-distancetype) | | | `dataset` | | `raft::mdspan, raft::row_major, data_accessor>` | | | `knn_graph` | | `raft::mdspan, raft::row_major, graph_accessor>` | | @@ -374,6 +415,7 @@ Usage examples: _Source: `cpp/include/cuvs/neighbors/cagra.hpp:559`_ + ### cuvs::neighbors::cagra::update_dataset Replace the dataset with a new dataset. @@ -475,6 +517,7 @@ Note: This will clear any precomputed dataset norms. _Source: `cpp/include/cuvs/neighbors/cagra.hpp:644`_ + ### cuvs::neighbors::cagra::update_graph Replace the graph with a new graph. @@ -525,6 +568,7 @@ We create a copy of the graph on the device. The index manages the lifetime of t _Source: `cpp/include/cuvs/neighbors/cagra.hpp:689`_ + ### cuvs::neighbors::cagra::update_source_indices Replace the source indices with a new source indices taking the ownership of the passed vector. @@ -585,7 +629,7 @@ This method configures the index to use a disk-based dataset. The dataset file s | Name | Direction | Type | Description | | --- | --- | --- | --- | | `res` | in | `raft::resources const&` | raft resources | -| `fd` | in | `cuvs::util::file_descriptor&&` | File descriptor (will be moved into the index for lifetime management) | +| `fd` | in | [`cuvs::util::file_descriptor&&`](/api-reference/cpp-api-util-file-io#cuvs-util-file-descriptor) | File descriptor (will be moved into the index for lifetime management) | **Returns** @@ -608,7 +652,7 @@ This method configures the index to use a disk-based graph. The graph file shoul | Name | Direction | Type | Description | | --- | --- | --- | --- | | `res` | in | `raft::resources const&` | raft resources | -| `fd` | in | `cuvs::util::file_descriptor&&` | File descriptor (will be moved into the index for lifetime management) | +| `fd` | in | [`cuvs::util::file_descriptor&&`](/api-reference/cpp-api-util-file-io#cuvs-util-file-descriptor) | File descriptor (will be moved into the index for lifetime management) | **Returns** @@ -616,6 +660,7 @@ This method configures the index to use a disk-based graph. The graph file shoul _Source: `cpp/include/cuvs/neighbors/cagra.hpp:794`_ + ### cuvs::neighbors::cagra::update_mapping Update the dataset mapping from a disk file using a file descriptor. @@ -631,7 +676,7 @@ This method configures the index to use a disk-based dataset mapping. The mappin | Name | Direction | Type | Description | | --- | --- | --- | --- | | `res` | in | `raft::resources const&` | raft resources | -| `fd` | in | `cuvs::util::file_descriptor&&` | File descriptor (will be moved into the index for lifetime management) | +| `fd` | in | [`cuvs::util::file_descriptor&&`](/api-reference/cpp-api-util-file-io#cuvs-util-file-descriptor) | File descriptor (will be moved into the index for lifetime management) | **Returns** @@ -643,6 +688,7 @@ _Source: `cpp/include/cuvs/neighbors/cagra.hpp:834`_ _Doxygen group: `cagra_cpp_index_build`_ + ### cuvs::neighbors::cagra::build Build the index from the dataset for efficient search. @@ -953,6 +999,7 @@ _Source: `cpp/include/cuvs/neighbors/cagra.hpp:1202`_ _Doxygen group: `cagra_cpp_index_extend`_ + ### cuvs::neighbors::cagra::extend Add new vectors to a CAGRA index @@ -977,7 +1024,7 @@ part. The data will be copied from the current index in this function. The num r | Name | Direction | Type | Description | | --- | --- | --- | --- | | `handle` | in | `raft::resources const&` | raft resources | -| `params` | in | `const cagra::extend_params&` | extend params | +| `params` | in | [`const cagra::extend_params&`](/api-reference/cpp-api-neighbors-cagra#cuvs-neighbors-cagra-extend-params) | extend params | | `additional_dataset` | in | `raft::device_matrix_view` | additional dataset on device memory | | `idx` | in,out | `cuvs::neighbors::cagra::index&` | CAGRA index | | `new_dataset_buffer_view` | out | `std::optional>` | memory buffer view for the dataset including the additional Default: `std::nullopt`. | @@ -1013,7 +1060,7 @@ part. The data will be copied from the current index in this function. The num r | Name | Direction | Type | Description | | --- | --- | --- | --- | | `handle` | in | `raft::resources const&` | raft resources | -| `params` | in | `const cagra::extend_params&` | extend params | +| `params` | in | [`const cagra::extend_params&`](/api-reference/cpp-api-neighbors-cagra#cuvs-neighbors-cagra-extend-params) | extend params | | `additional_dataset` | in | `raft::host_matrix_view` | additional dataset on host memory | | `idx` | in,out | `cuvs::neighbors::cagra::index&` | CAGRA index | | `new_dataset_buffer_view` | out | `std::optional>` | memory buffer view for the dataset including the additional Default: `std::nullopt`. | @@ -1049,7 +1096,7 @@ part. The data will be copied from the current index in this function. The num r | Name | Direction | Type | Description | | --- | --- | --- | --- | | `handle` | in | `raft::resources const&` | raft resources | -| `params` | in | `const cagra::extend_params&` | extend params | +| `params` | in | [`const cagra::extend_params&`](/api-reference/cpp-api-neighbors-cagra#cuvs-neighbors-cagra-extend-params) | extend params | | `additional_dataset` | in | `raft::device_matrix_view` | additional dataset on device memory | | `idx` | in,out | `cuvs::neighbors::cagra::index&` | CAGRA index | | `new_dataset_buffer_view` | out | `std::optional>` | memory buffer view for the dataset including the additional Default: `std::nullopt`. | @@ -1085,7 +1132,7 @@ part. The data will be copied from the current index in this function. The num r | Name | Direction | Type | Description | | --- | --- | --- | --- | | `handle` | in | `raft::resources const&` | raft resources | -| `params` | in | `const cagra::extend_params&` | extend params | +| `params` | in | [`const cagra::extend_params&`](/api-reference/cpp-api-neighbors-cagra#cuvs-neighbors-cagra-extend-params) | extend params | | `additional_dataset` | in | `raft::host_matrix_view` | additional dataset on host memory | | `idx` | in,out | `cuvs::neighbors::cagra::index&` | CAGRA index | | `new_dataset_buffer_view` | out | `std::optional>` | memory buffer view for the dataset including the additional Default: `std::nullopt`. | @@ -1121,7 +1168,7 @@ part. The data will be copied from the current index in this function. The num r | Name | Direction | Type | Description | | --- | --- | --- | --- | | `handle` | in | `raft::resources const&` | raft resources | -| `params` | in | `const cagra::extend_params&` | extend params | +| `params` | in | [`const cagra::extend_params&`](/api-reference/cpp-api-neighbors-cagra#cuvs-neighbors-cagra-extend-params) | extend params | | `additional_dataset` | in | `raft::device_matrix_view` | additional dataset on device memory | | `idx` | in,out | `cuvs::neighbors::cagra::index&` | CAGRA index | | `new_dataset_buffer_view` | out | `std::optional>` | memory buffer view for the dataset including the additional Default: `std::nullopt`. | @@ -1157,7 +1204,7 @@ part. The data will be copied from the current index in this function. The num r | Name | Direction | Type | Description | | --- | --- | --- | --- | | `handle` | in | `raft::resources const&` | raft resources | -| `params` | in | `const cagra::extend_params&` | extend params | +| `params` | in | [`const cagra::extend_params&`](/api-reference/cpp-api-neighbors-cagra#cuvs-neighbors-cagra-extend-params) | extend params | | `additional_dataset` | in | `raft::host_matrix_view` | additional dataset on host memory | | `idx` | in,out | `cuvs::neighbors::cagra::index&` | CAGRA index | | `new_dataset_buffer_view` | out | `std::optional>` | memory buffer view for the dataset including the additional Default: `std::nullopt`. | @@ -1193,7 +1240,7 @@ part. The data will be copied from the current index in this function. The num r | Name | Direction | Type | Description | | --- | --- | --- | --- | | `handle` | in | `raft::resources const&` | raft resources | -| `params` | in | `const cagra::extend_params&` | extend params | +| `params` | in | [`const cagra::extend_params&`](/api-reference/cpp-api-neighbors-cagra#cuvs-neighbors-cagra-extend-params) | extend params | | `additional_dataset` | in | `raft::device_matrix_view` | additional dataset on host memory | | `idx` | in,out | `cuvs::neighbors::cagra::index&` | CAGRA index | | `new_dataset_buffer_view` | out | `std::optional>` | memory buffer view for the dataset including the additional Default: `std::nullopt`. | @@ -1229,7 +1276,7 @@ part. The data will be copied from the current index in this function. The num r | Name | Direction | Type | Description | | --- | --- | --- | --- | | `handle` | in | `raft::resources const&` | raft resources | -| `params` | in | `const cagra::extend_params&` | extend params | +| `params` | in | [`const cagra::extend_params&`](/api-reference/cpp-api-neighbors-cagra#cuvs-neighbors-cagra-extend-params) | extend params | | `additional_dataset` | in | `raft::host_matrix_view` | additional dataset on host memory | | `idx` | in,out | `cuvs::neighbors::cagra::index&` | CAGRA index | | `new_dataset_buffer_view` | out | `std::optional>` | memory buffer view for the dataset including the additional Default: `std::nullopt`. | @@ -1245,6 +1292,7 @@ _Source: `cpp/include/cuvs/neighbors/cagra.hpp:1510`_ _Doxygen group: `cagra_cpp_index_search`_ + ### none_sample_filter Search ANN using the constructed index. @@ -1266,6 +1314,7 @@ _Source: `cpp/include/cuvs/neighbors/cagra.hpp:1541`_ _Doxygen group: `cagra_cpp_serialize`_ + ### cuvs::neighbors::cagra::serialize Save the index to file. @@ -1294,6 +1343,7 @@ Experimental, both the API and the serialization format are subject to change. _Source: `cpp/include/cuvs/neighbors/cagra.hpp:1758`_ + ### cuvs::neighbors::cagra::deserialize Load index from file. @@ -1698,6 +1748,7 @@ Experimental, both the API and the serialization format are subject to change. _Source: `cpp/include/cuvs/neighbors/cagra.hpp:2152`_ + ### cuvs::neighbors::cagra::serialize_to_hnswlib Write the CAGRA built index as a base layer HNSW index to an output stream diff --git a/fern/pages/cpp_api/cpp-api-neighbors-common.md b/fern/pages/cpp_api/cpp-api-neighbors-common.md index b65ece08a0..53e2596722 100644 --- a/fern/pages/cpp_api/cpp-api-neighbors-common.md +++ b/fern/pages/cpp_api/cpp-api-neighbors-common.md @@ -10,6 +10,7 @@ _Source header: `cpp/include/cuvs/neighbors/common.hpp`_ _Doxygen group: `neighbors_index`_ + ### cuvs::neighbors::index The base for approximate KNN index structures. @@ -20,6 +21,7 @@ struct index { ... } ; _Source: `cpp/include/cuvs/neighbors/common.hpp:107`_ + ### cuvs::neighbors::index_params The base for KNN index parameters. @@ -32,11 +34,12 @@ struct index_params { ... } ; | Name | Type | Description | | --- | --- | --- | -| `metric` | `cuvs::distance::DistanceType` | Distance type. | +| `metric` | [`cuvs::distance::DistanceType`](/api-reference/cpp-api-distance-distance#cuvs-distance-distancetype) | Distance type. | | `metric_arg` | `float` | The argument used by some distance metrics. | _Source: `cpp/include/cuvs/neighbors/common.hpp:110`_ + ### cuvs::neighbors::MergeStrategy Strategy for merging indices. @@ -60,6 +63,7 @@ _Source: `cpp/include/cuvs/neighbors/common.hpp:125`_ _Doxygen group: `neighbors_filtering`_ + ### filtering::FilterType Filtering for ANN Types @@ -78,6 +82,7 @@ enum class FilterType { ... } ; _Source: `cpp/include/cuvs/neighbors/common.hpp:496`_ + ### filtering::operator ```cpp @@ -96,6 +101,7 @@ const uint32_t sample_ix) const; _Source: `cpp/include/cuvs/neighbors/common.hpp:506`_ + ### filtering::get_filter_type ```cpp @@ -104,7 +110,7 @@ FilterType get_filter_type() const override; **Returns** -`FilterType` +[`FilterType`](/api-reference/cpp-api-neighbors-common#filtering-filtertype) _Source: `cpp/include/cuvs/neighbors/common.hpp:520`_ @@ -154,10 +160,11 @@ FilterType get_filter_type() const override; **Returns** -`FilterType` +[`FilterType`](/api-reference/cpp-api-neighbors-common#filtering-filtertype) _Source: `cpp/include/cuvs/neighbors/common.hpp:578`_ + ### filtering::bitset_filter ```cpp @@ -184,7 +191,7 @@ FilterType get_filter_type() const override; **Returns** -`FilterType` +[`FilterType`](/api-reference/cpp-api-neighbors-common#filtering-filtertype) _Source: `cpp/include/cuvs/neighbors/common.hpp:608`_ @@ -192,6 +199,7 @@ _Source: `cpp/include/cuvs/neighbors/common.hpp:608`_ _Doxygen group: `mg_cpp_index_params`_ + ### ivf::distribution_mode ```cpp @@ -204,6 +212,7 @@ _Source: `cpp/include/cuvs/neighbors/common.hpp:904`_ _Doxygen group: `mg_cpp_search_params`_ + ### ivf::replicated_search_mode ```cpp @@ -219,6 +228,7 @@ enum replicated_search_mode { ... } ; _Source: `cpp/include/cuvs/neighbors/common.hpp:915`_ + ### ivf::sharded_merge_mode ```cpp diff --git a/fern/pages/cpp_api/cpp-api-neighbors-dynamic-batching.md b/fern/pages/cpp_api/cpp-api-neighbors-dynamic-batching.md index a6444f8f57..121b4b771a 100644 --- a/fern/pages/cpp_api/cpp-api-neighbors-dynamic-batching.md +++ b/fern/pages/cpp_api/cpp-api-neighbors-dynamic-batching.md @@ -10,6 +10,7 @@ _Source header: `cpp/include/cuvs/neighbors/dynamic_batching.hpp`_ _Doxygen group: `dynamic_batching_cpp_index_params`_ + ### detail::index_params Dynamic Batching index parameters @@ -33,6 +34,7 @@ _Source: `cpp/include/cuvs/neighbors/dynamic_batching.hpp:21`_ _Doxygen group: `dynamic_batching_cpp_search_params`_ + ### detail::search_params Dynamic Batching search parameters @@ -53,6 +55,7 @@ _Source: `cpp/include/cuvs/neighbors/dynamic_batching.hpp:60`_ _Doxygen group: `dynamic_batching_cpp_index`_ + ### detail::index Construct a dynamic batching index by wrapping the upstream index. @@ -77,7 +80,7 @@ const cuvs::neighbors::filtering::base_filter* sample_filter = nullptr); | Name | Direction | Type | Description | | --- | --- | --- | --- | | `res` | in | `const raft::resources&` | raft resources | -| `params` | in | `const cuvs::neighbors::dynamic_batching::index_params&` | dynamic batching parameters | +| `params` | in | [`const cuvs::neighbors::dynamic_batching::index_params&`](/api-reference/cpp-api-neighbors-dynamic-batching#detail-index-params) | dynamic batching parameters | | `upstream_index` | in | `const Upstream&` | the original index to perform the search (the reference must be alive for the lifetime of the dynamic batching index) | | `upstream_params` | in | `const typename Upstream::search_params_type&` | the original index search parameters for all queries in a batch (the parameters are captured by value for the lifetime of the dynamic batching index) | | `sample_filter` | in | `const cuvs::neighbors::filtering::base_filter*` | filtering function, if any, must be the same for all requests in a batch (the pointer must be alive for the lifetime of the dynamic batching index) Default: `nullptr`. | @@ -92,6 +95,7 @@ _Source: `cpp/include/cuvs/neighbors/dynamic_batching.hpp:174`_ _Doxygen group: `dynamic_batching_cpp_search`_ + ### detail::search Search ANN using a dynamic batching index. @@ -116,7 +120,7 @@ Dynamic batching search is thread-safe: call the search function with copies of | Name | Direction | Type | Description | | --- | --- | --- | --- | | `res` | in | `raft::resources const&` | | -| `params` | in | `cuvs::neighbors::dynamic_batching::search_params const&` | query-specific batching parameters, such as the maximum waiting time | +| `params` | in | [`cuvs::neighbors::dynamic_batching::search_params const&`](/api-reference/cpp-api-neighbors-dynamic-batching#detail-search-params) | query-specific batching parameters, such as the maximum waiting time | | `index` | in | `dynamic_batching::index const&` | a dynamic batching index | | `queries` | in | `raft::device_matrix_view` | a device matrix view to a row-major matrix [n_queries, dim] | | `neighbors` | out | `raft::device_matrix_view` | a device matrix view to the indices of the neighbors in the source dataset [n_queries, k] | @@ -144,7 +148,7 @@ raft::device_matrix_view distances); | Name | Direction | Type | Description | | --- | --- | --- | --- | | `res` | | `raft::resources const&` | | -| `params` | | `cuvs::neighbors::dynamic_batching::search_params const&` | | +| `params` | | [`cuvs::neighbors::dynamic_batching::search_params const&`](/api-reference/cpp-api-neighbors-dynamic-batching#detail-search-params) | | | `index` | | `dynamic_batching::index const&` | | | `queries` | | `raft::device_matrix_view` | | | `neighbors` | | `raft::device_matrix_view` | | @@ -172,7 +176,7 @@ raft::device_matrix_view distances); | Name | Direction | Type | Description | | --- | --- | --- | --- | | `res` | | `raft::resources const&` | | -| `params` | | `cuvs::neighbors::dynamic_batching::search_params const&` | | +| `params` | | [`cuvs::neighbors::dynamic_batching::search_params const&`](/api-reference/cpp-api-neighbors-dynamic-batching#detail-search-params) | | | `index` | | `dynamic_batching::index const&` | | | `queries` | | `raft::device_matrix_view` | | | `neighbors` | | `raft::device_matrix_view` | | @@ -200,7 +204,7 @@ raft::device_matrix_view distances); | Name | Direction | Type | Description | | --- | --- | --- | --- | | `res` | | `raft::resources const&` | | -| `params` | | `cuvs::neighbors::dynamic_batching::search_params const&` | | +| `params` | | [`cuvs::neighbors::dynamic_batching::search_params const&`](/api-reference/cpp-api-neighbors-dynamic-batching#detail-search-params) | | | `index` | | `dynamic_batching::index const&` | | | `queries` | | `raft::device_matrix_view` | | | `neighbors` | | `raft::device_matrix_view` | | @@ -228,7 +232,7 @@ raft::device_matrix_view distances); | Name | Direction | Type | Description | | --- | --- | --- | --- | | `res` | | `raft::resources const&` | | -| `params` | | `cuvs::neighbors::dynamic_batching::search_params const&` | | +| `params` | | [`cuvs::neighbors::dynamic_batching::search_params const&`](/api-reference/cpp-api-neighbors-dynamic-batching#detail-search-params) | | | `index` | | `dynamic_batching::index const&` | | | `queries` | | `raft::device_matrix_view` | | | `neighbors` | | `raft::device_matrix_view` | | @@ -256,7 +260,7 @@ raft::device_matrix_view distances); | Name | Direction | Type | Description | | --- | --- | --- | --- | | `res` | | `raft::resources const&` | | -| `params` | | `cuvs::neighbors::dynamic_batching::search_params const&` | | +| `params` | | [`cuvs::neighbors::dynamic_batching::search_params const&`](/api-reference/cpp-api-neighbors-dynamic-batching#detail-search-params) | | | `index` | | `dynamic_batching::index const&` | | | `queries` | | `raft::device_matrix_view` | | | `neighbors` | | `raft::device_matrix_view` | | @@ -284,7 +288,7 @@ raft::device_matrix_view distances); | Name | Direction | Type | Description | | --- | --- | --- | --- | | `res` | | `raft::resources const&` | | -| `params` | | `cuvs::neighbors::dynamic_batching::search_params const&` | | +| `params` | | [`cuvs::neighbors::dynamic_batching::search_params const&`](/api-reference/cpp-api-neighbors-dynamic-batching#detail-search-params) | | | `index` | | `dynamic_batching::index const&` | | | `queries` | | `raft::device_matrix_view` | | | `neighbors` | | `raft::device_matrix_view` | | @@ -312,7 +316,7 @@ raft::device_matrix_view distances); | Name | Direction | Type | Description | | --- | --- | --- | --- | | `res` | | `raft::resources const&` | | -| `params` | | `cuvs::neighbors::dynamic_batching::search_params const&` | | +| `params` | | [`cuvs::neighbors::dynamic_batching::search_params const&`](/api-reference/cpp-api-neighbors-dynamic-batching#detail-search-params) | | | `index` | | `dynamic_batching::index const&` | | | `queries` | | `raft::device_matrix_view` | | | `neighbors` | | `raft::device_matrix_view` | | diff --git a/fern/pages/cpp_api/cpp-api-neighbors-epsilon-neighborhood.md b/fern/pages/cpp_api/cpp-api-neighbors-epsilon-neighborhood.md index 605028622e..a81427dece 100644 --- a/fern/pages/cpp_api/cpp-api-neighbors-epsilon-neighborhood.md +++ b/fern/pages/cpp_api/cpp-api-neighbors-epsilon-neighborhood.md @@ -10,6 +10,7 @@ _Source header: `cpp/include/cuvs/neighbors/epsilon_neighborhood.hpp`_ _Doxygen group: `epsilon_neighborhood_cpp_l2`_ + ### cuvs::neighbors::epsilon_neighborhood::compute Computes epsilon neighborhood for the given distance metric and ball size. @@ -47,7 +48,7 @@ Currently, only L2Unexpanded (L2-squared) distance metric is supported. Other me | `adj` | out | `raft::device_matrix_view` | adjacency matrix [row-major] [on device] [dim = m x n] | | `vd` | out | `raft::device_vector_view` | vertex degree array [on device] [len = m + 1] `vd + m` stores the total number of edges in the adjacency matrix. Pass a nullptr if you don't need this info. | | `eps` | in | `value_t` | defines epsilon neighborhood radius (should be passed as squared when using L2Unexpanded metric) | -| `metric` | in | `cuvs::distance::DistanceType` | distance metric to use. Currently only L2Unexpanded is supported. Default: `cuvs::distance::DistanceType::L2Unexpanded`. | +| `metric` | in | [`cuvs::distance::DistanceType`](/api-reference/cpp-api-distance-distance#cuvs-distance-distancetype) | distance metric to use. Currently only L2Unexpanded is supported. Default: `cuvs::distance::DistanceType::L2Unexpanded`. | **Returns** diff --git a/fern/pages/cpp_api/cpp-api-neighbors-hnsw.md b/fern/pages/cpp_api/cpp-api-neighbors-hnsw.md index 1dd18480d6..6099d653b9 100644 --- a/fern/pages/cpp_api/cpp-api-neighbors-hnsw.md +++ b/fern/pages/cpp_api/cpp-api-neighbors-hnsw.md @@ -10,6 +10,7 @@ _Source header: `cpp/include/cuvs/neighbors/hnsw.hpp`_ _Doxygen group: `hnsw_cpp_index_params`_ + ### cuvs::neighbors::hnsw::HnswHierarchy Hierarchy for HNSW index when converting from CAGRA index @@ -28,6 +29,7 @@ enum class HnswHierarchy { ... } ; _Source: `cpp/include/cuvs/neighbors/hnsw.hpp:40`_ + ### cuvs::neighbors::hnsw::[[deprecated Create a CAGRA index parameters compatible with HNSW index @@ -63,6 +65,7 @@ _Source: `cpp/include/cuvs/neighbors/hnsw.hpp:114`_ _Doxygen group: `hnsw_cpp_index`_ + ### template <typename T> hnswlib index wrapper @@ -73,6 +76,7 @@ template _Source: `cpp/include/cuvs/neighbors/hnsw.hpp:130`_ + ### cuvs::neighbors::hnsw::index load a base-layer-only hnswlib index originally saved from a built CAGRA index. @@ -89,8 +93,8 @@ This is a virtual class and it cannot be used directly. To create an index, use | Name | Direction | Type | Description | | --- | --- | --- | --- | | `dim` | in | `int` | dimensions of the training dataset | -| `metric` | in | `cuvs::distance::DistanceType` | distance metric to search. Supported metrics ("L2Expanded", "InnerProduct") | -| `hierarchy` | in | `HnswHierarchy` | hierarchy used for upper HNSW layers Default: `HnswHierarchy::NONE`. | +| `metric` | in | [`cuvs::distance::DistanceType`](/api-reference/cpp-api-distance-distance#cuvs-distance-distancetype) | distance metric to search. Supported metrics ("L2Expanded", "InnerProduct") | +| `hierarchy` | in | [`HnswHierarchy`](/api-reference/cpp-api-neighbors-hnsw#cuvs-neighbors-hnsw-hnswhierarchy) | hierarchy used for upper HNSW layers Default: `HnswHierarchy::NONE`. | **Returns** @@ -98,6 +102,7 @@ This is a virtual class and it cannot be used directly. To create an index, use _Source: `cpp/include/cuvs/neighbors/hnsw.hpp:143`_ + ### cuvs::neighbors::hnsw::get_index Get underlying index @@ -112,6 +117,7 @@ virtual void const* get_index() const = 0; _Source: `cpp/include/cuvs/neighbors/hnsw.hpp:153`_ + ### cuvs::neighbors::hnsw::set_ef Set ef for search @@ -132,6 +138,7 @@ virtual void set_ef(int ef) const = 0; _Source: `cpp/include/cuvs/neighbors/hnsw.hpp:164`_ + ### cuvs::neighbors::hnsw::file_path Get file path for disk-backed index @@ -150,6 +157,7 @@ _Source: `cpp/include/cuvs/neighbors/hnsw.hpp:169`_ _Doxygen group: `hnsw_cpp_extend_params`_ + ### cuvs::neighbors::hnsw::extend_params HNSW index extend parameters @@ -170,6 +178,7 @@ _Source: `cpp/include/cuvs/neighbors/hnsw.hpp:186`_ _Doxygen group: `hnsw_cpp_index_build`_ + ### cuvs::neighbors::hnsw::build Build an HNSW index on the GPU @@ -306,6 +315,7 @@ _Source: `cpp/include/cuvs/neighbors/hnsw.hpp:428`_ _Doxygen group: `hnsw_cpp_index_load`_ + ### cuvs::neighbors::hnsw::from_cagra Construct an hnswlib index from a CAGRA index @@ -450,6 +460,7 @@ _Source: `cpp/include/cuvs/neighbors/hnsw.hpp:579`_ _Doxygen group: `hnsw_cpp_index_extend`_ + ### cuvs::neighbors::hnsw::extend Add new vectors to an HNSW index @@ -470,7 +481,7 @@ Usage example: | Name | Direction | Type | Description | | --- | --- | --- | --- | | `res` | in | `raft::resources const&` | raft resources | -| `params` | in | `const extend_params&` | configure the extend | +| `params` | in | [`const extend_params&`](/api-reference/cpp-api-neighbors-hnsw#cuvs-neighbors-hnsw-extend-params) | configure the extend | | `additional_dataset` | in | `raft::host_matrix_view` | a host matrix view to a row-major matrix [n_rows, index->dim()] | | `idx` | inout | `index&` | HNSW index to extend | @@ -500,7 +511,7 @@ Usage example: | Name | Direction | Type | Description | | --- | --- | --- | --- | | `res` | in | `raft::resources const&` | raft resources | -| `params` | in | `const extend_params&` | configure the extend | +| `params` | in | [`const extend_params&`](/api-reference/cpp-api-neighbors-hnsw#cuvs-neighbors-hnsw-extend-params) | configure the extend | | `additional_dataset` | in | `raft::host_matrix_view` | a host matrix view to a row-major matrix [n_rows, index->dim()] | | `idx` | inout | `index&` | HNSW index to extend | @@ -530,7 +541,7 @@ Usage example: | Name | Direction | Type | Description | | --- | --- | --- | --- | | `res` | in | `raft::resources const&` | raft resources | -| `params` | in | `const extend_params&` | configure the extend | +| `params` | in | [`const extend_params&`](/api-reference/cpp-api-neighbors-hnsw#cuvs-neighbors-hnsw-extend-params) | configure the extend | | `additional_dataset` | in | `raft::host_matrix_view` | a host matrix view to a row-major matrix [n_rows, index->dim()] | | `idx` | inout | `index&` | HNSW index to extend | @@ -560,7 +571,7 @@ Usage example: | Name | Direction | Type | Description | | --- | --- | --- | --- | | `res` | in | `raft::resources const&` | raft resources | -| `params` | in | `const extend_params&` | configure the extend | +| `params` | in | [`const extend_params&`](/api-reference/cpp-api-neighbors-hnsw#cuvs-neighbors-hnsw-extend-params) | configure the extend | | `additional_dataset` | in | `raft::host_matrix_view` | a host matrix view to a row-major matrix [n_rows, index->dim()] | | `idx` | inout | `index&` | HNSW index to extend | @@ -574,6 +585,7 @@ _Source: `cpp/include/cuvs/neighbors/hnsw.hpp:726`_ _Doxygen group: `hnsw_cpp_search_params`_ + ### cuvs::neighbors::hnsw::search_params Build CAGRA index and search with hnswlib @@ -595,6 +607,7 @@ _Source: `cpp/include/cuvs/neighbors/hnsw.hpp:740`_ _Doxygen group: `hnsw_cpp_index_search`_ + ### cuvs::neighbors::hnsw::search Search HNSW index constructed from a CAGRA index @@ -619,7 +632,7 @@ Usage example: | Name | Direction | Type | Description | | --- | --- | --- | --- | | `res` | in | `raft::resources const&` | raft resources | -| `params` | in | `const search_params&` | configure the search | +| `params` | in | [`const search_params&`](/api-reference/cpp-api-neighbors-hnsw#cuvs-neighbors-hnsw-search-params) | configure the search | | `idx` | in | `const index&` | cagra index | | `queries` | in | `raft::host_matrix_view` | a host matrix view to a row-major matrix [n_queries, index->dim()] | | `neighbors` | out | `raft::host_matrix_view` | a host matrix view to the indices of the neighbors in the source dataset | @@ -655,7 +668,7 @@ Usage example: | Name | Direction | Type | Description | | --- | --- | --- | --- | | `res` | in | `raft::resources const&` | raft resources | -| `params` | in | `const search_params&` | configure the search | +| `params` | in | [`const search_params&`](/api-reference/cpp-api-neighbors-hnsw#cuvs-neighbors-hnsw-search-params) | configure the search | | `idx` | in | `const index&` | cagra index | | `queries` | in | `raft::host_matrix_view` | a host matrix view to a row-major matrix [n_queries, index->dim()] | | `neighbors` | out | `raft::host_matrix_view` | a host matrix view to the indices of the neighbors in the source dataset | @@ -691,7 +704,7 @@ Usage example: | Name | Direction | Type | Description | | --- | --- | --- | --- | | `res` | in | `raft::resources const&` | raft resources | -| `params` | in | `const search_params&` | configure the search | +| `params` | in | [`const search_params&`](/api-reference/cpp-api-neighbors-hnsw#cuvs-neighbors-hnsw-search-params) | configure the search | | `idx` | in | `const index&` | cagra index | | `queries` | in | `raft::host_matrix_view` | a host matrix view to a row-major matrix [n_queries, index->dim()] | | `neighbors` | out | `raft::host_matrix_view` | a host matrix view to the indices of the neighbors in the source dataset | @@ -727,7 +740,7 @@ Usage example: | Name | Direction | Type | Description | | --- | --- | --- | --- | | `res` | in | `raft::resources const&` | raft resources | -| `params` | in | `const search_params&` | configure the search | +| `params` | in | [`const search_params&`](/api-reference/cpp-api-neighbors-hnsw#cuvs-neighbors-hnsw-search-params) | configure the search | | `idx` | in | `const index&` | cagra index | | `queries` | in | `raft::host_matrix_view` | a host matrix view to a row-major matrix [n_queries, index->dim()] | | `neighbors` | out | `raft::host_matrix_view` | a host matrix view to the indices of the neighbors in the source dataset | @@ -743,6 +756,7 @@ _Source: `cpp/include/cuvs/neighbors/hnsw.hpp:926`_ _Doxygen group: `hnsw_cpp_index_serialize`_ + ### cuvs::neighbors::hnsw::serialize Serialize the HNSW index to file @@ -847,6 +861,7 @@ Usage example: _Source: `cpp/include/cuvs/neighbors/hnsw.hpp:1056`_ + ### cuvs::neighbors::hnsw::deserialize De-serialize a CAGRA index saved to a file as an hnswlib index @@ -872,7 +887,7 @@ Usage example: | `params` | in | `const index_params&` | hnsw index parameters | | `filename` | in | `const std::string&` | path to the file containing the serialized CAGRA index | | `dim` | in | `int` | dimensions of the training dataset | -| `metric` | in | `cuvs::distance::DistanceType` | distance metric to search. Supported metrics ("L2Expanded", "InnerProduct") | +| `metric` | in | [`cuvs::distance::DistanceType`](/api-reference/cpp-api-distance-distance#cuvs-distance-distancetype) | distance metric to search. Supported metrics ("L2Expanded", "InnerProduct") | | `index` | out | `index**` | hnsw index | **Returns** @@ -906,7 +921,7 @@ Usage example: | `params` | in | `const index_params&` | hnsw index parameters | | `filename` | in | `const std::string&` | path to the file containing the serialized CAGRA index | | `dim` | in | `int` | dimensions of the training dataset | -| `metric` | in | `cuvs::distance::DistanceType` | distance metric to search. Supported metrics ("L2Expanded", "InnerProduct") | +| `metric` | in | [`cuvs::distance::DistanceType`](/api-reference/cpp-api-distance-distance#cuvs-distance-distancetype) | distance metric to search. Supported metrics ("L2Expanded", "InnerProduct") | | `index` | out | `index**` | hnsw index | **Returns** @@ -940,7 +955,7 @@ Usage example: | `params` | in | `const index_params&` | hnsw index parameters | | `filename` | in | `const std::string&` | path to the file containing the serialized CAGRA index | | `dim` | in | `int` | dimensions of the training dataset | -| `metric` | in | `cuvs::distance::DistanceType` | distance metric to search. Supported metrics ("L2Expanded", "InnerProduct") | +| `metric` | in | [`cuvs::distance::DistanceType`](/api-reference/cpp-api-distance-distance#cuvs-distance-distancetype) | distance metric to search. Supported metrics ("L2Expanded", "InnerProduct") | | `index` | out | `index**` | hnsw index | **Returns** @@ -974,7 +989,7 @@ Usage example: | `params` | in | `const index_params&` | hnsw index parameters | | `filename` | in | `const std::string&` | path to the file containing the serialized CAGRA index | | `dim` | in | `int` | dimensions of the training dataset | -| `metric` | in | `cuvs::distance::DistanceType` | distance metric to search. Supported metrics ("L2Expanded", "InnerProduct") | +| `metric` | in | [`cuvs::distance::DistanceType`](/api-reference/cpp-api-distance-distance#cuvs-distance-distancetype) | distance metric to search. Supported metrics ("L2Expanded", "InnerProduct") | | `index` | out | `index**` | hnsw index | **Returns** diff --git a/fern/pages/cpp_api/cpp-api-neighbors-ivf-flat.md b/fern/pages/cpp_api/cpp-api-neighbors-ivf-flat.md index 8b2896d7d4..b068c1a660 100644 --- a/fern/pages/cpp_api/cpp-api-neighbors-ivf-flat.md +++ b/fern/pages/cpp_api/cpp-api-neighbors-ivf-flat.md @@ -10,6 +10,7 @@ _Source header: `cpp/include/cuvs/neighbors/ivf_flat.hpp`_ _Doxygen group: `ivf_flat_cpp_search_params`_ + ### cuvs::neighbors::ivf_flat::search_params IVF-Flat index search parameters @@ -27,6 +28,7 @@ struct search_params : cuvs::neighbors::search_params { ... } ; _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:73`_ + ### cuvs::neighbors::ivf_flat::make_list_extents Determine the extents of an array enough to hold a given amount of data. @@ -43,7 +45,7 @@ constexpr auto make_list_extents(SizeT n_rows) const -> list_extents; **Returns** -`list_extents` +[`list_extents`](/api-reference/cpp-api-neighbors-ivf-pq#list-extents) _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:108`_ @@ -51,6 +53,7 @@ _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:108`_ _Doxygen group: `ivf_flat_cpp_index`_ + ### cuvs::neighbors::ivf_flat::index Construct an empty index. @@ -113,7 +116,7 @@ uint32_t dim); | Name | Direction | Type | Description | | --- | --- | --- | --- | | `res` | | `raft::resources const&` | | -| `metric` | | `cuvs::distance::DistanceType` | | +| `metric` | | [`cuvs::distance::DistanceType`](/api-reference/cpp-api-distance-distance#cuvs-distance-distancetype) | | | `n_lists` | | `uint32_t` | | | `adaptive_centers` | | `bool` | | | `conservative_memory_allocation` | | `bool` | | @@ -125,6 +128,7 @@ uint32_t dim); _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:159`_ + ### cuvs::neighbors::ivf_flat::veclen Vectorized load/store size in elements, determines the size of interleaved data chunks. @@ -139,6 +143,7 @@ uint32_t veclen() const noexcept; _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:169`_ + ### cuvs::neighbors::ivf_flat::metric Distance metric used for clustering. @@ -149,10 +154,11 @@ cuvs::distance::DistanceType metric() const noexcept; **Returns** -`cuvs::distance::DistanceType` +[`cuvs::distance::DistanceType`](/api-reference/cpp-api-distance-distance#cuvs-distance-distancetype) _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:172`_ + ### cuvs::neighbors::ivf_flat::adaptive_centers Whether `centers()` change upon extending the index (ivf_flat::extend). @@ -167,6 +173,7 @@ bool adaptive_centers() const noexcept; _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:175`_ + ### cuvs::neighbors::ivf_flat::list_sizes Sizes of the lists (clusters) [n_lists] @@ -183,6 +190,7 @@ NB: This may differ from the actual list size if the shared lists have been exte _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:204`_ + ### cuvs::neighbors::ivf_flat::centers k-means cluster centers corresponding to the lists [n_lists, dim] @@ -197,6 +205,7 @@ raft::device_matrix_view centers() noexcept; _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:208`_ + ### cuvs::neighbors::ivf_flat::center_norms (Optional) Precomputed norms of the `centers` w.r.t. the chosen distance metric [n_lists]. @@ -213,6 +222,7 @@ NB: this may be empty if the index is empty or if the metric does not require th _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:217`_ + ### cuvs::neighbors::ivf_flat::accum_sorted_sizes Accumulated list sizes, sorted in descending order [n_lists + 1]. @@ -233,6 +243,7 @@ This span is used during search to estimate the maximum size of the workspace. _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:229`_ + ### cuvs::neighbors::ivf_flat::size Total length of the index. @@ -247,6 +258,7 @@ IdxT size() const noexcept; _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:234`_ + ### cuvs::neighbors::ivf_flat::dim Dimensionality of the data. @@ -261,6 +273,7 @@ uint32_t dim() const noexcept; _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:237`_ + ### cuvs::neighbors::ivf_flat::n_lists Number of clusters/inverted lists. @@ -275,6 +288,7 @@ uint32_t n_lists() const noexcept; _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:240`_ + ### cuvs::neighbors::ivf_flat::inds_ptrs Pointers to the inverted lists (clusters) indices [n_lists]. @@ -289,6 +303,7 @@ raft::device_vector_view inds_ptrs() noexcept; _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:245`_ + ### cuvs::neighbors::ivf_flat::conservative_memory_allocation Whether to use conservative memory allocation when extending the list (cluster) data @@ -305,6 +320,7 @@ bool conservative_memory_allocation() const noexcept; _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:252`_ + ### cuvs::neighbors::ivf_flat::lists Lists' data and indices. @@ -323,6 +339,7 @@ _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:257`_ _Doxygen group: `ivf_flat_cpp_index_build`_ + ### cuvs::neighbors::ivf_flat::build Build the index from the dataset for efficient search. @@ -911,6 +928,7 @@ _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:824`_ _Doxygen group: `ivf_flat_cpp_index_extend`_ + ### cuvs::neighbors::ivf_flat::extend Build a new index containing the data of the original plus new extra vectors. @@ -1419,6 +1437,7 @@ _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:1393`_ _Doxygen group: `ivf_flat_cpp_serialize`_ + ### cuvs::neighbors::ivf_flat::serialize Save the index to file. @@ -1445,6 +1464,7 @@ Experimental, both the API and the serialization format are subject to change. _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:1612`_ + ### cuvs::neighbors::ivf_flat::deserialize Load index from file. @@ -1839,6 +1859,7 @@ _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:2018`_ _Doxygen group: `ivf_flat_helpers`_ + ### namespace codepacker \{ Helper functions for IVF Flat @@ -1849,6 +1870,7 @@ namespace codepacker { _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:2484`_ + ### codepacker::pack Write flat codes into an existing list by the given offset. @@ -1875,7 +1897,7 @@ Usage example: | `codes` | in | `raft::device_matrix_view` | flat codes [n_vec, dim] | | `veclen` | in | `uint32_t` | size of interleaved data chunks | | `offset` | in | `uint32_t` | how many records to skip before writing the data into the list | -| `list_data` | inout | `raft::device_mdspan::list_extents, raft::row_major>` | block to write into | +| `list_data` | inout | [`raft::device_mdspan::list_extents, raft::row_major>`](/api-reference/cpp-api-neighbors-ivf-pq#list-extents) | block to write into | **Returns** @@ -1909,7 +1931,7 @@ Usage example: | `codes` | in | `raft::device_matrix_view` | flat codes [n_vec, dim] | | `veclen` | in | `uint32_t` | size of interleaved data chunks | | `offset` | in | `uint32_t` | how many records to skip before writing the data into the list | -| `list_data` | inout | `raft::device_mdspan::list_extents, raft::row_major>` | block to write into | +| `list_data` | inout | [`raft::device_mdspan::list_extents, raft::row_major>`](/api-reference/cpp-api-neighbors-ivf-pq#list-extents) | block to write into | **Returns** @@ -1943,7 +1965,7 @@ Usage example: | `codes` | in | `raft::device_matrix_view` | flat codes [n_vec, dim] | | `veclen` | in | `uint32_t` | size of interleaved data chunks | | `offset` | in | `uint32_t` | how many records to skip before writing the data into the list | -| `list_data` | inout | `raft::device_mdspan::list_extents, raft::row_major>` | block to write into | +| `list_data` | inout | [`raft::device_mdspan::list_extents, raft::row_major>`](/api-reference/cpp-api-neighbors-ivf-pq#list-extents) | block to write into | **Returns** @@ -1977,7 +1999,7 @@ Usage example: | `codes` | in | `raft::device_matrix_view` | flat codes [n_vec, dim] | | `veclen` | in | `uint32_t` | size of interleaved data chunks | | `offset` | in | `uint32_t` | how many records to skip before writing the data into the list | -| `list_data` | inout | `raft::device_mdspan::list_extents, raft::row_major>` | block to write into | +| `list_data` | inout | [`raft::device_mdspan::list_extents, raft::row_major>`](/api-reference/cpp-api-neighbors-ivf-pq#list-extents) | block to write into | **Returns** @@ -1985,6 +2007,7 @@ Usage example: _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:2598`_ + ### codepacker::unpack Unpack `n_take` consecutive records of a single list (cluster) in the compressed index @@ -2008,7 +2031,7 @@ Usage example: | Name | Direction | Type | Description | | --- | --- | --- | --- | | `res` | in | `raft::resources const&` | raft resource | -| `list_data` | in | `raft::device_mdspan::list_extents, raft::row_major>` | block to read from | +| `list_data` | in | [`raft::device_mdspan::list_extents, raft::row_major>`](/api-reference/cpp-api-neighbors-ivf-pq#list-extents) | block to read from | | `veclen` | in | `uint32_t` | size of interleaved data chunks | | `offset` | in | `uint32_t` | How many records in the list to skip. | | `codes` | inout | `raft::device_matrix_view` | the destination buffer [n_take, index.dim()]. The length `n_take` defines how many records to unpack, it must be <= the list size. | @@ -2042,7 +2065,7 @@ Usage example: | Name | Direction | Type | Description | | --- | --- | --- | --- | | `res` | in | `raft::resources const&` | raft resource | -| `list_data` | in | `raft::device_mdspan::list_extents, raft::row_major>` | block to read from | +| `list_data` | in | [`raft::device_mdspan::list_extents, raft::row_major>`](/api-reference/cpp-api-neighbors-ivf-pq#list-extents) | block to read from | | `veclen` | in | `uint32_t` | size of interleaved data chunks | | `offset` | in | `uint32_t` | How many records in the list to skip. | | `codes` | inout | `raft::device_matrix_view` | the destination buffer [n_take, index.dim()]. The length `n_take` defines how many records to unpack, it must be <= the list size. | @@ -2076,7 +2099,7 @@ Usage example: | Name | Direction | Type | Description | | --- | --- | --- | --- | | `res` | in | `raft::resources const&` | raft resource | -| `list_data` | in | `raft::device_mdspan::list_extents, raft::row_major>` | block to read from | +| `list_data` | in | [`raft::device_mdspan::list_extents, raft::row_major>`](/api-reference/cpp-api-neighbors-ivf-pq#list-extents) | block to read from | | `veclen` | in | `uint32_t` | size of interleaved data chunks | | `offset` | in | `uint32_t` | How many records in the list to skip. | | `codes` | inout | `raft::device_matrix_view` | the destination buffer [n_take, index.dim()]. The length `n_take` defines how many records to unpack, it must be <= the list size. | @@ -2110,7 +2133,7 @@ Usage example: | Name | Direction | Type | Description | | --- | --- | --- | --- | | `res` | in | `raft::resources const&` | raft resource | -| `list_data` | in | `raft::device_mdspan::list_extents, raft::row_major>` | block to read from | +| `list_data` | in | [`raft::device_mdspan::list_extents, raft::row_major>`](/api-reference/cpp-api-neighbors-ivf-pq#list-extents) | block to read from | | `veclen` | in | `uint32_t` | size of interleaved data chunks | | `offset` | in | `uint32_t` | How many records in the list to skip. | | `codes` | inout | `raft::device_matrix_view` | the destination buffer [n_take, index.dim()]. The length `n_take` defines how many records to unpack, it must be <= the list size. | @@ -2121,6 +2144,7 @@ Usage example: _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:2729`_ + ### codepacker::pack_1 Write one flat code into a block by the given offset. The offset indicates the id of the record @@ -2226,6 +2250,7 @@ in the list. This function interleaves the code and is intended to later copy th _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:2791`_ + ### codepacker::unpack_1 Unpack 1 record of a single list (cluster) in the index to fetch the flat code. The offset @@ -2340,6 +2365,7 @@ interleaved format. _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:2845`_ + ### codepacker::reset_index Public helper API to reset the data and indices ptrs, and the list sizes. Useful for @@ -2440,6 +2466,7 @@ Usage example: _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:2936`_ + ### codepacker::recompute_internal_state Helper exposing the re-computation of list sizes and related arrays if IVF lists have been diff --git a/fern/pages/cpp_api/cpp-api-neighbors-ivf-pq.md b/fern/pages/cpp_api/cpp-api-neighbors-ivf-pq.md index a0c1b34bd4..4d6cc919a0 100644 --- a/fern/pages/cpp_api/cpp-api-neighbors-ivf-pq.md +++ b/fern/pages/cpp_api/cpp-api-neighbors-ivf-pq.md @@ -10,6 +10,7 @@ _Source header: `cpp/include/cuvs/neighbors/ivf_pq.hpp`_ _Doxygen group: `ivf_pq_cpp_index_params`_ + ### cuvs::neighbors::ivf_pq::codebook_gen A type for specifying how PQ codebooks are created. @@ -20,6 +21,7 @@ enum class codebook_gen { ... } ; _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:31`_ + ### cuvs::neighbors::ivf_pq::list_layout A type for specifying the memory layout of PQ codes in IVF lists. @@ -30,6 +32,7 @@ enum class list_layout { ... } ; _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:37`_ + ### cuvs::neighbors::ivf_pq::from_dataset Creates index_params based on shape of the input dataset. @@ -47,7 +50,7 @@ Usage example: | Name | Direction | Type | Description | | --- | --- | --- | --- | | `dataset` | | `raft::matrix_extent` | | -| `metric` | | `cuvs::distance::DistanceType` | Default: `cuvs::distance::DistanceType::L2Expanded`. | +| `metric` | | [`cuvs::distance::DistanceType`](/api-reference/cpp-api-distance-distance#cuvs-distance-distancetype) | Default: `cuvs::distance::DistanceType::L2Expanded`. | **Returns** @@ -59,6 +62,7 @@ _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:145`_ _Doxygen group: `ivf_pq_cpp_search_params`_ + ### cuvs::neighbors::ivf_pq::search_params IVF-PQ index search parameters @@ -80,10 +84,44 @@ struct search_params : cuvs::neighbors::search_params { ... } ; _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:157`_ +## Types + + +### list_extents + +PQ-encoded data stored in the interleaved format: + +```cpp +using list_extents = raft:: +extents; +``` + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:243`_ + + +### cuvs::neighbors::graph_build_params::ivf_pq_params + +Specialized parameters utilizing IVF-PQ to build knn graph + +```cpp +struct ivf_pq_params { ... } ; +``` + +**Fields** + +| Name | Type | Description | +| --- | --- | --- | +| `build_params` | `cuvs::neighbors::ivf_pq::` | | +| `search_params` | `cuvs::neighbors::ivf_pq::` | | +| `refinement_rate` | `float` | | + +_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:3364`_ + ## IVF-PQ index _Doxygen group: `ivf_pq_cpp_index`_ + ### cuvs::neighbors::ivf_pq::index Construct an empty index. @@ -128,8 +166,8 @@ This constructor creates an owning index with the given parameters. | Name | Direction | Type | Description | | --- | --- | --- | --- | | `handle` | | `raft::resources const&` | RAFT resources handle | -| `metric` | | `cuvs::distance::DistanceType` | Distance metric for clustering | -| `codebook_kind` | | `codebook_gen` | How PQ codebooks are created | +| `metric` | | [`cuvs::distance::DistanceType`](/api-reference/cpp-api-distance-distance#cuvs-distance-distancetype) | Distance metric for clustering | +| `codebook_kind` | | [`codebook_gen`](/api-reference/cpp-api-neighbors-ivf-pq#cuvs-neighbors-ivf-pq-codebook-gen) | How PQ codebooks are created | | `n_lists` | | `uint32_t` | Number of inverted lists (clusters) | | `dim` | | `uint32_t` | Dimensionality of the input data | | `pq_bits` | | `uint32_t` | Bit length of vector elements after PQ compression Default: `8`. | @@ -164,6 +202,7 @@ index(raft::resources const& handle, const index_params& params, uint32_t dim); _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:525`_ + ### cuvs::neighbors::ivf_pq::size Total length of the index. @@ -178,6 +217,7 @@ IdxT size() const noexcept override; _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:528`_ + ### cuvs::neighbors::ivf_pq::dim Dimensionality of the input data. @@ -192,6 +232,7 @@ uint32_t dim() const noexcept override; _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:531`_ + ### cuvs::neighbors::ivf_pq::dim_ext Dimensionality of the cluster centers: @@ -208,6 +249,7 @@ input data dim extended with vector norms and padded to 8 elems. _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:537`_ + ### cuvs::neighbors::ivf_pq::rot_dim Dimensionality of the data after transforming it for PQ processing @@ -224,6 +266,7 @@ uint32_t rot_dim() const noexcept; _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:543`_ + ### cuvs::neighbors::ivf_pq::pq_bits The bit length of an encoded vector element after compression by PQ. @@ -238,6 +281,7 @@ uint32_t pq_bits() const noexcept override; _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:546`_ + ### cuvs::neighbors::ivf_pq::pq_dim The dimensionality of an encoded vector after compression by PQ. @@ -252,6 +296,7 @@ uint32_t pq_dim() const noexcept override; _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:549`_ + ### cuvs::neighbors::ivf_pq::pq_len Dimensionality of a subspace, i.e. the number of vector components mapped to a subspace @@ -266,6 +311,7 @@ uint32_t pq_len() const noexcept; _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:552`_ + ### cuvs::neighbors::ivf_pq::pq_book_size The number of vectors in a PQ codebook (`1 << pq_bits`). @@ -280,6 +326,7 @@ uint32_t pq_book_size() const noexcept; _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:555`_ + ### cuvs::neighbors::ivf_pq::metric Distance metric used for clustering. @@ -290,10 +337,11 @@ cuvs::distance::DistanceType metric() const noexcept override; **Returns** -`cuvs::distance::DistanceType` +[`cuvs::distance::DistanceType`](/api-reference/cpp-api-distance-distance#cuvs-distance-distancetype) _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:558`_ + ### cuvs::neighbors::ivf_pq::codebook_kind How PQ codebooks are created. @@ -304,10 +352,11 @@ codebook_gen codebook_kind() const noexcept override; **Returns** -`codebook_gen` +[`codebook_gen`](/api-reference/cpp-api-neighbors-ivf-pq#cuvs-neighbors-ivf-pq-codebook-gen) _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:561`_ + ### cuvs::neighbors::ivf_pq::codes_layout Memory layout of PQ codes in IVF lists. @@ -318,10 +367,11 @@ list_layout codes_layout() const noexcept override; **Returns** -`list_layout` +[`list_layout`](/api-reference/cpp-api-neighbors-ivf-pq#cuvs-neighbors-ivf-pq-list-layout) _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:564`_ + ### cuvs::neighbors::ivf_pq::n_lists Number of clusters/inverted lists (first level quantization). @@ -336,6 +386,7 @@ uint32_t n_lists() const noexcept; _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:567`_ + ### cuvs::neighbors::ivf_pq::conservative_memory_allocation Whether to use conservative memory allocation when extending the list (cluster) data @@ -352,6 +403,7 @@ bool conservative_memory_allocation() const noexcept override; _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:573`_ + ### cuvs::neighbors::ivf_pq::pq_centers PQ cluster centers @@ -370,6 +422,7 @@ const noexcept override; _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:581`_ + ### cuvs::neighbors::ivf_pq::lists Lists' data and indices (polymorphic, works for both FLAT and INTERLEAVED layouts). @@ -384,6 +437,7 @@ std::vector>>& lists() noexcept override; _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:585`_ + ### cuvs::neighbors::ivf_pq::data_ptrs Pointers to the inverted lists (clusters) data [n_lists]. @@ -398,6 +452,7 @@ raft::device_vector_view data_ptrs() noexce _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:589`_ + ### cuvs::neighbors::ivf_pq::inds_ptrs Pointers to the inverted lists (clusters) indices [n_lists]. @@ -412,6 +467,7 @@ raft::device_vector_view inds_ptrs() noexcept _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:594`_ + ### cuvs::neighbors::ivf_pq::rotation_matrix The transform matrix (original space -> rotated padded space) [rot_dim, dim] @@ -427,6 +483,7 @@ const noexcept override; _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:599`_ + ### cuvs::neighbors::ivf_pq::accum_sorted_sizes Accumulated list sizes, sorted in descending order [n_lists + 1]. @@ -447,6 +504,7 @@ This span is used during search to estimate the maximum size of the workspace. _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:616`_ + ### cuvs::neighbors::ivf_pq::list_sizes Sizes of the lists [n_lists]. @@ -461,6 +519,7 @@ raft::device_vector_view list_sizes() noexc _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:621`_ + ### cuvs::neighbors::ivf_pq::centers Cluster centers corresponding to the lists in the original space [n_lists, dim_ext] @@ -476,6 +535,7 @@ const noexcept override; _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:626`_ + ### cuvs::neighbors::ivf_pq::centers_rot Cluster centers corresponding to the lists in the rotated space [n_lists, rot_dim] @@ -491,6 +551,7 @@ const noexcept override; _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:635`_ + ### cuvs::neighbors::ivf_pq::get_list_size_in_bytes fetch size of a particular IVF list in bytes using the list extents. @@ -539,6 +600,7 @@ _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:663`_ _Doxygen group: `ivf_pq_cpp_index_build`_ + ### cuvs::neighbors::ivf_pq::build Build the index from the dataset for efficient search. @@ -1225,6 +1287,7 @@ _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:1253`_ _Doxygen group: `ivf_pq_cpp_index_extend`_ + ### cuvs::neighbors::ivf_pq::extend Extend the index with the new data. @@ -1701,6 +1764,7 @@ _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:1770`_ _Doxygen group: `ivf_pq_cpp_transform`_ + ### cuvs::neighbors::ivf_pq::transform Transform a dataset by applying pq-encoding to each vector @@ -1813,6 +1877,7 @@ _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:1999`_ _Doxygen group: `ivf_pq_cpp_serialize`_ + ### cuvs::neighbors::ivf_pq::serialize Write the index to an output stream @@ -1861,6 +1926,7 @@ const cuvs::neighbors::ivf_pq::index& index); _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:2054`_ + ### cuvs::neighbors::ivf_pq::deserialize Load index from input stream @@ -1913,6 +1979,7 @@ _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:2106`_ _Doxygen group: `ivf_pq_cpp_helpers`_ + ### namespace codepacker \{ IVF-PQ helper methods @@ -1923,6 +1990,7 @@ namespace codepacker { _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:2561`_ + ### codepacker::unpack Unpack `n_take` consecutive records of a single list (cluster) in the compressed index @@ -1948,7 +2016,7 @@ Usage example: | Name | Direction | Type | Description | | --- | --- | --- | --- | | `res` | in | `raft::resources const&` | raft resource | -| `list_data` | in | `raft::device_mdspan::list_extents, raft::row_major>` | block to read from | +| `list_data` | in | [`raft::device_mdspan::list_extents, raft::row_major>`](/api-reference/cpp-api-neighbors-ivf-pq#list-extents) | block to read from | | `pq_bits` | in | `uint32_t` | bit length of encoded vector elements | | `offset` | in | `uint32_t` | How many records in the list to skip. | | `codes` | out | `raft::device_matrix_view` | the destination buffer [n_take, index.pq_dim()]. The length `n_take` defines how many records to unpack, it must be smaller than the list size. | @@ -1959,6 +2027,7 @@ Usage example: _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:2594`_ + ### codepacker::unpack_contiguous Unpack `n_rows` consecutive records of a single list (cluster) in the compressed index @@ -1984,7 +2053,7 @@ Usage example: | Name | Direction | Type | Description | | --- | --- | --- | --- | | `res` | in | `raft::resources const&` | raft resource | -| `list_data` | in | `raft::device_mdspan::list_extents, raft::row_major>` | block to read from | +| `list_data` | in | [`raft::device_mdspan::list_extents, raft::row_major>`](/api-reference/cpp-api-neighbors-ivf-pq#list-extents) | block to read from | | `pq_bits` | in | `uint32_t` | bit length of encoded vector elements | | `offset` | in | `uint32_t` | How many records in the list to skip. | | `n_rows` | in | `uint32_t` | How many records to unpack | @@ -1997,6 +2066,7 @@ Usage example: _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:2634`_ + ### codepacker::pack Write flat PQ codes into an existing list by the given offset. @@ -2023,7 +2093,7 @@ Usage example: | `codes` | in | `raft::device_matrix_view` | flat PQ codes, one code per byte [n_vec, pq_dim] | | `pq_bits` | in | `uint32_t` | bit length of encoded vector elements | | `offset` | in | `uint32_t` | how many records to skip before writing the data into the list | -| `list_data` | in | `raft::device_mdspan::list_extents, raft::row_major>` | block to write into | +| `list_data` | in | [`raft::device_mdspan::list_extents, raft::row_major>`](/api-reference/cpp-api-neighbors-ivf-pq#list-extents) | block to write into | **Returns** @@ -2031,6 +2101,7 @@ Usage example: _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:2666`_ + ### codepacker::pack_contiguous Write flat PQ codes into an existing list by the given offset. The input codes of a single vector @@ -2063,7 +2134,7 @@ Usage example: | `pq_dim` | in | `uint32_t` | | | `pq_bits` | in | `uint32_t` | bit length of encoded vector elements | | `offset` | in | `uint32_t` | how many records to skip before writing the data into the list | -| `list_data` | in | `raft::device_mdspan::list_extents, raft::row_major>` | block to write into | +| `list_data` | in | [`raft::device_mdspan::list_extents, raft::row_major>`](/api-reference/cpp-api-neighbors-ivf-pq#list-extents) | block to write into | **Returns** @@ -2071,6 +2142,7 @@ Usage example: _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:2702`_ + ### codepacker::pack_list_data Write flat PQ codes into an existing list by the given offset. @@ -2105,6 +2177,7 @@ Usage example: _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:2736`_ + ### codepacker::pack_contiguous_list_data Write flat PQ codes into an existing list by the given offset. Use this when the input @@ -2143,6 +2216,7 @@ Usage example: _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:2779`_ + ### codepacker::unpack_list_data Unpack `n_take` consecutive records of a single list (cluster) in the compressed index @@ -2207,6 +2281,7 @@ Usage example: _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:2851`_ + ### codepacker::unpack_contiguous_list_data Unpack `n_rows` consecutive PQ encoded vectors of a single list (cluster) in the @@ -2241,6 +2316,7 @@ Usage example: _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:2892`_ + ### codepacker::reconstruct_list_data Decode `n_take` consecutive records of a single list (cluster) in the compressed index @@ -2305,6 +2381,7 @@ Usage example: _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:2984`_ + ### codepacker::extend_list_with_codes Extend one list of the index in-place, by the list label, skipping the classification and @@ -2338,6 +2415,7 @@ Usage example: _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:3032`_ + ### codepacker::extend_list_with_contiguous_codes Extend one list of the index in-place, by the list label, skipping the classification and @@ -2373,6 +2451,7 @@ Usage example: _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:3071`_ + ### codepacker::extend_list Extend one list of the index in-place, by the list label, skipping the classification @@ -2405,6 +2484,7 @@ Usage example: _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:3106`_ + ### codepacker::erase_list Remove all data from a single list (cluster) in the index. @@ -2429,6 +2509,7 @@ Usage example: _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:3141`_ + ### codepacker::reset_index Public helper API to reset the data and indices ptrs, and the list sizes. Useful for @@ -2454,6 +2535,7 @@ Usage example: _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:3163`_ + ### codepacker::pad_centers_with_norms Pad cluster centers with their L2 norms for efficient GEMM operations. @@ -2508,6 +2590,7 @@ This function takes cluster centers and pads them with their L2 norms to create _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:3192`_ + ### codepacker::rotate_padded_centers Rotate padded centers with the rotation matrix. @@ -2535,6 +2618,7 @@ raft::device_matrix_view rotated_centers); _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:3205`_ + ### codepacker::extract_centers Public helper API for fetching a trained index's IVF centroids @@ -2583,6 +2667,7 @@ raft::host_matrix_view cluster_centers); _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:3233`_ + ### codepacker::recompute_internal_state Helper exposing the re-computation of list sizes and related arrays if IVF lists have been @@ -2608,6 +2693,7 @@ Usage example: _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:3262`_ + ### codepacker::make_rotation_matrix Generate a rotation matrix into user-provided buffer (standalone version). @@ -2637,6 +2723,7 @@ Usage example: _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:3289`_ + ### codepacker::resize_list Resize an IVF-PQ list with flat layout. diff --git a/fern/pages/cpp_api/cpp-api-neighbors-nn-descent.md b/fern/pages/cpp_api/cpp-api-neighbors-nn-descent.md index b66e54eefd..4646e77cbe 100644 --- a/fern/pages/cpp_api/cpp-api-neighbors-nn-descent.md +++ b/fern/pages/cpp_api/cpp-api-neighbors-nn-descent.md @@ -10,6 +10,7 @@ _Source header: `cpp/include/cuvs/neighbors/nn_descent.hpp`_ _Doxygen group: `nn_descent_cpp_index_params`_ + ### cuvs::neighbors::nn_descent::DIST_COMP_DTYPE Dtype to use for distance computation @@ -28,6 +29,7 @@ enum class DIST_COMP_DTYPE { ... } ; _Source: `cpp/include/cuvs/neighbors/nn_descent.hpp:35`_ + ### cuvs::neighbors::nn_descent::index_params Parameters used to build an nn-descent index @@ -45,7 +47,7 @@ struct index_params : cuvs::neighbors::index_params { ... } ; | `max_iterations` | `size_t` | The number of iterations that nn-descent will refine the graph for. More iterations produce a better quality graph at cost of performance | | `termination_threshold` | `float` | The delta at which nn-descent will terminate its iterations | | `return_distances` | `bool` | Boolean to decide whether to return distances array | -| `dist_comp_dtype` | `DIST_COMP_DTYPE` | dtype to use for distance computation. Defaults to `AUTO` which automatically determines the best dtype for distance computation based on the dataset dimensions. Use `FP32` for better precision at the cost of performance and memory usage. This option is only valid when data type is fp32. Use `FP16` for better performance and memory usage at the cost of precision. | +| `dist_comp_dtype` | [`DIST_COMP_DTYPE`](/api-reference/cpp-api-neighbors-nn-descent#cuvs-neighbors-nn-descent-dist-comp-dtype) | dtype to use for distance computation. Defaults to `AUTO` which automatically determines the best dtype for distance computation based on the dataset dimensions. Use `FP32` for better precision at the cost of performance and memory usage. This option is only valid when data type is fp32. Use `FP16` for better performance and memory usage at the cost of precision. | _Source: `cpp/include/cuvs/neighbors/nn_descent.hpp:56`_ @@ -63,7 +65,7 @@ cuvs::distance::DistanceType metric = cuvs::distance::DistanceType::L2Expanded); | Name | Direction | Type | Description | | --- | --- | --- | --- | | `graph_degree` | | `size_t` | output graph degree Default: `64`. | -| `metric` | | `cuvs::distance::DistanceType` | distance metric to use Default: `cuvs::distance::DistanceType::L2Expanded`. | +| `metric` | | [`cuvs::distance::DistanceType`](/api-reference/cpp-api-distance-distance#cuvs-distance-distancetype) | distance metric to use Default: `cuvs::distance::DistanceType::L2Expanded`. | **Returns** @@ -75,6 +77,7 @@ _Source: `cpp/include/cuvs/neighbors/nn_descent.hpp:69`_ _Doxygen group: `nn_descent_cpp_index`_ + ### cuvs::neighbors::nn_descent::index Construct a new index object @@ -98,7 +101,7 @@ This constructor creates an nn-descent index which is a knn-graph in host memory | `n_rows` | | `int64_t` | number of rows in knn-graph | | `n_cols` | | `int64_t` | number of cols in knn-graph | | `return_distances` | | `bool` | whether to return distances Default: `false`. | -| `metric` | | `cuvs::distance::DistanceType` | distance metric to use Default: `cuvs::distance::DistanceType::L2Expanded`. | +| `metric` | | [`cuvs::distance::DistanceType`](/api-reference/cpp-api-distance-distance#cuvs-distance-distancetype) | distance metric to use Default: `cuvs::distance::DistanceType::L2Expanded`. | **Returns** @@ -130,7 +133,7 @@ distances | `res` | | `raft::resources const&` | raft::resources is an object managing resources | | `graph_view` | | `raft::host_matrix_view` | raft::host_matrix_view<IdxT, int64_t, raft::row_major> for storing knn-graph | | `distances_view` | | `std::optional>` | optional raft::device_matrix_view<float, int64_t, row_major> for storing Default: `std::nullopt`. | -| `metric` | | `cuvs::distance::DistanceType` | distance metric to use Default: `cuvs::distance::DistanceType::L2Expanded`. | +| `metric` | | [`cuvs::distance::DistanceType`](/api-reference/cpp-api-distance-distance#cuvs-distance-distancetype) | distance metric to use Default: `cuvs::distance::DistanceType::L2Expanded`. | **Returns** @@ -138,6 +141,7 @@ distances _Source: `cpp/include/cuvs/neighbors/nn_descent.hpp:141`_ + ### cuvs::neighbors::nn_descent::metric Distance metric used for clustering. @@ -148,10 +152,11 @@ Distance metric used for clustering. **Returns** -`cuvs::distance::DistanceType` +[`cuvs::distance::DistanceType`](/api-reference/cpp-api-distance-distance#cuvs-distance-distancetype) _Source: `cpp/include/cuvs/neighbors/nn_descent.hpp:157`_ + ### cuvs::neighbors::nn_descent::size Total length of the index (number of vectors). @@ -166,6 +171,7 @@ Total length of the index (number of vectors). _Source: `cpp/include/cuvs/neighbors/nn_descent.hpp:163`_ + ### cuvs::neighbors::nn_descent::graph_degree Graph degree @@ -180,6 +186,7 @@ Graph degree _Source: `cpp/include/cuvs/neighbors/nn_descent.hpp:169`_ + ### cuvs::neighbors::nn_descent::graph neighborhood graph [size, graph-degree] @@ -195,6 +202,7 @@ neighborhood graph [size, graph-degree] _Source: `cpp/include/cuvs/neighbors/nn_descent.hpp:175`_ + ### cuvs::neighbors::nn_descent::distances neighborhood graph distances [size, graph-degree] @@ -214,6 +222,7 @@ _Source: `cpp/include/cuvs/neighbors/nn_descent.hpp:182`_ _Doxygen group: `nn_descent_cpp_index_build`_ + ### cuvs::neighbors::nn_descent::build Build nn-descent Index with dataset in device memory @@ -243,7 +252,7 @@ the output graph | Name | Direction | Type | Description | | --- | --- | --- | --- | | `res` | in | `raft::resources const&` | raft::resources is an object managing resources | -| `params` | in | `index_params const&` | an instance of nn_descent::index_params that are parameters to run the nn-descent algorithm | +| `params` | in | [`index_params const&`](/api-reference/cpp-api-neighbors-nn-descent#cuvs-neighbors-nn-descent-index-params) | an instance of nn_descent::index_params that are parameters to run the nn-descent algorithm | | `dataset` | in | `raft::device_matrix_view` | raft::device_matrix_view input dataset expected to be located in device memory | | `graph` | in | `std::optional>` | optional raft::host_matrix_view<uint32_t, int64_t, raft::row_major> for owning Default: `std::nullopt`. | @@ -291,7 +300,7 @@ the output graph | Name | Direction | Type | Description | | --- | --- | --- | --- | | `res` | | `raft::resources const&` | raft::resources is an object managing resources | -| `params` | in | `index_params const&` | an instance of nn_descent::index_params that are parameters to run the nn-descent algorithm | +| `params` | in | [`index_params const&`](/api-reference/cpp-api-neighbors-nn-descent#cuvs-neighbors-nn-descent-index-params) | an instance of nn_descent::index_params that are parameters to run the nn-descent algorithm | | `dataset` | in | `raft::host_matrix_view` | raft::host_matrix_view input dataset expected to be located in host memory | | `graph` | in | `std::optional>` | optional raft::host_matrix_view<uint32_t, int64_t, raft::row_major> for owning Default: `std::nullopt`. | @@ -332,7 +341,7 @@ the output graph | Name | Direction | Type | Description | | --- | --- | --- | --- | | `res` | in | `raft::resources const&` | raft::resources is an object managing resources | -| `params` | in | `index_params const&` | an instance of nn_descent::index_params that are parameters to run the nn-descent algorithm | +| `params` | in | [`index_params const&`](/api-reference/cpp-api-neighbors-nn-descent#cuvs-neighbors-nn-descent-index-params) | an instance of nn_descent::index_params that are parameters to run the nn-descent algorithm | | `dataset` | in | `raft::device_matrix_view` | raft::device_matrix_view input dataset expected to be located in device memory | | `graph` | in | `std::optional>` | optional raft::host_matrix_view<uint32_t, int64_t, raft::row_major> for owning Default: `std::nullopt`. | @@ -380,7 +389,7 @@ the output graph | Name | Direction | Type | Description | | --- | --- | --- | --- | | `res` | | `raft::resources const&` | raft::resources is an object managing resources | -| `params` | in | `index_params const&` | an instance of nn_descent::index_params that are parameters to run the nn-descent algorithm | +| `params` | in | [`index_params const&`](/api-reference/cpp-api-neighbors-nn-descent#cuvs-neighbors-nn-descent-index-params) | an instance of nn_descent::index_params that are parameters to run the nn-descent algorithm | | `dataset` | in | `raft::host_matrix_view` | raft::host_matrix_view input dataset expected to be located in host memory | | `graph` | in | `std::optional>` | optional raft::host_matrix_view<uint32_t, int64_t, raft::row_major> for owning Default: `std::nullopt`. | @@ -422,7 +431,7 @@ the output graph | Name | Direction | Type | Description | | --- | --- | --- | --- | | `res` | in | `raft::resources const&` | raft::resources is an object managing resources | -| `params` | in | `index_params const&` | an instance of nn_descent::index_params that are parameters to run the nn-descent algorithm | +| `params` | in | [`index_params const&`](/api-reference/cpp-api-neighbors-nn-descent#cuvs-neighbors-nn-descent-index-params) | an instance of nn_descent::index_params that are parameters to run the nn-descent algorithm | | `dataset` | in | `raft::device_matrix_view` | raft::device_matrix_view input dataset expected to be located in device memory | | `graph` | in | `std::optional>` | optional raft::host_matrix_view<uint32_t, int64_t, raft::row_major> for owning Default: `std::nullopt`. | @@ -471,7 +480,7 @@ the output graph | Name | Direction | Type | Description | | --- | --- | --- | --- | | `res` | | `raft::resources const&` | raft::resources is an object managing resources | -| `params` | in | `index_params const&` | an instance of nn_descent::index_params that are parameters to run the nn-descent algorithm | +| `params` | in | [`index_params const&`](/api-reference/cpp-api-neighbors-nn-descent#cuvs-neighbors-nn-descent-index-params) | an instance of nn_descent::index_params that are parameters to run the nn-descent algorithm | | `dataset` | in | `raft::host_matrix_view` | raft::host_matrix_view input dataset expected to be located in host memory | | `graph` | in | `std::optional>` | optional raft::host_matrix_view<uint32_t, int64_t, raft::row_major> for owning Default: `std::nullopt`. | @@ -513,7 +522,7 @@ the output graph | Name | Direction | Type | Description | | --- | --- | --- | --- | | `res` | in | `raft::resources const&` | raft::resources is an object managing resources | -| `params` | in | `index_params const&` | an instance of nn_descent::index_params that are parameters to run the nn-descent algorithm | +| `params` | in | [`index_params const&`](/api-reference/cpp-api-neighbors-nn-descent#cuvs-neighbors-nn-descent-index-params) | an instance of nn_descent::index_params that are parameters to run the nn-descent algorithm | | `dataset` | in | `raft::device_matrix_view` | raft::device_matrix_view input dataset expected to be located in device memory | | `graph` | in | `std::optional>` | optional raft::host_matrix_view<uint32_t, int64_t, raft::row_major> for owning Default: `std::nullopt`. | @@ -562,7 +571,7 @@ the output graph | Name | Direction | Type | Description | | --- | --- | --- | --- | | `res` | | `raft::resources const&` | raft::resources is an object managing resources | -| `params` | in | `index_params const&` | an instance of nn_descent::index_params that are parameters to run the nn-descent algorithm | +| `params` | in | [`index_params const&`](/api-reference/cpp-api-neighbors-nn-descent#cuvs-neighbors-nn-descent-index-params) | an instance of nn_descent::index_params that are parameters to run the nn-descent algorithm | | `dataset` | in | `raft::host_matrix_view` | raft::host_matrix_view input dataset expected to be located in host memory | | `graph` | in | `std::optional>` | optional raft::host_matrix_view<uint32_t, int64_t, raft::row_major> for owning Default: `std::nullopt`. | diff --git a/fern/pages/cpp_api/cpp-api-neighbors-refine.md b/fern/pages/cpp_api/cpp-api-neighbors-refine.md index 681b5b7d04..47179def7a 100644 --- a/fern/pages/cpp_api/cpp-api-neighbors-refine.md +++ b/fern/pages/cpp_api/cpp-api-neighbors-refine.md @@ -10,6 +10,7 @@ _Source header: `cpp/include/cuvs/neighbors/refine.hpp`_ _Doxygen group: `ann_refine`_ + ### cuvs::neighbors::refine Refine nearest neighbor search. @@ -40,7 +41,7 @@ Example usage | `neighbor_candidates` | in | `raft::device_matrix_view` | indices of candidate vectors [n_queries, n_candidates], where n_candidates >= k | | `indices` | out | `raft::device_matrix_view` | device matrix that stores the refined indices [n_queries, k] | | `distances` | out | `raft::device_matrix_view` | device matrix that stores the refined distances [n_queries, k] | -| `metric` | in | `cuvs::distance::DistanceType` | distance metric to use. Euclidean (L2) is used by default Default: `cuvs::distance::DistanceType::L2Unexpanded`. | +| `metric` | in | [`cuvs::distance::DistanceType`](/api-reference/cpp-api-distance-distance#cuvs-distance-distancetype) | distance metric to use. Euclidean (L2) is used by default Default: `cuvs::distance::DistanceType::L2Unexpanded`. | **Returns** @@ -78,7 +79,7 @@ Example usage | `neighbor_candidates` | in | `raft::device_matrix_view` | indices of candidate vectors [n_queries, n_candidates], where n_candidates >= k | | `indices` | out | `raft::device_matrix_view` | device matrix that stores the refined indices [n_queries, k] | | `distances` | out | `raft::device_matrix_view` | device matrix that stores the refined distances [n_queries, k] | -| `metric` | in | `cuvs::distance::DistanceType` | distance metric to use. Euclidean (L2) is used by default Default: `cuvs::distance::DistanceType::L2Unexpanded`. | +| `metric` | in | [`cuvs::distance::DistanceType`](/api-reference/cpp-api-distance-distance#cuvs-distance-distancetype) | distance metric to use. Euclidean (L2) is used by default Default: `cuvs::distance::DistanceType::L2Unexpanded`. | **Returns** @@ -116,7 +117,7 @@ Example usage | `neighbor_candidates` | in | `raft::device_matrix_view` | indices of candidate vectors [n_queries, n_candidates], where n_candidates >= k | | `indices` | out | `raft::device_matrix_view` | device matrix that stores the refined indices [n_queries, k] | | `distances` | out | `raft::device_matrix_view` | device matrix that stores the refined distances [n_queries, k] | -| `metric` | in | `cuvs::distance::DistanceType` | distance metric to use. Euclidean (L2) is used by default Default: `cuvs::distance::DistanceType::L2Unexpanded`. | +| `metric` | in | [`cuvs::distance::DistanceType`](/api-reference/cpp-api-distance-distance#cuvs-distance-distancetype) | distance metric to use. Euclidean (L2) is used by default Default: `cuvs::distance::DistanceType::L2Unexpanded`. | **Returns** @@ -154,7 +155,7 @@ Example usage | `neighbor_candidates` | in | `raft::device_matrix_view` | indices of candidate vectors [n_queries, n_candidates], where n_candidates >= k | | `indices` | out | `raft::device_matrix_view` | device matrix that stores the refined indices [n_queries, k] | | `distances` | out | `raft::device_matrix_view` | device matrix that stores the refined distances [n_queries, k] | -| `metric` | in | `cuvs::distance::DistanceType` | distance metric to use. Euclidean (L2) is used by default Default: `cuvs::distance::DistanceType::L2Unexpanded`. | +| `metric` | in | [`cuvs::distance::DistanceType`](/api-reference/cpp-api-distance-distance#cuvs-distance-distancetype) | distance metric to use. Euclidean (L2) is used by default Default: `cuvs::distance::DistanceType::L2Unexpanded`. | **Returns** @@ -192,7 +193,7 @@ Example usage | `neighbor_candidates` | in | `raft::device_matrix_view` | indices of candidate vectors [n_queries, n_candidates], where n_candidates >= k | | `indices` | out | `raft::device_matrix_view` | device matrix that stores the refined indices [n_queries, k] | | `distances` | out | `raft::device_matrix_view` | device matrix that stores the refined distances [n_queries, k] | -| `metric` | in | `cuvs::distance::DistanceType` | distance metric to use. Euclidean (L2) is used by default Default: `cuvs::distance::DistanceType::L2Unexpanded`. | +| `metric` | in | [`cuvs::distance::DistanceType`](/api-reference/cpp-api-distance-distance#cuvs-distance-distancetype) | distance metric to use. Euclidean (L2) is used by default Default: `cuvs::distance::DistanceType::L2Unexpanded`. | **Returns** @@ -230,7 +231,7 @@ Example usage | `neighbor_candidates` | in | `raft::host_matrix_view` | host matrix with indices of candidate vectors [n_queries, n_candidates], where n_candidates >= k | | `indices` | out | `raft::host_matrix_view` | host matrix that stores the refined indices [n_queries, k] | | `distances` | out | `raft::host_matrix_view` | host matrix that stores the refined distances [n_queries, k] | -| `metric` | in | `cuvs::distance::DistanceType` | distance metric to use. Euclidean (L2) is used by default Default: `cuvs::distance::DistanceType::L2Unexpanded`. | +| `metric` | in | [`cuvs::distance::DistanceType`](/api-reference/cpp-api-distance-distance#cuvs-distance-distancetype) | distance metric to use. Euclidean (L2) is used by default Default: `cuvs::distance::DistanceType::L2Unexpanded`. | **Returns** @@ -268,7 +269,7 @@ Example usage | `neighbor_candidates` | in | `raft::host_matrix_view` | host matrix with indices of candidate vectors [n_queries, n_candidates], where n_candidates >= k | | `indices` | out | `raft::host_matrix_view` | host matrix that stores the refined indices [n_queries, k] | | `distances` | out | `raft::host_matrix_view` | host matrix that stores the refined distances [n_queries, k] | -| `metric` | in | `cuvs::distance::DistanceType` | distance metric to use. Euclidean (L2) is used by default Default: `cuvs::distance::DistanceType::L2Unexpanded`. | +| `metric` | in | [`cuvs::distance::DistanceType`](/api-reference/cpp-api-distance-distance#cuvs-distance-distancetype) | distance metric to use. Euclidean (L2) is used by default Default: `cuvs::distance::DistanceType::L2Unexpanded`. | **Returns** @@ -306,7 +307,7 @@ Example usage | `neighbor_candidates` | in | `raft::host_matrix_view` | host matrix with indices of candidate vectors [n_queries, n_candidates], where n_candidates >= k | | `indices` | out | `raft::host_matrix_view` | host matrix that stores the refined indices [n_queries, k] | | `distances` | out | `raft::host_matrix_view` | host matrix that stores the refined distances [n_queries, k] | -| `metric` | in | `cuvs::distance::DistanceType` | distance metric to use. Euclidean (L2) is used by default Default: `cuvs::distance::DistanceType::L2Unexpanded`. | +| `metric` | in | [`cuvs::distance::DistanceType`](/api-reference/cpp-api-distance-distance#cuvs-distance-distancetype) | distance metric to use. Euclidean (L2) is used by default Default: `cuvs::distance::DistanceType::L2Unexpanded`. | **Returns** @@ -344,7 +345,7 @@ Example usage | `neighbor_candidates` | in | `raft::host_matrix_view` | host matrix with indices of candidate vectors [n_queries, n_candidates], where n_candidates >= k | | `indices` | out | `raft::host_matrix_view` | host matrix that stores the refined indices [n_queries, k] | | `distances` | out | `raft::host_matrix_view` | host matrix that stores the refined distances [n_queries, k] | -| `metric` | in | `cuvs::distance::DistanceType` | distance metric to use. Euclidean (L2) is used by default Default: `cuvs::distance::DistanceType::L2Unexpanded`. | +| `metric` | in | [`cuvs::distance::DistanceType`](/api-reference/cpp-api-distance-distance#cuvs-distance-distancetype) | distance metric to use. Euclidean (L2) is used by default Default: `cuvs::distance::DistanceType::L2Unexpanded`. | **Returns** @@ -382,7 +383,7 @@ Example usage | `neighbor_candidates` | in | `raft::host_matrix_view` | host matrix with indices of candidate vectors [n_queries, n_candidates], where n_candidates >= k | | `indices` | out | `raft::host_matrix_view` | host matrix that stores the refined indices [n_queries, k] | | `distances` | out | `raft::host_matrix_view` | host matrix that stores the refined distances [n_queries, k] | -| `metric` | in | `cuvs::distance::DistanceType` | distance metric to use. Euclidean (L2) is used by default Default: `cuvs::distance::DistanceType::L2Unexpanded`. | +| `metric` | in | [`cuvs::distance::DistanceType`](/api-reference/cpp-api-distance-distance#cuvs-distance-distancetype) | distance metric to use. Euclidean (L2) is used by default Default: `cuvs::distance::DistanceType::L2Unexpanded`. | **Returns** diff --git a/fern/pages/cpp_api/cpp-api-neighbors-scann.md b/fern/pages/cpp_api/cpp-api-neighbors-scann.md index 488a7ffda4..adc396d677 100644 --- a/fern/pages/cpp_api/cpp-api-neighbors-scann.md +++ b/fern/pages/cpp_api/cpp-api-neighbors-scann.md @@ -10,6 +10,7 @@ _Source header: `cpp/include/cuvs/neighbors/scann.hpp`_ _Doxygen group: `scann_cpp_index_params`_ + ### cuvs::neighbors::experimental::scann::index_params ANN parameters used by ScaNN to build index @@ -40,6 +41,7 @@ _Source: `cpp/include/cuvs/neighbors/scann.hpp:36`_ _Doxygen group: `scann_cpp_index`_ + ### cuvs::neighbors::experimental::scann::metric Distance metric used for clustering. @@ -50,10 +52,11 @@ Distance metric used for clustering. **Returns** -`cuvs::distance::DistanceType` +[`cuvs::distance::DistanceType`](/api-reference/cpp-api-distance-distance#cuvs-distance-distancetype) _Source: `cpp/include/cuvs/neighbors/scann.hpp:110`_ + ### cuvs::neighbors::experimental::scann::size Total length of the index (number of vectors). @@ -68,6 +71,7 @@ IdxT size() const noexcept; _Source: `cpp/include/cuvs/neighbors/scann.hpp:116`_ + ### cuvs::neighbors::experimental::scann::dim Dimensionality of the data. @@ -86,6 +90,7 @@ _Source: `cpp/include/cuvs/neighbors/scann.hpp:119`_ _Doxygen group: `scann_cpp_index_build`_ + ### cuvs::neighbors::experimental::scann::build Build the index from the dataset for efficient search. @@ -102,7 +107,7 @@ raft::device_matrix_view dataset) | Name | Direction | Type | Description | | --- | --- | --- | --- | | `handle` | | `raft::resources const&` | | -| `params` | | `const cuvs::neighbors::experimental::scann::index_params&` | | +| `params` | | [`const cuvs::neighbors::experimental::scann::index_params&`](/api-reference/cpp-api-neighbors-scann#cuvs-neighbors-experimental-scann-index-params) | | | `dataset` | | `raft::device_matrix_view` | | **Returns** @@ -111,6 +116,7 @@ raft::device_matrix_view dataset) _Source: `cpp/include/cuvs/neighbors/scann.hpp:291`_ + ### cuvs::neighbors::experimental::scann::serialize Save the index to files in a directory diff --git a/fern/pages/cpp_api/cpp-api-neighbors-vamana.md b/fern/pages/cpp_api/cpp-api-neighbors-vamana.md index 84472ca5d8..e45890bf90 100644 --- a/fern/pages/cpp_api/cpp-api-neighbors-vamana.md +++ b/fern/pages/cpp_api/cpp-api-neighbors-vamana.md @@ -10,6 +10,7 @@ _Source header: `cpp/include/cuvs/neighbors/vamana.hpp`_ _Doxygen group: `vamana_cpp_index_params`_ + ### cuvs::neighbors::vamana::index_params Parameters used to build DiskANN index @@ -40,6 +41,7 @@ _Source: `cpp/include/cuvs/neighbors/vamana.hpp:56`_ _Doxygen group: `vamana_cpp_index`_ + ### cuvs::neighbors::vamana::metric Distance metric used for clustering. @@ -50,10 +52,11 @@ Distance metric used for clustering. **Returns** -`cuvs::distance::DistanceType` +[`cuvs::distance::DistanceType`](/api-reference/cpp-api-distance-distance#cuvs-distance-distancetype) _Source: `cpp/include/cuvs/neighbors/vamana.hpp:108`_ + ### cuvs::neighbors::vamana::size Total length of the index (number of vectors). @@ -68,6 +71,7 @@ Total length of the index (number of vectors). _Source: `cpp/include/cuvs/neighbors/vamana.hpp:114`_ + ### cuvs::neighbors::vamana::dim Dimensionality of the data. @@ -82,6 +86,7 @@ Dimensionality of the data. _Source: `cpp/include/cuvs/neighbors/vamana.hpp:121`_ + ### cuvs::neighbors::vamana::graph_degree Graph degree @@ -96,6 +101,7 @@ Graph degree _Source: `cpp/include/cuvs/neighbors/vamana.hpp:123`_ + ### cuvs::neighbors::vamana::data Dataset [size, dim] @@ -110,6 +116,7 @@ Dataset [size, dim] _Source: `cpp/include/cuvs/neighbors/vamana.hpp:129`_ + ### cuvs::neighbors::vamana::quantized_data Quantized dataset [size, codes_rowlen] @@ -125,6 +132,7 @@ Quantized dataset [size, codes_rowlen] _Source: `cpp/include/cuvs/neighbors/vamana.hpp:135`_ + ### cuvs::neighbors::vamana::graph vamana graph [size, graph-degree] @@ -140,6 +148,7 @@ vamana graph [size, graph-degree] _Source: `cpp/include/cuvs/neighbors/vamana.hpp:142`_ + ### cuvs::neighbors::vamana::medoid Return the id of the vector selected as the medoid. @@ -154,6 +163,7 @@ Return the id of the vector selected as the medoid. _Source: `cpp/include/cuvs/neighbors/vamana.hpp:149`_ + ### cuvs::neighbors::vamana::index ```cpp @@ -187,7 +197,7 @@ cuvs::distance::DistanceType metric = cuvs::distance::DistanceType::L2Expanded) | Name | Direction | Type | Description | | --- | --- | --- | --- | | `res` | | `raft::resources const&` | | -| `metric` | | `cuvs::distance::DistanceType` | Default: `cuvs::distance::DistanceType::L2Expanded`. | +| `metric` | | [`cuvs::distance::DistanceType`](/api-reference/cpp-api-distance-distance#cuvs-distance-distancetype) | Default: `cuvs::distance::DistanceType::L2Expanded`. | **Returns** @@ -215,7 +225,7 @@ IdxT medoid_id) | Name | Direction | Type | Description | | --- | --- | --- | --- | | `res` | | `raft::resources const&` | | -| `metric` | | `cuvs::distance::DistanceType` | | +| `metric` | | [`cuvs::distance::DistanceType`](/api-reference/cpp-api-distance-distance#cuvs-distance-distancetype) | | | `dataset` | | `raft::mdspan, raft::row_major, data_accessor>` | | | `vamana_graph` | | `raft::mdspan, raft::row_major, graph_accessor>` | | | `medoid_id` | | `IdxT` | | @@ -226,6 +236,7 @@ IdxT medoid_id) _Source: `cpp/include/cuvs/neighbors/vamana.hpp:174`_ + ### cuvs::neighbors::vamana::update_graph Replace the graph with a new graph. @@ -274,6 +285,7 @@ We create a copy of the graph on the device. The index manages the lifetime of t _Source: `cpp/include/cuvs/neighbors/vamana.hpp:212`_ + ### cuvs::neighbors::vamana::update_quantized_dataset Replace the current quantized dataset with a new quantized dataset. @@ -303,6 +315,7 @@ _Source: `cpp/include/cuvs/neighbors/vamana.hpp:240`_ _Doxygen group: `vamana_cpp_index_build`_ + ### cuvs::neighbors::vamana::build Build the index from the dataset for efficient DiskANN search. @@ -327,7 +340,7 @@ Usage example: | Name | Direction | Type | Description | | --- | --- | --- | --- | | `res` | in | `raft::resources const&` | | -| `params` | in | `const cuvs::neighbors::vamana::index_params&` | parameters for building the index | +| `params` | in | [`const cuvs::neighbors::vamana::index_params&`](/api-reference/cpp-api-neighbors-vamana#cuvs-neighbors-vamana-index-params) | parameters for building the index | | `dataset` | in | `raft::device_matrix_view` | a matrix view (device) to a row-major matrix [n_rows, dim] | **Returns** @@ -362,7 +375,7 @@ Usage example: | Name | Direction | Type | Description | | --- | --- | --- | --- | | `res` | in | `raft::resources const&` | | -| `params` | in | `const cuvs::neighbors::vamana::index_params&` | parameters for building the index | +| `params` | in | [`const cuvs::neighbors::vamana::index_params&`](/api-reference/cpp-api-neighbors-vamana#cuvs-neighbors-vamana-index-params) | parameters for building the index | | `dataset` | in | `raft::host_matrix_view` | a matrix view (host) to a row-major matrix [n_rows, dim] | **Returns** @@ -397,7 +410,7 @@ Usage example: | Name | Direction | Type | Description | | --- | --- | --- | --- | | `res` | in | `raft::resources const&` | | -| `params` | in | `const cuvs::neighbors::vamana::index_params&` | parameters for building the index | +| `params` | in | [`const cuvs::neighbors::vamana::index_params&`](/api-reference/cpp-api-neighbors-vamana#cuvs-neighbors-vamana-index-params) | parameters for building the index | | `dataset` | in | `raft::device_matrix_view` | a matrix view (device) to a row-major matrix [n_rows, dim] | **Returns** @@ -432,7 +445,7 @@ Usage example: | Name | Direction | Type | Description | | --- | --- | --- | --- | | `res` | in | `raft::resources const&` | | -| `params` | in | `const cuvs::neighbors::vamana::index_params&` | parameters for building the index | +| `params` | in | [`const cuvs::neighbors::vamana::index_params&`](/api-reference/cpp-api-neighbors-vamana#cuvs-neighbors-vamana-index-params) | parameters for building the index | | `dataset` | in | `raft::host_matrix_view` | a matrix view (host) to a row-major matrix [n_rows, dim] | **Returns** @@ -467,7 +480,7 @@ Usage example: | Name | Direction | Type | Description | | --- | --- | --- | --- | | `res` | in | `raft::resources const&` | | -| `params` | in | `const cuvs::neighbors::vamana::index_params&` | parameters for building the index | +| `params` | in | [`const cuvs::neighbors::vamana::index_params&`](/api-reference/cpp-api-neighbors-vamana#cuvs-neighbors-vamana-index-params) | parameters for building the index | | `dataset` | in | `raft::device_matrix_view` | a matrix view (device) to a row-major matrix [n_rows, dim] | **Returns** @@ -502,7 +515,7 @@ Usage example: | Name | Direction | Type | Description | | --- | --- | --- | --- | | `res` | in | `raft::resources const&` | | -| `params` | in | `const cuvs::neighbors::vamana::index_params&` | parameters for building the index | +| `params` | in | [`const cuvs::neighbors::vamana::index_params&`](/api-reference/cpp-api-neighbors-vamana#cuvs-neighbors-vamana-index-params) | parameters for building the index | | `dataset` | in | `raft::host_matrix_view` | a matrix view (host) to a row-major matrix [n_rows, dim] | **Returns** @@ -517,6 +530,7 @@ _Source: `cpp/include/cuvs/neighbors/vamana.hpp:475`_ _Doxygen group: `vamana_cpp_serialize`_ + ### cuvs::neighbors::vamana::serialize Save the index to file. @@ -611,6 +625,7 @@ _Source: `cpp/include/cuvs/neighbors/vamana.hpp:574`_ _Doxygen group: `vamana_cpp_codebook`_ + ### cuvs::neighbors::vamana::deserialize_codebooks Construct codebook parameters from input codebook files diff --git a/fern/pages/cpp_api/cpp-api-preprocessing-pca.md b/fern/pages/cpp_api/cpp-api-preprocessing-pca.md index f0f6e1e1ce..7718d74692 100644 --- a/fern/pages/cpp_api/cpp-api-preprocessing-pca.md +++ b/fern/pages/cpp_api/cpp-api-preprocessing-pca.md @@ -6,10 +6,37 @@ slug: api-reference/cpp-api-preprocessing-pca _Source header: `cpp/include/cuvs/preprocessing/pca.hpp`_ +## Types + + +### cuvs::preprocessing::pca::params + +Parameters for PCA decomposition. Ref: + +http://scikit-learn.org/stable/modules/generated/sklearn.decomposition.PCA.html + +```cpp +struct params { ... } ; +``` + +**Fields** + +| Name | Type | Description | +| --- | --- | --- | +| `n_components` | `int` | Number of components to keep. | +| `copy` | `bool` | If false, data passed to fit are overwritten and running fit(X).transform(X) will not yield the expected results, use fit_transform(X) instead. | +| `whiten` | `bool` | When true (false by default) the components vectors are multiplied by the square root of n_samples and then divided by the singular values to ensure uncorrelated outputs with unit component-wise variances. | +| `algorithm` | `solver` | The solver algorithm to use. | +| `tol` | `float` | Tolerance for singular values computed by svd_solver == 'arpack' or the Jacobi solver. | +| `n_iterations` | `int` | Number of iterations for the power method computed by the Jacobi solver. | + +_Source: `cpp/include/cuvs/preprocessing/pca.hpp:20`_ + ## PCA (Principal Component Analysis) _Doxygen group: `pca`_ + ### cuvs::preprocessing::pca::fit Perform PCA fit operation. @@ -34,7 +61,7 @@ Computes the principal components, explained variances, singular values, and col | Name | Direction | Type | Description | | --- | --- | --- | --- | | `handle` | in | `raft::resources const&` | raft resource handle | -| `config` | in | `const params&` | PCA parameters | +| `config` | in | [`const params&`](/api-reference/cpp-api-preprocessing-pca#cuvs-preprocessing-pca-params) | PCA parameters | | `input` | inout | `raft::device_matrix_view` | input data [n_rows x n_cols] (col-major). Modified temporarily. | | `components` | out | `raft::device_matrix_view` | principal components [n_components x n_cols] (col-major) | | `explained_var` | out | `raft::device_vector_view` | explained variances [n_components] | @@ -50,6 +77,7 @@ Computes the principal components, explained variances, singular values, and col _Source: `cpp/include/cuvs/preprocessing/pca.hpp:99`_ + ### cuvs::preprocessing::pca::fit_transform Perform PCA fit and transform operations. @@ -75,7 +103,7 @@ Computes the principal components and transforms the input data into the eigensp | Name | Direction | Type | Description | | --- | --- | --- | --- | | `handle` | in | `raft::resources const&` | raft resource handle | -| `config` | in | `const params&` | PCA parameters | +| `config` | in | [`const params&`](/api-reference/cpp-api-preprocessing-pca#cuvs-preprocessing-pca-params) | PCA parameters | | `input` | inout | `raft::device_matrix_view` | input data [n_rows x n_cols] (col-major). Modified temporarily. | | `trans_input` | out | `raft::device_matrix_view` | transformed data [n_rows x n_components] (col-major) | | `components` | out | `raft::device_matrix_view` | principal components [n_components x n_cols] (col-major) | @@ -92,6 +120,7 @@ Computes the principal components and transforms the input data into the eigensp _Source: `cpp/include/cuvs/preprocessing/pca.hpp:128`_ + ### cuvs::preprocessing::pca::transform Perform PCA transform operation. @@ -115,7 +144,7 @@ Transforms the input data into the eigenspace using previously computed principa | Name | Direction | Type | Description | | --- | --- | --- | --- | | `handle` | in | `raft::resources const&` | raft resource handle | -| `config` | in | `const params&` | PCA parameters | +| `config` | in | [`const params&`](/api-reference/cpp-api-preprocessing-pca#cuvs-preprocessing-pca-params) | PCA parameters | | `input` | inout | `raft::device_matrix_view` | data to transform [n_rows x n_cols] (col-major). Modified temporarily | | `components` | in | `raft::device_matrix_view` | principal components [n_components x n_cols] (col-major) | | `singular_vals` | in | `raft::device_vector_view` | singular values [n_components] | @@ -128,6 +157,7 @@ Transforms the input data into the eigenspace using previously computed principa _Source: `cpp/include/cuvs/preprocessing/pca.hpp:154`_ + ### cuvs::preprocessing::pca::inverse_transform Perform PCA inverse transform operation. @@ -149,7 +179,7 @@ Transforms data from the eigenspace back to the original space. | Name | Direction | Type | Description | | --- | --- | --- | --- | | `handle` | in | `raft::resources const&` | raft resource handle | -| `config` | in | `const params&` | PCA parameters | +| `config` | in | [`const params&`](/api-reference/cpp-api-preprocessing-pca#cuvs-preprocessing-pca-params) | PCA parameters | | `trans_input` | in | `raft::device_matrix_view` | transformed data [n_rows x n_components] (col-major) | | `components` | in | `raft::device_matrix_view` | principal components [n_components x n_cols] (col-major) | | `singular_vals` | in | `raft::device_vector_view` | singular values [n_components] | diff --git a/fern/pages/cpp_api/cpp-api-preprocessing-quantize-binary.md b/fern/pages/cpp_api/cpp-api-preprocessing-quantize-binary.md index 997c1fce85..834a12f544 100644 --- a/fern/pages/cpp_api/cpp-api-preprocessing-quantize-binary.md +++ b/fern/pages/cpp_api/cpp-api-preprocessing-quantize-binary.md @@ -10,6 +10,7 @@ _Source header: `cpp/include/cuvs/preprocessing/quantize/binary.hpp`_ _Doxygen group: `binary`_ + ### cuvs::preprocessing::quantize::binary::bit_threshold quantizer algorithms. The mean and sampling_median thresholds are calculated separately @@ -30,6 +31,7 @@ enum class bit_threshold { ... } ; _Source: `cpp/include/cuvs/preprocessing/quantize/binary.hpp:27`_ + ### cuvs::preprocessing::quantize::binary::params quantizer parameters. @@ -42,11 +44,12 @@ struct params { ... } ; | Name | Type | Description | | --- | --- | --- | -| `threshold` | `bit_threshold` | Threshold method for binarization. | +| `threshold` | [`bit_threshold`](/api-reference/cpp-api-preprocessing-quantize-binary#cuvs-preprocessing-quantize-binary-bit-threshold) | Threshold method for binarization. | | `sampling_ratio` | `float` | Specifies the sampling ratio. | _Source: `cpp/include/cuvs/preprocessing/quantize/binary.hpp:32`_ + ### cuvs::preprocessing::quantize::binary::quantizer Construct a quantizer with an empty threshold vector. @@ -67,6 +70,7 @@ quantizer(raft::resources const& res) : threshold(raft::make_device_vector ### cuvs::preprocessing::quantize::binary::train Initializes a binary quantizer to be used later for quantizing the dataset. @@ -84,7 +88,7 @@ Usage example: | Name | Direction | Type | Description | | --- | --- | --- | --- | | `res` | in | `raft::resources const&` | raft resource | -| `params` | in | `const params` | configure binary quantizer, e.g. threshold | +| `params` | in | [`const params`](/api-reference/cpp-api-preprocessing-quantize-binary#cuvs-preprocessing-quantize-binary-params) | configure binary quantizer, e.g. threshold | | `dataset` | in | `raft::device_matrix_view` | a row-major matrix view on device | **Returns** @@ -112,7 +116,7 @@ Usage example: | Name | Direction | Type | Description | | --- | --- | --- | --- | | `res` | in | `raft::resources const&` | raft resource | -| `params` | in | `const params` | configure binary quantizer, e.g. threshold | +| `params` | in | [`const params`](/api-reference/cpp-api-preprocessing-quantize-binary#cuvs-preprocessing-quantize-binary-params) | configure binary quantizer, e.g. threshold | | `dataset` | in | `raft::host_matrix_view` | a row-major matrix view on host | **Returns** @@ -123,6 +127,7 @@ quantizer _Source: `cpp/include/cuvs/preprocessing/quantize/binary.hpp:93`_ + ### cuvs::preprocessing::quantize::binary::transform Applies binary quantization transform to given dataset. If a dataset element is positive, @@ -200,7 +205,7 @@ Usage example: | Name | Direction | Type | Description | | --- | --- | --- | --- | | `res` | in | `raft::resources const&` | raft resource | -| `params` | in | `const params` | configure binary quantizer, e.g. threshold | +| `params` | in | [`const params`](/api-reference/cpp-api-preprocessing-quantize-binary#cuvs-preprocessing-quantize-binary-params) | configure binary quantizer, e.g. threshold | | `dataset` | in | `raft::device_matrix_view` | a row-major matrix view on device | **Returns** @@ -228,7 +233,7 @@ Usage example: | Name | Direction | Type | Description | | --- | --- | --- | --- | | `res` | in | `raft::resources const&` | raft resource | -| `params` | in | `const params` | configure binary quantizer, e.g. threshold | +| `params` | in | [`const params`](/api-reference/cpp-api-preprocessing-quantize-binary#cuvs-preprocessing-quantize-binary-params) | configure binary quantizer, e.g. threshold | | `dataset` | in | `raft::host_matrix_view` | a row-major matrix view on host | **Returns** @@ -316,7 +321,7 @@ Usage example: | Name | Direction | Type | Description | | --- | --- | --- | --- | | `res` | in | `raft::resources const&` | raft resource | -| `params` | in | `const params` | configure binary quantizer, e.g. threshold | +| `params` | in | [`const params`](/api-reference/cpp-api-preprocessing-quantize-binary#cuvs-preprocessing-quantize-binary-params) | configure binary quantizer, e.g. threshold | | `dataset` | in | `raft::device_matrix_view` | a row-major matrix view on device | **Returns** @@ -344,7 +349,7 @@ Usage example: | Name | Direction | Type | Description | | --- | --- | --- | --- | | `res` | in | `raft::resources const&` | raft resource | -| `params` | in | `const params` | configure binary quantizer, e.g. threshold | +| `params` | in | [`const params`](/api-reference/cpp-api-preprocessing-quantize-binary#cuvs-preprocessing-quantize-binary-params) | configure binary quantizer, e.g. threshold | | `dataset` | in | `raft::host_matrix_view` | a row-major matrix view on host | **Returns** @@ -411,6 +416,7 @@ Usage example: _Source: `cpp/include/cuvs/preprocessing/quantize/binary.hpp:340`_ + ### cuvs::preprocessing::quantize::binary::[[deprecated [deprecated] Applies binary quantization transform to given dataset. If a dataset element diff --git a/fern/pages/cpp_api/cpp-api-preprocessing-quantize-pq.md b/fern/pages/cpp_api/cpp-api-preprocessing-quantize-pq.md index 003603fef3..50481de695 100644 --- a/fern/pages/cpp_api/cpp-api-preprocessing-quantize-pq.md +++ b/fern/pages/cpp_api/cpp-api-preprocessing-quantize-pq.md @@ -10,6 +10,19 @@ _Source header: `cpp/include/cuvs/preprocessing/quantize/pq.hpp`_ _Doxygen group: `pq`_ + +### kmeans_params_variant + +Alias for the variant holding either balanced or regular k-means parameters. + +```cpp +using kmeans_params_variant = +std::variant; +``` + +_Source: `cpp/include/cuvs/preprocessing/quantize/pq.hpp:24`_ + + ### cuvs::preprocessing::quantize::pq::params Product Quantizer parameters. @@ -27,7 +40,7 @@ struct params { ... } ; | `use_subspaces` | `bool` | Whether to use subspaces for product quantization (PQ). When true, one PQ codebook is used for each subspace. Otherwise, a single PQ codebook is used. | | `use_vq` | `bool` | Whether to use Vector Quantization (KMeans) before product quantization (PQ). When true, VQ is used and PQ is trained on the residuals. | | `vq_n_centers` | `uint32_t` | Vector Quantization (VQ) codebook size - number of "coarse cluster centers". When zero, an optimal value is selected using a heuristic. (sqrt(n_rows)) | -| `kmeans_params` | `kmeans_params_variant` | K-means parameters for PQ codebook training. Set to cuvs::cluster::kmeans::balanced_params for balanced k-means (default), or cuvs::cluster::kmeans::params for regular k-means. The active variant type selects the algorithm; balanced k-means tends to be faster for PQ training where cluster sizes are approximately equal. Only L2Expanded metric is supported. The number of clusters is always set to 1 << pq_bits. | +| `kmeans_params` | [`kmeans_params_variant`](/api-reference/cpp-api-preprocessing-quantize-pq#kmeans-params-variant) | K-means parameters for PQ codebook training. Set to cuvs::cluster::kmeans::balanced_params for balanced k-means (default), or cuvs::cluster::kmeans::params for regular k-means. The active variant type selects the algorithm; balanced k-means tends to be faster for PQ training where cluster sizes are approximately equal. Only L2Expanded metric is supported. The number of clusters is always set to 1 << pq_bits. | | `max_train_points_per_pq_code` | `uint32_t` | The max number of data points to use per PQ code during PQ codebook training. Using more data points per PQ code may increase the quality of PQ codebook but may also increase the build time. We will use `pq_n_centers * max_train_points_per_pq_code` training points to train each PQ codebook. | | `max_train_points_per_vq_cluster` | `uint32_t` | The max number of data points to use per VQ cluster during training. | @@ -61,7 +74,7 @@ uint32_t max_train_points_per_vq_cluster = 1024) | `use_vq` | | `bool` | | | `vq_n_centers` | | `uint32_t` | | | `kmeans_n_iters` | | `uint32_t` | | -| `pq_kmeans_type` | | `cuvs::cluster::kmeans::kmeans_type` | Default: `cuvs::cluster::kmeans::kmeans_type::KMeansBalanced`. | +| `pq_kmeans_type` | | [`cuvs::cluster::kmeans::kmeans_type`](/api-reference/cpp-api-cluster-kmeans#cuvs-cluster-kmeans-kmeans-type) | Default: `cuvs::cluster::kmeans::kmeans_type::KMeansBalanced`. | | `max_train_points_per_pq_code` | | `uint32_t` | Default: `256`. | | `max_train_points_per_vq_cluster` | | `uint32_t` | Default: `1024`. | @@ -71,6 +84,7 @@ uint32_t max_train_points_per_vq_cluster = 1024) _Source: `cpp/include/cuvs/preprocessing/quantize/pq.hpp:34`_ + ### cuvs::preprocessing::quantize::pq::build Initializes a product quantizer to be used later for quantizing the dataset. @@ -90,7 +104,7 @@ Usage example: | Name | Direction | Type | Description | | --- | --- | --- | --- | | `res` | in | `raft::resources const&` | raft resource | -| `params` | in | `const params` | configure product quantizer, e.g. quantile | +| `params` | in | [`const params`](/api-reference/cpp-api-preprocessing-quantize-pq#cuvs-preprocessing-quantize-pq-params) | configure product quantizer, e.g. quantile | | `dataset` | in | `raft::device_matrix_view` | a row-major matrix view on device or host | **Returns** @@ -114,7 +128,7 @@ raft::host_matrix_view dataset); | Name | Direction | Type | Description | | --- | --- | --- | --- | | `res` | | `raft::resources const&` | | -| `params` | | `const params` | | +| `params` | | [`const params`](/api-reference/cpp-api-preprocessing-quantize-pq#cuvs-preprocessing-quantize-pq-params) | | | `dataset` | | `raft::host_matrix_view` | | **Returns** @@ -123,6 +137,7 @@ raft::host_matrix_view dataset); _Source: `cpp/include/cuvs/preprocessing/quantize/pq.hpp:174`_ + ### cuvs::preprocessing::quantize::pq::transform Applies quantization transform to given dataset @@ -181,6 +196,7 @@ std::optional> vq_labels = std::null _Source: `cpp/include/cuvs/preprocessing/quantize/pq.hpp:208`_ + ### cuvs::preprocessing::quantize::pq::get_quantized_dim Get the dimension of the quantized dataset (in bytes) @@ -193,7 +209,7 @@ inline int64_t get_quantized_dim(const params& config); | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `config` | in | `const params&` | product quantizer parameters | +| `config` | in | [`const params&`](/api-reference/cpp-api-preprocessing-quantize-pq#cuvs-preprocessing-quantize-pq-params) | product quantizer parameters | **Returns** @@ -203,6 +219,7 @@ the dimension of the quantized dataset _Source: `cpp/include/cuvs/preprocessing/quantize/pq.hpp:220`_ + ### cuvs::preprocessing::quantize::pq::inverse_transform Applies inverse quantization transform to given dataset diff --git a/fern/pages/cpp_api/cpp-api-preprocessing-quantize-scalar.md b/fern/pages/cpp_api/cpp-api-preprocessing-quantize-scalar.md index b7b2410891..cedd70d57d 100644 --- a/fern/pages/cpp_api/cpp-api-preprocessing-quantize-scalar.md +++ b/fern/pages/cpp_api/cpp-api-preprocessing-quantize-scalar.md @@ -10,6 +10,7 @@ _Source header: `cpp/include/cuvs/preprocessing/quantize/scalar.hpp`_ _Doxygen group: `scalar`_ + ### cuvs::preprocessing::quantize::scalar::params quantizer parameters. @@ -26,6 +27,7 @@ struct params { ... } ; _Source: `cpp/include/cuvs/preprocessing/quantize/scalar.hpp:26`_ + ### cuvs::preprocessing::quantize::scalar::train Initializes a scalar quantizer to be used later for quantizing the dataset. @@ -43,7 +45,7 @@ Usage example: | Name | Direction | Type | Description | | --- | --- | --- | --- | | `res` | in | `raft::resources const&` | raft resource | -| `params` | in | `const params` | configure scalar quantizer, e.g. quantile | +| `params` | in | [`const params`](/api-reference/cpp-api-preprocessing-quantize-scalar#cuvs-preprocessing-quantize-scalar-params) | configure scalar quantizer, e.g. quantile | | `dataset` | in | `raft::device_matrix_view` | a row-major matrix view on device | **Returns** @@ -71,7 +73,7 @@ Usage example: | Name | Direction | Type | Description | | --- | --- | --- | --- | | `res` | in | `raft::resources const&` | raft resource | -| `params` | in | `const params` | configure scalar quantizer, e.g. quantile | +| `params` | in | [`const params`](/api-reference/cpp-api-preprocessing-quantize-scalar#cuvs-preprocessing-quantize-scalar-params) | configure scalar quantizer, e.g. quantile | | `dataset` | in | `raft::host_matrix_view` | a row-major matrix view on host | **Returns** @@ -82,6 +84,7 @@ quantizer _Source: `cpp/include/cuvs/preprocessing/quantize/scalar.hpp:87`_ + ### cuvs::preprocessing::quantize::scalar::transform Applies quantization transform to given dataset @@ -138,6 +141,7 @@ Usage example: _Source: `cpp/include/cuvs/preprocessing/quantize/scalar.hpp:134`_ + ### cuvs::preprocessing::quantize::scalar::inverse_transform Perform inverse quantization step on previously quantized dataset @@ -215,7 +219,7 @@ Usage example: | Name | Direction | Type | Description | | --- | --- | --- | --- | | `res` | in | `raft::resources const&` | raft resource | -| `params` | in | `const params` | configure scalar quantizer, e.g. quantile | +| `params` | in | [`const params`](/api-reference/cpp-api-preprocessing-quantize-scalar#cuvs-preprocessing-quantize-scalar-params) | configure scalar quantizer, e.g. quantile | | `dataset` | in | `raft::device_matrix_view` | a row-major matrix view on device | **Returns** @@ -243,7 +247,7 @@ Usage example: | Name | Direction | Type | Description | | --- | --- | --- | --- | | `res` | in | `raft::resources const&` | raft resource | -| `params` | in | `const params` | configure scalar quantizer, e.g. quantile | +| `params` | in | [`const params`](/api-reference/cpp-api-preprocessing-quantize-scalar#cuvs-preprocessing-quantize-scalar-params) | configure scalar quantizer, e.g. quantile | | `dataset` | in | `raft::host_matrix_view` | a row-major matrix view on host | **Returns** @@ -387,7 +391,7 @@ Usage example: | Name | Direction | Type | Description | | --- | --- | --- | --- | | `res` | in | `raft::resources const&` | raft resource | -| `params` | in | `const params` | configure scalar quantizer, e.g. quantile | +| `params` | in | [`const params`](/api-reference/cpp-api-preprocessing-quantize-scalar#cuvs-preprocessing-quantize-scalar-params) | configure scalar quantizer, e.g. quantile | | `dataset` | in | `raft::device_matrix_view` | a row-major matrix view on device | **Returns** @@ -415,7 +419,7 @@ Usage example: | Name | Direction | Type | Description | | --- | --- | --- | --- | | `res` | in | `raft::resources const&` | raft resource | -| `params` | in | `const params` | configure scalar quantizer, e.g. quantile | +| `params` | in | [`const params`](/api-reference/cpp-api-preprocessing-quantize-scalar#cuvs-preprocessing-quantize-scalar-params) | configure scalar quantizer, e.g. quantile | | `dataset` | in | `raft::host_matrix_view` | a row-major matrix view on host | **Returns** diff --git a/fern/pages/cpp_api/cpp-api-preprocessing-spectral-embedding.md b/fern/pages/cpp_api/cpp-api-preprocessing-spectral-embedding.md index e17993025f..e7c2980b4e 100644 --- a/fern/pages/cpp_api/cpp-api-preprocessing-spectral-embedding.md +++ b/fern/pages/cpp_api/cpp-api-preprocessing-spectral-embedding.md @@ -6,10 +6,37 @@ slug: api-reference/cpp-api-preprocessing-spectral-embedding _Source header: `cpp/include/cuvs/preprocessing/spectral_embedding.hpp`_ +## Types + + +### cuvs::preprocessing::spectral_embedding::params + +Parameters for spectral embedding algorithm + +Spectral embedding is a dimensionality reduction technique that uses the eigenvectors of the graph Laplacian to embed data points into a lower-dimensional space. This technique is particularly useful for non-linear dimensionality reduction and clustering tasks. + +```cpp +struct params { ... } ; +``` + +**Fields** + +| Name | Type | Description | +| --- | --- | --- | +| `n_components` | `int` | The number of components to reduce the data to. | +| `n_neighbors` | `int` | The number of neighbors to use for the nearest neighbors graph. | +| `norm_laplacian` | `bool` | Whether to normalize the Laplacian matrix. If true, uses the normalized graph Laplacian (D^(-1/2) L D^(-1/2)). If false, uses the unnormalized graph Laplacian (L = D - W). Normalized Laplacian often leads to better results for clustering tasks. | +| `drop_first` | `bool` | Whether to drop the first eigenvector. The first eigenvector of the normalized Laplacian is constant and uninformative. Setting this to true drops it from the embedding. This is typically set to true when norm_laplacian is true. | +| `tolerance` | `float` | Tolerance for the eigenvalue solver. The tolerance for the eigenvalue solver. This is used to determine when to stop the eigenvalue solver. | +| `seed` | `std::optional` | Random seed for reproducibility. Controls the random number generation for k-NN graph construction and eigenvalue solver initialization. Use the same seed value to ensure reproducible results across runs. | + +_Source: `cpp/include/cuvs/preprocessing/spectral_embedding.hpp:25`_ + ## Spectral Embedding _Doxygen group: `spectral_embedding`_ + ### cuvs::preprocessing::spectral_embedding::transform Perform spectral embedding on input dataset @@ -33,7 +60,7 @@ This function computes the spectral embedding of the input dataset by: | Name | Direction | Type | Description | | --- | --- | --- | --- | | `handle` | in | `raft::resources const&` | RAFT resource handle for managing CUDA resources | -| `config` | in | `params` | Parameters controlling the spectral embedding algorithm | +| `config` | in | [`params`](/api-reference/cpp-api-preprocessing-spectral-embedding#cuvs-preprocessing-spectral-embedding-params) | Parameters controlling the spectral embedding algorithm | | `dataset` | in | `raft::device_matrix_view` | Input dataset in row-major format [n_samples x n_features] | | `embedding` | out | `raft::device_matrix_view` | Output embedding in column-major format [n_samples x n_components] | @@ -67,7 +94,7 @@ The function: | Name | Direction | Type | Description | | --- | --- | --- | --- | | `handle` | in | `raft::resources const&` | RAFT resource handle for managing CUDA resources | -| `config` | in | `params` | Parameters controlling the spectral embedding algorithm (n_neighbors parameter is ignored when using precomputed graph) | +| `config` | in | [`params`](/api-reference/cpp-api-preprocessing-spectral-embedding#cuvs-preprocessing-spectral-embedding-params) | Parameters controlling the spectral embedding algorithm (n_neighbors parameter is ignored when using precomputed graph) | | `connectivity_graph` | in | `raft::device_coo_matrix_view` | Precomputed sparse connectivity/affinity graph in COO format representing weighted connections between samples | | `embedding` | out | `raft::device_matrix_view` | Output embedding in column-major format [n_samples x n_components] | diff --git a/fern/pages/cpp_api/cpp-api-selection-select-k.md b/fern/pages/cpp_api/cpp-api-selection-select-k.md index 19dcbd25f7..cfb7baa8e0 100644 --- a/fern/pages/cpp_api/cpp-api-selection-select-k.md +++ b/fern/pages/cpp_api/cpp-api-selection-select-k.md @@ -10,6 +10,7 @@ _Source header: `cpp/include/cuvs/selection/select_k.hpp`_ _Doxygen group: `select_k`_ + ### cuvs::selection::select_k Select k smallest or largest key/values from each row in the input data. diff --git a/fern/pages/cpp_api/cpp-api-stats-silhouette-score.md b/fern/pages/cpp_api/cpp-api-stats-silhouette-score.md index c302f1ac5a..71517ee488 100644 --- a/fern/pages/cpp_api/cpp-api-stats-silhouette-score.md +++ b/fern/pages/cpp_api/cpp-api-stats-silhouette-score.md @@ -10,6 +10,7 @@ _Source header: `cpp/include/cuvs/stats/silhouette_score.hpp`_ _Doxygen group: `stats_silhouette_score`_ + ### stats::silhouette_score main function that returns the average silhouette score for a given set of data and its @@ -35,7 +36,7 @@ clusterings nRows) for every sample (length: nRows) | `labels` | in | `raft::device_vector_view` | : the pointer to the array containing labels for every data sample (length: | | `silhouette_score_per_sample` | out | `std::optional>` | : optional array populated with the silhouette score | | `n_unique_labels` | in | `int64_t` | : number of unique labels in the labels array | -| `metric` | in | `cuvs::distance::DistanceType` | : Distance metric to use. Euclidean (L2) is used by default Default: `cuvs::distance::DistanceType::L2Unexpanded`. | +| `metric` | in | [`cuvs::distance::DistanceType`](/api-reference/cpp-api-distance-distance#cuvs-distance-distancetype) | : Distance metric to use. Euclidean (L2) is used by default Default: `cuvs::distance::DistanceType::L2Unexpanded`. | **Returns** @@ -45,6 +46,7 @@ clusterings nRows) for every sample (length: nRows) _Source: `cpp/include/cuvs/stats/silhouette_score.hpp:31`_ + ### stats::silhouette_score_batched function that returns the average silhouette score for a given set of data and its @@ -72,7 +74,7 @@ clusterings nRows) for every sample (length: nRows) the calculations | `silhouette_score_per_sample` | out | `std::optional>` | : optional array populated with the silhouette score | | `n_unique_labels` | in | `int64_t` | : number of unique labels in the labels array | | `batch_size` | in | `int64_t` | : number of samples per batch | -| `metric` | in | `cuvs::distance::DistanceType` | : the numerical value that maps to the type of distance metric to be used in Default: `cuvs::distance::DistanceType::L2Unexpanded`. | +| `metric` | in | [`cuvs::distance::DistanceType`](/api-reference/cpp-api-distance-distance#cuvs-distance-distancetype) | : the numerical value that maps to the type of distance metric to be used in Default: `cuvs::distance::DistanceType::L2Unexpanded`. | **Returns** @@ -107,7 +109,7 @@ clusterings nRows) for every sample (length: nRows) the calculations | `labels` | in | `raft::device_vector_view` | : the pointer to the array containing labels for every data sample (length: | | `silhouette_score_per_sample` | out | `std::optional>` | : optional array populated with the silhouette score | | `n_unique_labels` | in | `int64_t` | : number of unique labels in the labels array | -| `metric` | in | `cuvs::distance::DistanceType` | : the numerical value that maps to the type of distance metric to be used in Default: `cuvs::distance::DistanceType::L2Unexpanded`. | +| `metric` | in | [`cuvs::distance::DistanceType`](/api-reference/cpp-api-distance-distance#cuvs-distance-distancetype) | : the numerical value that maps to the type of distance metric to be used in Default: `cuvs::distance::DistanceType::L2Unexpanded`. | **Returns** @@ -144,7 +146,7 @@ clusterings nRows) for every sample (length: nRows) the calculations | `silhouette_score_per_sample` | out | `std::optional>` | : optional array populated with the silhouette score | | `n_unique_labels` | in | `int64_t` | : number of unique labels in the labels array | | `batch_size` | in | `int64_t` | : number of samples per batch | -| `metric` | in | `cuvs::distance::DistanceType` | : the numerical value that maps to the type of distance metric to be used in Default: `cuvs::distance::DistanceType::L2Unexpanded`. | +| `metric` | in | [`cuvs::distance::DistanceType`](/api-reference/cpp-api-distance-distance#cuvs-distance-distancetype) | : the numerical value that maps to the type of distance metric to be used in Default: `cuvs::distance::DistanceType::L2Unexpanded`. | **Returns** diff --git a/fern/pages/cpp_api/cpp-api-stats-trustworthiness-score.md b/fern/pages/cpp_api/cpp-api-stats-trustworthiness-score.md index 8327221db2..040529d3b6 100644 --- a/fern/pages/cpp_api/cpp-api-stats-trustworthiness-score.md +++ b/fern/pages/cpp_api/cpp-api-stats-trustworthiness-score.md @@ -10,6 +10,7 @@ _Source header: `cpp/include/cuvs/stats/trustworthiness_score.hpp`_ _Doxygen group: `stats_trustworthiness`_ + ### stats::trustworthiness_score Compute the trustworthiness score @@ -34,7 +35,7 @@ modified. | `X` | in | `raft::device_matrix_view` | : Data in original dimension | | `X_embedded` | in | `raft::device_matrix_view` | : Data in target dimension (embedding) | | `n_neighbors` | in | `int` | Number of neighbors considered by trustworthiness score | -| `metric` | in | `cuvs::distance::DistanceType` | Distance metric to use. Euclidean (L2) is used by default Default: `cuvs::distance::DistanceType::L2SqrtUnexpanded`. | +| `metric` | in | [`cuvs::distance::DistanceType`](/api-reference/cpp-api-distance-distance#cuvs-distance-distancetype) | Distance metric to use. Euclidean (L2) is used by default Default: `cuvs::distance::DistanceType::L2SqrtUnexpanded`. | | `batch_size` | in | `int` | Batch size Default: `512`. | **Returns** diff --git a/fern/pages/cpp_api/cpp-api-util-cutlass-utils.md b/fern/pages/cpp_api/cpp-api-util-cutlass-utils.md new file mode 100644 index 0000000000..d06715c272 --- /dev/null +++ b/fern/pages/cpp_api/cpp-api-util-cutlass-utils.md @@ -0,0 +1,20 @@ +--- +slug: api-reference/cpp-api-util-cutlass-utils +--- + +# Cutlass Utils + +_Source header: `cpp/include/cuvs/util/cutlass_utils.hpp`_ + +## Types + + +### cuvs::cutlass_error + +Exception thrown when a CUTLASS error is encountered. + +```cpp +struct cutlass_error : public raft::exception { ... } ; +``` + +_Source: `cpp/include/cuvs/util/cutlass_utils.hpp:14`_ diff --git a/fern/pages/cpp_api/cpp-api-util-file-io.md b/fern/pages/cpp_api/cpp-api-util-file-io.md new file mode 100644 index 0000000000..43cd4838af --- /dev/null +++ b/fern/pages/cpp_api/cpp-api-util-file-io.md @@ -0,0 +1,57 @@ +--- +slug: api-reference/cpp-api-util-file-io +--- + +# File Io + +_Source header: `cpp/include/cuvs/util/file_io.hpp`_ + +## Types + + +### cuvs::util::fd_streambuf + +Streambuf that reads from a POSIX file descriptor + +```cpp +class fd_streambuf : public std::streambuf { ... } ; +``` + +_Source: `cpp/include/cuvs/util/file_io.hpp:30`_ + + +### cuvs::util::fd_istream + +Istream that reads from a POSIX file descriptor + +```cpp +class fd_istream : public std::istream { ... } ; +``` + +_Source: `cpp/include/cuvs/util/file_io.hpp:66`_ + + +### cuvs::util::file_descriptor + +RAII wrapper for POSIX file descriptors + +Manages file descriptor lifecycle with automatic cleanup. Non-copyable, move-only. + +```cpp +class file_descriptor { ... } ; +``` + +_Source: `cpp/include/cuvs/util/file_io.hpp:95`_ + + +### cuvs::util::buffered_ofstream + +Buffered output stream wrapper + +Wraps an std::ostream with a buffer to improve write performance by reducing the number of system calls. Automatically flushes on destruction. Non-copyable, non-movable. + +```cpp +class buffered_ofstream { ... } ; +``` + +_Source: `cpp/include/cuvs/util/file_io.hpp:262`_ diff --git a/fern/pages/cpp_api/index.md b/fern/pages/cpp_api/index.md index 96932a032c..73e3246af2 100644 --- a/fern/pages/cpp_api/index.md +++ b/fern/pages/cpp_api/index.md @@ -28,3 +28,5 @@ These pages are generated from the documented public headers in the cuVS source - [Select K](/api-reference/cpp-api-selection-select-k) - [Silhouette Score](/api-reference/cpp-api-stats-silhouette-score) - [Trustworthiness Score](/api-reference/cpp-api-stats-trustworthiness-score) +- [Cutlass Utils](/api-reference/cpp-api-util-cutlass-utils) +- [File Io](/api-reference/cpp-api-util-file-io) diff --git a/fern/scripts/generate_api_reference.py b/fern/scripts/generate_api_reference.py index 8182d9ed3a..c9e4a36402 100755 --- a/fern/scripts/generate_api_reference.py +++ b/fern/scripts/generate_api_reference.py @@ -11,7 +11,7 @@ from __future__ import annotations -from collections import defaultdict +from collections import Counter, defaultdict from dataclasses import dataclass, field import ast import re @@ -281,12 +281,23 @@ def _parse_header(self, path: Path) -> None: entry = parse_doxygen_entry( comment, declaration, rel_path, decl_line ) - if entry.kind == "member": + if entry.kind == "member" and not is_type_alias_signature( + entry.signature + ): continue self._qualify_function(entry, text[: match.start()]) - for candidate in candidate_groups: + target_groups = candidate_groups + if not target_groups and is_native_type_entry(entry): + target_groups = [synthetic_native_group_name(rel_path)] + for candidate in target_groups: self.groups.setdefault( - candidate, DoxygenGroup(candidate) + candidate, + DoxygenGroup( + candidate, + "Types" + if is_synthetic_native_group(candidate) + else "", + ), ).entries.append(entry) self._index_compound(entry, text[: match.start()]) @@ -309,6 +320,11 @@ def _parse_header(self, path: Path) -> None: current_groups.pop() def _index_compound(self, entry: DoxygenEntry, prefix: str) -> None: + if ( + is_type_alias_signature(entry.signature) + and "{" not in entry.signature + ): + return namespace = infer_namespace(prefix) struct_name = parse_struct_name(entry.signature) if struct_name: @@ -341,8 +357,17 @@ def _qualify_function(self, entry: DoxygenEntry, prefix: str) -> None: def main() -> int: remove_old_api_pages() native_index = DoxygenHeaderIndex.build(NATIVE_HEADER_DIRS) - generate_native_api_pages(native_index, "c") - generate_native_api_pages(native_index, "cpp") + native_pages_by_api = { + "c": collect_native_pages(native_index, "c"), + "cpp": collect_native_pages(native_index, "cpp"), + } + global_links, page_links = build_native_symbol_links(native_pages_by_api) + generate_native_api_pages( + native_pages_by_api["c"], "c", global_links, page_links + ) + generate_native_api_pages( + native_pages_by_api["cpp"], "cpp", global_links, page_links + ) generate_python_api_pages() generate_java_api_pages() generate_rust_api_pages() @@ -373,10 +398,33 @@ def remove_old_api_pages() -> None: path.unlink() -def generate_native_api_pages(index: DoxygenHeaderIndex, api: str) -> None: +def is_type_alias_signature(signature: str) -> bool: + stripped = signature.strip() + return stripped.startswith("typedef ") or stripped.startswith("using ") + + +def is_native_type_entry(entry: DoxygenEntry) -> bool: + return entry.kind in {"enum", "struct"} or is_type_alias_signature( + entry.signature + ) + + +def synthetic_native_group_name(source: str) -> str: + return f"__types__:{source}" + + +def is_synthetic_native_group(group_name: str) -> bool: + return group_name.startswith("__types__:") + + +def generate_native_api_pages( + pages: list[NativePage], + api: str, + global_links: dict[str, dict[str, str]], + page_links: dict[tuple[str, str], dict[str, str]], +) -> None: out_dir = FERN_PAGES / f"{api}_api" out_dir.mkdir(parents=True, exist_ok=True) - pages = collect_native_pages(index, api) title = "C API Documentation" if api == "c" else "C++ API Documentation" directory = f"{api}_api" @@ -402,8 +450,16 @@ def generate_native_api_pages(index: DoxygenHeaderIndex, api: str) -> None: "", ] page_headings: set[str] = set() + symbol_links = { + **global_links.get(api, {}), + **page_links.get((directory, page.slug), {}), + } for group in page.groups: - lines.extend(render_native_group(group, language, page_headings)) + lines.extend( + render_native_group( + group, language, page_headings, symbol_links + ) + ) lines.append("") write_page( out_dir / f"{api_page_route(directory, page.slug)}.md", lines @@ -446,27 +502,82 @@ def collect_native_pages( return ordered +def build_native_symbol_links( + pages_by_api: dict[str, list[NativePage]], +) -> tuple[dict[str, dict[str, str]], dict[tuple[str, str], dict[str, str]]]: + global_links: dict[str, dict[str, str]] = defaultdict(dict) + page_links: dict[tuple[str, str], dict[str, str]] = {} + + for api, pages in pages_by_api.items(): + directory = f"{api}_api" + for page in pages: + entries = [ + entry + for group in page.groups + for entry in group.entries + if is_linkable_native_type(entry) + ] + short_counts = Counter( + short_symbol_name(entry.name) for entry in entries + ) + local_links: dict[str, str] = {} + for entry in entries: + url = f"{api_doc_url(directory, page.slug)}#{symbol_anchor(entry.name)}" + for symbol in native_link_symbols(entry, api): + global_links[api].setdefault(symbol, url) + local_links[symbol] = url + short_name = short_symbol_name(entry.name) + if short_counts[short_name] == 1: + local_links[short_name] = url + page_links[(directory, page.slug)] = local_links + + return dict(global_links), page_links + + +def is_linkable_native_type(entry: DoxygenEntry) -> bool: + return is_native_type_entry(entry) + + +def native_link_symbols(entry: DoxygenEntry, api: str) -> list[str]: + symbols = [entry.name] + if api == "c" and entry.kind == "struct" and not entry.name.endswith("_t"): + symbols.append(f"{entry.name}_t") + return symbols + + +def short_symbol_name(name: str) -> str: + return name.split("::")[-1] + + def render_native_group( - group: DoxygenGroup, language: str, page_headings: set[str] | None = None + group: DoxygenGroup, + language: str, + page_headings: set[str] | None = None, + symbol_links: dict[str, str] | None = None, ) -> list[str]: lines = [f"## {heading_text(group.title or group.name)}", ""] - if group.name: + if group.name and not is_synthetic_native_group(group.name): lines.extend([f"_Doxygen group: `{group.name}`_", ""]) if page_headings is None: page_headings = set() + if symbol_links is None: + symbol_links = {} for entry in group.entries: if entry.kind == "function": include_heading = entry.name not in page_headings page_headings.add(entry.name) lines.extend( render_native_function( - entry, language, include_heading=include_heading + entry, + language, + include_heading=include_heading, + symbol_links=symbol_links, ) ) elif entry.kind in {"struct", "enum"}: page_headings.add(entry.name) - lines.extend(render_native_compound(entry, language)) + lines.extend(render_native_compound(entry, language, symbol_links)) else: page_headings.add(entry.name) lines.extend(render_native_member(entry, language)) @@ -475,11 +586,20 @@ def render_native_group( def render_native_function( - entry: DoxygenEntry, language: str, include_heading: bool = True + entry: DoxygenEntry, + language: str, + include_heading: bool = True, + symbol_links: dict[str, str] | None = None, ) -> list[str]: + if symbol_links is None: + symbol_links = {} signature = normalize_signature(entry.signature) if include_heading: - lines = [f"### {heading_text(entry.name)}", ""] + lines = [ + symbol_anchor_line(entry.name), + f"### {heading_text(entry.name)}", + "", + ] else: lines = [f"**Additional overload:** `{escape_code(entry.name)}`", ""] if entry.summary: @@ -523,12 +643,22 @@ def render_native_function( ) if rows: lines.extend(["**Parameters**", ""]) - lines.extend(render_param_table(rows, include_direction=True)) + lines.extend( + render_param_table( + rows, include_direction=True, symbol_links=symbol_links + ) + ) lines.append("") return_type = parse_return_type(signature) if return_type: - lines.extend(["**Returns**", "", f"`{escape_code(return_type)}`"]) + lines.extend( + [ + "**Returns**", + "", + render_type_reference(return_type, symbol_links), + ] + ) if entry.returns: lines.extend(["", escape_text(entry.returns)]) lines.append("") @@ -537,8 +667,18 @@ def render_native_function( return trim_blank_lines(lines) -def render_native_compound(entry: DoxygenEntry, language: str) -> list[str]: - lines = [f"### {heading_text(entry.name)}", ""] +def render_native_compound( + entry: DoxygenEntry, + language: str, + symbol_links: dict[str, str] | None = None, +) -> list[str]: + if symbol_links is None: + symbol_links = {} + lines = [ + symbol_anchor_line(entry.name), + f"### {heading_text(entry.name)}", + "", + ] if entry.summary: lines.extend([escape_text(entry.summary), ""]) @@ -551,7 +691,7 @@ def render_native_compound(entry: DoxygenEntry, language: str) -> list[str]: field_descriptions, details = extract_field_descriptions( entry.details, {value["name"] for value in values} ) - else: + elif not is_class_signature(entry.signature): members = parse_struct_members(entry) field_descriptions, details = extract_field_descriptions( entry.details, {member.name for member in members} @@ -611,7 +751,11 @@ def render_native_compound(entry: DoxygenEntry, language: str) -> list[str]: ), } ) - lines.extend(render_param_table(rows, include_direction=False)) + lines.extend( + render_param_table( + rows, include_direction=False, symbol_links=symbol_links + ) + ) lines.append("") lines.extend([source_line(entry), ""]) @@ -619,7 +763,11 @@ def render_native_compound(entry: DoxygenEntry, language: str) -> list[str]: def render_native_member(entry: DoxygenEntry, language: str) -> list[str]: - lines = [f"### {heading_text(entry.name)}", ""] + lines = [ + symbol_anchor_line(entry.name), + f"### {heading_text(entry.name)}", + "", + ] if entry.summary: lines.extend([escape_text(entry.summary), ""]) lines.extend( @@ -1260,11 +1408,14 @@ def parse_doxygen_entry( summary = details.pop(0).strip() kind = parse_doxygen_kind(declaration) - name = ( - parse_member_name(declaration) - if kind == "member" - else parse_entry_name(declaration) - ) + if is_type_alias_signature(declaration): + name = parse_type_alias_name(declaration) or parse_entry_name( + declaration + ) + elif kind == "member": + name = parse_member_name(declaration) + else: + name = parse_entry_name(declaration) return DoxygenEntry( kind=kind, name=name, @@ -1321,9 +1472,9 @@ def append_doxygen_line(existing: str, addition: str) -> str: def parse_doxygen_kind(declaration: str) -> str: - if re.search( - r"^\s*(?:typedef\s+)?(?:struct|class)\s+\w+", declaration - ) and ("{" in declaration or declaration.lstrip().startswith("typedef")): + if re.search(r"^\s*(?:typedef\s+)?(?:struct|class)\b", declaration) and ( + "{" in declaration or not declaration.lstrip().startswith("typedef") + ): return "struct" if ( re.search(r"^\s*(?:typedef\s+)?enum(?:\s+class)?\b", declaration) @@ -1335,6 +1486,27 @@ def parse_doxygen_kind(declaration: str) -> str: return "member" +def parse_type_alias_name(declaration: str) -> str | None: + signature = normalize_signature(declaration).rstrip(";").strip() + using_match = re.match(r"using\s+([A-Za-z_]\w*)\s*=", signature) + if using_match: + return using_match.group(1) + function_pointer_match = re.search( + r"\(\s*\*\s*([A-Za-z_]\w*)\s*\)", signature + ) + if function_pointer_match: + return function_pointer_match.group(1) + compound_alias_match = re.search( + r"}\s*([A-Za-z_]\w*)\s*$", signature, re.DOTALL + ) + if compound_alias_match: + return compound_alias_match.group(1) + typedef_match = re.search(r"\b([A-Za-z_]\w*)\s*$", signature) + if typedef_match and signature.startswith("typedef "): + return typedef_match.group(1) + return None + + def parse_entry_name(declaration: str) -> str: struct_name = parse_struct_name(declaration) if struct_name: @@ -1371,7 +1543,17 @@ def parse_struct_name(declaration: str) -> str | None: return match.group(1) if match else None +def is_class_signature(signature: str) -> bool: + return bool( + re.match( + r"^\s*(?:template\s*<[^>]+>\s*)?(?:typedef\s+)?class\b", signature + ) + ) + + def parse_enum_name(declaration: str) -> str | None: + if not re.search(r"^\s*(?:typedef\s+)?enum(?:\s+class)?\b", declaration): + return None match = re.search( r"^\s*(?:typedef\s+)?enum(?:\s+class)?\s+([A-Za-z_]\w*)", declaration ) @@ -1546,8 +1728,10 @@ def parse_plain_struct_members( return [] members: list[DoxygenEntry] = [] for declaration in top_level_member_declarations(body): + if "(" in declaration: + continue declaration = strip_member_initializer(declaration) - if not declaration or "(" in declaration: + if not declaration: continue if not declaration or declaration.startswith( ( @@ -3248,8 +3432,12 @@ def source_line(entry: DoxygenEntry) -> str: def render_param_table( - params: list[dict[str, str]], include_direction: bool + params: list[dict[str, str]], + include_direction: bool, + symbol_links: dict[str, str] | None = None, ) -> list[str]: + if symbol_links is None: + symbol_links = {} headers = ["Name"] if include_direction: headers.append("Direction") @@ -3262,7 +3450,7 @@ def render_param_table( row = [f"`{escape_code(param.get('name', ''))}`"] if include_direction: row.append(escape_text(param.get("direction", ""))) - row.append(f"`{escape_code(param.get('type', ''))}`") + row.append(render_type_reference(param.get("type", ""), symbol_links)) description = param.get("description", "") if param.get("default"): description = ( @@ -3273,6 +3461,39 @@ def render_param_table( return lines +def render_type_reference(value: str, symbol_links: dict[str, str]) -> str: + rendered = f"`{escape_code(value)}`" + link = find_native_symbol_link(value, symbol_links) + return f"[{rendered}]({link})" if link else rendered + + +def find_native_symbol_link( + value: str, symbol_links: dict[str, str] +) -> str | None: + if not value or not symbol_links: + return None + matches = [ + (len(name), name, link) + for name, link in symbol_links.items() + if native_symbol_occurs(value, name) + ] + if not matches: + return None + return max(matches)[2] + + +def native_symbol_occurs(value: str, name: str) -> bool: + return bool(re.search(rf"(? str: + return f'' + + +def symbol_anchor(name: str) -> str: + return slugify(name) + + def native_page_slug(source: str) -> str: source = re.sub(r"^(?:c|cpp)/include/cuvs/", "", source) source = re.sub(r"\.(?:h|hpp|cuh)$", "", source) From 599f96a1d6875ac868fe37b328a10612a9ef740a Mon Sep 17 00:00:00 2001 From: "Corey J. Nolet" Date: Thu, 7 May 2026 13:36:49 -0400 Subject: [PATCH 008/129] Hide native Doxygen group labels --- fern/pages/c_api/c-api-cluster-kmeans.md | 4 ---- fern/pages/c_api/c-api-core-c-api.md | 8 -------- .../c_api/c-api-distance-pairwise-distance.md | 2 -- .../c_api/c-api-neighbors-all-neighbors.md | 4 ---- .../pages/c_api/c-api-neighbors-brute-force.md | 8 -------- fern/pages/c_api/c-api-neighbors-cagra.md | 16 ---------------- fern/pages/c_api/c-api-neighbors-common.md | 4 ---- fern/pages/c_api/c-api-neighbors-hnsw.md | 18 ------------------ fern/pages/c_api/c-api-neighbors-ivf-flat.md | 14 -------------- fern/pages/c_api/c-api-neighbors-ivf-pq.md | 16 ---------------- fern/pages/c_api/c-api-neighbors-mg-cagra.md | 18 ------------------ fern/pages/c_api/c-api-neighbors-mg-common.md | 2 -- .../pages/c_api/c-api-neighbors-mg-ivf-flat.md | 18 ------------------ fern/pages/c_api/c-api-neighbors-mg-ivf-pq.md | 18 ------------------ fern/pages/c_api/c-api-neighbors-nn-descent.md | 6 ------ fern/pages/c_api/c-api-neighbors-refine.md | 2 -- .../c_api/c-api-neighbors-tiered-index.md | 12 ------------ fern/pages/c_api/c-api-neighbors-vamana.md | 8 -------- fern/pages/c_api/c-api-preprocessing-pca.md | 2 -- .../c-api-preprocessing-quantize-binary.md | 2 -- .../c_api/c-api-preprocessing-quantize-pq.md | 2 -- .../c-api-preprocessing-quantize-scalar.md | 2 -- .../cpp_api/cpp-api-cluster-agglomerative.md | 4 ---- fern/pages/cpp_api/cpp-api-cluster-kmeans.md | 6 ------ fern/pages/cpp_api/cpp-api-cluster-spectral.md | 4 ---- .../pages/cpp_api/cpp-api-distance-distance.md | 2 -- .../cpp_api/cpp-api-neighbors-all-neighbors.md | 4 ---- .../cpp_api/cpp-api-neighbors-ball-cover.md | 2 -- .../cpp_api/cpp-api-neighbors-brute-force.md | 10 ---------- fern/pages/cpp_api/cpp-api-neighbors-cagra.md | 16 ---------------- fern/pages/cpp_api/cpp-api-neighbors-common.md | 8 -------- .../cpp-api-neighbors-dynamic-batching.md | 8 -------- .../cpp-api-neighbors-epsilon-neighborhood.md | 2 -- fern/pages/cpp_api/cpp-api-neighbors-hnsw.md | 18 ------------------ .../cpp_api/cpp-api-neighbors-ivf-flat.md | 12 ------------ fern/pages/cpp_api/cpp-api-neighbors-ivf-pq.md | 16 ---------------- .../cpp_api/cpp-api-neighbors-nn-descent.md | 6 ------ fern/pages/cpp_api/cpp-api-neighbors-refine.md | 2 -- fern/pages/cpp_api/cpp-api-neighbors-scann.md | 8 -------- fern/pages/cpp_api/cpp-api-neighbors-vamana.md | 10 ---------- .../pages/cpp_api/cpp-api-preprocessing-pca.md | 2 -- .../cpp-api-preprocessing-quantize-binary.md | 2 -- .../cpp-api-preprocessing-quantize-pq.md | 2 -- .../cpp-api-preprocessing-quantize-scalar.md | 2 -- ...cpp-api-preprocessing-spectral-embedding.md | 2 -- .../cpp_api/cpp-api-selection-select-k.md | 2 -- .../cpp_api/cpp-api-stats-silhouette-score.md | 2 -- .../cpp-api-stats-trustworthiness-score.md | 2 -- fern/scripts/generate_api_reference.py | 2 -- 49 files changed, 342 deletions(-) diff --git a/fern/pages/c_api/c-api-cluster-kmeans.md b/fern/pages/c_api/c-api-cluster-kmeans.md index d6b322a985..6e436ee259 100644 --- a/fern/pages/c_api/c-api-cluster-kmeans.md +++ b/fern/pages/c_api/c-api-cluster-kmeans.md @@ -8,8 +8,6 @@ _Source header: `c/include/cuvs/cluster/kmeans.h`_ ## k-means hyperparameters -_Doxygen group: `kmeans_c_params`_ - ### cuvsKMeansInitMethod @@ -124,8 +122,6 @@ _Source: `c/include/cuvs/cluster/kmeans.h:135`_ ## k-means clustering APIs -_Doxygen group: `kmeans_c`_ - ### cuvsKMeansFit diff --git a/fern/pages/c_api/c-api-core-c-api.md b/fern/pages/c_api/c-api-core-c-api.md index 19020404ed..ad679fb508 100644 --- a/fern/pages/c_api/c-api-core-c-api.md +++ b/fern/pages/c_api/c-api-core-c-api.md @@ -8,8 +8,6 @@ _Source header: `c/include/cuvs/core/c_api.h`_ ## cuVS Error Messages -_Doxygen group: `error_c`_ - ### cuvsError_t @@ -70,8 +68,6 @@ _Source: `c/include/cuvs/core/c_api.h:36`_ ## cuVS Logging -_Doxygen group: `log_c`_ - ### cuvsLogLevel_t @@ -133,8 +129,6 @@ _Source: `c/include/cuvs/core/c_api.h:65`_ ## cuVS Resources Handle -_Doxygen group: `resources_c`_ - ### cuvsResources_t @@ -390,8 +384,6 @@ _Source: `c/include/cuvs/core/c_api.h:167`_ ## cuVS Memory Allocation -_Doxygen group: `memory_c`_ - ### cuvsRMMAlloc diff --git a/fern/pages/c_api/c-api-distance-pairwise-distance.md b/fern/pages/c_api/c-api-distance-pairwise-distance.md index 6a0f06ff86..6bcc2900f8 100644 --- a/fern/pages/c_api/c-api-distance-pairwise-distance.md +++ b/fern/pages/c_api/c-api-distance-pairwise-distance.md @@ -8,8 +8,6 @@ _Source header: `c/include/cuvs/distance/pairwise_distance.h`_ ## C pairwise distance -_Doxygen group: `pairwise_distance_c`_ - ### cuvsPairwiseDistance diff --git a/fern/pages/c_api/c-api-neighbors-all-neighbors.md b/fern/pages/c_api/c-api-neighbors-all-neighbors.md index 7e699f0a81..f552f34f0f 100644 --- a/fern/pages/c_api/c-api-neighbors-all-neighbors.md +++ b/fern/pages/c_api/c-api-neighbors-all-neighbors.md @@ -8,8 +8,6 @@ _Source header: `c/include/cuvs/neighbors/all_neighbors.h`_ ## All-neighbors C-API build parameters -_Doxygen group: `all_neighbors_c_params`_ - ### cuvsAllNeighborsAlgo @@ -99,8 +97,6 @@ _Source: `c/include/cuvs/neighbors/all_neighbors.h:79`_ ## All-neighbors C-API build -_Doxygen group: `all_neighbors_c_build`_ - ### cuvsAllNeighborsBuild diff --git a/fern/pages/c_api/c-api-neighbors-brute-force.md b/fern/pages/c_api/c-api-neighbors-brute-force.md index 6f6850bc9c..f6b4035f2e 100644 --- a/fern/pages/c_api/c-api-neighbors-brute-force.md +++ b/fern/pages/c_api/c-api-neighbors-brute-force.md @@ -8,8 +8,6 @@ _Source header: `c/include/cuvs/neighbors/brute_force.h`_ ## Bruteforce index -_Doxygen group: `bruteforce_c_index`_ - ### cuvsBruteForceIndex @@ -74,8 +72,6 @@ _Source: `c/include/cuvs/neighbors/brute_force.h:46`_ ## Bruteforce index build -_Doxygen group: `bruteforce_c_index_build`_ - ### cuvsBruteForceBuild @@ -114,8 +110,6 @@ _Source: `c/include/cuvs/neighbors/brute_force.h:92`_ ## Bruteforce index search -_Doxygen group: `bruteforce_c_index_search`_ - ### cuvsBruteForceSearch @@ -155,8 +149,6 @@ _Source: `c/include/cuvs/neighbors/brute_force.h:148`_ ## BRUTEFORCE C-API serialize functions -_Doxygen group: `bruteforce_c_index_serialize`_ - ### cuvsBruteForceSerialize diff --git a/fern/pages/c_api/c-api-neighbors-cagra.md b/fern/pages/c_api/c-api-neighbors-cagra.md index 2db7344aed..784a46a2e0 100644 --- a/fern/pages/c_api/c-api-neighbors-cagra.md +++ b/fern/pages/c_api/c-api-neighbors-cagra.md @@ -8,8 +8,6 @@ _Source header: `c/include/cuvs/neighbors/cagra.h`_ ## C API for CUDA ANN Graph-based nearest neighbor search -_Doxygen group: `cagra_c_index_params`_ - ### cuvsCagraGraphBuildAlgo @@ -293,8 +291,6 @@ _Source: `c/include/cuvs/neighbors/cagra.h:292`_ ## C API for CUDA ANN Graph-based nearest neighbor search -_Doxygen group: `cagra_c_extend_params`_ - ### cuvsCagraExtendParams @@ -396,8 +392,6 @@ _Source: `c/include/cuvs/neighbors/cagra.h:644`_ ## C API for CUDA ANN Graph-based nearest neighbor search -_Doxygen group: `cagra_c_search_params`_ - ### cuvsCagraSearchAlgo @@ -517,8 +511,6 @@ _Source: `c/include/cuvs/neighbors/cagra.h:455`_ ## C API for CUDA ANN Graph-based nearest neighbor search -_Doxygen group: `cagra_c_index`_ - ### cuvsCagraIndex @@ -711,8 +703,6 @@ _Source: `c/include/cuvs/neighbors/cagra.h:560`_ ## C API for CUDA ANN Graph-based nearest neighbor search -_Doxygen group: `cagra_c_index_build`_ - ### cuvsCagraBuild @@ -751,8 +741,6 @@ _Source: `c/include/cuvs/neighbors/cagra.h:615`_ ## C API for CUDA ANN Graph-based nearest neighbor search -_Doxygen group: `cagra_c_index_search`_ - ### cuvsCagraSearch @@ -794,8 +782,6 @@ _Source: `c/include/cuvs/neighbors/cagra.h:707`_ ## CAGRA C-API serialize functions -_Doxygen group: `cagra_c_index_serialize`_ - ### cuvsCagraSerialize @@ -910,8 +896,6 @@ _Source: `c/include/cuvs/neighbors/cagra.h:824`_ ## CAGRA C-API merge functions -_Doxygen group: `cagra_c_index_merge`_ - ### cuvsCagraMerge diff --git a/fern/pages/c_api/c-api-neighbors-common.md b/fern/pages/c_api/c-api-neighbors-common.md index ac7a08c857..16a6c3b169 100644 --- a/fern/pages/c_api/c-api-neighbors-common.md +++ b/fern/pages/c_api/c-api-neighbors-common.md @@ -8,8 +8,6 @@ _Source header: `c/include/cuvs/neighbors/common.h`_ ## Filters APIs -_Doxygen group: `filters`_ - ### cuvsFilterType @@ -48,8 +46,6 @@ _Source: `c/include/cuvs/neighbors/common.h:36`_ ## Index Merge -_Doxygen group: `index_merge`_ - ### cuvsMergeStrategy diff --git a/fern/pages/c_api/c-api-neighbors-hnsw.md b/fern/pages/c_api/c-api-neighbors-hnsw.md index f51a771526..ad32c1c433 100644 --- a/fern/pages/c_api/c-api-neighbors-hnsw.md +++ b/fern/pages/c_api/c-api-neighbors-hnsw.md @@ -8,8 +8,6 @@ _Source header: `c/include/cuvs/neighbors/hnsw.h`_ ## C API for HNSW index params -_Doxygen group: `hnsw_c_index_params`_ - ### cuvsHnswHierarchy @@ -151,8 +149,6 @@ _Source: `c/include/cuvs/neighbors/hnsw.h:149`_ ## C API for hnswlib wrapper index -_Doxygen group: `hnsw_c_index`_ - ### cuvsHnswIndex @@ -217,8 +213,6 @@ _Source: `c/include/cuvs/neighbors/hnsw.h:185`_ ## Parameters for extending HNSW index -_Doxygen group: `hnsw_c_extend_params`_ - ### cuvsHnswExtendParams @@ -284,8 +278,6 @@ _Source: `c/include/cuvs/neighbors/hnsw.h:218`_ ## Load CAGRA index as hnswlib index -_Doxygen group: `hnsw_c_index_load`_ - ### cuvsHnswFromCagra @@ -322,8 +314,6 @@ _Source: `c/include/cuvs/neighbors/hnsw.h:270`_ ## Build HNSW index using ACE algorithm -_Doxygen group: `hnsw_c_index_build`_ - ### cuvsHnswBuild @@ -363,8 +353,6 @@ _Source: `c/include/cuvs/neighbors/hnsw.h:347`_ ## Extend HNSW index with additional vectors -_Doxygen group: `hnsw_c_index_extend`_ - ### cuvsHnswExtend @@ -398,8 +386,6 @@ _Source: `c/include/cuvs/neighbors/hnsw.h:405`_ ## C API for hnswlib wrapper search params -_Doxygen group: `hnsw_c_search_params`_ - ### cuvsHnswSearchParams @@ -466,8 +452,6 @@ _Source: `c/include/cuvs/neighbors/hnsw.h:440`_ ## C API for CUDA ANN Graph-based nearest neighbor search -_Doxygen group: `hnsw_c_index_search`_ - ### cuvsHnswSearch @@ -507,8 +491,6 @@ _Source: `c/include/cuvs/neighbors/hnsw.h:499`_ ## HNSW C-API serialize functions -_Doxygen group: `hnsw_c_index_serialize`_ - ### cuvsHnswSerialize diff --git a/fern/pages/c_api/c-api-neighbors-ivf-flat.md b/fern/pages/c_api/c-api-neighbors-ivf-flat.md index 591dd311b3..c718465b6c 100644 --- a/fern/pages/c_api/c-api-neighbors-ivf-flat.md +++ b/fern/pages/c_api/c-api-neighbors-ivf-flat.md @@ -8,8 +8,6 @@ _Source header: `c/include/cuvs/neighbors/ivf_flat.h`_ ## IVF-Flat index build parameters -_Doxygen group: `ivf_flat_c_index_params`_ - ### cuvsIvfFlatIndexParams @@ -82,8 +80,6 @@ _Source: `c/include/cuvs/neighbors/ivf_flat.h:88`_ ## IVF-Flat index search parameters -_Doxygen group: `ivf_flat_c_search_params`_ - ### cuvsIvfFlatSearchParams @@ -149,8 +145,6 @@ _Source: `c/include/cuvs/neighbors/ivf_flat.h:122`_ ## IVF-Flat index -_Doxygen group: `ivf_flat_c_index`_ - ### cuvsIvfFlatIndex @@ -283,8 +277,6 @@ _Source: `c/include/cuvs/neighbors/ivf_flat.h:170`_ ## IVF-Flat index build -_Doxygen group: `ivf_flat_c_index_build`_ - ### cuvsIvfFlatBuild @@ -322,8 +314,6 @@ _Source: `c/include/cuvs/neighbors/ivf_flat.h:222`_ ## IVF-Flat index search -_Doxygen group: `ivf_flat_c_index_search`_ - ### cuvsIvfFlatSearch @@ -365,8 +355,6 @@ _Source: `c/include/cuvs/neighbors/ivf_flat.h:279`_ ## IVF-Flat C-API serialize functions -_Doxygen group: `ivf_flat_c_index_serialize`_ - ### cuvsIvfFlatSerialize @@ -423,8 +411,6 @@ _Source: `c/include/cuvs/neighbors/ivf_flat.h:328`_ ## IVF-Flat index extend -_Doxygen group: `ivf_flat_c_index_extend`_ - ### cuvsIvfFlatExtend diff --git a/fern/pages/c_api/c-api-neighbors-ivf-pq.md b/fern/pages/c_api/c-api-neighbors-ivf-pq.md index fc7f8767b0..52ee6abad9 100644 --- a/fern/pages/c_api/c-api-neighbors-ivf-pq.md +++ b/fern/pages/c_api/c-api-neighbors-ivf-pq.md @@ -8,8 +8,6 @@ _Source header: `c/include/cuvs/neighbors/ivf_pq.h`_ ## IVF-PQ index build parameters -_Doxygen group: `ivf_pq_c_index_params`_ - ### cuvsIvfPqCodebookGen @@ -123,8 +121,6 @@ _Source: `c/include/cuvs/neighbors/ivf_pq.h:152`_ ## IVF-PQ index search parameters -_Doxygen group: `ivf_pq_c_search_params`_ - ### cuvsIvfPqSearchParams @@ -195,8 +191,6 @@ _Source: `c/include/cuvs/neighbors/ivf_pq.h:235`_ ## IVF-PQ index -_Doxygen group: `ivf_pq_c_index`_ - ### cuvsIvfPqIndex @@ -611,8 +605,6 @@ _Source: `c/include/cuvs/neighbors/ivf_pq.h:386`_ ## IVF-PQ index build -_Doxygen group: `ivf_pq_c_index_build`_ - ### cuvsIvfPqBuild @@ -698,8 +690,6 @@ _Source: `c/include/cuvs/neighbors/ivf_pq.h:474`_ ## IVF-PQ index search -_Doxygen group: `ivf_pq_c_index_search`_ - ### cuvsIvfPqSearch @@ -739,8 +729,6 @@ _Source: `c/include/cuvs/neighbors/ivf_pq.h:534`_ ## IVF-PQ C-API serialize functions -_Doxygen group: `ivf_pq_c_index_serialize`_ - ### cuvsIvfPqSerialize @@ -793,8 +781,6 @@ _Source: `c/include/cuvs/neighbors/ivf_pq.h:579`_ ## IVF-PQ index extend -_Doxygen group: `ivf_pq_c_index_extend`_ - ### cuvsIvfPqExtend @@ -826,8 +812,6 @@ _Source: `c/include/cuvs/neighbors/ivf_pq.h:597`_ ## IVF-PQ index transform -_Doxygen group: `ivf_pq_c_index_transform`_ - ### cuvsIvfPqTransform diff --git a/fern/pages/c_api/c-api-neighbors-mg-cagra.md b/fern/pages/c_api/c-api-neighbors-mg-cagra.md index 16a5a530f8..0c7e70c564 100644 --- a/fern/pages/c_api/c-api-neighbors-mg-cagra.md +++ b/fern/pages/c_api/c-api-neighbors-mg-cagra.md @@ -8,8 +8,6 @@ _Source header: `c/include/cuvs/neighbors/mg_cagra.h`_ ## Multi-GPU CAGRA index build parameters -_Doxygen group: `mg_cagra_c_index_params`_ - ### cuvsMultiGpuCagraIndexParams @@ -78,8 +76,6 @@ _Source: `c/include/cuvs/neighbors/mg_cagra.h:51`_ ## Multi-GPU CAGRA index search parameters -_Doxygen group: `mg_cagra_c_search_params`_ - ### cuvsMultiGpuCagraSearchParams @@ -150,8 +146,6 @@ _Source: `c/include/cuvs/neighbors/mg_cagra.h:94`_ ## Multi-GPU CAGRA index -_Doxygen group: `mg_cagra_c_index`_ - ### cuvsMultiGpuCagraIndex @@ -220,8 +214,6 @@ _Source: `c/include/cuvs/neighbors/mg_cagra.h:130`_ ## Multi-GPU CAGRA index build -_Doxygen group: `mg_cagra_c_index_build`_ - ### cuvsMultiGpuCagraBuild @@ -253,8 +245,6 @@ _Source: `c/include/cuvs/neighbors/mg_cagra.h:150`_ ## Multi-GPU CAGRA index search -_Doxygen group: `mg_cagra_c_index_search`_ - ### cuvsMultiGpuCagraSearch @@ -290,8 +280,6 @@ _Source: `c/include/cuvs/neighbors/mg_cagra.h:175`_ ## Multi-GPU CAGRA index extend -_Doxygen group: `mg_cagra_c_index_extend`_ - ### cuvsMultiGpuCagraExtend @@ -323,8 +311,6 @@ _Source: `c/include/cuvs/neighbors/mg_cagra.h:200`_ ## Multi-GPU CAGRA index serialize -_Doxygen group: `mg_cagra_c_index_serialize`_ - ### cuvsMultiGpuCagraSerialize @@ -354,8 +340,6 @@ _Source: `c/include/cuvs/neighbors/mg_cagra.h:222`_ ## Multi-GPU CAGRA index deserialize -_Doxygen group: `mg_cagra_c_index_deserialize`_ - ### cuvsMultiGpuCagraDeserialize @@ -385,8 +369,6 @@ _Source: `c/include/cuvs/neighbors/mg_cagra.h:243`_ ## Multi-GPU CAGRA index distribute -_Doxygen group: `mg_cagra_c_index_distribute`_ - ### cuvsMultiGpuCagraDistribute diff --git a/fern/pages/c_api/c-api-neighbors-mg-common.md b/fern/pages/c_api/c-api-neighbors-mg-common.md index cd4a19bfc9..e2d480831c 100644 --- a/fern/pages/c_api/c-api-neighbors-mg-common.md +++ b/fern/pages/c_api/c-api-neighbors-mg-common.md @@ -8,8 +8,6 @@ _Source header: `c/include/cuvs/neighbors/mg_common.h`_ ## Multi-GPU common types and enums -_Doxygen group: `mg_c_common_types`_ - ### cuvsMultiGpuDistributionMode diff --git a/fern/pages/c_api/c-api-neighbors-mg-ivf-flat.md b/fern/pages/c_api/c-api-neighbors-mg-ivf-flat.md index 29432e05fe..687b3b6cd8 100644 --- a/fern/pages/c_api/c-api-neighbors-mg-ivf-flat.md +++ b/fern/pages/c_api/c-api-neighbors-mg-ivf-flat.md @@ -8,8 +8,6 @@ _Source header: `c/include/cuvs/neighbors/mg_ivf_flat.h`_ ## Multi-GPU IVF-Flat index build parameters -_Doxygen group: `mg_ivf_flat_c_index_params`_ - ### cuvsMultiGpuIvfFlatIndexParams @@ -78,8 +76,6 @@ _Source: `c/include/cuvs/neighbors/mg_ivf_flat.h:51`_ ## Multi-GPU IVF-Flat index search parameters -_Doxygen group: `mg_ivf_flat_c_search_params`_ - ### cuvsMultiGpuIvfFlatSearchParams @@ -150,8 +146,6 @@ _Source: `c/include/cuvs/neighbors/mg_ivf_flat.h:94`_ ## Multi-GPU IVF-Flat index -_Doxygen group: `mg_ivf_flat_c_index`_ - ### cuvsMultiGpuIvfFlatIndex @@ -220,8 +214,6 @@ _Source: `c/include/cuvs/neighbors/mg_ivf_flat.h:130`_ ## Multi-GPU IVF-Flat index build -_Doxygen group: `mg_ivf_flat_c_index_build`_ - ### cuvsMultiGpuIvfFlatBuild @@ -253,8 +245,6 @@ _Source: `c/include/cuvs/neighbors/mg_ivf_flat.h:150`_ ## Multi-GPU IVF-Flat index search -_Doxygen group: `mg_ivf_flat_c_index_search`_ - ### cuvsMultiGpuIvfFlatSearch @@ -290,8 +280,6 @@ _Source: `c/include/cuvs/neighbors/mg_ivf_flat.h:175`_ ## Multi-GPU IVF-Flat index extend -_Doxygen group: `mg_ivf_flat_c_index_extend`_ - ### cuvsMultiGpuIvfFlatExtend @@ -323,8 +311,6 @@ _Source: `c/include/cuvs/neighbors/mg_ivf_flat.h:200`_ ## Multi-GPU IVF-Flat index serialize -_Doxygen group: `mg_ivf_flat_c_index_serialize`_ - ### cuvsMultiGpuIvfFlatSerialize @@ -354,8 +340,6 @@ _Source: `c/include/cuvs/neighbors/mg_ivf_flat.h:222`_ ## Multi-GPU IVF-Flat index deserialize -_Doxygen group: `mg_ivf_flat_c_index_deserialize`_ - ### cuvsMultiGpuIvfFlatDeserialize @@ -385,8 +369,6 @@ _Source: `c/include/cuvs/neighbors/mg_ivf_flat.h:243`_ ## Multi-GPU IVF-Flat index distribute -_Doxygen group: `mg_ivf_flat_c_index_distribute`_ - ### cuvsMultiGpuIvfFlatDistribute diff --git a/fern/pages/c_api/c-api-neighbors-mg-ivf-pq.md b/fern/pages/c_api/c-api-neighbors-mg-ivf-pq.md index 2807bb9b77..6ba1841745 100644 --- a/fern/pages/c_api/c-api-neighbors-mg-ivf-pq.md +++ b/fern/pages/c_api/c-api-neighbors-mg-ivf-pq.md @@ -8,8 +8,6 @@ _Source header: `c/include/cuvs/neighbors/mg_ivf_pq.h`_ ## Multi-GPU IVF-PQ index build parameters -_Doxygen group: `mg_ivf_pq_c_index_params`_ - ### cuvsMultiGpuIvfPqIndexParams @@ -78,8 +76,6 @@ _Source: `c/include/cuvs/neighbors/mg_ivf_pq.h:51`_ ## Multi-GPU IVF-PQ index search parameters -_Doxygen group: `mg_ivf_pq_c_search_params`_ - ### cuvsMultiGpuIvfPqSearchParams @@ -150,8 +146,6 @@ _Source: `c/include/cuvs/neighbors/mg_ivf_pq.h:94`_ ## Multi-GPU IVF-PQ index -_Doxygen group: `mg_ivf_pq_c_index`_ - ### cuvsMultiGpuIvfPqIndex @@ -220,8 +214,6 @@ _Source: `c/include/cuvs/neighbors/mg_ivf_pq.h:130`_ ## Multi-GPU IVF-PQ index build -_Doxygen group: `mg_ivf_pq_c_index_build`_ - ### cuvsMultiGpuIvfPqBuild @@ -253,8 +245,6 @@ _Source: `c/include/cuvs/neighbors/mg_ivf_pq.h:150`_ ## Multi-GPU IVF-PQ index search -_Doxygen group: `mg_ivf_pq_c_index_search`_ - ### cuvsMultiGpuIvfPqSearch @@ -290,8 +280,6 @@ _Source: `c/include/cuvs/neighbors/mg_ivf_pq.h:175`_ ## Multi-GPU IVF-PQ index extend -_Doxygen group: `mg_ivf_pq_c_index_extend`_ - ### cuvsMultiGpuIvfPqExtend @@ -323,8 +311,6 @@ _Source: `c/include/cuvs/neighbors/mg_ivf_pq.h:200`_ ## Multi-GPU IVF-PQ index serialize -_Doxygen group: `mg_ivf_pq_c_index_serialize`_ - ### cuvsMultiGpuIvfPqSerialize @@ -354,8 +340,6 @@ _Source: `c/include/cuvs/neighbors/mg_ivf_pq.h:222`_ ## Multi-GPU IVF-PQ index deserialize -_Doxygen group: `mg_ivf_pq_c_index_deserialize`_ - ### cuvsMultiGpuIvfPqDeserialize @@ -385,8 +369,6 @@ _Source: `c/include/cuvs/neighbors/mg_ivf_pq.h:243`_ ## Multi-GPU IVF-PQ index distribute -_Doxygen group: `mg_ivf_pq_c_index_distribute`_ - ### cuvsMultiGpuIvfPqDistribute diff --git a/fern/pages/c_api/c-api-neighbors-nn-descent.md b/fern/pages/c_api/c-api-neighbors-nn-descent.md index 916499051d..df20eb674f 100644 --- a/fern/pages/c_api/c-api-neighbors-nn-descent.md +++ b/fern/pages/c_api/c-api-neighbors-nn-descent.md @@ -29,8 +29,6 @@ _Source: `c/include/cuvs/neighbors/nn_descent.h:24`_ ## The nn-descent algorithm parameters. -_Doxygen group: `nn_descent_c_index_params`_ - ### cuvsNNDescentIndexParams @@ -105,8 +103,6 @@ _Source: `c/include/cuvs/neighbors/nn_descent.h:79`_ ## NN-Descent index -_Doxygen group: `nn_descent_c_index`_ - ### cuvsNNDescentIndex @@ -171,8 +167,6 @@ _Source: `c/include/cuvs/neighbors/nn_descent.h:112`_ ## NN-Descent index build -_Doxygen group: `nn_descent_c_index_build`_ - ### cuvsNNDescentBuild diff --git a/fern/pages/c_api/c-api-neighbors-refine.md b/fern/pages/c_api/c-api-neighbors-refine.md index c73f45bfce..8afe844201 100644 --- a/fern/pages/c_api/c-api-neighbors-refine.md +++ b/fern/pages/c_api/c-api-neighbors-refine.md @@ -8,8 +8,6 @@ _Source header: `c/include/cuvs/neighbors/refine.h`_ ## Approximate Nearest Neighbors Refinement C-API -_Doxygen group: `ann_refine_c`_ - ### cuvsRefine diff --git a/fern/pages/c_api/c-api-neighbors-tiered-index.md b/fern/pages/c_api/c-api-neighbors-tiered-index.md index 7be0a86f73..e9a2d52b7a 100644 --- a/fern/pages/c_api/c-api-neighbors-tiered-index.md +++ b/fern/pages/c_api/c-api-neighbors-tiered-index.md @@ -29,8 +29,6 @@ _Source: `c/include/cuvs/neighbors/tiered_index.h:24`_ ## Tiered Index -_Doxygen group: `tiered_index_c_index`_ - ### cuvsTieredIndex @@ -98,8 +96,6 @@ _Source: `c/include/cuvs/neighbors/tiered_index.h:60`_ ## Tiered Index build parameters -_Doxygen group: `tiered_c_index_params`_ - ### cuvsTieredIndexParams @@ -171,8 +167,6 @@ _Source: `c/include/cuvs/neighbors/tiered_index.h:113`_ ## Tiered index build -_Doxygen group: `tieredindex_c_index_build`_ - ### cuvsTieredIndexBuild @@ -209,8 +203,6 @@ _Source: `c/include/cuvs/neighbors/tiered_index.h:162`_ ## Tiered index search -_Doxygen group: `tieredindex_c_index_search`_ - ### cuvsTieredIndexSearch @@ -248,8 +240,6 @@ _Source: `c/include/cuvs/neighbors/tiered_index.h:212`_ ## Tiered index extend -_Doxygen group: `tiered_c_index_extend`_ - ### cuvsTieredIndexExtend @@ -279,8 +269,6 @@ _Source: `c/include/cuvs/neighbors/tiered_index.h:235`_ ## Tiered index merge -_Doxygen group: `tiered_c_index_merge`_ - ### cuvsTieredIndexMerge diff --git a/fern/pages/c_api/c-api-neighbors-vamana.md b/fern/pages/c_api/c-api-neighbors-vamana.md index c2df69c0cb..243ee27785 100644 --- a/fern/pages/c_api/c-api-neighbors-vamana.md +++ b/fern/pages/c_api/c-api-neighbors-vamana.md @@ -8,8 +8,6 @@ _Source header: `c/include/cuvs/neighbors/vamana.h`_ ## C API for Vamana index build -_Doxygen group: `vamana_c_index_params`_ - ### cuvsVamanaIndexParams @@ -85,8 +83,6 @@ _Source: `c/include/cuvs/neighbors/vamana.h:77`_ ## Vamana index -_Doxygen group: `vamana_c_index`_ - ### cuvsVamanaIndex @@ -177,8 +173,6 @@ _Source: `c/include/cuvs/neighbors/vamana.h:123`_ ## Vamana index build -_Doxygen group: `vamana_c_index_build`_ - ### cuvsVamanaBuild @@ -220,8 +214,6 @@ _Source: `c/include/cuvs/neighbors/vamana.h:169`_ ## Vamana index serialize -_Doxygen group: `vamana_c_index_serialize`_ - ### cuvsVamanaSerialize diff --git a/fern/pages/c_api/c-api-preprocessing-pca.md b/fern/pages/c_api/c-api-preprocessing-pca.md index 21470d2375..d5219ec555 100644 --- a/fern/pages/c_api/c-api-preprocessing-pca.md +++ b/fern/pages/c_api/c-api-preprocessing-pca.md @@ -8,8 +8,6 @@ _Source header: `c/include/cuvs/preprocessing/pca.h`_ ## C API for PCA (Principal Component Analysis) -_Doxygen group: `preprocessing_c_pca`_ - ### cuvsPcaSolver diff --git a/fern/pages/c_api/c-api-preprocessing-quantize-binary.md b/fern/pages/c_api/c-api-preprocessing-quantize-binary.md index cea4f53736..e2c23ef949 100644 --- a/fern/pages/c_api/c-api-preprocessing-quantize-binary.md +++ b/fern/pages/c_api/c-api-preprocessing-quantize-binary.md @@ -8,8 +8,6 @@ _Source header: `c/include/cuvs/preprocessing/quantize/binary.h`_ ## C API for Binary Quantizer -_Doxygen group: `preprocessing_c_binary`_ - ### cuvsBinaryQuantizerThreshold diff --git a/fern/pages/c_api/c-api-preprocessing-quantize-pq.md b/fern/pages/c_api/c-api-preprocessing-quantize-pq.md index 14af2b8394..2eae37e65c 100644 --- a/fern/pages/c_api/c-api-preprocessing-quantize-pq.md +++ b/fern/pages/c_api/c-api-preprocessing-quantize-pq.md @@ -8,8 +8,6 @@ _Source header: `c/include/cuvs/preprocessing/quantize/pq.h`_ ## C API for Product Quantizer -_Doxygen group: `preprocessing_c_pq`_ - ### cuvsProductQuantizerParams diff --git a/fern/pages/c_api/c-api-preprocessing-quantize-scalar.md b/fern/pages/c_api/c-api-preprocessing-quantize-scalar.md index 4f7fdb4c98..de46f55550 100644 --- a/fern/pages/c_api/c-api-preprocessing-quantize-scalar.md +++ b/fern/pages/c_api/c-api-preprocessing-quantize-scalar.md @@ -8,8 +8,6 @@ _Source header: `c/include/cuvs/preprocessing/quantize/scalar.h`_ ## C API for Scalar Quantizer -_Doxygen group: `preprocessing_c_scalar`_ - ### cuvsScalarQuantizerParams diff --git a/fern/pages/cpp_api/cpp-api-cluster-agglomerative.md b/fern/pages/cpp_api/cpp-api-cluster-agglomerative.md index 1c4271d63b..ed44cc97b4 100644 --- a/fern/pages/cpp_api/cpp-api-cluster-agglomerative.md +++ b/fern/pages/cpp_api/cpp-api-cluster-agglomerative.md @@ -8,8 +8,6 @@ _Source header: `cpp/include/cuvs/cluster/agglomerative.hpp`_ ## agglomerative clustering hyperparameters -_Doxygen group: `agglomerative_params`_ - ### cuvs::cluster::agglomerative::Linkage @@ -30,8 +28,6 @@ _Source: `cpp/include/cuvs/cluster/agglomerative.hpp:30`_ ## single-linkage clustering APIs -_Doxygen group: `single_linkage`_ - ### cuvs::cluster::agglomerative::single_linkage diff --git a/fern/pages/cpp_api/cpp-api-cluster-kmeans.md b/fern/pages/cpp_api/cpp-api-cluster-kmeans.md index 89ca3f4508..c00d071d61 100644 --- a/fern/pages/cpp_api/cpp-api-cluster-kmeans.md +++ b/fern/pages/cpp_api/cpp-api-cluster-kmeans.md @@ -27,8 +27,6 @@ _Source: `cpp/include/cuvs/cluster/kmeans.hpp:19`_ ## k-means hyperparameters -_Doxygen group: `kmeans_params`_ - ### cuvs::cluster::kmeans::params @@ -101,8 +99,6 @@ _Source: `cpp/include/cuvs/cluster/kmeans.hpp:149`_ ## k-means clustering APIs -_Doxygen group: `kmeans`_ - ### cuvs::cluster::kmeans::fit @@ -1140,8 +1136,6 @@ _Source: `cpp/include/cuvs/cluster/kmeans.hpp:1566`_ ## k-means API helpers -_Doxygen group: `kmeans_helpers`_ - ### helpers::find_k diff --git a/fern/pages/cpp_api/cpp-api-cluster-spectral.md b/fern/pages/cpp_api/cpp-api-cluster-spectral.md index 792614bc5a..e6cb9a61c7 100644 --- a/fern/pages/cpp_api/cpp-api-cluster-spectral.md +++ b/fern/pages/cpp_api/cpp-api-cluster-spectral.md @@ -8,8 +8,6 @@ _Source header: `cpp/include/cuvs/cluster/spectral.hpp`_ ## Spectral Clustering Parameters -_Doxygen group: `spectral_params`_ - ### cuvs::cluster::spectral::params @@ -34,8 +32,6 @@ _Source: `cpp/include/cuvs/cluster/spectral.hpp:22`_ ## Spectral Clustering -_Doxygen group: `spectral`_ - ### cuvs::cluster::spectral::fit_predict diff --git a/fern/pages/cpp_api/cpp-api-distance-distance.md b/fern/pages/cpp_api/cpp-api-distance-distance.md index 741f239a3d..156a923fd0 100644 --- a/fern/pages/cpp_api/cpp-api-distance-distance.md +++ b/fern/pages/cpp_api/cpp-api-distance-distance.md @@ -98,8 +98,6 @@ _Source: `cpp/include/cuvs/distance/distance.hpp:111`_ ## Pairwise Distances API -_Doxygen group: `pairwise_distance`_ - ### kernels::pairwise_distance diff --git a/fern/pages/cpp_api/cpp-api-neighbors-all-neighbors.md b/fern/pages/cpp_api/cpp-api-neighbors-all-neighbors.md index a7dce2d886..8ecd20d0f1 100644 --- a/fern/pages/cpp_api/cpp-api-neighbors-all-neighbors.md +++ b/fern/pages/cpp_api/cpp-api-neighbors-all-neighbors.md @@ -8,8 +8,6 @@ _Source header: `cpp/include/cuvs/neighbors/all_neighbors.hpp`_ ## The all-neighbors algorithm parameters. -_Doxygen group: `all_neighbors_cpp_params`_ - ### GraphBuildParams @@ -47,8 +45,6 @@ _Source: `cpp/include/cuvs/neighbors/all_neighbors.hpp:37`_ ## The all-neighbors knn graph build -_Doxygen group: `all_neighbors_cpp_build`_ - ### cuvs::neighbors::all_neighbors::build diff --git a/fern/pages/cpp_api/cpp-api-neighbors-ball-cover.md b/fern/pages/cpp_api/cpp-api-neighbors-ball-cover.md index ea2edb0fc9..f8366d4884 100644 --- a/fern/pages/cpp_api/cpp-api-neighbors-ball-cover.md +++ b/fern/pages/cpp_api/cpp-api-neighbors-ball-cover.md @@ -8,8 +8,6 @@ _Source header: `cpp/include/cuvs/neighbors/ball_cover.hpp`_ ## Random Ball Cover algorithm -_Doxygen group: `random_ball_cover`_ - ### cuvs::neighbors::ball_cover::build diff --git a/fern/pages/cpp_api/cpp-api-neighbors-brute-force.md b/fern/pages/cpp_api/cpp-api-neighbors-brute-force.md index 0e56f231aa..198e7c869c 100644 --- a/fern/pages/cpp_api/cpp-api-neighbors-brute-force.md +++ b/fern/pages/cpp_api/cpp-api-neighbors-brute-force.md @@ -8,8 +8,6 @@ _Source header: `cpp/include/cuvs/neighbors/brute_force.hpp`_ ## Bruteforce index -_Doxygen group: `bruteforce_cpp_index`_ - ### cuvs::neighbors::brute_force::index @@ -337,8 +335,6 @@ _Source: `cpp/include/cuvs/neighbors/brute_force.hpp:156`_ ## Bruteforce index build -_Doxygen group: `bruteforce_cpp_index_build`_ - ### cuvs::neighbors::brute_force::build @@ -512,8 +508,6 @@ _Source: `cpp/include/cuvs/neighbors/brute_force.hpp:298`_ ## Sparse Brute Force index -_Doxygen group: `sparse_bruteforce_cpp_index`_ - ### cuvs::neighbors::brute_force::sparse_index @@ -571,8 +565,6 @@ _Source: `cpp/include/cuvs/neighbors/brute_force.hpp:618`_ ## Sparse Brute Force index search -_Doxygen group: `sparse_bruteforce_cpp_index_search`_ - ### cuvs::neighbors::brute_force::sparse_search_params @@ -586,8 +578,6 @@ _Source: `cpp/include/cuvs/neighbors/brute_force.hpp:668`_ ## Bruteforce index serialize functions -_Doxygen group: `bruteforce_cpp_index_serialize`_ - ### cuvs::neighbors::brute_force::serialize diff --git a/fern/pages/cpp_api/cpp-api-neighbors-cagra.md b/fern/pages/cpp_api/cpp-api-neighbors-cagra.md index fa2e9cb22e..35b306e808 100644 --- a/fern/pages/cpp_api/cpp-api-neighbors-cagra.md +++ b/fern/pages/cpp_api/cpp-api-neighbors-cagra.md @@ -32,8 +32,6 @@ _Source: `cpp/include/cuvs/neighbors/cagra.hpp:37`_ ## CAGRA index build parameters -_Doxygen group: `cagra_cpp_index_params`_ - ### cuvs::neighbors::vpq_params @@ -112,8 +110,6 @@ _Source: `cpp/include/cuvs/neighbors/cagra.hpp:245`_ ## CAGRA index search parameters -_Doxygen group: `cagra_cpp_search_params`_ - ### cuvs::neighbors::cagra::search_algo @@ -136,8 +132,6 @@ _Source: `cpp/include/cuvs/neighbors/cagra.hpp:262`_ ## CAGRA index extend parameters -_Doxygen group: `cagra_cpp_extend_params`_ - ### cuvs::neighbors::cagra::extend_params @@ -157,8 +151,6 @@ _Source: `cpp/include/cuvs/neighbors/cagra.hpp:357`_ ## CAGRA index type -_Doxygen group: `cagra_cpp_index`_ - ### cuvs::neighbors::cagra::metric @@ -686,8 +678,6 @@ _Source: `cpp/include/cuvs/neighbors/cagra.hpp:834`_ ## CAGRA index build functions -_Doxygen group: `cagra_cpp_index_build`_ - ### cuvs::neighbors::cagra::build @@ -997,8 +987,6 @@ _Source: `cpp/include/cuvs/neighbors/cagra.hpp:1202`_ ## CAGRA extend functions -_Doxygen group: `cagra_cpp_index_extend`_ - ### cuvs::neighbors::cagra::extend @@ -1290,8 +1278,6 @@ _Source: `cpp/include/cuvs/neighbors/cagra.hpp:1510`_ ## CAGRA search functions -_Doxygen group: `cagra_cpp_index_search`_ - ### none_sample_filter @@ -1312,8 +1298,6 @@ _Source: `cpp/include/cuvs/neighbors/cagra.hpp:1541`_ ## CAGRA serialize functions -_Doxygen group: `cagra_cpp_serialize`_ - ### cuvs::neighbors::cagra::serialize diff --git a/fern/pages/cpp_api/cpp-api-neighbors-common.md b/fern/pages/cpp_api/cpp-api-neighbors-common.md index 53e2596722..293c77d0e5 100644 --- a/fern/pages/cpp_api/cpp-api-neighbors-common.md +++ b/fern/pages/cpp_api/cpp-api-neighbors-common.md @@ -8,8 +8,6 @@ _Source header: `cpp/include/cuvs/neighbors/common.hpp`_ ## Approximate Nearest Neighbors Types -_Doxygen group: `neighbors_index`_ - ### cuvs::neighbors::index @@ -61,8 +59,6 @@ _Source: `cpp/include/cuvs/neighbors/common.hpp:125`_ ## Filtering for ANN Types -_Doxygen group: `neighbors_filtering`_ - ### filtering::FilterType @@ -197,8 +193,6 @@ _Source: `cpp/include/cuvs/neighbors/common.hpp:608`_ ## ANN MG index build parameters -_Doxygen group: `mg_cpp_index_params`_ - ### ivf::distribution_mode @@ -210,8 +204,6 @@ _Source: `cpp/include/cuvs/neighbors/common.hpp:904`_ ## ANN MG search parameters -_Doxygen group: `mg_cpp_search_params`_ - ### ivf::replicated_search_mode diff --git a/fern/pages/cpp_api/cpp-api-neighbors-dynamic-batching.md b/fern/pages/cpp_api/cpp-api-neighbors-dynamic-batching.md index 121b4b771a..dca1cb04b1 100644 --- a/fern/pages/cpp_api/cpp-api-neighbors-dynamic-batching.md +++ b/fern/pages/cpp_api/cpp-api-neighbors-dynamic-batching.md @@ -8,8 +8,6 @@ _Source header: `cpp/include/cuvs/neighbors/dynamic_batching.hpp`_ ## Dynamic Batching index parameters -_Doxygen group: `dynamic_batching_cpp_index_params`_ - ### detail::index_params @@ -32,8 +30,6 @@ _Source: `cpp/include/cuvs/neighbors/dynamic_batching.hpp:21`_ ## Dynamic Batching search parameters -_Doxygen group: `dynamic_batching_cpp_search_params`_ - ### detail::search_params @@ -53,8 +49,6 @@ _Source: `cpp/include/cuvs/neighbors/dynamic_batching.hpp:60`_ ## Dynamic Batching index type -_Doxygen group: `dynamic_batching_cpp_index`_ - ### detail::index @@ -93,8 +87,6 @@ _Source: `cpp/include/cuvs/neighbors/dynamic_batching.hpp:174`_ ## Dynamic Batching search -_Doxygen group: `dynamic_batching_cpp_search`_ - ### detail::search diff --git a/fern/pages/cpp_api/cpp-api-neighbors-epsilon-neighborhood.md b/fern/pages/cpp_api/cpp-api-neighbors-epsilon-neighborhood.md index a81427dece..c521fe6d5f 100644 --- a/fern/pages/cpp_api/cpp-api-neighbors-epsilon-neighborhood.md +++ b/fern/pages/cpp_api/cpp-api-neighbors-epsilon-neighborhood.md @@ -8,8 +8,6 @@ _Source header: `cpp/include/cuvs/neighbors/epsilon_neighborhood.hpp`_ ## Epsilon Neighborhood L2 Operations -_Doxygen group: `epsilon_neighborhood_cpp_l2`_ - ### cuvs::neighbors::epsilon_neighborhood::compute diff --git a/fern/pages/cpp_api/cpp-api-neighbors-hnsw.md b/fern/pages/cpp_api/cpp-api-neighbors-hnsw.md index 6099d653b9..1439e92db5 100644 --- a/fern/pages/cpp_api/cpp-api-neighbors-hnsw.md +++ b/fern/pages/cpp_api/cpp-api-neighbors-hnsw.md @@ -8,8 +8,6 @@ _Source header: `cpp/include/cuvs/neighbors/hnsw.hpp`_ ## hnswlib index wrapper params -_Doxygen group: `hnsw_cpp_index_params`_ - ### cuvs::neighbors::hnsw::HnswHierarchy @@ -63,8 +61,6 @@ _Source: `cpp/include/cuvs/neighbors/hnsw.hpp:114`_ ## hnswlib index wrapper -_Doxygen group: `hnsw_cpp_index`_ - ### template <typename T> @@ -155,8 +151,6 @@ _Source: `cpp/include/cuvs/neighbors/hnsw.hpp:169`_ ## HNSW index extend parameters -_Doxygen group: `hnsw_cpp_extend_params`_ - ### cuvs::neighbors::hnsw::extend_params @@ -176,8 +170,6 @@ _Source: `cpp/include/cuvs/neighbors/hnsw.hpp:186`_ ## Build HNSW index on the GPU -_Doxygen group: `hnsw_cpp_index_build`_ - ### cuvs::neighbors::hnsw::build @@ -313,8 +305,6 @@ _Source: `cpp/include/cuvs/neighbors/hnsw.hpp:428`_ ## Load CAGRA index as hnswlib index -_Doxygen group: `hnsw_cpp_index_load`_ - ### cuvs::neighbors::hnsw::from_cagra @@ -458,8 +448,6 @@ _Source: `cpp/include/cuvs/neighbors/hnsw.hpp:579`_ ## Extend HNSW index with additional vectors -_Doxygen group: `hnsw_cpp_index_extend`_ - ### cuvs::neighbors::hnsw::extend @@ -583,8 +571,6 @@ _Source: `cpp/include/cuvs/neighbors/hnsw.hpp:726`_ ## Build CAGRA index and search with hnswlib -_Doxygen group: `hnsw_cpp_search_params`_ - ### cuvs::neighbors::hnsw::search_params @@ -605,8 +591,6 @@ _Source: `cpp/include/cuvs/neighbors/hnsw.hpp:740`_ ## Search hnswlib index -_Doxygen group: `hnsw_cpp_index_search`_ - ### cuvs::neighbors::hnsw::search @@ -754,8 +738,6 @@ _Source: `cpp/include/cuvs/neighbors/hnsw.hpp:926`_ ## Deserialize CAGRA index as hnswlib index -_Doxygen group: `hnsw_cpp_index_serialize`_ - ### cuvs::neighbors::hnsw::serialize diff --git a/fern/pages/cpp_api/cpp-api-neighbors-ivf-flat.md b/fern/pages/cpp_api/cpp-api-neighbors-ivf-flat.md index b068c1a660..01518b22d9 100644 --- a/fern/pages/cpp_api/cpp-api-neighbors-ivf-flat.md +++ b/fern/pages/cpp_api/cpp-api-neighbors-ivf-flat.md @@ -8,8 +8,6 @@ _Source header: `cpp/include/cuvs/neighbors/ivf_flat.hpp`_ ## IVF-Flat index search parameters -_Doxygen group: `ivf_flat_cpp_search_params`_ - ### cuvs::neighbors::ivf_flat::search_params @@ -51,8 +49,6 @@ _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:108`_ ## IVF-Flat index -_Doxygen group: `ivf_flat_cpp_index`_ - ### cuvs::neighbors::ivf_flat::index @@ -337,8 +333,6 @@ _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:257`_ ## IVF-Flat index build -_Doxygen group: `ivf_flat_cpp_index_build`_ - ### cuvs::neighbors::ivf_flat::build @@ -926,8 +920,6 @@ _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:824`_ ## IVF-Flat index extend -_Doxygen group: `ivf_flat_cpp_index_extend`_ - ### cuvs::neighbors::ivf_flat::extend @@ -1435,8 +1427,6 @@ _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:1393`_ ## IVF-Flat index serialize -_Doxygen group: `ivf_flat_cpp_serialize`_ - ### cuvs::neighbors::ivf_flat::serialize @@ -1857,8 +1847,6 @@ _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:2018`_ ## Helper functions for IVF Flat -_Doxygen group: `ivf_flat_helpers`_ - ### namespace codepacker \{ diff --git a/fern/pages/cpp_api/cpp-api-neighbors-ivf-pq.md b/fern/pages/cpp_api/cpp-api-neighbors-ivf-pq.md index 4d6cc919a0..fea57e2524 100644 --- a/fern/pages/cpp_api/cpp-api-neighbors-ivf-pq.md +++ b/fern/pages/cpp_api/cpp-api-neighbors-ivf-pq.md @@ -8,8 +8,6 @@ _Source header: `cpp/include/cuvs/neighbors/ivf_pq.hpp`_ ## IVF-PQ index build parameters -_Doxygen group: `ivf_pq_cpp_index_params`_ - ### cuvs::neighbors::ivf_pq::codebook_gen @@ -60,8 +58,6 @@ _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:145`_ ## IVF-PQ index search parameters -_Doxygen group: `ivf_pq_cpp_search_params`_ - ### cuvs::neighbors::ivf_pq::search_params @@ -119,8 +115,6 @@ _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:3364`_ ## IVF-PQ index -_Doxygen group: `ivf_pq_cpp_index`_ - ### cuvs::neighbors::ivf_pq::index @@ -598,8 +592,6 @@ _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:663`_ ## IVF-PQ index build -_Doxygen group: `ivf_pq_cpp_index_build`_ - ### cuvs::neighbors::ivf_pq::build @@ -1285,8 +1277,6 @@ _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:1253`_ ## IVF-PQ index extend -_Doxygen group: `ivf_pq_cpp_index_extend`_ - ### cuvs::neighbors::ivf_pq::extend @@ -1762,8 +1752,6 @@ _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:1770`_ ## IVF-PQ index transform -_Doxygen group: `ivf_pq_cpp_transform`_ - ### cuvs::neighbors::ivf_pq::transform @@ -1875,8 +1863,6 @@ _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:1999`_ ## IVF-PQ index serialize -_Doxygen group: `ivf_pq_cpp_serialize`_ - ### cuvs::neighbors::ivf_pq::serialize @@ -1977,8 +1963,6 @@ _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:2106`_ ## IVF-PQ helper methods -_Doxygen group: `ivf_pq_cpp_helpers`_ - ### namespace codepacker \{ diff --git a/fern/pages/cpp_api/cpp-api-neighbors-nn-descent.md b/fern/pages/cpp_api/cpp-api-neighbors-nn-descent.md index 4646e77cbe..b7ebca2440 100644 --- a/fern/pages/cpp_api/cpp-api-neighbors-nn-descent.md +++ b/fern/pages/cpp_api/cpp-api-neighbors-nn-descent.md @@ -8,8 +8,6 @@ _Source header: `cpp/include/cuvs/neighbors/nn_descent.hpp`_ ## The nn-descent algorithm parameters. -_Doxygen group: `nn_descent_cpp_index_params`_ - ### cuvs::neighbors::nn_descent::DIST_COMP_DTYPE @@ -75,8 +73,6 @@ _Source: `cpp/include/cuvs/neighbors/nn_descent.hpp:69`_ ## nn-descent index -_Doxygen group: `nn_descent_cpp_index`_ - ### cuvs::neighbors::nn_descent::index @@ -220,8 +216,6 @@ _Source: `cpp/include/cuvs/neighbors/nn_descent.hpp:182`_ ## nn-descent index build -_Doxygen group: `nn_descent_cpp_index_build`_ - ### cuvs::neighbors::nn_descent::build diff --git a/fern/pages/cpp_api/cpp-api-neighbors-refine.md b/fern/pages/cpp_api/cpp-api-neighbors-refine.md index 47179def7a..089386aed6 100644 --- a/fern/pages/cpp_api/cpp-api-neighbors-refine.md +++ b/fern/pages/cpp_api/cpp-api-neighbors-refine.md @@ -8,8 +8,6 @@ _Source header: `cpp/include/cuvs/neighbors/refine.hpp`_ ## Approximate Nearest Neighbors Refinement -_Doxygen group: `ann_refine`_ - ### cuvs::neighbors::refine diff --git a/fern/pages/cpp_api/cpp-api-neighbors-scann.md b/fern/pages/cpp_api/cpp-api-neighbors-scann.md index adc396d677..c3722352d8 100644 --- a/fern/pages/cpp_api/cpp-api-neighbors-scann.md +++ b/fern/pages/cpp_api/cpp-api-neighbors-scann.md @@ -8,8 +8,6 @@ _Source header: `cpp/include/cuvs/neighbors/scann.hpp`_ ## ScaNN index build parameters -_Doxygen group: `scann_cpp_index_params`_ - ### cuvs::neighbors::experimental::scann::index_params @@ -39,8 +37,6 @@ _Source: `cpp/include/cuvs/neighbors/scann.hpp:36`_ ## ScaNN index type -_Doxygen group: `scann_cpp_index`_ - ### cuvs::neighbors::experimental::scann::metric @@ -88,8 +84,6 @@ _Source: `cpp/include/cuvs/neighbors/scann.hpp:119`_ ## ScaNN index build functions -_Doxygen group: `scann_cpp_index_build`_ - ### cuvs::neighbors::experimental::scann::build @@ -147,8 +141,6 @@ _Source: `cpp/include/cuvs/neighbors/scann.hpp:316`_ ## ScaNN serialize functions -_Doxygen group: `scann_cpp_serialize`_ - **Additional overload:** `cuvs::neighbors::experimental::scann::serialize` Save the index to files in a directory diff --git a/fern/pages/cpp_api/cpp-api-neighbors-vamana.md b/fern/pages/cpp_api/cpp-api-neighbors-vamana.md index e45890bf90..746939b906 100644 --- a/fern/pages/cpp_api/cpp-api-neighbors-vamana.md +++ b/fern/pages/cpp_api/cpp-api-neighbors-vamana.md @@ -8,8 +8,6 @@ _Source header: `cpp/include/cuvs/neighbors/vamana.hpp`_ ## Vamana index build parameters -_Doxygen group: `vamana_cpp_index_params`_ - ### cuvs::neighbors::vamana::index_params @@ -39,8 +37,6 @@ _Source: `cpp/include/cuvs/neighbors/vamana.hpp:56`_ ## Vamana index type -_Doxygen group: `vamana_cpp_index`_ - ### cuvs::neighbors::vamana::metric @@ -313,8 +309,6 @@ _Source: `cpp/include/cuvs/neighbors/vamana.hpp:240`_ ## Vamana index build functions -_Doxygen group: `vamana_cpp_index_build`_ - ### cuvs::neighbors::vamana::build @@ -528,8 +522,6 @@ _Source: `cpp/include/cuvs/neighbors/vamana.hpp:475`_ ## Vamana serialize functions -_Doxygen group: `vamana_cpp_serialize`_ - ### cuvs::neighbors::vamana::serialize @@ -623,8 +615,6 @@ _Source: `cpp/include/cuvs/neighbors/vamana.hpp:574`_ ## Vamana codebook functions -_Doxygen group: `vamana_cpp_codebook`_ - ### cuvs::neighbors::vamana::deserialize_codebooks diff --git a/fern/pages/cpp_api/cpp-api-preprocessing-pca.md b/fern/pages/cpp_api/cpp-api-preprocessing-pca.md index 7718d74692..2218500f5f 100644 --- a/fern/pages/cpp_api/cpp-api-preprocessing-pca.md +++ b/fern/pages/cpp_api/cpp-api-preprocessing-pca.md @@ -34,8 +34,6 @@ _Source: `cpp/include/cuvs/preprocessing/pca.hpp:20`_ ## PCA (Principal Component Analysis) -_Doxygen group: `pca`_ - ### cuvs::preprocessing::pca::fit diff --git a/fern/pages/cpp_api/cpp-api-preprocessing-quantize-binary.md b/fern/pages/cpp_api/cpp-api-preprocessing-quantize-binary.md index 834a12f544..2e42e5c9af 100644 --- a/fern/pages/cpp_api/cpp-api-preprocessing-quantize-binary.md +++ b/fern/pages/cpp_api/cpp-api-preprocessing-quantize-binary.md @@ -8,8 +8,6 @@ _Source header: `cpp/include/cuvs/preprocessing/quantize/binary.hpp`_ ## Binary quantizer utilities -_Doxygen group: `binary`_ - ### cuvs::preprocessing::quantize::binary::bit_threshold diff --git a/fern/pages/cpp_api/cpp-api-preprocessing-quantize-pq.md b/fern/pages/cpp_api/cpp-api-preprocessing-quantize-pq.md index 50481de695..4f57c94742 100644 --- a/fern/pages/cpp_api/cpp-api-preprocessing-quantize-pq.md +++ b/fern/pages/cpp_api/cpp-api-preprocessing-quantize-pq.md @@ -8,8 +8,6 @@ _Source header: `cpp/include/cuvs/preprocessing/quantize/pq.hpp`_ ## Product Quantizer utilities -_Doxygen group: `pq`_ - ### kmeans_params_variant diff --git a/fern/pages/cpp_api/cpp-api-preprocessing-quantize-scalar.md b/fern/pages/cpp_api/cpp-api-preprocessing-quantize-scalar.md index cedd70d57d..e2232c5927 100644 --- a/fern/pages/cpp_api/cpp-api-preprocessing-quantize-scalar.md +++ b/fern/pages/cpp_api/cpp-api-preprocessing-quantize-scalar.md @@ -8,8 +8,6 @@ _Source header: `cpp/include/cuvs/preprocessing/quantize/scalar.hpp`_ ## Scalar quantizer utilities -_Doxygen group: `scalar`_ - ### cuvs::preprocessing::quantize::scalar::params diff --git a/fern/pages/cpp_api/cpp-api-preprocessing-spectral-embedding.md b/fern/pages/cpp_api/cpp-api-preprocessing-spectral-embedding.md index e7c2980b4e..7c13ad8ae9 100644 --- a/fern/pages/cpp_api/cpp-api-preprocessing-spectral-embedding.md +++ b/fern/pages/cpp_api/cpp-api-preprocessing-spectral-embedding.md @@ -34,8 +34,6 @@ _Source: `cpp/include/cuvs/preprocessing/spectral_embedding.hpp:25`_ ## Spectral Embedding -_Doxygen group: `spectral_embedding`_ - ### cuvs::preprocessing::spectral_embedding::transform diff --git a/fern/pages/cpp_api/cpp-api-selection-select-k.md b/fern/pages/cpp_api/cpp-api-selection-select-k.md index cfb7baa8e0..fefba6e6d6 100644 --- a/fern/pages/cpp_api/cpp-api-selection-select-k.md +++ b/fern/pages/cpp_api/cpp-api-selection-select-k.md @@ -8,8 +8,6 @@ _Source header: `cpp/include/cuvs/selection/select_k.hpp`_ ## Batched-select k smallest or largest key/values -_Doxygen group: `select_k`_ - ### cuvs::selection::select_k diff --git a/fern/pages/cpp_api/cpp-api-stats-silhouette-score.md b/fern/pages/cpp_api/cpp-api-stats-silhouette-score.md index 71517ee488..ee2b94ddc3 100644 --- a/fern/pages/cpp_api/cpp-api-stats-silhouette-score.md +++ b/fern/pages/cpp_api/cpp-api-stats-silhouette-score.md @@ -8,8 +8,6 @@ _Source header: `cpp/include/cuvs/stats/silhouette_score.hpp`_ ## Silhouette Score -_Doxygen group: `stats_silhouette_score`_ - ### stats::silhouette_score diff --git a/fern/pages/cpp_api/cpp-api-stats-trustworthiness-score.md b/fern/pages/cpp_api/cpp-api-stats-trustworthiness-score.md index 040529d3b6..4967ae6dd6 100644 --- a/fern/pages/cpp_api/cpp-api-stats-trustworthiness-score.md +++ b/fern/pages/cpp_api/cpp-api-stats-trustworthiness-score.md @@ -8,8 +8,6 @@ _Source header: `cpp/include/cuvs/stats/trustworthiness_score.hpp`_ ## Trustworthiness -_Doxygen group: `stats_trustworthiness`_ - ### stats::trustworthiness_score diff --git a/fern/scripts/generate_api_reference.py b/fern/scripts/generate_api_reference.py index c9e4a36402..c4871381bb 100755 --- a/fern/scripts/generate_api_reference.py +++ b/fern/scripts/generate_api_reference.py @@ -556,8 +556,6 @@ def render_native_group( symbol_links: dict[str, str] | None = None, ) -> list[str]: lines = [f"## {heading_text(group.title or group.name)}", ""] - if group.name and not is_synthetic_native_group(group.name): - lines.extend([f"_Doxygen group: `{group.name}`_", ""]) if page_headings is None: page_headings = set() From 93bccb36391e920afbba3cad83c7c57d6959e163 Mon Sep 17 00:00:00 2001 From: "Corey J. Nolet" Date: Thu, 7 May 2026 13:43:23 -0400 Subject: [PATCH 009/129] Exclude detail namespace APIs from Fern docs --- .../cpp_api/cpp-api-cluster-agglomerative.md | 22 ++--- fern/pages/cpp_api/cpp-api-cluster-kmeans.md | 4 +- .../cpp_api/cpp-api-distance-distance.md | 22 ++--- .../pages/cpp_api/cpp-api-neighbors-common.md | 42 ++++----- .../cpp-api-neighbors-dynamic-batching.md | 48 +++++----- .../cpp_api/cpp-api-neighbors-ivf-flat.md | 60 ++++++------- .../pages/cpp_api/cpp-api-neighbors-ivf-pq.md | 90 +++++++++---------- .../cpp_api/cpp-api-stats-silhouette-score.md | 12 +-- .../cpp-api-stats-trustworthiness-score.md | 4 +- fern/scripts/generate_api_reference.py | 36 ++++++-- 10 files changed, 180 insertions(+), 160 deletions(-) diff --git a/fern/pages/cpp_api/cpp-api-cluster-agglomerative.md b/fern/pages/cpp_api/cpp-api-cluster-agglomerative.md index ed44cc97b4..4ed5be2bf9 100644 --- a/fern/pages/cpp_api/cpp-api-cluster-agglomerative.md +++ b/fern/pages/cpp_api/cpp-api-cluster-agglomerative.md @@ -66,8 +66,8 @@ scale the algorithm beyond the n^2 memory consumption of implementations that us _Source: `cpp/include/cuvs/cluster/agglomerative.hpp:104`_ - -### linkage_graph_params::distance_params + +### cuvs::cluster::agglomerative::helpers::linkage_graph_params::distance_params Specialized parameters to build the KNN graph with regular distances @@ -84,8 +84,8 @@ struct distance_params { ... } ; _Source: `cpp/include/cuvs/cluster/agglomerative.hpp:118`_ - -### linkage_graph_params::mutual_reachability_params + +### cuvs::cluster::agglomerative::helpers::linkage_graph_params::mutual_reachability_params Specialized parameters to build the Mutual Reachability graph @@ -103,8 +103,8 @@ struct mutual_reachability_params { ... } ; _Source: `cpp/include/cuvs/cluster/agglomerative.hpp:130`_ - -### linkage_graph_params::build_linkage + +### cuvs::cluster::agglomerative::helpers::build_linkage Given a dataset, builds the KNN graph, connects graph components and builds a linkage @@ -130,7 +130,7 @@ std::optional> core_dists); | --- | --- | --- | --- | | `handle` | in | `raft::resources const&` | raft handle for resource reuse | | `X` | in | `raft::device_matrix_view` | data points on device memory (size n_rows * d) | -| `linkage_graph_params` | in | [`std::variant`](/api-reference/cpp-api-cluster-agglomerative#linkage-graph-params-mutual-reachability-params) | Parameters controlling how the KNN graph is built. This can be either:
- distance_params: standard distance-based KNN graph construction for traditional agglomerative clustering.
- mutual_reachability_params: parameters to compute a mutual reachability graph for density-aware hierarchical clustering (e.g. HDBSCAN). | +| `linkage_graph_params` | in | [`std::variant`](/api-reference/cpp-api-cluster-agglomerative#cuvs-cluster-agglomerative-helpers-linkage-graph-params-mutual-reachability-params) | Parameters controlling how the KNN graph is built. This can be either:
- distance_params: standard distance-based KNN graph construction for traditional agglomerative clustering.
- mutual_reachability_params: parameters to compute a mutual reachability graph for density-aware hierarchical clustering (e.g. HDBSCAN). | | `metric` | in | [`cuvs::distance::DistanceType`](/api-reference/cpp-api-distance-distance#cuvs-distance-distancetype) | distance metric to use | | `out_mst` | out | `raft::device_coo_matrix_view` | output MST sorted by edge weights (size n_rows - 1) | | `dendrogram` | out | `raft::device_matrix_view` | output dendrogram (size [n_rows - 1] * 2) | @@ -144,7 +144,7 @@ std::optional> core_dists); _Source: `cpp/include/cuvs/cluster/agglomerative.hpp:188`_ -**Additional overload:** `linkage_graph_params::build_linkage` +**Additional overload:** `cuvs::cluster::agglomerative::helpers::build_linkage` Given a dataset, builds the KNN graph, connects graph components and builds a linkage @@ -170,7 +170,7 @@ std::optional> core_dists); | --- | --- | --- | --- | | `handle` | in | `raft::resources const&` | raft handle for resource reuse | | `X` | in | `raft::host_matrix_view` | data points on host memory (size n_rows * d) | -| `linkage_graph_params` | in | [`std::variant`](/api-reference/cpp-api-cluster-agglomerative#linkage-graph-params-mutual-reachability-params) | Parameters controlling how the KNN graph is built. This can be either:
- distance_params: standard distance-based KNN graph construction for traditional agglomerative clustering.
- mutual_reachability_params: parameters to compute a mutual reachability graph for density-aware hierarchical clustering (e.g. HDBSCAN). | +| `linkage_graph_params` | in | [`std::variant`](/api-reference/cpp-api-cluster-agglomerative#cuvs-cluster-agglomerative-helpers-linkage-graph-params-mutual-reachability-params) | Parameters controlling how the KNN graph is built. This can be either:
- distance_params: standard distance-based KNN graph construction for traditional agglomerative clustering.
- mutual_reachability_params: parameters to compute a mutual reachability graph for density-aware hierarchical clustering (e.g. HDBSCAN). | | `metric` | in | [`cuvs::distance::DistanceType`](/api-reference/cpp-api-distance-distance#cuvs-distance-distancetype) | distance metric to use | | `out_mst` | out | `raft::device_coo_matrix_view` | output MST sorted by edge weights (size n_rows - 1) | | `dendrogram` | out | `raft::device_matrix_view` | output dendrogram (size [n_rows - 1] * 2) | @@ -184,8 +184,8 @@ std::optional> core_dists); _Source: `cpp/include/cuvs/cluster/agglomerative.hpp:219`_ - -### linkage_graph_params::build_dendrogram + +### cuvs::cluster::agglomerative::helpers::build_dendrogram Build dendrogram from a Minimum Spanning Tree (MST). diff --git a/fern/pages/cpp_api/cpp-api-cluster-kmeans.md b/fern/pages/cpp_api/cpp-api-cluster-kmeans.md index c00d071d61..9d7ae3a7e2 100644 --- a/fern/pages/cpp_api/cpp-api-cluster-kmeans.md +++ b/fern/pages/cpp_api/cpp-api-cluster-kmeans.md @@ -1136,8 +1136,8 @@ _Source: `cpp/include/cuvs/cluster/kmeans.hpp:1566`_ ## k-means API helpers - -### helpers::find_k + +### cuvs::cluster::kmeans::helpers::find_k Automatically find the optimal value of k using a binary search. diff --git a/fern/pages/cpp_api/cpp-api-distance-distance.md b/fern/pages/cpp_api/cpp-api-distance-distance.md index 156a923fd0..e36d995b94 100644 --- a/fern/pages/cpp_api/cpp-api-distance-distance.md +++ b/fern/pages/cpp_api/cpp-api-distance-distance.md @@ -69,8 +69,8 @@ enum class DensityKernelType : int { ... } ; _Source: `cpp/include/cuvs/distance/distance.hpp:91`_ - -### kernels::KernelParams + +### cuvs::distance::kernels::KernelParams Parameters for kernel matrices. @@ -98,8 +98,8 @@ _Source: `cpp/include/cuvs/distance/distance.hpp:111`_ ## Pairwise Distances API - -### kernels::pairwise_distance + +### cuvs::distance::pairwise_distance Compute pairwise distances for two matrices @@ -134,7 +134,7 @@ Usage example: _Source: `cpp/include/cuvs/distance/distance.hpp:161`_ -**Additional overload:** `kernels::pairwise_distance` +**Additional overload:** `cuvs::distance::pairwise_distance` Compute pairwise distances for two matrices @@ -169,7 +169,7 @@ Usage example: _Source: `cpp/include/cuvs/distance/distance.hpp:205`_ -**Additional overload:** `kernels::pairwise_distance` +**Additional overload:** `cuvs::distance::pairwise_distance` Compute pairwise distances for two matrices @@ -204,7 +204,7 @@ Usage example: _Source: `cpp/include/cuvs/distance/distance.hpp:248`_ -**Additional overload:** `kernels::pairwise_distance` +**Additional overload:** `cuvs::distance::pairwise_distance` Compute pairwise distances for two matrices @@ -239,7 +239,7 @@ Usage example: _Source: `cpp/include/cuvs/distance/distance.hpp:292`_ -**Additional overload:** `kernels::pairwise_distance` +**Additional overload:** `cuvs::distance::pairwise_distance` Compute pairwise distances for two matrices @@ -274,7 +274,7 @@ Usage example: _Source: `cpp/include/cuvs/distance/distance.hpp:335`_ -**Additional overload:** `kernels::pairwise_distance` +**Additional overload:** `cuvs::distance::pairwise_distance` Compute pairwise distances for two matrices @@ -309,7 +309,7 @@ Usage example: _Source: `cpp/include/cuvs/distance/distance.hpp:378`_ -**Additional overload:** `kernels::pairwise_distance` +**Additional overload:** `cuvs::distance::pairwise_distance` Compute sparse pairwise distances between x and y, using the provided @@ -341,7 +341,7 @@ input configuration and distance function. _Source: `cpp/include/cuvs/distance/distance.hpp:419`_ -**Additional overload:** `kernels::pairwise_distance` +**Additional overload:** `cuvs::distance::pairwise_distance` Compute sparse pairwise distances between x and y, using the provided diff --git a/fern/pages/cpp_api/cpp-api-neighbors-common.md b/fern/pages/cpp_api/cpp-api-neighbors-common.md index 293c77d0e5..98d02dcace 100644 --- a/fern/pages/cpp_api/cpp-api-neighbors-common.md +++ b/fern/pages/cpp_api/cpp-api-neighbors-common.md @@ -59,8 +59,8 @@ _Source: `cpp/include/cuvs/neighbors/common.hpp:125`_ ## Filtering for ANN Types - -### filtering::FilterType + +### cuvs::neighbors::filtering::FilterType Filtering for ANN Types @@ -78,8 +78,8 @@ enum class FilterType { ... } ; _Source: `cpp/include/cuvs/neighbors/common.hpp:496`_ - -### filtering::operator + +### cuvs::neighbors::filtering::operator ```cpp constexpr __forceinline__ _RAFT_HOST_DEVICE bool operator()( @@ -97,8 +97,8 @@ const uint32_t sample_ix) const; _Source: `cpp/include/cuvs/neighbors/common.hpp:506`_ - -### filtering::get_filter_type + +### cuvs::neighbors::filtering::get_filter_type ```cpp FilterType get_filter_type() const override; @@ -106,11 +106,11 @@ FilterType get_filter_type() const override; **Returns** -[`FilterType`](/api-reference/cpp-api-neighbors-common#filtering-filtertype) +[`FilterType`](/api-reference/cpp-api-neighbors-common#cuvs-neighbors-filtering-filtertype) _Source: `cpp/include/cuvs/neighbors/common.hpp:520`_ -**Additional overload:** `filtering::operator` +**Additional overload:** `cuvs::neighbors::filtering::operator` If the original filter takes three arguments, then don't modify the arguments. @@ -132,7 +132,7 @@ If the original filter takes two arguments, then we are using `inds_ptr_` to obt _Source: `cpp/include/cuvs/neighbors/common.hpp:544`_ -**Additional overload:** `filtering::operator` +**Additional overload:** `cuvs::neighbors::filtering::operator` ```cpp inline _RAFT_HOST_DEVICE bool operator()( @@ -148,7 +148,7 @@ const uint32_t sample_ix) const; _Source: `cpp/include/cuvs/neighbors/common.hpp:571`_ -**Additional overload:** `filtering::get_filter_type` +**Additional overload:** `cuvs::neighbors::filtering::get_filter_type` ```cpp FilterType get_filter_type() const override; @@ -156,12 +156,12 @@ FilterType get_filter_type() const override; **Returns** -[`FilterType`](/api-reference/cpp-api-neighbors-common#filtering-filtertype) +[`FilterType`](/api-reference/cpp-api-neighbors-common#cuvs-neighbors-filtering-filtertype) _Source: `cpp/include/cuvs/neighbors/common.hpp:578`_ - -### filtering::bitset_filter + +### cuvs::neighbors::filtering::bitset_filter ```cpp _RAFT_HOST_DEVICE bitset_filter(const view_t bitset_for_filtering); @@ -179,7 +179,7 @@ _RAFT_HOST_DEVICE bitset_filter(const view_t bitset_for_filtering); _Source: `cpp/include/cuvs/neighbors/common.hpp:600`_ -**Additional overload:** `filtering::get_filter_type` +**Additional overload:** `cuvs::neighbors::filtering::get_filter_type` ```cpp FilterType get_filter_type() const override; @@ -187,14 +187,14 @@ FilterType get_filter_type() const override; **Returns** -[`FilterType`](/api-reference/cpp-api-neighbors-common#filtering-filtertype) +[`FilterType`](/api-reference/cpp-api-neighbors-common#cuvs-neighbors-filtering-filtertype) _Source: `cpp/include/cuvs/neighbors/common.hpp:608`_ ## ANN MG index build parameters - -### ivf::distribution_mode + +### cuvs::neighbors::distribution_mode ```cpp enum distribution_mode { ... } ; @@ -204,8 +204,8 @@ _Source: `cpp/include/cuvs/neighbors/common.hpp:904`_ ## ANN MG search parameters - -### ivf::replicated_search_mode + +### cuvs::neighbors::replicated_search_mode ```cpp enum replicated_search_mode { ... } ; @@ -220,8 +220,8 @@ enum replicated_search_mode { ... } ; _Source: `cpp/include/cuvs/neighbors/common.hpp:915`_ - -### ivf::sharded_merge_mode + +### cuvs::neighbors::sharded_merge_mode ```cpp enum sharded_merge_mode { ... } ; diff --git a/fern/pages/cpp_api/cpp-api-neighbors-dynamic-batching.md b/fern/pages/cpp_api/cpp-api-neighbors-dynamic-batching.md index dca1cb04b1..9a8a7a7134 100644 --- a/fern/pages/cpp_api/cpp-api-neighbors-dynamic-batching.md +++ b/fern/pages/cpp_api/cpp-api-neighbors-dynamic-batching.md @@ -8,8 +8,8 @@ _Source header: `cpp/include/cuvs/neighbors/dynamic_batching.hpp`_ ## Dynamic Batching index parameters - -### detail::index_params + +### cuvs::neighbors::dynamic_batching::index_params Dynamic Batching index parameters @@ -30,8 +30,8 @@ _Source: `cpp/include/cuvs/neighbors/dynamic_batching.hpp:21`_ ## Dynamic Batching search parameters - -### detail::search_params + +### cuvs::neighbors::dynamic_batching::search_params Dynamic Batching search parameters @@ -49,8 +49,8 @@ _Source: `cpp/include/cuvs/neighbors/dynamic_batching.hpp:60`_ ## Dynamic Batching index type - -### detail::index + +### cuvs::neighbors::dynamic_batching::index Construct a dynamic batching index by wrapping the upstream index. @@ -74,7 +74,7 @@ const cuvs::neighbors::filtering::base_filter* sample_filter = nullptr); | Name | Direction | Type | Description | | --- | --- | --- | --- | | `res` | in | `const raft::resources&` | raft resources | -| `params` | in | [`const cuvs::neighbors::dynamic_batching::index_params&`](/api-reference/cpp-api-neighbors-dynamic-batching#detail-index-params) | dynamic batching parameters | +| `params` | in | [`const cuvs::neighbors::dynamic_batching::index_params&`](/api-reference/cpp-api-neighbors-dynamic-batching#cuvs-neighbors-dynamic-batching-index-params) | dynamic batching parameters | | `upstream_index` | in | `const Upstream&` | the original index to perform the search (the reference must be alive for the lifetime of the dynamic batching index) | | `upstream_params` | in | `const typename Upstream::search_params_type&` | the original index search parameters for all queries in a batch (the parameters are captured by value for the lifetime of the dynamic batching index) | | `sample_filter` | in | `const cuvs::neighbors::filtering::base_filter*` | filtering function, if any, must be the same for all requests in a batch (the pointer must be alive for the lifetime of the dynamic batching index) Default: `nullptr`. | @@ -87,8 +87,8 @@ _Source: `cpp/include/cuvs/neighbors/dynamic_batching.hpp:174`_ ## Dynamic Batching search - -### detail::search + +### cuvs::neighbors::dynamic_batching::search Search ANN using a dynamic batching index. @@ -112,7 +112,7 @@ Dynamic batching search is thread-safe: call the search function with copies of | Name | Direction | Type | Description | | --- | --- | --- | --- | | `res` | in | `raft::resources const&` | | -| `params` | in | [`cuvs::neighbors::dynamic_batching::search_params const&`](/api-reference/cpp-api-neighbors-dynamic-batching#detail-search-params) | query-specific batching parameters, such as the maximum waiting time | +| `params` | in | [`cuvs::neighbors::dynamic_batching::search_params const&`](/api-reference/cpp-api-neighbors-dynamic-batching#cuvs-neighbors-dynamic-batching-search-params) | query-specific batching parameters, such as the maximum waiting time | | `index` | in | `dynamic_batching::index const&` | a dynamic batching index | | `queries` | in | `raft::device_matrix_view` | a device matrix view to a row-major matrix [n_queries, dim] | | `neighbors` | out | `raft::device_matrix_view` | a device matrix view to the indices of the neighbors in the source dataset [n_queries, k] | @@ -124,7 +124,7 @@ Dynamic batching search is thread-safe: call the search function with copies of _Source: `cpp/include/cuvs/neighbors/dynamic_batching.hpp:214`_ -**Additional overload:** `detail::search` +**Additional overload:** `cuvs::neighbors::dynamic_batching::search` ```cpp void search(raft::resources const& res, @@ -140,7 +140,7 @@ raft::device_matrix_view distances); | Name | Direction | Type | Description | | --- | --- | --- | --- | | `res` | | `raft::resources const&` | | -| `params` | | [`cuvs::neighbors::dynamic_batching::search_params const&`](/api-reference/cpp-api-neighbors-dynamic-batching#detail-search-params) | | +| `params` | | [`cuvs::neighbors::dynamic_batching::search_params const&`](/api-reference/cpp-api-neighbors-dynamic-batching#cuvs-neighbors-dynamic-batching-search-params) | | | `index` | | `dynamic_batching::index const&` | | | `queries` | | `raft::device_matrix_view` | | | `neighbors` | | `raft::device_matrix_view` | | @@ -152,7 +152,7 @@ raft::device_matrix_view distances); _Source: `cpp/include/cuvs/neighbors/dynamic_batching.hpp:222`_ -**Additional overload:** `detail::search` +**Additional overload:** `cuvs::neighbors::dynamic_batching::search` ```cpp void search(raft::resources const& res, @@ -168,7 +168,7 @@ raft::device_matrix_view distances); | Name | Direction | Type | Description | | --- | --- | --- | --- | | `res` | | `raft::resources const&` | | -| `params` | | [`cuvs::neighbors::dynamic_batching::search_params const&`](/api-reference/cpp-api-neighbors-dynamic-batching#detail-search-params) | | +| `params` | | [`cuvs::neighbors::dynamic_batching::search_params const&`](/api-reference/cpp-api-neighbors-dynamic-batching#cuvs-neighbors-dynamic-batching-search-params) | | | `index` | | `dynamic_batching::index const&` | | | `queries` | | `raft::device_matrix_view` | | | `neighbors` | | `raft::device_matrix_view` | | @@ -180,7 +180,7 @@ raft::device_matrix_view distances); _Source: `cpp/include/cuvs/neighbors/dynamic_batching.hpp:230`_ -**Additional overload:** `detail::search` +**Additional overload:** `cuvs::neighbors::dynamic_batching::search` ```cpp void search(raft::resources const& res, @@ -196,7 +196,7 @@ raft::device_matrix_view distances); | Name | Direction | Type | Description | | --- | --- | --- | --- | | `res` | | `raft::resources const&` | | -| `params` | | [`cuvs::neighbors::dynamic_batching::search_params const&`](/api-reference/cpp-api-neighbors-dynamic-batching#detail-search-params) | | +| `params` | | [`cuvs::neighbors::dynamic_batching::search_params const&`](/api-reference/cpp-api-neighbors-dynamic-batching#cuvs-neighbors-dynamic-batching-search-params) | | | `index` | | `dynamic_batching::index const&` | | | `queries` | | `raft::device_matrix_view` | | | `neighbors` | | `raft::device_matrix_view` | | @@ -208,7 +208,7 @@ raft::device_matrix_view distances); _Source: `cpp/include/cuvs/neighbors/dynamic_batching.hpp:238`_ -**Additional overload:** `detail::search` +**Additional overload:** `cuvs::neighbors::dynamic_batching::search` ```cpp void search(raft::resources const& res, @@ -224,7 +224,7 @@ raft::device_matrix_view distances); | Name | Direction | Type | Description | | --- | --- | --- | --- | | `res` | | `raft::resources const&` | | -| `params` | | [`cuvs::neighbors::dynamic_batching::search_params const&`](/api-reference/cpp-api-neighbors-dynamic-batching#detail-search-params) | | +| `params` | | [`cuvs::neighbors::dynamic_batching::search_params const&`](/api-reference/cpp-api-neighbors-dynamic-batching#cuvs-neighbors-dynamic-batching-search-params) | | | `index` | | `dynamic_batching::index const&` | | | `queries` | | `raft::device_matrix_view` | | | `neighbors` | | `raft::device_matrix_view` | | @@ -236,7 +236,7 @@ raft::device_matrix_view distances); _Source: `cpp/include/cuvs/neighbors/dynamic_batching.hpp:246`_ -**Additional overload:** `detail::search` +**Additional overload:** `cuvs::neighbors::dynamic_batching::search` ```cpp void search(raft::resources const& res, @@ -252,7 +252,7 @@ raft::device_matrix_view distances); | Name | Direction | Type | Description | | --- | --- | --- | --- | | `res` | | `raft::resources const&` | | -| `params` | | [`cuvs::neighbors::dynamic_batching::search_params const&`](/api-reference/cpp-api-neighbors-dynamic-batching#detail-search-params) | | +| `params` | | [`cuvs::neighbors::dynamic_batching::search_params const&`](/api-reference/cpp-api-neighbors-dynamic-batching#cuvs-neighbors-dynamic-batching-search-params) | | | `index` | | `dynamic_batching::index const&` | | | `queries` | | `raft::device_matrix_view` | | | `neighbors` | | `raft::device_matrix_view` | | @@ -264,7 +264,7 @@ raft::device_matrix_view distances); _Source: `cpp/include/cuvs/neighbors/dynamic_batching.hpp:254`_ -**Additional overload:** `detail::search` +**Additional overload:** `cuvs::neighbors::dynamic_batching::search` ```cpp void search(raft::resources const& res, @@ -280,7 +280,7 @@ raft::device_matrix_view distances); | Name | Direction | Type | Description | | --- | --- | --- | --- | | `res` | | `raft::resources const&` | | -| `params` | | [`cuvs::neighbors::dynamic_batching::search_params const&`](/api-reference/cpp-api-neighbors-dynamic-batching#detail-search-params) | | +| `params` | | [`cuvs::neighbors::dynamic_batching::search_params const&`](/api-reference/cpp-api-neighbors-dynamic-batching#cuvs-neighbors-dynamic-batching-search-params) | | | `index` | | `dynamic_batching::index const&` | | | `queries` | | `raft::device_matrix_view` | | | `neighbors` | | `raft::device_matrix_view` | | @@ -292,7 +292,7 @@ raft::device_matrix_view distances); _Source: `cpp/include/cuvs/neighbors/dynamic_batching.hpp:262`_ -**Additional overload:** `detail::search` +**Additional overload:** `cuvs::neighbors::dynamic_batching::search` ```cpp void search(raft::resources const& res, @@ -308,7 +308,7 @@ raft::device_matrix_view distances); | Name | Direction | Type | Description | | --- | --- | --- | --- | | `res` | | `raft::resources const&` | | -| `params` | | [`cuvs::neighbors::dynamic_batching::search_params const&`](/api-reference/cpp-api-neighbors-dynamic-batching#detail-search-params) | | +| `params` | | [`cuvs::neighbors::dynamic_batching::search_params const&`](/api-reference/cpp-api-neighbors-dynamic-batching#cuvs-neighbors-dynamic-batching-search-params) | | | `index` | | `dynamic_batching::index const&` | | | `queries` | | `raft::device_matrix_view` | | | `neighbors` | | `raft::device_matrix_view` | | diff --git a/fern/pages/cpp_api/cpp-api-neighbors-ivf-flat.md b/fern/pages/cpp_api/cpp-api-neighbors-ivf-flat.md index 01518b22d9..870568208e 100644 --- a/fern/pages/cpp_api/cpp-api-neighbors-ivf-flat.md +++ b/fern/pages/cpp_api/cpp-api-neighbors-ivf-flat.md @@ -1858,8 +1858,8 @@ namespace codepacker { _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:2484`_ - -### codepacker::pack + +### cuvs::neighbors::ivf_flat::helpers::codepacker::pack Write flat codes into an existing list by the given offset. @@ -1893,7 +1893,7 @@ Usage example: _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:2508`_ -**Additional overload:** `codepacker::pack` +**Additional overload:** `cuvs::neighbors::ivf_flat::helpers::codepacker::pack` Write flat codes into an existing list by the given offset. @@ -1927,7 +1927,7 @@ Usage example: _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:2538`_ -**Additional overload:** `codepacker::pack` +**Additional overload:** `cuvs::neighbors::ivf_flat::helpers::codepacker::pack` Write flat codes into an existing list by the given offset. @@ -1961,7 +1961,7 @@ Usage example: _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:2568`_ -**Additional overload:** `codepacker::pack` +**Additional overload:** `cuvs::neighbors::ivf_flat::helpers::codepacker::pack` Write flat codes into an existing list by the given offset. @@ -1995,8 +1995,8 @@ Usage example: _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:2598`_ - -### codepacker::unpack + +### cuvs::neighbors::ivf_flat::helpers::codepacker::unpack Unpack `n_take` consecutive records of a single list (cluster) in the compressed index @@ -2030,7 +2030,7 @@ Usage example: _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:2631`_ -**Additional overload:** `codepacker::unpack` +**Additional overload:** `cuvs::neighbors::ivf_flat::helpers::codepacker::unpack` Unpack `n_take` consecutive records of a single list (cluster) in the compressed index @@ -2064,7 +2064,7 @@ Usage example: _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:2664`_ -**Additional overload:** `codepacker::unpack` +**Additional overload:** `cuvs::neighbors::ivf_flat::helpers::codepacker::unpack` Unpack `n_take` consecutive records of a single list (cluster) in the compressed index @@ -2098,7 +2098,7 @@ Usage example: _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:2696`_ -**Additional overload:** `codepacker::unpack` +**Additional overload:** `cuvs::neighbors::ivf_flat::helpers::codepacker::unpack` Unpack `n_take` consecutive records of a single list (cluster) in the compressed index @@ -2132,8 +2132,8 @@ Usage example: _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:2729`_ - -### codepacker::pack_1 + +### cuvs::neighbors::ivf_flat::helpers::codepacker::pack_1 Write one flat code into a block by the given offset. The offset indicates the id of the record @@ -2159,7 +2159,7 @@ in the list. This function interleaves the code and is intended to later copy th _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:2749`_ -**Additional overload:** `codepacker::pack_1` +**Additional overload:** `cuvs::neighbors::ivf_flat::helpers::codepacker::pack_1` Write one flat code into a block by the given offset. The offset indicates the id of the record @@ -2185,7 +2185,7 @@ in the list. This function interleaves the code and is intended to later copy th _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:2763`_ -**Additional overload:** `codepacker::pack_1` +**Additional overload:** `cuvs::neighbors::ivf_flat::helpers::codepacker::pack_1` Write one flat code into a block by the given offset. The offset indicates the id of the record @@ -2211,7 +2211,7 @@ in the list. This function interleaves the code and is intended to later copy th _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:2777`_ -**Additional overload:** `codepacker::pack_1` +**Additional overload:** `cuvs::neighbors::ivf_flat::helpers::codepacker::pack_1` Write one flat code into a block by the given offset. The offset indicates the id of the record @@ -2238,8 +2238,8 @@ in the list. This function interleaves the code and is intended to later copy th _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:2791`_ - -### codepacker::unpack_1 + +### cuvs::neighbors::ivf_flat::helpers::codepacker::unpack_1 Unpack 1 record of a single list (cluster) in the index to fetch the flat code. The offset @@ -2267,7 +2267,7 @@ interleaved format. _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:2805`_ -**Additional overload:** `codepacker::unpack_1` +**Additional overload:** `cuvs::neighbors::ivf_flat::helpers::codepacker::unpack_1` Unpack 1 record of a single list (cluster) in the index to fetch the flat code. The offset @@ -2295,7 +2295,7 @@ interleaved format. _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:2818`_ -**Additional overload:** `codepacker::unpack_1` +**Additional overload:** `cuvs::neighbors::ivf_flat::helpers::codepacker::unpack_1` Unpack 1 record of a single list (cluster) in the index to fetch the flat code. The offset @@ -2324,7 +2324,7 @@ interleaved format. _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:2831`_ -**Additional overload:** `codepacker::unpack_1` +**Additional overload:** `cuvs::neighbors::ivf_flat::helpers::codepacker::unpack_1` Unpack 1 record of a single list (cluster) in the index to fetch the flat code. The offset @@ -2353,8 +2353,8 @@ interleaved format. _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:2845`_ - -### codepacker::reset_index + +### cuvs::neighbors::ivf_flat::helpers::reset_index Public helper API to reset the data and indices ptrs, and the list sizes. Useful for @@ -2379,7 +2379,7 @@ Usage example: _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:2870`_ -**Additional overload:** `codepacker::reset_index` +**Additional overload:** `cuvs::neighbors::ivf_flat::helpers::reset_index` Public helper API to reset the data and indices ptrs, and the list sizes. Useful for @@ -2404,7 +2404,7 @@ Usage example: _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:2892`_ -**Additional overload:** `codepacker::reset_index` +**Additional overload:** `cuvs::neighbors::ivf_flat::helpers::reset_index` Public helper API to reset the data and indices ptrs, and the list sizes. Useful for @@ -2429,7 +2429,7 @@ Usage example: _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:2914`_ -**Additional overload:** `codepacker::reset_index` +**Additional overload:** `cuvs::neighbors::ivf_flat::helpers::reset_index` Public helper API to reset the data and indices ptrs, and the list sizes. Useful for @@ -2454,8 +2454,8 @@ Usage example: _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:2936`_ - -### codepacker::recompute_internal_state + +### cuvs::neighbors::ivf_flat::helpers::recompute_internal_state Helper exposing the re-computation of list sizes and related arrays if IVF lists have been @@ -2480,7 +2480,7 @@ Usage example: _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:2964`_ -**Additional overload:** `codepacker::recompute_internal_state` +**Additional overload:** `cuvs::neighbors::ivf_flat::helpers::recompute_internal_state` Helper exposing the re-computation of list sizes and related arrays if IVF lists have been @@ -2505,7 +2505,7 @@ Usage example: _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:2992`_ -**Additional overload:** `codepacker::recompute_internal_state` +**Additional overload:** `cuvs::neighbors::ivf_flat::helpers::recompute_internal_state` Helper exposing the re-computation of list sizes and related arrays if IVF lists have been @@ -2530,7 +2530,7 @@ Usage example: _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:3020`_ -**Additional overload:** `codepacker::recompute_internal_state` +**Additional overload:** `cuvs::neighbors::ivf_flat::helpers::recompute_internal_state` Helper exposing the re-computation of list sizes and related arrays if IVF lists have been diff --git a/fern/pages/cpp_api/cpp-api-neighbors-ivf-pq.md b/fern/pages/cpp_api/cpp-api-neighbors-ivf-pq.md index fea57e2524..368bb564f7 100644 --- a/fern/pages/cpp_api/cpp-api-neighbors-ivf-pq.md +++ b/fern/pages/cpp_api/cpp-api-neighbors-ivf-pq.md @@ -1974,8 +1974,8 @@ namespace codepacker { _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:2561`_ - -### codepacker::unpack + +### cuvs::neighbors::ivf_pq::helpers::codepacker::unpack Unpack `n_take` consecutive records of a single list (cluster) in the compressed index @@ -2011,8 +2011,8 @@ Usage example: _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:2594`_ - -### codepacker::unpack_contiguous + +### cuvs::neighbors::ivf_pq::helpers::codepacker::unpack_contiguous Unpack `n_rows` consecutive records of a single list (cluster) in the compressed index @@ -2050,8 +2050,8 @@ Usage example: _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:2634`_ - -### codepacker::pack + +### cuvs::neighbors::ivf_pq::helpers::codepacker::pack Write flat PQ codes into an existing list by the given offset. @@ -2085,8 +2085,8 @@ Usage example: _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:2666`_ - -### codepacker::pack_contiguous + +### cuvs::neighbors::ivf_pq::helpers::codepacker::pack_contiguous Write flat PQ codes into an existing list by the given offset. The input codes of a single vector @@ -2126,8 +2126,8 @@ Usage example: _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:2702`_ - -### codepacker::pack_list_data + +### cuvs::neighbors::ivf_pq::helpers::codepacker::pack_list_data Write flat PQ codes into an existing list by the given offset. @@ -2161,8 +2161,8 @@ Usage example: _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:2736`_ - -### codepacker::pack_contiguous_list_data + +### cuvs::neighbors::ivf_pq::helpers::codepacker::pack_contiguous_list_data Write flat PQ codes into an existing list by the given offset. Use this when the input @@ -2200,8 +2200,8 @@ Usage example: _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:2779`_ - -### codepacker::unpack_list_data + +### cuvs::neighbors::ivf_pq::helpers::codepacker::unpack_list_data Unpack `n_take` consecutive records of a single list (cluster) in the compressed index @@ -2233,7 +2233,7 @@ Usage example: _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:2815`_ -**Additional overload:** `codepacker::unpack_list_data` +**Additional overload:** `cuvs::neighbors::ivf_pq::helpers::codepacker::unpack_list_data` Unpack a series of records of a single list (cluster) in the compressed index @@ -2265,8 +2265,8 @@ Usage example: _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:2851`_ - -### codepacker::unpack_contiguous_list_data + +### cuvs::neighbors::ivf_pq::helpers::codepacker::unpack_contiguous_list_data Unpack `n_rows` consecutive PQ encoded vectors of a single list (cluster) in the @@ -2300,8 +2300,8 @@ Usage example: _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:2892`_ - -### codepacker::reconstruct_list_data + +### cuvs::neighbors::ivf_pq::helpers::codepacker::reconstruct_list_data Decode `n_take` consecutive records of a single list (cluster) in the compressed index @@ -2333,7 +2333,7 @@ Usage example: _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:2929`_ -**Additional overload:** `codepacker::reconstruct_list_data` +**Additional overload:** `cuvs::neighbors::ivf_pq::helpers::codepacker::reconstruct_list_data` Decode a series of records of a single list (cluster) in the compressed index @@ -2365,8 +2365,8 @@ Usage example: _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:2984`_ - -### codepacker::extend_list_with_codes + +### cuvs::neighbors::ivf_pq::helpers::codepacker::extend_list_with_codes Extend one list of the index in-place, by the list label, skipping the classification and @@ -2399,8 +2399,8 @@ Usage example: _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:3032`_ - -### codepacker::extend_list_with_contiguous_codes + +### cuvs::neighbors::ivf_pq::helpers::codepacker::extend_list_with_contiguous_codes Extend one list of the index in-place, by the list label, skipping the classification and @@ -2435,8 +2435,8 @@ Usage example: _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:3071`_ - -### codepacker::extend_list + +### cuvs::neighbors::ivf_pq::helpers::codepacker::extend_list Extend one list of the index in-place, by the list label, skipping the classification @@ -2468,8 +2468,8 @@ Usage example: _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:3106`_ - -### codepacker::erase_list + +### cuvs::neighbors::ivf_pq::helpers::erase_list Remove all data from a single list (cluster) in the index. @@ -2493,8 +2493,8 @@ Usage example: _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:3141`_ - -### codepacker::reset_index + +### cuvs::neighbors::ivf_pq::helpers::reset_index Public helper API to reset the data and indices ptrs, and the list sizes. Useful for @@ -2519,8 +2519,8 @@ Usage example: _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:3163`_ - -### codepacker::pad_centers_with_norms + +### cuvs::neighbors::ivf_pq::helpers::pad_centers_with_norms Pad cluster centers with their L2 norms for efficient GEMM operations. @@ -2547,7 +2547,7 @@ This function takes cluster centers and pads them with their L2 norms to create _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:3176`_ -**Additional overload:** `codepacker::pad_centers_with_norms` +**Additional overload:** `cuvs::neighbors::ivf_pq::helpers::pad_centers_with_norms` Pad cluster centers with their L2 norms for efficient GEMM operations. @@ -2574,8 +2574,8 @@ This function takes cluster centers and pads them with their L2 norms to create _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:3192`_ - -### codepacker::rotate_padded_centers + +### cuvs::neighbors::ivf_pq::helpers::rotate_padded_centers Rotate padded centers with the rotation matrix. @@ -2602,8 +2602,8 @@ raft::device_matrix_view rotated_centers); _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:3205`_ - -### codepacker::extract_centers + +### cuvs::neighbors::ivf_pq::helpers::extract_centers Public helper API for fetching a trained index's IVF centroids @@ -2629,7 +2629,7 @@ Usage example: _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:3228`_ -**Additional overload:** `codepacker::extract_centers` +**Additional overload:** `cuvs::neighbors::ivf_pq::helpers::extract_centers` ```cpp void extract_centers(raft::resources const& res, @@ -2651,8 +2651,8 @@ raft::host_matrix_view cluster_centers); _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:3233`_ - -### codepacker::recompute_internal_state + +### cuvs::neighbors::ivf_pq::helpers::recompute_internal_state Helper exposing the re-computation of list sizes and related arrays if IVF lists have been @@ -2677,8 +2677,8 @@ Usage example: _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:3262`_ - -### codepacker::make_rotation_matrix + +### cuvs::neighbors::ivf_pq::helpers::make_rotation_matrix Generate a rotation matrix into user-provided buffer (standalone version). @@ -2707,8 +2707,8 @@ Usage example: _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:3289`_ - -### codepacker::resize_list + +### cuvs::neighbors::ivf_pq::helpers::resize_list Resize an IVF-PQ list with flat layout. @@ -2740,7 +2740,7 @@ Usage example: _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:3319`_ -**Additional overload:** `codepacker::resize_list` +**Additional overload:** `cuvs::neighbors::ivf_pq::helpers::resize_list` Resize an IVF-PQ list with interleaved layout. diff --git a/fern/pages/cpp_api/cpp-api-stats-silhouette-score.md b/fern/pages/cpp_api/cpp-api-stats-silhouette-score.md index ee2b94ddc3..d80a42ce9a 100644 --- a/fern/pages/cpp_api/cpp-api-stats-silhouette-score.md +++ b/fern/pages/cpp_api/cpp-api-stats-silhouette-score.md @@ -8,8 +8,8 @@ _Source header: `cpp/include/cuvs/stats/silhouette_score.hpp`_ ## Silhouette Score - -### stats::silhouette_score + +### cuvs::stats::silhouette_score main function that returns the average silhouette score for a given set of data and its @@ -44,8 +44,8 @@ clusterings nRows) for every sample (length: nRows) _Source: `cpp/include/cuvs/stats/silhouette_score.hpp:31`_ - -### stats::silhouette_score_batched + +### cuvs::stats::silhouette_score_batched function that returns the average silhouette score for a given set of data and its @@ -82,7 +82,7 @@ clusterings nRows) for every sample (length: nRows) the calculations _Source: `cpp/include/cuvs/stats/silhouette_score.hpp:54`_ -**Additional overload:** `stats::silhouette_score` +**Additional overload:** `cuvs::stats::silhouette_score` main function that returns the average silhouette score for a given set of data and its @@ -117,7 +117,7 @@ clusterings nRows) for every sample (length: nRows) the calculations _Source: `cpp/include/cuvs/stats/silhouette_score.hpp:77`_ -**Additional overload:** `stats::silhouette_score_batched` +**Additional overload:** `cuvs::stats::silhouette_score_batched` function that returns the average silhouette score for a given set of data and its diff --git a/fern/pages/cpp_api/cpp-api-stats-trustworthiness-score.md b/fern/pages/cpp_api/cpp-api-stats-trustworthiness-score.md index 4967ae6dd6..9fdd00eab4 100644 --- a/fern/pages/cpp_api/cpp-api-stats-trustworthiness-score.md +++ b/fern/pages/cpp_api/cpp-api-stats-trustworthiness-score.md @@ -8,8 +8,8 @@ _Source header: `cpp/include/cuvs/stats/trustworthiness_score.hpp`_ ## Trustworthiness - -### stats::trustworthiness_score + +### cuvs::stats::trustworthiness_score Compute the trustworthiness score diff --git a/fern/scripts/generate_api_reference.py b/fern/scripts/generate_api_reference.py index c4871381bb..ca7f0cd1e9 100755 --- a/fern/scripts/generate_api_reference.py +++ b/fern/scripts/generate_api_reference.py @@ -474,7 +474,10 @@ def collect_native_pages( for group in index.groups.values(): entries = [ - entry for entry in group.entries if entry.source.startswith(prefix) + entry + for entry in group.entries + if entry.source.startswith(prefix) + and not is_detail_namespace_entry(entry) ] if not entries: continue @@ -549,6 +552,10 @@ def short_symbol_name(name: str) -> str: return name.split("::")[-1] +def is_detail_namespace_entry(entry: DoxygenEntry) -> bool: + return "detail" in entry.name.split("::") + + def render_native_group( group: DoxygenGroup, language: str, @@ -1564,14 +1571,27 @@ def parse_enum_name(declaration: str) -> str | None: def infer_namespace(prefix: str) -> str: - matches = list( - re.finditer( - r"\bnamespace\s+([A-Za-z_][\w:]*)(?:\s*=\s*[^;]+)?\s*{", prefix - ) + text = COMMENT_RE.sub("", prefix) + text = re.sub(r"//.*", "", text) + namespace_stack: list[tuple[str, int]] = [] + depth = 0 + token_re = re.compile( + r"\bnamespace\s+([A-Za-z_][\w:]*)(?:\s*=\s*[^;{}]+)?\s*{|[{}]" ) - if not matches: - return "" - return matches[-1].group(1) + for match in token_re.finditer(text): + namespace_name = match.group(1) + if namespace_name: + depth += 1 + namespace_stack.append((namespace_name, depth)) + continue + token = match.group(0) + if token == "{": + depth += 1 + elif token == "}": + depth = max(depth - 1, 0) + while namespace_stack and namespace_stack[-1][1] > depth: + namespace_stack.pop() + return "::".join(name for name, _ in namespace_stack) def normalize_entry_signature(declaration: str, kind: str) -> str: From 158598fdea6aa04dfe76532f90852a57f3432af5 Mon Sep 17 00:00:00 2001 From: "Corey J. Nolet" Date: Thu, 7 May 2026 13:51:51 -0400 Subject: [PATCH 010/129] Skip namespace declarations in C++ docs --- fern/pages/cpp_api/cpp-api-neighbors-ivf-flat.md | 11 ----------- fern/pages/cpp_api/cpp-api-neighbors-ivf-pq.md | 11 ----------- fern/scripts/generate_api_reference.py | 9 +++++++++ 3 files changed, 9 insertions(+), 22 deletions(-) diff --git a/fern/pages/cpp_api/cpp-api-neighbors-ivf-flat.md b/fern/pages/cpp_api/cpp-api-neighbors-ivf-flat.md index 870568208e..39fa13cc43 100644 --- a/fern/pages/cpp_api/cpp-api-neighbors-ivf-flat.md +++ b/fern/pages/cpp_api/cpp-api-neighbors-ivf-flat.md @@ -1847,17 +1847,6 @@ _Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:2018`_ ## Helper functions for IVF Flat - -### namespace codepacker \{ - -Helper functions for IVF Flat - -```cpp -namespace codepacker { -``` - -_Source: `cpp/include/cuvs/neighbors/ivf_flat.hpp:2484`_ - ### cuvs::neighbors::ivf_flat::helpers::codepacker::pack diff --git a/fern/pages/cpp_api/cpp-api-neighbors-ivf-pq.md b/fern/pages/cpp_api/cpp-api-neighbors-ivf-pq.md index 368bb564f7..4bbef2c2d3 100644 --- a/fern/pages/cpp_api/cpp-api-neighbors-ivf-pq.md +++ b/fern/pages/cpp_api/cpp-api-neighbors-ivf-pq.md @@ -1963,17 +1963,6 @@ _Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:2106`_ ## IVF-PQ helper methods - -### namespace codepacker \{ - -IVF-PQ helper methods - -```cpp -namespace codepacker { -``` - -_Source: `cpp/include/cuvs/neighbors/ivf_pq.hpp:2561`_ - ### cuvs::neighbors::ivf_pq::helpers::codepacker::unpack diff --git a/fern/scripts/generate_api_reference.py b/fern/scripts/generate_api_reference.py index ca7f0cd1e9..20e8852377 100755 --- a/fern/scripts/generate_api_reference.py +++ b/fern/scripts/generate_api_reference.py @@ -281,6 +281,8 @@ def _parse_header(self, path: Path) -> None: entry = parse_doxygen_entry( comment, declaration, rel_path, decl_line ) + if is_namespace_entry(entry): + continue if entry.kind == "member" and not is_type_alias_signature( entry.signature ): @@ -311,6 +313,8 @@ def _parse_header(self, path: Path) -> None: entry = parse_doxygen_entry( comment, declaration, rel_path, decl_line ) + if is_namespace_entry(entry): + continue self._qualify_function(entry, text[: match.start()]) if not entry.summary and self.groups[group_name].title: entry.summary = self.groups[group_name].title @@ -478,6 +482,7 @@ def collect_native_pages( for entry in group.entries if entry.source.startswith(prefix) and not is_detail_namespace_entry(entry) + and not is_namespace_entry(entry) ] if not entries: continue @@ -556,6 +561,10 @@ def is_detail_namespace_entry(entry: DoxygenEntry) -> bool: return "detail" in entry.name.split("::") +def is_namespace_entry(entry: DoxygenEntry) -> bool: + return bool(re.match(r"^\s*(?:inline\s+)?namespace\b", entry.signature)) + + def render_native_group( group: DoxygenGroup, language: str, From a0977740899d8c3ba0819a4e7997e7e6813e6ce3 Mon Sep 17 00:00:00 2001 From: "Corey J. Nolet" Date: Thu, 7 May 2026 15:37:07 -0400 Subject: [PATCH 011/129] Fix LaTeX escaping in Fern docs --- .../cpp_api/cpp-api-distance-distance.md | 8 +-- fern/pages/neighbors/cagra.md | 72 +++++++++---------- fern/pages/neighbors/ivfflat.md | 8 +-- fern/pages/neighbors/ivfpq.md | 20 +++--- fern/scripts/generate_api_reference.py | 58 ++++++++++++++- 5 files changed, 111 insertions(+), 55 deletions(-) diff --git a/fern/pages/cpp_api/cpp-api-distance-distance.md b/fern/pages/cpp_api/cpp-api-distance-distance.md index e36d995b94..4a01bdcce4 100644 --- a/fern/pages/cpp_api/cpp-api-distance-distance.md +++ b/fern/pages/cpp_api/cpp-api-distance-distance.md @@ -76,10 +76,10 @@ Parameters for kernel matrices. The following kernels are implemented: -- LINEAR \f[ K(x_1,x_2) = <x_1,x_2>, \f] where \f$< , >\f$ is the dot product -- POLYNOMIAL \f[ K(x_1, x_2) = (\gamma <x_1,x_2> + \mathrm\{coef0\})^\mathrm\{degree\} \f] -- RBF \f[ K(x_1, x_2) = \exp(- \gamma \|x_1-x_2\|^2) \f] -- TANH \f[ K(x_1, x_2) = \tanh(\gamma <x_1,x_2> + \mathrm\{coef0\}) \f] +- LINEAR $K(x_1,x_2) = \langle x_1,x_2 \rangle,$ where $\langle , \rangle$ is the dot product +- POLYNOMIAL $K(x_1, x_2) = (\gamma \langle x_1,x_2 \rangle + \mathrm{coef0})^\mathrm{degree}$ +- RBF $K(x_1, x_2) = \exp(- \gamma \lVert x_1-x_2 \rVert^2)$ +- TANH $K(x_1, x_2) = \tanh(\gamma \langle x_1,x_2 \rangle + \mathrm{coef0})$ ```cpp struct KernelParams { ... } ; diff --git a/fern/pages/neighbors/cagra.md b/fern/pages/neighbors/cagra.md index a641037903..76a42b6fd7 100644 --- a/fern/pages/neighbors/cagra.md +++ b/fern/pages/neighbors/cagra.md @@ -63,15 +63,15 @@ CAGRA builds a nearest-neighbor graph (stored on host) while keeping the origina The baseline memory footprint after index construction: $$ -\text\\\\\\\\{dataset_size (device)\\\\\\\\} +\text{dataset\_size (device)} \;=\; -\text\\\\\\\\{number_vectors\\\\\\\\} \times \text\\\\\\\\{vector_dimension\\\\\\\\} \times \text\\\\\\\\{bytes_per_dimension\\\\\\\\} +\text{number\_vectors} \times \text{vector\_dimension} \times \text{bytes\_per\_dimension} $$ $$ -\text\\\\\\\\{graph_size (host)\\\\\\\\} +\text{graph\_size (host)} \;=\; -\text\\\\\\\\{number_vectors\\\\\\\\} \times \text\\\\\\\\{graph_degree\\\\\\\\} \times \operatorname\\\\\\\\{sizeof\\\\\\\\}\!\big(\mathrm\\\\\\\\{IdxT\\\\\\\\}\big) +\text{number\_vectors} \times \text{graph\_degree} \times \operatorname{sizeof}\!\big(\mathrm{IdxT}\big) $$ Note: The dataset must be in GPU memory during index build, but can be detached afterward if not needed for search. @@ -94,13 +94,13 @@ The knn graph can be constructed using the IVF-PQ algorithm, which works in two **IVF-PQ Build (centroid training)** — uses a training subset to compute cluster centroids and PQ codebooks. $$ -\text\\\\\\\\{IVFPQ_build_peak\\\\\\\\} +\text{IVFPQ\_build\_peak} \;=\; -\frac\\\\\\\\{n_\\\\\\\\{\text\\\\\\\\{vectors\\\\\\\\}\\\\\\\\}\\\\\\\\}\\\\\\\\{\text\\\\\\\\{train_set_ratio\\\\\\\\}\\\\\\\\} \times \text\\\\\\\\{dim\\\\\\\\} \times 4 +\frac{n_{\text{vectors}}}{\text{train\_set\_ratio}} \times \text{dim} \times 4 \;+\; -n_\\\\\\\\{\text\\\\\\\\{clusters\\\\\\\\}\\\\\\\\} \times \text\\\\\\\\{dim\\\\\\\\} \times 4 +n_{\text{clusters}} \times \text{dim} \times 4 \;+\; -\frac\\\\\\\\{n_\\\\\\\\{\text\\\\\\\\{vectors\\\\\\\\}\\\\\\\\}\\\\\\\\}\\\\\\\\{\text\\\\\\\\{train_set_ratio\\\\\\\\}\\\\\\\\} \times \operatorname\\\\\\\\{sizeof\\\\\\\\}(\mathrm\\\\\\\\{uint32\_t\\\\\\\\}) +\frac{n_{\text{vectors}}}{\text{train\_set\_ratio}} \times \operatorname{sizeof}(\mathrm{uint32\_t}) $$ **Example** (n = 1e6; dim = 1024; n\_clusters = 1024; train\_set\_ratio = 10): 395.01 MB @@ -108,13 +108,13 @@ $$ **IVF-PQ Search (forms the intermediate graph)** — Constructs the knn graph in batches by querying the IVF-PQ index for the nearest neighbors of all training points. $$ -\text\\\\\\\\{IVFPQ_search_peak\\\\\\\\} +\text{IVFPQ\_search\_peak} \;=\; -\text\\\\\\\\{batch_size\\\\\\\\} \times \text\\\\\\\\{dim\\\\\\\\} \times 4 +\text{batch\_size} \times \text{dim} \times 4 \;+\; -\text\\\\\\\\{batch_size\\\\\\\\} \times \text\\\\\\\\{intermediate_degree\\\\\\\\} \times \operatorname\\\\\\\\{sizeof\\\\\\\\}(\mathrm\\\\\\\\{uint32\_t\\\\\\\\}) +\text{batch\_size} \times \text{intermediate\_degree} \times \operatorname{sizeof}(\mathrm{uint32\_t}) \;+\; -\text\\\\\\\\{batch_size\\\\\\\\} \times \text\\\\\\\\{intermediate_degree\\\\\\\\} \times 4 +\text{batch\_size} \times \text{intermediate\_degree} \times 4 $$ **Example** (batch = 1024, dim = 1024, intermediate\_degree = 128): 5.00 MB @@ -124,25 +124,25 @@ $$ **Peak device memory:** $$ -\text\\\\\\\\{NND_device_peak\\\\\\\\} +\text{NND\_device\_peak} \;=\; -n_\text\\\\\\\\{vectors\\\\\\\\} \times (n_\text\\\\\\\\{dims\\\\\\\\} \times 2 + 276) +n_{\text{vectors}} \times (n_{\text{dims}} \times 2 + 276) $$ -- Data vectors (transferred to device and stored as fp16): $n_\text\\\\\\\\{dims\\\\\\\\} \times 2$ bytes per vector +- Data vectors (transferred to device and stored as fp16): $n_{\text{dims}} \times 2$ bytes per vector - Small working graph, locks, edge counters: 276 bytes per vector (fixed) - Additional $4$ bytes per vector when using L2 metric (for precomputed norms) **Peak host memory:** $$ -\text\\\\\\\\{NND_host_peak\\\\\\\\} +\text{NND\_host\_peak} \;=\; -n_\text\\\\\\\\{vectors\\\\\\\\} \times (13 \times \text\\\\\\\\{intermediate_graph_degree\\\\\\\\} + 912) +n_{\text{vectors}} \times (13 \times \text{intermediate\_graph\_degree} + 912) $$ -- Full graph with distances (~1.3x overallocation): $1.3 \times 8 \times \text\\\\\\\\{intermediate_graph_degree\\\\\\\\}$ bytes per vector -- Bloom filter for sampling: $1.3 \times 2 \times \text\\\\\\\\{intermediate_graph_degree\\\\\\\\}$ bytes per vector +- Full graph with distances (~1.3x overallocation): $1.3 \times 8 \times \text{intermediate\_graph\_degree}$ bytes per vector +- Bloom filter for sampling: $1.3 \times 2 \times \text{intermediate\_graph\_degree}$ bytes per vector - 5 sample buffers (degree 32 each): 640 bytes per vector - Graph update buffer (degree 32): 256 bytes per vector - Edge counters: 16 bytes per vector @@ -152,10 +152,10 @@ $$ Pruning/reordering the intermediate graph; peak scales linearly with intermediate degree. $$ -\text\\\\\\\\{optimize_peak\\\\\\\\} +\text{optimize\_peak} \;=\; -n_\\\\\\\\{\text\\\\\\\\{vectors\\\\\\\\}\\\\\\\\} \times -\Big( 4 + \big(\operatorname\\\\\\\\{sizeof\\\\\\\\}(\mathrm\\\\\\\\{IdxT\\\\\\\\}) + 1\big)\times \text\\\\\\\\{intermediate_degree\\\\\\\\} \Big) +n_{\text{vectors}} \times +\Big( 4 + \big(\operatorname{sizeof}(\mathrm{IdxT}) + 1\big)\times \text{intermediate\_degree} \Big) $$ **Example** (n = 1e6, intermediate\_degree = 128, IdxT = int32): 614.17 MB @@ -168,11 +168,11 @@ The overall peak memory footprint on the device is the maximum allocation across **Using IVF-PQ:** $$ -\text\\\\\\\\{build_peak\\\\\\\\} +\text{build\_peak} \;=\; -\text\\\\\\\\{dataset_size\\\\\\\\} +\text{dataset\_size} \;+\; -\max\!\big(\text\\\\\\\\{IVFPQ_build_peak\\\\\\\\},\ \text\\\\\\\\{IVFPQ_search_peak\\\\\\\\},\ \text\\\\\\\\{optimize_peak\\\\\\\\}\big) +\max\!\big(\text{IVFPQ\_build\_peak},\ \text{IVFPQ\_search\_peak},\ \text{optimize\_peak}\big) $$ **Example:** 3906.25 + max(395.01, 5.00, 614.17) = 4520.42 MB @@ -180,14 +180,14 @@ $$ **Using NN-Descent:** $$ -\text\\\\\\\\{build_peak\\\\\\\\} +\text{build\_peak} \;=\; -\text\\\\\\\\{dataset_size\\\\\\\\}^\\\\\\\\{*\\\\\\\\} +\text{dataset\_size}^{*} \;+\; -\max\!\big(\text\\\\\\\\{NND_device_peak\\\\\\\\},\ \text\\\\\\\\{optimize_peak\\\\\\\\}\big) +\max\!\big(\text{NND\_device\_peak},\ \text{optimize\_peak}\big) $$ -$\text\\\\\\\\{dataset_size\\\\\\\\}^\\\\\\\\{*\\\\\\\\}$ applies only when the user passes data residing in device memory; NN-Descent internally copies the dataset to the device as fp16, so host-memory inputs do not add this term. +$\text{dataset\_size}^{*}$ applies only when the user passes data residing in device memory; NN-Descent internally copies the dataset to the device as fp16, so host-memory inputs do not add this term. ## Search peak memory usage @@ -196,24 +196,24 @@ If multiple batches are to be launched concurrently or overlapped, separate resu The below memory estimate assumes just one batch of queries being run at a time and reusing the buffers. $$ -\text\\\\\\\\{search_memory\\\\\\\\} +\text{search\_memory} \;=\; -\text\\\\\\\\{dataset_size\\\\\\\\} + \text\\\\\\\\{graph_size\\\\\\\\} + \text\\\\\\\\{workspace_size\\\\\\\\} +\text{dataset\_size} + \text{graph\_size} + \text{workspace\_size} $$ Where `workspace_size` is the temporary memory used for query vectors and result storage: $$ -\text\\\\\\\\{query_size\\\\\\\\} +\text{query\_size} \;=\; -\text\\\\\\\\{batch_size\\\\\\\\} \times \text\\\\\\\\{dim\\\\\\\\} \times \operatorname\\\\\\\\{sizeof\\\\\\\\}(\mathrm\\\\\\\\{float\\\\\\\\}) +\text{batch\_size} \times \text{dim} \times \operatorname{sizeof}(\mathrm{float}) $$ $$ -\text\\\\\\\\{result_size\\\\\\\\} +\text{result\_size} \;=\; -\text\\\\\\\\{batch_size\\\\\\\\} \times \text\\\\\\\\{topk\\\\\\\\} \times -\big(\operatorname\\\\\\\\{sizeof\\\\\\\\}(\mathrm\\\\\\\\{IdxT\\\\\\\\}) + \operatorname\\\\\\\\{sizeof\\\\\\\\}(\mathrm\\\\\\\\{float\\\\\\\\})\big) +\text{batch\_size} \times \text{topk} \times +\big(\operatorname{sizeof}(\mathrm{IdxT}) + \operatorname{sizeof}(\mathrm{float})\big) $$ **Example** (dim = 1024, batch\_size = 100, topk = 10, IdxT = int32): diff --git a/fern/pages/neighbors/ivfflat.md b/fern/pages/neighbors/ivfflat.md index 5230a2a093..9a0bac89b5 100644 --- a/fern/pages/neighbors/ivfflat.md +++ b/fern/pages/neighbors/ivfflat.md @@ -45,14 +45,14 @@ assumption that the number of lists, and thus the max size of the data in the in might not matter. For example, most vector databases build many smaller physical approximate nearest neighbors indexes, each from fixed-size or maximum-sized immutable segments and so the number of lists can be tuned based on the number of vectors in the indexes. -Empirically, we've found $\sqrt\\\\\\\\{n\_index\_vectors\\\\\\\\}$ to be a good starting point for the $n\_lists$ hyper-parameter. Remember, having more +Empirically, we've found $\sqrt{n\_index\_vectors}$ to be a good starting point for the $n\_lists$ hyper-parameter. Remember, having more lists means less points to search within each list, but it could also mean more $n\_probes$ are needed at search time to reach an acceptable recall. ## Memory footprint Each cluster is padded to at least 32 vectors (but potentially up to 1024). Assuming uniform random distribution of vectors/list, we would have -$cluster\_overhead = (conservative\_memory\_allocation ? 16 : 512 ) * dim * sizeof_\\\\\\\\{float\\\\\\\\}$ +$cluster\_overhead = (conservative\_memory\_allocation ? 16 : 512 ) * dim * sizeof_{float}$ Note that each cluster is allocated as a separate allocation. If we use a `cuda_memory_resource`, that would grab memory in 1 MiB chunks, so on average we might have 0.5 MiB overhead per cluster. If we us 10s of thousands of clusters, it becomes essential to use pool allocator to avoid this overhead. @@ -67,11 +67,11 @@ n\_vectors * sizeof(int_type) + n\_clusters * n\_dimensions * sizeof(T) + -n\_clusters * cluster_overhead` +n\_clusters * cluster\_overhead $$ ### Peak device memory usage for index build: -$workspace = min(1GB, n\_queries * [(n\_lists + 1 + n\_probes * (k + 1)) * sizeof_\\\\\\\\{float\\\\\\\\} + n\_probes * k * sizeof_\\\\\\\\{idx\\\\\\\\}])$ +$workspace = min(1GB, n\_queries * [(n\_lists + 1 + n\_probes * (k + 1)) * sizeof_{float} + n\_probes * k * sizeof_{idx}])$ $index\_size + workspace$ diff --git a/fern/pages/neighbors/ivfpq.md b/fern/pages/neighbors/ivfpq.md index 61e96aae88..b08a3cbf2e 100644 --- a/fern/pages/neighbors/ivfpq.md +++ b/fern/pages/neighbors/ivfpq.md @@ -46,25 +46,25 @@ It's important to note that IVF-PQ becomes very lossy very quickly, and so refin ### Index (device memory): -Simple approximate formula: $n\_vectors * (pq\_dim * \frac\\\\\\\\{pq\_bits\\\\\\\\}\\\\\\\\{8\\\\\\\\} + sizeof_\\\\\\\\{idx\\\\\\\\}) + n\_clusters$ +Simple approximate formula: $n\_vectors * (pq\_dim * \frac{pq\_bits}{8} + sizeof_{idx}) + n\_clusters$ The IVF lists end up being represented by a sparse data structure that stores the pointers to each list, an indices array that contains the indexes of each vector in each list, and an array with the encoded (and interleaved) data for each list. -IVF list pointers: $n\_clusters * sizeof_\\\\\\\\{uint32\_t\\\\\\\\}$ +IVF list pointers: $n\_clusters * sizeof_{uint32\_t}$ -Indices: $n\_vectors * sizeof_\\\\\\\\{idx\\\\\\\\}$ +Indices: $n\_vectors * sizeof_{idx}$ -Encoded data (interleaved): $n\_vectors * pq\_dim * \frac\\\\\\\\{pq\_bits\\\\\\\\}\\\\\\\\{8\\\\\\\\}$ +Encoded data (interleaved): $n\_vectors * pq\_dim * \frac{pq\_bits}{8}$ -Per subspace method: $4 * pq\_dim * pq\_len * 2^\\\\\\\\{pq\_bits\\\\\\\\}$ +Per subspace method: $4 * pq\_dim * pq\_len * 2^{pq\_bits}$ -Per cluster method: $4 * n\_clusters * pq\_len * 2^\\\\\\\\{pq\_bits\\\\\\\\}$ +Per cluster method: $4 * n\_clusters * pq\_len * 2^{pq\_bits}$ Extras: $n\_clusters * (20 + 8 * dim)$ ### Index (host memory): -When refinement is used with the dataset on host, the original raw vectors are needed: $n\_vectors * dims * sizeof_\\\\\\\\{float\\\\\\\\}$ +When refinement is used with the dataset on host, the original raw vectors are needed: $n\_vectors * dims * sizeof_{float}$ ### Search peak memory usage (device); @@ -75,11 +75,11 @@ Workspace size is not trivial, a heuristic controls the batch size to make sure ### Build peak memory usage (device): $$ -\frac\\\\\\\\{n\_vectors\\\\\\\\}\\\\\\\\{trainset\_ratio * dims * sizeof_\\\\\\\\{float\\\\\\\\}\\\\\\\\} +\frac{n\_vectors}{trainset\_ratio * dims * sizeof_{float}} -+ \frac\\\\\\\\{n\_vectors\\\\\\\\}\\\\\\\\{trainset\_ratio * sizeof_\\\\\\\\{uint32\_t\\\\\\\\}\\\\\\\\} ++ \frac{n\_vectors}{trainset\_ratio * sizeof_{uint32\_t}} -+ n\_clusters * dim * sizeof_\\\\\\\\{float\\\\\\\\} ++ n\_clusters * dim * sizeof_{float} $$ Note, if there’s not enough space left in the workspace memory resource, IVF-PQ build automatically switches to the managed memory for the training set and labels. diff --git a/fern/scripts/generate_api_reference.py b/fern/scripts/generate_api_reference.py index 20e8852377..a3d2ae13aa 100755 --- a/fern/scripts/generate_api_reference.py +++ b/fern/scripts/generate_api_reference.py @@ -83,6 +83,7 @@ SPHINX_ROLE_RE = re.compile( r"(?[^`]+)`" ) +MATH_PLACEHOLDER_RE = re.compile(r"@@FERN_MATH_([0-9a-f]+)@@") @dataclass @@ -1458,10 +1459,57 @@ def clean_doxygen_text(text: str) -> str: lambda match: match.group(2) or f"`{match.group(1)}`", text, ) + text = normalize_doxygen_math(text) text = text.replace("@copydoc", "") return text.strip() +def normalize_doxygen_math(text: str) -> str: + text = re.sub( + r"\\f\[(.*?)\\f\]", + lambda match: math_placeholder( + f"${clean_latex_math(match.group(1))}$" + ), + text, + ) + text = re.sub( + r"\\f\$(.*?)\\f\$", + lambda match: math_placeholder( + f"${clean_latex_math(match.group(1))}$" + ), + text, + ) + return text + + +def clean_latex_math(math: str) -> str: + math = math.strip() + math = re.sub( + r"<\s*([^<>]*?)\s*>", + lambda match: rf"\langle {match.group(1).strip()} \rangle", + math, + ) + math = re.sub( + r"\|\s*([^|]*?)\s*\|", + lambda match: rf"\lVert {match.group(1).strip()} \rVert", + math, + ) + math = re.sub( + r"(\\(?:mathrm|operatorname|text)\{)([^{}]*)(\})", + lambda match: ( + f"{match.group(1)}" + f"{re.sub(r'(? str: + return f"@@FERN_MATH_{math.encode('utf-8').hex()}@@" + + def append_sentence(existing: str, addition: str) -> str: addition = addition.strip() if not addition: @@ -3603,7 +3651,7 @@ def escape_code(value: str) -> str: def escape_text(value: str) -> str: - return ( + escaped = ( str(value) .replace("|", "\\|") .replace("<", "<") @@ -3612,6 +3660,14 @@ def escape_text(value: str) -> str: .replace("}", "\\}") .replace("\n", " ") ) + return restore_math_placeholders(escaped) + + +def restore_math_placeholders(value: str) -> str: + return MATH_PLACEHOLDER_RE.sub( + lambda match: bytes.fromhex(match.group(1)).decode("utf-8"), + value, + ) def heading_text(value: str) -> str: From c40f61deb26895dc63eb1c8b76a5d796f9b4b141 Mon Sep 17 00:00:00 2001 From: "Corey J. Nolet" Date: Thu, 7 May 2026 15:56:11 -0400 Subject: [PATCH 012/129] Qualify C++ member functions in Fern docs --- fern/docs.yml | 6 + fern/pages/c_api/c-api-cluster-kmeans.md | 2 +- .../c_api/c-api-neighbors-all-neighbors.md | 2 +- fern/pages/c_api/c-api-neighbors-cagra.md | 18 +- fern/pages/c_api/c-api-neighbors-common.md | 2 +- fern/pages/c_api/c-api-neighbors-hnsw.md | 8 +- fern/pages/c_api/c-api-neighbors-ivf-flat.md | 4 +- fern/pages/c_api/c-api-neighbors-ivf-pq.md | 8 +- fern/pages/c_api/c-api-neighbors-mg-cagra.md | 4 +- .../c_api/c-api-neighbors-mg-ivf-flat.md | 4 +- fern/pages/c_api/c-api-neighbors-mg-ivf-pq.md | 4 +- .../pages/c_api/c-api-neighbors-nn-descent.md | 2 +- .../c_api/c-api-neighbors-tiered-index.md | 2 +- fern/pages/c_api/c-api-neighbors-vamana.md | 2 +- fern/pages/c_api/c-api-preprocessing-pca.md | 4 +- .../c-api-preprocessing-quantize-binary.md | 8 +- .../c_api/c-api-preprocessing-quantize-pq.md | 2 +- .../c-api-preprocessing-quantize-scalar.md | 2 +- .../cpp_api/cpp-api-cluster-agglomerative.md | 22 +- fern/pages/cpp_api/cpp-api-cluster-kmeans.md | 8 +- .../pages/cpp_api/cpp-api-cluster-spectral.md | 2 +- .../cpp_api/cpp-api-distance-distance.md | 6 +- .../cpp_api/cpp-api-distance-grammian.md | 64 ++++ .../cpp-api-neighbors-all-neighbors.md | 2 +- .../cpp_api/cpp-api-neighbors-ball-cover.md | 36 +- .../cpp_api/cpp-api-neighbors-brute-force.md | 123 ++++--- fern/pages/cpp_api/cpp-api-neighbors-cagra.md | 214 ++++++------ .../pages/cpp_api/cpp-api-neighbors-common.md | 204 +++++++++++- .../cpp-api-neighbors-composite-index.md | 25 ++ .../cpp-api-neighbors-dynamic-batching.md | 48 ++- fern/pages/cpp_api/cpp-api-neighbors-hnsw.md | 90 ++--- .../cpp_api/cpp-api-neighbors-ivf-flat.md | 253 +++++++++------ .../pages/cpp_api/cpp-api-neighbors-ivf-pq.md | 307 +++++++++++------- .../cpp_api/cpp-api-neighbors-nn-descent.md | 73 +++-- fern/pages/cpp_api/cpp-api-neighbors-scann.md | 34 +- .../cpp_api/cpp-api-neighbors-tiered-index.md | 29 ++ .../pages/cpp_api/cpp-api-neighbors-vamana.md | 125 ++++--- .../cpp_api/cpp-api-preprocessing-pca.md | 2 +- .../cpp-api-preprocessing-quantize-binary.md | 60 ++-- .../cpp-api-preprocessing-quantize-pq.md | 34 +- .../cpp-api-preprocessing-quantize-scalar.md | 59 ++-- ...pp-api-preprocessing-spectral-embedding.md | 2 +- .../cpp_api/cpp-api-util-cutlass-utils.md | 2 +- fern/pages/cpp_api/cpp-api-util-file-io.md | 8 +- fern/pages/cpp_api/index.md | 3 + fern/scripts/generate_api_reference.py | 142 +++++--- 46 files changed, 1425 insertions(+), 636 deletions(-) create mode 100644 fern/pages/cpp_api/cpp-api-distance-grammian.md create mode 100644 fern/pages/cpp_api/cpp-api-neighbors-composite-index.md create mode 100644 fern/pages/cpp_api/cpp-api-neighbors-tiered-index.md diff --git a/fern/docs.yml b/fern/docs.yml index d646e11f9a..76d75d80ec 100644 --- a/fern/docs.yml +++ b/fern/docs.yml @@ -158,6 +158,8 @@ navigation: path: "./pages/cpp_api/cpp-api-cluster-spectral.md" - page: "Distance Distance" path: "./pages/cpp_api/cpp-api-distance-distance.md" + - page: "Distance Grammian" + path: "./pages/cpp_api/cpp-api-distance-grammian.md" - page: "Neighbors All Neighbors" path: "./pages/cpp_api/cpp-api-neighbors-all-neighbors.md" - page: "Neighbors Ball Cover" @@ -168,6 +170,8 @@ navigation: path: "./pages/cpp_api/cpp-api-neighbors-cagra.md" - page: "Neighbors Common" path: "./pages/cpp_api/cpp-api-neighbors-common.md" + - page: "Neighbors Composite Index" + path: "./pages/cpp_api/cpp-api-neighbors-composite-index.md" - page: "Neighbors Dynamic Batching" path: "./pages/cpp_api/cpp-api-neighbors-dynamic-batching.md" - page: "Neighbors Epsilon Neighborhood" @@ -184,6 +188,8 @@ navigation: path: "./pages/cpp_api/cpp-api-neighbors-refine.md" - page: "Neighbors Scann" path: "./pages/cpp_api/cpp-api-neighbors-scann.md" + - page: "Neighbors Tiered Index" + path: "./pages/cpp_api/cpp-api-neighbors-tiered-index.md" - page: "Neighbors Vamana" path: "./pages/cpp_api/cpp-api-neighbors-vamana.md" - page: "Preprocessing PCA" diff --git a/fern/pages/c_api/c-api-cluster-kmeans.md b/fern/pages/c_api/c-api-cluster-kmeans.md index 6e436ee259..23cae13e53 100644 --- a/fern/pages/c_api/c-api-cluster-kmeans.md +++ b/fern/pages/c_api/c-api-cluster-kmeans.md @@ -33,7 +33,7 @@ _Source: `c/include/cuvs/cluster/kmeans.h:22`_ Hyper-parameters for the kmeans algorithm ```c -struct cuvsKMeansParams { ... } ; +struct cuvsKMeansParams { ... }; ``` **Fields** diff --git a/fern/pages/c_api/c-api-neighbors-all-neighbors.md b/fern/pages/c_api/c-api-neighbors-all-neighbors.md index f552f34f0f..c010b73c67 100644 --- a/fern/pages/c_api/c-api-neighbors-all-neighbors.md +++ b/fern/pages/c_api/c-api-neighbors-all-neighbors.md @@ -33,7 +33,7 @@ _Source: `c/include/cuvs/neighbors/all_neighbors.h:38`_ Parameters controlling SNMG all-neighbors build. ```c -struct cuvsAllNeighborsIndexParams { ... } ; +struct cuvsAllNeighborsIndexParams { ... }; ``` **Fields** diff --git a/fern/pages/c_api/c-api-neighbors-cagra.md b/fern/pages/c_api/c-api-neighbors-cagra.md index 784a46a2e0..0bfc107d06 100644 --- a/fern/pages/c_api/c-api-neighbors-cagra.md +++ b/fern/pages/c_api/c-api-neighbors-cagra.md @@ -14,7 +14,7 @@ _Source header: `c/include/cuvs/neighbors/cagra.h`_ Enum to denote which ANN algorithm is used to build CAGRA graph ```c -enum cuvsCagraGraphBuildAlgo { ... } ; +enum cuvsCagraGraphBuildAlgo { ... }; ``` **Values** @@ -36,7 +36,7 @@ parameters. Define how cuvsCagraIndexParamsFromHnswParams should construct a graph to construct a graph that is to be converted to (used by) a CPU HNSW index. ```c -enum cuvsCagraHnswHeuristicType { ... } ; +enum cuvsCagraHnswHeuristicType { ... }; ``` _Source: `c/include/cuvs/neighbors/cagra.h:54`_ @@ -47,7 +47,7 @@ _Source: `c/include/cuvs/neighbors/cagra.h:54`_ Parameters for VPQ compression. ```c -struct cuvsCagraCompressionParams { ... } ; +struct cuvsCagraCompressionParams { ... }; ``` **Fields** @@ -75,7 +75,7 @@ ACE enables building indexes for datasets too large to fit in GPU memory by: 3. Concatenating sub-graphs into a final unified index ```c -struct cuvsAceParams { ... } ; +struct cuvsAceParams { ... }; ``` **Fields** @@ -97,7 +97,7 @@ _Source: `c/include/cuvs/neighbors/cagra.h:136`_ Supplemental parameters to build CAGRA Index ```c -struct cuvsCagraIndexParams { ... } ; +struct cuvsCagraIndexParams { ... }; ``` **Fields** @@ -297,7 +297,7 @@ _Source: `c/include/cuvs/neighbors/cagra.h:292`_ Supplemental parameters to extend CAGRA Index ```c -struct cuvsCagraExtendParams { ... } ; +struct cuvsCagraExtendParams { ... }; ``` **Fields** @@ -398,7 +398,7 @@ _Source: `c/include/cuvs/neighbors/cagra.h:644`_ Enum to denote algorithm used to search CAGRA Index ```c -enum cuvsCagraSearchAlgo { ... } ; +enum cuvsCagraSearchAlgo { ... }; ``` **Values** @@ -418,7 +418,7 @@ _Source: `c/include/cuvs/neighbors/cagra.h:352`_ Enum to denote Hash Mode used while searching CAGRA index ```c -enum cuvsCagraHashMode { ... } ; +enum cuvsCagraHashMode { ... }; ``` **Values** @@ -437,7 +437,7 @@ _Source: `c/include/cuvs/neighbors/cagra.h:365`_ Supplemental parameters to search CAGRA index ```c -struct cuvsCagraSearchParams { ... } ; +struct cuvsCagraSearchParams { ... }; ``` **Fields** diff --git a/fern/pages/c_api/c-api-neighbors-common.md b/fern/pages/c_api/c-api-neighbors-common.md index 16a6c3b169..742e479d9c 100644 --- a/fern/pages/c_api/c-api-neighbors-common.md +++ b/fern/pages/c_api/c-api-neighbors-common.md @@ -14,7 +14,7 @@ _Source header: `c/include/cuvs/neighbors/common.h`_ Enum to denote filter type. ```c -enum cuvsFilterType { ... } ; +enum cuvsFilterType { ... }; ``` **Values** diff --git a/fern/pages/c_api/c-api-neighbors-hnsw.md b/fern/pages/c_api/c-api-neighbors-hnsw.md index ad32c1c433..bbfa73b1b2 100644 --- a/fern/pages/c_api/c-api-neighbors-hnsw.md +++ b/fern/pages/c_api/c-api-neighbors-hnsw.md @@ -16,7 +16,7 @@ Hierarchy for HNSW index when converting from CAGRA index NOTE: When the value is `NONE`, the HNSW index is built as a base-layer-only index. ```c -enum cuvsHnswHierarchy { ... } ; +enum cuvsHnswHierarchy { ... }; ``` **Values** @@ -40,7 +40,7 @@ ACE enables building indexes for datasets too large to fit in GPU memory by: 3. Concatenating sub-graphs into a final unified index ```c -struct cuvsHnswAceParams { ... } ; +struct cuvsHnswAceParams { ... }; ``` **Fields** @@ -219,7 +219,7 @@ _Source: `c/include/cuvs/neighbors/hnsw.h:185`_ Parameters for extending HNSW index ```c -struct cuvsHnswExtendParams { ... } ; +struct cuvsHnswExtendParams { ... }; ``` **Fields** @@ -392,7 +392,7 @@ _Source: `c/include/cuvs/neighbors/hnsw.h:405`_ C API for hnswlib wrapper search params ```c -struct cuvsHnswSearchParams { ... } ; +struct cuvsHnswSearchParams { ... }; ``` **Fields** diff --git a/fern/pages/c_api/c-api-neighbors-ivf-flat.md b/fern/pages/c_api/c-api-neighbors-ivf-flat.md index c718465b6c..946b48c71a 100644 --- a/fern/pages/c_api/c-api-neighbors-ivf-flat.md +++ b/fern/pages/c_api/c-api-neighbors-ivf-flat.md @@ -14,7 +14,7 @@ _Source header: `c/include/cuvs/neighbors/ivf_flat.h`_ Supplemental parameters to build IVF-Flat Index ```c -struct cuvsIvfFlatIndexParams { ... } ; +struct cuvsIvfFlatIndexParams { ... }; ``` **Fields** @@ -86,7 +86,7 @@ _Source: `c/include/cuvs/neighbors/ivf_flat.h:88`_ Supplemental parameters to search IVF-Flat index ```c -struct cuvsIvfFlatSearchParams { ... } ; +struct cuvsIvfFlatSearchParams { ... }; ``` **Fields** diff --git a/fern/pages/c_api/c-api-neighbors-ivf-pq.md b/fern/pages/c_api/c-api-neighbors-ivf-pq.md index 52ee6abad9..a58a212246 100644 --- a/fern/pages/c_api/c-api-neighbors-ivf-pq.md +++ b/fern/pages/c_api/c-api-neighbors-ivf-pq.md @@ -14,7 +14,7 @@ _Source header: `c/include/cuvs/neighbors/ivf_pq.h`_ A type for specifying how PQ codebooks are created ```c -enum cuvsIvfPqCodebookGen { ... } ; +enum cuvsIvfPqCodebookGen { ... }; ``` **Values** @@ -32,7 +32,7 @@ _Source: `c/include/cuvs/neighbors/ivf_pq.h:26`_ A type for specifying the memory layout of IVF-PQ list data ```c -enum cuvsIvfPqListLayout { ... } ; +enum cuvsIvfPqListLayout { ... }; ``` **Values** @@ -50,7 +50,7 @@ _Source: `c/include/cuvs/neighbors/ivf_pq.h:35`_ Supplemental parameters to build IVF-PQ Index ```c -struct cuvsIvfPqIndexParams { ... } ; +struct cuvsIvfPqIndexParams { ... }; ``` **Fields** @@ -127,7 +127,7 @@ _Source: `c/include/cuvs/neighbors/ivf_pq.h:152`_ Supplemental parameters to search IVF-PQ index ```c -struct cuvsIvfPqSearchParams { ... } ; +struct cuvsIvfPqSearchParams { ... }; ``` **Fields** diff --git a/fern/pages/c_api/c-api-neighbors-mg-cagra.md b/fern/pages/c_api/c-api-neighbors-mg-cagra.md index 0c7e70c564..77c5febc6b 100644 --- a/fern/pages/c_api/c-api-neighbors-mg-cagra.md +++ b/fern/pages/c_api/c-api-neighbors-mg-cagra.md @@ -16,7 +16,7 @@ Multi-GPU parameters to build CAGRA Index This structure extends the base CAGRA index parameters with multi-GPU specific settings. ```c -struct cuvsMultiGpuCagraIndexParams { ... } ; +struct cuvsMultiGpuCagraIndexParams { ... }; ``` **Fields** @@ -84,7 +84,7 @@ Multi-GPU parameters to search CAGRA index This structure extends the base CAGRA search parameters with multi-GPU specific settings. ```c -struct cuvsMultiGpuCagraSearchParams { ... } ; +struct cuvsMultiGpuCagraSearchParams { ... }; ``` **Fields** diff --git a/fern/pages/c_api/c-api-neighbors-mg-ivf-flat.md b/fern/pages/c_api/c-api-neighbors-mg-ivf-flat.md index 687b3b6cd8..52162c2ae4 100644 --- a/fern/pages/c_api/c-api-neighbors-mg-ivf-flat.md +++ b/fern/pages/c_api/c-api-neighbors-mg-ivf-flat.md @@ -16,7 +16,7 @@ Multi-GPU parameters to build IVF-Flat Index This structure extends the base IVF-Flat index parameters with multi-GPU specific settings. ```c -struct cuvsMultiGpuIvfFlatIndexParams { ... } ; +struct cuvsMultiGpuIvfFlatIndexParams { ... }; ``` **Fields** @@ -84,7 +84,7 @@ Multi-GPU parameters to search IVF-Flat index This structure extends the base IVF-Flat search parameters with multi-GPU specific settings. ```c -struct cuvsMultiGpuIvfFlatSearchParams { ... } ; +struct cuvsMultiGpuIvfFlatSearchParams { ... }; ``` **Fields** diff --git a/fern/pages/c_api/c-api-neighbors-mg-ivf-pq.md b/fern/pages/c_api/c-api-neighbors-mg-ivf-pq.md index 6ba1841745..78aa6ecc2b 100644 --- a/fern/pages/c_api/c-api-neighbors-mg-ivf-pq.md +++ b/fern/pages/c_api/c-api-neighbors-mg-ivf-pq.md @@ -16,7 +16,7 @@ Multi-GPU parameters to build IVF-PQ Index This structure extends the base IVF-PQ index parameters with multi-GPU specific settings. ```c -struct cuvsMultiGpuIvfPqIndexParams { ... } ; +struct cuvsMultiGpuIvfPqIndexParams { ... }; ``` **Fields** @@ -84,7 +84,7 @@ Multi-GPU parameters to search IVF-PQ index This structure extends the base IVF-PQ search parameters with multi-GPU specific settings. ```c -struct cuvsMultiGpuIvfPqSearchParams { ... } ; +struct cuvsMultiGpuIvfPqSearchParams { ... }; ``` **Fields** diff --git a/fern/pages/c_api/c-api-neighbors-nn-descent.md b/fern/pages/c_api/c-api-neighbors-nn-descent.md index df20eb674f..fb7ba64071 100644 --- a/fern/pages/c_api/c-api-neighbors-nn-descent.md +++ b/fern/pages/c_api/c-api-neighbors-nn-descent.md @@ -37,7 +37,7 @@ Parameters used to build an nn-descent index `metric`: The distance metric to use `metric_arg`: The argument used by distance metrics like Minkowskidistance `graph_degree`: For an input dataset of dimensions (N, D), determines the final dimensions of the all-neighbors knn graph which turns out to be of dimensions (N, graph_degree) `intermediate_graph_degree`: Internally, nn-descent builds an all-neighbors knn graph of dimensions (N, intermediate_graph_degree) before selecting the final `graph_degree` neighbors. It's recommended that `intermediate_graph_degree` >= 1.5 * graph_degree `max_iterations`: The number of iterations that nn-descent will refine the graph for. More iterations produce a better quality graph at cost of performance `termination_threshold`: The delta at which nn-descent will terminate its iterations `return_distances`: Boolean to decide whether to return distances array `dist_comp_dtype`: dtype to use for distance computation. Defaults to `NND_DIST_COMP_AUTO` which automatically determines the best dtype for distance computation based on the dataset dimensions. Use `NND_DIST_COMP_FP32` for better precision at the cost of performance and memory usage. This option is only valid when data type is fp32. Use `NND_DIST_COMP_FP16` for better performance and memory usage at the cost of precision. ```c -struct cuvsNNDescentIndexParams { ... } ; +struct cuvsNNDescentIndexParams { ... }; ``` **Fields** diff --git a/fern/pages/c_api/c-api-neighbors-tiered-index.md b/fern/pages/c_api/c-api-neighbors-tiered-index.md index e9a2d52b7a..be6322558e 100644 --- a/fern/pages/c_api/c-api-neighbors-tiered-index.md +++ b/fern/pages/c_api/c-api-neighbors-tiered-index.md @@ -102,7 +102,7 @@ _Source: `c/include/cuvs/neighbors/tiered_index.h:60`_ Supplemental parameters to build a TieredIndex ```c -struct cuvsTieredIndexParams { ... } ; +struct cuvsTieredIndexParams { ... }; ``` **Fields** diff --git a/fern/pages/c_api/c-api-neighbors-vamana.md b/fern/pages/c_api/c-api-neighbors-vamana.md index 243ee27785..97512f7dee 100644 --- a/fern/pages/c_api/c-api-neighbors-vamana.md +++ b/fern/pages/c_api/c-api-neighbors-vamana.md @@ -16,7 +16,7 @@ Supplemental parameters to build Vamana Index `graph_degree`: Maximum degree of graph; corresponds to the R parameter of Vamana algorithm in the literature. `visited_size`: Maximum number of visited nodes per search during Vamana algorithm. Loosely corresponds to the L parameter in the literature. `vamana_iters`: The number of times all vectors are inserted into the graph. If > 1, all vectors are re-inserted to improve graph quality. `max_fraction`: The maximum batch size is this fraction of the total dataset size. Larger gives faster build but lower graph quality. `alpha`: Used to determine how aggressive the pruning will be. ```c -struct cuvsVamanaIndexParams { ... } ; +struct cuvsVamanaIndexParams { ... }; ``` **Fields** diff --git a/fern/pages/c_api/c-api-preprocessing-pca.md b/fern/pages/c_api/c-api-preprocessing-pca.md index d5219ec555..27859190fe 100644 --- a/fern/pages/c_api/c-api-preprocessing-pca.md +++ b/fern/pages/c_api/c-api-preprocessing-pca.md @@ -14,7 +14,7 @@ _Source header: `c/include/cuvs/preprocessing/pca.h`_ Solver algorithm for PCA eigen decomposition. ```c -enum cuvsPcaSolver { ... } ; +enum cuvsPcaSolver { ... }; ``` **Values** @@ -32,7 +32,7 @@ _Source: `c/include/cuvs/preprocessing/pca.h:25`_ Parameters for PCA decomposition. ```c -struct cuvsPcaParams { ... } ; +struct cuvsPcaParams { ... }; ``` **Fields** diff --git a/fern/pages/c_api/c-api-preprocessing-quantize-binary.md b/fern/pages/c_api/c-api-preprocessing-quantize-binary.md index e2c23ef949..db1947dcc4 100644 --- a/fern/pages/c_api/c-api-preprocessing-quantize-binary.md +++ b/fern/pages/c_api/c-api-preprocessing-quantize-binary.md @@ -16,7 +16,7 @@ In the cuvsBinaryQuantizerTransform function, a bit is set if the corresponding the dataset vector is greater than the corresponding element in the threshold vector. The mean and sampling_median thresholds are calculated separately for each dimension. ```c -enum cuvsBinaryQuantizerThreshold { ... } ; +enum cuvsBinaryQuantizerThreshold { ... }; ``` **Values** @@ -35,15 +35,15 @@ _Source: `c/include/cuvs/preprocessing/quantize/binary.h:26`_ Binary quantizer parameters. ```c -struct cuvsBinaryQuantizerParams { ... } ; +struct cuvsBinaryQuantizerParams { ... }; ``` **Fields** | Name | Type | Description | | --- | --- | --- | -| `threshold` | `/* * specifies the threshold to set a bit in cuvsBinaryQuantizerTransform */ enum` | | -| `sampling_ratio` | `/* * specifies the sampling ratio */` | | +| `threshold` | [`/* * specifies the threshold to set a bit in cuvsBinaryQuantizerTransform */ enum cuvsBinaryQuantizerThreshold`](/api-reference/c-api-preprocessing-quantize-binary#cuvsbinaryquantizerthreshold) | | +| `sampling_ratio` | `/* * specifies the sampling ratio */ float` | | _Source: `c/include/cuvs/preprocessing/quantize/binary.h:35`_ diff --git a/fern/pages/c_api/c-api-preprocessing-quantize-pq.md b/fern/pages/c_api/c-api-preprocessing-quantize-pq.md index 2eae37e65c..cc37e8cb33 100644 --- a/fern/pages/c_api/c-api-preprocessing-quantize-pq.md +++ b/fern/pages/c_api/c-api-preprocessing-quantize-pq.md @@ -14,7 +14,7 @@ _Source header: `c/include/cuvs/preprocessing/quantize/pq.h`_ Product quantizer parameters. ```c -struct cuvsProductQuantizerParams { ... } ; +struct cuvsProductQuantizerParams { ... }; ``` **Fields** diff --git a/fern/pages/c_api/c-api-preprocessing-quantize-scalar.md b/fern/pages/c_api/c-api-preprocessing-quantize-scalar.md index de46f55550..0f70d05cd1 100644 --- a/fern/pages/c_api/c-api-preprocessing-quantize-scalar.md +++ b/fern/pages/c_api/c-api-preprocessing-quantize-scalar.md @@ -14,7 +14,7 @@ _Source header: `c/include/cuvs/preprocessing/quantize/scalar.h`_ Scalar quantizer parameters. ```c -struct cuvsScalarQuantizerParams { ... } ; +struct cuvsScalarQuantizerParams { ... }; ``` _Source: `c/include/cuvs/preprocessing/quantize/scalar.h:23`_ diff --git a/fern/pages/cpp_api/cpp-api-cluster-agglomerative.md b/fern/pages/cpp_api/cpp-api-cluster-agglomerative.md index 4ed5be2bf9..69e8e597e7 100644 --- a/fern/pages/cpp_api/cpp-api-cluster-agglomerative.md +++ b/fern/pages/cpp_api/cpp-api-cluster-agglomerative.md @@ -14,7 +14,7 @@ _Source header: `cpp/include/cuvs/cluster/agglomerative.hpp`_ Determines the method for computing the minimum spanning tree (MST) ```cpp -enum Linkage { ... } ; +enum Linkage { ... }; ``` **Values** @@ -26,6 +26,22 @@ enum Linkage { ... } ; _Source: `cpp/include/cuvs/cluster/agglomerative.hpp:30`_ +## Types + + +### cuvs::cluster::agglomerative::single_linkage_output + +Simple container object for consolidating linkage results. This closely + +mirrors the trained instance variables populated in Scikit-learn's AgglomerativeClustering estimator. + +```cpp +template +class single_linkage_output { ... }; +``` + +_Source: `cpp/include/cuvs/cluster/agglomerative.hpp:56`_ + ## single-linkage clustering APIs @@ -72,7 +88,7 @@ _Source: `cpp/include/cuvs/cluster/agglomerative.hpp:104`_ Specialized parameters to build the KNN graph with regular distances ```cpp -struct distance_params { ... } ; +struct distance_params { ... }; ``` **Fields** @@ -90,7 +106,7 @@ _Source: `cpp/include/cuvs/cluster/agglomerative.hpp:118`_ Specialized parameters to build the Mutual Reachability graph ```cpp -struct mutual_reachability_params { ... } ; +struct mutual_reachability_params { ... }; ``` **Fields** diff --git a/fern/pages/cpp_api/cpp-api-cluster-kmeans.md b/fern/pages/cpp_api/cpp-api-cluster-kmeans.md index 9d7ae3a7e2..668f7f981a 100644 --- a/fern/pages/cpp_api/cpp-api-cluster-kmeans.md +++ b/fern/pages/cpp_api/cpp-api-cluster-kmeans.md @@ -14,7 +14,7 @@ _Source header: `cpp/include/cuvs/cluster/kmeans.hpp`_ Base structure for parameters that are common to all k-means algorithms ```cpp -struct base_params { ... } ; +struct base_params { ... }; ``` **Fields** @@ -33,7 +33,7 @@ _Source: `cpp/include/cuvs/cluster/kmeans.hpp:19`_ Simple object to specify hyper-parameters to the kmeans algorithm. ```cpp -struct params : base_params { ... } ; +struct params : base_params { ... }; ``` **Fields** @@ -68,7 +68,7 @@ The following metrics are currently supported in k-means balanced: - L2SqrtExpanded ```cpp -struct balanced_params : base_params { ... } ; +struct balanced_params : base_params { ... }; ``` **Fields** @@ -85,7 +85,7 @@ _Source: `cpp/include/cuvs/cluster/kmeans.hpp:139`_ Type of k-means algorithm. ```cpp -enum class kmeans_type { ... } ; +enum class kmeans_type { ... }; ``` **Values** diff --git a/fern/pages/cpp_api/cpp-api-cluster-spectral.md b/fern/pages/cpp_api/cpp-api-cluster-spectral.md index e6cb9a61c7..f8ddf95928 100644 --- a/fern/pages/cpp_api/cpp-api-cluster-spectral.md +++ b/fern/pages/cpp_api/cpp-api-cluster-spectral.md @@ -14,7 +14,7 @@ _Source header: `cpp/include/cuvs/cluster/spectral.hpp`_ Parameters for spectral clustering ```cpp -struct params { ... } ; +struct params { ... }; ``` **Fields** diff --git a/fern/pages/cpp_api/cpp-api-distance-distance.md b/fern/pages/cpp_api/cpp-api-distance-distance.md index 4a01bdcce4..bee78dfb9f 100644 --- a/fern/pages/cpp_api/cpp-api-distance-distance.md +++ b/fern/pages/cpp_api/cpp-api-distance-distance.md @@ -14,7 +14,7 @@ _Source header: `cpp/include/cuvs/distance/distance.hpp`_ enum to tell how to compute distance ```cpp -enum class DistanceType : int { ... } ; +enum class DistanceType : int { ... }; ``` **Values** @@ -53,7 +53,7 @@ Density kernel type for Kernel Density Estimation. These are the smoothing kernels used in KDE — distinct from the dot-product kernels (RBF, Polynomial, etc.) in cuvs::distance::kernels used by SVMs. ```cpp -enum class DensityKernelType : int { ... } ; +enum class DensityKernelType : int { ... }; ``` **Values** @@ -82,7 +82,7 @@ The following kernels are implemented: - TANH $K(x_1, x_2) = \tanh(\gamma \langle x_1,x_2 \rangle + \mathrm{coef0})$ ```cpp -struct KernelParams { ... } ; +struct KernelParams { ... }; ``` **Fields** diff --git a/fern/pages/cpp_api/cpp-api-distance-grammian.md b/fern/pages/cpp_api/cpp-api-distance-grammian.md new file mode 100644 index 0000000000..4dbc29238c --- /dev/null +++ b/fern/pages/cpp_api/cpp-api-distance-grammian.md @@ -0,0 +1,64 @@ +--- +slug: api-reference/cpp-api-distance-grammian +--- + +# Grammian + +_Source header: `cpp/include/cuvs/distance/grammian.hpp`_ + +## Types + + +### cuvs::distance::kernels::GramMatrixBase + +Base class for general Gram matrices + +A Gram matrix is the Hermitian matrix of inner probucts G_ik = <x_i, x_k> Here, the inner product is evaluated for all elements from vectors sets X1, and X2. + +To be more precise, on exit the output buffer will store: + +- if is_row_major == true: out[j+k*n1] = <x1_j, x2_k>, +- if is_row_major == false: out[j*n2 + k] = <x1_j, x2_k>, where x1_j is the j-th vector from the x1 set and x2_k is the k-th vector from the x2 set. + +```cpp +template +class GramMatrixBase { ... }; +``` + +_Source: `cpp/include/cuvs/distance/grammian.hpp:36`_ + + +### cuvs::distance::kernels::PolynomialKernel + +Create a kernel matrix using polynomial kernel function. + +```cpp +template +class PolynomialKernel : public GramMatrixBase { ... }; +``` + +_Source: `cpp/include/cuvs/distance/grammian.hpp:301`_ + + +### cuvs::distance::kernels::TanhKernel + +Create a kernel matrix using tanh kernel function. + +```cpp +template +class TanhKernel : public GramMatrixBase { ... }; +``` + +_Source: `cpp/include/cuvs/distance/grammian.hpp:419`_ + + +### cuvs::distance::kernels::RBFKernel + +Create a kernel matrix using RBF kernel function. + +```cpp +template +class RBFKernel : public GramMatrixBase { ... }; +``` + +_Source: `cpp/include/cuvs/distance/grammian.hpp:532`_ diff --git a/fern/pages/cpp_api/cpp-api-neighbors-all-neighbors.md b/fern/pages/cpp_api/cpp-api-neighbors-all-neighbors.md index 8ecd20d0f1..62f93cd26b 100644 --- a/fern/pages/cpp_api/cpp-api-neighbors-all-neighbors.md +++ b/fern/pages/cpp_api/cpp-api-neighbors-all-neighbors.md @@ -29,7 +29,7 @@ Parameters used to build an all-neighbors graph (find nearest neighbors for all training vectors). For scalability, the all-neighbors graph construction algorithm partitions a set of training vectors into overlapping clusters, computes a local knn graph on each cluster, and merges the local graphs into a single global graph. Device memory usage and accuracy can be configured by changing the `overlap_factor` and `n_clusters`. The algorithm used to build each local graph is also configurable. ```cpp -struct all_neighbors_params { ... } ; +struct all_neighbors_params { ... }; ``` **Fields** diff --git a/fern/pages/cpp_api/cpp-api-neighbors-ball-cover.md b/fern/pages/cpp_api/cpp-api-neighbors-ball-cover.md index f8366d4884..51905f8ea5 100644 --- a/fern/pages/cpp_api/cpp-api-neighbors-ball-cover.md +++ b/fern/pages/cpp_api/cpp-api-neighbors-ball-cover.md @@ -6,6 +6,40 @@ slug: api-reference/cpp-api-neighbors-ball-cover _Source header: `cpp/include/cuvs/neighbors/ball_cover.hpp`_ +## Types + + +### cuvs::neighbors::ball_cover::index + +Stores raw index data points, sampled landmarks, the 1-nns of index points + +to their closest landmarks, and the ball radii of each landmark. This class is intended to be constructed once and reused across subsequent queries. + +```cpp +template +struct index : cuvs::neighbors::index { ... }; +``` + +**Fields** + +| Name | Type | Description | +| --- | --- | --- | +| `m` | `int64_t` | | +| `n` | `int64_t` | | +| `n_landmarks` | `int64_t` | | +| `X` | `raft::device_matrix_view` | | +| `metric` | [`cuvs::distance::DistanceType`](/api-reference/cpp-api-distance-distance#cuvs-distance-distancetype) | | +| `R_indptr` | `private: raft::device_vector` | | +| `R_1nn_cols` | `raft::device_vector` | | +| `R_1nn_dists` | `raft::device_vector` | | +| `R_closest_landmark_dists` | `raft::device_vector` | | +| `R_radius` | `raft::device_vector` | | +| `R` | `raft::device_matrix` | | +| `X_reordered` | `raft::device_matrix` | | +| `index_trained` | `protected: bool` | | + +_Source: `cpp/include/cuvs/neighbors/ball_cover.hpp:35`_ + ## Random Ball Cover algorithm @@ -26,7 +60,7 @@ cuvs::neighbors::ball_cover::index | Name | Direction | Type | Description | | --- | --- | --- | --- | | `handle` | in | `raft::resources const&` | library resource management handle | -| `index` | inout | `index&` | an empty (and not previous built) instance of | +| `index` | inout | [`index&`](/api-reference/cpp-api-neighbors-ball-cover#cuvs-neighbors-ball-cover-index) | an empty (and not previous built) instance of | **Returns** diff --git a/fern/pages/cpp_api/cpp-api-neighbors-brute-force.md b/fern/pages/cpp_api/cpp-api-neighbors-brute-force.md index 198e7c869c..102bffede7 100644 --- a/fern/pages/cpp_api/cpp-api-neighbors-brute-force.md +++ b/fern/pages/cpp_api/cpp-api-neighbors-brute-force.md @@ -11,6 +11,30 @@ _Source header: `cpp/include/cuvs/neighbors/brute_force.hpp`_ ### cuvs::neighbors::brute_force::index +Brute Force index. + +The index stores the dataset and norms for the dataset in device memory. + +```cpp +template +struct index : cuvs::neighbors::index { ... }; +``` + +**Fields** + +| Name | Type | Description | +| --- | --- | --- | +| `dataset_` | `raft::device_matrix` | | +| `norms_` | `std::optional>` | | +| `norms_view_` | `std::optional>` | | +| `dataset_view_` | `raft::device_matrix_view` | | +| `metric_arg_` | `DistT` | | + +_Source: `cpp/include/cuvs/neighbors/brute_force.hpp:34`_ + + +### cuvs::neighbors::brute_force::index::index + Construct an empty index. ```cpp @@ -31,7 +55,7 @@ Constructs an empty index. This index will either need to be trained with `build _Source: `cpp/include/cuvs/neighbors/brute_force.hpp:54`_ -**Additional overload:** `cuvs::neighbors::brute_force::index` +**Additional overload:** `cuvs::neighbors::brute_force::index::index` Construct a brute force index from dataset @@ -61,7 +85,7 @@ Constructs a brute force index from a dataset. This lets us precompute norms for _Source: `cpp/include/cuvs/neighbors/brute_force.hpp:63`_ -**Additional overload:** `cuvs::neighbors::brute_force::index` +**Additional overload:** `cuvs::neighbors::brute_force::index::index` Construct a brute force index from dataset @@ -91,7 +115,7 @@ Constructs a brute force index from a dataset. This lets us precompute norms for _Source: `cpp/include/cuvs/neighbors/brute_force.hpp:76`_ -**Additional overload:** `cuvs::neighbors::brute_force::index` +**Additional overload:** `cuvs::neighbors::brute_force::index::index` Construct a brute force index from dataset @@ -121,7 +145,7 @@ This class stores a non-owning reference to the dataset and norms. Having precom _Source: `cpp/include/cuvs/neighbors/brute_force.hpp:87`_ -**Additional overload:** `cuvs::neighbors::brute_force::index` +**Additional overload:** `cuvs::neighbors::brute_force::index::index` Construct a brute force index from dataset @@ -151,7 +175,7 @@ Constructs a brute force index from a dataset. This lets us precompute norms for _Source: `cpp/include/cuvs/neighbors/brute_force.hpp:100`_ -**Additional overload:** `cuvs::neighbors::brute_force::index` +**Additional overload:** `cuvs::neighbors::brute_force::index::index` Construct a brute force index from dataset @@ -181,8 +205,8 @@ This class stores a non-owning reference to the dataset and norms, with the data _Source: `cpp/include/cuvs/neighbors/brute_force.hpp:111`_ - -### cuvs::neighbors::brute_force::update_dataset + +### cuvs::neighbors::brute_force::index::update_dataset Replace the dataset with a new dataset. @@ -204,7 +228,7 @@ raft::device_matrix_view dataset); _Source: `cpp/include/cuvs/neighbors/brute_force.hpp:120`_ -**Additional overload:** `cuvs::neighbors::brute_force::update_dataset` +**Additional overload:** `cuvs::neighbors::brute_force::index::update_dataset` Replace the dataset with a new dataset. @@ -228,8 +252,8 @@ We create a copy of the dataset on the device. The index manages the lifetime of _Source: `cpp/include/cuvs/neighbors/brute_force.hpp:128`_ - -### cuvs::neighbors::brute_force::metric + +### cuvs::neighbors::brute_force::index::metric Distance metric used for retrieval @@ -243,8 +267,8 @@ cuvs::distance::DistanceType metric() const noexcept; _Source: `cpp/include/cuvs/neighbors/brute_force.hpp:132`_ - -### cuvs::neighbors::brute_force::metric_arg + +### cuvs::neighbors::brute_force::index::metric_arg Metric argument @@ -258,8 +282,8 @@ DistT metric_arg() const noexcept; _Source: `cpp/include/cuvs/neighbors/brute_force.hpp:135`_ - -### cuvs::neighbors::brute_force::size + +### cuvs::neighbors::brute_force::index::size Total length of the index (number of vectors). @@ -273,8 +297,8 @@ size_t size() const noexcept; _Source: `cpp/include/cuvs/neighbors/brute_force.hpp:138`_ - -### cuvs::neighbors::brute_force::dim + +### cuvs::neighbors::brute_force::index::dim Dimensionality of the data. @@ -288,8 +312,8 @@ size_t dim() const noexcept; _Source: `cpp/include/cuvs/neighbors/brute_force.hpp:141`_ - -### cuvs::neighbors::brute_force::dataset + +### cuvs::neighbors::brute_force::index::dataset Dataset [size, dim] @@ -303,8 +327,8 @@ raft::device_matrix_view dataset() const noex _Source: `cpp/include/cuvs/neighbors/brute_force.hpp:144`_ - -### cuvs::neighbors::brute_force::norms + +### cuvs::neighbors::brute_force::index::norms Dataset norms @@ -318,8 +342,8 @@ raft::device_vector_view norms() const; _Source: `cpp/include/cuvs/neighbors/brute_force.hpp:150`_ - -### cuvs::neighbors::brute_force::has_norms + +### cuvs::neighbors::brute_force::index::has_norms Whether ot not this index has dataset norms @@ -359,7 +383,7 @@ Usage example: **Returns** -`cuvs::neighbors::brute_force::index` +[`cuvs::neighbors::brute_force::index`](/api-reference/cpp-api-neighbors-brute-force#cuvs-neighbors-brute-force-index) the constructed brute-force index @@ -386,7 +410,7 @@ raft::host_matrix_view dataset) **Returns** -`cuvs::neighbors::brute_force::index` +[`cuvs::neighbors::brute_force::index`](/api-reference/cpp-api-neighbors-brute-force#cuvs-neighbors-brute-force-index) the constructed brute-force index @@ -415,7 +439,7 @@ Usage example: **Returns** -`cuvs::neighbors::brute_force::index` +[`cuvs::neighbors::brute_force::index`](/api-reference/cpp-api-neighbors-brute-force#cuvs-neighbors-brute-force-index) the constructed brute force index @@ -442,7 +466,7 @@ raft::host_matrix_view dataset) **Returns** -`cuvs::neighbors::brute_force::index` +[`cuvs::neighbors::brute_force::index`](/api-reference/cpp-api-neighbors-brute-force#cuvs-neighbors-brute-force-index) the constructed brute-force index @@ -471,7 +495,7 @@ Usage example: **Returns** -`cuvs::neighbors::brute_force::index` +[`cuvs::neighbors::brute_force::index`](/api-reference/cpp-api-neighbors-brute-force#cuvs-neighbors-brute-force-index) the constructed brute force index @@ -500,7 +524,7 @@ Usage example: **Returns** -`cuvs::neighbors::brute_force::index` +[`cuvs::neighbors::brute_force::index`](/api-reference/cpp-api-neighbors-brute-force#cuvs-neighbors-brute-force-index) the constructed brute force index @@ -511,6 +535,25 @@ _Source: `cpp/include/cuvs/neighbors/brute_force.hpp:298`_ ### cuvs::neighbors::brute_force::sparse_index +Sparse Brute Force index. + +```cpp +template +struct sparse_index { ... }; +``` + +**Fields** + +| Name | Type | Description | +| --- | --- | --- | +| `metric_` | [`cuvs::distance::DistanceType`](/api-reference/cpp-api-distance-distance#cuvs-distance-distancetype) | | +| `metric_arg_` | `T` | | + +_Source: `cpp/include/cuvs/neighbors/brute_force.hpp:599`_ + + +### cuvs::neighbors::brute_force::sparse_index::sparse_index + Construct a sparse brute force sparse_index from dataset ```cpp @@ -535,7 +578,8 @@ T metric_arg); _Source: `cpp/include/cuvs/neighbors/brute_force.hpp:609`_ -**Additional overload:** `cuvs::neighbors::brute_force::metric` + +### cuvs::neighbors::brute_force::sparse_index::metric Distance metric used for retrieval @@ -549,7 +593,8 @@ cuvs::distance::DistanceType metric() const noexcept; _Source: `cpp/include/cuvs/neighbors/brute_force.hpp:615`_ -**Additional overload:** `cuvs::neighbors::brute_force::metric_arg` + +### cuvs::neighbors::brute_force::sparse_index::metric_arg Metric argument @@ -571,7 +616,7 @@ _Source: `cpp/include/cuvs/neighbors/brute_force.hpp:618`_ Sparse Brute Force index search ```cpp -struct sparse_search_params { ... } ; +struct sparse_search_params { ... }; ``` _Source: `cpp/include/cuvs/neighbors/brute_force.hpp:668`_ @@ -606,7 +651,7 @@ output | --- | --- | --- | --- | | `handle` | in | `raft::resources const&` | the raft handle | | `filename` | in | `const std::string&` | the file name for saving the index | -| `index` | in | `const cuvs::neighbors::brute_force::index&` | brute force index | +| `index` | in | [`const cuvs::neighbors::brute_force::index&`](/api-reference/cpp-api-neighbors-brute-force#cuvs-neighbors-brute-force-index) | brute force index | | `include_dataset` | in | `bool` | whether to include the dataset in the serialized Default: `true`. | **Returns** @@ -642,7 +687,7 @@ output | --- | --- | --- | --- | | `handle` | in | `raft::resources const&` | the raft handle | | `filename` | in | `const std::string&` | the file name for saving the index | -| `index` | in | `const cuvs::neighbors::brute_force::index&` | brute force index | +| `index` | in | [`const cuvs::neighbors::brute_force::index&`](/api-reference/cpp-api-neighbors-brute-force#cuvs-neighbors-brute-force-index) | brute force index | | `include_dataset` | in | `bool` | whether to include the dataset in the serialized Default: `true`. | **Returns** @@ -670,7 +715,7 @@ The serialization format can be subject to changes, therefore loading an index s | --- | --- | --- | --- | | `handle` | in | `raft::resources const&` | the raft handle | | `os` | in | `std::ostream&` | output stream | -| `index` | in | `const cuvs::neighbors::brute_force::index&` | brute force index | +| `index` | in | [`const cuvs::neighbors::brute_force::index&`](/api-reference/cpp-api-neighbors-brute-force#cuvs-neighbors-brute-force-index) | brute force index | | `include_dataset` | in | `bool` | Whether or not to write out the dataset to the file. Default: `true`. | **Returns** @@ -698,7 +743,7 @@ The serialization format can be subject to changes, therefore loading an index s | --- | --- | --- | --- | | `handle` | in | `raft::resources const&` | the raft handle | | `os` | in | `std::ostream&` | output stream | -| `index` | in | `const cuvs::neighbors::brute_force::index&` | brute force index | +| `index` | in | [`const cuvs::neighbors::brute_force::index&`](/api-reference/cpp-api-neighbors-brute-force#cuvs-neighbors-brute-force-index) | brute force index | | `include_dataset` | in | `bool` | Whether or not to write out the dataset to the file. Default: `true`. | **Returns** @@ -726,7 +771,7 @@ The serialization format can be subject to changes, therefore loading an index s | --- | --- | --- | --- | | `handle` | in | `raft::resources const&` | the raft handle | | `filename` | in | `const std::string&` | the name of the file that stores the index | -| `index` | out | `cuvs::neighbors::brute_force::index*` | brute force index | +| `index` | out | [`cuvs::neighbors::brute_force::index*`](/api-reference/cpp-api-neighbors-brute-force#cuvs-neighbors-brute-force-index) | brute force index | **Returns** @@ -752,7 +797,7 @@ The serialization format can be subject to changes, therefore loading an index s | --- | --- | --- | --- | | `handle` | in | `raft::resources const&` | the raft handle | | `filename` | in | `const std::string&` | the name of the file that stores the index | -| `index` | out | `cuvs::neighbors::brute_force::index*` | brute force index | +| `index` | out | [`cuvs::neighbors::brute_force::index*`](/api-reference/cpp-api-neighbors-brute-force#cuvs-neighbors-brute-force-index) | brute force index | **Returns** @@ -778,7 +823,7 @@ The serialization format can be subject to changes, therefore loading an index s | --- | --- | --- | --- | | `handle` | in | `raft::resources const&` | the raft handle | | `is` | in | `std::istream&` | input stream | -| `index` | out | `cuvs::neighbors::brute_force::index*` | brute force index | +| `index` | out | [`cuvs::neighbors::brute_force::index*`](/api-reference/cpp-api-neighbors-brute-force#cuvs-neighbors-brute-force-index) | brute force index | **Returns** @@ -804,7 +849,7 @@ The serialization format can be subject to changes, therefore loading an index s | --- | --- | --- | --- | | `handle` | in | `raft::resources const&` | the raft handle | | `is` | in | `std::istream&` | input stream | -| `index` | out | `cuvs::neighbors::brute_force::index*` | brute force index | +| `index` | out | [`cuvs::neighbors::brute_force::index*`](/api-reference/cpp-api-neighbors-brute-force#cuvs-neighbors-brute-force-index) | brute force index | **Returns** diff --git a/fern/pages/cpp_api/cpp-api-neighbors-cagra.md b/fern/pages/cpp_api/cpp-api-neighbors-cagra.md index 35b306e808..1ddafe4960 100644 --- a/fern/pages/cpp_api/cpp-api-neighbors-cagra.md +++ b/fern/pages/cpp_api/cpp-api-neighbors-cagra.md @@ -14,7 +14,7 @@ _Source header: `cpp/include/cuvs/neighbors/cagra.hpp`_ Specialized parameters for ACE (Augmented Core Extraction) graph build ```cpp -struct ace_params { ... } ; +struct ace_params { ... }; ``` **Fields** @@ -38,7 +38,7 @@ _Source: `cpp/include/cuvs/neighbors/cagra.hpp:37`_ Parameters for VPQ compression. ```cpp -struct vpq_params { ... } ; +struct vpq_params { ... }; ``` **Fields** @@ -67,13 +67,13 @@ parameters. Define how `cagra::index_params::from_hnsw_params` should construct a graph to construct a graph that is to be converted to (used by) a CPU HNSW index. ```cpp -enum class hnsw_heuristic_type : uint32_t { ... } ; +enum class hnsw_heuristic_type : uint32_t { ... }; ``` _Source: `cpp/include/cuvs/neighbors/cagra.hpp:115`_ - -### cuvs::neighbors::cagra::from_hnsw_params + +### cuvs::neighbors::cagra::index_params::from_hnsw_params Create a CAGRA index parameters compatible with HNSW index @@ -116,7 +116,7 @@ _Source: `cpp/include/cuvs/neighbors/cagra.hpp:245`_ CAGRA index search parameters ```cpp -enum class search_algo { ... } ; +enum class search_algo { ... }; ``` **Values** @@ -138,7 +138,7 @@ _Source: `cpp/include/cuvs/neighbors/cagra.hpp:262`_ CAGRA index extend parameters ```cpp -struct extend_params { ... } ; +struct extend_params { ... }; ``` **Fields** @@ -151,8 +151,40 @@ _Source: `cpp/include/cuvs/neighbors/cagra.hpp:357`_ ## CAGRA index type - -### cuvs::neighbors::cagra::metric + +### cuvs::neighbors::cagra::index + +CAGRA index. + +The index stores the dataset and a kNN graph in device memory. + +```cpp +template +struct index : cuvs::neighbors::index { ... }; +``` + +**Fields** + +| Name | Type | Description | +| --- | --- | --- | +| `template ` | `template ` | Replace the dataset with a new dataset. It is expected that the same set of vectors are used for update_dataset and index build. Note: This will clear any precomputed dataset norms. | +| `template ` | `template ` | Copy the provided source indices into the index. | +| `graph_` | `raft::device_matrix` | | +| `graph_view_` | `raft::device_matrix_view` | | +| `dataset_` | `std::unique_ptr>` | | +| `source_indices_` | `std::optional>` | | +| `dataset_norms_` | `std::optional>` | | +| `dataset_fd_` | [`std::optional`](/api-reference/cpp-api-util-file-io#cuvs-util-file-descriptor) | | +| `graph_fd_` | [`std::optional`](/api-reference/cpp-api-util-file-io#cuvs-util-file-descriptor) | | +| `mapping_fd_` | [`std::optional`](/api-reference/cpp-api-util-file-io#cuvs-util-file-descriptor) | | +| `n_rows_` | `size_t` | | +| `dim_` | `size_t` | | +| `graph_degree_` | `size_t` | | + +_Source: `cpp/include/cuvs/neighbors/cagra.hpp:387`_ + + +### cuvs::neighbors::cagra::index::metric Distance metric used for clustering. @@ -166,8 +198,8 @@ Distance metric used for clustering. _Source: `cpp/include/cuvs/neighbors/cagra.hpp:401`_ - -### cuvs::neighbors::cagra::size + +### cuvs::neighbors::cagra::index::size Total length of the index (number of vectors). @@ -181,8 +213,8 @@ Total length of the index (number of vectors). _Source: `cpp/include/cuvs/neighbors/cagra.hpp:407`_ - -### cuvs::neighbors::cagra::dim + +### cuvs::neighbors::cagra::index::dim Dimensionality of the data. @@ -196,8 +228,8 @@ Dimensionality of the data. _Source: `cpp/include/cuvs/neighbors/cagra.hpp:415`_ - -### cuvs::neighbors::cagra::graph_degree + +### cuvs::neighbors::cagra::index::graph_degree Graph degree @@ -211,8 +243,8 @@ Graph degree _Source: `cpp/include/cuvs/neighbors/cagra.hpp:420`_ - -### cuvs::neighbors::cagra::data + +### cuvs::neighbors::cagra::index::data Dataset [size, dim] @@ -222,12 +254,12 @@ Dataset [size, dim] **Returns** -`const cuvs::neighbors::dataset&` +[`const cuvs::neighbors::dataset&`](/api-reference/cpp-api-neighbors-common#cuvs-neighbors-dataset) _Source: `cpp/include/cuvs/neighbors/cagra.hpp:435`_ - -### cuvs::neighbors::cagra::graph + +### cuvs::neighbors::cagra::index::graph neighborhood graph [size, graph-degree] @@ -242,8 +274,8 @@ neighborhood graph [size, graph-degree] _Source: `cpp/include/cuvs/neighbors/cagra.hpp:441`_ - -### cuvs::neighbors::cagra::source_indices + +### cuvs::neighbors::cagra::index::source_indices Mapping from internal graph node indices to the original user-provided indices. @@ -258,8 +290,8 @@ Mapping from internal graph node indices to the original user-provided indices. _Source: `cpp/include/cuvs/neighbors/cagra.hpp:448`_ - -### cuvs::neighbors::cagra::dataset_fd + +### cuvs::neighbors::cagra::index::dataset_fd Get the dataset file descriptor (for disk-backed index) @@ -274,8 +306,8 @@ Get the dataset file descriptor (for disk-backed index) _Source: `cpp/include/cuvs/neighbors/cagra.hpp:458`_ - -### cuvs::neighbors::cagra::graph_fd + +### cuvs::neighbors::cagra::index::graph_fd Get the graph file descriptor (for disk-backed index) @@ -290,8 +322,8 @@ Get the graph file descriptor (for disk-backed index) _Source: `cpp/include/cuvs/neighbors/cagra.hpp:465`_ - -### cuvs::neighbors::cagra::mapping_fd + +### cuvs::neighbors::cagra::index::mapping_fd Get the mapping file descriptor (for disk-backed index) @@ -306,8 +338,8 @@ Get the mapping file descriptor (for disk-backed index) _Source: `cpp/include/cuvs/neighbors/cagra.hpp:472`_ - -### cuvs::neighbors::cagra::dataset_norms + +### cuvs::neighbors::cagra::index::dataset_norms Dataset norms for cosine distance [size] @@ -322,8 +354,8 @@ Dataset norms for cosine distance [size] _Source: `cpp/include/cuvs/neighbors/cagra.hpp:479`_ - -### cuvs::neighbors::cagra::index + +### cuvs::neighbors::cagra::index::index ```cpp index(const index&) = delete; @@ -333,7 +365,7 @@ index(const index&) = delete; | Name | Direction | Type | Description | | --- | --- | --- | --- | -| `arg1` | | `const index&` | | +| `arg1` | | [`const index&`](/api-reference/cpp-api-neighbors-cagra#cuvs-neighbors-cagra-index) | | **Returns** @@ -341,7 +373,7 @@ index(const index&) = delete; _Source: `cpp/include/cuvs/neighbors/cagra.hpp:488`_ -**Additional overload:** `cuvs::neighbors::cagra::index` +**Additional overload:** `cuvs::neighbors::cagra::index::index` Construct an empty index. @@ -364,7 +396,7 @@ cuvs::distance::DistanceType metric = cuvs::distance::DistanceType::L2Expanded) _Source: `cpp/include/cuvs/neighbors/cagra.hpp:496`_ -**Additional overload:** `cuvs::neighbors::cagra::index` +**Additional overload:** `cuvs::neighbors::cagra::index::index` Construct an index from dataset and knn_graph arrays @@ -407,8 +439,8 @@ Usage examples: _Source: `cpp/include/cuvs/neighbors/cagra.hpp:559`_ - -### cuvs::neighbors::cagra::update_dataset + +### cuvs::neighbors::cagra::index::update_dataset Replace the dataset with a new dataset. @@ -434,7 +466,7 @@ Note: This will clear any precomputed dataset norms. _Source: `cpp/include/cuvs/neighbors/cagra.hpp:597`_ -**Additional overload:** `cuvs::neighbors::cagra::update_dataset` +**Additional overload:** `cuvs::neighbors::cagra::index::update_dataset` Set the dataset reference explicitly to a device matrix view with padding. @@ -456,7 +488,7 @@ raft::device_matrix_view dataset); _Source: `cpp/include/cuvs/neighbors/cagra.hpp:609`_ -**Additional overload:** `cuvs::neighbors::cagra::update_dataset` +**Additional overload:** `cuvs::neighbors::cagra::index::update_dataset` Replace the dataset with a new dataset. @@ -482,7 +514,7 @@ Note: This will clear any precomputed dataset norms. _Source: `cpp/include/cuvs/neighbors/cagra.hpp:628`_ -**Additional overload:** `cuvs::neighbors::cagra::update_dataset` +**Additional overload:** `cuvs::neighbors::cagra::index::update_dataset` Replace the dataset with a new dataset. It is expected that the same set of vectors are used @@ -505,12 +537,12 @@ Note: This will clear any precomputed dataset norms. **Returns** -`std::enable_if_t, DatasetT>>` +[`std::enable_if_t, DatasetT>>`](/api-reference/cpp-api-neighbors-common#cuvs-neighbors-dataset) _Source: `cpp/include/cuvs/neighbors/cagra.hpp:644`_ - -### cuvs::neighbors::cagra::update_graph + +### cuvs::neighbors::cagra::index::update_graph Replace the graph with a new graph. @@ -535,7 +567,7 @@ Since the new graph is a device array, we store a reference to that, and it is t _Source: `cpp/include/cuvs/neighbors/cagra.hpp:677`_ -**Additional overload:** `cuvs::neighbors::cagra::update_graph` +**Additional overload:** `cuvs::neighbors::cagra::index::update_graph` Replace the graph with a new graph. @@ -560,8 +592,8 @@ We create a copy of the graph on the device. The index manages the lifetime of t _Source: `cpp/include/cuvs/neighbors/cagra.hpp:689`_ - -### cuvs::neighbors::cagra::update_source_indices + +### cuvs::neighbors::cagra::index::update_source_indices Replace the source indices with a new source indices taking the ownership of the passed vector. @@ -581,7 +613,7 @@ void update_source_indices(raft::device_vector&& source_ind _Source: `cpp/include/cuvs/neighbors/cagra.hpp:713`_ -**Additional overload:** `cuvs::neighbors::cagra::update_source_indices` +**Additional overload:** `cuvs::neighbors::cagra::index::update_source_indices` Copy the provided source indices into the index. @@ -606,7 +638,7 @@ source_indices); _Source: `cpp/include/cuvs/neighbors/cagra.hpp:723`_ -**Additional overload:** `cuvs::neighbors::cagra::update_dataset` +**Additional overload:** `cuvs::neighbors::cagra::index::update_dataset` Update the dataset from a disk file using a file descriptor. @@ -629,7 +661,7 @@ This method configures the index to use a disk-based dataset. The dataset file s _Source: `cpp/include/cuvs/neighbors/cagra.hpp:759`_ -**Additional overload:** `cuvs::neighbors::cagra::update_graph` +**Additional overload:** `cuvs::neighbors::cagra::index::update_graph` Update the graph from a disk file using a file descriptor. @@ -652,8 +684,8 @@ This method configures the index to use a disk-based graph. The graph file shoul _Source: `cpp/include/cuvs/neighbors/cagra.hpp:794`_ - -### cuvs::neighbors::cagra::update_mapping + +### cuvs::neighbors::cagra::index::update_mapping Update the dataset mapping from a disk file using a file descriptor. @@ -711,7 +743,7 @@ Usage example: **Returns** -`cuvs::neighbors::cagra::index` +[`cuvs::neighbors::cagra::index`](/api-reference/cpp-api-neighbors-cagra#cuvs-neighbors-cagra-index) the constructed cagra index @@ -749,7 +781,7 @@ Usage example: **Returns** -`cuvs::neighbors::cagra::index` +[`cuvs::neighbors::cagra::index`](/api-reference/cpp-api-neighbors-cagra#cuvs-neighbors-cagra-index) the constructed cagra index @@ -787,7 +819,7 @@ Usage example: **Returns** -`cuvs::neighbors::cagra::index` +[`cuvs::neighbors::cagra::index`](/api-reference/cpp-api-neighbors-cagra#cuvs-neighbors-cagra-index) the constructed cagra index @@ -824,7 +856,7 @@ Usage example: **Returns** -`cuvs::neighbors::cagra::index` +[`cuvs::neighbors::cagra::index`](/api-reference/cpp-api-neighbors-cagra#cuvs-neighbors-cagra-index) the constructed cagra index @@ -862,7 +894,7 @@ Usage example: **Returns** -`cuvs::neighbors::cagra::index` +[`cuvs::neighbors::cagra::index`](/api-reference/cpp-api-neighbors-cagra#cuvs-neighbors-cagra-index) the constructed cagra index @@ -901,7 +933,7 @@ Usage example: **Returns** -`cuvs::neighbors::cagra::index` +[`cuvs::neighbors::cagra::index`](/api-reference/cpp-api-neighbors-cagra#cuvs-neighbors-cagra-index) the constructed cagra index @@ -940,7 +972,7 @@ Usage example: **Returns** -`cuvs::neighbors::cagra::index` +[`cuvs::neighbors::cagra::index`](/api-reference/cpp-api-neighbors-cagra#cuvs-neighbors-cagra-index) the constructed cagra index @@ -979,7 +1011,7 @@ Usage example: **Returns** -`cuvs::neighbors::cagra::index` +[`cuvs::neighbors::cagra::index`](/api-reference/cpp-api-neighbors-cagra#cuvs-neighbors-cagra-index) the constructed cagra index @@ -1014,7 +1046,7 @@ part. The data will be copied from the current index in this function. The num r | `handle` | in | `raft::resources const&` | raft resources | | `params` | in | [`const cagra::extend_params&`](/api-reference/cpp-api-neighbors-cagra#cuvs-neighbors-cagra-extend-params) | extend params | | `additional_dataset` | in | `raft::device_matrix_view` | additional dataset on device memory | -| `idx` | in,out | `cuvs::neighbors::cagra::index&` | CAGRA index | +| `idx` | in,out | [`cuvs::neighbors::cagra::index&`](/api-reference/cpp-api-neighbors-cagra#cuvs-neighbors-cagra-index) | CAGRA index | | `new_dataset_buffer_view` | out | `std::optional>` | memory buffer view for the dataset including the additional Default: `std::nullopt`. | | `new_graph_buffer_view` | out | `std::optional>` | memory buffer view for the graph including the additional part. Default: `std::nullopt`. | @@ -1050,7 +1082,7 @@ part. The data will be copied from the current index in this function. The num r | `handle` | in | `raft::resources const&` | raft resources | | `params` | in | [`const cagra::extend_params&`](/api-reference/cpp-api-neighbors-cagra#cuvs-neighbors-cagra-extend-params) | extend params | | `additional_dataset` | in | `raft::host_matrix_view` | additional dataset on host memory | -| `idx` | in,out | `cuvs::neighbors::cagra::index&` | CAGRA index | +| `idx` | in,out | [`cuvs::neighbors::cagra::index&`](/api-reference/cpp-api-neighbors-cagra#cuvs-neighbors-cagra-index) | CAGRA index | | `new_dataset_buffer_view` | out | `std::optional>` | memory buffer view for the dataset including the additional Default: `std::nullopt`. | | `new_graph_buffer_view` | out | `std::optional>` | memory buffer view for the graph including the additional part. Default: `std::nullopt`. | @@ -1086,7 +1118,7 @@ part. The data will be copied from the current index in this function. The num r | `handle` | in | `raft::resources const&` | raft resources | | `params` | in | [`const cagra::extend_params&`](/api-reference/cpp-api-neighbors-cagra#cuvs-neighbors-cagra-extend-params) | extend params | | `additional_dataset` | in | `raft::device_matrix_view` | additional dataset on device memory | -| `idx` | in,out | `cuvs::neighbors::cagra::index&` | CAGRA index | +| `idx` | in,out | [`cuvs::neighbors::cagra::index&`](/api-reference/cpp-api-neighbors-cagra#cuvs-neighbors-cagra-index) | CAGRA index | | `new_dataset_buffer_view` | out | `std::optional>` | memory buffer view for the dataset including the additional Default: `std::nullopt`. | | `new_graph_buffer_view` | out | `std::optional>` | memory buffer view for the graph including the additional part. Default: `std::nullopt`. | @@ -1122,7 +1154,7 @@ part. The data will be copied from the current index in this function. The num r | `handle` | in | `raft::resources const&` | raft resources | | `params` | in | [`const cagra::extend_params&`](/api-reference/cpp-api-neighbors-cagra#cuvs-neighbors-cagra-extend-params) | extend params | | `additional_dataset` | in | `raft::host_matrix_view` | additional dataset on host memory | -| `idx` | in,out | `cuvs::neighbors::cagra::index&` | CAGRA index | +| `idx` | in,out | [`cuvs::neighbors::cagra::index&`](/api-reference/cpp-api-neighbors-cagra#cuvs-neighbors-cagra-index) | CAGRA index | | `new_dataset_buffer_view` | out | `std::optional>` | memory buffer view for the dataset including the additional Default: `std::nullopt`. | | `new_graph_buffer_view` | out | `std::optional>` | memory buffer view for the graph including the additional part. Default: `std::nullopt`. | @@ -1158,7 +1190,7 @@ part. The data will be copied from the current index in this function. The num r | `handle` | in | `raft::resources const&` | raft resources | | `params` | in | [`const cagra::extend_params&`](/api-reference/cpp-api-neighbors-cagra#cuvs-neighbors-cagra-extend-params) | extend params | | `additional_dataset` | in | `raft::device_matrix_view` | additional dataset on device memory | -| `idx` | in,out | `cuvs::neighbors::cagra::index&` | CAGRA index | +| `idx` | in,out | [`cuvs::neighbors::cagra::index&`](/api-reference/cpp-api-neighbors-cagra#cuvs-neighbors-cagra-index) | CAGRA index | | `new_dataset_buffer_view` | out | `std::optional>` | memory buffer view for the dataset including the additional Default: `std::nullopt`. | | `new_graph_buffer_view` | out | `std::optional>` | memory buffer view for the graph including the additional part. Default: `std::nullopt`. | @@ -1194,7 +1226,7 @@ part. The data will be copied from the current index in this function. The num r | `handle` | in | `raft::resources const&` | raft resources | | `params` | in | [`const cagra::extend_params&`](/api-reference/cpp-api-neighbors-cagra#cuvs-neighbors-cagra-extend-params) | extend params | | `additional_dataset` | in | `raft::host_matrix_view` | additional dataset on host memory | -| `idx` | in,out | `cuvs::neighbors::cagra::index&` | CAGRA index | +| `idx` | in,out | [`cuvs::neighbors::cagra::index&`](/api-reference/cpp-api-neighbors-cagra#cuvs-neighbors-cagra-index) | CAGRA index | | `new_dataset_buffer_view` | out | `std::optional>` | memory buffer view for the dataset including the additional Default: `std::nullopt`. | | `new_graph_buffer_view` | out | `std::optional>` | memory buffer view for the graph including the additional part. Default: `std::nullopt`. | @@ -1230,7 +1262,7 @@ part. The data will be copied from the current index in this function. The num r | `handle` | in | `raft::resources const&` | raft resources | | `params` | in | [`const cagra::extend_params&`](/api-reference/cpp-api-neighbors-cagra#cuvs-neighbors-cagra-extend-params) | extend params | | `additional_dataset` | in | `raft::device_matrix_view` | additional dataset on host memory | -| `idx` | in,out | `cuvs::neighbors::cagra::index&` | CAGRA index | +| `idx` | in,out | [`cuvs::neighbors::cagra::index&`](/api-reference/cpp-api-neighbors-cagra#cuvs-neighbors-cagra-index) | CAGRA index | | `new_dataset_buffer_view` | out | `std::optional>` | memory buffer view for the dataset including the additional Default: `std::nullopt`. | | `new_graph_buffer_view` | out | `std::optional>` | memory buffer view for the graph including the additional part. Default: `std::nullopt`. | @@ -1266,7 +1298,7 @@ part. The data will be copied from the current index in this function. The num r | `handle` | in | `raft::resources const&` | raft resources | | `params` | in | [`const cagra::extend_params&`](/api-reference/cpp-api-neighbors-cagra#cuvs-neighbors-cagra-extend-params) | extend params | | `additional_dataset` | in | `raft::host_matrix_view` | additional dataset on host memory | -| `idx` | in,out | `cuvs::neighbors::cagra::index&` | CAGRA index | +| `idx` | in,out | [`cuvs::neighbors::cagra::index&`](/api-reference/cpp-api-neighbors-cagra#cuvs-neighbors-cagra-index) | CAGRA index | | `new_dataset_buffer_view` | out | `std::optional>` | memory buffer view for the dataset including the additional Default: `std::nullopt`. | | `new_graph_buffer_view` | out | `std::optional>` | memory buffer view for the graph including the additional part. Default: `std::nullopt`. | @@ -1318,7 +1350,7 @@ Experimental, both the API and the serialization format are subject to change. | --- | --- | --- | --- | | `handle` | in | `raft::resources const&` | the raft handle | | `filename` | in | `const std::string&` | the file name for saving the index | -| `index` | in | `const cuvs::neighbors::cagra::index&` | CAGRA index | +| `index` | in | [`const cuvs::neighbors::cagra::index&`](/api-reference/cpp-api-neighbors-cagra#cuvs-neighbors-cagra-index) | CAGRA index | | `include_dataset` | in | `bool` | Whether or not to write out the dataset to the file. Default: `true`. | **Returns** @@ -1346,7 +1378,7 @@ Experimental, both the API and the serialization format are subject to change. | --- | --- | --- | --- | | `handle` | in | `raft::resources const&` | the raft handle | | `filename` | in | `const std::string&` | the name of the file that stores the index | -| `index` | out | `cuvs::neighbors::cagra::index*` | the cagra index | +| `index` | out | [`cuvs::neighbors::cagra::index*`](/api-reference/cpp-api-neighbors-cagra#cuvs-neighbors-cagra-index) | the cagra index | **Returns** @@ -1373,7 +1405,7 @@ Experimental, both the API and the serialization format are subject to change. | --- | --- | --- | --- | | `handle` | in | `raft::resources const&` | the raft handle | | `os` | in | `std::ostream&` | output stream | -| `index` | in | `const cuvs::neighbors::cagra::index&` | CAGRA index | +| `index` | in | [`const cuvs::neighbors::cagra::index&`](/api-reference/cpp-api-neighbors-cagra#cuvs-neighbors-cagra-index) | CAGRA index | | `include_dataset` | in | `bool` | Whether or not to write out the dataset to the file. Default: `true`. | **Returns** @@ -1400,7 +1432,7 @@ Experimental, both the API and the serialization format are subject to change. | --- | --- | --- | --- | | `handle` | in | `raft::resources const&` | the raft handle | | `is` | in | `std::istream&` | input stream | -| `index` | out | `cuvs::neighbors::cagra::index*` | the cagra index | +| `index` | out | [`cuvs::neighbors::cagra::index*`](/api-reference/cpp-api-neighbors-cagra#cuvs-neighbors-cagra-index) | the cagra index | **Returns** @@ -1427,7 +1459,7 @@ Experimental, both the API and the serialization format are subject to change. | --- | --- | --- | --- | | `handle` | in | `raft::resources const&` | the raft handle | | `filename` | in | `const std::string&` | the file name for saving the index | -| `index` | in | `const cuvs::neighbors::cagra::index&` | CAGRA index | +| `index` | in | [`const cuvs::neighbors::cagra::index&`](/api-reference/cpp-api-neighbors-cagra#cuvs-neighbors-cagra-index) | CAGRA index | | `include_dataset` | in | `bool` | Whether or not to write out the dataset to the file. Default: `true`. | **Returns** @@ -1454,7 +1486,7 @@ Experimental, both the API and the serialization format are subject to change. | --- | --- | --- | --- | | `handle` | in | `raft::resources const&` | the raft handle | | `filename` | in | `const std::string&` | the name of the file that stores the index | -| `index` | out | `cuvs::neighbors::cagra::index*` | the cagra index | +| `index` | out | [`cuvs::neighbors::cagra::index*`](/api-reference/cpp-api-neighbors-cagra#cuvs-neighbors-cagra-index) | the cagra index | **Returns** @@ -1481,7 +1513,7 @@ Experimental, both the API and the serialization format are subject to change. | --- | --- | --- | --- | | `handle` | in | `raft::resources const&` | the raft handle | | `os` | in | `std::ostream&` | output stream | -| `index` | in | `const cuvs::neighbors::cagra::index&` | CAGRA index | +| `index` | in | [`const cuvs::neighbors::cagra::index&`](/api-reference/cpp-api-neighbors-cagra#cuvs-neighbors-cagra-index) | CAGRA index | | `include_dataset` | in | `bool` | Whether or not to write out the dataset to the file. Default: `true`. | **Returns** @@ -1508,7 +1540,7 @@ Experimental, both the API and the serialization format are subject to change. | --- | --- | --- | --- | | `handle` | in | `raft::resources const&` | the raft handle | | `is` | in | `std::istream&` | input stream | -| `index` | out | `cuvs::neighbors::cagra::index*` | the cagra index | +| `index` | out | [`cuvs::neighbors::cagra::index*`](/api-reference/cpp-api-neighbors-cagra#cuvs-neighbors-cagra-index) | the cagra index | **Returns** @@ -1535,7 +1567,7 @@ Experimental, both the API and the serialization format are subject to change. | --- | --- | --- | --- | | `handle` | in | `raft::resources const&` | the raft handle | | `filename` | in | `const std::string&` | the file name for saving the index | -| `index` | in | `const cuvs::neighbors::cagra::index&` | CAGRA index | +| `index` | in | [`const cuvs::neighbors::cagra::index&`](/api-reference/cpp-api-neighbors-cagra#cuvs-neighbors-cagra-index) | CAGRA index | | `include_dataset` | in | `bool` | Whether or not to write out the dataset to the file. Default: `true`. | **Returns** @@ -1562,7 +1594,7 @@ Experimental, both the API and the serialization format are subject to change. | --- | --- | --- | --- | | `handle` | in | `raft::resources const&` | the raft handle | | `filename` | in | `const std::string&` | the name of the file that stores the index | -| `index` | out | `cuvs::neighbors::cagra::index*` | the cagra index | +| `index` | out | [`cuvs::neighbors::cagra::index*`](/api-reference/cpp-api-neighbors-cagra#cuvs-neighbors-cagra-index) | the cagra index | **Returns** @@ -1589,7 +1621,7 @@ Experimental, both the API and the serialization format are subject to change. | --- | --- | --- | --- | | `handle` | in | `raft::resources const&` | the raft handle | | `os` | in | `std::ostream&` | output stream | -| `index` | in | `const cuvs::neighbors::cagra::index&` | CAGRA index | +| `index` | in | [`const cuvs::neighbors::cagra::index&`](/api-reference/cpp-api-neighbors-cagra#cuvs-neighbors-cagra-index) | CAGRA index | | `include_dataset` | in | `bool` | Whether or not to write out the dataset to the file. Default: `true`. | **Returns** @@ -1616,7 +1648,7 @@ Experimental, both the API and the serialization format are subject to change. | --- | --- | --- | --- | | `handle` | in | `raft::resources const&` | the raft handle | | `is` | in | `std::istream&` | input stream | -| `index` | out | `cuvs::neighbors::cagra::index*` | the cagra index | +| `index` | out | [`cuvs::neighbors::cagra::index*`](/api-reference/cpp-api-neighbors-cagra#cuvs-neighbors-cagra-index) | the cagra index | **Returns** @@ -1643,7 +1675,7 @@ Experimental, both the API and the serialization format are subject to change. | --- | --- | --- | --- | | `handle` | in | `raft::resources const&` | the raft handle | | `filename` | in | `const std::string&` | the file name for saving the index | -| `index` | in | `const cuvs::neighbors::cagra::index&` | CAGRA index | +| `index` | in | [`const cuvs::neighbors::cagra::index&`](/api-reference/cpp-api-neighbors-cagra#cuvs-neighbors-cagra-index) | CAGRA index | | `include_dataset` | in | `bool` | Whether or not to write out the dataset to the file. Default: `true`. | **Returns** @@ -1670,7 +1702,7 @@ Experimental, both the API and the serialization format are subject to change. | --- | --- | --- | --- | | `handle` | in | `raft::resources const&` | the raft handle | | `filename` | in | `const std::string&` | the name of the file that stores the index | -| `index` | out | `cuvs::neighbors::cagra::index*` | the cagra index | +| `index` | out | [`cuvs::neighbors::cagra::index*`](/api-reference/cpp-api-neighbors-cagra#cuvs-neighbors-cagra-index) | the cagra index | **Returns** @@ -1697,7 +1729,7 @@ Experimental, both the API and the serialization format are subject to change. | --- | --- | --- | --- | | `handle` | in | `raft::resources const&` | the raft handle | | `os` | in | `std::ostream&` | output stream | -| `index` | in | `const cuvs::neighbors::cagra::index&` | CAGRA index | +| `index` | in | [`const cuvs::neighbors::cagra::index&`](/api-reference/cpp-api-neighbors-cagra#cuvs-neighbors-cagra-index) | CAGRA index | | `include_dataset` | in | `bool` | Whether or not to write out the dataset to the file. Default: `true`. | **Returns** @@ -1724,7 +1756,7 @@ Experimental, both the API and the serialization format are subject to change. | --- | --- | --- | --- | | `handle` | in | `raft::resources const&` | the raft handle | | `is` | in | `std::istream&` | input stream | -| `index` | out | `cuvs::neighbors::cagra::index*` | the cagra index | +| `index` | out | [`cuvs::neighbors::cagra::index*`](/api-reference/cpp-api-neighbors-cagra#cuvs-neighbors-cagra-index) | the cagra index | **Returns** @@ -1756,7 +1788,7 @@ Experimental, both the API and the serialization format are subject to change. | --- | --- | --- | --- | | `handle` | in | `raft::resources const&` | the raft handle | | `os` | in | `std::ostream&` | output stream | -| `index` | in | `const cuvs::neighbors::cagra::index&` | CAGRA index | +| `index` | in | [`const cuvs::neighbors::cagra::index&`](/api-reference/cpp-api-neighbors-cagra#cuvs-neighbors-cagra-index) | CAGRA index | | `dataset` | in | `std::optional>` | [optional] host array that stores the dataset, required if the index does not contain the dataset. Default: `std::nullopt`. | **Returns** @@ -1788,7 +1820,7 @@ Experimental, both the API and the serialization format are subject to change. | --- | --- | --- | --- | | `handle` | in | `raft::resources const&` | the raft handle | | `filename` | in | `const std::string&` | the file name for saving the index | -| `index` | in | `const cuvs::neighbors::cagra::index&` | CAGRA index | +| `index` | in | [`const cuvs::neighbors::cagra::index&`](/api-reference/cpp-api-neighbors-cagra#cuvs-neighbors-cagra-index) | CAGRA index | | `dataset` | in | `std::optional>` | [optional] host array that stores the dataset, required if the index does not contain the dataset. Default: `std::nullopt`. | **Returns** @@ -1820,7 +1852,7 @@ Experimental, both the API and the serialization format are subject to change. | --- | --- | --- | --- | | `handle` | in | `raft::resources const&` | the raft handle | | `os` | in | `std::ostream&` | output stream | -| `index` | in | `const cuvs::neighbors::cagra::index&` | CAGRA index | +| `index` | in | [`const cuvs::neighbors::cagra::index&`](/api-reference/cpp-api-neighbors-cagra#cuvs-neighbors-cagra-index) | CAGRA index | | `dataset` | in | `std::optional>` | [optional] host array that stores the dataset, required if the index does not contain the dataset. Default: `std::nullopt`. | **Returns** @@ -1852,7 +1884,7 @@ Experimental, both the API and the serialization format are subject to change. | --- | --- | --- | --- | | `handle` | in | `raft::resources const&` | the raft handle | | `filename` | in | `const std::string&` | the file name for saving the index | -| `index` | in | `const cuvs::neighbors::cagra::index&` | CAGRA index | +| `index` | in | [`const cuvs::neighbors::cagra::index&`](/api-reference/cpp-api-neighbors-cagra#cuvs-neighbors-cagra-index) | CAGRA index | | `dataset` | in | `std::optional>` | [optional] host array that stores the dataset, required if the index does not contain the dataset. Default: `std::nullopt`. | **Returns** @@ -1884,7 +1916,7 @@ Experimental, both the API and the serialization format are subject to change. | --- | --- | --- | --- | | `handle` | in | `raft::resources const&` | the raft handle | | `os` | in | `std::ostream&` | output stream | -| `index` | in | `const cuvs::neighbors::cagra::index&` | CAGRA index | +| `index` | in | [`const cuvs::neighbors::cagra::index&`](/api-reference/cpp-api-neighbors-cagra#cuvs-neighbors-cagra-index) | CAGRA index | | `dataset` | in | `std::optional>` | [optional] host array that stores the dataset, required if the index does not contain the dataset. Default: `std::nullopt`. | **Returns** @@ -1916,7 +1948,7 @@ Experimental, both the API and the serialization format are subject to change. | --- | --- | --- | --- | | `handle` | in | `raft::resources const&` | the raft handle | | `filename` | in | `const std::string&` | the file name for saving the index | -| `index` | in | `const cuvs::neighbors::cagra::index&` | CAGRA index | +| `index` | in | [`const cuvs::neighbors::cagra::index&`](/api-reference/cpp-api-neighbors-cagra#cuvs-neighbors-cagra-index) | CAGRA index | | `dataset` | in | `std::optional>` | [optional] host array that stores the dataset, required if the index does not contain the dataset. Default: `std::nullopt`. | **Returns** @@ -1948,7 +1980,7 @@ Experimental, both the API and the serialization format are subject to change. | --- | --- | --- | --- | | `handle` | in | `raft::resources const&` | the raft handle | | `os` | in | `std::ostream&` | output stream | -| `index` | in | `const cuvs::neighbors::cagra::index&` | CAGRA index | +| `index` | in | [`const cuvs::neighbors::cagra::index&`](/api-reference/cpp-api-neighbors-cagra#cuvs-neighbors-cagra-index) | CAGRA index | | `dataset` | in | `std::optional>` | [optional] host array that stores the dataset, required if the index does not contain the dataset. Default: `std::nullopt`. | **Returns** @@ -1980,7 +2012,7 @@ Experimental, both the API and the serialization format are subject to change. | --- | --- | --- | --- | | `handle` | in | `raft::resources const&` | the raft handle | | `filename` | in | `const std::string&` | the file name for saving the index | -| `index` | in | `const cuvs::neighbors::cagra::index&` | CAGRA index | +| `index` | in | [`const cuvs::neighbors::cagra::index&`](/api-reference/cpp-api-neighbors-cagra#cuvs-neighbors-cagra-index) | CAGRA index | | `dataset` | in | `std::optional>` | [optional] host array that stores the dataset, required if the index does not contain the dataset. Default: `std::nullopt`. | **Returns** diff --git a/fern/pages/cpp_api/cpp-api-neighbors-common.md b/fern/pages/cpp_api/cpp-api-neighbors-common.md index 98d02dcace..d5bb3550b1 100644 --- a/fern/pages/cpp_api/cpp-api-neighbors-common.md +++ b/fern/pages/cpp_api/cpp-api-neighbors-common.md @@ -14,7 +14,7 @@ _Source header: `cpp/include/cuvs/neighbors/common.hpp`_ The base for approximate KNN index structures. ```cpp -struct index { ... } ; +struct index { ... }; ``` _Source: `cpp/include/cuvs/neighbors/common.hpp:107`_ @@ -25,7 +25,7 @@ _Source: `cpp/include/cuvs/neighbors/common.hpp:107`_ The base for KNN index parameters. ```cpp -struct index_params { ... } ; +struct index_params { ... }; ``` **Fields** @@ -45,7 +45,7 @@ Strategy for merging indices. This enum is declared separately to avoid namespace pollution when including common.hpp. It provides a generic merge strategy that can be used across different index types. ```cpp -enum class MergeStrategy { ... } ; +enum class MergeStrategy { ... }; ``` **Values** @@ -57,6 +57,85 @@ enum class MergeStrategy { ... } ; _Source: `cpp/include/cuvs/neighbors/common.hpp:125`_ +## Types + + +### cuvs::neighbors::dataset + +Two-dimensional dataset; maybe owning, maybe compressed, maybe strided. + +```cpp +template +struct dataset { ... }; +``` + +_Source: `cpp/include/cuvs/neighbors/common.hpp:135`_ + + +### cuvs::neighbors::vpq_dataset + +VPQ compressed dataset. + +The dataset is compressed using two level quantization + +1. Vector Quantization +2. Product Quantization of residuals + +```cpp +template +struct vpq_dataset : public dataset { ... }; +``` + +**Fields** + +| Name | Type | Description | +| --- | --- | --- | +| `vq_code_book` | `raft::device_matrix` | Vector Quantization codebook - "coarse cluster centers". | +| `pq_code_book` | `raft::device_matrix` | Product Quantization codebook - "fine cluster centers". | +| `data` | `raft::device_matrix` | Compressed dataset. | + +_Source: `cpp/include/cuvs/neighbors/common.hpp:406`_ + + +### cuvs::neighbors::ivf::list_base + +Abstract base class for IVF list data. + +This allows polymorphic access to list data regardless of the underlying layout. + +TODO: Make this struct internal (tracking issue: https://github.com/rapidsai/cuvs/issues/1726) + +```cpp +template +struct list_base { ... }; +``` + +_Source: `cpp/include/cuvs/neighbors/common.hpp:719`_ + + +### cuvs::neighbors::ivf::list + +The data for a single IVF list. + +```cpp +template