HNSW

View as Markdown

Source header: cuvs/neighbors/hnsw.h

C API for HNSW index params

cuvsHnswHierarchy

Hierarchy for HNSW index when converting from CAGRA index

NOTE: When the value is NONE, the HNSW index is built as a base-layer-only index.

1enum cuvsHnswHierarchy { ... };

Values

NameValue
CPU1
GPU2

cuvsHnswAceParams

Parameters for ACE (Augmented Core Extraction) graph build for HNSW.

ACE enables building indexes for datasets too large to fit in GPU memory by:

  1. Partitioning the dataset in core and augmented partitions using balanced k-means
  2. Building sub-indexes for each partition independently
  3. Concatenating sub-graphs into a final unified index
1struct cuvsHnswAceParams { ... };

Fields

NameTypeDescription
npartitionssize_tNumber 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_dirconst char*Directory to store ACE build artifacts (e.g., KNN graph, optimized graph). Used when use_disk is true or when the graph does not fit in memory.
use_diskboolWhether to use disk-based storage for ACE build. When true, enables disk-based operations for memory-efficient graph construction.
max_host_memory_gbdoubleMaximum 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_gbdoubleMaximum 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.

cuvsHnswAceParamsCreate

Allocate HNSW ACE params, and populate with default values

1CUVS_EXPORT cuvsError_t cuvsHnswAceParamsCreate(cuvsHnswAceParams_t* params);

Parameters

NameDirectionTypeDescription
paramsincuvsHnswAceParams_t*cuvsHnswAceParams_t to allocate

Returns

CUVS_EXPORT cuvsError_t

cuvsHnswAceParamsDestroy

De-allocate HNSW ACE params

1CUVS_EXPORT cuvsError_t cuvsHnswAceParamsDestroy(cuvsHnswAceParams_t params);

Parameters

NameDirectionTypeDescription
paramsincuvsHnswAceParams_t

Returns

CUVS_EXPORT cuvsError_t

cuvsHnswIndexParamsCreate

Allocate HNSW Index params, and populate with default values

1CUVS_EXPORT cuvsError_t cuvsHnswIndexParamsCreate(cuvsHnswIndexParams_t* params);

Parameters

NameDirectionTypeDescription
paramsincuvsHnswIndexParams_t*cuvsHnswIndexParams_t to allocate

Returns

CUVS_EXPORT cuvsError_t

cuvsHnswIndexParamsDestroy

De-allocate HNSW Index params

1CUVS_EXPORT cuvsError_t cuvsHnswIndexParamsDestroy(cuvsHnswIndexParams_t params);

Parameters

NameDirectionTypeDescription
paramsincuvsHnswIndexParams_t

Returns

CUVS_EXPORT cuvsError_t

C API for hnswlib wrapper index

cuvsHnswIndex

Struct to hold address of cuvs::neighbors::Hnsw::index and its active trained dtype

1typedef struct { ... } cuvsHnswIndex;

Fields

NameTypeDescription
addruintptr_t
dtypeDLDataType

cuvsHnswIndexCreate

Allocate HNSW index

1CUVS_EXPORT cuvsError_t cuvsHnswIndexCreate(cuvsHnswIndex_t* index);

Parameters

NameDirectionTypeDescription
indexincuvsHnswIndex_t*cuvsHnswIndex_t to allocate

Returns

CUVS_EXPORT cuvsError_t

cuvsHnswIndexDestroy

De-allocate HNSW index

1CUVS_EXPORT cuvsError_t cuvsHnswIndexDestroy(cuvsHnswIndex_t index);

Parameters

NameDirectionTypeDescription
indexincuvsHnswIndex_tcuvsHnswIndex_t to de-allocate

Returns

CUVS_EXPORT cuvsError_t

Parameters for extending HNSW index

cuvsHnswExtendParams

Parameters for extending HNSW index

1struct cuvsHnswExtendParams { ... };

Fields

NameTypeDescription
num_threadsintNumber of CPU threads used to extend additional vectors

cuvsHnswExtendParamsCreate

Allocate HNSW extend params, and populate with default values

1CUVS_EXPORT cuvsError_t cuvsHnswExtendParamsCreate(cuvsHnswExtendParams_t* params);

Parameters

NameDirectionTypeDescription
paramsincuvsHnswExtendParams_t*cuvsHnswExtendParams_t to allocate

