diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 3e35c05767..328a99e1a4 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -51,6 +51,25 @@ repos:
args: ["-fallback-style=none", "-style=file", "-i"]
- repo: local
hooks:
+ - id: fern-api-reference
+ name: fern-api-reference
+ description: 'Regenerate the Fern API reference pages from the sources'
+ entry: python3 fern/scripts/generate_api_reference.py --quiet
+ language: system
+ pass_filenames: false
+ require_serial: true
+ files: |
+ (?x)
+ ^c/include/.*[.](h|hpp)$|
+ ^cpp/include/.*[.](h|hpp|cuh)$|
+ ^python/cuvs/cuvs/.*[.](py|pyx|pxd)$|
+ ^java/cuvs-java/src/main/.*[.]java$|
+ ^rust/cuvs/src/.*[.]rs$|
+ ^go/.*[.]go$|
+ ^fern/scripts/generate_api_reference[.]py$|
+ ^fern/pages/(c|cpp|python|java|rust|go)_api/.*[.]md$|
+ ^fern/pages/api_reference[.]md$|
+ ^fern/docs[.]yml$
- id: no-deprecationwarning
name: no-deprecationwarning
description: 'Enforce that DeprecationWarning is not introduced (use FutureWarning instead)'
diff --git a/fern/docs.yml b/fern/docs.yml
index 2aafaea69e..9e47025b33 100644
--- a/fern/docs.yml
+++ b/fern/docs.yml
@@ -274,6 +274,8 @@ navigation:
path: "./pages/c_api/c-api-cluster-mg-kmeans.md"
- page: "Core C API"
path: "./pages/c_api/c-api-core-c-api.md"
+ - page: "Core Dataset"
+ path: "./pages/c_api/c-api-core-dataset.md"
- page: "Distance Distance"
path: "./pages/c_api/c-api-distance-distance.md"
- page: "Distance Pairwise Distance"
@@ -329,6 +331,8 @@ navigation:
path: "./pages/cpp_api/cpp-api-cluster-kmeans.md"
- page: "Cluster Spectral"
path: "./pages/cpp_api/cpp-api-cluster-spectral.md"
+ - page: "Core Bloom Filter"
+ path: "./pages/cpp_api/cpp-api-core-bloom-filter.md"
- section: "Common Types"
path: "./pages/cpp_api/cpp-api-common-types.md"
contents:
@@ -410,6 +414,8 @@ navigation:
path: "./pages/cpp_api/cpp-api-util-cutlass-utils.md"
- page: "Util File Io"
path: "./pages/cpp_api/cpp-api-util-file-io.md"
+ - page: "Util Host Memory"
+ path: "./pages/cpp_api/cpp-api-util-host-memory.md"
- section: "Python API Documentation"
path: "./pages/python_api/index.md"
contents:
@@ -462,75 +468,81 @@ navigation:
- section: "Java API Documentation"
path: "./pages/java_api/index.md"
contents:
- - page: "Com Nvidia cuVS Cuvsdevicematrix"
+ - page: "CuVSDeviceMatrix"
path: "./pages/java_api/java-api-com-nvidia-cuvs-cuvsdevicematrix.md"
- - page: "Com Nvidia cuVS Cuvshostmatrix"
+ - page: "CuVSHostMatrix"
path: "./pages/java_api/java-api-com-nvidia-cuvs-cuvshostmatrix.md"
- - page: "Com Nvidia cuVS Cuvsmatrix"
+ - page: "CuVSMatrix"
path: "./pages/java_api/java-api-com-nvidia-cuvs-cuvsmatrix.md"
- - page: "Com Nvidia cuVS Spi Cuvsprovider"
+ - page: "CuVSProvider"
path: "./pages/java_api/java-api-com-nvidia-cuvs-spi-cuvsprovider.md"
- - page: "Com Nvidia cuVS Cuvsresources"
+ - page: "CuVSResources"
path: "./pages/java_api/java-api-com-nvidia-cuvs-cuvsresources.md"
- - page: "Com Nvidia cuVS Cuvsresourcesinfo"
+ - page: "CuVSResourcesInfo"
path: "./pages/java_api/java-api-com-nvidia-cuvs-cuvsresourcesinfo.md"
- - page: "Com Nvidia cuVS Spi Cuvsserviceprovider"
+ - page: "CuVSServiceProvider"
path: "./pages/java_api/java-api-com-nvidia-cuvs-spi-cuvsserviceprovider.md"
- - page: "Com Nvidia cuVS Delegatingscopedaccess"
+ - page: "DelegatingScopedAccess"
path: "./pages/java_api/java-api-com-nvidia-cuvs-delegatingscopedaccess.md"
- - page: "Com Nvidia cuVS Gpuinfo"
+ - page: "FilterBitsetHandle"
+ path: "./pages/java_api/java-api-com-nvidia-cuvs-filterbitsethandle.md"
+ - page: "GPUInfo"
path: "./pages/java_api/java-api-com-nvidia-cuvs-gpuinfo.md"
- - page: "Com Nvidia cuVS Gpuinfoprovider"
+ - page: "GPUInfoProvider"
path: "./pages/java_api/java-api-com-nvidia-cuvs-gpuinfoprovider.md"
- - page: "Com Nvidia cuVS Libraryexception"
+ - page: "LibraryException"
path: "./pages/java_api/java-api-com-nvidia-cuvs-libraryexception.md"
- - page: "Com Nvidia cuVS Rowview"
+ - page: "RowView"
path: "./pages/java_api/java-api-com-nvidia-cuvs-rowview.md"
- - page: "Com Nvidia cuVS Synchronizedcuvsresources"
+ - page: "SynchronizedCuVSResources"
path: "./pages/java_api/java-api-com-nvidia-cuvs-synchronizedcuvsresources.md"
- - page: "Com Nvidia cuVS Bruteforceindex"
+ - page: "BruteForceIndex"
path: "./pages/java_api/java-api-com-nvidia-cuvs-bruteforceindex.md"
- - page: "Com Nvidia cuVS Bruteforceindexparams"
+ - page: "BruteForceIndexParams"
path: "./pages/java_api/java-api-com-nvidia-cuvs-bruteforceindexparams.md"
- - page: "Com Nvidia cuVS Bruteforcequery"
+ - page: "BruteForceQuery"
path: "./pages/java_api/java-api-com-nvidia-cuvs-bruteforcequery.md"
- - page: "Com Nvidia cuVS Cagracompressionparams"
+ - page: "CagraCompressionParams"
path: "./pages/java_api/java-api-com-nvidia-cuvs-cagracompressionparams.md"
- - page: "Com Nvidia cuVS Cagraindex"
+ - page: "CagraIndex"
path: "./pages/java_api/java-api-com-nvidia-cuvs-cagraindex.md"
- - page: "Com Nvidia cuVS Cagraindexparams"
+ - page: "CagraIndexParams"
path: "./pages/java_api/java-api-com-nvidia-cuvs-cagraindexparams.md"
- - page: "Com Nvidia cuVS Cagramergeparams"
+ - page: "CagraMergeParams"
path: "./pages/java_api/java-api-com-nvidia-cuvs-cagramergeparams.md"
- - page: "Com Nvidia cuVS Cagraquery"
+ - page: "CagraQuery"
path: "./pages/java_api/java-api-com-nvidia-cuvs-cagraquery.md"
- - page: "Com Nvidia cuVS Cagrasearchparams"
+ - page: "CagraSearchParams"
path: "./pages/java_api/java-api-com-nvidia-cuvs-cagrasearchparams.md"
- - page: "Com Nvidia cuVS Cuvsaceparams"
+ - page: "CuVSAceParams"
path: "./pages/java_api/java-api-com-nvidia-cuvs-cuvsaceparams.md"
- - page: "Com Nvidia cuVS Cuvsivfpqindexparams"
+ - page: "CuVSIvfPqIndexParams"
path: "./pages/java_api/java-api-com-nvidia-cuvs-cuvsivfpqindexparams.md"
- - page: "Com Nvidia cuVS Cuvsivfpqparams"
+ - page: "CuVSIvfPqParams"
path: "./pages/java_api/java-api-com-nvidia-cuvs-cuvsivfpqparams.md"
- - page: "Com Nvidia cuVS Cuvsivfpqsearchparams"
+ - page: "CuVSIvfPqSearchParams"
path: "./pages/java_api/java-api-com-nvidia-cuvs-cuvsivfpqsearchparams.md"
- - page: "Com Nvidia cuVS Hnswaceparams"
+ - page: "HnswAceParams"
path: "./pages/java_api/java-api-com-nvidia-cuvs-hnswaceparams.md"
- - page: "Com Nvidia cuVS Hnswindex"
+ - page: "HnswIndex"
path: "./pages/java_api/java-api-com-nvidia-cuvs-hnswindex.md"
- - page: "Com Nvidia cuVS Hnswindexparams"
+ - page: "HnswIndexParams"
path: "./pages/java_api/java-api-com-nvidia-cuvs-hnswindexparams.md"
- - page: "Com Nvidia cuVS Hnswquery"
+ - page: "HnswQuery"
path: "./pages/java_api/java-api-com-nvidia-cuvs-hnswquery.md"
- - page: "Com Nvidia cuVS Hnswsearchparams"
+ - page: "HnswSearchParams"
path: "./pages/java_api/java-api-com-nvidia-cuvs-hnswsearchparams.md"
- - page: "Com Nvidia cuVS Searchresults"
+ - page: "MultiPartitionCagraSearch"
+ path: "./pages/java_api/java-api-com-nvidia-cuvs-multipartitioncagrasearch.md"
+ - page: "MultiPartitionSearchResults"
+ path: "./pages/java_api/java-api-com-nvidia-cuvs-multipartitionsearchresults.md"
+ - page: "SearchResults"
path: "./pages/java_api/java-api-com-nvidia-cuvs-searchresults.md"
- - page: "Com Nvidia cuVS Tieredindex"
+ - page: "TieredIndex"
path: "./pages/java_api/java-api-com-nvidia-cuvs-tieredindex.md"
- - page: "Com Nvidia cuVS Tieredindexparams"
+ - page: "TieredIndexParams"
path: "./pages/java_api/java-api-com-nvidia-cuvs-tieredindexparams.md"
- - page: "Com Nvidia cuVS Tieredindexquery"
+ - page: "TieredIndexQuery"
path: "./pages/java_api/java-api-com-nvidia-cuvs-tieredindexquery.md"
- section: "Rust API Documentation"
path: "./pages/rust_api/index.md"
@@ -543,6 +555,8 @@ navigation:
path: "./pages/rust_api/rust-api-cuvs-cluster-kmeans-params.md"
- page: "cuVS"
path: "./pages/rust_api/rust-api-cuvs.md"
+ - page: "cuVS Dataset"
+ path: "./pages/rust_api/rust-api-cuvs-dataset.md"
- page: "cuVS Dlpack"
path: "./pages/rust_api/rust-api-cuvs-dlpack.md"
- page: "cuVS Error"
@@ -553,6 +567,8 @@ navigation:
path: "./pages/rust_api/rust-api-cuvs-neighbors-filters.md"
- page: "cuVS Resources"
path: "./pages/rust_api/rust-api-cuvs-resources.md"
+ - page: "cuVS Version"
+ path: "./pages/rust_api/rust-api-cuvs-version.md"
- page: "cuVS Distance"
path: "./pages/rust_api/rust-api-cuvs-distance.md"
- page: "cuVS Neighbors Brute Force"
diff --git a/fern/pages/c_api/c-api-cluster-kmeans.md b/fern/pages/c_api/c-api-cluster-kmeans.md
index d2eb3efbcd..d715413db0 100644
--- a/fern/pages/c_api/c-api-cluster-kmeans.md
+++ b/fern/pages/c_api/c-api-cluster-kmeans.md
@@ -146,7 +146,7 @@ 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->device_buffer_samples.
+X may reside on either host (CPU) or device (GPU) memory. When X is on the host the data is buffered to the GPU in batches controlled by params->device_buffer_samples.
**Parameters**
diff --git a/fern/pages/c_api/c-api-cluster-mg-kmeans.md b/fern/pages/c_api/c-api-cluster-mg-kmeans.md
index cfd3d4dd90..5305541d6f 100644
--- a/fern/pages/c_api/c-api-cluster-mg-kmeans.md
+++ b/fern/pages/c_api/c-api-cluster-mg-kmeans.md
@@ -14,7 +14,7 @@ _Source header: `cuvs/cluster/mg_kmeans.h`_
Find clusters with single-node multi-GPU k-means using host data.
```c
-CUVS_EXPORT cuvsError_t cuvsMultiGpuKMeansFit(cuvsResources_t res,
+cuvsError_t cuvsMultiGpuKMeansFit(cuvsResources_t res,
cuvsKMeansParams_t params,
DLManagedTensor* X,
DLManagedTensor* sample_weight,
@@ -39,4 +39,4 @@ X, sample_weight, and centroids must be host-accessible, row-major, C-contiguous
**Returns**
-[`CUVS_EXPORT cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t)
+[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t)
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 14a14ce46b..df84ff2435 100644
--- a/fern/pages/c_api/c-api-core-c-api.md
+++ b/fern/pages/c_api/c-api-core-c-api.md
@@ -152,6 +152,31 @@ cuvsError_t cuvsResourcesCreate(cuvsResources_t* res);
[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t)
+
+### cuvsResourcesCreateWithMemoryTracking
+
+Create an opaque C handle for C++ type `raft::resources` whose memory allocations are tracked and written as CSV samples from a background thread.
+
+```c
+cuvsError_t cuvsResourcesCreateWithMemoryTracking(cuvsResources_t* res,
+const char* csv_path,
+int64_t sample_interval_ms);
+```
+
+The returned handle wraps all reachable memory resources (host, pinned, managed, device, workspace, large_workspace) with allocation-tracking adaptors and replaces the global host and device memory resources for the lifetime of the handle. It is otherwise indistinguishable from a handle created by ::cuvsResourcesCreate and can be used wherever a :cuvsResources_t is accepted. The CSV reporter is stopped and the global memory resources are restored when the handle is destroyed via :cuvsResourcesDestroy.
+
+**Parameters**
+
+| Name | Direction | Type | Description |
+| --- | --- | --- | --- |
+| `res` | out | [`cuvsResources_t*`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle |
+| `csv_path` | in | `const char*` | Path to the output CSV file (created/truncated). Must be a non-empty, null-terminated UTF-8 string. |
+| `sample_interval_ms` | in | `int64_t` | Minimum time in milliseconds between successive CSV samples. Pass 10 to match the C++ default. |
+
+**Returns**
+
+[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t)
+
### cuvsResourcesDestroy
@@ -250,6 +275,27 @@ cuvsError_t cuvsDeviceIdGet(cuvsResources_t res, int* device_id);
[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t)
+
+### cuvsResourcesSetWorkspacePool
+
+Configure the temporary workspace on this resources object as an uncapped pool, backed by the current device memory resource. After the initial reservation is allocated on first use, subsequent calls to cuvsRMMAlloc / cuvsRMMFree on the same resources handle hit the pool cache rather than calling cudaMallocAsync / cudaFreeAsync, reducing CUDA context lock contention under concurrent query threads. The pool grows without shrinking: freed allocations are returned to the pool rather than to the device, so the pool's high-water mark only increases until the resources object is destroyed.
+
+```c
+cuvsError_t cuvsResourcesSetWorkspacePool(cuvsResources_t res,
+size_t initial_size_bytes);
+```
+
+**Parameters**
+
+| Name | Direction | Type | Description |
+| --- | --- | --- | --- |
+| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle |
+| `initial_size_bytes` | in | `size_t` | initial pool reservation in bytes; size to cover the steady-state working set to avoid growth after warmup |
+
+**Returns**
+
+[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t)
+
### cuvsMultiGpuResourcesCreate
@@ -396,6 +442,19 @@ bool managed);
[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t)
+
+### cuvsRMMAsyncMemoryResourceEnable
+
+Switches the working memory resource to use stream-ordered asynchronous allocation (cudaMallocAsync / cudaFreeAsync). Unlike the pool resource, this resource returns memory to the stream immediately without blocking the CPU, eliminating device-wide synchronization on deallocation. This is especially beneficial when multiple CAGRA searches run concurrently on separate CUDA streams, because the internal workspace allocations no longer serialize kernel launches. 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.
+
+```c
+cuvsError_t cuvsRMMAsyncMemoryResourceEnable();
+```
+
+**Returns**
+
+[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t)
+
### cuvsRMMMemoryResourceReset
diff --git a/fern/pages/c_api/c-api-core-dataset.md b/fern/pages/c_api/c-api-core-dataset.md
new file mode 100644
index 0000000000..1ea26bdaa5
--- /dev/null
+++ b/fern/pages/c_api/c-api-core-dataset.md
@@ -0,0 +1,74 @@
+---
+slug: api-reference/c-api-core-dataset
+---
+
+# Dataset
+
+_Source header: `cuvs/core/dataset.h`_
+
+## Types
+
+
+### cuvsDatasetLayout_t
+
+Generic dataset layout kind for C API dataset handles.
+
+```c
+typedef enum {
+ CUVS_DATASET_LAYOUT_STANDARD = 0,
+ CUVS_DATASET_LAYOUT_PADDED = 1
+} cuvsDatasetLayout_t;
+```
+
+**Values**
+
+| Name | Value |
+| --- | --- |
+| `CUVS_DATASET_LAYOUT_STANDARD` | `0` |
+| `CUVS_DATASET_LAYOUT_PADDED` | `1` |
+
+
+### cuvsDatasetMemType_t
+
+Memory space holding a C API dataset handle's data.
+
+```c
+typedef enum {
+ CUVS_DATASET_MEM_TYPE_HOST = 0,
+ CUVS_DATASET_MEM_TYPE_DEVICE = 1
+} cuvsDatasetMemType_t;
+```
+
+**Values**
+
+| Name | Value |
+| --- | --- |
+| `CUVS_DATASET_MEM_TYPE_HOST` | `0` |
+| `CUVS_DATASET_MEM_TYPE_DEVICE` | `1` |
+
+
+### destroy_addr
+
+Dataset handle representing owning storage or a non-owning view.
+
+`addr` points to C++ dataset storage or view metadata managed by the C API. `mem_type` identifies the memory space, `layout` identifies the data layout, and `is_owning` indicates whether the handle owns its backing data.
+
+```c
+typedef struct {
+ uintptr_t addr;
+ DLDataType dtype;
+ cuvsDatasetMemType_t mem_type;
+ cuvsDatasetLayout_t layout;
+ bool is_owning;
+} cuvsDataset;
+```
+
+**Fields**
+
+| Name | Type | Description |
+| --- | --- | --- |
+| `addr` | `uintptr_t` | |
+| `dtype` | `DLDataType` | |
+| `mem_type` | [`cuvsDatasetMemType_t`](/api-reference/c-api-core-dataset#cuvsdatasetmemtype-t) | |
+| `layout` | [`cuvsDatasetLayout_t`](/api-reference/c-api-core-dataset#cuvsdatasetlayout-t) | |
+| `is_owning` | `bool` | |
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 9c15676edf..b7dc390e08 100644
--- a/fern/pages/c_api/c-api-neighbors-all-neighbors.md
+++ b/fern/pages/c_api/c-api-neighbors-all-neighbors.md
@@ -111,7 +111,9 @@ DLManagedTensor* core_distances,
float alpha);
```
-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.
+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.
+
+Output memory space: a host dataset supports host- or device-resident outputs; a device dataset requires device-resident outputs. All provided outputs must share the same memory space.
**Parameters**
@@ -120,9 +122,9 @@ The function automatically detects whether the dataset is host-resident or devic
| `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 resources |
| `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 |
-| `core_distances` | out | `DLManagedTensor*` | Optional 1D tensor [num_rows] on device (float32); can be NULL |
+| `indices` | out | `DLManagedTensor*` | 2D tensor [num_rows x k] (int64), host or device |
+| `distances` | out | `DLManagedTensor*` | Optional 2D tensor [num_rows x k] (float32), host or device; can be NULL |
+| `core_distances` | out | `DLManagedTensor*` | Optional 1D tensor [num_rows] (float32), host or device; can be NULL |
| `alpha` | in | `float` | Mutual-reachability scaling; used only when core_distances is provided |
**Returns**
diff --git a/fern/pages/c_api/c-api-neighbors-cagra.md b/fern/pages/c_api/c-api-neighbors-cagra.md
index d77cff2312..7af4269b6d 100644
--- a/fern/pages/c_api/c-api-neighbors-cagra.md
+++ b/fern/pages/c_api/c-api-neighbors-cagra.md
@@ -93,7 +93,7 @@ struct cuvsAceParams {
| --- | --- | --- |
| `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. |
+| `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. The directory may already exist, but ACE's named artifacts must not already exist. Simultaneous builds must use different directories. On failure, ACE removes only artifacts it created and never deletes unrelated directory contents. |
| `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. |
@@ -110,7 +110,6 @@ struct cuvsCagraIndexParams {
size_t graph_degree;
enum cuvsCagraGraphBuildAlgo build_algo;
size_t nn_descent_niter;
- cuvsCagraCompressionParams_t compression;
void* graph_build_params;
};
```
@@ -124,9 +123,58 @@ struct cuvsCagraIndexParams {
| `graph_degree` | `size_t` | Degree of output 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`](/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 |
+
+### cuvsCagraMergeAlgo
+
+Algorithm used to merge physical CAGRA indices.
+
+```c
+enum cuvsCagraMergeAlgo {
+ CUVS_CAGRA_MERGE_AUTO = 0,
+ CUVS_CAGRA_MERGE_FASTENER = 1,
+ CUVS_CAGRA_MERGE_REBUILD = 2
+};
+```
+
+**Values**
+
+| Name | Value |
+| --- | --- |
+| `CUVS_CAGRA_MERGE_AUTO` | `0` |
+| `CUVS_CAGRA_MERGE_FASTENER` | `1` |
+| `CUVS_CAGRA_MERGE_REBUILD` | `2` |
+
+
+### cuvsCagraMergeParams
+
+Parameters controlling how physical CAGRA indices are merged.
+
+```c
+struct cuvsCagraMergeParams {
+ uint32_t levels;
+ uint32_t root_fanout;
+ uint32_t lower_fanout;
+ double leader_fraction;
+ uint32_t max_leaders;
+ uint32_t leaf_size;
+ uint32_t leaf_degree;
+};
+```
+
+**Fields**
+
+| Name | Type | Description |
+| --- | --- | --- |
+| `levels` | `uint32_t` | |
+| `root_fanout` | `uint32_t` | |
+| `lower_fanout` | `uint32_t` | |
+| `leader_fraction` | `double` | |
+| `max_leaders` | `uint32_t` | |
+| `leaf_size` | `uint32_t` | |
+| `leaf_degree` | `uint32_t` | |
+
### cuvsCagraIndexParamsCreate
@@ -165,6 +213,44 @@ cuvsError_t cuvsCagraIndexParamsDestroy(cuvsCagraIndexParams_t params);
[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t)
+
+### cuvsCagraMergeParamsCreate
+
+Allocate CAGRA merge params and populate them with AUTO defaults.
+
+```c
+cuvsError_t cuvsCagraMergeParamsCreate(cuvsCagraMergeParams_t* params);
+```
+
+**Parameters**
+
+| Name | Direction | Type | Description |
+| --- | --- | --- | --- |
+| `params` | | [`cuvsCagraMergeParams_t*`](/api-reference/c-api-neighbors-cagra#cuvscagramergeparams) | |
+
+**Returns**
+
+[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t)
+
+
+### cuvsCagraMergeParamsDestroy
+
+De-allocate CAGRA merge params.
+
+```c
+cuvsError_t cuvsCagraMergeParamsDestroy(cuvsCagraMergeParams_t params);
+```
+
+**Parameters**
+
+| Name | Direction | Type | Description |
+| --- | --- | --- | --- |
+| `params` | | [`cuvsCagraMergeParams_t`](/api-reference/c-api-neighbors-cagra#cuvscagramergeparams) | |
+
+**Returns**
+
+[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t)
+
### cuvsCagraCompressionParamsCreate
@@ -274,6 +360,37 @@ This factory function creates CAGRA parameters that yield a graph compatible wit
[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t)
+
+### cuvsCagraIndexParamsFromDataset
+
+Create CAGRA index parameters heuristically tuned for a dataset
+
+```c
+cuvsError_t cuvsCagraIndexParamsFromDataset(cuvsCagraIndexParams_t params,
+int64_t n_rows,
+int64_t dim,
+size_t graph_degree,
+cuvsDistanceType metric,
+size_t build_quality);
+```
+
+This factory function selects the graph build algorithm and its parameters based on the shape of the dataset.
+
+**Parameters**
+
+| Name | Direction | Type | Description |
+| --- | --- | --- | --- |
+| `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 |
+| `graph_degree` | in | `size_t` | Degree of the output graph |
+| `metric` | in | [`cuvsDistanceType`](/api-reference/c-api-distance-distance#cuvsdistancetype) | Distance metric to use |
+| `build_quality` | in | `size_t` | Higher values increase build quality (and cost) up to a point |
+
+**Returns**
+
+[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t)
+
## C API for CUDA ANN Graph-based nearest neighbor search
@@ -334,19 +451,7 @@ cuvsError_t cuvsCagraExtendParamsDestroy(cuvsCagraExtendParams_t params);
### cuvsCagraExtend
-Extend a CAGRA index using a caller-owned pre-concatenated device-padded
-dataset view. The caller must build `extended_dataset` as `old || new`
-before calling. Rows `[0, new_start_row)` are the original vectors; rows
-`[new_start_row, n_rows)` are the additional vectors. `new_start_row`
-must equal the current index size. The library only extends the graph
-and rebinds the index to `extended_dataset`.
-
-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`
+Extend a CAGRA index with a caller-owned pre-concatenated padded dataset.
```c
cuvsError_t cuvsCagraExtend(cuvsResources_t res,
@@ -356,14 +461,16 @@ int64_t new_start_row,
cuvsCagraIndex_t index);
```
+The caller must build `extended_dataset` as `old \|\| new` (size `n_old + n_new`) before calling. Rows `[0, new_start_row)` are the original vectors; rows `[new_start_row, n_rows)` are the additional vectors. `new_start_row` must equal the current index size. The library only extends the graph and rebinds the index to `extended_dataset`; keep that dataset alive for the index lifetime.
+
**Parameters**
| Name | Direction | Type | Description |
| --- | --- | --- | --- |
| `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 |
-| `extended_dataset` | in | `cuvsDataset_t` | Caller-owned device-padded dataset already containing old \|\| new |
-| `new_start_row` | in | `int64_t` | Row index where the additional vectors begin |
+| `extended_dataset` | in | `cuvsDataset_t` | cuvsDataset_t caller-owned device-padded dataset of old \|\| new |
+| `new_start_row` | in | `int64_t` | row index where the additional vectors begin |
| `index` | in,out | [`cuvsCagraIndex_t`](/api-reference/c-api-neighbors-cagra#cuvscagraindex) | cuvsCagraIndex_t CAGRA index |
**Returns**
@@ -506,10 +613,12 @@ cuvsError_t cuvsCagraSearchParamsDestroy(cuvsCagraSearchParams_t params);
### cuvsCagraIndex
-Struct to hold address of cuvs::neighbors::cagra::index and its active trained dtype
+Struct holding the CAGRA index storage address and vector element dtype (DLPack-style)
+
+Matches the usual cuVS C index pattern (`addr` + `dtype`). `addr` points at implementation-owned storage (not always a bare `cagra::index*`); free only via `cuvsCagraIndexDestroy`. `dtype` describes index vector elements for queries and template dispatch.
```c
-typedef struct {
+typedef struct cuvsCagraIndex {
uintptr_t addr;
DLDataType dtype;
} cuvsCagraIndex;
@@ -668,21 +777,43 @@ Note that the DLManagedTensor graph returned will have an associated 'deleter' f
[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t)
+
+### cuvsCagraUpdateDataset
+
+Update a CAGRA index with a device-padded dataset.
+
+```c
+cuvsError_t cuvsCagraUpdateDataset(cuvsResources_t res,
+cuvsDataset_t device_padded_dataset,
+cuvsCagraIndex_t index);
+```
+
+This is the centralized dataset update operation for C callers. If `index` is already device-padded, its dataset view is replaced in place. Otherwise, the index is converted and its opaque handle is rebound to a search-ready device-padded index. Caller retains ownership of
+
+**Parameters**
+
+| Name | Direction | Type | Description |
+| --- | --- | --- | --- |
+| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle |
+| `device_padded_dataset` | in | `cuvsDataset_t` | owning or non-owning device-padded dataset handle |
+| `index` | inout | [`cuvsCagraIndex_t`](/api-reference/c-api-neighbors-cagra#cuvscagraindex) | CAGRA index handle |
+
+**Returns**
+
+[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t)
+
## C API for CUDA ANN Graph-based nearest neighbor search
### cuvsCagraBuild
-Build a CAGRA index from a dataset view handle. Acceptable underlying types are:
+Build a CAGRA index from a dataset handle. 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`
-The memory space and layout `dataset` was constructed with select the C++ build overload. Build the
-handle with the matching type-specific view factory; memory residency is inferred from the tensor.
-
```c
cuvsError_t cuvsCagraBuild(cuvsResources_t res,
cuvsCagraIndexParams_t params,
@@ -690,13 +821,17 @@ cuvsDataset_t dataset,
cuvsCagraIndex_t index);
```
+The memory space and layout `dataset` was constructed with select the C++ build overload. Build the handle with an owning factory or the matching dataset view factory (`cuvsDatasetMakePaddedView` / `cuvsDatasetMakeStandardView`).
+
+Note that a dataset residing in host memory produces a host-backed index, which must be made search-ready with `cuvsCagraUpdateDataset` (using a device-padded dataset) before calling `cuvsCagraSearch`.
+
**Parameters**
| Name | Direction | Type | Description |
| --- | --- | --- | --- |
| `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 | `cuvsDataset_t` | Training dataset or dataset view |
+| `dataset` | in | `cuvsDataset_t` | cuvsDataset_t training dataset or dataset view |
| `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**
@@ -740,6 +875,45 @@ cuvsFilter filter);
[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t)
+
+### cuvsCagraSearchMultiPartition
+
+Search multiple CAGRA index partitions concurrently and return the global top-k per query.
+
+```c
+cuvsError_t cuvsCagraSearchMultiPartition(cuvsResources_t res,
+cuvsCagraSearchParams_t params,
+uint32_t num_partitions,
+cuvsCagraIndex_t* indices,
+DLManagedTensor* queries,
+DLManagedTensor* partition_ids,
+DLManagedTensor* neighbors,
+DLManagedTensor* distances,
+cuvsFilter* filters);
+```
+
+For each query row, the function searches all partitions in parallel into an internal intermediate buffer, applies per-partition distance post-processing, runs a batched top-k merge across partitions, and writes the final outputs to the caller-supplied device tensors. All work is submitted to the CUDA stream associated with `res`; use `cuvsStreamSync` to wait for completion.
+
+The index element type may be float32, float16, int8, or uint8. All partitions must share the same element type, and the queries must use that same type.
+
+**Parameters**
+
+| Name | Direction | Type | Description |
+| --- | --- | --- | --- |
+| `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) | search parameters (shared across partitions) |
+| `num_partitions` | in | `uint32_t` | number of index partitions |
+| `indices` | in | [`cuvsCagraIndex_t*`](/api-reference/c-api-neighbors-cagra#cuvscagraindex) | array of num_partitions cuvsCagraIndex_t pointers, all of the same element type |
+| `queries` | in | `DLManagedTensor*` | DLManagedTensor* (device, same dtype as the indices, [n_queries, dim]); the queries matrix is searched against every partition |
+| `partition_ids` | out | `DLManagedTensor*` | DLManagedTensor* (device, uint32, [n_queries, k]); which partition each returned neighbor came from |
+| `neighbors` | out | `DLManagedTensor*` | DLManagedTensor* (device, uint32 or int64, [n_queries, k]); ordinal in the corresponding partition's dataset |
+| `distances` | out | `DLManagedTensor*` | DLManagedTensor* (device, float32, [n_queries, k]); post-processed distance for each (query, neighbor) |
+| `filters` | in | [`cuvsFilter*`](/api-reference/c-api-neighbors-common#cuvsfilter) | array of `num_partitions` filters, one per partition (or NULL for a fully unfiltered search). `filters[i]` applies to partition `i`: use \{.type=NO_FILTER, .addr=0\} for no filter on that partition, or \{.type=BITSET, .addr=ptr\} where ptr is a uintptr_t-cast DLManagedTensor* holding that partition's own bitset (one bit per vector in that partition; standard 32-bit packing). |
+
+**Returns**
+
+[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t)
+
## CAGRA C-API serialize functions
@@ -770,7 +944,7 @@ Experimental, both the API and the serialization format are subject to change.
### cuvsCagraSerializeGraphAndDataset
-Save the CAGRA graph and its attached host or device dataset to file. Returns an error without modifying the destination file if no dataset is attached.
+Save the CAGRA graph and its attached dataset to file.
```c
cuvsError_t cuvsCagraSerializeGraphAndDataset(cuvsResources_t res,
@@ -778,13 +952,17 @@ const char* filename,
cuvsCagraIndex_t index);
```
+The index stores a non-owning dataset view. The caller must keep the dataset backing that view alive while this function runs. Returns CUVS_ERROR without modifying the destination file if the index has no attached dataset.
+
+Experimental, both the API and the serialization format are subject to change.
+
**Parameters**
| Name | Direction | Type | Description |
| --- | --- | --- | --- |
| `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 graph and dataset |
-| `index` | in | [`cuvsCagraIndex_t`](/api-reference/c-api-neighbors-cagra#cuvscagraindex) | CAGRA index with an attached dataset |
+| `index` | in | [`cuvsCagraIndex_t`](/api-reference/c-api-neighbors-cagra#cuvscagraindex) | CAGRA index with an attached host or device dataset |
**Returns**
@@ -820,19 +998,25 @@ Experimental, both the API and the serialization format are subject to change.
### cuvsCagraDeserializeGraph
-Load the graph from either serialized file form without retaining its dataset.
+Load the CAGRA graph from file without retaining a serialized dataset.
```c
-cuvsError_t cuvsCagraDeserializeGraph(cuvsResources_t res, const char* filename, cuvsCagraIndex_t index);
+cuvsError_t cuvsCagraDeserializeGraph(cuvsResources_t res,
+const char* filename,
+cuvsCagraIndex_t index);
```
+This succeeds whether or not the file contains a dataset. Use cuvsCagraUpdateDataset to attach a caller-owned device-padded dataset view before searching the graph-only index.
+
+Experimental, both the API and the serialization format are subject to change.
+
**Parameters**
| Name | Direction | Type | Description |
| --- | --- | --- | --- |
| `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`](/api-reference/c-api-neighbors-cagra#cuvscagraindex) | Pre-created CAGRA index populated on success and unchanged on failure |
+| `index` | inout | [`cuvsCagraIndex_t`](/api-reference/c-api-neighbors-cagra#cuvscagraindex) | pre-created CAGRA index populated on success and unchanged on failure |
**Returns**
@@ -841,11 +1025,7 @@ cuvsError_t cuvsCagraDeserializeGraph(cuvsResources_t res, const char* filename,
### cuvsCagraDeserializeGraphAndDataset
-Load the graph and dataset. The function allocates an owning dataset that preserves the
-serialized host/device memory type and standard/padded layout. The caller must keep it alive while
-the index uses its non-owning view and destroy it separately. Only a device-padded result is
-immediately searchable through the C API; attach a caller-owned device-padded view with
-`cuvsCagraUpdateDataset` for any other kind.
+Load the CAGRA graph and dataset from file.
```c
cuvsError_t cuvsCagraDeserializeGraphAndDataset(cuvsResources_t res,
@@ -854,7 +1034,9 @@ cuvsCagraIndex_t index,
cuvsDataset_t* out_dataset);
```
-Returns an error when the file has no dataset or the output pointer does not point to a null handle. The index and output remain unchanged on failure.
+The returned owning dataset preserves the serialized host/device memory type and standard/padded layout. The index stores a non-owning view into it, so the caller must keep the dataset alive while the index uses it and destroy it separately with cuvsDatasetDestroy. Only a device-padded result is immediately searchable through the C API; attach a caller-owned device-padded view with cuvsCagraUpdateDataset for any other kind. The output pointer must point to a null handle on entry; deserialization acts as a factory and transfers ownership of the allocated dataset handle on success. Returns CUVS_ERROR when the file has no dataset; the index and output handle are unchanged on failure.
+
+Experimental, both the API and the serialization format are subject to change.
**Parameters**
@@ -862,8 +1044,8 @@ Returns an error when the file has no dataset or the output pointer does not poi
| --- | --- | --- | --- |
| `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 graph and dataset |
-| `index` | inout | [`cuvsCagraIndex_t`](/api-reference/c-api-neighbors-cagra#cuvscagraindex) | Pre-created CAGRA index populated on success and unchanged on failure |
-| `out_dataset` | out | [`cuvsDataset_t`](/api-reference/c-api-core-dataset#cuvsdataset-t) | Receives the allocated owning dataset handle; must point to null on entry |
+| `index` | inout | [`cuvsCagraIndex_t`](/api-reference/c-api-neighbors-cagra#cuvscagraindex) | pre-created CAGRA index populated on success and unchanged on failure |
+| `out_dataset` | out | `cuvsDataset_t*` | receives the allocated owning dataset handle; must point to null on entry |
**Returns**
@@ -913,7 +1095,7 @@ cuvsDataset_t merged_dataset,
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`.
+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`. The merge algorithm is selected automatically.
Input indices must have:
@@ -929,13 +1111,46 @@ Example:
| Name | Direction | Type | Description |
| --- | --- | --- | --- |
| `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 |
+| `params` | in | [`cuvsCagraIndexParams_t`](/api-reference/c-api-neighbors-cagra#cuvscagraindexparams) | cuvsCagraIndexParams_t parameters for the output index |
| `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`](/api-reference/c-api-neighbors-common#cuvsfilter) | Filter that can be used to filter out vectors from the merged index |
-| `merged_dataset` | out | `cuvsDataset_t` | Empty owning dataset handle. Merge allocates and populates its device storage using the input index layout. Keep it alive while using the output index. |
+| `merged_dataset` | out | `cuvsDataset_t` | Empty owning dataset handle. Merge first attempts to allocate and populate device storage with the same layout as the input indices. For an unfiltered merge, if device allocation fails, it falls back to host storage and returns a host-backed output index. Keep this dataset alive while using `output_index`. A host-backed output index must be updated with `cuvsCagraUpdateDataset` before device search. |
| `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`](/api-reference/c-api-core-c-api#cuvserror-t)
+
+
+### cuvsCagraMergeWithParams
+
+Merge multiple CAGRA indices with explicit merge parameters.
+
+```c
+cuvsError_t cuvsCagraMergeWithParams(cuvsResources_t res,
+cuvsCagraIndexParams_t params,
+cuvsCagraMergeParams_t merge_params,
+cuvsCagraIndex_t* indices,
+size_t num_indices,
+cuvsFilter filter,
+cuvsDataset_t merged_dataset,
+cuvsCagraIndex_t output_index);
+```
+
+**Parameters**
+
+| Name | Direction | Type | Description |
+| --- | --- | --- | --- |
+| `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 for the output index |
+| `merge_params` | in | [`cuvsCagraMergeParams_t`](/api-reference/c-api-neighbors-cagra#cuvscagramergeparams) | cuvsCagraMergeParams_t parameters controlling the merge algorithm, or NULL to use AUTO defaults |
+| `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`](/api-reference/c-api-neighbors-common#cuvsfilter) | Filter that can be used to filter out vectors from the merged index |
+| `merged_dataset` | out | `cuvsDataset_t` | Empty owning dataset handle. Merge first attempts to allocate and populate device storage with the same layout as the input indices. For an unfiltered merge, AUTO and REBUILD can fall back to host storage if device allocation fails; explicit FASTENER reports the allocation failure instead. Keep this dataset alive while using `output_index`. A host-backed output index must be updated with `cuvsCagraUpdateDataset` before device search. |
+| `output_index` | out | [`cuvsCagraIndex_t`](/api-reference/c-api-neighbors-cagra#cuvscagraindex) | Output handle initialized with `cuvsCagraIndexCreate` |
+
+**Returns**
+
+[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t)
diff --git a/fern/pages/c_api/c-api-neighbors-common.md b/fern/pages/c_api/c-api-neighbors-common.md
index 3c679f6946..53483246ff 100644
--- a/fern/pages/c_api/c-api-neighbors-common.md
+++ b/fern/pages/c_api/c-api-neighbors-common.md
@@ -34,6 +34,8 @@ enum cuvsFilterType {
Struct to hold address of cuvs::neighbors::prefilter and its type
+`addr` points to a filter object owned by the caller; the library performs no caching of the underlying bitset across search calls. Allocating and populating the device bitset may be more expensive than a single filtered search, so callers that issue repeated searches against the same filter (e.g. many queries over one index) should build the bitset once and reuse the same cuvsFilter across those calls rather than rebuild it per search. Reusing the bitset is essential for realizing the full throughput of filtered search.
+
```c
typedef struct {
uintptr_t addr;
diff --git a/fern/pages/c_api/c-api-neighbors-hnsw.md b/fern/pages/c_api/c-api-neighbors-hnsw.md
index 497fe89584..4d46dbfa0e 100644
--- a/fern/pages/c_api/c-api-neighbors-hnsw.md
+++ b/fern/pages/c_api/c-api-neighbors-hnsw.md
@@ -55,7 +55,7 @@ struct cuvsHnswAceParams {
| Name | Type | Description |
| --- | --- | --- |
| `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. |
+| `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. The directory may already exist, but ACE's named artifacts and `hnsw_index.bin` must not already exist. Simultaneous builds must use different directories. On failure, ACE removes only its uncommitted CAGRA artifacts; a completed CAGRA stage is retained if creating the HNSW index fails. |
| `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. |
@@ -296,8 +296,7 @@ DLManagedTensor* dataset,
cuvsHnswIndex_t index);
```
-The graph is built on the GPU and converted to an HNSW index that can be searched on the CPU.
-The graph build algorithm is selected automatically unless explicit ACE parameters are provided.
+The graph is built on the GPU and converted to an HNSW index that can be searched on the CPU. The graph build algorithm is selected automatically unless explicit ACE parameters are provided.
NOTE: This function requires CUDA to be available at runtime.
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 4bcb60dee4..1a6d74adcd 100644
--- a/fern/pages/c_api/c-api-neighbors-mg-cagra.md
+++ b/fern/pages/c_api/c-api-neighbors-mg-cagra.md
@@ -218,6 +218,34 @@ cuvsMultiGpuCagraIndex_t index);
[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t)
+## Multi-GPU CAGRA index dataset update
+
+
+### cuvsMultiGpuCagraUpdateDataset
+
+Update a Multi-GPU CAGRA index with a device-padded dataset.
+
+```c
+cuvsError_t cuvsMultiGpuCagraUpdateDataset(
+cuvsResources_t res,
+cuvsDataset_t device_padded_dataset,
+cuvsMultiGpuCagraIndex_t index);
+```
+
+Standard indexes are converted to device-padded indexes. Existing device-padded indexes are updated in place with the same layout.
+
+**Parameters**
+
+| Name | Direction | Type | Description |
+| --- | --- | --- | --- |
+| `res` | in | [`cuvsResources_t`](/api-reference/c-api-core-c-api#cuvsresources-t) | cuvsResources_t opaque C handle |
+| `device_padded_dataset` | in | `cuvsDataset_t` | caller-owned device-padded dataset view |
+| `index` | in,out | [`cuvsMultiGpuCagraIndex_t`](/api-reference/c-api-neighbors-mg-cagra#cuvsmultigpucagraindex) | Multi-GPU CAGRA index |
+
+**Returns**
+
+[`cuvsError_t`](/api-reference/c-api-core-c-api#cuvserror-t)
+
## Multi-GPU CAGRA index search
diff --git a/fern/pages/c_api/c-api-preprocessing-pca.md b/fern/pages/c_api/c-api-preprocessing-pca.md
index 4bfb7d7b51..c95bf324b2 100644
--- a/fern/pages/c_api/c-api-preprocessing-pca.md
+++ b/fern/pages/c_api/c-api-preprocessing-pca.md
@@ -112,14 +112,16 @@ bool flip_signs_based_on_U);
Computes the principal components, explained variances, singular values, and column means from the input data.
+The layout of `input` (C-contiguous / row-major or F-contiguous / col-major) is detected from its DLPack strides; `components` must use the same layout as `input`.
+
**Parameters**
| Name | Direction | Type | Description |
| --- | --- | --- | --- |
| `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) |
+| `input` | inout | `DLManagedTensor*` | input data [n_rows x n_cols] (C- or F-contiguous, float32, device) |
+| `components` | out | `DLManagedTensor*` | principal components [n_components x n_cols] (same layout as input) |
| `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) |
@@ -150,7 +152,7 @@ DLManagedTensor* noise_vars,
bool flip_signs_based_on_U);
```
-Computes the principal components and transforms the input data into the eigenspace.
+Computes the principal components and transforms the input data into the eigenspace. The layout of `input` (C- or F-contiguous) is detected from its DLPack strides; all other matrix tensors must use the same layout.
**Parameters**
@@ -158,9 +160,9 @@ Computes the principal components and transforms the input data into the eigensp
| --- | --- | --- | --- |
| `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) |
+| `input` | inout | `DLManagedTensor*` | input data [n_rows x n_cols] (C- or F-contiguous, float32, device) |
+| `trans_input` | out | `DLManagedTensor*` | transformed data [n_rows x n_components] (same layout as input) |
+| `components` | out | `DLManagedTensor*` | principal components [n_components x n_cols] (same layout as input) |
| `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) |
@@ -187,7 +189,7 @@ DLManagedTensor* mu,
DLManagedTensor* trans_input);
```
-Transforms the input data into the eigenspace using previously computed principal components.
+Transforms the input data into the eigenspace using previously computed principal components. The layout of `input` (C- or F-contiguous) is detected from its DLPack strides; all other matrix tensors must use the same layout.
**Parameters**
@@ -195,11 +197,11 @@ Transforms the input data into the eigenspace using previously computed principa
| --- | --- | --- | --- |
| `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) |
+| `input` | inout | `DLManagedTensor*` | data to transform [n_rows x n_cols] (C- or F-contiguous, float32, device) |
+| `components` | in | `DLManagedTensor*` | principal components [n_components x n_cols] (same layout as input) |
| `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) |
+| `trans_input` | out | `DLManagedTensor*` | transformed data [n_rows x n_components] (same layout as input) |
**Returns**
@@ -220,7 +222,7 @@ DLManagedTensor* mu,
DLManagedTensor* output);
```
-Transforms data from the eigenspace back to the original space.
+Transforms data from the eigenspace back to the original space. The layout of `trans_input` (C- or F-contiguous) is detected from its DLPack strides; all other matrix tensors must use the same layout.
**Parameters**
@@ -228,11 +230,11 @@ Transforms data from the eigenspace back to the original space.
| --- | --- | --- | --- |
| `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) |
+| `trans_input` | in | `DLManagedTensor*` | transformed data [n_rows x n_components] (C- or F-contiguous, float32, device) |
+| `components` | in | `DLManagedTensor*` | principal components [n_components x n_cols] (same layout as trans_input) |
| `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) |
+| `output` | out | `DLManagedTensor*` | reconstructed data [n_rows x n_cols] (same layout as trans_input) |
**Returns**
diff --git a/fern/pages/c_api/index.md b/fern/pages/c_api/index.md
index d98f4cebe5..968ef01b0e 100644
--- a/fern/pages/c_api/index.md
+++ b/fern/pages/c_api/index.md
@@ -10,6 +10,7 @@ These pages are generated from the documented public headers in the cuVS source
## Common
- [C API](/api-reference/c-api-core-c-api)
+- [Dataset](/api-reference/c-api-core-dataset)
## Distance
diff --git a/fern/pages/cpp_api/cpp-api-cluster-gmm.md b/fern/pages/cpp_api/cpp-api-cluster-gmm.md
index df5afb1f17..66dff88db2 100644
--- a/fern/pages/cpp_api/cpp-api-cluster-gmm.md
+++ b/fern/pages/cpp_api/cpp-api-cluster-gmm.md
@@ -59,6 +59,8 @@ enum class init_method {
Hyper-parameters for the Gaussian mixture EM solver.
+All defaults match scikit-learn's ``GaussianMixture`` so that results are directly comparable out of the box.
+
```cpp
struct params {
int n_components;
@@ -136,6 +138,8 @@ When `warm_start` is true the incoming ``weights`` / ``means`` / ``covariances``
**Additional overload:** `cluster::gmm::fit`
+Fit a Gaussian mixture with the EM algorithm.
+
```cpp
void fit(raft::resources const& handle,
const params& params,
@@ -152,6 +156,8 @@ raft::host_scalar_view converged,
bool warm_start = false);
```
+Double-precision overload; see the single-precision overload for details.
+
**Parameters**
| Name | Direction | Type | Description |
@@ -207,6 +213,8 @@ raft::device_vector_view labels);
**Additional overload:** `cluster::gmm::predict`
+Hard component labels (argmax responsibility) for new data.
+
```cpp
void predict(raft::resources const& handle,
const params& params,
@@ -217,6 +225,8 @@ raft::device_vector_view precisions_chol,
raft::device_vector_view labels);
```
+Double-precision overload; see the single-precision overload for details.
+
**Parameters**
| Name | Direction | Type | Description |
@@ -266,6 +276,8 @@ raft::device_matrix_view resp);
**Additional overload:** `cluster::gmm::predict_proba`
+Posterior responsibilities for new data.
+
```cpp
void predict_proba(raft::resources const& handle,
const params& params,
@@ -276,6 +288,8 @@ raft::device_vector_view precisions_chol,
raft::device_matrix_view resp);
```
+Double-precision overload; see the single-precision overload for details.
+
**Parameters**
| Name | Direction | Type | Description |
@@ -325,6 +339,8 @@ raft::device_vector_view log_prob_norm);
**Additional overload:** `cluster::gmm::score_samples`
+Per-sample log-likelihood log p(x_i) for new data.
+
```cpp
void score_samples(raft::resources const& handle,
const params& params,
@@ -335,6 +351,8 @@ raft::device_vector_view precisions_chol,
raft::device_vector_view log_prob_norm);
```
+Double-precision overload; see the single-precision overload for details.
+
**Parameters**
| Name | Direction | Type | Description |
diff --git a/fern/pages/cpp_api/cpp-api-cluster-kmeans.md b/fern/pages/cpp_api/cpp-api-cluster-kmeans.md
index 4ad724c483..65e8dd62f2 100644
--- a/fern/pages/cpp_api/cpp-api-cluster-kmeans.md
+++ b/fern/pages/cpp_api/cpp-api-cluster-kmeans.md
@@ -60,35 +60,30 @@ struct params : base_params {
| `verbosity` | `rapids_logger::level_enum` | verbosity level. |
| `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 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 device_buffer_samples, which controls how many samples to transfer from host to device per batch when processing out-of-core data. |
+| `oversampling_factor` | `double` | Oversampling factor for use in the k-means\|\| algorithm.
In the single-GPU path the value `0` is overloaded as an algorithm switch that selects the classic sequential k-means++ instead of the scalable variant. Any value `> 0` is used as-is.
In the multi-GPU path (a `fit` call issued with a multi-GPU `handle` and device-resident inputs) any value `< 1.0` (including `0`) is internally clamped to `1.0`. Values `>= 1.0` are passed through unchanged. |
+| `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 device_buffer_samples, which specifies the number of training vectors that get buffered on device when the training vectors are passed in on host. |
| `batch_centroids` | `int` | if 0 then batch_centroids = n_clusters |
| `init_size` | `int64_t` | Number of samples to randomly draw for the KMeansPlusPlus initialization step. A random subset of this size is used for centroid seeding.
Only applies when dataset is on host; for device data the full dataset is always used for seeding and this parameter is ignored.
When set to 0 (default) with host data uses `min(3 * n_clusters, n_samples)` as a default.
In Batched multi-GPU host-data fits, the effective KMeansPlusPlus initialization sample is materialized on device on every rank. Every rank must have enough GPU memory for this sample, and rank 0 must also have enough GPU memory for the seeding workspace.
Default: 0. |
-| `device_buffer_samples` | `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.
In multi-GPU mode, this is a per-rank batch size. Each rank processes up to this many local samples per batch, clamped to that rank's local sample count.
Default: 0 (process all data at once). |
+| `device_buffer_samples` | `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.
In multi-GPU mode this is a per-rank batch size: each rank processes up to this many local samples per batch, clamped to that rank's local sample count. This is is ignored by device-data overloads.
Default: 0 (process all data at once). |
-
-### cluster::kmeans::balanced_params
+
+### cluster::kmeans::balanced_donor_selection
-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
+Donor selection strategy used by balanced k-means rebalancing.
```cpp
-struct balanced_params : base_params {
- uint32_t n_iters;
+enum class balanced_donor_selection {
+ SizeSorted = 0,
+ Random = 1
};
```
-**Fields**
+**Values**
-| Name | Type | Description |
-| --- | --- | --- |
-| `n_iters` | `uint32_t` | Number of training iterations |
+| Name | Value |
+| --- | --- |
+| `SizeSorted` | `0` |
+| `Random` | `1` |
### cluster::kmeans::kmeans_type
@@ -126,9 +121,11 @@ raft::host_scalar_view inertia,
raft::host_scalar_view n_iter);
```
+Runs on multiple GPUs when `handle` carries an SNMG clique (`raft::resource::is_multi_gpu(handle)`) or initialized RAFT comms (`raft::resource::comms_initialized(handle)`), and on a single GPU otherwise.
+
TODO: Evaluate replacing the extent type with int64_t. Reference issue: https://github.com/nvidia/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.device_buffer_samples. In multi-GPU mode, this is a per-rank batch size.
+This overload supports out-of-core computation where the dataset resides on the host. Data is processed in batches, streaming from host to device. The batch size is controlled by `params.device_buffer_samples`.
Multi-GPU dispatch is selected automatically based on the handle state:
@@ -351,7 +348,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&`](/api-reference/cpp-api-cluster-kmeans#cluster-kmeans-balanced-params) | Parameters for KMeans model. |
+| `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`. |
@@ -377,7 +374,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&`](/api-reference/cpp-api-cluster-kmeans#cluster-kmeans-balanced-params) | Parameters for KMeans model. |
+| `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`. |
@@ -403,7 +400,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&`](/api-reference/cpp-api-cluster-kmeans#cluster-kmeans-balanced-params) | Parameters for KMeans model. |
+| `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`. |
@@ -429,7 +426,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&`](/api-reference/cpp-api-cluster-kmeans#cluster-kmeans-balanced-params) | Parameters for KMeans model. |
+| `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`. |
@@ -584,7 +581,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&`](/api-reference/cpp-api-cluster-kmeans#cluster-kmeans-balanced-params) | Parameters for KMeans model. |
+| `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] |
@@ -610,7 +607,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&`](/api-reference/cpp-api-cluster-kmeans#cluster-kmeans-balanced-params) | Parameters for KMeans model. |
+| `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] |
@@ -636,7 +633,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&`](/api-reference/cpp-api-cluster-kmeans#cluster-kmeans-balanced-params) | Parameters for KMeans model. |
+| `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] |
@@ -662,7 +659,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&`](/api-reference/cpp-api-cluster-kmeans#cluster-kmeans-balanced-params) | Parameters for KMeans model. |
+| `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] |
@@ -688,7 +685,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&`](/api-reference/cpp-api-cluster-kmeans#cluster-kmeans-balanced-params) | Parameters for KMeans model. |
+| `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] |
@@ -714,7 +711,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&`](/api-reference/cpp-api-cluster-kmeans#cluster-kmeans-balanced-params) | Parameters for KMeans model. |
+| `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] |
@@ -869,7 +866,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&`](/api-reference/cpp-api-cluster-kmeans#cluster-kmeans-balanced-params) | Parameters for KMeans model. |
+| `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] |
@@ -895,7 +892,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&`](/api-reference/cpp-api-cluster-kmeans#cluster-kmeans-balanced-params) | Parameters for KMeans model. |
+| `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] |
@@ -1066,6 +1063,201 @@ std::optional> sample_weight = s
`void`
+## Multi-GPU / out-of-core k-means fit (multiple partitions per rank)
+
+**Additional overload:** `cluster::kmeans::fit`
+
+Multi-GPU k-means fit with one or more local data partitions per rank.
+
+```cpp
+void fit(
+raft::resources const& handle,
+const cuvs::cluster::kmeans::params& params,
+const std::vector>& X_parts,
+const std::optional>>& sample_weight_parts,
+raft::device_matrix_view centroids,
+raft::host_scalar_view inertia,
+raft::host_scalar_view n_iter);
+```
+
+Each rank supplies its local training data as a vector of partitions. For host-resident partitions the implementation streams each partition using `params.device_buffer_samples` (per rank). For device-resident partitions `device_buffer_samples` is ignored and each local partition is processed in full.
+
+The active backend is selected by the resources attached to `handle`:
+
+- When `raft::resource::is_multi_gpu(handle)` is true (SNMG clique), the call must be issued from inside an OpenMP region with one thread per rank in the clique.
+- Otherwise, multi-process NCCL comms must be initialized on the handle (`raft::resource::comms_initialized(handle)`); each process supplies its own local partitions.
+
+**Parameters**
+
+| Name | Direction | Type | Description |
+| --- | --- | --- | --- |
+| `handle` | in | `raft::resources const&` | The raft handle. Must have NCCL comms or a SNMG clique initialized. |
+| `params` | in | [`const cuvs::cluster::kmeans::params&`](/api-reference/cpp-api-cluster-kmeans#cluster-kmeans-params) | K-means parameters. For host-resident partitions the per-rank streaming batch size is read from `params.device_buffer_samples`; it is ignored for device-resident partitions. |
+| `X_parts` | in | `const std::vector>&` | Per-partition local data on this rank. Each entry is [n_rows_i x n_features]. |
+| `sample_weight_parts` | in | `const std::optional>>&` | Optional per-partition row weights with one vector per data partition. |
+| `centroids` | inout | `raft::device_matrix_view` | Device matrix [n_clusters x n_features]. On entry, used as the initial centers when `params.init == InitMethod::Array`. On return, holds the converged centroids. |
+| `inertia` | out | `raft::host_scalar_view` | Host scalar receiving the final clustering cost. |
+| `n_iter` | out | `raft::host_scalar_view` | Host scalar receiving the iteration count at which the run terminated. |
+
+**Returns**
+
+`void`
+
+**Additional overload:** `cluster::kmeans::fit`
+
+Multi-GPU k-means fit.
+
+```cpp
+void fit(raft::resources const& handle,
+const cuvs::cluster::kmeans::params& params,
+const std::vector>& X_parts,
+const std::optional>>&
+sample_weight_parts,
+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&`](/api-reference/cpp-api-cluster-kmeans#cluster-kmeans-params) | |
+| `X_parts` | | `const std::vector>&` | |
+| `sample_weight_parts` | | `const std::optional>>&` | |
+| `centroids` | | `raft::device_matrix_view` | |
+| `inertia` | | `raft::host_scalar_view` | |
+| `n_iter` | | `raft::host_scalar_view` | |
+
+**Returns**
+
+`void`
+
+**Additional overload:** `cluster::kmeans::fit`
+
+Multi-GPU k-means fit.
+
+```cpp
+void fit(raft::resources const& handle,
+const cuvs::cluster::kmeans::params& params,
+const std::vector>& X_parts,
+const std::optional>>&
+sample_weight_parts,
+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&`](/api-reference/cpp-api-cluster-kmeans#cluster-kmeans-params) | |
+| `X_parts` | | `const std::vector>&` | |
+| `sample_weight_parts` | | `const std::optional>>&` | |
+| `centroids` | | `raft::device_matrix_view` | |
+| `inertia` | | `raft::host_scalar_view` | |
+| `n_iter` | | `raft::host_scalar_view` | |
+
+**Returns**
+
+`void`
+
+**Additional overload:** `cluster::kmeans::fit`
+
+Multi-GPU k-means fit.
+
+```cpp
+void fit(raft::resources const& handle,
+const cuvs::cluster::kmeans::params& params,
+const std::vector>& X_parts,
+const std::optional>>&
+sample_weight_parts,
+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&`](/api-reference/cpp-api-cluster-kmeans#cluster-kmeans-params) | |
+| `X_parts` | | `const std::vector>&` | |
+| `sample_weight_parts` | | `const std::optional>>&` | |
+| `centroids` | | `raft::device_matrix_view` | |
+| `inertia` | | `raft::host_scalar_view` | |
+| `n_iter` | | `raft::host_scalar_view` | |
+
+**Returns**
+
+`void`
+
+**Additional overload:** `cluster::kmeans::fit`
+
+Multi-GPU / out-of-core k-means fit.
+
+```cpp
+void fit(raft::resources const& handle,
+const cuvs::cluster::kmeans::params& params,
+const std::vector>& X_parts,
+const std::optional>>&
+sample_weight_parts,
+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&`](/api-reference/cpp-api-cluster-kmeans#cluster-kmeans-params) | |
+| `X_parts` | | `const std::vector>&` | |
+| `sample_weight_parts` | | `const std::optional>>&` | |
+| `centroids` | | `raft::device_matrix_view` | |
+| `inertia` | | `raft::host_scalar_view` | |
+| `n_iter` | | `raft::host_scalar_view` | |
+
+**Returns**
+
+`void`
+
+**Additional overload:** `cluster::kmeans::fit`
+
+Multi-GPU / out-of-core k-means fit.
+
+```cpp
+void fit(raft::resources const& handle,
+const cuvs::cluster::kmeans::params& params,
+const std::vector>& X_parts,
+const std::optional>>&
+sample_weight_parts,
+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&`](/api-reference/cpp-api-cluster-kmeans#cluster-kmeans-params) | |
+| `X_parts` | | `const std::vector>&` | |
+| `sample_weight_parts` | | `const std::optional>>&` | |
+| `centroids` | | `raft::device_matrix_view` | |
+| `inertia` | | `raft::host_scalar_view` | |
+| `n_iter` | | `raft::host_scalar_view` | |
+
+**Returns**
+
+`void`
+
## k-means API helpers
diff --git a/fern/pages/cpp_api/cpp-api-core-bloom-filter.md b/fern/pages/cpp_api/cpp-api-core-bloom-filter.md
new file mode 100644
index 0000000000..f94f768042
--- /dev/null
+++ b/fern/pages/cpp_api/cpp-api-core-bloom-filter.md
@@ -0,0 +1,20 @@
+---
+slug: api-reference/cpp-api-core-bloom-filter
+---
+
+# Bloom Filter
+
+_Source header: `cuvs/core/bloom_filter.hpp`_
+
+## Types
+
+
+### core::bloom_filter
+
+cuVS-owned Bloom filter wrapper with opaque implementation.
+
+This class intentionally hides cuCollections types from the cuVS public API. The wrapper supports the expected bulk host APIs used by ANN workflows.
+
+```cpp
+class bloom_filter;
+```
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 5569e3ffbc..9a908bd2d2 100644
--- a/fern/pages/cpp_api/cpp-api-neighbors-all-neighbors.md
+++ b/fern/pages/cpp_api/cpp-api-neighbors-all-neighbors.md
@@ -69,8 +69,8 @@ Usage example:
| `handle` | in | `const raft::resources&` | raft::resources is an object managing resources |
| `params` | in | [`const all_neighbors_params&`](/api-reference/cpp-api-neighbors-all-neighbors#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`. |
+| `indices` | out | `raft::device_matrix_view` | nearest neighbor indices of shape [n_row x k] on device memory |
+| `distances` | out | `std::optional>` | nearest neighbor distances [n_row x k] on device memory
Default: `std::nullopt`. |
| `core_distances` | out | `std::optional>` | array for core distances of size [n_row]. Requires distances matrix to compute core_distances. If core_distances is given, the resulting indices and distances will be mutual reachability space.
Default: `std::nullopt`. |
| `alpha` | in | `float` | distance scaling parameter as used in robust single linkage.
Default: `1.0`. |
@@ -80,6 +80,39 @@ Usage example:
**Additional overload:** `neighbors::all_neighbors::build`
+Builds an approximate all-neighbors knn graph (find nearest neighbors for all the training vectors)
+
+```cpp
+void build(
+const raft::resources& handle,
+const all_neighbors_params& params,
+raft::host_matrix_view dataset,
+raft::host_matrix_view indices,
+std::optional> distances = std::nullopt,
+std::optional> core_distances = std::nullopt,
+float alpha = 1.0);
+```
+
+Usage example:
+
+**Parameters**
+
+| Name | Direction | Type | Description |
+| --- | --- | --- | --- |
+| `handle` | in | `const raft::resources&` | raft::resources is an object managing resources |
+| `params` | in | [`const all_neighbors_params&`](/api-reference/cpp-api-neighbors-all-neighbors#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::host_matrix_view` | nearest neighbor indices of shape [n_row x k] on host memory |
+| `distances` | out | `std::optional>` | nearest neighbor distances [n_row x k] on host memory
Default: `std::nullopt`. |
+| `core_distances` | out | `std::optional>` | array for core distances of size [n_row] on host memory. Requires distances matrix to compute core_distances. If core_distances is given, the resulting indices and distances will be mutual reachability space.
Default: `std::nullopt`. |
+| `alpha` | in | `float` | distance scaling parameter as used in robust single linkage.
Default: `1.0`. |
+
+**Returns**
+
+`void`
+
+**Additional overload:** `neighbors::all_neighbors::build`
+
Builds an approximate all-neighbors knn graph (find nearest neighbors for all the training 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.
```cpp
@@ -102,8 +135,8 @@ Usage example:
| `handle` | in | `const raft::resources&` | raft::resources is an object managing resources |
| `params` | in | [`const all_neighbors_params&`](/api-reference/cpp-api-neighbors-all-neighbors#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`. |
+| `indices` | out | `raft::device_matrix_view` | nearest neighbor indices of shape [n_row x k] on device memory |
+| `distances` | out | `std::optional>` | nearest neighbor distances [n_row x k] on device memory
Default: `std::nullopt`. |
| `core_distances` | out | `std::optional>` | array for core distances of size [n_row]. Requires distances matrix to compute core_distances. If core_distances is given, the resulting indices and distances will be mutual reachability space.
Default: `std::nullopt`. |
| `alpha` | in | `float` | distance scaling parameter as used in robust single linkage.
Default: `1.0`. |
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 1bab0cbd05..b5bdd6cc78 100644
--- a/fern/pages/cpp_api/cpp-api-neighbors-brute-force.md
+++ b/fern/pages/cpp_api/cpp-api-neighbors-brute-force.md
@@ -71,6 +71,32 @@ Constructs a brute force index from a dataset. This lets us precompute norms for
**Additional overload:** `neighbors::brute_force::index::index`
+Construct a brute force index and take ownership of a row-major device dataset.
+
+```cpp
+index(raft::resources const& res,
+raft::device_matrix&& dataset,
+std::optional>&& norms,
+cuvs::distance::DistanceType metric,
+DistT metric_arg = 0.0);
+```
+
+**Parameters**
+
+| Name | Direction | Type | Description |
+| --- | --- | --- | --- |
+| `res` | | `raft::resources const&` | |
+| `dataset` | | `raft::device_matrix&&` | |
+| `norms` | | `std::optional>&&` | |
+| `metric` | | [`cuvs::distance::DistanceType`](/api-reference/cpp-api-distance-distance#distance-distancetype) | |
+| `metric_arg` | | `DistT` | Default: `0.0`. |
+
+**Returns**
+
+`void`
+
+**Additional overload:** `neighbors::brute_force::index::index`
+
Construct a brute force index from dataset
```cpp
diff --git a/fern/pages/cpp_api/cpp-api-neighbors-cagra.md b/fern/pages/cpp_api/cpp-api-neighbors-cagra.md
index 81699949a7..5f1865967d 100644
--- a/fern/pages/cpp_api/cpp-api-neighbors-cagra.md
+++ b/fern/pages/cpp_api/cpp-api-neighbors-cagra.md
@@ -30,7 +30,7 @@ struct ace_params {
| --- | --- | --- |
| `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. |
+| `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. The directory may already exist, but ACE's named artifacts must not already exist. Simultaneous builds must use different directories. On failure, ACE removes only artifacts it created and never deletes unrelated directory contents. |
| `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. |
@@ -70,6 +70,19 @@ struct vpq_params {
| `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. |
+
+### graph_build_params_t
+
+CAGRA index build parameters
+
+```cpp
+using graph_build_params_t = std::variant;
+```
+
### neighbors::cagra::hnsw_heuristic_type
@@ -81,6 +94,64 @@ Define how `cagra::index_params::from_hnsw_params` should construct a graph to c
enum class hnsw_heuristic_type : uint32_t;
```
+
+### neighbors::cagra::index_params::graph_build_heuristic
+
+Select the graph build algorithm and its parameters for a dataset.
+
+```cpp
+static graph_build_params_t graph_build_heuristic(
+raft::matrix_extent dataset,
+size_t intermediate_graph_degree,
+cuvs::distance::DistanceType metric = cuvs::distance::DistanceType::L2Expanded,
+size_t build_quality = 7);
+```
+
+This is the main CAGRA build heuristic: it chooses between NN-descent and IVF-PQ based on the dataset size and tunes their parameters based on the target intermediate graph degree and the requested build quality. It returns the `graph_build_params` variant only; the caller is responsible for setting `graph_degree` / `intermediate_graph_degree`.
+
+**Parameters**
+
+| Name | Direction | Type | Description |
+| --- | --- | --- | --- |
+| `dataset` | | `raft::matrix_extent` | The shape of the input dataset |
+| `intermediate_graph_degree` | | `size_t` | The intermediate (kNN) graph degree the build should target.
Note: the intermediate graph degree must be not smaller than the output graph degree; a good practice is to have it 1.5x to 2x of the desired graph_degree and a multiple of 32. |
+| `metric` | | [`cuvs::distance::DistanceType`](/api-reference/cpp-api-distance-distance#distance-distancetype) | The distance metric to search
Default: `cuvs::distance::DistanceType::L2Expanded`. |
+| `build_quality` | | `size_t` | Higher values increase the build quality (and cost) up to a point. Any value is valid, but values below 20 are the most practical (default = 7).
Default: `7`. |
+
+**Returns**
+
+[`static graph_build_params_t`](/api-reference/cpp-api-neighbors-cagra#graph-build-params-t)
+
+
+### neighbors::cagra::index_params::from_dataset
+
+Create CAGRA index parameters heuristically tuned for a dataset.
+
+```cpp
+static cagra::index_params from_dataset(
+raft::matrix_extent dataset,
+size_t graph_degree = 64,
+cuvs::distance::DistanceType metric = cuvs::distance::DistanceType::L2Expanded,
+size_t build_quality = 7);
+```
+
+Returns default CAGRA `index_params` with `graph_build_params` selected by `graph_build_heuristic` for the given dataset.
+
+Usage example:
+
+**Parameters**
+
+| Name | Direction | Type | Description |
+| --- | --- | --- | --- |
+| `dataset` | | `raft::matrix_extent` | The shape of the input dataset |
+| `graph_degree` | | `size_t` | Degree of the output graph.
Default: `64`. |
+| `metric` | | [`cuvs::distance::DistanceType`](/api-reference/cpp-api-distance-distance#distance-distancetype) | The distance metric to search
Default: `cuvs::distance::DistanceType::L2Expanded`. |
+| `build_quality` | | `size_t` | Higher values increase the build quality (and cost) up to a point. Any value is valid, but values below 20 are the most practical (default = 7).
Default: `7`. |
+
+**Returns**
+
+`static cagra::index_params`
+
### neighbors::cagra::index_params::from_hnsw_params
@@ -169,7 +240,9 @@ CAGRA index.
The index stores the dataset and a kNN graph in device memory.
```cpp
-template
+template >
struct index;
```
@@ -225,18 +298,31 @@ Graph degree
`uint32_t`
-
-### neighbors::cagra::index::data
+
+### neighbors::cagra::index::graph_size
+
+Number of rows represented by the graph.
+
+```cpp
+[[nodiscard]] constexpr inline auto graph_size() const noexcept -> IdxT;
+```
+
+**Returns**
+
+`IdxT`
+
+
+### neighbors::cagra::index::dataset
-Dataset [size, dim]
+Non-owning dataset binding stored by the index.
```cpp
-[[nodiscard]] inline auto data() const noexcept -> const cuvs::neighbors::dataset&;
+[[nodiscard]] inline auto dataset() const noexcept -> DatasetViewT const&;
```
**Returns**
-[`const cuvs::neighbors::dataset&`](/api-reference/cpp-api-neighbors-common#neighbors-dataset)
+`DatasetViewT const&`
### neighbors::cagra::index::graph
@@ -341,11 +427,13 @@ index(const index&) = delete;
**Additional overload:** `neighbors::cagra::index::index`
-Construct an empty index.
+Construct a graph-only index with a zero-row dataset view placeholder.
```cpp
-index(raft::resources const& res,
-cuvs::distance::DistanceType metric = cuvs::distance::DistanceType::L2Expanded);
+explicit index(raft::resources const& res,
+cuvs::distance::DistanceType metric = cuvs::distance::DistanceType::L2Expanded)
+requires(cuvs::neighbors::ann_dataset_view)
+: cuvs::neighbors::index(),;
```
**Parameters**
@@ -357,34 +445,28 @@ cuvs::distance::DistanceType metric = cuvs::distance::DistanceType::L2Expanded);
**Returns**
-`void`
+`explicit`
**Additional overload:** `neighbors::cagra::index::index`
-Construct an index from dataset and knn_graph arrays
+Construct an index from a `dataset_view` and knn_graph.
```cpp
-template
+template
index(raft::resources const& res,
cuvs::distance::DistanceType metric,
-raft::mdspan, raft::row_major, data_accessor> dataset,
+DatasetViewT const& dataset,
raft::mdspan,
raft::row_major,
graph_accessor> 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.
+Stores a shallow copy of the dataset view. The index stores a **non-owning** view; the caller must keep the underlying host or device storage alive for the index lifetime.
-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.
+Example — **non-owning** `make_device_padded_dataset_view` (wraps an existing device matrix; that matrix must outlive 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
+Example — **owning** `make_device_padded_dataset` returns owning storage (`std::unique_ptr`). You must **keep that object alive** (e.g. hold the `unique_ptr` in a variable or member) for as long as the index uses the dataset; the index does not take ownership of the buffer.
**Parameters**
@@ -392,126 +474,52 @@ Usage examples:
| --- | --- | --- | --- |
| `res` | | `raft::resources const&` | |
| `metric` | | [`cuvs::distance::DistanceType`](/api-reference/cpp-api-distance-distance#distance-distancetype) | |
-| `dataset` | | `raft::mdspan, raft::row_major, data_accessor>` | |
+| `dataset` | | `DatasetViewT const&` | |
| `knn_graph` | | `raft::mdspan, raft::row_major, graph_accessor>` | |
**Returns**
`void`
-
-### neighbors::cagra::index::update_device_dataset_same_layout
-
-Replace the dataset with a new dataset.
-
-```cpp
-void update_device_dataset_same_layout(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_device_dataset_same_layout 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`
-
-**Additional overload:** `neighbors::cagra::index::update_device_dataset_same_layout`
-
-Set the dataset reference explicitly to a device matrix view with padding.
-
-```cpp
-void update_device_dataset_same_layout(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`
-
-**Additional overload:** `neighbors::cagra::index::update_device_dataset_same_layout`
+
+### neighbors::cagra::index::update_graph
-Replace the dataset with a new dataset.
+Replace the graph with a new graph.
```cpp
-void update_device_dataset_same_layout(raft::resources const& res,
-raft::host_matrix_view dataset);
+void update_graph(
+raft::resources const& res,
+raft::device_matrix_view knn_graph);
```
-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_device_dataset_same_layout and index build.
-
-Note: This will clear any precomputed dataset norms.
+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&` | |
-| `dataset` | | `raft::host_matrix_view` | |
+| `knn_graph` | | `raft::device_matrix_view` | |
**Returns**
`void`
-**Additional overload:** `neighbors::cagra::index::update_device_dataset_same_layout`
-
-Replace the dataset with a new dataset. It is expected that the same set of vectors are used
-
-```cpp
-template
-auto update_device_dataset_same_layout(raft::resources const& res, DatasetT&& dataset)
--> std::enable_if_t, DatasetT>>;
-```
-
-for update_device_dataset_same_layout 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>>`](/api-reference/cpp-api-neighbors-common#neighbors-dataset)
-
-
-### neighbors::cagra::index::update_graph
+**Additional overload:** `neighbors::cagra::index::update_graph`
-Replace the graph with a new graph.
+Replace the graph by taking ownership of an existing device matrix.
```cpp
-void update_graph(
-raft::resources const& res,
-raft::device_matrix_view knn_graph);
+void update_graph(raft::resources const&,
+raft::device_matrix&& 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` | |
+| `arg1` | | `raft::resources const&` | |
+| `knn_graph` | | `raft::device_matrix&&` | |
**Returns**
@@ -582,7 +590,8 @@ source_indices);
`void`
-**Additional overload:** `neighbors::cagra::index::update_dataset`
+
+### neighbors::cagra::index::update_dataset
Update the dataset from a disk file using a file descriptor.
@@ -651,456 +660,424 @@ This method configures the index to use a disk-based dataset mapping. The mappin
### neighbors::cagra::build
-Build the index from the dataset for efficient search.
+Build from a device padded dataset view (`float`).
```cpp
auto build(raft::resources const& res,
const cuvs::neighbors::cagra::index_params& params,
-raft::device_matrix_view dataset)
--> cuvs::neighbors::cagra::index;
+cuvs::neighbors::device_padded_dataset_view const& dataset)
+-> cuvs::neighbors::cagra::device_padded_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] |
+| `res` | in | `raft::resources const&` | raft resources |
+| `params` | in | `const cuvs::neighbors::cagra::index_params&` | CAGRA index build parameters |
+| `dataset` | in | `cuvs::neighbors::device_padded_dataset_view const&` | device padded dataset view [n_rows, dim] |
**Returns**
-[`cuvs::neighbors::cagra::index`](/api-reference/cpp-api-neighbors-cagra#neighbors-cagra-index)
+`cuvs::neighbors::cagra::device_padded_index`
+
+built `device_padded_index<float, uint32_t>`
**Additional overload:** `neighbors::cagra::build`
-Build the index from the dataset for efficient search.
+Build from a device standard dataset view (`float`).
```cpp
auto build(raft::resources const& res,
const cuvs::neighbors::cagra::index_params& params,
-raft::host_matrix_view dataset)
--> cuvs::neighbors::cagra::index;
+cuvs::neighbors::device_standard_dataset_view const& dataset)
+-> cuvs::neighbors::cagra::device_standard_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] |
+| `res` | in | `raft::resources const&` | raft resources |
+| `params` | in | `const cuvs::neighbors::cagra::index_params&` | CAGRA index build parameters |
+| `dataset` | in | `cuvs::neighbors::device_standard_dataset_view const&` | device standard dataset view [n_rows, dim] |
**Returns**
-[`cuvs::neighbors::cagra::index`](/api-reference/cpp-api-neighbors-cagra#neighbors-cagra-index)
+`cuvs::neighbors::cagra::device_standard_index`
+
+built `device_standard_index<float, uint32_t>`
**Additional overload:** `neighbors::cagra::build`
-Build the index from the dataset for efficient search.
+Build from a host padded dataset view (`float`).
```cpp
auto build(raft::resources const& res,
const cuvs::neighbors::cagra::index_params& params,
-raft::device_matrix_view dataset)
--> cuvs::neighbors::cagra::index;
+cuvs::neighbors::host_padded_dataset_view const& dataset)
+-> cuvs::neighbors::cagra::host_padded_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] |
+| `res` | in | `raft::resources const&` | raft resources |
+| `params` | in | `const cuvs::neighbors::cagra::index_params&` | CAGRA index build parameters |
+| `dataset` | in | `cuvs::neighbors::host_padded_dataset_view const&` | host padded dataset view [n_rows, dim] |
**Returns**
-[`cuvs::neighbors::cagra::index`](/api-reference/cpp-api-neighbors-cagra#neighbors-cagra-index)
+`cuvs::neighbors::cagra::host_padded_index`
+
+built `host_padded_index<float, uint32_t>`
**Additional overload:** `neighbors::cagra::build`
-Build the index from the dataset for efficient search.
+Build from a host standard dataset view (`float`).
```cpp
auto build(raft::resources const& res,
const cuvs::neighbors::cagra::index_params& params,
-raft::host_matrix_view dataset)
--> cuvs::neighbors::cagra::index;
+cuvs::neighbors::host_standard_dataset_view const& dataset)
+-> cuvs::neighbors::cagra::host_standard_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] |
+| `res` | in | `raft::resources const&` | raft resources |
+| `params` | in | `const cuvs::neighbors::cagra::index_params&` | CAGRA index build parameters |
+| `dataset` | in | `cuvs::neighbors::host_standard_dataset_view const&` | host standard dataset view [n_rows, dim] |
**Returns**
-[`cuvs::neighbors::cagra::index`](/api-reference/cpp-api-neighbors-cagra#neighbors-cagra-index)
+`cuvs::neighbors::cagra::host_standard_index`
+
+built `host_standard_index<float, uint32_t>`
**Additional overload:** `neighbors::cagra::build`
-Build the index from the dataset for efficient search.
+Build from a device padded dataset view (`half`).
```cpp
auto build(raft::resources const& res,
const cuvs::neighbors::cagra::index_params& params,
-raft::device_matrix_view dataset)
--> cuvs::neighbors::cagra::index;
+cuvs::neighbors::device_padded_dataset_view const& dataset)
+-> cuvs::neighbors::cagra::device_padded_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] |
+| `res` | in | `raft::resources const&` | raft resources |
+| `params` | in | `const cuvs::neighbors::cagra::index_params&` | CAGRA index build parameters |
+| `dataset` | in | `cuvs::neighbors::device_padded_dataset_view const&` | device padded dataset view [n_rows, dim] |
**Returns**
-[`cuvs::neighbors::cagra::index`](/api-reference/cpp-api-neighbors-cagra#neighbors-cagra-index)
+`cuvs::neighbors::cagra::device_padded_index`
+
+built `device_padded_index<half, uint32_t>`
**Additional overload:** `neighbors::cagra::build`
-Build the index from the dataset for efficient search.
+Build from a device standard dataset view (`half`).
```cpp
auto build(raft::resources const& res,
const cuvs::neighbors::cagra::index_params& params,
-raft::host_matrix_view dataset)
--> cuvs::neighbors::cagra::index;
+cuvs::neighbors::device_standard_dataset_view const& dataset)
+-> cuvs::neighbors::cagra::device_standard_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] |
+| `res` | in | `raft::resources const&` | raft resources |
+| `params` | in | `const cuvs::neighbors::cagra::index_params&` | CAGRA index build parameters |
+| `dataset` | in | `cuvs::neighbors::device_standard_dataset_view const&` | device standard dataset view [n_rows, dim] |
**Returns**
-[`cuvs::neighbors::cagra::index`](/api-reference/cpp-api-neighbors-cagra#neighbors-cagra-index)
+`cuvs::neighbors::cagra::device_standard_index`
+
+built `device_standard_index<half, uint32_t>`
**Additional overload:** `neighbors::cagra::build`
-Build the index from the dataset for efficient search.
+Build from a host padded dataset view (`half`).
```cpp
auto build(raft::resources const& res,
const cuvs::neighbors::cagra::index_params& params,
-raft::device_matrix_view dataset)
--> cuvs::neighbors::cagra::index;
+cuvs::neighbors::host_padded_dataset_view const& dataset)
+-> cuvs::neighbors::cagra::host_padded_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] |
+| `res` | in | `raft::resources const&` | raft resources |
+| `params` | in | `const cuvs::neighbors::cagra::index_params&` | CAGRA index build parameters |
+| `dataset` | in | `cuvs::neighbors::host_padded_dataset_view const&` | host padded dataset view [n_rows, dim] |
**Returns**
-[`cuvs::neighbors::cagra::index`](/api-reference/cpp-api-neighbors-cagra#neighbors-cagra-index)
+`cuvs::neighbors::cagra::host_padded_index`
+
+built `host_padded_index<half, uint32_t>`
**Additional overload:** `neighbors::cagra::build`
-Build the index from the dataset for efficient search.
+Build from a host standard dataset view (`half`).
```cpp
auto build(raft::resources const& res,
const cuvs::neighbors::cagra::index_params& params,
-raft::host_matrix_view dataset)
--> cuvs::neighbors::cagra::index;
+cuvs::neighbors::host_standard_dataset_view const& dataset)
+-> cuvs::neighbors::cagra::host_standard_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] |
+| `res` | in | `raft::resources const&` | raft resources |
+| `params` | in | `const cuvs::neighbors::cagra::index_params&` | CAGRA index build parameters |
+| `dataset` | in | `cuvs::neighbors::host_standard_dataset_view const&` | host standard dataset view [n_rows, dim] |
**Returns**
-[`cuvs::neighbors::cagra::index`](/api-reference/cpp-api-neighbors-cagra#neighbors-cagra-index)
+`cuvs::neighbors::cagra::host_standard_index`
-## CAGRA extend functions
+built `host_standard_index<half, uint32_t>`
-
-### neighbors::cagra::extend
+**Additional overload:** `neighbors::cagra::build`
-Add new vectors to a CAGRA index
+Build from a device padded dataset view (`int8_t`).
```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);
+auto build(raft::resources const& res,
+const cuvs::neighbors::cagra::index_params& params,
+cuvs::neighbors::device_padded_dataset_view const& dataset)
+-> cuvs::neighbors::cagra::device_padded_index;
```
-Usage example:
-
**Parameters**
| Name | Direction | Type | Description |
| --- | --- | --- | --- |
-| `handle` | in | `raft::resources const&` | raft resources |
-| `params` | in | [`const cagra::extend_params&`](/api-reference/cpp-api-neighbors-cagra#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&`](/api-reference/cpp-api-neighbors-cagra#neighbors-cagra-index) | CAGRA index |
-| `new_dataset_buffer_view` | out | `std::optional>` | memory buffer view for the dataset including the additional 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.
Default: `std::nullopt`. |
-| `new_graph_buffer_view` | out | `std::optional>` | memory buffer view for the graph including the additional 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 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.
Default: `std::nullopt`. |
+| `res` | in | `raft::resources const&` | raft resources |
+| `params` | in | `const cuvs::neighbors::cagra::index_params&` | CAGRA index build parameters |
+| `dataset` | in | `cuvs::neighbors::device_padded_dataset_view const&` | device padded dataset view [n_rows, dim] |
**Returns**
-`void`
+`cuvs::neighbors::cagra::device_padded_index`
-**Additional overload:** `neighbors::cagra::extend`
+built `device_padded_index<int8_t, uint32_t>`
-Add new vectors to a CAGRA index
+**Additional overload:** `neighbors::cagra::build`
+
+Build from a device standard dataset view (`int8_t`).
```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