-
Notifications
You must be signed in to change notification settings - Fork 197
IVF-SQ C API #1910
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
IVF-SQ C API #1910
Changes from all commits
Commits
Show all changes
63 commits
Select commit
Hold shift + click to select a range
75ceb6f
IVF-SQ
viclafargue cf19a86
add IVF-SQ bench constraints
viclafargue 6a95e8a
Update default IVF-SQ benchmark config
viclafargue 2d78609
Merge branch 'main' into ivf-sq
viclafargue b652160
IVF-SQ C API
viclafargue 83b8c63
Update postprocess_neighbors signature
viclafargue 1050deb
update testing
viclafargue e2a95dd
Merge branch 'main' into ivf-sq-c-api
viclafargue 928830a
Add C documentation
viclafargue 3a911d8
documentation
viclafargue b124628
memset in index constructor
viclafargue 641c6ca
random sampling
viclafargue 70ca00a
inplace residuals
viclafargue e7d660c
improved kernel layout for residuals computation
viclafargue 96b28db
raft::device_vector
viclafargue 206cb2e
drop adaptative_centers feature
viclafargue e34bdd8
Add IVF-SQ FAISS benchmark
viclafargue dcb8a59
Merge branch 'main' into ivf-sq
viclafargue 9bd7bc0
Adressing review
viclafargue 0ce1641
Addressing review
viclafargue 3694e43
Merge branch 'main' into ivf-sq
cjnolet cbe2a7e
Merge branch 'main' into ivf-sq
viclafargue 77c4a79
Fix issue with host data + half testing
viclafargue b46ea79
Update metric in doc
viclafargue 44c5f0a
Fix manage_local_topk / Capacity mismatch in IVF-SQ search
viclafargue ef957f7
Add large-k tests for IVF-SQ materialized fallback path
viclafargue 56ebfc9
Improve shared memory synchronization in IVF-SQ scan kernel
viclafargue 15b2f15
IVF-SQ scan: reduce L2 global reads and refine fused top-k capacity s…
viclafargue 3a3427f
Addressing review (tests updates)
viclafargue 7a238d3
Merge branch 'main' into ivf-sq
viclafargue 1b182d7
Swap IdxT for CodeT
viclafargue 8c44557
addressing review
viclafargue e087e19
Merge branch 'main' into ivf-sq
viclafargue d8ada75
Merge branch 'main' into ivf-sq
viclafargue 80a55fd
account for RAFT update
viclafargue ac8ea4e
IVF-SQ JIT-LTO
viclafargue 3ba5e70
Merge branch 'main' into ivf-sq
viclafargue 55a91bf
doc fix + build assert addition
viclafargue 6d5ec72
Switching to raft::TxN_t
viclafargue 1e638e5
Merge branch 'main' into ivf-sq
viclafargue 6889624
Dropping the MetricTag template parameter
viclafargue df55c51
Inner product trick
viclafargue c5948a2
Fix + minor cleanups
viclafargue 652e307
Merge branch 'main' into ivf-sq
viclafargue d2e1c62
Fix serialization vulnerabilities
viclafargue 063beb8
CUVS_EXPORT
viclafargue 0e48e20
Merge branch 'main' into ivf-sq
viclafargue d4ca8f3
Merge branch 'main' into ivf-sq
cjnolet 1d40d47
review 1/2
viclafargue 43c4f00
review 2/2
viclafargue 2e5e6ba
Drop IVF-SQ void build functions
viclafargue 78a920c
Drop IVF-SQ auto extend functions
viclafargue fb7d6f7
Merge branch 'release/26.06' into ivf-sq
viclafargue 07cca61
Merge branch 'ivf-sq' into ivf-sq-c-api
viclafargue 387b645
updates
viclafargue 2deda5d
Merge branch 'release/26.06' into ivf-sq
viclafargue 44dfa38
Docs to Fern
viclafargue f3b2572
Merge branch 'release/26.06' into ivf-sq
viclafargue f0f6ed8
Merge branch 'ivf-sq' into ivf-sq-c-api
viclafargue 8141440
Doc to fern
viclafargue f7ea1a0
Merge branch 'release/26.06' into ivf-sq-c-api
viclafargue b0cd8d8
Address review
viclafargue 9cce0c2
Merge branch 'release/26.06' into ivf-sq-c-api
viclafargue File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,346 @@ | ||
| /* | ||
| * SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION. | ||
| * SPDX-License-Identifier: Apache-2.0 | ||
| */ | ||
|
|
||
| #pragma once | ||
|
|
||
| #include <cuvs/core/c_api.h> | ||
| #include <cuvs/distance/distance.h> | ||
| #include <cuvs/neighbors/common.h> | ||
| #include <dlpack/dlpack.h> | ||
| #include <stdbool.h> | ||
| #include <stdint.h> | ||
|
|
||
| #ifdef __cplusplus | ||
| extern "C" { | ||
| #endif | ||
|
|
||
| /** | ||
| * @defgroup ivf_sq_c_index_params IVF-SQ index build parameters | ||
| * @{ | ||
| */ | ||
| /** | ||
| * @brief Supplemental parameters to build IVF-SQ Index | ||
| * | ||
| */ | ||
| struct cuvsIvfSqIndexParams { | ||
| /** Distance type. */ | ||
| cuvsDistanceType metric; | ||
| /** The argument used by some distance metrics. */ | ||
| float metric_arg; | ||
| /** | ||
| * Whether to add the dataset content to the index, i.e.: | ||
| * | ||
| * - `true` means the index is filled with the dataset vectors and ready to search after calling | ||
| * `build`. | ||
| * - `false` means `build` only trains the underlying model (e.g. quantizer or clustering), but | ||
| * the index is left empty; you'd need to call `extend` on the index afterwards to populate it. | ||
| */ | ||
| bool add_data_on_build; | ||
| /** The number of inverted lists (clusters) */ | ||
| uint32_t n_lists; | ||
| /** The number of iterations searching for kmeans centers (index building). */ | ||
| uint32_t kmeans_n_iters; | ||
| /** | ||
| * The number of data vectors per cluster to use during iterative kmeans building. | ||
| * The index uses at most `n_lists * max_train_points_per_cluster` rows for training. | ||
| */ | ||
| uint32_t max_train_points_per_cluster; | ||
| /** | ||
| * By default, the algorithm allocates more space than necessary for individual clusters | ||
| * (`list_data`). This allows to amortize the cost of memory allocation and reduce the number of | ||
| * data copies during repeated calls to `extend` (extending the database). | ||
| * | ||
| * The alternative is the conservative allocation behavior; when enabled, the algorithm always | ||
| * allocates the minimum amount of memory required to store the given number of records. Set this | ||
| * flag to `true` if you prefer to use as little GPU memory for the database as possible. | ||
| */ | ||
| bool conservative_memory_allocation; | ||
| }; | ||
|
|
||
| typedef struct cuvsIvfSqIndexParams* cuvsIvfSqIndexParams_t; | ||
|
|
||
| /** | ||
| * @brief Allocate IVF-SQ Index params, and populate with default values | ||
| * | ||
| * @param[in] index_params cuvsIvfSqIndexParams_t to allocate | ||
| * @return cuvsError_t | ||
| */ | ||
| CUVS_EXPORT cuvsError_t cuvsIvfSqIndexParamsCreate(cuvsIvfSqIndexParams_t* index_params); | ||
|
|
||
| /** | ||
| * @brief De-allocate IVF-SQ Index params | ||
| * | ||
| * @param[in] index_params | ||
| * @return cuvsError_t | ||
| */ | ||
| CUVS_EXPORT cuvsError_t cuvsIvfSqIndexParamsDestroy(cuvsIvfSqIndexParams_t index_params); | ||
| /** | ||
| * @} | ||
| */ | ||
|
|
||
| /** | ||
| * @defgroup ivf_sq_c_search_params IVF-SQ index search parameters | ||
| * @{ | ||
| */ | ||
| /** | ||
| * @brief Supplemental parameters to search IVF-SQ index | ||
| * | ||
| */ | ||
| struct cuvsIvfSqSearchParams { | ||
| /** The number of clusters to search. */ | ||
| uint32_t n_probes; | ||
| }; | ||
|
|
||
| typedef struct cuvsIvfSqSearchParams* cuvsIvfSqSearchParams_t; | ||
|
|
||
| /** | ||
| * @brief Allocate IVF-SQ search params, and populate with default values | ||
| * | ||
| * @param[in] params cuvsIvfSqSearchParams_t to allocate | ||
| * @return cuvsError_t | ||
| */ | ||
| CUVS_EXPORT cuvsError_t cuvsIvfSqSearchParamsCreate(cuvsIvfSqSearchParams_t* params); | ||
|
|
||
| /** | ||
| * @brief De-allocate IVF-SQ search params | ||
| * | ||
| * @param[in] params | ||
| * @return cuvsError_t | ||
| */ | ||
| CUVS_EXPORT cuvsError_t cuvsIvfSqSearchParamsDestroy(cuvsIvfSqSearchParams_t params); | ||
| /** | ||
| * @} | ||
| */ | ||
|
|
||
| /** | ||
| * @defgroup ivf_sq_c_index IVF-SQ index | ||
| * @{ | ||
| */ | ||
| /** | ||
| * @brief Struct to hold address of cuvs::neighbors::ivf_sq::index and its active trained dtype | ||
| * | ||
| */ | ||
| typedef struct { | ||
| uintptr_t addr; | ||
| DLDataType dtype; | ||
| } cuvsIvfSqIndex; | ||
|
|
||
| typedef cuvsIvfSqIndex* cuvsIvfSqIndex_t; | ||
|
|
||
| /** | ||
| * @brief Allocate IVF-SQ index | ||
| * | ||
| * @param[in] index cuvsIvfSqIndex_t to allocate | ||
| * @return cuvsError_t | ||
| */ | ||
| CUVS_EXPORT cuvsError_t cuvsIvfSqIndexCreate(cuvsIvfSqIndex_t* index); | ||
|
|
||
| /** | ||
| * @brief De-allocate IVF-SQ index | ||
| * | ||
| * @param[in] index cuvsIvfSqIndex_t to de-allocate | ||
| */ | ||
| CUVS_EXPORT cuvsError_t cuvsIvfSqIndexDestroy(cuvsIvfSqIndex_t index); | ||
|
|
||
| /** Get the number of clusters/inverted lists */ | ||
| CUVS_EXPORT cuvsError_t cuvsIvfSqIndexGetNLists(cuvsIvfSqIndex_t index, int64_t* n_lists); | ||
|
|
||
| /** Get the dimensionality of the data */ | ||
| CUVS_EXPORT cuvsError_t cuvsIvfSqIndexGetDim(cuvsIvfSqIndex_t index, int64_t* dim); | ||
|
|
||
| /** Get the size of the index */ | ||
| CUVS_EXPORT cuvsError_t cuvsIvfSqIndexGetSize(cuvsIvfSqIndex_t index, int64_t* size); | ||
|
|
||
| /** | ||
| * @brief Get the cluster centers corresponding to the lists [n_lists, dim] | ||
| * | ||
| * @param[in] index cuvsIvfSqIndex_t Built Ivf-SQ Index | ||
| * @param[out] centers Preallocated array on host or device memory to store output, [n_lists, dim] | ||
| * @return cuvsError_t | ||
| */ | ||
| CUVS_EXPORT cuvsError_t cuvsIvfSqIndexGetCenters(cuvsIvfSqIndex_t index, DLManagedTensor* centers); | ||
|
|
||
| /** | ||
| * @} | ||
| */ | ||
|
|
||
| /** | ||
| * @defgroup ivf_sq_c_index_build IVF-SQ index build | ||
| * @{ | ||
| */ | ||
| /** | ||
| * @brief Build an IVF-SQ index with a `DLManagedTensor` which has underlying | ||
| * `DLDeviceType` equal to `kDLCUDA`, `kDLCUDAHost`, `kDLCUDAManaged`, | ||
| * or `kDLCPU`. Also, acceptable underlying types are: | ||
| * 1. `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 32` | ||
| * 2. `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 16` | ||
| * | ||
| * @code {.c} | ||
| * #include <cuvs/core/c_api.h> | ||
| * #include <cuvs/neighbors/ivf_sq.h> | ||
| * | ||
| * // Create cuvsResources_t | ||
| * cuvsResources_t res; | ||
| * cuvsError_t res_create_status = cuvsResourcesCreate(&res); | ||
| * | ||
| * // Assume a populated `DLManagedTensor` type here | ||
| * DLManagedTensor dataset; | ||
| * | ||
| * // Create default index params | ||
| * cuvsIvfSqIndexParams_t index_params; | ||
| * cuvsError_t params_create_status = cuvsIvfSqIndexParamsCreate(&index_params); | ||
| * | ||
| * // Create IVF-SQ index | ||
| * cuvsIvfSqIndex_t index; | ||
| * cuvsError_t index_create_status = cuvsIvfSqIndexCreate(&index); | ||
| * | ||
| * // Build the IVF-SQ Index | ||
| * cuvsError_t build_status = cuvsIvfSqBuild(res, index_params, &dataset, index); | ||
| * | ||
| * // de-allocate `index_params`, `index` and `res` | ||
| * cuvsError_t params_destroy_status = cuvsIvfSqIndexParamsDestroy(index_params); | ||
| * cuvsError_t index_destroy_status = cuvsIvfSqIndexDestroy(index); | ||
| * cuvsError_t res_destroy_status = cuvsResourcesDestroy(res); | ||
| * @endcode | ||
| * | ||
| * @param[in] res cuvsResources_t opaque C handle | ||
| * @param[in] index_params cuvsIvfSqIndexParams_t used to build IVF-SQ index | ||
| * @param[in] dataset DLManagedTensor* training dataset | ||
| * @param[out] index cuvsIvfSqIndex_t Newly built IVF-SQ index | ||
| * @return cuvsError_t | ||
| */ | ||
| CUVS_EXPORT cuvsError_t cuvsIvfSqBuild(cuvsResources_t res, | ||
| cuvsIvfSqIndexParams_t index_params, | ||
| DLManagedTensor* dataset, | ||
| cuvsIvfSqIndex_t index); | ||
| /** | ||
| * @} | ||
| */ | ||
|
|
||
| /** | ||
| * @defgroup ivf_sq_c_index_search IVF-SQ index search | ||
| * @{ | ||
| */ | ||
| /** | ||
| * @brief Search an IVF-SQ index with a `DLManagedTensor` which has underlying | ||
| * `DLDeviceType` equal to `kDLCUDA`, `kDLCUDAHost`, `kDLCUDAManaged`. | ||
| * Types for input are: | ||
| * 1. `queries`: `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 32` or 16 | ||
| * 2. `neighbors`: `kDLDataType.code == kDLInt` and `kDLDataType.bits = 64` | ||
| * 3. `distances`: `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 32` | ||
| * | ||
| * @code {.c} | ||
| * #include <cuvs/core/c_api.h> | ||
| * #include <cuvs/neighbors/ivf_sq.h> | ||
| * | ||
| * // Create cuvsResources_t | ||
| * cuvsResources_t res; | ||
| * cuvsError_t res_create_status = cuvsResourcesCreate(&res); | ||
| * | ||
| * // Assume a populated `DLManagedTensor` type here | ||
| * DLManagedTensor queries; | ||
| * DLManagedTensor neighbors; | ||
| * DLManagedTensor distances; | ||
| * | ||
| * // Create default search params | ||
| * cuvsIvfSqSearchParams_t search_params; | ||
| * cuvsError_t params_create_status = cuvsIvfSqSearchParamsCreate(&search_params); | ||
| * | ||
| * // Search the `index` built using `cuvsIvfSqBuild` | ||
| * cuvsError_t search_status = cuvsIvfSqSearch( | ||
| * res, search_params, index, &queries, &neighbors, &distances, (cuvsFilter){}); | ||
| * | ||
| * // de-allocate `search_params` and `res` | ||
| * cuvsError_t params_destroy_status = cuvsIvfSqSearchParamsDestroy(search_params); | ||
| * cuvsError_t res_destroy_status = cuvsResourcesDestroy(res); | ||
| * @endcode | ||
| * | ||
| * @param[in] res cuvsResources_t opaque C handle | ||
| * @param[in] search_params cuvsIvfSqSearchParams_t used to search IVF-SQ index | ||
| * @param[in] index ivfSqIndex which has been returned by `cuvsIvfSqBuild` | ||
| * @param[in] queries DLManagedTensor* queries dataset to search | ||
| * @param[out] neighbors DLManagedTensor* output `k` neighbors for queries | ||
| * @param[out] distances DLManagedTensor* output `k` distances for queries | ||
| * @param[in] filter cuvsFilter input filter that can be used | ||
| * to filter queries and neighbors based on the given bitset. | ||
| */ | ||
| CUVS_EXPORT cuvsError_t cuvsIvfSqSearch(cuvsResources_t res, | ||
| cuvsIvfSqSearchParams_t search_params, | ||
| cuvsIvfSqIndex_t index, | ||
| DLManagedTensor* queries, | ||
| DLManagedTensor* neighbors, | ||
| DLManagedTensor* distances, | ||
| cuvsFilter filter); | ||
|
|
||
| /** | ||
| * @} | ||
| */ | ||
|
|
||
| /** | ||
| * @defgroup ivf_sq_c_index_serialize IVF-SQ C-API serialize functions | ||
| * @{ | ||
| */ | ||
| /** | ||
| * Save the index to file. | ||
| * | ||
| * Experimental, both the API and the serialization format are subject to change. | ||
| * | ||
| * @code{.c} | ||
| * #include <cuvs/neighbors/ivf_sq.h> | ||
| * | ||
| * // Create cuvsResources_t | ||
| * cuvsResources_t res; | ||
| * cuvsError_t res_create_status = cuvsResourcesCreate(&res); | ||
| * | ||
| * // create an index with `cuvsIvfSqBuild` | ||
| * cuvsIvfSqSerialize(res, "/path/to/index", index); | ||
| * @endcode | ||
| * | ||
| * @param[in] res cuvsResources_t opaque C handle | ||
| * @param[in] filename the file name for saving the index | ||
| * @param[in] index IVF-SQ index | ||
| */ | ||
| CUVS_EXPORT cuvsError_t cuvsIvfSqSerialize(cuvsResources_t res, const char* filename, cuvsIvfSqIndex_t index); | ||
|
|
||
| /** | ||
| * Load index from file. | ||
| * | ||
| * Experimental, both the API and the serialization format are subject to change. | ||
| * | ||
| * @param[in] res cuvsResources_t opaque C handle | ||
| * @param[in] filename the name of the file that stores the index | ||
| * @param[out] index IVF-SQ index loaded from disk | ||
| */ | ||
| CUVS_EXPORT cuvsError_t cuvsIvfSqDeserialize(cuvsResources_t res, | ||
| const char* filename, | ||
| cuvsIvfSqIndex_t index); | ||
| /** | ||
| * @} | ||
| */ | ||
|
|
||
| /** | ||
| * @defgroup ivf_sq_c_index_extend IVF-SQ index extend | ||
| * @{ | ||
| */ | ||
| /** | ||
| * @brief Extend the index with the new data. | ||
| * | ||
| * @param[in] res cuvsResources_t opaque C handle | ||
| * @param[in] new_vectors DLManagedTensor* the new vectors to add to the index | ||
| * @param[in] new_indices DLManagedTensor* vector of new indices for the new vectors. If the index | ||
| * is empty, this can be NULL to imply a continuous range `[0...n_rows)`. | ||
| * @param[inout] index IVF-SQ index to be extended | ||
| * @return cuvsError_t | ||
| */ | ||
| CUVS_EXPORT cuvsError_t cuvsIvfSqExtend(cuvsResources_t res, | ||
| DLManagedTensor* new_vectors, | ||
| DLManagedTensor* new_indices, | ||
| cuvsIvfSqIndex_t index); | ||
| /** | ||
| * @} | ||
| */ | ||
| #ifdef __cplusplus | ||
| } | ||
| #endif | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win
Complete Doxygen docs for all exported functions.
A few public APIs still use partial docs (e.g., getters and serialize/deserialize). Please add full Doxygen entries with params, return value, and side effects/errors for consistency across the public C surface.
As per coding guidelines, “For public C API headers, additionally check: Doxygen documentation for all public functions/classes”.
Also applies to: 323-336
🤖 Prompt for AI Agents