Returns

CUVS_EXPORT cuvsError_t

cuvsHnswExtendParamsDestroy

De-allocate HNSW extend params

1CUVS_EXPORT cuvsError_t cuvsHnswExtendParamsDestroy(cuvsHnswExtendParams_t params);

Parameters

NameDirectionTypeDescription
paramsincuvsHnswExtendParams_tcuvsHnswExtendParams_t to de-allocate

Returns

CUVS_EXPORT cuvsError_t

Load CAGRA index as hnswlib index

cuvsHnswFromCagra

Convert a CAGRA Index to an HNSW index.

1CUVS_EXPORT cuvsError_t cuvsHnswFromCagra(cuvsResources_t res,
2cuvsHnswIndexParams_t params,
3cuvsCagraIndex_t cagra_index,
4cuvsHnswIndex_t hnsw_index);

NOTE: When hierarchy is:

  1. NONE: This method uses the filesystem to write the CAGRA index in /tmp/<random_number>.bin before reading it as an hnswlib index, then deleting the temporary file. The returned index is immutable and can only be searched by the hnswlib wrapper in cuVS, as the format is not compatible with the original hnswlib.
  2. CPU: The returned index is mutable and can be extended with additional vectors. The serialized index is also compatible with the original hnswlib library.

Parameters

NameDirectionTypeDescription
resincuvsResources_tcuvsResources_t opaque C handle
paramsincuvsHnswIndexParams_tcuvsHnswIndexParams_t used to load Hnsw index
cagra_indexincuvsCagraIndex_tcuvsCagraIndex_t to convert to HNSW index
hnsw_indexoutcuvsHnswIndex_tcuvsHnswIndex_t to return the HNSW index

Returns

CUVS_EXPORT cuvsError_t

Build HNSW index using ACE algorithm

cuvsHnswBuild

Build an HNSW index using ACE (Augmented Core Extraction) algorithm.

1CUVS_EXPORT cuvsError_t cuvsHnswBuild(cuvsResources_t res,
2cuvsHnswIndexParams_t params,
3DLManagedTensor* dataset,
4cuvsHnswIndex_t index);

ACE enables building HNSW indexes for datasets too large to fit in GPU memory by:

  1. Partitioning the dataset using balanced k-means into core and augmented partitions
  2. Building sub-indexes for each partition independently
  3. Concatenating sub-graphs into a final unified index

NOTE: This function requires CUDA to be available at runtime.

Parameters

NameDirectionTypeDescription
resincuvsResources_tcuvsResources_t opaque C handle
paramsincuvsHnswIndexParams_tcuvsHnswIndexParams_t with ACE parameters configured
datasetinDLManagedTensor*DLManagedTensor* host dataset to build index from
indexoutcuvsHnswIndex_tcuvsHnswIndex_t to return the built HNSW index

Returns

CUVS_EXPORT cuvsError_t

Extend HNSW index with additional vectors

cuvsHnswExtend

Add new vectors to an HNSW index

1CUVS_EXPORT cuvsError_t cuvsHnswExtend(cuvsResources_t res,
2cuvsHnswExtendParams_t params,
3DLManagedTensor* additional_dataset,
4cuvsHnswIndex_t index);

NOTE: The HNSW index can only be extended when the hierarchy is CPU when converting from a CAGRA index.

Parameters

NameDirectionTypeDescription
resincuvsResources_tcuvsResources_t opaque C handle
paramsincuvsHnswExtendParams_tcuvsHnswExtendParams_t used to extend Hnsw index
additional_datasetinDLManagedTensor*DLManagedTensor* additional dataset to extend the index
indexinoutcuvsHnswIndex_tcuvsHnswIndex_t to extend

Returns

CUVS_EXPORT cuvsError_t

C API for hnswlib wrapper search params

cuvsHnswSearchParams

C API for hnswlib wrapper search params

1struct cuvsHnswSearchParams { ... };

Fields

NameTypeDescription
efint32_t
num_threadsint32_t

cuvsHnswSearchParamsCreate

Allocate HNSW search params, and populate with default values

1CUVS_EXPORT cuvsError_t cuvsHnswSearchParamsCreate(cuvsHnswSearchParams_t* params);

Parameters

NameDirectionTypeDescription
paramsincuvsHnswSearchParams_t*cuvsHnswSearchParams_t to allocate

Returns

CUVS_EXPORT cuvsError_t

cuvsHnswSearchParamsDestroy

De-allocate HNSW search params

1CUVS_EXPORT cuvsError_t cuvsHnswSearchParamsDestroy(cuvsHnswSearchParams_t params);

Parameters

NameDirectionTypeDescription
paramsincuvsHnswSearchParams_tcuvsHnswSearchParams_t to de-allocate

Returns

CUVS_EXPORT cuvsError_t

cuvsHnswSearch

Search a HNSW index with a DLManagedTensor which has underlying

1CUVS_EXPORT cuvsError_t cuvsHnswSearch(cuvsResources_t res,
2cuvsHnswSearchParams_t params,
3cuvsHnswIndex_t index,
4DLManagedTensor* queries,
5DLManagedTensor* neighbors,
6DLManagedTensor* distances);

DLDeviceType equal to kDLCPU, kDLCUDAHost, or kDLCUDAManaged. It is also important to note that the HNSW Index must have been built with the same type of queries, such that index.dtype.code == queries.dl_tensor.dtype.code Supported types for input are:

  1. queries: a. kDLDataType.code == kDLFloat and kDLDataType.bits = 32 b. kDLDataType.code == kDLInt and kDLDataType.bits = 8 c. kDLDataType.code == kDLUInt and kDLDataType.bits = 8
  2. neighbors: kDLDataType.code == kDLUInt and kDLDataType.bits = 64
  3. distances: kDLDataType.code == kDLFloat and kDLDataType.bits = 32 NOTE: When hierarchy is NONE, the HNSW index can only be searched by the hnswlib wrapper in cuVS, as the format is not compatible with the original hnswlib.

Parameters

NameDirectionTypeDescription
resincuvsResources_tcuvsResources_t opaque C handle
paramsincuvsHnswSearchParams_tcuvsHnswSearchParams_t used to search Hnsw index
indexincuvsHnswIndex_tcuvsHnswIndex which has been returned by cuvsHnswFromCagra
queriesinDLManagedTensor*DLManagedTensor* queries dataset to search
neighborsoutDLManagedTensor*DLManagedTensor* output k neighbors for queries
distancesoutDLManagedTensor*DLManagedTensor* output k distances for queries

Returns

CUVS_EXPORT cuvsError_t

HNSW C-API serialize functions

cuvsHnswSerialize

Serialize a CAGRA index to a file as an hnswlib index

1CUVS_EXPORT cuvsError_t cuvsHnswSerialize(cuvsResources_t res, const char* filename, cuvsHnswIndex_t index);

NOTE: When hierarchy is NONE, the saved hnswlib index is immutable and can only be read by the hnswlib wrapper in cuVS, as the serialization format is not compatible with the original hnswlib. However, when hierarchy is CPU, the saved hnswlib index is compatible with the original hnswlib library.

Parameters

NameDirectionTypeDescription
resincuvsResources_tcuvsResources_t opaque C handle
filenameinconst char*the name of the file to save the index
indexincuvsHnswIndex_tcuvsHnswIndex_t to serialize

Returns

CUVS_EXPORT cuvsError_t

cuvsHnswDeserialize

Load hnswlib index from file which was serialized from a HNSW index.

1CUVS_EXPORT cuvsError_t cuvsHnswDeserialize(cuvsResources_t res,
2cuvsHnswIndexParams_t params,
3const char* filename,
4int dim,
5cuvsDistanceType metric,
6cuvsHnswIndex_t index);

NOTE: When hierarchy is NONE, the loaded hnswlib index is immutable, and only be read by the hnswlib wrapper in cuVS, as the serialization format is not compatible with the original hnswlib. Experimental, both the API and the serialization format are subject to change.

Parameters

NameDirectionTypeDescription
resincuvsResources_tcuvsResources_t opaque C handle
paramsincuvsHnswIndexParams_tcuvsHnswIndexParams_t used to load Hnsw index
filenameinconst char*the name of the file that stores the index
diminintthe dimension of the vectors in the index
metricincuvsDistanceTypethe distance metric used to build the index
indexoutcuvsHnswIndex_tHNSW index loaded disk

Returns

CUVS_EXPORT cuvsError_t