Skip to main content

cuvs_sys/
bindings.rs

1/* automatically generated by rust-bindgen 0.73.2 */
2
3use crate::{cudaDataType_t, cudaStream_t};
4
5#[repr(u32)]
6#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
7pub enum DLDeviceType {
8    #[doc = " \\brief CPU device"]
9    kDLCPU = 1,
10    #[doc = " \\brief CUDA GPU device"]
11    kDLCUDA = 2,
12    #[doc = " \\brief Pinned CUDA CPU memory by cudaMallocHost"]
13    kDLCUDAHost = 3,
14    #[doc = " \\brief OpenCL devices."]
15    kDLOpenCL = 4,
16    #[doc = " \\brief Vulkan buffer for next generation graphics."]
17    kDLVulkan = 7,
18    #[doc = " \\brief Metal for Apple GPU."]
19    kDLMetal = 8,
20    #[doc = " \\brief Verilog simulator buffer"]
21    kDLVPI = 9,
22    #[doc = " \\brief ROCm GPUs for AMD GPUs"]
23    kDLROCM = 10,
24    #[doc = " \\brief Pinned ROCm CPU memory allocated by hipMallocHost"]
25    kDLROCMHost = 11,
26    #[doc = " \\brief Reserved extension device type,\n used for quickly test extension device\n The semantics can differ depending on the implementation."]
27    kDLExtDev = 12,
28    #[doc = " \\brief CUDA managed/unified memory allocated by cudaMallocManaged"]
29    kDLCUDAManaged = 13,
30    #[doc = " \\brief Unified shared memory allocated on a oneAPI non-partititioned\n device. Call to oneAPI runtime is required to determine the device\n type, the USM allocation type and the sycl context it is bound to.\n"]
31    kDLOneAPI = 14,
32    #[doc = " \\brief GPU support for next generation WebGPU standard."]
33    kDLWebGPU = 15,
34    #[doc = " \\brief Qualcomm Hexagon DSP"]
35    kDLHexagon = 16,
36}
37#[doc = " \\brief A Device for Tensor and operator."]
38#[repr(C)]
39#[derive(Debug, Copy, Clone)]
40pub struct DLDevice {
41    #[doc = " \\brief The device type used in the device."]
42    pub device_type: DLDeviceType,
43    #[doc = " \\brief The device index.\n For vanilla CPU memory, pinned memory, or managed memory, this is set to 0."]
44    pub device_id: i32,
45}
46#[allow(clippy::unnecessary_operation, clippy::identity_op)]
47const _: () = {
48    ["Size of DLDevice"][::std::mem::size_of::<DLDevice>() - 8usize];
49    ["Alignment of DLDevice"][::std::mem::align_of::<DLDevice>() - 4usize];
50    ["Offset of field: DLDevice::device_type"][::std::mem::offset_of!(DLDevice, device_type) - 0usize];
51    ["Offset of field: DLDevice::device_id"][::std::mem::offset_of!(DLDevice, device_id) - 4usize];
52};
53#[repr(u32)]
54#[doc = " \\brief The type code options DLDataType."]
55#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
56pub enum DLDataTypeCode {
57    #[doc = " \\brief signed integer"]
58    kDLInt = 0,
59    #[doc = " \\brief unsigned integer"]
60    kDLUInt = 1,
61    #[doc = " \\brief IEEE floating point"]
62    kDLFloat = 2,
63    #[doc = " \\brief Opaque handle type, reserved for testing purposes.\n Frameworks need to agree on the handle data type for the exchange to be well-defined."]
64    kDLOpaqueHandle = 3,
65    #[doc = " \\brief bfloat16"]
66    kDLBfloat = 4,
67    #[doc = " \\brief complex number\n (C/C++/Python layout: compact struct per complex number)"]
68    kDLComplex = 5,
69    #[doc = " \\brief boolean"]
70    kDLBool = 6,
71}
72#[doc = " \\brief The data type the tensor can hold. The data type is assumed to follow the\n native endian-ness. An explicit error message should be raised when attempting to\n export an array with non-native endianness\n\n  Examples\n   - float: type_code = 2, bits = 32, lanes = 1\n   - float4(vectorized 4 float): type_code = 2, bits = 32, lanes = 4\n   - int8: type_code = 0, bits = 8, lanes = 1\n   - std::complex<float>: type_code = 5, bits = 64, lanes = 1\n   - bool: type_code = 6, bits = 8, lanes = 1 (as per common array library convention, the underlying storage size of bool is 8 bits)"]
73#[repr(C)]
74#[derive(Debug, Copy, Clone)]
75pub struct DLDataType {
76    #[doc = " \\brief Type code of base types.\n We keep it uint8_t instead of DLDataTypeCode for minimal memory\n footprint, but the value should be one of DLDataTypeCode enum values."]
77    pub code: u8,
78    #[doc = " \\brief Number of bits, common choices are 8, 16, 32."]
79    pub bits: u8,
80    #[doc = " \\brief Number of lanes in the type, used for vector types."]
81    pub lanes: u16,
82}
83#[allow(clippy::unnecessary_operation, clippy::identity_op)]
84const _: () = {
85    ["Size of DLDataType"][::std::mem::size_of::<DLDataType>() - 4usize];
86    ["Alignment of DLDataType"][::std::mem::align_of::<DLDataType>() - 2usize];
87    ["Offset of field: DLDataType::code"][::std::mem::offset_of!(DLDataType, code) - 0usize];
88    ["Offset of field: DLDataType::bits"][::std::mem::offset_of!(DLDataType, bits) - 1usize];
89    ["Offset of field: DLDataType::lanes"][::std::mem::offset_of!(DLDataType, lanes) - 2usize];
90};
91#[doc = " \\brief Plain C Tensor object, does not manage memory."]
92#[repr(C)]
93#[derive(Debug, Copy, Clone)]
94pub struct DLTensor {
95    #[doc = " \\brief The data pointer points to the allocated data. This will be CUDA\n device pointer or cl_mem handle in OpenCL. It may be opaque on some device\n types. This pointer is always aligned to 256 bytes as in CUDA. The\n `byte_offset` field should be used to point to the beginning of the data.\n\n Note that as of Nov 2021, multiply libraries (CuPy, PyTorch, TensorFlow,\n TVM, perhaps others) do not adhere to this 256 byte aligment requirement\n on CPU/CUDA/ROCm, and always use `byte_offset=0`.  This must be fixed\n (after which this note will be updated); at the moment it is recommended\n to not rely on the data pointer being correctly aligned.\n\n For given DLTensor, the size of memory required to store the contents of\n data is calculated as follows:\n\n \\code{.c}\n static inline size_t GetDataSize(const DLTensor* t) {\n   size_t size = 1;\n   for (tvm_index_t i = 0; i < t->ndim; ++i) {\n     size *= t->shape[i];\n   }\n   size *= (t->dtype.bits * t->dtype.lanes + 7) / 8;\n   return size;\n }\n \\endcode"]
96    pub data: *mut ::std::os::raw::c_void,
97    #[doc = " \\brief The device of the tensor"]
98    pub device: DLDevice,
99    #[doc = " \\brief Number of dimensions"]
100    pub ndim: i32,
101    #[doc = " \\brief The data type of the pointer"]
102    pub dtype: DLDataType,
103    #[doc = " \\brief The shape of the tensor"]
104    pub shape: *mut i64,
105    #[doc = " \\brief strides of the tensor (in number of elements, not bytes)\n  can be NULL, indicating tensor is compact and row-majored."]
106    pub strides: *mut i64,
107    #[doc = " \\brief The offset in bytes to the beginning pointer to data"]
108    pub byte_offset: u64,
109}
110#[allow(clippy::unnecessary_operation, clippy::identity_op)]
111const _: () = {
112    ["Size of DLTensor"][::std::mem::size_of::<DLTensor>() - 48usize];
113    ["Alignment of DLTensor"][::std::mem::align_of::<DLTensor>() - 8usize];
114    ["Offset of field: DLTensor::data"][::std::mem::offset_of!(DLTensor, data) - 0usize];
115    ["Offset of field: DLTensor::device"][::std::mem::offset_of!(DLTensor, device) - 8usize];
116    ["Offset of field: DLTensor::ndim"][::std::mem::offset_of!(DLTensor, ndim) - 16usize];
117    ["Offset of field: DLTensor::dtype"][::std::mem::offset_of!(DLTensor, dtype) - 20usize];
118    ["Offset of field: DLTensor::shape"][::std::mem::offset_of!(DLTensor, shape) - 24usize];
119    ["Offset of field: DLTensor::strides"][::std::mem::offset_of!(DLTensor, strides) - 32usize];
120    ["Offset of field: DLTensor::byte_offset"][::std::mem::offset_of!(DLTensor, byte_offset) - 40usize];
121};
122#[doc = " \\brief C Tensor object, manage memory of DLTensor. This data structure is\n  intended to facilitate the borrowing of DLTensor by another framework. It is\n  not meant to transfer the tensor. When the borrowing framework doesn't need\n  the tensor, it should call the deleter to notify the host that the resource\n  is no longer needed."]
123#[repr(C)]
124#[derive(Debug, Copy, Clone)]
125pub struct DLManagedTensor {
126    #[doc = " \\brief DLTensor which is being memory managed"]
127    pub dl_tensor: DLTensor,
128    #[doc = " \\brief the context of the original host framework of DLManagedTensor in\n   which DLManagedTensor is used in the framework. It can also be NULL."]
129    pub manager_ctx: *mut ::std::os::raw::c_void,
130    #[doc = " \\brief Destructor signature void (*)(void*) - this should be called\n   to destruct manager_ctx which holds the DLManagedTensor. It can be NULL\n   if there is no way for the caller to provide a reasonable destructor.\n   The destructors deletes the argument self as well."]
131    pub deleter: ::std::option::Option<unsafe extern "C" fn(self_: *mut DLManagedTensor)>,
132}
133#[allow(clippy::unnecessary_operation, clippy::identity_op)]
134const _: () = {
135    ["Size of DLManagedTensor"][::std::mem::size_of::<DLManagedTensor>() - 64usize];
136    ["Alignment of DLManagedTensor"][::std::mem::align_of::<DLManagedTensor>() - 8usize];
137    ["Offset of field: DLManagedTensor::dl_tensor"][::std::mem::offset_of!(DLManagedTensor, dl_tensor) - 0usize];
138    ["Offset of field: DLManagedTensor::manager_ctx"][::std::mem::offset_of!(DLManagedTensor, manager_ctx) - 48usize];
139    ["Offset of field: DLManagedTensor::deleter"][::std::mem::offset_of!(DLManagedTensor, deleter) - 56usize];
140};
141#[repr(u32)]
142#[doc = " @defgroup error_c cuVS Error Messages\n @{\n/\n/**\n @brief An enum denoting error statuses for function calls\n"]
143#[must_use]
144#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
145pub enum cuvsError_t {
146    CUVS_ERROR = 0,
147    CUVS_SUCCESS = 1,
148}
149#[repr(u32)]
150#[doc = " @brief The kind of error from a C API call that passed through the exception boundary."]
151#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
152pub enum cuvsErrorKind_t {
153    CUVS_ERROR_KIND_NONE = 0,
154    CUVS_ERROR_KIND_UNKNOWN = 1,
155    CUVS_ERROR_KIND_DEVICE_OUT_OF_MEMORY = 2,
156    CUVS_ERROR_KIND_HOST_OUT_OF_MEMORY = 3,
157}
158unsafe extern "C" {
159    #[doc = " @brief Returns the calling thread's error kind for the most recent C API call that\n         passed through the exception boundary. Returns CUVS_ERROR_KIND_NONE after success."]
160    pub fn cuvsGetLastErrorKind() -> cuvsErrorKind_t;
161}
162unsafe extern "C" {
163    #[doc = " @brief Returns a string describing the last seen error on this thread, or\n         NULL if the last function succeeded."]
164    pub fn cuvsGetLastErrorText() -> *const ::std::os::raw::c_char;
165}
166unsafe extern "C" {
167    #[doc = " @brief Sets a string describing an error seen on the thread. Passing NULL\n        clears any previously seen error message."]
168    pub fn cuvsSetLastErrorText(error: *const ::std::os::raw::c_char);
169}
170#[repr(u32)]
171#[doc = " @brief An enum denoting log levels\n"]
172#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
173pub enum cuvsLogLevel_t {
174    CUVS_LOG_LEVEL_TRACE = 0,
175    CUVS_LOG_LEVEL_DEBUG = 1,
176    CUVS_LOG_LEVEL_INFO = 2,
177    CUVS_LOG_LEVEL_WARN = 3,
178    CUVS_LOG_LEVEL_ERROR = 4,
179    CUVS_LOG_LEVEL_CRITICAL = 5,
180    CUVS_LOG_LEVEL_OFF = 6,
181}
182unsafe extern "C" {
183    #[doc = " @brief Returns the current log level"]
184    pub fn cuvsGetLogLevel() -> cuvsLogLevel_t;
185}
186unsafe extern "C" {
187    #[doc = " @brief Sets the log level"]
188    pub fn cuvsSetLogLevel(arg1: cuvsLogLevel_t);
189}
190#[doc = " @brief An opaque C handle for C++ type `raft::resources`\n"]
191pub type cuvsResources_t = usize;
192unsafe extern "C" {
193    #[must_use]
194    #[doc = " @brief Create an Initialized opaque C handle for C++ type `raft::resources`\n\n @param[in] res cuvsResources_t opaque C handle\n @return cuvsError_t"]
195    pub fn cuvsResourcesCreate(res: *mut cuvsResources_t) -> cuvsError_t;
196}
197unsafe extern "C" {
198    #[must_use]
199    #[doc = " @brief Create an opaque C handle for C++ type `raft::resources` whose memory\n        allocations are tracked and written as CSV samples from a background\n        thread.\n\n The returned handle wraps all reachable memory resources (host, pinned,\n managed, device, workspace, large_workspace) with allocation-tracking\n adaptors and replaces the global host and device memory resources for the\n lifetime of the handle. It is otherwise indistinguishable from a handle\n created by ::cuvsResourcesCreate and can be used wherever a\n ::cuvsResources_t is accepted. The CSV reporter is stopped and the global\n memory resources are restored when the handle is destroyed via\n ::cuvsResourcesDestroy.\n\n @param[out] res                 cuvsResources_t opaque C handle\n @param[in]  csv_path            Path to the output CSV file\n                                 (created/truncated). Must be a non-empty,\n                                 null-terminated UTF-8 string.\n @param[in]  sample_interval_ms  Minimum time in milliseconds between\n                                 successive CSV samples. Pass 10 to match the\n                                 C++ default.\n @return cuvsError_t"]
200    pub fn cuvsResourcesCreateWithMemoryTracking(
201        res: *mut cuvsResources_t,
202        csv_path: *const ::std::os::raw::c_char,
203        sample_interval_ms: i64,
204    ) -> cuvsError_t;
205}
206unsafe extern "C" {
207    #[must_use]
208    #[doc = " @brief Destroy and de-allocate opaque C handle for C++ type `raft::resources`\n\n @param[in] res cuvsResources_t opaque C handle\n @return cuvsError_t"]
209    pub fn cuvsResourcesDestroy(res: cuvsResources_t) -> cuvsError_t;
210}
211unsafe extern "C" {
212    #[must_use]
213    #[doc = " @brief Set cudaStream_t on cuvsResources_t to queue CUDA kernels on APIs\n        that accept a cuvsResources_t handle\n\n @param[in] res cuvsResources_t opaque C handle\n @param[in] stream cudaStream_t stream to queue CUDA kernels\n @return cuvsError_t"]
214    pub fn cuvsStreamSet(res: cuvsResources_t, stream: cudaStream_t) -> cuvsError_t;
215}
216unsafe extern "C" {
217    #[must_use]
218    #[doc = " @brief Get the cudaStream_t from a cuvsResources_t\n\n @param[in] res cuvsResources_t opaque C handle\n @param[out] stream cudaStream_t stream to queue CUDA kernels\n @return cuvsError_t"]
219    pub fn cuvsStreamGet(res: cuvsResources_t, stream: *mut cudaStream_t) -> cuvsError_t;
220}
221unsafe extern "C" {
222    #[must_use]
223    #[doc = " @brief Syncs the current CUDA stream on the resources object\n\n @param[in] res cuvsResources_t opaque C handle\n @return cuvsError_t"]
224    pub fn cuvsStreamSync(res: cuvsResources_t) -> cuvsError_t;
225}
226unsafe extern "C" {
227    #[must_use]
228    #[doc = " @brief Get the id of the device associated with this cuvsResources_t\n\n @param[in] res cuvsResources_t opaque C handle\n @param[out] device_id int the id of the device associated with res\n @return cuvsError_t"]
229    pub fn cuvsDeviceIdGet(res: cuvsResources_t, device_id: *mut ::std::os::raw::c_int) -> cuvsError_t;
230}
231unsafe extern "C" {
232    #[must_use]
233    #[doc = " @brief Configure the temporary workspace on this resources object as an uncapped pool, backed\n        by the current device memory resource. After the initial reservation is allocated on\n        first use, subsequent calls to cuvsRMMAlloc / cuvsRMMFree on the same resources handle\n        hit the pool cache rather than calling cudaMallocAsync / cudaFreeAsync, reducing CUDA\n        context lock contention under concurrent query threads. The pool grows without shrinking:\n        freed allocations are returned to the pool rather than to the device, so the pool's\n        high-water mark only increases until the resources object is destroyed.\n\n @param[in] res                cuvsResources_t opaque C handle\n @param[in] initial_size_bytes initial pool reservation in bytes; size to cover the\n                               steady-state working set to avoid growth after warmup\n @return cuvsError_t"]
234    pub fn cuvsResourcesSetWorkspacePool(res: cuvsResources_t, initial_size_bytes: usize) -> cuvsError_t;
235}
236unsafe extern "C" {
237    #[must_use]
238    #[doc = " @brief Install a RAFT CUDA stream pool on a resources handle, replacing any existing pool.\n\n The pool owns its streams for the lifetime of res or until the pool is replaced. RAFT\n algorithms may issue work and device allocations on these streams. Synchronize work and\n retire any external stream attachments before replacing the pool or destroying res.\n\n @param[in] res cuvsResources_t opaque C handle\n @param[in] pool_size Number of streams to create; must be at least 1\n @return cuvsError_t"]
239    pub fn cuvsResourcesSetStreamPool(res: cuvsResources_t, pool_size: usize) -> cuvsError_t;
240}
241unsafe extern "C" {
242    #[must_use]
243    #[doc = " @brief Get the number of streams in a resources handle's RAFT CUDA stream pool.\n\n @param[in] res cuvsResources_t opaque C handle\n @param[out] pool_size Pool size, or 0 if no pool is installed\n @return cuvsError_t"]
244    pub fn cuvsResourcesGetStreamPoolSize(res: cuvsResources_t, pool_size: *mut usize) -> cuvsError_t;
245}
246unsafe extern "C" {
247    #[must_use]
248    #[doc = " @brief Borrow a CUDA stream from a resources handle's RAFT CUDA stream pool.\n\n The pool owns the returned stream for the lifetime of res or until the pool is replaced.\n RAFT algorithms may issue work and device allocations on it. Index must be less than the\n pool size reported by ::cuvsResourcesGetStreamPoolSize.\n\n @param[in] res cuvsResources_t opaque C handle\n @param[in] index Zero-based pool stream index\n @param[out] stream Borrowed CUDA stream\n @return cuvsError_t"]
249    pub fn cuvsResourcesGetStreamPoolStream(
250        res: cuvsResources_t,
251        index: usize,
252        stream: *mut cudaStream_t,
253    ) -> cuvsError_t;
254}
255unsafe extern "C" {
256    #[must_use]
257    #[doc = " @brief Create an Initialized opaque C handle for C++ type `raft::device_resources_snmg`\n        for multi-GPU operations\n\n @param[in] res cuvsResources_t opaque C handle\n @return cuvsError_t"]
258    pub fn cuvsMultiGpuResourcesCreate(res: *mut cuvsResources_t) -> cuvsError_t;
259}
260unsafe extern "C" {
261    #[must_use]
262    #[doc = " @brief Create an Initialized opaque C handle for C++ type `raft::device_resources_snmg`\n        for multi-GPU operations with specific device IDs\n\n @param[in] res cuvsResources_t opaque C handle\n @param[in] device_ids DLManagedTensor* containing device IDs to use\n @return cuvsError_t"]
263    pub fn cuvsMultiGpuResourcesCreateWithDeviceIds(
264        res: *mut cuvsResources_t,
265        device_ids: *mut DLManagedTensor,
266    ) -> cuvsError_t;
267}
268unsafe extern "C" {
269    #[must_use]
270    #[doc = " @brief Destroy and de-allocate opaque C handle for C++ type `raft::device_resources_snmg`\n\n @param[in] res cuvsResources_t opaque C handle\n @return cuvsError_t"]
271    pub fn cuvsMultiGpuResourcesDestroy(res: cuvsResources_t) -> cuvsError_t;
272}
273unsafe extern "C" {
274    #[must_use]
275    #[doc = " @brief Set a memory pool on all devices managed by the multi-GPU resources\n\n @param[in] res cuvsResources_t opaque C handle for multi-GPU resources\n @param[in] percent_of_free_memory Percent of free memory to allocate for the pool\n @return cuvsError_t"]
276    pub fn cuvsMultiGpuResourcesSetMemoryPool(
277        res: cuvsResources_t,
278        percent_of_free_memory: ::std::os::raw::c_int,
279    ) -> cuvsError_t;
280}
281unsafe extern "C" {
282    #[must_use]
283    #[doc = " @brief Allocates device memory using RMM\n\n\n @param[in] res cuvsResources_t opaque C handle\n @param[out] ptr Pointer to allocated device memory\n @param[in] bytes Size in bytes to allocate\n @return cuvsError_t"]
284    pub fn cuvsRMMAlloc(res: cuvsResources_t, ptr: *mut *mut ::std::os::raw::c_void, bytes: usize) -> cuvsError_t;
285}
286unsafe extern "C" {
287    #[must_use]
288    #[doc = " @brief Deallocates device memory using RMM\n\n @param[in] res cuvsResources_t opaque C handle\n @param[in] ptr Pointer to allocated device memory to free\n @param[in] bytes Size in bytes to allocate\n @return cuvsError_t"]
289    pub fn cuvsRMMFree(res: cuvsResources_t, ptr: *mut ::std::os::raw::c_void, bytes: usize) -> cuvsError_t;
290}
291unsafe extern "C" {
292    #[must_use]
293    #[doc = " @brief Switches the working memory resource to use the RMM pool memory resource, which will\n bypass unnecessary synchronizations by allocating a chunk of device memory up front and carving\n that up for temporary memory allocations within algorithms. Be aware that this function will\n change the memory resource for the whole process and the new memory resource will be used until\n explicitly changed.\n\n @param[in] initial_pool_size_percent The initial pool size as a percentage of the total\n available memory\n @param[in] max_pool_size_percent The maximum pool size as a percentage of the total\n available memory\n @param[in] managed Whether to use a managed memory resource as upstream resource or not\n @return cuvsError_t"]
294    pub fn cuvsRMMPoolMemoryResourceEnable(
295        initial_pool_size_percent: ::std::os::raw::c_int,
296        max_pool_size_percent: ::std::os::raw::c_int,
297        managed: bool,
298    ) -> cuvsError_t;
299}
300unsafe extern "C" {
301    #[must_use]
302    #[doc = " @brief Switches the working memory resource to use stream-ordered asynchronous allocation\n (cudaMallocAsync / cudaFreeAsync). Unlike the pool resource, this resource returns memory to\n the stream immediately without blocking the CPU, eliminating device-wide synchronization on\n deallocation. This is especially beneficial when multiple CAGRA searches run concurrently on\n separate CUDA streams, because the internal workspace allocations no longer serialize kernel\n launches. Be aware that this function will change the memory resource for the whole process\n and the new memory resource will be used until explicitly changed.\n\n @return cuvsError_t"]
303    pub fn cuvsRMMAsyncMemoryResourceEnable() -> cuvsError_t;
304}
305unsafe extern "C" {
306    #[must_use]
307    #[doc = " @brief Resets the memory resource to use the default memory resource (cuda_memory_resource)\n @return cuvsError_t"]
308    pub fn cuvsRMMMemoryResourceReset() -> cuvsError_t;
309}
310unsafe extern "C" {
311    #[must_use]
312    #[doc = " @brief Allocates pinned memory on the host using RMM\n @param[out] ptr Pointer to allocated host memory\n @param[in] bytes Size in bytes to allocate\n @return cuvsError_t"]
313    pub fn cuvsRMMHostAlloc(ptr: *mut *mut ::std::os::raw::c_void, bytes: usize) -> cuvsError_t;
314}
315unsafe extern "C" {
316    #[must_use]
317    #[doc = " @brief Deallocates pinned memory on the host using RMM\n @param[in] ptr Pointer to allocated host memory to free\n @param[in] bytes Size in bytes to deallocate\n @return cuvsError_t"]
318    pub fn cuvsRMMHostFree(ptr: *mut ::std::os::raw::c_void, bytes: usize) -> cuvsError_t;
319}
320unsafe extern "C" {
321    #[must_use]
322    #[doc = " @brief Get the version of the cuVS library\n @param[out] major Major version\n @param[out] minor Minor version\n @param[out] patch Patch version\n @return cuvsError_t"]
323    pub fn cuvsVersionGet(major: *mut u16, minor: *mut u16, patch: *mut u16) -> cuvsError_t;
324}
325unsafe extern "C" {
326    #[must_use]
327    #[doc = " @brief Copy a matrix\n\n This function copies a matrix from dst to src. This lets you copy a matrix\n from device memory to host memory (or vice versa), while accounting for\n differences in strides.\n\n Both src and dst must have the same shape and dtype, but can have different\n strides and device type. The memory for the output dst tensor must already be\n allocated and the tensor initialized.\n\n @param[in] res cuvsResources_t opaque C handle\n @param[in] src Pointer to DLManagedTensor to copy\n @param[out] dst Pointer to DLManagedTensor to receive copy of data"]
328    pub fn cuvsMatrixCopy(res: cuvsResources_t, src: *mut DLManagedTensor, dst: *mut DLManagedTensor) -> cuvsError_t;
329}
330unsafe extern "C" {
331    #[must_use]
332    #[doc = " @brief Slices rows from a matrix\n\n @param[in] res cuvsResources_t opaque C handle\n @param[in] src Pointer to DLManagedTensor to copy\n @param[in] start First row index to include in the output\n @param[in] end Last row index to include in the output\n @param[out] dst Pointer to DLManagedTensor to receive slice from matrix"]
333    pub fn cuvsMatrixSliceRows(
334        res: cuvsResources_t,
335        src: *mut DLManagedTensor,
336        start: i64,
337        end: i64,
338        dst: *mut DLManagedTensor,
339    ) -> cuvsError_t;
340}
341#[repr(u32)]
342#[doc = " @brief Generic dataset layout kind for C API dataset handles."]
343#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
344pub enum cuvsDatasetLayout_t {
345    CUVS_DATASET_LAYOUT_STANDARD = 0,
346    CUVS_DATASET_LAYOUT_PADDED = 1,
347}
348#[repr(u32)]
349#[doc = " @brief Memory space holding a C API dataset handle's data."]
350#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
351pub enum cuvsDatasetMemType_t {
352    CUVS_DATASET_MEM_TYPE_HOST = 0,
353    CUVS_DATASET_MEM_TYPE_DEVICE = 1,
354}
355#[doc = " @brief Dataset handle representing owning storage or a non-owning view.\n\n `addr` points to C++ dataset storage or view metadata managed by the C API. `mem_type`\n identifies the memory space, `layout` identifies the data layout, and `is_owning` indicates\n whether the handle owns its backing data."]
356#[repr(C)]
357#[derive(Debug, Copy, Clone)]
358pub struct cuvsDataset {
359    pub addr: usize,
360    pub destroy_addr: ::std::option::Option<unsafe extern "C" fn(arg1: *mut ::std::os::raw::c_void)>,
361    pub dtype: DLDataType,
362    pub mem_type: cuvsDatasetMemType_t,
363    pub layout: cuvsDatasetLayout_t,
364    pub is_owning: bool,
365}
366#[allow(clippy::unnecessary_operation, clippy::identity_op)]
367const _: () = {
368    ["Size of cuvsDataset"][::std::mem::size_of::<cuvsDataset>() - 32usize];
369    ["Alignment of cuvsDataset"][::std::mem::align_of::<cuvsDataset>() - 8usize];
370    ["Offset of field: cuvsDataset::addr"][::std::mem::offset_of!(cuvsDataset, addr) - 0usize];
371    ["Offset of field: cuvsDataset::destroy_addr"][::std::mem::offset_of!(cuvsDataset, destroy_addr) - 8usize];
372    ["Offset of field: cuvsDataset::dtype"][::std::mem::offset_of!(cuvsDataset, dtype) - 16usize];
373    ["Offset of field: cuvsDataset::mem_type"][::std::mem::offset_of!(cuvsDataset, mem_type) - 20usize];
374    ["Offset of field: cuvsDataset::layout"][::std::mem::offset_of!(cuvsDataset, layout) - 24usize];
375    ["Offset of field: cuvsDataset::is_owning"][::std::mem::offset_of!(cuvsDataset, is_owning) - 28usize];
376};
377pub type cuvsDataset_t = *mut cuvsDataset;
378unsafe extern "C" {
379    #[must_use]
380    #[doc = " @brief Create an empty owning dataset handle.\n\n The dataset storage, memory type, layout, and dtype are populated by the operation that fills\n this handle."]
381    pub fn cuvsDatasetCreate(dataset: *mut cuvsDataset_t) -> cuvsError_t;
382}
383unsafe extern "C" {
384    #[must_use]
385    #[doc = " @brief Create an owning padded dataset in the requested memory space.\n\n The source tensor may reside in host- or device-accessible memory. Its contents are copied into\n newly allocated padded storage in `target_mem_type`.\n\n @param[in] res cuVS resources\n @param[in] dataset source tensor\n @param[in] target_mem_type memory space in which to allocate the padded dataset\n @param[out] padded_dataset newly allocated owning padded dataset"]
386    pub fn cuvsDatasetMakePadded(
387        res: cuvsResources_t,
388        dataset: *mut DLManagedTensor,
389        target_mem_type: cuvsDatasetMemType_t,
390        padded_dataset: *mut cuvsDataset_t,
391    ) -> cuvsError_t;
392}
393unsafe extern "C" {
394    #[must_use]
395    #[doc = " @brief Create a non-owning padded dataset view from a host- or device-resident tensor.\n\n Memory residency is inferred from the tensor."]
396    pub fn cuvsDatasetMakePaddedView(
397        res: cuvsResources_t,
398        dataset: *mut DLManagedTensor,
399        padded_dataset: *mut cuvsDataset_t,
400    ) -> cuvsError_t;
401}
402unsafe extern "C" {
403    #[must_use]
404    #[doc = " @brief Create a non-owning standard dataset view from a host- or device-resident tensor.\n\n Memory residency is inferred from the tensor."]
405    pub fn cuvsDatasetMakeStandardView(
406        res: cuvsResources_t,
407        dataset: *mut DLManagedTensor,
408        standard_dataset: *mut cuvsDataset_t,
409    ) -> cuvsError_t;
410}
411unsafe extern "C" {
412    #[must_use]
413    #[doc = " @brief Destroy a dataset handle created by a `cuvsDatasetMake*` function."]
414    pub fn cuvsDatasetDestroy(dataset: cuvsDataset_t) -> cuvsError_t;
415}
416unsafe extern "C" {
417    #[must_use]
418    #[doc = " @brief Get the memory residency of a dataset handle."]
419    pub fn cuvsDatasetGetMemType(dataset: cuvsDataset_t, mem_type: *mut cuvsDatasetMemType_t) -> cuvsError_t;
420}
421unsafe extern "C" {
422    #[must_use]
423    #[doc = " @brief Get the layout of a dataset handle."]
424    pub fn cuvsDatasetGetLayout(dataset: cuvsDataset_t, layout: *mut cuvsDatasetLayout_t) -> cuvsError_t;
425}
426unsafe extern "C" {
427    #[must_use]
428    #[doc = " @brief Get whether a dataset handle owns its backing storage."]
429    pub fn cuvsDatasetGetIsOwning(dataset: cuvsDataset_t, is_owning: *mut bool) -> cuvsError_t;
430}
431unsafe extern "C" {
432    #[must_use]
433    #[doc = " @brief Get the element dtype of a dataset handle."]
434    pub fn cuvsDatasetGetDtype(dataset: cuvsDataset_t, dtype: *mut DLDataType) -> cuvsError_t;
435}
436#[repr(u32)]
437#[doc = " enum to tell how to compute distance"]
438#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
439pub enum cuvsDistanceType {
440    #[doc = " evaluate as dist_ij = sum(x_ik^2) + sum(y_ij)^2 - 2*sum(x_ik * y_jk)"]
441    L2Expanded = 0,
442    #[doc = " same as above, but inside the epilogue, perform square root operation"]
443    L2SqrtExpanded = 1,
444    #[doc = " cosine distance"]
445    CosineExpanded = 2,
446    #[doc = " L1 distance"]
447    L1 = 3,
448    #[doc = " evaluate as dist_ij += (x_ik - y-jk)^2"]
449    L2Unexpanded = 4,
450    #[doc = " same as above, but inside the epilogue, perform square root operation"]
451    L2SqrtUnexpanded = 5,
452    #[doc = " basic inner product"]
453    InnerProduct = 6,
454    #[doc = " Chebyshev (Linf) distance"]
455    Linf = 7,
456    #[doc = " Canberra distance"]
457    Canberra = 8,
458    #[doc = " Generalized Minkowski distance"]
459    LpUnexpanded = 9,
460    #[doc = " Correlation distance"]
461    CorrelationExpanded = 10,
462    #[doc = " Jaccard distance"]
463    JaccardExpanded = 11,
464    #[doc = " Hellinger distance"]
465    HellingerExpanded = 12,
466    #[doc = " Haversine distance"]
467    Haversine = 13,
468    #[doc = " Bray-Curtis distance"]
469    BrayCurtis = 14,
470    #[doc = " Jensen-Shannon distance"]
471    JensenShannon = 15,
472    #[doc = " Hamming distance"]
473    HammingUnexpanded = 16,
474    #[doc = " KLDivergence"]
475    KLDivergence = 17,
476    #[doc = " RusselRao"]
477    RusselRaoExpanded = 18,
478    #[doc = " Dice-Sorensen distance"]
479    DiceExpanded = 19,
480    #[doc = " Bitstring Hamming distance"]
481    BitwiseHamming = 20,
482    #[doc = " Precomputed (special value)"]
483    Precomputed = 100,
484}
485#[repr(u32)]
486#[doc = " @defgroup kmeans_c_params k-means hyperparameters\n @{"]
487#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
488pub enum cuvsKMeansInitMethod {
489    #[doc = " Sample the centroids using the kmeans++ strategy"]
490    KMeansPlusPlus = 0,
491    #[doc = " Sample the centroids uniformly at random"]
492    Random = 1,
493    #[doc = " User provides the array of initial centroids"]
494    Array = 2,
495}
496#[doc = " @brief Hyper-parameters for the kmeans algorithm"]
497#[repr(C)]
498#[derive(Debug, Copy, Clone)]
499pub struct cuvsKMeansParams {
500    pub metric: cuvsDistanceType,
501    #[doc = " The number of clusters to form as well as the number of centroids to generate (default:8)."]
502    pub n_clusters: ::std::os::raw::c_int,
503    #[doc = " Method for initialization, defaults to k-means++:\n  - cuvsKMeansInitMethod::KMeansPlusPlus (k-means++): Use scalable k-means++ algorithm\n to select the initial cluster centers.\n  - cuvsKMeansInitMethod::Random (random): Choose 'n_clusters' observations (rows) at\n random from the input data for the initial centroids.\n  - cuvsKMeansInitMethod::Array (ndarray): Use 'centroids' as initial cluster centers."]
504    pub init: cuvsKMeansInitMethod,
505    #[doc = " Maximum number of iterations of the k-means algorithm for a single run."]
506    pub max_iter: ::std::os::raw::c_int,
507    #[doc = " Relative tolerance with regards to inertia to declare convergence."]
508    pub tol: f64,
509    #[doc = " Number of instance k-means algorithm will be run with different seeds."]
510    pub n_init: ::std::os::raw::c_int,
511    #[doc = " Oversampling factor for use in the k-means|| algorithm"]
512    pub oversampling_factor: f64,
513    #[doc = " batch_samples and batch_centroids are used to tile 1NN computation which is\n useful to optimize/control the memory footprint\n Default tile is [batch_samples x n_clusters] i.e. when batch_centroids is 0\n then don't tile the centroids"]
514    pub batch_samples: ::std::os::raw::c_int,
515    #[doc = " if 0 then batch_centroids = n_clusters"]
516    pub batch_centroids: ::std::os::raw::c_int,
517    #[doc = " Whether to use hierarchical (balanced) kmeans or not"]
518    pub hierarchical: bool,
519    #[doc = " For hierarchical k-means , defines the number of training iterations"]
520    pub hierarchical_n_iters: ::std::os::raw::c_int,
521    #[doc = " Number of samples to process per GPU batch for the batched (host-data) API.\n When set to 0, defaults to n_samples (process all at once)."]
522    pub device_buffer_samples: i64,
523    #[doc = " Number of samples to draw for KMeansPlusPlus initialization.\n When set to 0, uses heuristic min(3 * n_clusters, n_samples) for host data,\n or n_samples for device data."]
524    pub init_size: i64,
525}
526#[allow(clippy::unnecessary_operation, clippy::identity_op)]
527const _: () = {
528    ["Size of cuvsKMeansParams"][::std::mem::size_of::<cuvsKMeansParams>() - 72usize];
529    ["Alignment of cuvsKMeansParams"][::std::mem::align_of::<cuvsKMeansParams>() - 8usize];
530    ["Offset of field: cuvsKMeansParams::metric"][::std::mem::offset_of!(cuvsKMeansParams, metric) - 0usize];
531    ["Offset of field: cuvsKMeansParams::n_clusters"][::std::mem::offset_of!(cuvsKMeansParams, n_clusters) - 4usize];
532    ["Offset of field: cuvsKMeansParams::init"][::std::mem::offset_of!(cuvsKMeansParams, init) - 8usize];
533    ["Offset of field: cuvsKMeansParams::max_iter"][::std::mem::offset_of!(cuvsKMeansParams, max_iter) - 12usize];
534    ["Offset of field: cuvsKMeansParams::tol"][::std::mem::offset_of!(cuvsKMeansParams, tol) - 16usize];
535    ["Offset of field: cuvsKMeansParams::n_init"][::std::mem::offset_of!(cuvsKMeansParams, n_init) - 24usize];
536    ["Offset of field: cuvsKMeansParams::oversampling_factor"]
537        [::std::mem::offset_of!(cuvsKMeansParams, oversampling_factor) - 32usize];
538    ["Offset of field: cuvsKMeansParams::batch_samples"]
539        [::std::mem::offset_of!(cuvsKMeansParams, batch_samples) - 40usize];
540    ["Offset of field: cuvsKMeansParams::batch_centroids"]
541        [::std::mem::offset_of!(cuvsKMeansParams, batch_centroids) - 44usize];
542    ["Offset of field: cuvsKMeansParams::hierarchical"]
543        [::std::mem::offset_of!(cuvsKMeansParams, hierarchical) - 48usize];
544    ["Offset of field: cuvsKMeansParams::hierarchical_n_iters"]
545        [::std::mem::offset_of!(cuvsKMeansParams, hierarchical_n_iters) - 52usize];
546    ["Offset of field: cuvsKMeansParams::device_buffer_samples"]
547        [::std::mem::offset_of!(cuvsKMeansParams, device_buffer_samples) - 56usize];
548    ["Offset of field: cuvsKMeansParams::init_size"][::std::mem::offset_of!(cuvsKMeansParams, init_size) - 64usize];
549};
550pub type cuvsKMeansParams_t = *mut cuvsKMeansParams;
551unsafe extern "C" {
552    #[must_use]
553    #[doc = " @brief Allocate KMeans params, and populate with default values\n\n @param[in] params cuvsKMeansParams_t to allocate\n @return cuvsError_t"]
554    pub fn cuvsKMeansParamsCreate(params: *mut cuvsKMeansParams_t) -> cuvsError_t;
555}
556unsafe extern "C" {
557    #[must_use]
558    #[doc = " @brief De-allocate KMeans params\n\n @param[in] params\n @return cuvsError_t"]
559    pub fn cuvsKMeansParamsDestroy(params: cuvsKMeansParams_t) -> cuvsError_t;
560}
561#[repr(u32)]
562#[doc = " @brief Type of k-means algorithm."]
563#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
564pub enum cuvsKMeansType {
565    CUVS_KMEANS_TYPE_KMEANS = 0,
566    CUVS_KMEANS_TYPE_KMEANS_BALANCED = 1,
567}
568unsafe extern "C" {
569    #[must_use]
570    #[doc = " @brief Find clusters with k-means algorithm.\n\n   Initial centroids are chosen with k-means++ algorithm. Empty\n   clusters are reinitialized by choosing new centroids with\n   k-means++ algorithm.\n\n   X may reside on either host (CPU) or device (GPU) memory.\n   When X is on the host the data is buffered to the GPU in\n   batches controlled by params->device_buffer_samples.\n\n @param[in]     res           opaque C handle\n @param[in]     params        Parameters for KMeans model.\n @param[in]     X             Training instances to cluster. The data must\n                              be in row-major format. May be on host or\n                              device memory.\n                              [dim = n_samples x n_features]\n @param[in]     sample_weight Optional weights for each observation in X.\n                              Must be on the same memory space as X.\n                              [len = n_samples]\n @param[inout]  centroids     [in] When init is InitMethod::Array, use\n                              centroids as the initial cluster centers.\n                              [out] The generated centroids from the\n                              kmeans algorithm are stored at the address\n                              pointed by 'centroids'. Must be on device.\n                              [dim = n_clusters x n_features]\n @param[out]    inertia       Sum of squared distances of samples to their\n                              closest cluster center.\n @param[out]    n_iter        Number of iterations run."]
571    pub fn cuvsKMeansFit(
572        res: cuvsResources_t,
573        params: cuvsKMeansParams_t,
574        X: *mut DLManagedTensor,
575        sample_weight: *mut DLManagedTensor,
576        centroids: *mut DLManagedTensor,
577        inertia: *mut f64,
578        n_iter: *mut ::std::os::raw::c_int,
579    ) -> cuvsError_t;
580}
581unsafe extern "C" {
582    #[must_use]
583    #[doc = " @brief Predict the closest cluster each sample in X belongs to.\n\n @param[in]     res              opaque C handle\n @param[in]     params           Parameters for KMeans model.\n @param[in]     X                New data to predict.\n                                 [dim = n_samples x n_features]\n @param[in]     sample_weight    Optional weights for each observation in X.\n                                 [len = n_samples]\n @param[in]     centroids        Cluster centroids. The data must be in\n                                 row-major format.\n                                 [dim = n_clusters x n_features]\n @param[in]     normalize_weight True if the weights should be normalized\n @param[out]    labels           Index of the cluster each sample in X\n                                 belongs to.\n                                 [len = n_samples]\n @param[out]    inertia          Sum of squared distances of samples to\n                                 their closest cluster center."]
584    pub fn cuvsKMeansPredict(
585        res: cuvsResources_t,
586        params: cuvsKMeansParams_t,
587        X: *mut DLManagedTensor,
588        sample_weight: *mut DLManagedTensor,
589        centroids: *mut DLManagedTensor,
590        labels: *mut DLManagedTensor,
591        normalize_weight: bool,
592        inertia: *mut f64,
593    ) -> cuvsError_t;
594}
595unsafe extern "C" {
596    #[must_use]
597    #[doc = " @brief Compute cluster cost\n\n @param[in]  res            opaque C handle\n @param[in]  X              Training instances to cluster. The data must\n                            be in row-major format.\n                            [dim = n_samples x n_features]\n @param[in]  centroids      Cluster centroids. The data must be in\n                            row-major format.\n                            [dim = n_clusters x n_features]\n @param[out] cost           Resulting cluster cost\n"]
598    pub fn cuvsKMeansClusterCost(
599        res: cuvsResources_t,
600        X: *mut DLManagedTensor,
601        centroids: *mut DLManagedTensor,
602        cost: *mut f64,
603    ) -> cuvsError_t;
604}
605unsafe extern "C" {
606    #[must_use]
607    #[doc = " @brief Compute pairwise distances for two matrices\n\n\n Usage example:\n @code{.c}\n #include <cuvs/core/c_api.h>\n #include <cuvs/distance/pairwise_distance.h>\n\n // Create cuvsResources_t\n cuvsResources_t res;\n cuvsError_t res_create_status = cuvsResourcesCreate(&res);\n\n // Assume a populated `DLManagedTensor` type here\n DLManagedTensor x;\n DLManagedTensor y;\n DLManagedTensor dist;\n\n cuvsPairwiseDistance(res, &x, &y, &dist, L2SqrtUnexpanded, 2.0);\n @endcode\n\n @param[in] res cuvs resources object for managing expensive resources\n @param[in] x first set of points (size n*k)\n @param[in] y second set of points (size m*k)\n @param[out] dist output distance matrix (size n*m)\n @param[in] metric distance to evaluate\n @param[in] metric_arg metric argument (used for Minkowski distance)"]
608    pub fn cuvsPairwiseDistance(
609        res: cuvsResources_t,
610        x: *mut DLManagedTensor,
611        y: *mut DLManagedTensor,
612        dist: *mut DLManagedTensor,
613        metric: cuvsDistanceType,
614        metric_arg: f32,
615    ) -> cuvsError_t;
616}
617#[repr(u32)]
618#[doc = " @defgroup ivf_pq_c_index_params IVF-PQ index build parameters\n @{\n/\n/**\n @brief A type for specifying how PQ codebooks are created\n"]
619#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
620pub enum cuvsIvfPqCodebookGen {
621    CUVS_IVF_PQ_CODEBOOK_GEN_PER_SUBSPACE = 0,
622    CUVS_IVF_PQ_CODEBOOK_GEN_PER_CLUSTER = 1,
623}
624#[repr(u32)]
625#[doc = " @brief A type for specifying the memory layout of IVF-PQ list data\n"]
626#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
627pub enum cuvsIvfPqListLayout {
628    CUVS_IVF_PQ_LIST_LAYOUT_FLAT = 0,
629    CUVS_IVF_PQ_LIST_LAYOUT_INTERLEAVED = 1,
630}
631#[doc = " @brief Supplemental parameters to build IVF-PQ Index\n"]
632#[repr(C)]
633#[derive(Debug, Copy, Clone)]
634pub struct cuvsIvfPqIndexParams {
635    #[doc = " Distance type."]
636    pub metric: cuvsDistanceType,
637    #[doc = " The argument used by some distance metrics."]
638    pub metric_arg: f32,
639    #[doc = " Whether to add the dataset content to the index, i.e.:\n\n  - `true` means the index is filled with the dataset vectors and ready to search after calling\n `build`.\n  - `false` means `build` only trains the underlying model (e.g. quantizer or clustering), but\n the index is left empty; you'd need to call `extend` on the index afterwards to populate it."]
640    pub add_data_on_build: bool,
641    #[doc = " The number of inverted lists (clusters)\n\n Hint: the number of vectors per cluster (`n_rows/n_lists`) should be approximately 1,000 to\n 10,000."]
642    pub n_lists: u32,
643    #[doc = " The number of iterations searching for kmeans centers (index building)."]
644    pub kmeans_n_iters: u32,
645    #[doc = " The fraction of data to use during iterative kmeans building."]
646    pub kmeans_trainset_fraction: f64,
647    #[doc = " The bit length of the vector element after compression by PQ.\n\n Possible values: [4, 5, 6, 7, 8].\n\n Hint: the smaller the 'pq_bits', the smaller the index size and the better the search\n performance, but the lower the recall."]
648    pub pq_bits: u32,
649    #[doc = " The dimensionality of the vector after compression by PQ. When zero, an optimal value is\n selected using a heuristic.\n\n NB: `pq_dim * pq_bits` must be a multiple of 8.\n\n Hint: a smaller 'pq_dim' results in a smaller index size and better search performance, but\n lower recall. If 'pq_bits' is 8, 'pq_dim' can be set to any number, but multiple of 8 are\n desirable for good performance. If 'pq_bits' is not 8, 'pq_dim' should be a multiple of 8.\n For good performance, it is desirable that 'pq_dim' is a multiple of 32. Ideally, 'pq_dim'\n should be also a divisor of the dataset dim."]
650    pub pq_dim: u32,
651    #[doc = " How PQ codebooks are created."]
652    pub codebook_kind: cuvsIvfPqCodebookGen,
653    #[doc = " Apply a random rotation matrix on the input data and queries even if `dim % pq_dim == 0`.\n\n Note: if `dim` is not multiple of `pq_dim`, a random rotation is always applied to the input\n data and queries to transform the working space from `dim` to `rot_dim`, which may be slightly\n larger than the original space and and is a multiple of `pq_dim` (`rot_dim % pq_dim == 0`).\n However, this transform is not necessary when `dim` is multiple of `pq_dim`\n   (`dim == rot_dim`, hence no need in adding \"extra\" data columns / features).\n\n By default, if `dim == rot_dim`, the rotation transform is initialized with the identity\n matrix. When `force_random_rotation == true`, a random orthogonal transform matrix is generated\n regardless of the values of `dim` and `pq_dim`."]
654    pub force_random_rotation: bool,
655    #[doc = " By default, the algorithm allocates more space than necessary for individual clusters\n (`list_data`). This allows to amortize the cost of memory allocation and reduce the number of\n data copies during repeated calls to `extend` (extending the database).\n\n The alternative is the conservative allocation behavior; when enabled, the algorithm always\n allocates the minimum amount of memory required to store the given number of records. Set this\n flag to `true` if you prefer to use as little GPU memory for the database as possible."]
656    pub conservative_memory_allocation: bool,
657    #[doc = " The max number of data points to use per PQ code during PQ codebook training. Using more data\n points per PQ code may increase the quality of PQ codebook but may also increase the build\n time. The parameter is applied to both PQ codebook generation methods, i.e., PER_SUBSPACE and\n PER_CLUSTER. In both cases, we will use `pq_book_size * max_train_points_per_pq_code` training\n points to train each codebook."]
658    pub max_train_points_per_pq_code: u32,
659    #[doc = " Memory layout of the IVF-PQ list data.\n\n - CUVS_IVF_PQ_LIST_LAYOUT_FLAT: Codes are stored contiguously, one vector's codes after another.\n - CUVS_IVF_PQ_LIST_LAYOUT_INTERLEAVED: Codes are interleaved for optimized search performance.\n   This is the default and recommended for search workloads."]
660    pub codes_layout: cuvsIvfPqListLayout,
661}
662#[allow(clippy::unnecessary_operation, clippy::identity_op)]
663const _: () = {
664    ["Size of cuvsIvfPqIndexParams"][::std::mem::size_of::<cuvsIvfPqIndexParams>() - 56usize];
665    ["Alignment of cuvsIvfPqIndexParams"][::std::mem::align_of::<cuvsIvfPqIndexParams>() - 8usize];
666    ["Offset of field: cuvsIvfPqIndexParams::metric"][::std::mem::offset_of!(cuvsIvfPqIndexParams, metric) - 0usize];
667    ["Offset of field: cuvsIvfPqIndexParams::metric_arg"]
668        [::std::mem::offset_of!(cuvsIvfPqIndexParams, metric_arg) - 4usize];
669    ["Offset of field: cuvsIvfPqIndexParams::add_data_on_build"]
670        [::std::mem::offset_of!(cuvsIvfPqIndexParams, add_data_on_build) - 8usize];
671    ["Offset of field: cuvsIvfPqIndexParams::n_lists"][::std::mem::offset_of!(cuvsIvfPqIndexParams, n_lists) - 12usize];
672    ["Offset of field: cuvsIvfPqIndexParams::kmeans_n_iters"]
673        [::std::mem::offset_of!(cuvsIvfPqIndexParams, kmeans_n_iters) - 16usize];
674    ["Offset of field: cuvsIvfPqIndexParams::kmeans_trainset_fraction"]
675        [::std::mem::offset_of!(cuvsIvfPqIndexParams, kmeans_trainset_fraction) - 24usize];
676    ["Offset of field: cuvsIvfPqIndexParams::pq_bits"][::std::mem::offset_of!(cuvsIvfPqIndexParams, pq_bits) - 32usize];
677    ["Offset of field: cuvsIvfPqIndexParams::pq_dim"][::std::mem::offset_of!(cuvsIvfPqIndexParams, pq_dim) - 36usize];
678    ["Offset of field: cuvsIvfPqIndexParams::codebook_kind"]
679        [::std::mem::offset_of!(cuvsIvfPqIndexParams, codebook_kind) - 40usize];
680    ["Offset of field: cuvsIvfPqIndexParams::force_random_rotation"]
681        [::std::mem::offset_of!(cuvsIvfPqIndexParams, force_random_rotation) - 44usize];
682    ["Offset of field: cuvsIvfPqIndexParams::conservative_memory_allocation"]
683        [::std::mem::offset_of!(cuvsIvfPqIndexParams, conservative_memory_allocation) - 45usize];
684    ["Offset of field: cuvsIvfPqIndexParams::max_train_points_per_pq_code"]
685        [::std::mem::offset_of!(cuvsIvfPqIndexParams, max_train_points_per_pq_code) - 48usize];
686    ["Offset of field: cuvsIvfPqIndexParams::codes_layout"]
687        [::std::mem::offset_of!(cuvsIvfPqIndexParams, codes_layout) - 52usize];
688};
689pub type cuvsIvfPqIndexParams_t = *mut cuvsIvfPqIndexParams;
690unsafe extern "C" {
691    #[must_use]
692    #[doc = " @brief Allocate IVF-PQ Index params, and populate with default values\n\n @param[in] index_params cuvsIvfPqIndexParams_t to allocate\n @return cuvsError_t"]
693    pub fn cuvsIvfPqIndexParamsCreate(index_params: *mut cuvsIvfPqIndexParams_t) -> cuvsError_t;
694}
695unsafe extern "C" {
696    #[must_use]
697    #[doc = " @brief De-allocate IVF-PQ Index params\n\n @param[in] index_params\n @return cuvsError_t"]
698    pub fn cuvsIvfPqIndexParamsDestroy(index_params: cuvsIvfPqIndexParams_t) -> cuvsError_t;
699}
700#[doc = " @defgroup ivf_pq_c_search_params IVF-PQ index search parameters\n @{\n/\n/**\n @brief Supplemental parameters to search IVF-PQ index\n"]
701#[repr(C)]
702pub struct cuvsIvfPqSearchParams {
703    #[doc = " The number of clusters to search."]
704    pub n_probes: u32,
705    #[doc = " Data type of look up table to be created dynamically at search time.\n\n Possible values: [CUDA_R_32F, CUDA_R_16F, CUDA_R_8U]\n\n The use of low-precision types reduces the amount of shared memory required at search time, so\n fast shared memory kernels can be used even for datasets with large dimansionality. Note that\n the recall is slightly degraded when low-precision type is selected."]
706    pub lut_dtype: cudaDataType_t,
707    #[doc = " Storage data type for distance/similarity computed at search time.\n\n Possible values: [CUDA_R_16F, CUDA_R_32F]\n\n If the performance limiter at search time is device memory access, selecting FP16 will improve\n performance slightly."]
708    pub internal_distance_dtype: cudaDataType_t,
709    #[doc = " The data type to use as the GEMM element type when searching the clusters to probe.\n\n Possible values: [CUDA_R_8I, CUDA_R_16F, CUDA_R_32F].\n\n - Legacy default: CUDA_R_32F (float)\n - Recommended for performance: CUDA_R_16F (half)\n - Experimental/low-precision: CUDA_R_8I (int8_t)\n    (WARNING: int8_t variant degrades recall unless data is normalized and low-dimensional)"]
710    pub coarse_search_dtype: cudaDataType_t,
711    #[doc = " Set the internal batch size to improve GPU utilization at the cost of larger memory footprint."]
712    pub max_internal_batch_size: u32,
713    #[doc = " Preferred fraction of SM's unified memory / L1 cache to be used as shared memory.\n\n Possible values: [0.0 - 1.0] as a fraction of the `sharedMemPerMultiprocessor`.\n\n One wants to increase the carveout to make sure a good GPU occupancy for the main search\n kernel, but not to keep it too high to leave some memory to be used as L1 cache. Note, this\n value is interpreted only as a hint. Moreover, a GPU usually allows only a fixed set of cache\n configurations, so the provided value is rounded up to the nearest configuration. Refer to the\n NVIDIA tuning guide for the target GPU architecture.\n\n Note, this is a low-level tuning parameter that can have drastic negative effects on the search\n performance if tweaked incorrectly."]
714    pub preferred_shmem_carveout: f64,
715}
716#[allow(clippy::unnecessary_operation, clippy::identity_op)]
717const _: () = {
718    ["Size of cuvsIvfPqSearchParams"][::std::mem::size_of::<cuvsIvfPqSearchParams>() - 32usize];
719    ["Alignment of cuvsIvfPqSearchParams"][::std::mem::align_of::<cuvsIvfPqSearchParams>() - 8usize];
720    ["Offset of field: cuvsIvfPqSearchParams::n_probes"]
721        [::std::mem::offset_of!(cuvsIvfPqSearchParams, n_probes) - 0usize];
722    ["Offset of field: cuvsIvfPqSearchParams::lut_dtype"]
723        [::std::mem::offset_of!(cuvsIvfPqSearchParams, lut_dtype) - 4usize];
724    ["Offset of field: cuvsIvfPqSearchParams::internal_distance_dtype"]
725        [::std::mem::offset_of!(cuvsIvfPqSearchParams, internal_distance_dtype) - 8usize];
726    ["Offset of field: cuvsIvfPqSearchParams::coarse_search_dtype"]
727        [::std::mem::offset_of!(cuvsIvfPqSearchParams, coarse_search_dtype) - 12usize];
728    ["Offset of field: cuvsIvfPqSearchParams::max_internal_batch_size"]
729        [::std::mem::offset_of!(cuvsIvfPqSearchParams, max_internal_batch_size) - 16usize];
730    ["Offset of field: cuvsIvfPqSearchParams::preferred_shmem_carveout"]
731        [::std::mem::offset_of!(cuvsIvfPqSearchParams, preferred_shmem_carveout) - 24usize];
732};
733pub type cuvsIvfPqSearchParams_t = *mut cuvsIvfPqSearchParams;
734unsafe extern "C" {
735    #[must_use]
736    #[doc = " @brief Allocate IVF-PQ search params, and populate with default values\n\n @param[in] params cuvsIvfPqSearchParams_t to allocate\n @return cuvsError_t"]
737    pub fn cuvsIvfPqSearchParamsCreate(params: *mut cuvsIvfPqSearchParams_t) -> cuvsError_t;
738}
739unsafe extern "C" {
740    #[must_use]
741    #[doc = " @brief De-allocate IVF-PQ search params\n\n @param[in] params\n @return cuvsError_t"]
742    pub fn cuvsIvfPqSearchParamsDestroy(params: cuvsIvfPqSearchParams_t) -> cuvsError_t;
743}
744#[doc = " @defgroup ivf_pq_c_index IVF-PQ index\n @{\n/\n/**\n @brief Struct to hold address of cuvs::neighbors::ivf_pq::index and its active trained dtype\n"]
745#[repr(C)]
746#[derive(Debug, Copy, Clone)]
747pub struct cuvsIvfPqIndex {
748    pub addr: usize,
749    pub dtype: DLDataType,
750}
751#[allow(clippy::unnecessary_operation, clippy::identity_op)]
752const _: () = {
753    ["Size of cuvsIvfPqIndex"][::std::mem::size_of::<cuvsIvfPqIndex>() - 16usize];
754    ["Alignment of cuvsIvfPqIndex"][::std::mem::align_of::<cuvsIvfPqIndex>() - 8usize];
755    ["Offset of field: cuvsIvfPqIndex::addr"][::std::mem::offset_of!(cuvsIvfPqIndex, addr) - 0usize];
756    ["Offset of field: cuvsIvfPqIndex::dtype"][::std::mem::offset_of!(cuvsIvfPqIndex, dtype) - 8usize];
757};
758pub type cuvsIvfPqIndex_t = *mut cuvsIvfPqIndex;
759unsafe extern "C" {
760    #[must_use]
761    #[doc = " @brief Allocate IVF-PQ index\n\n @param[in] index cuvsIvfPqIndex_t to allocate\n @return cuvsError_t"]
762    pub fn cuvsIvfPqIndexCreate(index: *mut cuvsIvfPqIndex_t) -> cuvsError_t;
763}
764unsafe extern "C" {
765    #[must_use]
766    #[doc = " @brief De-allocate IVF-PQ index\n\n @param[in] index cuvsIvfPqIndex_t to de-allocate"]
767    pub fn cuvsIvfPqIndexDestroy(index: cuvsIvfPqIndex_t) -> cuvsError_t;
768}
769unsafe extern "C" {
770    #[must_use]
771    #[doc = " Get the number of clusters/inverted lists"]
772    pub fn cuvsIvfPqIndexGetNLists(index: cuvsIvfPqIndex_t, n_lists: *mut i64) -> cuvsError_t;
773}
774unsafe extern "C" {
775    #[must_use]
776    #[doc = " Get the dimensionality"]
777    pub fn cuvsIvfPqIndexGetDim(index: cuvsIvfPqIndex_t, dim: *mut i64) -> cuvsError_t;
778}
779unsafe extern "C" {
780    #[must_use]
781    #[doc = " Get the size of the index"]
782    pub fn cuvsIvfPqIndexGetSize(index: cuvsIvfPqIndex_t, size: *mut i64) -> cuvsError_t;
783}
784unsafe extern "C" {
785    #[must_use]
786    #[doc = " Get the dimensionality of an encoded vector after compression by PQ."]
787    pub fn cuvsIvfPqIndexGetPqDim(index: cuvsIvfPqIndex_t, pq_dim: *mut i64) -> cuvsError_t;
788}
789unsafe extern "C" {
790    #[must_use]
791    #[doc = " Get the bit length of an encoded vector element after compression by PQ."]
792    pub fn cuvsIvfPqIndexGetPqBits(index: cuvsIvfPqIndex_t, pq_bits: *mut i64) -> cuvsError_t;
793}
794unsafe extern "C" {
795    #[must_use]
796    #[doc = " Get the Dimensionality of a subspace, i.e. the number of vector\n components mapped to a subspace"]
797    pub fn cuvsIvfPqIndexGetPqLen(index: cuvsIvfPqIndex_t, pq_len: *mut i64) -> cuvsError_t;
798}
799unsafe extern "C" {
800    #[must_use]
801    #[doc = " @brief Get the cluster centers corresponding to the lists in the original space\n\n @param[in] index cuvsIvfPqIndex_t Built Ivf-Pq index\n @param[out] centers Output tensor that will be populated with a non-owning view of the data\n @return cuvsError_t"]
802    pub fn cuvsIvfPqIndexGetCenters(index: cuvsIvfPqIndex_t, centers: *mut DLManagedTensor) -> cuvsError_t;
803}
804unsafe extern "C" {
805    #[must_use]
806    #[doc = " @brief Get the padded cluster centers [n_lists, dim_ext]\n   where dim_ext = round_up(dim + 1, 8)\n\n This returns the full padded centers as a contiguous array, suitable for\n use with cuvsIvfPqBuildPrecomputed.\n\n @param[in] index cuvsIvfPqIndex_t Built Ivf-Pq index\n @param[out] centers Output tensor that will be populated with a non-owning view of the data\n @return cuvsError_t"]
807    pub fn cuvsIvfPqIndexGetCentersPadded(index: cuvsIvfPqIndex_t, centers: *mut DLManagedTensor) -> cuvsError_t;
808}
809unsafe extern "C" {
810    #[must_use]
811    #[doc = " @brief Get the PQ cluster centers\n\n   - CUVS_IVF_PQ_CODEBOOK_GEN_PER_SUBSPACE: [pq_dim , pq_len, pq_book_size]\n   - CUVS_IVF_PQ_CODEBOOK_GEN_PER_CLUSTER:  [n_lists, pq_len, pq_book_size]\n\n @param[in] index cuvsIvfPqIndex_t Built Ivf-Pq index\n @param[out] pq_centers Output tensor that will be populated with a non-owning view of the data\n @return cuvsError_t"]
812    pub fn cuvsIvfPqIndexGetPqCenters(index: cuvsIvfPqIndex_t, pq_centers: *mut DLManagedTensor) -> cuvsError_t;
813}
814unsafe extern "C" {
815    #[must_use]
816    #[doc = " @brief Get the rotated cluster centers [n_lists, rot_dim]\n   where rot_dim = pq_len * pq_dim\n\n @param[in] index cuvsIvfPqIndex_t Built Ivf-Pq index\n @param[out] centers_rot Output tensor that will be populated with a non-owning view of the data\n @return cuvsError_t"]
817    pub fn cuvsIvfPqIndexGetCentersRot(index: cuvsIvfPqIndex_t, centers_rot: *mut DLManagedTensor) -> cuvsError_t;
818}
819unsafe extern "C" {
820    #[must_use]
821    #[doc = " @brief Get the rotation matrix [rot_dim, dim]\n   Transform matrix (original space -> rotated padded space)\n\n @param[in] index cuvsIvfPqIndex_t Built Ivf-Pq index\n @param[out] rotation_matrix Output tensor that will be populated with a non-owning view of the\n data\n @return cuvsError_t"]
822    pub fn cuvsIvfPqIndexGetRotationMatrix(
823        index: cuvsIvfPqIndex_t,
824        rotation_matrix: *mut DLManagedTensor,
825    ) -> cuvsError_t;
826}
827unsafe extern "C" {
828    #[must_use]
829    #[doc = " @brief Get the sizes of each list\n\n @param[in] index cuvsIvfPqIndex_t Built Ivf-Pq index\n @param[out] list_sizes Output tensor that will be populated with a non-owning view of the data\n @return cuvsError_t"]
830    pub fn cuvsIvfPqIndexGetListSizes(index: cuvsIvfPqIndex_t, list_sizes: *mut DLManagedTensor) -> cuvsError_t;
831}
832unsafe extern "C" {
833    #[must_use]
834    #[doc = " @brief Unpack `n_rows` consecutive PQ encoded vectors of a single list (cluster) in the\n compressed index starting at given `offset`, not expanded to one code per byte. Each code in the\n output buffer occupies ceildiv(index.pq_dim() * index.pq_bits(), 8) bytes.\n\n @param[in] res raft resource\n @param[in] index cuvsIvfPqIndex_t Built Ivf-Pq index\n @param[out] out_codes\n   the destination buffer [n_rows, ceildiv(index.pq_dim() * index.pq_bits(), 8)].\n   The length `n_rows` defines how many records to unpack,\n   offset + n_rows must be smaller than or equal to the list size.\n   This DLManagedTensor must already point to allocated device memory\n @param[in] label\n   The id of the list (cluster) to decode.\n @param[in] offset\n   How many records in the list to skip."]
835    pub fn cuvsIvfPqIndexUnpackContiguousListData(
836        res: cuvsResources_t,
837        index: cuvsIvfPqIndex_t,
838        out_codes: *mut DLManagedTensor,
839        label: u32,
840        offset: u32,
841    ) -> cuvsError_t;
842}
843unsafe extern "C" {
844    #[must_use]
845    #[doc = " @brief Get the indices of each vector in a ivf-pq list\n\n @param[in] index cuvsIvfPqIndex_t Built Ivf-Pq index\n @param[in] label\n   The id of the list (cluster) to decode.\n @param[out] out_labels\n   output tensor that will be populated with a non-owning view of the data\n @return cuvsError_t"]
846    pub fn cuvsIvfPqIndexGetListIndices(
847        index: cuvsIvfPqIndex_t,
848        label: u32,
849        out_labels: *mut DLManagedTensor,
850    ) -> cuvsError_t;
851}
852unsafe extern "C" {
853    #[must_use]
854    #[doc = " @defgroup ivf_pq_c_index_build IVF-PQ index build\n @{\n/\n/**\n @brief Build a IVF-PQ index with a `DLManagedTensor` which has underlying\n        `DLDeviceType` equal to `kDLCUDA`, `kDLCUDAHost`, `kDLCUDAManaged`,\n        or `kDLCPU`. Also, acceptable underlying types are:\n        1. `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 32`\n        2. `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 16`\n        3. `kDLDataType.code == kDLInt` and `kDLDataType.bits = 8`\n        4. `kDLDataType.code == kDLUInt` and `kDLDataType.bits = 8`\n\n @code {.c}\n #include <cuvs/core/c_api.h>\n #include <cuvs/neighbors/ivf_pq.h>\n\n // Create cuvsResources_t\n cuvsResources_t res;\n cuvsError_t res_create_status = cuvsResourcesCreate(&res);\n\n // Assume a populated `DLManagedTensor` type here\n DLManagedTensor dataset;\n\n // Create default index params\n cuvsIvfPqIndexParams_t index_params;\n cuvsError_t params_create_status = cuvsIvfPqIndexParamsCreate(&index_params);\n\n // Create IVF-PQ index\n cuvsIvfPqIndex_t index;\n cuvsError_t index_create_status = cuvsIvfPqIndexCreate(&index);\n\n // Build the IVF-PQ Index\n cuvsError_t build_status = cuvsIvfPqBuild(res, index_params, &dataset, index);\n\n // de-allocate `index_params`, `index` and `res`\n cuvsError_t params_destroy_status = cuvsIvfPqIndexParamsDestroy(index_params);\n cuvsError_t index_destroy_status = cuvsIvfPqIndexDestroy(index);\n cuvsError_t res_destroy_status = cuvsResourcesDestroy(res);\n @endcode\n\n @param[in] res cuvsResources_t opaque C handle\n @param[in] params cuvsIvfPqIndexParams_t used to build IVF-PQ index\n @param[in] dataset DLManagedTensor* training dataset\n @param[out] index cuvsIvfPqIndex_t Newly built IVF-PQ index\n @return cuvsError_t"]
855    pub fn cuvsIvfPqBuild(
856        res: cuvsResources_t,
857        params: cuvsIvfPqIndexParams_t,
858        dataset: *mut DLManagedTensor,
859        index: cuvsIvfPqIndex_t,
860    ) -> cuvsError_t;
861}
862unsafe extern "C" {
863    #[must_use]
864    #[doc = " @brief Build a view-type IVF-PQ index from device memory precomputed centroids and codebook.\n\n This function creates a non-owning index that stores a reference to the provided device data.\n All parameters must be provided with correct extents. The caller is responsible for ensuring\n the lifetime of the input data exceeds the lifetime of the returned index.\n\n The index_params must be consistent with the provided matrices. Specifically:\n - index_params.codebook_kind determines the expected shape of pq_centers\n - index_params.metric will be stored in the index\n - index_params.conservative_memory_allocation will be stored in the index\n The function will verify consistency between index_params, dim, and the matrix extents.\n\n @param[in] res cuvsResources_t opaque C handle\n @param[in] params cuvsIvfPqIndexParams_t used to configure the index (must be consistent with\n matrices)\n @param[in] dim dimensionality of the input data\n @param[in] pq_centers PQ codebook on device memory with required shape:\n   - codebook_kind CUVS_IVF_PQ_CODEBOOK_GEN_PER_SUBSPACE: [pq_dim, pq_len, pq_book_size]\n   - codebook_kind CUVS_IVF_PQ_CODEBOOK_GEN_PER_CLUSTER:  [n_lists, pq_len, pq_book_size]\n @param[in] centers Cluster centers in the original space [n_lists, dim_ext]\n   where dim_ext = round_up(dim + 1, 8)\n @param[in] centers_rot Rotated cluster centers [n_lists, rot_dim]\n   where rot_dim = pq_len * pq_dim\n @param[in] rotation_matrix Transform matrix (original space -> rotated padded space) [rot_dim,\n dim]\n @param[out] index cuvsIvfPqIndex_t Newly built view-type IVF-PQ index\n @return cuvsError_t"]
865    pub fn cuvsIvfPqBuildPrecomputed(
866        res: cuvsResources_t,
867        params: cuvsIvfPqIndexParams_t,
868        dim: u32,
869        pq_centers: *mut DLManagedTensor,
870        centers: *mut DLManagedTensor,
871        centers_rot: *mut DLManagedTensor,
872        rotation_matrix: *mut DLManagedTensor,
873        index: cuvsIvfPqIndex_t,
874    ) -> cuvsError_t;
875}
876unsafe extern "C" {
877    #[must_use]
878    #[doc = " @defgroup ivf_pq_c_index_search IVF-PQ index search\n @{\n/\n/**\n @brief Search a IVF-PQ index with a `DLManagedTensor` which has underlying\n        `DLDeviceType` equal to `kDLCUDA`, `kDLCUDAHost`, `kDLCUDAManaged`.\n        It is also important to note that the IVF-PQ Index must have been built\n        with the same type of `queries`, such that `index.dtype.code ==\n queries.dl_tensor.dtype.code` Types for input are:\n        1. `queries`: `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 32`\n            or `kDLDataType.bits = 16`\n        2. `neighbors`: `kDLDataType.code == kDLUInt` and `kDLDataType.bits = 32`\n        3. `distances`: `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 32`\n\n @code {.c}\n #include <cuvs/core/c_api.h>\n #include <cuvs/neighbors/ivf_pq.h>\n\n // Create cuvsResources_t\n cuvsResources_t res;\n cuvsError_t res_create_status = cuvsResourcesCreate(&res);\n\n // Assume a populated `DLManagedTensor` type here\n DLManagedTensor dataset;\n DLManagedTensor queries;\n DLManagedTensor neighbors;\n\n // Create default search params\n cuvsIvfPqSearchParams_t search_params;\n cuvsError_t params_create_status = cuvsIvfPqSearchParamsCreate(&search_params);\n\n // Search the `index` built using `cuvsIvfPqBuild`\n cuvsError_t search_status = cuvsIvfPqSearch(res, search_params, index, &queries, &neighbors,\n &distances);\n\n // de-allocate `search_params` and `res`\n cuvsError_t params_destroy_status = cuvsIvfPqSearchParamsDestroy(search_params);\n cuvsError_t res_destroy_status = cuvsResourcesDestroy(res);\n @endcode\n\n @param[in] res cuvsResources_t opaque C handle\n @param[in] search_params cuvsIvfPqSearchParams_t used to search IVF-PQ index\n @param[in] index cuvsIvfPqIndex which has been returned by `cuvsIvfPqBuild`\n @param[in] queries DLManagedTensor* queries dataset to search\n @param[out] neighbors DLManagedTensor* output `k` neighbors for queries\n @param[out] distances DLManagedTensor* output `k` distances for queries"]
879    pub fn cuvsIvfPqSearch(
880        res: cuvsResources_t,
881        search_params: cuvsIvfPqSearchParams_t,
882        index: cuvsIvfPqIndex_t,
883        queries: *mut DLManagedTensor,
884        neighbors: *mut DLManagedTensor,
885        distances: *mut DLManagedTensor,
886    ) -> cuvsError_t;
887}
888unsafe extern "C" {
889    #[must_use]
890    #[doc = " @defgroup ivf_pq_c_index_serialize IVF-PQ C-API serialize functions\n @{\n/\n/**\n Save the index to file.\n\n Experimental, both the API and the serialization format are subject to change.\n\n @code{.cpp}\n #include <cuvs/neighbors/ivf_pq.h>\n\n // Create cuvsResources_t\n cuvsResources_t res;\n cuvsError_t res_create_status = cuvsResourcesCreate(&res);\n\n // create an index with `cuvsIvfPqBuild`\n cuvsIvfPqSerialize(res, \"/path/to/index\", index, true);\n @endcode\n\n @param[in] res cuvsResources_t opaque C handle\n @param[in] filename the file name for saving the index\n @param[in] index IVF-PQ index"]
891    pub fn cuvsIvfPqSerialize(
892        res: cuvsResources_t,
893        filename: *const ::std::os::raw::c_char,
894        index: cuvsIvfPqIndex_t,
895    ) -> cuvsError_t;
896}
897unsafe extern "C" {
898    #[must_use]
899    #[doc = " Load index from file.\n\n Experimental, both the API and the serialization format are subject to change.\n\n @param[in] res cuvsResources_t opaque C handle\n @param[in] filename the name of the file that stores the index\n @param[out] index IVF-PQ index loaded disk"]
900    pub fn cuvsIvfPqDeserialize(
901        res: cuvsResources_t,
902        filename: *const ::std::os::raw::c_char,
903        index: cuvsIvfPqIndex_t,
904    ) -> cuvsError_t;
905}
906unsafe extern "C" {
907    #[must_use]
908    #[doc = " @defgroup ivf_pq_c_index_extend IVF-PQ index extend\n @{\n/\n/**\n @brief Extend the index with the new data.\n\n @param[in] res cuvsResources_t opaque C handle\n @param[in] new_vectors DLManagedTensor* the new vectors to add to the index\n @param[in] new_indices DLManagedTensor* vector of new indices for the new vectors\n @param[inout] index IVF-PQ index to be extended\n @return cuvsError_t"]
909    pub fn cuvsIvfPqExtend(
910        res: cuvsResources_t,
911        new_vectors: *mut DLManagedTensor,
912        new_indices: *mut DLManagedTensor,
913        index: cuvsIvfPqIndex_t,
914    ) -> cuvsError_t;
915}
916unsafe extern "C" {
917    #[must_use]
918    #[doc = " @defgroup ivf_pq_c_index_transform IVF-PQ index transform\n @{\n/\n/**\n @brief Transform the input data by applying pq-encoding\n\n @param[in] res cuvsResources_t opaque C handle\n @param[in] index IVF-PQ index\n @param[in] input_dataset DLManagedTensor* vectors to transform\n @param[out] output_labels DLManagedTensor* Vector of cluster labels for each vector in the input\n @param[out] output_dataset DLManagedTensor* input vectors after pq-encoding\n @return cuvsError_t"]
919    pub fn cuvsIvfPqTransform(
920        res: cuvsResources_t,
921        index: cuvsIvfPqIndex_t,
922        input_dataset: *mut DLManagedTensor,
923        output_labels: *mut DLManagedTensor,
924        output_dataset: *mut DLManagedTensor,
925    ) -> cuvsError_t;
926}
927#[repr(u32)]
928#[doc = " @brief Dtype to use for distance computation\n - `NND_DIST_COMP_AUTO`: Automatically determine the best dtype for distance computation based on the dataset dimensions.\n - `NND_DIST_COMP_FP32`: Use fp32 distance computation for better precision at the cost of performance and memory usage.\n - `NND_DIST_COMP_FP16`: Use fp16 distance computation."]
929#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
930pub enum cuvsNNDescentDistCompDtype {
931    NND_DIST_COMP_AUTO = 0,
932    NND_DIST_COMP_FP32 = 1,
933    NND_DIST_COMP_FP16 = 2,
934}
935#[doc = " @defgroup nn_descent_c_index_params The nn-descent algorithm parameters.\n @{\n/\n/**\n @brief Parameters used to build an nn-descent index\n\n `metric`: The distance metric to use\n `metric_arg`: The argument used by distance metrics like Minkowskidistance\n `graph_degree`: For an input dataset of dimensions (N, D),\n determines the final dimensions of the all-neighbors knn graph\n which turns out to be of dimensions (N, graph_degree)\n `intermediate_graph_degree`: Internally, nn-descent builds an\n all-neighbors knn graph of dimensions (N, intermediate_graph_degree)\n before selecting the final `graph_degree` neighbors. It's recommended\n that `intermediate_graph_degree` >= 1.5 * graph_degree\n `max_iterations`: The number of iterations that nn-descent will refine\n the graph for. More iterations produce a better quality graph at cost of performance\n `termination_threshold`: The delta at which nn-descent will terminate its iterations\n `return_distances`: Boolean to decide whether to return distances array\n `dist_comp_dtype`: dtype to use for distance computation. Defaults to `NND_DIST_COMP_AUTO` which automatically determines the best dtype for distance computation based on the dataset dimensions. Use `NND_DIST_COMP_FP32` for better precision at the cost of performance and memory usage. This option is only valid when data type is fp32. Use `NND_DIST_COMP_FP16` for better performance and memory usage at the cost of precision."]
936#[repr(C)]
937#[derive(Debug, Copy, Clone)]
938pub struct cuvsNNDescentIndexParams {
939    pub metric: cuvsDistanceType,
940    pub metric_arg: f32,
941    pub graph_degree: usize,
942    pub intermediate_graph_degree: usize,
943    pub max_iterations: usize,
944    pub termination_threshold: f32,
945    pub return_distances: bool,
946    pub dist_comp_dtype: cuvsNNDescentDistCompDtype,
947}
948#[allow(clippy::unnecessary_operation, clippy::identity_op)]
949const _: () = {
950    ["Size of cuvsNNDescentIndexParams"][::std::mem::size_of::<cuvsNNDescentIndexParams>() - 48usize];
951    ["Alignment of cuvsNNDescentIndexParams"][::std::mem::align_of::<cuvsNNDescentIndexParams>() - 8usize];
952    ["Offset of field: cuvsNNDescentIndexParams::metric"]
953        [::std::mem::offset_of!(cuvsNNDescentIndexParams, metric) - 0usize];
954    ["Offset of field: cuvsNNDescentIndexParams::metric_arg"]
955        [::std::mem::offset_of!(cuvsNNDescentIndexParams, metric_arg) - 4usize];
956    ["Offset of field: cuvsNNDescentIndexParams::graph_degree"]
957        [::std::mem::offset_of!(cuvsNNDescentIndexParams, graph_degree) - 8usize];
958    ["Offset of field: cuvsNNDescentIndexParams::intermediate_graph_degree"]
959        [::std::mem::offset_of!(cuvsNNDescentIndexParams, intermediate_graph_degree) - 16usize];
960    ["Offset of field: cuvsNNDescentIndexParams::max_iterations"]
961        [::std::mem::offset_of!(cuvsNNDescentIndexParams, max_iterations) - 24usize];
962    ["Offset of field: cuvsNNDescentIndexParams::termination_threshold"]
963        [::std::mem::offset_of!(cuvsNNDescentIndexParams, termination_threshold) - 32usize];
964    ["Offset of field: cuvsNNDescentIndexParams::return_distances"]
965        [::std::mem::offset_of!(cuvsNNDescentIndexParams, return_distances) - 36usize];
966    ["Offset of field: cuvsNNDescentIndexParams::dist_comp_dtype"]
967        [::std::mem::offset_of!(cuvsNNDescentIndexParams, dist_comp_dtype) - 40usize];
968};
969pub type cuvsNNDescentIndexParams_t = *mut cuvsNNDescentIndexParams;
970unsafe extern "C" {
971    #[must_use]
972    #[doc = " @brief Allocate NN-Descent Index params, and populate with default values\n\n @param[in] index_params cuvsNNDescentIndexParams_t to allocate\n @return cuvsError_t"]
973    pub fn cuvsNNDescentIndexParamsCreate(index_params: *mut cuvsNNDescentIndexParams_t) -> cuvsError_t;
974}
975unsafe extern "C" {
976    #[must_use]
977    #[doc = " @brief De-allocate NN-Descent Index params\n\n @param[in] index_params\n @return cuvsError_t"]
978    pub fn cuvsNNDescentIndexParamsDestroy(index_params: cuvsNNDescentIndexParams_t) -> cuvsError_t;
979}
980#[doc = " @defgroup nn_descent_c_index NN-Descent index\n @{\n/\n/**\n @brief Struct to hold address of cuvs::neighbors::nn_descent::index and its active trained dtype\n"]
981#[repr(C)]
982#[derive(Debug, Copy, Clone)]
983pub struct cuvsNNDescentIndex {
984    pub addr: usize,
985    pub dtype: DLDataType,
986}
987#[allow(clippy::unnecessary_operation, clippy::identity_op)]
988const _: () = {
989    ["Size of cuvsNNDescentIndex"][::std::mem::size_of::<cuvsNNDescentIndex>() - 16usize];
990    ["Alignment of cuvsNNDescentIndex"][::std::mem::align_of::<cuvsNNDescentIndex>() - 8usize];
991    ["Offset of field: cuvsNNDescentIndex::addr"][::std::mem::offset_of!(cuvsNNDescentIndex, addr) - 0usize];
992    ["Offset of field: cuvsNNDescentIndex::dtype"][::std::mem::offset_of!(cuvsNNDescentIndex, dtype) - 8usize];
993};
994pub type cuvsNNDescentIndex_t = *mut cuvsNNDescentIndex;
995unsafe extern "C" {
996    #[must_use]
997    #[doc = " @brief Allocate NN-Descent index\n\n @param[in] index cuvsNNDescentIndex_t to allocate\n @return cuvsError_t"]
998    pub fn cuvsNNDescentIndexCreate(index: *mut cuvsNNDescentIndex_t) -> cuvsError_t;
999}
1000unsafe extern "C" {
1001    #[must_use]
1002    #[doc = " @brief De-allocate NN-Descent index\n\n @param[in] index cuvsNNDescentIndex_t to de-allocate"]
1003    pub fn cuvsNNDescentIndexDestroy(index: cuvsNNDescentIndex_t) -> cuvsError_t;
1004}
1005unsafe extern "C" {
1006    #[must_use]
1007    #[doc = " @defgroup nn_descent_c_index_build NN-Descent index build\n @{\n/\n/**\n @brief Build a NN-Descent index with a `DLManagedTensor` which has underlying\n        `DLDeviceType` equal to `kDLCUDA`, `kDLCUDAHost`, `kDLCUDAManaged`,\n        or `kDLCPU`. Also, acceptable underlying types are:\n        1. `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 32`\n        2. `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 16`\n        3. `kDLDataType.code == kDLInt` and `kDLDataType.bits = 8`\n        4. `kDLDataType.code == kDLUInt` and `kDLDataType.bits = 8`\n\n @code {.c}\n #include <cuvs/core/c_api.h>\n #include <cuvs/neighbors/nn_descent.h>\n\n // Create cuvsResources_t\n cuvsResources_t res;\n cuvsError_t res_create_status = cuvsResourcesCreate(&res);\n\n // Assume a populated `DLManagedTensor` type here\n DLManagedTensor dataset;\n\n // Create default index params\n cuvsNNDescentIndexParams_t index_params;\n cuvsError_t params_create_status = cuvsNNDescentIndexParamsCreate(&index_params);\n\n // Create NN-Descent index\n cuvsNNDescentIndex_t index;\n cuvsError_t index_create_status = cuvsNNDescentIndexCreate(&index);\n\n // Build the NN-Descent Index\n cuvsError_t build_status = cuvsNNDescentBuild(res, index_params, &dataset, index);\n\n // de-allocate `index_params`, `index` and `res`\n cuvsError_t params_destroy_status = cuvsNNDescentIndexParamsDestroy(index_params);\n cuvsError_t index_destroy_status = cuvsNNDescentIndexDestroy(index);\n cuvsError_t res_destroy_status = cuvsResourcesDestroy(res);\n @endcode\n\n @param[in] res cuvsResources_t opaque C handle\n @param[in] index_params cuvsNNDescentIndexParams_t used to build NN-Descent index\n @param[in] dataset DLManagedTensor* training dataset on host or device memory\n @param[inout] graph Optional preallocated graph on host memory to store output\n @param[out] index cuvsNNDescentIndex_t Newly built NN-Descent index\n @return cuvsError_t"]
1008    pub fn cuvsNNDescentBuild(
1009        res: cuvsResources_t,
1010        index_params: cuvsNNDescentIndexParams_t,
1011        dataset: *mut DLManagedTensor,
1012        graph: *mut DLManagedTensor,
1013        index: cuvsNNDescentIndex_t,
1014    ) -> cuvsError_t;
1015}
1016unsafe extern "C" {
1017    #[must_use]
1018    #[doc = " @brief Get the KNN graph from a built NN-Descent index\n\n @param[in] res cuvsResources_t opaque C handle\n @param[in] index cuvsNNDescentIndex_t Built NN-Descent index\n @param[out] graph Preallocated graph on host memory to store output\n @return cuvsError_t"]
1019    pub fn cuvsNNDescentIndexGetGraph(
1020        res: cuvsResources_t,
1021        index: cuvsNNDescentIndex_t,
1022        graph: *mut DLManagedTensor,
1023    ) -> cuvsError_t;
1024}
1025unsafe extern "C" {
1026    #[must_use]
1027    #[doc = " @brief Get the distances from a build NN_Descent index\n\n This requires that the `return_distances` parameter was set when building the\n graph\n\n @param[in] res cuvsResources_t opaque C handle\n @param[in] index cuvsNNDescentIndex_t Built NN-Descent index\n @param[out] distances Preallocated memory to store the output distances tensor\n @return cuvsError_t"]
1028    pub fn cuvsNNDescentIndexGetDistances(
1029        res: cuvsResources_t,
1030        index: cuvsNNDescentIndex_t,
1031        distances: *mut DLManagedTensor,
1032    ) -> cuvsError_t;
1033}
1034#[repr(u32)]
1035#[doc = " @brief Graph build algorithm selection."]
1036#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
1037pub enum cuvsAllNeighborsAlgo {
1038    #[doc = "< Use Brute Force for local kNN subgraphs"]
1039    CUVS_ALL_NEIGHBORS_ALGO_BRUTE_FORCE = 0,
1040    #[doc = "< Use IVF-PQ for local kNN subgraphs (host dataset only)"]
1041    CUVS_ALL_NEIGHBORS_ALGO_IVF_PQ = 1,
1042    #[doc = "< Use NN-Descent for local kNN subgraphs"]
1043    CUVS_ALL_NEIGHBORS_ALGO_NN_DESCENT = 2,
1044}
1045#[doc = " @brief Parameters controlling SNMG all-neighbors build."]
1046#[repr(C)]
1047#[derive(Debug, Copy, Clone)]
1048pub struct cuvsAllNeighborsIndexParams {
1049    #[doc = "< Local kNN graph build algorithm"]
1050    pub algo: cuvsAllNeighborsAlgo,
1051    #[doc = "< Number of clusters each point is assigned to (must be < n_clusters)"]
1052    pub overlap_factor: usize,
1053    #[doc = "< Number of clusters/batches to partition the dataset into (> overlap_factor)"]
1054    pub n_clusters: usize,
1055    #[doc = "< Distance metric used for graph construction"]
1056    pub metric: cuvsDistanceType,
1057    #[doc = "< Parameters for IVF-PQ algorithm (when algo ==\n< CUVS_ALL_NEIGHBORS_ALGO_IVF_PQ)"]
1058    pub ivf_pq_params: cuvsIvfPqIndexParams_t,
1059    #[doc = "< Parameters for NN-Descent algorithm (when algo\n< == CUVS_ALL_NEIGHBORS_ALGO_NN_DESCENT)"]
1060    pub nn_descent_params: cuvsNNDescentIndexParams_t,
1061}
1062#[allow(clippy::unnecessary_operation, clippy::identity_op)]
1063const _: () = {
1064    ["Size of cuvsAllNeighborsIndexParams"][::std::mem::size_of::<cuvsAllNeighborsIndexParams>() - 48usize];
1065    ["Alignment of cuvsAllNeighborsIndexParams"][::std::mem::align_of::<cuvsAllNeighborsIndexParams>() - 8usize];
1066    ["Offset of field: cuvsAllNeighborsIndexParams::algo"]
1067        [::std::mem::offset_of!(cuvsAllNeighborsIndexParams, algo) - 0usize];
1068    ["Offset of field: cuvsAllNeighborsIndexParams::overlap_factor"]
1069        [::std::mem::offset_of!(cuvsAllNeighborsIndexParams, overlap_factor) - 8usize];
1070    ["Offset of field: cuvsAllNeighborsIndexParams::n_clusters"]
1071        [::std::mem::offset_of!(cuvsAllNeighborsIndexParams, n_clusters) - 16usize];
1072    ["Offset of field: cuvsAllNeighborsIndexParams::metric"]
1073        [::std::mem::offset_of!(cuvsAllNeighborsIndexParams, metric) - 24usize];
1074    ["Offset of field: cuvsAllNeighborsIndexParams::ivf_pq_params"]
1075        [::std::mem::offset_of!(cuvsAllNeighborsIndexParams, ivf_pq_params) - 32usize];
1076    ["Offset of field: cuvsAllNeighborsIndexParams::nn_descent_params"]
1077        [::std::mem::offset_of!(cuvsAllNeighborsIndexParams, nn_descent_params) - 40usize];
1078};
1079pub type cuvsAllNeighborsIndexParams_t = *mut cuvsAllNeighborsIndexParams;
1080unsafe extern "C" {
1081    #[must_use]
1082    #[doc = " @brief Create a default all-neighbors index parameters struct.\n\n @param[out] index_params  Pointer to allocated index_params struct\n\n @return cuvsError_t"]
1083    pub fn cuvsAllNeighborsIndexParamsCreate(index_params: *mut cuvsAllNeighborsIndexParams_t) -> cuvsError_t;
1084}
1085unsafe extern "C" {
1086    #[must_use]
1087    #[doc = " @brief Destroy an all-neighbors index parameters struct.\n\n @param[in] index_params  Index parameters struct to destroy\n\n @return cuvsError_t"]
1088    pub fn cuvsAllNeighborsIndexParamsDestroy(index_params: cuvsAllNeighborsIndexParams_t) -> cuvsError_t;
1089}
1090unsafe extern "C" {
1091    #[must_use]
1092    #[doc = " @brief Build an all-neighbors k-NN graph automatically detecting host vs device dataset.\n\n @param[in] res             Can be a SNMG multi-GPU resources (`cuvsResources_t`) or single-GPU\n resources\n @param[in] params          Build parameters (see cuvsAllNeighborsIndexParams)\n @param[in] dataset         2D tensor [num_rows x dim] on host or device (auto-detected)\n @param[out] indices        2D tensor [num_rows x k] (int64), host or device\n @param[out] distances      Optional 2D tensor [num_rows x k] (float32), host or device; can be\n                            NULL\n @param[out] core_distances Optional 1D tensor [num_rows] (float32), host or device; can be NULL\n @param[in] alpha           Mutual-reachability scaling; used only when core_distances is provided\n\n The function automatically detects whether the dataset is host-resident or device-resident\n and calls the appropriate implementation. For host datasets, it partitions data into\n `n_clusters` clusters and assigns each row to `overlap_factor` nearest clusters. For device\n datasets, `n_clusters` must be 1 (no batching); `overlap_factor` is ignored.\n\n Output memory space: a host dataset supports host- or device-resident outputs; a device dataset\n requires device-resident outputs. All provided outputs must share the same memory space."]
1093    pub fn cuvsAllNeighborsBuild(
1094        res: cuvsResources_t,
1095        params: cuvsAllNeighborsIndexParams_t,
1096        dataset: *mut DLManagedTensor,
1097        indices: *mut DLManagedTensor,
1098        distances: *mut DLManagedTensor,
1099        core_distances: *mut DLManagedTensor,
1100        alpha: f32,
1101    ) -> cuvsError_t;
1102}
1103#[repr(u32)]
1104#[doc = " @brief Enum to denote filter type."]
1105#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
1106pub enum cuvsFilterType {
1107    NO_FILTER = 0,
1108    BITSET = 1,
1109    BITMAP = 2,
1110}
1111#[doc = " @brief Struct to hold address of cuvs::neighbors::prefilter and its type\n\n `addr` points to a filter object owned by the caller; the library performs no caching of the\n underlying bitset across search calls. Allocating and populating the device bitset may be more\n expensive than a single filtered search, so callers that issue repeated searches against the same\n filter (e.g. many queries over one index) should build the bitset once and reuse the same\n cuvsFilter across those calls rather than rebuild it per search. Reusing the bitset is essential\n for realizing the full throughput of filtered search."]
1112#[repr(C)]
1113#[derive(Debug, Copy, Clone)]
1114pub struct cuvsFilter {
1115    pub addr: usize,
1116    pub type_: cuvsFilterType,
1117}
1118#[allow(clippy::unnecessary_operation, clippy::identity_op)]
1119const _: () = {
1120    ["Size of cuvsFilter"][::std::mem::size_of::<cuvsFilter>() - 16usize];
1121    ["Alignment of cuvsFilter"][::std::mem::align_of::<cuvsFilter>() - 8usize];
1122    ["Offset of field: cuvsFilter::addr"][::std::mem::offset_of!(cuvsFilter, addr) - 0usize];
1123    ["Offset of field: cuvsFilter::type_"][::std::mem::offset_of!(cuvsFilter, type_) - 8usize];
1124};
1125#[repr(u32)]
1126#[doc = " @brief Strategy for merging indices."]
1127#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
1128pub enum cuvsMergeStrategy {
1129    #[doc = "< Merge indices physically"]
1130    MERGE_STRATEGY_PHYSICAL = 0,
1131    #[doc = "< Merge indices logically"]
1132    MERGE_STRATEGY_LOGICAL = 1,
1133}
1134#[doc = " @defgroup bruteforce_c_index Bruteforce index\n @{\n/\n/**\n @brief Struct to hold address of cuvs::neighbors::brute_force::index and its active trained dtype\n"]
1135#[repr(C)]
1136#[derive(Debug, Copy, Clone)]
1137pub struct cuvsBruteForceIndex {
1138    pub addr: usize,
1139    pub dtype: DLDataType,
1140}
1141#[allow(clippy::unnecessary_operation, clippy::identity_op)]
1142const _: () = {
1143    ["Size of cuvsBruteForceIndex"][::std::mem::size_of::<cuvsBruteForceIndex>() - 16usize];
1144    ["Alignment of cuvsBruteForceIndex"][::std::mem::align_of::<cuvsBruteForceIndex>() - 8usize];
1145    ["Offset of field: cuvsBruteForceIndex::addr"][::std::mem::offset_of!(cuvsBruteForceIndex, addr) - 0usize];
1146    ["Offset of field: cuvsBruteForceIndex::dtype"][::std::mem::offset_of!(cuvsBruteForceIndex, dtype) - 8usize];
1147};
1148pub type cuvsBruteForceIndex_t = *mut cuvsBruteForceIndex;
1149unsafe extern "C" {
1150    #[must_use]
1151    #[doc = " @brief Allocate BRUTEFORCE index\n\n @param[in] index cuvsBruteForceIndex_t to allocate\n @return cuvsError_t"]
1152    pub fn cuvsBruteForceIndexCreate(index: *mut cuvsBruteForceIndex_t) -> cuvsError_t;
1153}
1154unsafe extern "C" {
1155    #[must_use]
1156    #[doc = " @brief De-allocate BRUTEFORCE index\n\n @param[in] index cuvsBruteForceIndex_t to de-allocate"]
1157    pub fn cuvsBruteForceIndexDestroy(index: cuvsBruteForceIndex_t) -> cuvsError_t;
1158}
1159unsafe extern "C" {
1160    #[must_use]
1161    #[doc = " @defgroup bruteforce_c_index_build Bruteforce index build\n @{\n/\n/**\n @brief Build a BRUTEFORCE index with a `DLManagedTensor` which has underlying\n        `DLDeviceType` equal to `kDLCUDA`, `kDLCUDAHost`, `kDLCUDAManaged`,\n        or `kDLCPU`. Also, acceptable underlying types are:\n        1. `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 32`\n        2. `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 16`\n\n @code {.c}\n #include <cuvs/core/c_api.h>\n #include <cuvs/neighbors/brute_force.h>\n\n // Create cuvsResources_t\n cuvsResources_t res;\n cuvsError_t res_create_status = cuvsResourcesCreate(&res);\n\n // Assume a populated `DLManagedTensor` type here\n DLManagedTensor dataset;\n\n // Create BRUTEFORCE index\n cuvsBruteForceIndex_t index;\n cuvsError_t index_create_status = cuvsBruteForceIndexCreate(&index);\n\n // Build the BRUTEFORCE Index\n cuvsError_t build_status = cuvsBruteForceBuild(res, &dataset_tensor, L2Expanded, 0.f, index);\n\n // de-allocate `index` and `res`\n cuvsError_t index_destroy_status = cuvsBruteForceIndexDestroy(index);\n cuvsError_t res_destroy_status = cuvsResourcesDestroy(res);\n @endcode\n\n @param[in] res cuvsResources_t opaque C handle\n @param[in] dataset DLManagedTensor* training dataset\n @param[in] metric metric\n @param[in] metric_arg metric_arg\n @param[out] index cuvsBruteForceIndex_t Newly built BRUTEFORCE index\n @return cuvsError_t"]
1162    pub fn cuvsBruteForceBuild(
1163        res: cuvsResources_t,
1164        dataset: *mut DLManagedTensor,
1165        metric: cuvsDistanceType,
1166        metric_arg: f32,
1167        index: cuvsBruteForceIndex_t,
1168    ) -> cuvsError_t;
1169}
1170unsafe extern "C" {
1171    #[must_use]
1172    #[doc = " @defgroup bruteforce_c_index_search Bruteforce index search\n @{\n/\n/**\n @brief Search a BRUTEFORCE index with a `DLManagedTensor` which has underlying\n        `DLDeviceType` equal to `kDLCUDA`, `kDLCUDAHost`, `kDLCUDAManaged`.\n        It is also important to note that the BRUTEFORCE index must have been built\n        with the same type of `queries`, such that `index.dtype.code ==\n        queries.dl_tensor.dtype.code` Types for input are:\n        1. `queries`: `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 32` or\n          `kDLDataType.bits = 16`\n        2. `neighbors`: `kDLDataType.code == kDLUInt` and `kDLDataType.bits = 32`\n        3. `distances`: `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 32`\n\n @code {.c}\n #include <cuvs/core/c_api.h>\n #include <cuvs/neighbors/brute_force.h>\n\n // Create cuvsResources_t\n cuvsResources_t res;\n cuvsError_t res_create_status = cuvsResourcesCreate(&res);\n\n // Assume a populated `DLManagedTensor` type here\n DLManagedTensor dataset;\n DLManagedTensor queries;\n DLManagedTensor neighbors;\n DLManagedTensor bitmap;\n\n cuvsFilter prefilter{(uintptr_t)&bitmap, BITMAP};\n\n // Search the `index` built using `cuvsBruteForceBuild`\n cuvsError_t search_status = cuvsBruteForceSearch(res, index, &queries, &neighbors, &distances,\n prefilter);\n\n // de-allocate `res`\n cuvsError_t res_destroy_status = cuvsResourcesDestroy(res);\n @endcode\n\n @param[in] res cuvsResources_t opaque C handle\n @param[in] index cuvsBruteForceIndex which has been returned by `cuvsBruteForceBuild`\n @param[in] queries DLManagedTensor* queries dataset to search\n @param[out] neighbors DLManagedTensor* output `k` neighbors for queries\n @param[out] distances DLManagedTensor* output `k` distances for queries\n @param[in] prefilter cuvsFilter input prefilter that can be used\nto filter queries and neighbors based on the given bitmap."]
1173    pub fn cuvsBruteForceSearch(
1174        res: cuvsResources_t,
1175        index: cuvsBruteForceIndex_t,
1176        queries: *mut DLManagedTensor,
1177        neighbors: *mut DLManagedTensor,
1178        distances: *mut DLManagedTensor,
1179        prefilter: cuvsFilter,
1180    ) -> cuvsError_t;
1181}
1182unsafe extern "C" {
1183    #[must_use]
1184    #[doc = " @defgroup bruteforce_c_index_serialize BRUTEFORCE C-API serialize functions\n @{\n/\n/**\n Save the index to file.\n The serialization format can be subject to changes, therefore loading\n an index saved with a previous version of cuvs is not guaranteed\n to work.\n\n @code{.c}\n #include <cuvs/neighbors/brute_force.h>\n\n // Create cuvsResources_t\n cuvsResources_t res;\n cuvsError_t res_create_status = cuvsResourcesCreate(&res);\n\n // create an index with `cuvsBruteforceBuild`\n cuvsBruteForceSerialize(res, \"/path/to/index\", index);\n @endcode\n\n @param[in] res cuvsResources_t opaque C handle\n @param[in] filename the file name for saving the index\n @param[in] index BRUTEFORCE index\n"]
1185    pub fn cuvsBruteForceSerialize(
1186        res: cuvsResources_t,
1187        filename: *const ::std::os::raw::c_char,
1188        index: cuvsBruteForceIndex_t,
1189    ) -> cuvsError_t;
1190}
1191unsafe extern "C" {
1192    #[must_use]
1193    #[doc = " Load index from file.\n The serialization format can be subject to changes, therefore loading\n an index saved with a previous version of cuvs is not guaranteed\n to work.\n\n @code{.c}\n #include <cuvs/neighbors/brute_force.h>\n\n // Create cuvsResources_t\n cuvsResources_t res;\n cuvsError_t res_create_status = cuvsResourcesCreate(&res);\n\n // Deserialize an index previously built with `cuvsBruteforceBuild`\n cuvsBruteForceIndex_t index;\n cuvsBruteForceIndexCreate(&index);\n cuvsBruteForceDeserialize(res, \"/path/to/index\", index);\n @endcode\n\n @param[in] res cuvsResources_t opaque C handle\n @param[in] filename the name of the file that stores the index\n @param[out] index BRUTEFORCE index loaded disk"]
1194    pub fn cuvsBruteForceDeserialize(
1195        res: cuvsResources_t,
1196        filename: *const ::std::os::raw::c_char,
1197        index: cuvsBruteForceIndex_t,
1198    ) -> cuvsError_t;
1199}
1200#[repr(u32)]
1201#[doc = " @brief Enum to denote which ANN algorithm is used to build CAGRA graph\n"]
1202#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
1203pub enum cuvsCagraGraphBuildAlgo {
1204    AUTO_SELECT = 0,
1205    IVF_PQ = 1,
1206    NN_DESCENT = 2,
1207    ITERATIVE_CAGRA_SEARCH = 3,
1208    #[doc = " Experimental, use ACE (Augmented Core Extraction) to build the graph. ACE partitions the\n dataset into core and augmented partitions and builds a sub-index for each partition. This\n enables building indices for datasets too large to fit in GPU or host memory.\n See cuvsAceParams for more details about the ACE algorithm and its parameters."]
1209    ACE = 4,
1210}
1211#[repr(u32)]
1212#[doc = " @brief A strategy for selecting the graph build parameters based on similar HNSW index\n parameters.\n\n Define how cuvsCagraIndexParamsFromHnswParams should construct a graph to construct a graph\n that is to be converted to (used by) a CPU HNSW index."]
1213#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
1214pub enum cuvsCagraHnswHeuristicType {
1215    #[doc = " Create a graph that is very similar to an HNSW graph in\n terms of the number of nodes and search performance. Since HNSW produces a variable-degree\n graph (2M being the max graph degree) and CAGRA produces a fixed-degree graph, there's always a\n difference in the performance of the two.\n\n This function attempts to produce such a graph that the QPS and recall of the two graphs being\n searched by HNSW are close for any search parameter combination. The CAGRA-produced graph tends\n to have a \"longer tail\" on the low recall side (that is being slightly faster and less\n precise).\n"]
1216    CUVS_CAGRA_HEURISTIC_SIMILAR_SEARCH_PERFORMANCE = 0,
1217    #[doc = " Create a graph that has the same binary size as an HNSW graph with the given parameters\n (graph_degree = 2 * M) while trying to match the search performance as closely as possible.\n\n The reference HNSW index and the corresponding from-CAGRA generated HNSW index will NOT produce\n the same recalls and QPS for the same parameter ef. The graphs are different internally. For\n the same ef, the from-CAGRA index likely has a slightly higher recall and slightly lower QPS.\n However, the Recall-QPS curves should be similar (i.e. the points are just shifted along the\n curve)."]
1218    CUVS_CAGRA_HEURISTIC_SAME_GRAPH_FOOTPRINT = 1,
1219}
1220#[doc = " Parameters for VPQ compression."]
1221#[repr(C)]
1222#[derive(Debug, Copy, Clone)]
1223pub struct cuvsCagraCompressionParams {
1224    #[doc = " The bit length of the vector element after compression by PQ.\n\n Possible values: [4, 5, 6, 7, 8].\n\n Hint: the smaller the 'pq_bits', the smaller the index size and the better the search\n performance, but the lower the recall."]
1225    pub pq_bits: u32,
1226    #[doc = " The dimensionality of the vector after compression by PQ.\n When zero, an optimal value is selected using a heuristic.\n\n TODO: at the moment `dim` must be a multiple `pq_dim`."]
1227    pub pq_dim: u32,
1228    #[doc = " Vector Quantization (VQ) codebook size - number of \"coarse cluster centers\".\n When zero, an optimal value is selected using a heuristic."]
1229    pub vq_n_centers: u32,
1230    #[doc = " The number of iterations searching for kmeans centers (both VQ & PQ phases)."]
1231    pub kmeans_n_iters: u32,
1232    #[doc = " The fraction of data to use during iterative kmeans building (VQ phase).\n When zero, an optimal value is selected using a heuristic."]
1233    pub vq_kmeans_trainset_fraction: f64,
1234    #[doc = " The fraction of data to use during iterative kmeans building (PQ phase).\n When zero, an optimal value is selected using a heuristic."]
1235    pub pq_kmeans_trainset_fraction: f64,
1236}
1237#[allow(clippy::unnecessary_operation, clippy::identity_op)]
1238const _: () = {
1239    ["Size of cuvsCagraCompressionParams"][::std::mem::size_of::<cuvsCagraCompressionParams>() - 32usize];
1240    ["Alignment of cuvsCagraCompressionParams"][::std::mem::align_of::<cuvsCagraCompressionParams>() - 8usize];
1241    ["Offset of field: cuvsCagraCompressionParams::pq_bits"]
1242        [::std::mem::offset_of!(cuvsCagraCompressionParams, pq_bits) - 0usize];
1243    ["Offset of field: cuvsCagraCompressionParams::pq_dim"]
1244        [::std::mem::offset_of!(cuvsCagraCompressionParams, pq_dim) - 4usize];
1245    ["Offset of field: cuvsCagraCompressionParams::vq_n_centers"]
1246        [::std::mem::offset_of!(cuvsCagraCompressionParams, vq_n_centers) - 8usize];
1247    ["Offset of field: cuvsCagraCompressionParams::kmeans_n_iters"]
1248        [::std::mem::offset_of!(cuvsCagraCompressionParams, kmeans_n_iters) - 12usize];
1249    ["Offset of field: cuvsCagraCompressionParams::vq_kmeans_trainset_fraction"]
1250        [::std::mem::offset_of!(cuvsCagraCompressionParams, vq_kmeans_trainset_fraction) - 16usize];
1251    ["Offset of field: cuvsCagraCompressionParams::pq_kmeans_trainset_fraction"]
1252        [::std::mem::offset_of!(cuvsCagraCompressionParams, pq_kmeans_trainset_fraction) - 24usize];
1253};
1254pub type cuvsCagraCompressionParams_t = *mut cuvsCagraCompressionParams;
1255#[repr(C)]
1256#[derive(Debug, Copy, Clone)]
1257pub struct cuvsIvfPqParams {
1258    pub ivf_pq_build_params: cuvsIvfPqIndexParams_t,
1259    pub ivf_pq_search_params: cuvsIvfPqSearchParams_t,
1260    pub refinement_rate: f32,
1261}
1262#[allow(clippy::unnecessary_operation, clippy::identity_op)]
1263const _: () = {
1264    ["Size of cuvsIvfPqParams"][::std::mem::size_of::<cuvsIvfPqParams>() - 24usize];
1265    ["Alignment of cuvsIvfPqParams"][::std::mem::align_of::<cuvsIvfPqParams>() - 8usize];
1266    ["Offset of field: cuvsIvfPqParams::ivf_pq_build_params"]
1267        [::std::mem::offset_of!(cuvsIvfPqParams, ivf_pq_build_params) - 0usize];
1268    ["Offset of field: cuvsIvfPqParams::ivf_pq_search_params"]
1269        [::std::mem::offset_of!(cuvsIvfPqParams, ivf_pq_search_params) - 8usize];
1270    ["Offset of field: cuvsIvfPqParams::refinement_rate"]
1271        [::std::mem::offset_of!(cuvsIvfPqParams, refinement_rate) - 16usize];
1272};
1273pub type cuvsIvfPqParams_t = *mut cuvsIvfPqParams;
1274#[doc = " Parameters for ACE (Augmented Core Extraction) graph build.\n ACE enables building indexes for datasets too large to fit in GPU memory by:\n 1. Partitioning the dataset in core (closest) and augmented (second-closest)\n partitions using balanced k-means.\n 2. Building sub-indexes for each partition independently\n 3. Concatenating sub-graphs into a final unified index"]
1275#[repr(C)]
1276#[derive(Debug, Copy, Clone)]
1277pub struct cuvsAceParams {
1278    #[doc = " Number of partitions for ACE (Augmented Core Extraction) partitioned build.\n\n When set to 0 (default), the number of partitions is automatically derived\n based on available host and GPU memory to maximize partition size while\n ensuring the build fits in memory.\n\n Small values might improve recall but potentially degrade performance and\n increase memory usage. Partitions should not be too small to prevent issues\n in KNN graph construction. The partition size is on average 2 * (n_rows /\n npartitions) * dim * sizeof(T). 2 is because of the core and augmented\n vectors. Please account for imbalance in the partition sizes (up to 3x in\n our tests).\n\n If the specified number of partitions results in partitions that exceed\n available memory, the value will be automatically increased to fit memory\n constraints and a warning will be issued."]
1279    pub npartitions: usize,
1280    #[doc = " The index quality for the ACE build.\n\n Bigger values increase the index quality. At some point, increasing this will no longer\n improve the quality."]
1281    pub ef_construction: usize,
1282    #[doc = " Directory to store ACE build artifacts (e.g., KNN graph, optimized graph).\n\n Used when `use_disk` is true or when the graph does not fit in host and GPU\n memory. This should be the fastest disk in the system and hold enough space\n for twice the dataset, final graph, and label mapping."]
1283    pub build_dir: *const ::std::os::raw::c_char,
1284    #[doc = " Whether to use disk-based storage for ACE build.\n\n When true, enables disk-based operations for memory-efficient graph construction."]
1285    pub use_disk: bool,
1286    #[doc = " Maximum host memory to use for ACE build in GiB.\n\n When set to 0 (default), uses available host memory.\n When set to a positive value, limits host memory usage to the specified amount.\n Useful for testing or when running alongside other memory-intensive processes."]
1287    pub max_host_memory_gb: f64,
1288    #[doc = " Maximum GPU memory to use for ACE build in GiB.\n\n When set to 0 (default), uses available GPU memory.\n When set to a positive value, limits GPU memory usage to the specified amount.\n Useful for testing or when running alongside other memory-intensive processes."]
1289    pub max_gpu_memory_gb: f64,
1290}
1291#[allow(clippy::unnecessary_operation, clippy::identity_op)]
1292const _: () = {
1293    ["Size of cuvsAceParams"][::std::mem::size_of::<cuvsAceParams>() - 48usize];
1294    ["Alignment of cuvsAceParams"][::std::mem::align_of::<cuvsAceParams>() - 8usize];
1295    ["Offset of field: cuvsAceParams::npartitions"][::std::mem::offset_of!(cuvsAceParams, npartitions) - 0usize];
1296    ["Offset of field: cuvsAceParams::ef_construction"]
1297        [::std::mem::offset_of!(cuvsAceParams, ef_construction) - 8usize];
1298    ["Offset of field: cuvsAceParams::build_dir"][::std::mem::offset_of!(cuvsAceParams, build_dir) - 16usize];
1299    ["Offset of field: cuvsAceParams::use_disk"][::std::mem::offset_of!(cuvsAceParams, use_disk) - 24usize];
1300    ["Offset of field: cuvsAceParams::max_host_memory_gb"]
1301        [::std::mem::offset_of!(cuvsAceParams, max_host_memory_gb) - 32usize];
1302    ["Offset of field: cuvsAceParams::max_gpu_memory_gb"]
1303        [::std::mem::offset_of!(cuvsAceParams, max_gpu_memory_gb) - 40usize];
1304};
1305pub type cuvsAceParams_t = *mut cuvsAceParams;
1306#[doc = " @brief Supplemental parameters to build CAGRA Index\n"]
1307#[repr(C)]
1308#[derive(Debug, Copy, Clone)]
1309pub struct cuvsCagraIndexParams {
1310    #[doc = " Distance type."]
1311    pub metric: cuvsDistanceType,
1312    #[doc = " Degree of input graph for pruning."]
1313    pub intermediate_graph_degree: usize,
1314    #[doc = " Degree of output graph."]
1315    pub graph_degree: usize,
1316    #[doc = " ANN algorithm to build knn graph."]
1317    pub build_algo: cuvsCagraGraphBuildAlgo,
1318    #[doc = " Number of Iterations to run if building with NN_DESCENT"]
1319    pub nn_descent_niter: usize,
1320    #[doc = " Optional: specify graph build params based on build_algo\n - IVF_PQ: cuvsIvfPqParams_t\n - ACE: cuvsAceParams_t\n - Others: nullptr"]
1321    pub graph_build_params: *mut ::std::os::raw::c_void,
1322}
1323#[allow(clippy::unnecessary_operation, clippy::identity_op)]
1324const _: () = {
1325    ["Size of cuvsCagraIndexParams"][::std::mem::size_of::<cuvsCagraIndexParams>() - 48usize];
1326    ["Alignment of cuvsCagraIndexParams"][::std::mem::align_of::<cuvsCagraIndexParams>() - 8usize];
1327    ["Offset of field: cuvsCagraIndexParams::metric"][::std::mem::offset_of!(cuvsCagraIndexParams, metric) - 0usize];
1328    ["Offset of field: cuvsCagraIndexParams::intermediate_graph_degree"]
1329        [::std::mem::offset_of!(cuvsCagraIndexParams, intermediate_graph_degree) - 8usize];
1330    ["Offset of field: cuvsCagraIndexParams::graph_degree"]
1331        [::std::mem::offset_of!(cuvsCagraIndexParams, graph_degree) - 16usize];
1332    ["Offset of field: cuvsCagraIndexParams::build_algo"]
1333        [::std::mem::offset_of!(cuvsCagraIndexParams, build_algo) - 24usize];
1334    ["Offset of field: cuvsCagraIndexParams::nn_descent_niter"]
1335        [::std::mem::offset_of!(cuvsCagraIndexParams, nn_descent_niter) - 32usize];
1336    ["Offset of field: cuvsCagraIndexParams::graph_build_params"]
1337        [::std::mem::offset_of!(cuvsCagraIndexParams, graph_build_params) - 40usize];
1338};
1339pub type cuvsCagraIndexParams_t = *mut cuvsCagraIndexParams;
1340unsafe extern "C" {
1341    #[must_use]
1342    #[doc = " @brief Allocate CAGRA Index params, and populate with default values\n\n @param[in] params cuvsCagraIndexParams_t to allocate\n @return cuvsError_t"]
1343    pub fn cuvsCagraIndexParamsCreate(params: *mut cuvsCagraIndexParams_t) -> cuvsError_t;
1344}
1345unsafe extern "C" {
1346    #[must_use]
1347    #[doc = " @brief De-allocate CAGRA Index params\n\n @param[in] params\n @return cuvsError_t"]
1348    pub fn cuvsCagraIndexParamsDestroy(params: cuvsCagraIndexParams_t) -> cuvsError_t;
1349}
1350unsafe extern "C" {
1351    #[must_use]
1352    #[doc = " @brief Allocate CAGRA Compression params, and populate with default values\n\n @param[in] params cuvsCagraCompressionParams_t to allocate\n @return cuvsError_t"]
1353    pub fn cuvsCagraCompressionParamsCreate(params: *mut cuvsCagraCompressionParams_t) -> cuvsError_t;
1354}
1355unsafe extern "C" {
1356    #[must_use]
1357    #[doc = " @brief De-allocate CAGRA Compression params\n\n @param[in] params\n @return cuvsError_t"]
1358    pub fn cuvsCagraCompressionParamsDestroy(params: cuvsCagraCompressionParams_t) -> cuvsError_t;
1359}
1360unsafe extern "C" {
1361    #[must_use]
1362    #[doc = " @brief Allocate ACE params, and populate with default values\n\n @param[in] params cuvsAceParams_t to allocate\n @return cuvsError_t"]
1363    pub fn cuvsAceParamsCreate(params: *mut cuvsAceParams_t) -> cuvsError_t;
1364}
1365unsafe extern "C" {
1366    #[must_use]
1367    #[doc = " @brief De-allocate ACE params\n\n @param[in] params\n @return cuvsError_t"]
1368    pub fn cuvsAceParamsDestroy(params: cuvsAceParams_t) -> cuvsError_t;
1369}
1370unsafe extern "C" {
1371    #[must_use]
1372    #[doc = " @brief Create CAGRA index parameters similar to an HNSW index\n\n This factory function creates CAGRA parameters that yield a graph compatible with\n an HNSW graph with the given parameters.\n\n @param[out] params The CAGRA index params to populate\n @param[in] n_rows Number of rows in the dataset\n @param[in] dim Number of dimensions in the dataset\n @param[in] M HNSW index parameter M\n @param[in] ef_construction HNSW index parameter ef_construction\n @param[in] heuristic Strategy for parameter selection\n @param[in] metric Distance metric to use\n @return cuvsError_t"]
1373    pub fn cuvsCagraIndexParamsFromHnswParams(
1374        params: cuvsCagraIndexParams_t,
1375        n_rows: i64,
1376        dim: i64,
1377        M: ::std::os::raw::c_int,
1378        ef_construction: ::std::os::raw::c_int,
1379        heuristic: cuvsCagraHnswHeuristicType,
1380        metric: cuvsDistanceType,
1381    ) -> cuvsError_t;
1382}
1383unsafe extern "C" {
1384    #[must_use]
1385    #[doc = " @brief Create CAGRA index parameters heuristically tuned for a dataset\n\n This factory function selects the graph build algorithm and its parameters based on the shape of\n the dataset.\n\n @param[out] params The CAGRA index params to populate\n @param[in] n_rows Number of rows in the dataset\n @param[in] dim Number of dimensions in the dataset\n @param[in] graph_degree Degree of the output graph\n @param[in] metric Distance metric to use\n @param[in] build_quality Higher values increase build quality (and cost) up to a point\n @return cuvsError_t"]
1386    pub fn cuvsCagraIndexParamsFromDataset(
1387        params: cuvsCagraIndexParams_t,
1388        n_rows: i64,
1389        dim: i64,
1390        graph_degree: usize,
1391        metric: cuvsDistanceType,
1392        build_quality: usize,
1393    ) -> cuvsError_t;
1394}
1395#[doc = " @defgroup cagra_c_extend_params C API for CUDA ANN Graph-based nearest neighbor search\n @{\n/\n/**\n @brief Supplemental parameters to extend CAGRA Index\n"]
1396#[repr(C)]
1397#[derive(Debug, Copy, Clone)]
1398pub struct cuvsCagraExtendParams {
1399    #[doc = " The additional dataset is divided into chunks and added to the graph. This is the knob to\n adjust the tradeoff between the recall and operation throughput. Large chunk sizes can result\n in high throughput, but use more working memory (O(max_chunk_size*degree^2)). This can also\n degrade recall because no edges are added between the nodes in the same chunk. Auto select when\n 0."]
1400    pub max_chunk_size: u32,
1401}
1402#[allow(clippy::unnecessary_operation, clippy::identity_op)]
1403const _: () = {
1404    ["Size of cuvsCagraExtendParams"][::std::mem::size_of::<cuvsCagraExtendParams>() - 4usize];
1405    ["Alignment of cuvsCagraExtendParams"][::std::mem::align_of::<cuvsCagraExtendParams>() - 4usize];
1406    ["Offset of field: cuvsCagraExtendParams::max_chunk_size"]
1407        [::std::mem::offset_of!(cuvsCagraExtendParams, max_chunk_size) - 0usize];
1408};
1409pub type cuvsCagraExtendParams_t = *mut cuvsCagraExtendParams;
1410unsafe extern "C" {
1411    #[must_use]
1412    #[doc = " @brief Allocate CAGRA Extend params, and populate with default values\n\n @param[in] params cuvsCagraExtendParams_t to allocate\n @return cuvsError_t"]
1413    pub fn cuvsCagraExtendParamsCreate(params: *mut cuvsCagraExtendParams_t) -> cuvsError_t;
1414}
1415unsafe extern "C" {
1416    #[must_use]
1417    #[doc = " @brief De-allocate CAGRA Extend params\n\n @param[in] params\n @return cuvsError_t"]
1418    pub fn cuvsCagraExtendParamsDestroy(params: cuvsCagraExtendParams_t) -> cuvsError_t;
1419}
1420#[repr(u32)]
1421#[doc = " @brief Enum to denote algorithm used to search CAGRA Index\n"]
1422#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
1423pub enum cuvsCagraSearchAlgo {
1424    #[doc = " For large batch sizes."]
1425    SINGLE_CTA = 0,
1426    #[doc = " For small batch sizes."]
1427    MULTI_CTA = 1,
1428    #[doc = " For small batch sizes."]
1429    MULTI_KERNEL = 2,
1430    #[doc = " For small batch sizes."]
1431    AUTO = 100,
1432}
1433#[repr(u32)]
1434#[doc = " @brief Enum to denote Hash Mode used while searching CAGRA index\n"]
1435#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
1436pub enum cuvsCagraHashMode {
1437    HASH = 0,
1438    SMALL = 1,
1439    AUTO_HASH = 100,
1440}
1441#[doc = " @brief Supplemental parameters to search CAGRA index\n"]
1442#[repr(C)]
1443#[derive(Debug, Copy, Clone)]
1444pub struct cuvsCagraSearchParams {
1445    #[doc = " Maximum number of queries to search at the same time (batch size). Auto select when 0."]
1446    pub max_queries: usize,
1447    #[doc = " Number of intermediate search results retained during the search.\n\n  This is the main knob to adjust trade off between accuracy and search speed.\n  Higher values improve the search accuracy."]
1448    pub itopk_size: usize,
1449    #[doc = " Upper limit of search iterations. Auto select when 0."]
1450    pub max_iterations: usize,
1451    #[doc = " Which search implementation to use."]
1452    pub algo: cuvsCagraSearchAlgo,
1453    #[doc = " Number of threads used to calculate a single distance. 4, 8, 16, or 32."]
1454    pub team_size: usize,
1455    #[doc = " Number of graph nodes to select as the starting point for the search in each iteration. aka\n search width?"]
1456    pub search_width: usize,
1457    #[doc = " Lower limit of search iterations."]
1458    pub min_iterations: usize,
1459    #[doc = " Thread block size. 0, 64, 128, 256, 512, 1024. Auto selection when 0."]
1460    pub thread_block_size: usize,
1461    #[doc = " Hashmap type. Auto selection when AUTO."]
1462    pub hashmap_mode: cuvsCagraHashMode,
1463    #[doc = " Lower limit of hashmap bit length. More than 8."]
1464    pub hashmap_min_bitlen: usize,
1465    #[doc = " Upper limit of hashmap fill rate. More than 0.1, less than 0.9."]
1466    pub hashmap_max_fill_rate: f32,
1467    #[doc = " Number of iterations of initial random seed node selection. 1 or more."]
1468    pub num_random_samplings: u32,
1469    #[doc = " Bit mask used for initial random seed node selection."]
1470    pub rand_xor_mask: u64,
1471    #[doc = " Whether to use the persistent version of the kernel (only SINGLE_CTA is supported a.t.m.)"]
1472    pub persistent: bool,
1473    #[doc = " Persistent kernel: time in seconds before the kernel stops if no requests received."]
1474    pub persistent_lifetime: f32,
1475    #[doc = " Set the fraction of maximum grid size used by persistent kernel.\n Value 1.0 means the kernel grid size is maximum possible for the selected device.\n The value must be greater than 0.0 and not greater than 1.0.\n\n One may need to run other kernels alongside this persistent kernel. This parameter can\n be used to reduce the grid size of the persistent kernel to leave a few SMs idle.\n Note: running any other work on GPU alongside with the persistent kernel makes the setup\n fragile.\n   - Running another kernel in another thread usually works, but no progress guaranteed\n   - Any CUDA allocations block the context (this issue may be obscured by using pools)\n   - Memory copies to not-pinned host memory may block the context\n\n Even when we know there are no other kernels working at the same time, setting\n kDeviceUsage to 1.0 surprisingly sometimes hurts performance. Proceed with care.\n If you suspect this is an issue, you can reduce this number to ~0.9 without a significant\n impact on the throughput."]
1476    pub persistent_device_usage: f32,
1477}
1478#[allow(clippy::unnecessary_operation, clippy::identity_op)]
1479const _: () = {
1480    ["Size of cuvsCagraSearchParams"][::std::mem::size_of::<cuvsCagraSearchParams>() - 112usize];
1481    ["Alignment of cuvsCagraSearchParams"][::std::mem::align_of::<cuvsCagraSearchParams>() - 8usize];
1482    ["Offset of field: cuvsCagraSearchParams::max_queries"]
1483        [::std::mem::offset_of!(cuvsCagraSearchParams, max_queries) - 0usize];
1484    ["Offset of field: cuvsCagraSearchParams::itopk_size"]
1485        [::std::mem::offset_of!(cuvsCagraSearchParams, itopk_size) - 8usize];
1486    ["Offset of field: cuvsCagraSearchParams::max_iterations"]
1487        [::std::mem::offset_of!(cuvsCagraSearchParams, max_iterations) - 16usize];
1488    ["Offset of field: cuvsCagraSearchParams::algo"][::std::mem::offset_of!(cuvsCagraSearchParams, algo) - 24usize];
1489    ["Offset of field: cuvsCagraSearchParams::team_size"]
1490        [::std::mem::offset_of!(cuvsCagraSearchParams, team_size) - 32usize];
1491    ["Offset of field: cuvsCagraSearchParams::search_width"]
1492        [::std::mem::offset_of!(cuvsCagraSearchParams, search_width) - 40usize];
1493    ["Offset of field: cuvsCagraSearchParams::min_iterations"]
1494        [::std::mem::offset_of!(cuvsCagraSearchParams, min_iterations) - 48usize];
1495    ["Offset of field: cuvsCagraSearchParams::thread_block_size"]
1496        [::std::mem::offset_of!(cuvsCagraSearchParams, thread_block_size) - 56usize];
1497    ["Offset of field: cuvsCagraSearchParams::hashmap_mode"]
1498        [::std::mem::offset_of!(cuvsCagraSearchParams, hashmap_mode) - 64usize];
1499    ["Offset of field: cuvsCagraSearchParams::hashmap_min_bitlen"]
1500        [::std::mem::offset_of!(cuvsCagraSearchParams, hashmap_min_bitlen) - 72usize];
1501    ["Offset of field: cuvsCagraSearchParams::hashmap_max_fill_rate"]
1502        [::std::mem::offset_of!(cuvsCagraSearchParams, hashmap_max_fill_rate) - 80usize];
1503    ["Offset of field: cuvsCagraSearchParams::num_random_samplings"]
1504        [::std::mem::offset_of!(cuvsCagraSearchParams, num_random_samplings) - 84usize];
1505    ["Offset of field: cuvsCagraSearchParams::rand_xor_mask"]
1506        [::std::mem::offset_of!(cuvsCagraSearchParams, rand_xor_mask) - 88usize];
1507    ["Offset of field: cuvsCagraSearchParams::persistent"]
1508        [::std::mem::offset_of!(cuvsCagraSearchParams, persistent) - 96usize];
1509    ["Offset of field: cuvsCagraSearchParams::persistent_lifetime"]
1510        [::std::mem::offset_of!(cuvsCagraSearchParams, persistent_lifetime) - 100usize];
1511    ["Offset of field: cuvsCagraSearchParams::persistent_device_usage"]
1512        [::std::mem::offset_of!(cuvsCagraSearchParams, persistent_device_usage) - 104usize];
1513};
1514pub type cuvsCagraSearchParams_t = *mut cuvsCagraSearchParams;
1515unsafe extern "C" {
1516    #[must_use]
1517    #[doc = " @brief Allocate CAGRA search params, and populate with default values\n\n @param[in] params cuvsCagraSearchParams_t to allocate\n @return cuvsError_t"]
1518    pub fn cuvsCagraSearchParamsCreate(params: *mut cuvsCagraSearchParams_t) -> cuvsError_t;
1519}
1520unsafe extern "C" {
1521    #[must_use]
1522    #[doc = " @brief De-allocate CAGRA search params\n\n @param[in] params\n @return cuvsError_t"]
1523    pub fn cuvsCagraSearchParamsDestroy(params: cuvsCagraSearchParams_t) -> cuvsError_t;
1524}
1525#[doc = " @brief Struct holding the CAGRA index storage address and vector element dtype (DLPack-style)\n\n Matches the usual cuVS C index pattern (`addr` + `dtype`). \\p addr points at implementation-owned\n storage (not always a bare `cagra::index*`); free only via \\ref cuvsCagraIndexDestroy. \\p dtype\n describes index vector elements for queries and template dispatch."]
1526#[repr(C)]
1527#[derive(Debug, Copy, Clone)]
1528pub struct cuvsCagraIndex {
1529    pub addr: usize,
1530    pub dtype: DLDataType,
1531}
1532#[allow(clippy::unnecessary_operation, clippy::identity_op)]
1533const _: () = {
1534    ["Size of cuvsCagraIndex"][::std::mem::size_of::<cuvsCagraIndex>() - 16usize];
1535    ["Alignment of cuvsCagraIndex"][::std::mem::align_of::<cuvsCagraIndex>() - 8usize];
1536    ["Offset of field: cuvsCagraIndex::addr"][::std::mem::offset_of!(cuvsCagraIndex, addr) - 0usize];
1537    ["Offset of field: cuvsCagraIndex::dtype"][::std::mem::offset_of!(cuvsCagraIndex, dtype) - 8usize];
1538};
1539pub type cuvsCagraIndex_t = *mut cuvsCagraIndex;
1540unsafe extern "C" {
1541    #[must_use]
1542    #[doc = " @brief Allocate CAGRA index\n\n @param[in] index cuvsCagraIndex_t to allocate\n @return cagraError_t"]
1543    pub fn cuvsCagraIndexCreate(index: *mut cuvsCagraIndex_t) -> cuvsError_t;
1544}
1545unsafe extern "C" {
1546    #[must_use]
1547    #[doc = " @brief De-allocate CAGRA index\n\n @param[in] index cuvsCagraIndex_t to de-allocate"]
1548    pub fn cuvsCagraIndexDestroy(index: cuvsCagraIndex_t) -> cuvsError_t;
1549}
1550unsafe extern "C" {
1551    #[must_use]
1552    #[doc = " @brief Get dimension of the CAGRA index\n\n @param[in] index CAGRA index\n @param[out] dim return dimension of the index\n @return cuvsError_t"]
1553    pub fn cuvsCagraIndexGetDims(index: cuvsCagraIndex_t, dim: *mut i64) -> cuvsError_t;
1554}
1555unsafe extern "C" {
1556    #[must_use]
1557    #[doc = " @brief Get size of the CAGRA index\n\n @param[in] index CAGRA index\n @param[out] size return number of vectors in the index\n @return cuvsError_t"]
1558    pub fn cuvsCagraIndexGetSize(index: cuvsCagraIndex_t, size: *mut i64) -> cuvsError_t;
1559}
1560unsafe extern "C" {
1561    #[must_use]
1562    #[doc = " @brief Get graph degree of the CAGRA index\n\n @param[in] index CAGRA index\n @param[out] graph_degree return graph degree\n @return cuvsError_t"]
1563    pub fn cuvsCagraIndexGetGraphDegree(index: cuvsCagraIndex_t, graph_degree: *mut i64) -> cuvsError_t;
1564}
1565unsafe extern "C" {
1566    #[must_use]
1567    #[doc = " @brief Returns a view of the CAGRA dataset\n\n This function returns a non-owning view of the CAGRA dataset.\n The output will be referencing device memory that is directly used\n in CAGRA, without copying the dataset at all. This means that the\n output is only valid as long as the CAGRA index is alive, and once\n cuvsCagraIndexDestroy is called on the cagra index - the returned\n dataset view will be invalid.\n\n Note that the DLManagedTensor dataset returned will have an associated\n 'deleter' function that must be called when the dataset is no longer\n needed. This will free up host memory that stores the shape of the\n dataset view.\n\n @param[in] index CAGRA index\n @param[out] dataset the dataset used in cagra\n @return cuvsError_t"]
1568    pub fn cuvsCagraIndexGetDataset(index: cuvsCagraIndex_t, dataset: *mut DLManagedTensor) -> cuvsError_t;
1569}
1570unsafe extern "C" {
1571    #[must_use]
1572    #[doc = " @brief Returns a view of the CAGRA graph\n\n This function returns a non-owning view of the CAGRA graph.\n The output will be referencing device memory that is directly used\n in CAGRA, without copying the graph at all. This means that the\n output is only valid as long as the CAGRA index is alive, and once\n cuvsCagraIndexDestroy is called on the cagra index - the returned\n graph view will be invalid.\n\n Note that the DLManagedTensor graph returned will have an associated\n 'deleter' function that must be called when the graph is no longer\n needed. This will free up host memory that stores the metadata for the\n graph view.\n\n @param[in] index CAGRA index\n @param[out] graph the output knn graph.\n @return cuvsError_t"]
1573    pub fn cuvsCagraIndexGetGraph(index: cuvsCagraIndex_t, graph: *mut DLManagedTensor) -> cuvsError_t;
1574}
1575unsafe extern "C" {
1576    #[must_use]
1577    #[doc = " @brief Update a CAGRA index with a device-padded dataset.\n\n This is the centralized dataset update operation for C callers. If \\p index\n is already device-padded, its dataset view is replaced in place. Otherwise,\n the index is converted and its opaque handle is rebound to a search-ready\n device-padded index. Caller retains ownership of\n \\p device_padded_dataset and must keep it alive while \\p index uses it.\n\n @param[in] res             cuvsResources_t opaque C handle\n @param[in] device_padded_dataset owning or non-owning device-padded dataset handle\n @param[inout] index        CAGRA index handle\n @return cuvsError_t"]
1578    pub fn cuvsCagraUpdateDataset(
1579        res: cuvsResources_t,
1580        device_padded_dataset: cuvsDataset_t,
1581        index: cuvsCagraIndex_t,
1582    ) -> cuvsError_t;
1583}
1584unsafe extern "C" {
1585    #[must_use]
1586    #[doc = " @brief Build a CAGRA index from a dataset handle. Acceptable underlying\n        types are:\n        1. `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 32`\n        2. `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 16`\n        3. `kDLDataType.code == kDLInt` and `kDLDataType.bits = 8`\n        4. `kDLDataType.code == kDLUInt` and `kDLDataType.bits = 8`\n\n The memory space and layout \\p dataset was constructed with select the C++ build overload.\n Build the handle with an owning factory or the matching dataset view factory\n (`cuvsDatasetMakePaddedView` / `cuvsDatasetMakeStandardView`).\n\n Note that a dataset residing in host memory produces a host-backed index, which\n must be made search-ready with `cuvsCagraUpdateDataset` (using a device-padded\n dataset) before calling `cuvsCagraSearch`.\n\n @code {.c}\n #include <cuvs/core/c_api.h>\n #include <cuvs/neighbors/cagra.h>\n\n // Create cuvsResources_t\n cuvsResources_t res;\n cuvsError_t res_create_status = cuvsResourcesCreate(&res);\n\n // Assume a populated `DLManagedTensor` type here holding a device padded dataset\n DLManagedTensor dataset;\n\n // Wrap it in a non-owning dataset handle\n cuvsDataset_t dataset_view;\n cuvsError_t view_create_status = cuvsDatasetMakePaddedView(res, &dataset, &dataset_view);\n\n // Create default index params\n cuvsCagraIndexParams_t params;\n cuvsError_t params_create_status = cuvsCagraIndexParamsCreate(&params);\n\n // Create CAGRA index\n cuvsCagraIndex_t index;\n cuvsError_t index_create_status = cuvsCagraIndexCreate(&index);\n\n // Build the CAGRA Index\n cuvsError_t build_status = cuvsCagraBuild(res, params, dataset_view, index);\n\n // de-allocate `dataset_view`, `params`, `index` and `res`\n cuvsError_t view_destroy_status = cuvsDatasetDestroy(dataset_view);\n cuvsError_t params_destroy_status = cuvsCagraIndexParamsDestroy(params);\n cuvsError_t index_destroy_status = cuvsCagraIndexDestroy(index);\n cuvsError_t res_destroy_status = cuvsResourcesDestroy(res);\n @endcode\n\n @param[in] res cuvsResources_t opaque C handle\n @param[in] params cuvsCagraIndexParams_t used to build CAGRA index\n @param[in] dataset cuvsDataset_t training dataset or dataset view\n @param[inout] index cuvsCagraIndex_t Newly built CAGRA index. This index needs to be already\n                                      created with cuvsCagraIndexCreate.\n @return cuvsError_t"]
1587    pub fn cuvsCagraBuild(
1588        res: cuvsResources_t,
1589        params: cuvsCagraIndexParams_t,
1590        dataset: cuvsDataset_t,
1591        index: cuvsCagraIndex_t,
1592    ) -> cuvsError_t;
1593}
1594unsafe extern "C" {
1595    #[must_use]
1596    #[doc = " @brief Extend a CAGRA index with a caller-owned pre-concatenated padded dataset.\n\n The caller must build `extended_dataset` as `old || new` (size `n_old + n_new`) before calling.\n Rows `[0, new_start_row)` are the original vectors; rows `[new_start_row, n_rows)` are the\n additional vectors. `new_start_row` must equal the current index size. The library only extends\n the graph and rebinds the index to `extended_dataset`; keep that dataset alive for the index\n lifetime.\n\n @param[in] res cuvsResources_t opaque C handle\n @param[in] params cuvsCagraExtendParams_t used to extend CAGRA index\n @param[in] extended_dataset cuvsDataset_t caller-owned device-padded dataset of old || new\n @param[in] new_start_row row index where the additional vectors begin\n @param[in,out] index cuvsCagraIndex_t CAGRA index\n @return cuvsError_t"]
1597    pub fn cuvsCagraExtend(
1598        res: cuvsResources_t,
1599        params: cuvsCagraExtendParams_t,
1600        extended_dataset: cuvsDataset_t,
1601        new_start_row: i64,
1602        index: cuvsCagraIndex_t,
1603    ) -> cuvsError_t;
1604}
1605unsafe extern "C" {
1606    #[must_use]
1607    #[doc = " @defgroup cagra_c_index_search C API for CUDA ANN Graph-based nearest neighbor search\n @{\n/\n/**\n @brief Search a CAGRA index with a `DLManagedTensor` which has underlying\n        `DLDeviceType` equal to `kDLCUDA`, `kDLCUDAHost`, `kDLCUDAManaged`.\n        It is also important to note that the CAGRA Index must have been built\n        with the same type of `queries`, such that `index.dtype.code ==\n queries.dl_tensor.dtype.code` Types for input are:\n        1. `queries`:\n          a. `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 32`\n          b. `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 16`\n          c. `kDLDataType.code == kDLInt` and `kDLDataType.bits = 8`\n          d. `kDLDataType.code == kDLUInt` and `kDLDataType.bits = 8`\n        2. `neighbors`: `kDLDataType.code == kDLUInt` and `kDLDataType.bits = 32`\n                     or `kDLDataType.code == kDLInt`  and `kDLDataType.bits = 64`\n        3. `distances`: `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 32`\n\n @code {.c}\n #include <cuvs/core/c_api.h>\n #include <cuvs/neighbors/cagra.h>\n\n // Create cuvsResources_t\n cuvsResources_t res;\n cuvsError_t res_create_status = cuvsResourcesCreate(&res);\n\n // Assume a populated `DLManagedTensor` type here\n DLManagedTensor dataset;\n DLManagedTensor queries;\n DLManagedTensor neighbors;\n\n // Create default search params\n cuvsCagraSearchParams_t params;\n cuvsError_t params_create_status = cuvsCagraSearchParamsCreate(&params);\n\n // Search the `index` built using `cuvsCagraBuild`\n cuvsError_t search_status = cuvsCagraSearch(res, params, index, &queries, &neighbors,\n &distances);\n\n // de-allocate `params` and `res`\n cuvsError_t params_destroy_status = cuvsCagraSearchParamsDestroy(params);\n cuvsError_t res_destroy_status = cuvsResourcesDestroy(res);\n @endcode\n\n @param[in] res cuvsResources_t opaque C handle\n @param[in] params cuvsCagraSearchParams_t used to search CAGRA index\n @param[in] index cuvsCagraIndex which has been returned by `cuvsCagraBuild`\n @param[in] queries DLManagedTensor* queries dataset to search\n @param[out] neighbors DLManagedTensor* output `k` neighbors for queries\n @param[out] distances DLManagedTensor* output `k` distances for queries\n @param[in] filter cuvsFilter input filter that can be used\nto filter queries and neighbors based on the given bitset."]
1608    pub fn cuvsCagraSearch(
1609        res: cuvsResources_t,
1610        params: cuvsCagraSearchParams_t,
1611        index: cuvsCagraIndex_t,
1612        queries: *mut DLManagedTensor,
1613        neighbors: *mut DLManagedTensor,
1614        distances: *mut DLManagedTensor,
1615        filter: cuvsFilter,
1616    ) -> cuvsError_t;
1617}
1618unsafe extern "C" {
1619    #[must_use]
1620    #[doc = " @brief Search multiple CAGRA index partitions concurrently and return the global top-k per\n query.\n\n For each query row, the function searches all partitions in parallel into an internal\n intermediate buffer, applies per-partition distance post-processing, runs a batched top-k\n merge across partitions, and writes the final outputs to the caller-supplied device tensors.\n All work is submitted to the CUDA stream associated with @p res; use @c cuvsStreamSync to\n wait for completion.\n\n The index element type may be float32, float16, int8, or uint8. All partitions must share the\n same element type, and the queries must use that same type.\n\n @param[in]  res            cuvsResources_t opaque C handle\n @param[in]  params         search parameters (shared across partitions)\n @param[in]  num_partitions number of index partitions\n @param[in]  indices        array of num_partitions cuvsCagraIndex_t pointers, all of the same\n                            element type\n @param[in]  queries        DLManagedTensor* (device, same dtype as the indices, [n_queries,\n                            dim]); the queries matrix is searched against every partition\n @param[out] partition_ids  DLManagedTensor* (device, uint32, [n_queries, k]); which partition\n                            each returned neighbor came from\n @param[out] neighbors      DLManagedTensor* (device, uint32 or int64, [n_queries, k]); ordinal\n                            in the corresponding partition's dataset\n @param[out] distances      DLManagedTensor* (device, float32, [n_queries, k]); post-processed\n                            distance for each (query, neighbor)\n @param[in]  filters        array of `num_partitions` filters, one per partition (or NULL for a\n                            fully unfiltered search). `filters[i]` applies to partition `i`: use\n                            {.type=NO_FILTER, .addr=0} for no filter on that partition, or\n                            {.type=BITSET, .addr=ptr} where ptr is a uintptr_t-cast\n                            DLManagedTensor* holding that partition's own bitset (one bit per\n                            vector in that partition; standard 32-bit packing)."]
1621    pub fn cuvsCagraSearchMultiPartition(
1622        res: cuvsResources_t,
1623        params: cuvsCagraSearchParams_t,
1624        num_partitions: u32,
1625        indices: *mut cuvsCagraIndex_t,
1626        queries: *mut DLManagedTensor,
1627        partition_ids: *mut DLManagedTensor,
1628        neighbors: *mut DLManagedTensor,
1629        distances: *mut DLManagedTensor,
1630        filters: *mut cuvsFilter,
1631    ) -> cuvsError_t;
1632}
1633unsafe extern "C" {
1634    #[must_use]
1635    #[doc = " @defgroup cagra_c_index_serialize CAGRA C-API serialize functions\n @{\n/\n/**\n Save the CAGRA graph to file without its dataset.\n\n Experimental, both the API and the serialization format are subject to change.\n\n @param[in] res cuvsResources_t opaque C handle\n @param[in] filename the file name for saving the graph\n @param[in] index CAGRA index"]
1636    pub fn cuvsCagraSerializeGraph(
1637        res: cuvsResources_t,
1638        filename: *const ::std::os::raw::c_char,
1639        index: cuvsCagraIndex_t,
1640    ) -> cuvsError_t;
1641}
1642unsafe extern "C" {
1643    #[must_use]
1644    #[doc = " Save the CAGRA graph and its attached dataset to file.\n\n The index stores a non-owning dataset view. The caller must keep the dataset backing that view\n alive while this function runs. Returns CUVS_ERROR without modifying the destination file if\n the index has no attached dataset.\n\n Experimental, both the API and the serialization format are subject to change.\n\n @param[in] res cuvsResources_t opaque C handle\n @param[in] filename the file name for saving the graph and dataset\n @param[in] index CAGRA index with an attached host or device dataset"]
1645    pub fn cuvsCagraSerializeGraphAndDataset(
1646        res: cuvsResources_t,
1647        filename: *const ::std::os::raw::c_char,
1648        index: cuvsCagraIndex_t,
1649    ) -> cuvsError_t;
1650}
1651unsafe extern "C" {
1652    #[must_use]
1653    #[doc = " Save the CAGRA index to file in hnswlib format.\n NOTE: The saved index can only be read by the hnswlib wrapper in cuVS,\n       as the serialization format is not compatible with the original hnswlib.\n\n Experimental, both the API and the serialization format are subject to change.\n\n @code{.c}\n #include <cuvs/core/c_api.h>\n #include <cuvs/neighbors/cagra.h>\n\n // Create cuvsResources_t\n cuvsResources_t res;\n cuvsError_t res_create_status = cuvsResourcesCreate(&res);\n\n // create an index with `cuvsCagraBuild`\n cuvsCagraSerializeHnswlib(res, \"/path/to/index\", index);\n @endcode\n\n @param[in] res cuvsResources_t opaque C handle\n @param[in] filename the file name for saving the index\n @param[in] index CAGRA index\n"]
1654    pub fn cuvsCagraSerializeToHnswlib(
1655        res: cuvsResources_t,
1656        filename: *const ::std::os::raw::c_char,
1657        index: cuvsCagraIndex_t,
1658    ) -> cuvsError_t;
1659}
1660unsafe extern "C" {
1661    #[must_use]
1662    #[doc = " Load the CAGRA graph from file without retaining a serialized dataset.\n\n This succeeds whether or not the file contains a dataset. Use cuvsCagraUpdateDataset to attach a\n caller-owned device-padded dataset view before searching the graph-only index.\n\n Experimental, both the API and the serialization format are subject to change.\n\n @param[in] res cuvsResources_t opaque C handle\n @param[in] filename the name of the file that stores the index\n @param[inout] index pre-created CAGRA index populated on success and unchanged on failure"]
1663    pub fn cuvsCagraDeserializeGraph(
1664        res: cuvsResources_t,
1665        filename: *const ::std::os::raw::c_char,
1666        index: cuvsCagraIndex_t,
1667    ) -> cuvsError_t;
1668}
1669unsafe extern "C" {
1670    #[must_use]
1671    #[doc = " Load the CAGRA graph and dataset from file.\n\n The returned owning dataset preserves the serialized host/device memory type and\n standard/padded layout. The index stores a non-owning view into it, so the caller must keep the\n dataset alive while the index uses it and destroy it separately with cuvsDatasetDestroy. Only a\n device-padded result is immediately searchable through the C API; attach a caller-owned\n device-padded view with cuvsCagraUpdateDataset for any other kind. The output pointer\n must point to a null handle on entry; deserialization acts as a factory and transfers ownership\n of the allocated dataset handle on success. Returns CUVS_ERROR when the file has no dataset; the\n index and output handle are unchanged on failure.\n\n Experimental, both the API and the serialization format are subject to change.\n\n @param[in] res cuvsResources_t opaque C handle\n @param[in] filename the name of the file that stores the graph and dataset\n @param[inout] index pre-created CAGRA index populated on success and unchanged on failure\n @param[out] out_dataset receives the allocated owning dataset handle; must point to null on entry"]
1672    pub fn cuvsCagraDeserializeGraphAndDataset(
1673        res: cuvsResources_t,
1674        filename: *const ::std::os::raw::c_char,
1675        index: cuvsCagraIndex_t,
1676        out_dataset: *mut cuvsDataset_t,
1677    ) -> cuvsError_t;
1678}
1679unsafe extern "C" {
1680    #[must_use]
1681    #[doc = " Load index from a dataset and graph\n\n @param[in] res cuvsResources_t opaque C handle\n @param[in] metric cuvsDistanceType to use in the index\n @param[in] graph the knn graph to use, shape (size, graph_degree)\n @param[in] dataset the dataset to use, shape (size, dim)\n @param[inout] index cuvsCagraIndex_t CAGRA index populated with the graph and dataset.\n                                      This index needs to be already created with\n                                      cuvsCagraIndexCreate.\n\n @code {.c}\n #include <cuvs/core/c_api.h>\n #include <cuvs/neighbors/cagra.h>\n\n // Create cuvsResources_t\n cuvsResources_t res;\n cuvsError_t res_create_status = cuvsResourcesCreate(&res);\n\n // Create CAGRA index\n cuvsCagraIndex_t index;\n cuvsError_t index_create_status = cuvsCagraIndexCreate(&index);\n\n // Assume a populated `DLManagedTensor` type here for the graph and dataset\n DLManagedTensor dataset;\n DLManagedTensor graph;\n\n cuvsDistanceType metric = L2Expanded;\n\n // Build the CAGRA Index from the graph/dataset\n cuvsError_t status = cuvsCagraIndexFromArgs(res, metric, &graph, &dataset, index);\n\n @endcode"]
1682    pub fn cuvsCagraIndexFromArgs(
1683        res: cuvsResources_t,
1684        metric: cuvsDistanceType,
1685        graph: *mut DLManagedTensor,
1686        dataset: *mut DLManagedTensor,
1687        index: cuvsCagraIndex_t,
1688    ) -> cuvsError_t;
1689}
1690unsafe extern "C" {
1691    #[must_use]
1692    #[doc = " @brief Merge multiple CAGRA indices into a single CAGRA index.\n\n All input indices must have been built with the same data type (`index.dtype`) and\n have the same dimensionality (`index.dims`). The merged index uses the output\n parameters specified in `cuvsCagraIndexParams`.\n\n Input indices must have:\n  - `index.dtype.code` and `index.dtype.bits` matching across all indices.\n  - Supported data types for indices:\n      a. `kDLFloat` with `bits = 32`\n      b. `kDLFloat` with `bits = 16`\n      c. `kDLInt` with `bits = 8`\n      d. `kDLUInt` with `bits = 8`\n\n The resulting output index will have the same data type as the input indices.\n\n Example:\n @code{.c}\n #include <cuvs/core/c_api.h>\n #include <cuvs/neighbors/cagra.h>\n\n cuvsResources_t res;\n cuvsError_t res_create_status = cuvsResourcesCreate(&res);\n\n cuvsCagraIndex_t index1, index2, merged_index;\n cuvsCagraIndexCreate(&index1);\n cuvsCagraIndexCreate(&index2);\n cuvsCagraIndexCreate(&merged_index);\n\n // Assume index1 and index2 have device datasets and were built using cuvsCagraBuild.\n\n cuvsCagraIndexParams_t merge_params;\n cuvsError_t params_create_status = cuvsCagraIndexParamsCreate(&merge_params);\n\n cuvsDataset_t merged_dataset;\n cuvsDatasetCreate(&merged_dataset);\n cuvsFilter filter = {.type = NO_FILTER, .addr = 0};\n\n cuvsError_t merge_status = cuvsCagraMerge(res, merge_params, (cuvsCagraIndex_t[]){index1,\n index2}, 2, filter, merged_dataset, merged_index);\n\n // Use merged_index for search operations\n\n cuvsCagraIndexDestroy(merged_index);\n cuvsDatasetDestroy(merged_dataset);\n cuvsError_t params_destroy_status = cuvsCagraIndexParamsDestroy(merge_params);\n cuvsError_t res_destroy_status = cuvsResourcesDestroy(res);\n @endcode\n\n @param[in] res cuvsResources_t opaque C handle\n @param[in] params cuvsCagraIndexParams_t parameters controlling merge behavior\n @param[in] indices Array of input cuvsCagraIndex_t handles to merge\n @param[in] num_indices Number of input indices\n @param[in] filter Filter that can be used to filter out vectors from the merged index\n @param[out] merged_dataset Empty owning dataset handle. Merge first attempts to allocate and\n                            populate device storage with the same layout as the input indices. For\n                            an unfiltered merge, if device allocation fails, it falls back to host\n                            storage and returns a host-backed output index. Keep this dataset alive\n                            while using \\p output_index. A host-backed output index must be updated\n                            with `cuvsCagraUpdateDataset` before device search.\n @param[out] output_index Output handle that will store the merged index.\n                          Must be initialized using `cuvsCagraIndexCreate` before use."]
1693    pub fn cuvsCagraMerge(
1694        res: cuvsResources_t,
1695        params: cuvsCagraIndexParams_t,
1696        indices: *mut cuvsCagraIndex_t,
1697        num_indices: usize,
1698        filter: cuvsFilter,
1699        merged_dataset: cuvsDataset_t,
1700        output_index: cuvsCagraIndex_t,
1701    ) -> cuvsError_t;
1702}
1703#[doc = " @defgroup ivf_flat_c_index_params IVF-Flat index build parameters\n @{\n/\n/**\n @brief Supplemental parameters to build IVF-Flat Index\n"]
1704#[repr(C)]
1705#[derive(Debug, Copy, Clone)]
1706pub struct cuvsIvfFlatIndexParams {
1707    #[doc = " Distance type."]
1708    pub metric: cuvsDistanceType,
1709    #[doc = " The argument used by some distance metrics."]
1710    pub metric_arg: f32,
1711    #[doc = " Whether to add the dataset content to the index, i.e.:\n\n  - `true` means the index is filled with the dataset vectors and ready to search after calling\n `build`.\n  - `false` means `build` only trains the underlying model (e.g. quantizer or clustering), but\n the index is left empty; you'd need to call `extend` on the index afterwards to populate it."]
1712    pub add_data_on_build: bool,
1713    #[doc = " The number of inverted lists (clusters)"]
1714    pub n_lists: u32,
1715    #[doc = " The number of iterations searching for kmeans centers (index building)."]
1716    pub kmeans_n_iters: u32,
1717    #[doc = " The fraction of data to use during iterative kmeans building."]
1718    pub kmeans_trainset_fraction: f64,
1719    #[doc = " By default (adaptive_centers = false), the cluster centers are trained in `ivf_flat::build`,\n and never modified in `ivf_flat::extend`. As a result, you may need to retrain the index\n from scratch after invoking (`ivf_flat::extend`) a few times with new data, the distribution of\n which is no longer representative of the original training set.\n\n The alternative behavior (adaptive_centers = true) is to update the cluster centers for new\n data when it is added. In this case, `index.centers()` are always exactly the centroids of the\n data in the corresponding clusters. The drawback of this behavior is that the centroids depend\n on the order of adding new data (through the classification of the added data); that is,\n `index.centers()` \"drift\" together with the changing distribution of the newly added data."]
1720    pub adaptive_centers: bool,
1721    #[doc = " By default, the algorithm allocates more space than necessary for individual clusters\n (`list_data`). This allows to amortize the cost of memory allocation and reduce the number of\n data copies during repeated calls to `extend` (extending the database).\n\n The alternative is the conservative allocation behavior; when enabled, the algorithm always\n allocates the minimum amount of memory required to store the given number of records. Set this\n flag to `true` if you prefer to use as little GPU memory for the database as possible."]
1722    pub conservative_memory_allocation: bool,
1723}
1724#[allow(clippy::unnecessary_operation, clippy::identity_op)]
1725const _: () = {
1726    ["Size of cuvsIvfFlatIndexParams"][::std::mem::size_of::<cuvsIvfFlatIndexParams>() - 40usize];
1727    ["Alignment of cuvsIvfFlatIndexParams"][::std::mem::align_of::<cuvsIvfFlatIndexParams>() - 8usize];
1728    ["Offset of field: cuvsIvfFlatIndexParams::metric"]
1729        [::std::mem::offset_of!(cuvsIvfFlatIndexParams, metric) - 0usize];
1730    ["Offset of field: cuvsIvfFlatIndexParams::metric_arg"]
1731        [::std::mem::offset_of!(cuvsIvfFlatIndexParams, metric_arg) - 4usize];
1732    ["Offset of field: cuvsIvfFlatIndexParams::add_data_on_build"]
1733        [::std::mem::offset_of!(cuvsIvfFlatIndexParams, add_data_on_build) - 8usize];
1734    ["Offset of field: cuvsIvfFlatIndexParams::n_lists"]
1735        [::std::mem::offset_of!(cuvsIvfFlatIndexParams, n_lists) - 12usize];
1736    ["Offset of field: cuvsIvfFlatIndexParams::kmeans_n_iters"]
1737        [::std::mem::offset_of!(cuvsIvfFlatIndexParams, kmeans_n_iters) - 16usize];
1738    ["Offset of field: cuvsIvfFlatIndexParams::kmeans_trainset_fraction"]
1739        [::std::mem::offset_of!(cuvsIvfFlatIndexParams, kmeans_trainset_fraction) - 24usize];
1740    ["Offset of field: cuvsIvfFlatIndexParams::adaptive_centers"]
1741        [::std::mem::offset_of!(cuvsIvfFlatIndexParams, adaptive_centers) - 32usize];
1742    ["Offset of field: cuvsIvfFlatIndexParams::conservative_memory_allocation"]
1743        [::std::mem::offset_of!(cuvsIvfFlatIndexParams, conservative_memory_allocation) - 33usize];
1744};
1745pub type cuvsIvfFlatIndexParams_t = *mut cuvsIvfFlatIndexParams;
1746unsafe extern "C" {
1747    #[must_use]
1748    #[doc = " @brief Allocate IVF-Flat Index params, and populate with default values\n\n @param[in] index_params cuvsIvfFlatIndexParams_t to allocate\n @return cuvsError_t"]
1749    pub fn cuvsIvfFlatIndexParamsCreate(index_params: *mut cuvsIvfFlatIndexParams_t) -> cuvsError_t;
1750}
1751unsafe extern "C" {
1752    #[must_use]
1753    #[doc = " @brief De-allocate IVF-Flat Index params\n\n @param[in] index_params\n @return cuvsError_t"]
1754    pub fn cuvsIvfFlatIndexParamsDestroy(index_params: cuvsIvfFlatIndexParams_t) -> cuvsError_t;
1755}
1756#[doc = " @defgroup ivf_flat_c_search_params IVF-Flat index search parameters\n @{\n/\n/**\n @brief Supplemental parameters to search IVF-Flat index\n"]
1757#[repr(C)]
1758#[derive(Debug, Copy, Clone)]
1759pub struct cuvsIvfFlatSearchParams {
1760    #[doc = " The number of clusters to search."]
1761    pub n_probes: u32,
1762}
1763#[allow(clippy::unnecessary_operation, clippy::identity_op)]
1764const _: () = {
1765    ["Size of cuvsIvfFlatSearchParams"][::std::mem::size_of::<cuvsIvfFlatSearchParams>() - 4usize];
1766    ["Alignment of cuvsIvfFlatSearchParams"][::std::mem::align_of::<cuvsIvfFlatSearchParams>() - 4usize];
1767    ["Offset of field: cuvsIvfFlatSearchParams::n_probes"]
1768        [::std::mem::offset_of!(cuvsIvfFlatSearchParams, n_probes) - 0usize];
1769};
1770pub type cuvsIvfFlatSearchParams_t = *mut cuvsIvfFlatSearchParams;
1771unsafe extern "C" {
1772    #[must_use]
1773    #[doc = " @brief Allocate IVF-Flat search params, and populate with default values\n\n @param[in] params cuvsIvfFlatSearchParams_t to allocate\n @return cuvsError_t"]
1774    pub fn cuvsIvfFlatSearchParamsCreate(params: *mut cuvsIvfFlatSearchParams_t) -> cuvsError_t;
1775}
1776unsafe extern "C" {
1777    #[must_use]
1778    #[doc = " @brief De-allocate IVF-Flat search params\n\n @param[in] params\n @return cuvsError_t"]
1779    pub fn cuvsIvfFlatSearchParamsDestroy(params: cuvsIvfFlatSearchParams_t) -> cuvsError_t;
1780}
1781#[doc = " @defgroup ivf_flat_c_index IVF-Flat index\n @{\n/\n/**\n @brief Struct to hold address of cuvs::neighbors::ivf_flat::index and its active trained dtype\n"]
1782#[repr(C)]
1783#[derive(Debug, Copy, Clone)]
1784pub struct cuvsIvfFlatIndex {
1785    pub addr: usize,
1786    pub dtype: DLDataType,
1787}
1788#[allow(clippy::unnecessary_operation, clippy::identity_op)]
1789const _: () = {
1790    ["Size of cuvsIvfFlatIndex"][::std::mem::size_of::<cuvsIvfFlatIndex>() - 16usize];
1791    ["Alignment of cuvsIvfFlatIndex"][::std::mem::align_of::<cuvsIvfFlatIndex>() - 8usize];
1792    ["Offset of field: cuvsIvfFlatIndex::addr"][::std::mem::offset_of!(cuvsIvfFlatIndex, addr) - 0usize];
1793    ["Offset of field: cuvsIvfFlatIndex::dtype"][::std::mem::offset_of!(cuvsIvfFlatIndex, dtype) - 8usize];
1794};
1795pub type cuvsIvfFlatIndex_t = *mut cuvsIvfFlatIndex;
1796unsafe extern "C" {
1797    #[must_use]
1798    #[doc = " @brief Allocate IVF-Flat index\n\n @param[in] index cuvsIvfFlatIndex_t to allocate\n @return cuvsError_t"]
1799    pub fn cuvsIvfFlatIndexCreate(index: *mut cuvsIvfFlatIndex_t) -> cuvsError_t;
1800}
1801unsafe extern "C" {
1802    #[must_use]
1803    #[doc = " @brief De-allocate IVF-Flat index\n\n @param[in] index cuvsIvfFlatIndex_t to de-allocate"]
1804    pub fn cuvsIvfFlatIndexDestroy(index: cuvsIvfFlatIndex_t) -> cuvsError_t;
1805}
1806unsafe extern "C" {
1807    #[must_use]
1808    #[doc = " @brief Get the number of clusters/inverted lists in the index\n\n @param[in] index cuvsIvfFlatIndex_t Built IVF-Flat index\n @param[out] n_lists Pointer to store the number of lists\n @return cuvsError_t"]
1809    pub fn cuvsIvfFlatIndexGetNLists(index: cuvsIvfFlatIndex_t, n_lists: *mut i64) -> cuvsError_t;
1810}
1811unsafe extern "C" {
1812    #[must_use]
1813    #[doc = " @brief Get the dimensionality of the indexed data\n\n @param[in] index cuvsIvfFlatIndex_t Built IVF-Flat index\n @param[out] dim Pointer to store the dimensionality\n @return cuvsError_t"]
1814    pub fn cuvsIvfFlatIndexGetDim(index: cuvsIvfFlatIndex_t, dim: *mut i64) -> cuvsError_t;
1815}
1816unsafe extern "C" {
1817    #[must_use]
1818    #[doc = " @brief Get the cluster centers corresponding to the lists [n_lists, dim]\n\n @param[in] index cuvsIvfFlatIndex_t Built Ivf-Flat Index\n @param[out] centers Preallocated array on host or device memory to store output, [n_lists, dim]\n @return cuvsError_t"]
1819    pub fn cuvsIvfFlatIndexGetCenters(index: cuvsIvfFlatIndex_t, centers: *mut DLManagedTensor) -> cuvsError_t;
1820}
1821unsafe extern "C" {
1822    #[must_use]
1823    #[doc = " @defgroup ivf_flat_c_index_build IVF-Flat index build\n @{\n/\n/**\n @brief Build a IVF-Flat index with a `DLManagedTensor` which has underlying\n        `DLDeviceType` equal to `kDLCUDA`, `kDLCUDAHost`, `kDLCUDAManaged`,\n        or `kDLCPU`. Also, acceptable underlying types are:\n        1. `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 32`\n        2. `kDLDataType.code == kDLInt` and `kDLDataType.bits = 8`\n        3. `kDLDataType.code == kDLUInt` and `kDLDataType.bits = 8`\n\n @code {.c}\n #include <cuvs/core/c_api.h>\n #include <cuvs/neighbors/ivf_flat.h>\n\n // Create cuvsResources_t\n cuvsResources_t res;\n cuvsError_t res_create_status = cuvsResourcesCreate(&res);\n\n // Assume a populated `DLManagedTensor` type here\n DLManagedTensor dataset;\n\n // Create default index params\n cuvsIvfFlatIndexParams_t index_params;\n cuvsError_t params_create_status = cuvsIvfFlatIndexParamsCreate(&index_params);\n\n // Create IVF-Flat index\n cuvsIvfFlatIndex_t index;\n cuvsError_t index_create_status = cuvsIvfFlatIndexCreate(&index);\n\n // Build the IVF-Flat Index\n cuvsError_t build_status = cuvsIvfFlatBuild(res, index_params, &dataset, index);\n\n // de-allocate `index_params`, `index` and `res`\n cuvsError_t params_destroy_status = cuvsIvfFlatIndexParamsDestroy(index_params);\n cuvsError_t index_destroy_status = cuvsIvfFlatIndexDestroy(index);\n cuvsError_t res_destroy_status = cuvsResourcesDestroy(res);\n @endcode\n\n @param[in] res cuvsResources_t opaque C handle\n @param[in] index_params cuvsIvfFlatIndexParams_t used to build IVF-Flat index\n @param[in] dataset DLManagedTensor* training dataset\n @param[out] index cuvsIvfFlatIndex_t Newly built IVF-Flat index\n @return cuvsError_t"]
1824    pub fn cuvsIvfFlatBuild(
1825        res: cuvsResources_t,
1826        index_params: cuvsIvfFlatIndexParams_t,
1827        dataset: *mut DLManagedTensor,
1828        index: cuvsIvfFlatIndex_t,
1829    ) -> cuvsError_t;
1830}
1831unsafe extern "C" {
1832    #[must_use]
1833    #[doc = " @defgroup ivf_flat_c_index_search IVF-Flat index search\n @{\n/\n/**\n @brief Search a IVF-Flat index with a `DLManagedTensor` which has underlying\n        `DLDeviceType` equal to `kDLCUDA`, `kDLCUDAHost`, `kDLCUDAManaged`.\n        It is also important to note that the IVF-Flat Index must have been built\n        with the same type of `queries`, such that `index.dtype.code ==\n queries.dl_tensor.dtype.code` Types for input are:\n        1. `queries`: `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 32`\n        2. `neighbors`: `kDLDataType.code == kDLUInt` and `kDLDataType.bits = 32`\n        3. `distances`: `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 32`\n\n @code {.c}\n #include <cuvs/core/c_api.h>\n #include <cuvs/neighbors/ivf_flat.h>\n\n // Create cuvsResources_t\n cuvsResources_t res;\n cuvsError_t res_create_status = cuvsResourcesCreate(&res);\n\n // Assume a populated `DLManagedTensor` type here\n DLManagedTensor dataset;\n DLManagedTensor queries;\n DLManagedTensor neighbors;\n\n // Create default search params\n cuvsIvfFlatSearchParams_t search_params;\n cuvsError_t params_create_status = cuvsIvfFlatSearchParamsCreate(&search_params);\n\n // Search the `index` built using `ivfFlatBuild`\n cuvsError_t search_status = cuvsIvfFlatSearch(res, search_params, index, &queries, &neighbors,\n &distances);\n\n // de-allocate `search_params` and `res`\n cuvsError_t params_destroy_status = cuvsIvfFlatSearchParamsDestroy(search_params);\n cuvsError_t res_destroy_status = cuvsResourcesDestroy(res);\n @endcode\n\n @param[in] res cuvsResources_t opaque C handle\n @param[in] search_params cuvsIvfFlatSearchParams_t used to search IVF-Flat index\n @param[in] index ivfFlatIndex which has been returned by `ivfFlatBuild`\n @param[in] queries DLManagedTensor* queries dataset to search\n @param[out] neighbors DLManagedTensor* output `k` neighbors for queries\n @param[out] distances DLManagedTensor* output `k` distances for queries\n @param[in] filter cuvsFilter input filter that can be used\nto filter queries and neighbors based on the given bitset."]
1834    pub fn cuvsIvfFlatSearch(
1835        res: cuvsResources_t,
1836        search_params: cuvsIvfFlatSearchParams_t,
1837        index: cuvsIvfFlatIndex_t,
1838        queries: *mut DLManagedTensor,
1839        neighbors: *mut DLManagedTensor,
1840        distances: *mut DLManagedTensor,
1841        filter: cuvsFilter,
1842    ) -> cuvsError_t;
1843}
1844unsafe extern "C" {
1845    #[must_use]
1846    #[doc = " @defgroup ivf_flat_c_index_serialize IVF-Flat C-API serialize functions\n @{\n/\n/**\n Save the index to file.\n\n Experimental, both the API and the serialization format are subject to change.\n\n @code{.cpp}\n #include <cuvs/neighbors/ivf_flat.h>\n\n // Create cuvsResources_t\n cuvsResources_t res;\n cuvsError_t res_create_status = cuvsResourcesCreate(&res);\n\n // create an index with `cuvsIvfFlatBuild`\n cuvsIvfFlatSerialize(res, \"/path/to/index\", index, true);\n @endcode\n\n @param[in] res cuvsResources_t opaque C handle\n @param[in] filename the file name for saving the index\n @param[in] index IVF-Flat index"]
1847    pub fn cuvsIvfFlatSerialize(
1848        res: cuvsResources_t,
1849        filename: *const ::std::os::raw::c_char,
1850        index: cuvsIvfFlatIndex_t,
1851    ) -> cuvsError_t;
1852}
1853unsafe extern "C" {
1854    #[must_use]
1855    #[doc = " Load index from file.\n\n Experimental, both the API and the serialization format are subject to change.\n\n @param[in] res cuvsResources_t opaque C handle\n @param[in] filename the name of the file that stores the index\n @param[out] index IVF-Flat index loaded disk"]
1856    pub fn cuvsIvfFlatDeserialize(
1857        res: cuvsResources_t,
1858        filename: *const ::std::os::raw::c_char,
1859        index: cuvsIvfFlatIndex_t,
1860    ) -> cuvsError_t;
1861}
1862unsafe extern "C" {
1863    #[must_use]
1864    #[doc = " @defgroup ivf_flat_c_index_extend IVF-Flat index extend\n @{\n/\n/**\n @brief Extend the index with the new data.\n\n @param[in] res cuvsResources_t opaque C handle\n @param[in] new_vectors DLManagedTensor* the new vectors to add to the index\n @param[in] new_indices DLManagedTensor* vector of new indices for the new vectors\n @param[inout] index IVF-Flat index to be extended\n @return cuvsError_t"]
1865    pub fn cuvsIvfFlatExtend(
1866        res: cuvsResources_t,
1867        new_vectors: *mut DLManagedTensor,
1868        new_indices: *mut DLManagedTensor,
1869        index: cuvsIvfFlatIndex_t,
1870    ) -> cuvsError_t;
1871}
1872#[doc = " @defgroup ivf_sq_c_index_params IVF-SQ index build parameters\n @{\n/\n/**\n @brief Supplemental parameters to build IVF-SQ Index\n"]
1873#[repr(C)]
1874#[derive(Debug, Copy, Clone)]
1875pub struct cuvsIvfSqIndexParams {
1876    #[doc = " Distance type."]
1877    pub metric: cuvsDistanceType,
1878    #[doc = " The argument used by some distance metrics."]
1879    pub metric_arg: f32,
1880    #[doc = " Whether to add the dataset content to the index, i.e.:\n\n  - `true` means the index is filled with the dataset vectors and ready to search after calling\n `build`.\n  - `false` means `build` only trains the underlying model (e.g. quantizer or clustering), but\n the index is left empty; you'd need to call `extend` on the index afterwards to populate it."]
1881    pub add_data_on_build: bool,
1882    #[doc = " The number of inverted lists (clusters)"]
1883    pub n_lists: u32,
1884    #[doc = " The number of iterations searching for kmeans centers (index building)."]
1885    pub kmeans_n_iters: u32,
1886    #[doc = " The number of data vectors per cluster to use during iterative kmeans building.\n The index uses at most `n_lists * max_train_points_per_cluster` rows for training."]
1887    pub max_train_points_per_cluster: u32,
1888    #[doc = " By default, the algorithm allocates more space than necessary for individual clusters\n (`list_data`). This allows to amortize the cost of memory allocation and reduce the number of\n data copies during repeated calls to `extend` (extending the database).\n\n The alternative is the conservative allocation behavior; when enabled, the algorithm always\n allocates the minimum amount of memory required to store the given number of records. Set this\n flag to `true` if you prefer to use as little GPU memory for the database as possible."]
1889    pub conservative_memory_allocation: bool,
1890}
1891#[allow(clippy::unnecessary_operation, clippy::identity_op)]
1892const _: () = {
1893    ["Size of cuvsIvfSqIndexParams"][::std::mem::size_of::<cuvsIvfSqIndexParams>() - 28usize];
1894    ["Alignment of cuvsIvfSqIndexParams"][::std::mem::align_of::<cuvsIvfSqIndexParams>() - 4usize];
1895    ["Offset of field: cuvsIvfSqIndexParams::metric"][::std::mem::offset_of!(cuvsIvfSqIndexParams, metric) - 0usize];
1896    ["Offset of field: cuvsIvfSqIndexParams::metric_arg"]
1897        [::std::mem::offset_of!(cuvsIvfSqIndexParams, metric_arg) - 4usize];
1898    ["Offset of field: cuvsIvfSqIndexParams::add_data_on_build"]
1899        [::std::mem::offset_of!(cuvsIvfSqIndexParams, add_data_on_build) - 8usize];
1900    ["Offset of field: cuvsIvfSqIndexParams::n_lists"][::std::mem::offset_of!(cuvsIvfSqIndexParams, n_lists) - 12usize];
1901    ["Offset of field: cuvsIvfSqIndexParams::kmeans_n_iters"]
1902        [::std::mem::offset_of!(cuvsIvfSqIndexParams, kmeans_n_iters) - 16usize];
1903    ["Offset of field: cuvsIvfSqIndexParams::max_train_points_per_cluster"]
1904        [::std::mem::offset_of!(cuvsIvfSqIndexParams, max_train_points_per_cluster) - 20usize];
1905    ["Offset of field: cuvsIvfSqIndexParams::conservative_memory_allocation"]
1906        [::std::mem::offset_of!(cuvsIvfSqIndexParams, conservative_memory_allocation) - 24usize];
1907};
1908pub type cuvsIvfSqIndexParams_t = *mut cuvsIvfSqIndexParams;
1909unsafe extern "C" {
1910    #[must_use]
1911    #[doc = " @brief Allocate IVF-SQ Index params, and populate with default values\n\n @param[in] index_params cuvsIvfSqIndexParams_t to allocate\n @return cuvsError_t"]
1912    pub fn cuvsIvfSqIndexParamsCreate(index_params: *mut cuvsIvfSqIndexParams_t) -> cuvsError_t;
1913}
1914unsafe extern "C" {
1915    #[must_use]
1916    #[doc = " @brief De-allocate IVF-SQ Index params\n\n @param[in] index_params\n @return cuvsError_t"]
1917    pub fn cuvsIvfSqIndexParamsDestroy(index_params: cuvsIvfSqIndexParams_t) -> cuvsError_t;
1918}
1919#[doc = " @defgroup ivf_sq_c_search_params IVF-SQ index search parameters\n @{\n/\n/**\n @brief Supplemental parameters to search IVF-SQ index\n"]
1920#[repr(C)]
1921#[derive(Debug, Copy, Clone)]
1922pub struct cuvsIvfSqSearchParams {
1923    #[doc = " The number of clusters to search."]
1924    pub n_probes: u32,
1925}
1926#[allow(clippy::unnecessary_operation, clippy::identity_op)]
1927const _: () = {
1928    ["Size of cuvsIvfSqSearchParams"][::std::mem::size_of::<cuvsIvfSqSearchParams>() - 4usize];
1929    ["Alignment of cuvsIvfSqSearchParams"][::std::mem::align_of::<cuvsIvfSqSearchParams>() - 4usize];
1930    ["Offset of field: cuvsIvfSqSearchParams::n_probes"]
1931        [::std::mem::offset_of!(cuvsIvfSqSearchParams, n_probes) - 0usize];
1932};
1933pub type cuvsIvfSqSearchParams_t = *mut cuvsIvfSqSearchParams;
1934unsafe extern "C" {
1935    #[must_use]
1936    #[doc = " @brief Allocate IVF-SQ search params, and populate with default values\n\n @param[in] params cuvsIvfSqSearchParams_t to allocate\n @return cuvsError_t"]
1937    pub fn cuvsIvfSqSearchParamsCreate(params: *mut cuvsIvfSqSearchParams_t) -> cuvsError_t;
1938}
1939unsafe extern "C" {
1940    #[must_use]
1941    #[doc = " @brief De-allocate IVF-SQ search params\n\n @param[in] params\n @return cuvsError_t"]
1942    pub fn cuvsIvfSqSearchParamsDestroy(params: cuvsIvfSqSearchParams_t) -> cuvsError_t;
1943}
1944#[doc = " @defgroup ivf_sq_c_index IVF-SQ index\n @{\n/\n/**\n @brief Struct to hold address of cuvs::neighbors::ivf_sq::index and its active trained dtype\n"]
1945#[repr(C)]
1946#[derive(Debug, Copy, Clone)]
1947pub struct cuvsIvfSqIndex {
1948    pub addr: usize,
1949    pub dtype: DLDataType,
1950}
1951#[allow(clippy::unnecessary_operation, clippy::identity_op)]
1952const _: () = {
1953    ["Size of cuvsIvfSqIndex"][::std::mem::size_of::<cuvsIvfSqIndex>() - 16usize];
1954    ["Alignment of cuvsIvfSqIndex"][::std::mem::align_of::<cuvsIvfSqIndex>() - 8usize];
1955    ["Offset of field: cuvsIvfSqIndex::addr"][::std::mem::offset_of!(cuvsIvfSqIndex, addr) - 0usize];
1956    ["Offset of field: cuvsIvfSqIndex::dtype"][::std::mem::offset_of!(cuvsIvfSqIndex, dtype) - 8usize];
1957};
1958pub type cuvsIvfSqIndex_t = *mut cuvsIvfSqIndex;
1959unsafe extern "C" {
1960    #[must_use]
1961    #[doc = " @brief Allocate IVF-SQ index\n\n @param[in] index cuvsIvfSqIndex_t to allocate\n @return cuvsError_t"]
1962    pub fn cuvsIvfSqIndexCreate(index: *mut cuvsIvfSqIndex_t) -> cuvsError_t;
1963}
1964unsafe extern "C" {
1965    #[must_use]
1966    #[doc = " @brief De-allocate IVF-SQ index\n\n @param[in] index cuvsIvfSqIndex_t to de-allocate"]
1967    pub fn cuvsIvfSqIndexDestroy(index: cuvsIvfSqIndex_t) -> cuvsError_t;
1968}
1969unsafe extern "C" {
1970    #[must_use]
1971    #[doc = " Get the number of clusters/inverted lists"]
1972    pub fn cuvsIvfSqIndexGetNLists(index: cuvsIvfSqIndex_t, n_lists: *mut i64) -> cuvsError_t;
1973}
1974unsafe extern "C" {
1975    #[must_use]
1976    #[doc = " Get the dimensionality of the data"]
1977    pub fn cuvsIvfSqIndexGetDim(index: cuvsIvfSqIndex_t, dim: *mut i64) -> cuvsError_t;
1978}
1979unsafe extern "C" {
1980    #[must_use]
1981    #[doc = " Get the size of the index"]
1982    pub fn cuvsIvfSqIndexGetSize(index: cuvsIvfSqIndex_t, size: *mut i64) -> cuvsError_t;
1983}
1984unsafe extern "C" {
1985    #[must_use]
1986    #[doc = " @brief Get the cluster centers corresponding to the lists [n_lists, dim]\n\n @param[in] index cuvsIvfSqIndex_t Built Ivf-SQ Index\n @param[out] centers Preallocated array on host or device memory to store output, [n_lists, dim]\n @return cuvsError_t"]
1987    pub fn cuvsIvfSqIndexGetCenters(index: cuvsIvfSqIndex_t, centers: *mut DLManagedTensor) -> cuvsError_t;
1988}
1989unsafe extern "C" {
1990    #[must_use]
1991    #[doc = " @defgroup ivf_sq_c_index_build IVF-SQ index build\n @{\n/\n/**\n @brief Build an IVF-SQ index with a `DLManagedTensor` which has underlying\n        `DLDeviceType` equal to `kDLCUDA`, `kDLCUDAHost`, `kDLCUDAManaged`,\n        or `kDLCPU`. Also, acceptable underlying types are:\n        1. `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 32`\n        2. `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 16`\n\n @code {.c}\n #include <cuvs/core/c_api.h>\n #include <cuvs/neighbors/ivf_sq.h>\n\n // Create cuvsResources_t\n cuvsResources_t res;\n cuvsError_t res_create_status = cuvsResourcesCreate(&res);\n\n // Assume a populated `DLManagedTensor` type here\n DLManagedTensor dataset;\n\n // Create default index params\n cuvsIvfSqIndexParams_t index_params;\n cuvsError_t params_create_status = cuvsIvfSqIndexParamsCreate(&index_params);\n\n // Create IVF-SQ index\n cuvsIvfSqIndex_t index;\n cuvsError_t index_create_status = cuvsIvfSqIndexCreate(&index);\n\n // Build the IVF-SQ Index\n cuvsError_t build_status = cuvsIvfSqBuild(res, index_params, &dataset, index);\n\n // de-allocate `index_params`, `index` and `res`\n cuvsError_t params_destroy_status = cuvsIvfSqIndexParamsDestroy(index_params);\n cuvsError_t index_destroy_status = cuvsIvfSqIndexDestroy(index);\n cuvsError_t res_destroy_status = cuvsResourcesDestroy(res);\n @endcode\n\n @param[in] res cuvsResources_t opaque C handle\n @param[in] index_params cuvsIvfSqIndexParams_t used to build IVF-SQ index\n @param[in] dataset DLManagedTensor* training dataset\n @param[out] index cuvsIvfSqIndex_t Newly built IVF-SQ index\n @return cuvsError_t"]
1992    pub fn cuvsIvfSqBuild(
1993        res: cuvsResources_t,
1994        index_params: cuvsIvfSqIndexParams_t,
1995        dataset: *mut DLManagedTensor,
1996        index: cuvsIvfSqIndex_t,
1997    ) -> cuvsError_t;
1998}
1999unsafe extern "C" {
2000    #[must_use]
2001    #[doc = " @defgroup ivf_sq_c_index_search IVF-SQ index search\n @{\n/\n/**\n @brief Search an IVF-SQ index with a `DLManagedTensor` which has underlying\n        `DLDeviceType` equal to `kDLCUDA`, `kDLCUDAHost`, `kDLCUDAManaged`.\n        Types for input are:\n        1. `queries`: `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 32` or 16\n        2. `neighbors`: `kDLDataType.code == kDLInt` and `kDLDataType.bits = 64`\n        3. `distances`: `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 32`\n\n @code {.c}\n #include <cuvs/core/c_api.h>\n #include <cuvs/neighbors/ivf_sq.h>\n\n // Create cuvsResources_t\n cuvsResources_t res;\n cuvsError_t res_create_status = cuvsResourcesCreate(&res);\n\n // Assume a populated `DLManagedTensor` type here\n DLManagedTensor queries;\n DLManagedTensor neighbors;\n DLManagedTensor distances;\n\n // Create default search params\n cuvsIvfSqSearchParams_t search_params;\n cuvsError_t params_create_status = cuvsIvfSqSearchParamsCreate(&search_params);\n\n // Search the `index` built using `cuvsIvfSqBuild`\n cuvsError_t search_status = cuvsIvfSqSearch(\n   res, search_params, index, &queries, &neighbors, &distances, (cuvsFilter){});\n\n // de-allocate `search_params` and `res`\n cuvsError_t params_destroy_status = cuvsIvfSqSearchParamsDestroy(search_params);\n cuvsError_t res_destroy_status = cuvsResourcesDestroy(res);\n @endcode\n\n @param[in] res cuvsResources_t opaque C handle\n @param[in] search_params cuvsIvfSqSearchParams_t used to search IVF-SQ index\n @param[in] index ivfSqIndex which has been returned by `cuvsIvfSqBuild`\n @param[in] queries DLManagedTensor* queries dataset to search\n @param[out] neighbors DLManagedTensor* output `k` neighbors for queries\n @param[out] distances DLManagedTensor* output `k` distances for queries\n @param[in] filter cuvsFilter input filter that can be used\n            to filter queries and neighbors based on the given bitset."]
2002    pub fn cuvsIvfSqSearch(
2003        res: cuvsResources_t,
2004        search_params: cuvsIvfSqSearchParams_t,
2005        index: cuvsIvfSqIndex_t,
2006        queries: *mut DLManagedTensor,
2007        neighbors: *mut DLManagedTensor,
2008        distances: *mut DLManagedTensor,
2009        filter: cuvsFilter,
2010    ) -> cuvsError_t;
2011}
2012unsafe extern "C" {
2013    #[must_use]
2014    #[doc = " @defgroup ivf_sq_c_index_serialize IVF-SQ C-API serialize functions\n @{\n/\n/**\n Save the index to file.\n\n Experimental, both the API and the serialization format are subject to change.\n\n @code{.c}\n #include <cuvs/neighbors/ivf_sq.h>\n\n // Create cuvsResources_t\n cuvsResources_t res;\n cuvsError_t res_create_status = cuvsResourcesCreate(&res);\n\n // create an index with `cuvsIvfSqBuild`\n cuvsIvfSqSerialize(res, \"/path/to/index\", index);\n @endcode\n\n @param[in] res cuvsResources_t opaque C handle\n @param[in] filename the file name for saving the index\n @param[in] index IVF-SQ index"]
2015    pub fn cuvsIvfSqSerialize(
2016        res: cuvsResources_t,
2017        filename: *const ::std::os::raw::c_char,
2018        index: cuvsIvfSqIndex_t,
2019    ) -> cuvsError_t;
2020}
2021unsafe extern "C" {
2022    #[must_use]
2023    #[doc = " Load index from file.\n\n Experimental, both the API and the serialization format are subject to change.\n\n @param[in] res cuvsResources_t opaque C handle\n @param[in] filename the name of the file that stores the index\n @param[out] index IVF-SQ index loaded from disk"]
2024    pub fn cuvsIvfSqDeserialize(
2025        res: cuvsResources_t,
2026        filename: *const ::std::os::raw::c_char,
2027        index: cuvsIvfSqIndex_t,
2028    ) -> cuvsError_t;
2029}
2030unsafe extern "C" {
2031    #[must_use]
2032    #[doc = " @defgroup ivf_sq_c_index_extend IVF-SQ index extend\n @{\n/\n/**\n @brief Extend the index with the new data.\n\n @param[in] res cuvsResources_t opaque C handle\n @param[in] new_vectors DLManagedTensor* the new vectors to add to the index\n @param[in] new_indices DLManagedTensor* vector of new indices for the new vectors. If the index\n            is empty, this can be NULL to imply a continuous range `[0...n_rows)`.\n @param[inout] index IVF-SQ index to be extended\n @return cuvsError_t"]
2033    pub fn cuvsIvfSqExtend(
2034        res: cuvsResources_t,
2035        new_vectors: *mut DLManagedTensor,
2036        new_indices: *mut DLManagedTensor,
2037        index: cuvsIvfSqIndex_t,
2038    ) -> cuvsError_t;
2039}
2040unsafe extern "C" {
2041    #[must_use]
2042    #[doc = " @defgroup ann_refine_c Approximate Nearest Neighbors Refinement C-API\n @{\n/\n/**\n @brief Refine nearest neighbor search.\n\n Refinement is an operation that follows an approximate NN search. The approximate search has\n already selected n_candidates neighbor candidates for each query. We narrow it down to k\n neighbors. For each query, we calculate the exact distance between the query and its\n n_candidates neighbor candidate, and select the k nearest ones.\n\n @param[in] res cuvsResources_t opaque C handle\n @param[in] dataset device matrix that stores the dataset [n_rows, dims]\n @param[in] queries device matrix of the queries [n_queris, dims]\n @param[in] candidates indices of candidate vectors [n_queries, n_candidates], where\n   n_candidates >= k\n @param[in] metric distance metric to use. Euclidean (L2) is used by default\n @param[out] indices device matrix that stores the refined indices [n_queries, k]\n @param[out] distances device matrix that stores the refined distances [n_queries, k]"]
2043    pub fn cuvsRefine(
2044        res: cuvsResources_t,
2045        dataset: *mut DLManagedTensor,
2046        queries: *mut DLManagedTensor,
2047        candidates: *mut DLManagedTensor,
2048        metric: cuvsDistanceType,
2049        indices: *mut DLManagedTensor,
2050        distances: *mut DLManagedTensor,
2051    ) -> cuvsError_t;
2052}
2053#[repr(u32)]
2054#[doc = " @brief Enum to hold which ANN algorithm is being used in the tiered index"]
2055#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
2056pub enum cuvsTieredIndexANNAlgo {
2057    CUVS_TIERED_INDEX_ALGO_CAGRA = 0,
2058    CUVS_TIERED_INDEX_ALGO_IVF_FLAT = 1,
2059    CUVS_TIERED_INDEX_ALGO_IVF_PQ = 2,
2060}
2061#[doc = " @defgroup tiered_index_c_index Tiered Index\n @{\n/\n/**\n @brief Struct to hold address of cuvs::neighbors::tiered_index::index and its active trained\n dtype\n"]
2062#[repr(C)]
2063#[derive(Debug, Copy, Clone)]
2064pub struct cuvsTieredIndex {
2065    pub addr: usize,
2066    pub dtype: DLDataType,
2067    pub algo: cuvsTieredIndexANNAlgo,
2068}
2069#[allow(clippy::unnecessary_operation, clippy::identity_op)]
2070const _: () = {
2071    ["Size of cuvsTieredIndex"][::std::mem::size_of::<cuvsTieredIndex>() - 16usize];
2072    ["Alignment of cuvsTieredIndex"][::std::mem::align_of::<cuvsTieredIndex>() - 8usize];
2073    ["Offset of field: cuvsTieredIndex::addr"][::std::mem::offset_of!(cuvsTieredIndex, addr) - 0usize];
2074    ["Offset of field: cuvsTieredIndex::dtype"][::std::mem::offset_of!(cuvsTieredIndex, dtype) - 8usize];
2075    ["Offset of field: cuvsTieredIndex::algo"][::std::mem::offset_of!(cuvsTieredIndex, algo) - 12usize];
2076};
2077pub type cuvsTieredIndex_t = *mut cuvsTieredIndex;
2078unsafe extern "C" {
2079    #[must_use]
2080    #[doc = " @brief Allocate Tiered Index\n\n @param[in] index cuvsTieredIndex_t to allocate\n @return cuvsError_t"]
2081    pub fn cuvsTieredIndexCreate(index: *mut cuvsTieredIndex_t) -> cuvsError_t;
2082}
2083unsafe extern "C" {
2084    #[must_use]
2085    #[doc = " @brief De-allocate Tiered index\n\n @param[in] index cuvsTieredIndex_t to de-allocate"]
2086    pub fn cuvsTieredIndexDestroy(index: cuvsTieredIndex_t) -> cuvsError_t;
2087}
2088#[doc = " @defgroup tiered_c_index_params Tiered Index build parameters\n @{\n/\n/**\n @brief Supplemental parameters to build a TieredIndex"]
2089#[repr(C)]
2090#[derive(Debug, Copy, Clone)]
2091pub struct cuvsTieredIndexParams {
2092    #[doc = " Distance type."]
2093    pub metric: cuvsDistanceType,
2094    #[doc = " The type of ANN algorithm we are using"]
2095    pub algo: cuvsTieredIndexANNAlgo,
2096    #[doc = " The minimum number of rows necessary in the index to create an\nann index"]
2097    pub min_ann_rows: i64,
2098    #[doc = " Whether or not to create a new ann index on extend, if the number\nof rows in the incremental (bfknn) portion is above min_ann_rows"]
2099    pub create_ann_index_on_extend: bool,
2100    #[doc = " Optional parameters for building a cagra index"]
2101    pub cagra_params: cuvsCagraIndexParams_t,
2102    #[doc = " Optional parameters for building a ivf_flat index"]
2103    pub ivf_flat_params: cuvsIvfFlatIndexParams_t,
2104    #[doc = " Optional parameters for building a ivf-pq index"]
2105    pub ivf_pq_params: cuvsIvfPqIndexParams_t,
2106}
2107#[allow(clippy::unnecessary_operation, clippy::identity_op)]
2108const _: () = {
2109    ["Size of cuvsTieredIndexParams"][::std::mem::size_of::<cuvsTieredIndexParams>() - 48usize];
2110    ["Alignment of cuvsTieredIndexParams"][::std::mem::align_of::<cuvsTieredIndexParams>() - 8usize];
2111    ["Offset of field: cuvsTieredIndexParams::metric"][::std::mem::offset_of!(cuvsTieredIndexParams, metric) - 0usize];
2112    ["Offset of field: cuvsTieredIndexParams::algo"][::std::mem::offset_of!(cuvsTieredIndexParams, algo) - 4usize];
2113    ["Offset of field: cuvsTieredIndexParams::min_ann_rows"]
2114        [::std::mem::offset_of!(cuvsTieredIndexParams, min_ann_rows) - 8usize];
2115    ["Offset of field: cuvsTieredIndexParams::create_ann_index_on_extend"]
2116        [::std::mem::offset_of!(cuvsTieredIndexParams, create_ann_index_on_extend) - 16usize];
2117    ["Offset of field: cuvsTieredIndexParams::cagra_params"]
2118        [::std::mem::offset_of!(cuvsTieredIndexParams, cagra_params) - 24usize];
2119    ["Offset of field: cuvsTieredIndexParams::ivf_flat_params"]
2120        [::std::mem::offset_of!(cuvsTieredIndexParams, ivf_flat_params) - 32usize];
2121    ["Offset of field: cuvsTieredIndexParams::ivf_pq_params"]
2122        [::std::mem::offset_of!(cuvsTieredIndexParams, ivf_pq_params) - 40usize];
2123};
2124pub type cuvsTieredIndexParams_t = *mut cuvsTieredIndexParams;
2125unsafe extern "C" {
2126    #[must_use]
2127    #[doc = " @brief Allocate Tiered Index Params and populate with default values\n\n @param[in] index_params cuvsTieredIndexParams_t to allocate\n @return cuvsError_t"]
2128    pub fn cuvsTieredIndexParamsCreate(index_params: *mut cuvsTieredIndexParams_t) -> cuvsError_t;
2129}
2130unsafe extern "C" {
2131    #[must_use]
2132    #[doc = " @brief De-allocate Tiered Index params\n\n @param[in] index_params\n @return cuvsError_t"]
2133    pub fn cuvsTieredIndexParamsDestroy(index_params: cuvsTieredIndexParams_t) -> cuvsError_t;
2134}
2135unsafe extern "C" {
2136    #[must_use]
2137    #[doc = " @defgroup tieredindex_c_index_build Tiered index build\n @{\n/\n/**\n @brief Build a TieredIndex index with a `DLManagedTensor` which has underlying\n        `DLDeviceType` equal to `kDLCUDA`, `kDLCUDAHost`, `kDLCUDAManaged`,\n        or `kDLCPU`. Also, acceptable underlying types are:\n        1. `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 32`\n        2. `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 16`\n\n @code {.c}\n #include <cuvs/core/c_api.h>\n #include <cuvs/neighbors/tiered_index.h>\n\n // Create cuvsResources_t\n cuvsResources_t res;\n cuvsError_t res_create_status = cuvsResourcesCreate(&res);\n\n // Assume a populated `DLManagedTensor` type here\n DLManagedTensor dataset;\n\n // Create TieredIndex index\n cuvsTieredIndex_t index;\n cuvsError_t index_create_status = cuvsTieredIndexCreate(&index);\n\n // Create default index params\n cuvsTieredIndexParams_t index_params;\n cuvsError_t params_create_status = cuvsTieredIndexParamsCreate(&index_params);\n\n // Build the TieredIndex Index\n cuvsError_t build_status = cuvsTieredIndexBuild(res, index_params, &dataset_tensor, index);\n\n // de-allocate `index` and `res`\n cuvsError_t index_destroy_status = cuvsTieredIndexDestroy(index);\n cuvsError_t res_destroy_status = cuvsResourcesDestroy(res);\n @endcode\n\n @param[in] res cuvsResources_t opaque C handle\n @param[in] dataset DLManagedTensor* training dataset\n @param[in] index_params Index parameters to use when building the index\n @param[out] index cuvsTieredIndex_t Newly built TieredIndex index\n @return cuvsError_t"]
2138    pub fn cuvsTieredIndexBuild(
2139        res: cuvsResources_t,
2140        index_params: cuvsTieredIndexParams_t,
2141        dataset: *mut DLManagedTensor,
2142        index: cuvsTieredIndex_t,
2143    ) -> cuvsError_t;
2144}
2145unsafe extern "C" {
2146    #[must_use]
2147    #[doc = " @defgroup tieredindex_c_index_search Tiered index search\n @{\n/\n/**\n @brief Search a TieredIndex index with a `DLManagedTensor`\n\n @code {.c}\n #include <cuvs/core/c_api.h>\n #include <cuvs/neighbors/tiered_index.h>\n\n // Create cuvsResources_t\n cuvsResources_t res;\n cuvsError_t res_create_status = cuvsResourcesCreate(&res);\n\n // Assume a populated `DLManagedTensor` type here\n DLManagedTensor dataset;\n DLManagedTensor queries;\n DLManagedTensor neighbors;\n DLManagedTensor bitmap;\n\n cuvsFilter prefilter{(uintptr_t)&bitmap, BITMAP};\n\n // Search the `index` built using `cuvsTieredIndexBuild`\n cuvsError_t search_status = cuvsTieredIndexSearch(res, index, &queries, &neighbors, &distances,\n prefilter);\n\n // de-allocate `res`\n cuvsError_t res_destroy_status = cuvsResourcesDestroy(res);\n @endcode\n\n @param[in] res cuvsResources_t opaque C handle\n @param[in] search_params params used to the ANN index, should be one of\n cuvsCagraSearchParams_t, cuvsIvfFlatSearchParams_t, cuvsIvfPqSearchParams_t\n depending on the type of the tiered index used\n @param[in] index cuvsTieredIndex which has been returned by `cuvsTieredIndexBuild`\n @param[in] queries DLManagedTensor* queries dataset to search\n @param[out] neighbors DLManagedTensor* output `k` neighbors for queries\n @param[out] distances DLManagedTensor* output `k` distances for queries\n @param[in] prefilter cuvsFilter input prefilter that can be used\nto filter queries and neighbors based on the given bitmap."]
2148    pub fn cuvsTieredIndexSearch(
2149        res: cuvsResources_t,
2150        search_params: *mut ::std::os::raw::c_void,
2151        index: cuvsTieredIndex_t,
2152        queries: *mut DLManagedTensor,
2153        neighbors: *mut DLManagedTensor,
2154        distances: *mut DLManagedTensor,
2155        prefilter: cuvsFilter,
2156    ) -> cuvsError_t;
2157}
2158unsafe extern "C" {
2159    #[must_use]
2160    #[doc = " @}\n/\n/**\n @defgroup tiered_c_index_extend Tiered index extend\n @{\n/\n/**\n @brief Extend the index with the new data.\n\n @param[in] res cuvsResources_t opaque C handle\n @param[in] new_vectors DLManagedTensor* the new vectors to add to the index\n @param[inout] index Tiered index to be extended\n @return cuvsError_t"]
2161    pub fn cuvsTieredIndexExtend(
2162        res: cuvsResources_t,
2163        new_vectors: *mut DLManagedTensor,
2164        index: cuvsTieredIndex_t,
2165    ) -> cuvsError_t;
2166}
2167unsafe extern "C" {
2168    #[must_use]
2169    #[doc = " @defgroup tiered_c_index_merge Tiered index merge\n @{\n/\n/**\n @brief Merge multiple indices together into a single index\n\n @param[in] res cuvsResources_t opaque C handle\n @param[in] index_params Index parameters to use when merging\n @param[in] indices pointers to indices to merge together\n @param[in] num_indices the number of indices to merge\n @param[out] output_index the merged index\n @return cuvsError_t"]
2170    pub fn cuvsTieredIndexMerge(
2171        res: cuvsResources_t,
2172        index_params: cuvsTieredIndexParams_t,
2173        indices: *mut cuvsTieredIndex_t,
2174        num_indices: usize,
2175        output_index: cuvsTieredIndex_t,
2176    ) -> cuvsError_t;
2177}
2178#[doc = " @brief Supplemental parameters to build Vamana Index\n\n `graph_degree`: Maximum degree of graph; corresponds to the R parameter of\n Vamana algorithm in the literature.\n `visited_size`: Maximum number of visited nodes per search during Vamana algorithm.\n Loosely corresponds to the L parameter in the literature.\n `vamana_iters`: The number of times all vectors are inserted into the graph. If > 1,\n all vectors are re-inserted to improve graph quality.\n `max_fraction`: The maximum batch size is this fraction of the total dataset size. Larger\n gives faster build but lower graph quality.\n `alpha`: Used to determine how aggressive the pruning will be."]
2179#[repr(C)]
2180#[derive(Debug, Copy, Clone)]
2181pub struct cuvsVamanaIndexParams {
2182    #[doc = " Distance type."]
2183    pub metric: cuvsDistanceType,
2184    #[doc = " Maximum degree of output graph corresponds to the R parameter in the original Vamana\n literature."]
2185    pub graph_degree: u32,
2186    #[doc = " Maximum number of visited nodes per search corresponds to the L parameter in the Vamana\n literature"]
2187    pub visited_size: u32,
2188    #[doc = " Number of Vamana vector insertion iterations (each iteration inserts all vectors)."]
2189    pub vamana_iters: f32,
2190    #[doc = " Alpha for pruning parameter"]
2191    pub alpha: f32,
2192    #[doc = " Maximum fraction of dataset inserted per batch.              *\n Larger max batch decreases graph quality, but improves speed"]
2193    pub max_fraction: f32,
2194    #[doc = " Base of growth rate of batch sizes"]
2195    pub batch_base: f32,
2196    #[doc = " Size of candidate queue structure - should be (2^x)-1"]
2197    pub queue_size: u32,
2198    #[doc = " Max batchsize of reverse edge processing (reduces memory footprint)"]
2199    pub reverse_batchsize: u32,
2200}
2201#[allow(clippy::unnecessary_operation, clippy::identity_op)]
2202const _: () = {
2203    ["Size of cuvsVamanaIndexParams"][::std::mem::size_of::<cuvsVamanaIndexParams>() - 36usize];
2204    ["Alignment of cuvsVamanaIndexParams"][::std::mem::align_of::<cuvsVamanaIndexParams>() - 4usize];
2205    ["Offset of field: cuvsVamanaIndexParams::metric"][::std::mem::offset_of!(cuvsVamanaIndexParams, metric) - 0usize];
2206    ["Offset of field: cuvsVamanaIndexParams::graph_degree"]
2207        [::std::mem::offset_of!(cuvsVamanaIndexParams, graph_degree) - 4usize];
2208    ["Offset of field: cuvsVamanaIndexParams::visited_size"]
2209        [::std::mem::offset_of!(cuvsVamanaIndexParams, visited_size) - 8usize];
2210    ["Offset of field: cuvsVamanaIndexParams::vamana_iters"]
2211        [::std::mem::offset_of!(cuvsVamanaIndexParams, vamana_iters) - 12usize];
2212    ["Offset of field: cuvsVamanaIndexParams::alpha"][::std::mem::offset_of!(cuvsVamanaIndexParams, alpha) - 16usize];
2213    ["Offset of field: cuvsVamanaIndexParams::max_fraction"]
2214        [::std::mem::offset_of!(cuvsVamanaIndexParams, max_fraction) - 20usize];
2215    ["Offset of field: cuvsVamanaIndexParams::batch_base"]
2216        [::std::mem::offset_of!(cuvsVamanaIndexParams, batch_base) - 24usize];
2217    ["Offset of field: cuvsVamanaIndexParams::queue_size"]
2218        [::std::mem::offset_of!(cuvsVamanaIndexParams, queue_size) - 28usize];
2219    ["Offset of field: cuvsVamanaIndexParams::reverse_batchsize"]
2220        [::std::mem::offset_of!(cuvsVamanaIndexParams, reverse_batchsize) - 32usize];
2221};
2222pub type cuvsVamanaIndexParams_t = *mut cuvsVamanaIndexParams;
2223unsafe extern "C" {
2224    #[must_use]
2225    #[doc = " @brief Allocate Vamana Index params, and populate with default values\n\n @param[in] params cuvsVamanaIndexParams_t to allocate\n @return cuvsError_t"]
2226    pub fn cuvsVamanaIndexParamsCreate(params: *mut cuvsVamanaIndexParams_t) -> cuvsError_t;
2227}
2228unsafe extern "C" {
2229    #[must_use]
2230    #[doc = " @brief De-allocate Vamana Index params\n\n @param[in] params cuvsVamanaIndexParams_t to de-allocate\n @return cuvsError_t"]
2231    pub fn cuvsVamanaIndexParamsDestroy(params: cuvsVamanaIndexParams_t) -> cuvsError_t;
2232}
2233#[doc = " @brief Struct to hold address of cuvs::neighbors::vamana::index and its active trained dtype\n"]
2234#[repr(C)]
2235#[derive(Debug, Copy, Clone)]
2236pub struct cuvsVamanaIndex {
2237    pub addr: usize,
2238    pub dtype: DLDataType,
2239}
2240#[allow(clippy::unnecessary_operation, clippy::identity_op)]
2241const _: () = {
2242    ["Size of cuvsVamanaIndex"][::std::mem::size_of::<cuvsVamanaIndex>() - 16usize];
2243    ["Alignment of cuvsVamanaIndex"][::std::mem::align_of::<cuvsVamanaIndex>() - 8usize];
2244    ["Offset of field: cuvsVamanaIndex::addr"][::std::mem::offset_of!(cuvsVamanaIndex, addr) - 0usize];
2245    ["Offset of field: cuvsVamanaIndex::dtype"][::std::mem::offset_of!(cuvsVamanaIndex, dtype) - 8usize];
2246};
2247pub type cuvsVamanaIndex_t = *mut cuvsVamanaIndex;
2248unsafe extern "C" {
2249    #[must_use]
2250    #[doc = " @brief Allocate Vamana index\n\n @param[in] index cuvsVamanaIndex_t to allocate\n @return cuvsError_t"]
2251    pub fn cuvsVamanaIndexCreate(index: *mut cuvsVamanaIndex_t) -> cuvsError_t;
2252}
2253unsafe extern "C" {
2254    #[must_use]
2255    #[doc = " @brief De-allocate Vamana index\n\n @param[in] index cuvsVamanaIndex_t to de-allocate\n @return cuvsError_t"]
2256    pub fn cuvsVamanaIndexDestroy(index: cuvsVamanaIndex_t) -> cuvsError_t;
2257}
2258unsafe extern "C" {
2259    #[must_use]
2260    #[doc = " @brief Get the dimension of the index\n\n @param[in] index cuvsVamanaIndex_t to get dimension of\n @param[out] dim pointer to dimension to set\n @return cuvsError_t"]
2261    pub fn cuvsVamanaIndexGetDims(index: cuvsVamanaIndex_t, dim: *mut ::std::os::raw::c_int) -> cuvsError_t;
2262}
2263unsafe extern "C" {
2264    #[must_use]
2265    #[doc = " @brief Build Vamana index\n\n Build the index from the dataset for efficient DiskANN search.\n\n The build uses the Vamana insertion-based algorithm to create the graph. The algorithm\n starts with an empty graph and iteratively inserts batches of nodes. Each batch involves\n performing a greedy search for each vector to be inserted, and inserting it with edges to\n all nodes traversed during the search. Reverse edges are also inserted and robustPrune is applied\n to improve graph quality. The index_params struct controls the degree of the final graph.\n\n The following distance metrics are supported:\n - L2\n\n Usage example:\n @code{.c}\n   // Create cuvsResources_t\n   cuvsResources_t res;\n   cuvsResourcesCreate(&res);\n\n   // Assume a row-major dataset [n_rows, n_cols] is defined as `float* dataset`\n   cuvsVamanaIndexParams_t index_params;\n   cuvsVamanaIndexParamsCreate(&index_params);\n   index_params->metric = L2Expanded; // set distance metric\n   cuvsVamanaIndex_t index;\n   cuvsVamanaIndexCreate(&index);\n   cuvsVamanaBuild(res, index_params, dataset, index);\n @endcode\n\n @param[in] res cuvsResources_t opaque C handle\n @param[in] params cuvsVamanaIndexParams_t used to build Vamana index\n @param[in] dataset DLManagedTensor* training dataset\n @param[out] index cuvsVamanaIndex_t Vamana index\n @return cuvsError_t"]
2266    pub fn cuvsVamanaBuild(
2267        res: cuvsResources_t,
2268        params: cuvsVamanaIndexParams_t,
2269        dataset: *mut DLManagedTensor,
2270        index: cuvsVamanaIndex_t,
2271    ) -> cuvsError_t;
2272}
2273unsafe extern "C" {
2274    #[must_use]
2275    #[doc = " @brief Save Vamana index to file\n\n Matches the file format used by the DiskANN open-source repository, allowing cross-compatibility.\n\n Serialized Index is to be used by the DiskANN open-source repository for graph search.\n\n @code{.c}\n   // Create cuvsResources_t\n   cuvsResources_t res;\n   cuvsResourcesCreate(&res);\n\n   // create an index with `cuvsVamanaBuild`\n   cuvsVamanaSerialize(res, \"/path/to/index\", index, true);\n @endcode\n\n @param[in] res cuvsResources_t opaque C handle\n @param[in] filename the file prefix for where the index is saved\n @param[in] index cuvsVamanaIndex_t to serialize\n @param[in] include_dataset whether to include the dataset in the serialized index\n @return cuvsError_t"]
2276    pub fn cuvsVamanaSerialize(
2277        res: cuvsResources_t,
2278        filename: *const ::std::os::raw::c_char,
2279        index: cuvsVamanaIndex_t,
2280        include_dataset: bool,
2281    ) -> cuvsError_t;
2282}
2283#[repr(u32)]
2284#[doc = " @brief Hierarchy for HNSW index when converting from CAGRA index\n\n NOTE: When the value is `NONE`, the HNSW index is built as a base-layer-only index."]
2285#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
2286pub enum cuvsHnswHierarchy {
2287    NONE = 0,
2288    CPU = 1,
2289    GPU = 2,
2290}
2291#[doc = " Parameters for ACE (Augmented Core Extraction) graph build for HNSW.\n ACE enables building indexes for datasets too large to fit in GPU memory by:\n 1. Partitioning the dataset in core and augmented partitions using balanced k-means\n 2. Building sub-indexes for each partition independently\n 3. Concatenating sub-graphs into a final unified index"]
2292#[repr(C)]
2293#[derive(Debug, Copy, Clone)]
2294pub struct cuvsHnswAceParams {
2295    #[doc = " Number of partitions for ACE partitioned build.\n\n When set to 0 (default), the number of partitions is automatically derived\n based on available host and GPU memory to maximize partition size while\n ensuring the build fits in memory.\n\n Small values might improve recall but potentially degrade performance and\n increase memory usage. The partition size is on average 2 * (n_rows /\n npartitions) * dim * sizeof(T). 2 is because of the core and augmented\n vectors. Please account for imbalance in the partition sizes (up to 3x in\n our tests).\n\n If the specified number of partitions results in partitions that exceed\n available memory, the value will be automatically increased to fit memory\n constraints and a warning will be issued."]
2296    pub npartitions: usize,
2297    #[doc = " Directory to store ACE build artifacts (e.g., KNN graph, optimized graph).\n Used when `use_disk` is true or when the graph does not fit in memory."]
2298    pub build_dir: *const ::std::os::raw::c_char,
2299    #[doc = " Whether to use disk-based storage for ACE build.\n When true, enables disk-based operations for memory-efficient graph construction."]
2300    pub use_disk: bool,
2301    #[doc = " Maximum host memory to use for ACE build in GiB.\n When set to 0 (default), uses available host memory.\n Useful for testing or when running alongside other memory-intensive processes."]
2302    pub max_host_memory_gb: f64,
2303    #[doc = " Maximum GPU memory to use for ACE build in GiB.\n When set to 0 (default), uses available GPU memory.\n Useful for testing or when running alongside other memory-intensive processes."]
2304    pub max_gpu_memory_gb: f64,
2305}
2306#[allow(clippy::unnecessary_operation, clippy::identity_op)]
2307const _: () = {
2308    ["Size of cuvsHnswAceParams"][::std::mem::size_of::<cuvsHnswAceParams>() - 40usize];
2309    ["Alignment of cuvsHnswAceParams"][::std::mem::align_of::<cuvsHnswAceParams>() - 8usize];
2310    ["Offset of field: cuvsHnswAceParams::npartitions"]
2311        [::std::mem::offset_of!(cuvsHnswAceParams, npartitions) - 0usize];
2312    ["Offset of field: cuvsHnswAceParams::build_dir"][::std::mem::offset_of!(cuvsHnswAceParams, build_dir) - 8usize];
2313    ["Offset of field: cuvsHnswAceParams::use_disk"][::std::mem::offset_of!(cuvsHnswAceParams, use_disk) - 16usize];
2314    ["Offset of field: cuvsHnswAceParams::max_host_memory_gb"]
2315        [::std::mem::offset_of!(cuvsHnswAceParams, max_host_memory_gb) - 24usize];
2316    ["Offset of field: cuvsHnswAceParams::max_gpu_memory_gb"]
2317        [::std::mem::offset_of!(cuvsHnswAceParams, max_gpu_memory_gb) - 32usize];
2318};
2319pub type cuvsHnswAceParams_t = *mut cuvsHnswAceParams;
2320unsafe extern "C" {
2321    #[must_use]
2322    #[doc = " @brief Allocate HNSW ACE params, and populate with default values\n\n @param[in] params cuvsHnswAceParams_t to allocate\n @return cuvsError_t"]
2323    pub fn cuvsHnswAceParamsCreate(params: *mut cuvsHnswAceParams_t) -> cuvsError_t;
2324}
2325unsafe extern "C" {
2326    #[must_use]
2327    #[doc = " @brief De-allocate HNSW ACE params\n\n @param[in] params\n @return cuvsError_t"]
2328    pub fn cuvsHnswAceParamsDestroy(params: cuvsHnswAceParams_t) -> cuvsError_t;
2329}
2330#[repr(C)]
2331#[derive(Debug, Copy, Clone)]
2332pub struct cuvsHnswIndexParams {
2333    pub hierarchy: cuvsHnswHierarchy,
2334    #[doc = " Size of the candidate list during hierarchy construction when hierarchy is `CPU`"]
2335    pub ef_construction: ::std::os::raw::c_int,
2336    #[doc = " Number of host threads to use to construct hierarchy when hierarchy is `CPU` or `GPU`.\nWhen the value is 0, the number of threads is automatically determined to the\nmaximum number of threads available.\nNOTE: When hierarchy is `GPU`, while the majority of the work is done on the GPU,\ninitialization of the HNSW index itself and some other work\nis parallelized with the help of CPU threads."]
2337    pub num_threads: ::std::os::raw::c_int,
2338    #[doc = " HNSW M parameter: number of bi-directional links per node (used when building with ACE).\n  graph_degree = m * 2, intermediate_graph_degree = m * 3."]
2339    pub M: usize,
2340    #[doc = " Distance type for the index."]
2341    pub metric: cuvsDistanceType,
2342    #[doc = " Optional: specify ACE parameters for building HNSW index using ACE algorithm.\n Set to nullptr for default behavior (from_cagra conversion)."]
2343    pub ace_params: cuvsHnswAceParams_t,
2344}
2345#[allow(clippy::unnecessary_operation, clippy::identity_op)]
2346const _: () = {
2347    ["Size of cuvsHnswIndexParams"][::std::mem::size_of::<cuvsHnswIndexParams>() - 40usize];
2348    ["Alignment of cuvsHnswIndexParams"][::std::mem::align_of::<cuvsHnswIndexParams>() - 8usize];
2349    ["Offset of field: cuvsHnswIndexParams::hierarchy"]
2350        [::std::mem::offset_of!(cuvsHnswIndexParams, hierarchy) - 0usize];
2351    ["Offset of field: cuvsHnswIndexParams::ef_construction"]
2352        [::std::mem::offset_of!(cuvsHnswIndexParams, ef_construction) - 4usize];
2353    ["Offset of field: cuvsHnswIndexParams::num_threads"]
2354        [::std::mem::offset_of!(cuvsHnswIndexParams, num_threads) - 8usize];
2355    ["Offset of field: cuvsHnswIndexParams::M"][::std::mem::offset_of!(cuvsHnswIndexParams, M) - 16usize];
2356    ["Offset of field: cuvsHnswIndexParams::metric"][::std::mem::offset_of!(cuvsHnswIndexParams, metric) - 24usize];
2357    ["Offset of field: cuvsHnswIndexParams::ace_params"]
2358        [::std::mem::offset_of!(cuvsHnswIndexParams, ace_params) - 32usize];
2359};
2360pub type cuvsHnswIndexParams_t = *mut cuvsHnswIndexParams;
2361unsafe extern "C" {
2362    #[must_use]
2363    #[doc = " @brief Allocate HNSW Index params, and populate with default values\n\n @param[in] params cuvsHnswIndexParams_t to allocate\n @return cuvsError_t"]
2364    pub fn cuvsHnswIndexParamsCreate(params: *mut cuvsHnswIndexParams_t) -> cuvsError_t;
2365}
2366unsafe extern "C" {
2367    #[must_use]
2368    #[doc = " @brief De-allocate HNSW Index params\n\n @param[in] params\n @return cuvsError_t"]
2369    pub fn cuvsHnswIndexParamsDestroy(params: cuvsHnswIndexParams_t) -> cuvsError_t;
2370}
2371#[doc = " @brief Struct to hold address of cuvs::neighbors::Hnsw::index and its active trained dtype\n"]
2372#[repr(C)]
2373#[derive(Debug, Copy, Clone)]
2374pub struct cuvsHnswIndex {
2375    pub addr: usize,
2376    pub dtype: DLDataType,
2377}
2378#[allow(clippy::unnecessary_operation, clippy::identity_op)]
2379const _: () = {
2380    ["Size of cuvsHnswIndex"][::std::mem::size_of::<cuvsHnswIndex>() - 16usize];
2381    ["Alignment of cuvsHnswIndex"][::std::mem::align_of::<cuvsHnswIndex>() - 8usize];
2382    ["Offset of field: cuvsHnswIndex::addr"][::std::mem::offset_of!(cuvsHnswIndex, addr) - 0usize];
2383    ["Offset of field: cuvsHnswIndex::dtype"][::std::mem::offset_of!(cuvsHnswIndex, dtype) - 8usize];
2384};
2385pub type cuvsHnswIndex_t = *mut cuvsHnswIndex;
2386unsafe extern "C" {
2387    #[must_use]
2388    #[doc = " @brief Allocate HNSW index\n\n @param[in] index cuvsHnswIndex_t to allocate\n @return HnswError_t"]
2389    pub fn cuvsHnswIndexCreate(index: *mut cuvsHnswIndex_t) -> cuvsError_t;
2390}
2391unsafe extern "C" {
2392    #[must_use]
2393    #[doc = " @brief De-allocate HNSW index\n\n @param[in] index cuvsHnswIndex_t to de-allocate"]
2394    pub fn cuvsHnswIndexDestroy(index: cuvsHnswIndex_t) -> cuvsError_t;
2395}
2396#[doc = " @defgroup hnsw_c_extend_params Parameters for extending HNSW index\n @{"]
2397#[repr(C)]
2398#[derive(Debug, Copy, Clone)]
2399pub struct cuvsHnswExtendParams {
2400    #[doc = " Number of CPU threads used to extend additional vectors"]
2401    pub num_threads: ::std::os::raw::c_int,
2402}
2403#[allow(clippy::unnecessary_operation, clippy::identity_op)]
2404const _: () = {
2405    ["Size of cuvsHnswExtendParams"][::std::mem::size_of::<cuvsHnswExtendParams>() - 4usize];
2406    ["Alignment of cuvsHnswExtendParams"][::std::mem::align_of::<cuvsHnswExtendParams>() - 4usize];
2407    ["Offset of field: cuvsHnswExtendParams::num_threads"]
2408        [::std::mem::offset_of!(cuvsHnswExtendParams, num_threads) - 0usize];
2409};
2410pub type cuvsHnswExtendParams_t = *mut cuvsHnswExtendParams;
2411unsafe extern "C" {
2412    #[must_use]
2413    #[doc = " @brief Allocate HNSW extend params, and populate with default values\n\n @param[in] params cuvsHnswExtendParams_t to allocate\n @return cuvsError_t"]
2414    pub fn cuvsHnswExtendParamsCreate(params: *mut cuvsHnswExtendParams_t) -> cuvsError_t;
2415}
2416unsafe extern "C" {
2417    #[must_use]
2418    #[doc = " @brief De-allocate HNSW extend params\n\n @param[in] params cuvsHnswExtendParams_t to de-allocate\n @return cuvsError_t"]
2419    pub fn cuvsHnswExtendParamsDestroy(params: cuvsHnswExtendParams_t) -> cuvsError_t;
2420}
2421unsafe extern "C" {
2422    #[must_use]
2423    #[doc = " @brief Convert a CAGRA Index to an HNSW index.\n NOTE: When hierarchy is:\n       1. `NONE`: This method uses the filesystem to write the CAGRA index in\n `/tmp/<random_number>.bin` before reading it as an hnswlib index, then deleting the temporary\n file. The returned index is immutable and can only be searched by the hnswlib wrapper in cuVS,\n as the format is not compatible with the original hnswlib.\n       2. `CPU`: The returned index is mutable and can be extended with additional vectors. The\n serialized index is also compatible with the original hnswlib library.\n\n @param[in] res cuvsResources_t opaque C handle\n @param[in] params cuvsHnswIndexParams_t used to load Hnsw index\n @param[in] cagra_index cuvsCagraIndex_t to convert to HNSW index\n @param[out] hnsw_index cuvsHnswIndex_t to return the HNSW index\n\n @return cuvsError_t\n\n @code{.c}\n #include <cuvs/core/c_api.h>\n #include <cuvs/neighbors/cagra.h>\n #include <cuvs/neighbors/hnsw.h>\n\n // Create cuvsResources_t\n cuvsResources_t res;\n cuvsError_t res_create_status = cuvsResourcesCreate(&res);\n\n // create a CAGRA index with `cuvsCagraBuild`\n\n // Convert the CAGRA index to an HNSW index\n cuvsHnswIndex_t hnsw_index;\n cuvsHnswIndexCreate(&hnsw_index);\n cuvsHnswIndexParams_t hnsw_params;\n cuvsHnswIndexParamsCreate(&hnsw_params);\n cuvsHnswFromCagra(res, hnsw_params, cagra_index, hnsw_index);\n\n // de-allocate `hnsw_params`, `hnsw_index` and `res`\n cuvsError_t hnsw_params_destroy_status = cuvsHnswIndexParamsDestroy(hnsw_params);\n cuvsError_t hnsw_index_destroy_status = cuvsHnswIndexDestroy(hnsw_index);\n cuvsError_t res_destroy_status = cuvsResourcesDestroy(res);\n @endcode"]
2424    pub fn cuvsHnswFromCagra(
2425        res: cuvsResources_t,
2426        params: cuvsHnswIndexParams_t,
2427        cagra_index: cuvsCagraIndex_t,
2428        hnsw_index: cuvsHnswIndex_t,
2429    ) -> cuvsError_t;
2430}
2431unsafe extern "C" {
2432    #[must_use]
2433    pub fn cuvsHnswFromCagraWithDataset(
2434        res: cuvsResources_t,
2435        params: cuvsHnswIndexParams_t,
2436        cagra_index: cuvsCagraIndex_t,
2437        hnsw_index: cuvsHnswIndex_t,
2438        dataset_tensor: *mut DLManagedTensor,
2439    ) -> cuvsError_t;
2440}
2441unsafe extern "C" {
2442    #[must_use]
2443    #[doc = " @brief Build an HNSW index using ACE (Augmented Core Extraction) algorithm.\n\n ACE enables building HNSW indexes for datasets too large to fit in GPU memory by:\n 1. Partitioning the dataset using balanced k-means into core and augmented partitions\n 2. Building sub-indexes for each partition independently\n 3. Concatenating sub-graphs into a final unified index\n\n NOTE: This function requires CUDA to be available at runtime.\n\n @param[in] res cuvsResources_t opaque C handle\n @param[in] params cuvsHnswIndexParams_t with ACE parameters configured\n @param[in] dataset DLManagedTensor* host dataset to build index from\n @param[out] index cuvsHnswIndex_t to return the built HNSW index\n\n @return cuvsError_t\n\n @code{.c}\n #include <cuvs/core/c_api.h>\n #include <cuvs/neighbors/hnsw.h>\n\n // Create cuvsResources_t\n cuvsResources_t res;\n cuvsResourcesCreate(&res);\n\n // Create ACE parameters\n cuvsHnswAceParams_t ace_params;\n cuvsHnswAceParamsCreate(&ace_params);\n ace_params->npartitions = 4;\n ace_params->use_disk = true;\n ace_params->build_dir = \"/tmp/hnsw_ace_build\";\n\n // Create index parameters\n cuvsHnswIndexParams_t params;\n cuvsHnswIndexParamsCreate(&params);\n params->hierarchy = GPU;\n params->ace_params = ace_params;\n params->M = 32;\n params->ef_construction = 120;\n\n // Create HNSW index\n cuvsHnswIndex_t hnsw_index;\n cuvsHnswIndexCreate(&hnsw_index);\n\n // Assume dataset is a populated DLManagedTensor with host data\n DLManagedTensor dataset;\n\n // Build the index\n cuvsHnswBuild(res, params, &dataset, hnsw_index);\n\n // Clean up\n cuvsHnswAceParamsDestroy(ace_params);\n cuvsHnswIndexParamsDestroy(params);\n cuvsHnswIndexDestroy(hnsw_index);\n cuvsResourcesDestroy(res);\n @endcode"]
2444    pub fn cuvsHnswBuild(
2445        res: cuvsResources_t,
2446        params: cuvsHnswIndexParams_t,
2447        dataset: *mut DLManagedTensor,
2448        index: cuvsHnswIndex_t,
2449    ) -> cuvsError_t;
2450}
2451unsafe extern "C" {
2452    #[must_use]
2453    #[doc = " @brief Add new vectors to an HNSW index\n NOTE: The HNSW index can only be extended when the hierarchy is `CPU`\n       when converting from a CAGRA index.\n\n @param[in] res cuvsResources_t opaque C handle\n @param[in] params cuvsHnswExtendParams_t used to extend Hnsw index\n @param[in] additional_dataset DLManagedTensor* additional dataset to extend the index\n @param[inout] index cuvsHnswIndex_t to extend\n\n @return cuvsError_t\n\n @code{.c}\n #include <cuvs/core/c_api.h>\n #include <cuvs/neighbors/cagra.h>\n #include <cuvs/neighbors/hnsw.h>\n\n // Create cuvsResources_t\n cuvsResources_t res;\n cuvsError_t res_create_status = cuvsResourcesCreate(&res);\n\n // create an index with `cuvsCagraBuild`\n\n // Convert the CAGRA index to an HNSW index\n cuvsHnswIndex_t hnsw_index;\n cuvsHnswIndexCreate(&hnsw_index);\n cuvsHnswIndexParams_t hnsw_params;\n cuvsHnswIndexParamsCreate(&hnsw_params);\n cuvsHnswFromCagra(res, hnsw_params, cagra_index, hnsw_index);\n\n // Extend the HNSW index with additional vectors\n DLManagedTensor additional_dataset;\n cuvsHnswExtendParams_t extend_params;\n cuvsHnswExtendParamsCreate(&extend_params);\n cuvsHnswExtend(res, extend_params, additional_dataset, hnsw_index);\n\n // de-allocate `hnsw_params`, `hnsw_index`, `extend_params` and `res`\n cuvsError_t hnsw_params_destroy_status = cuvsHnswIndexParamsDestroy(hnsw_params);\n cuvsError_t hnsw_index_destroy_status = cuvsHnswIndexDestroy(hnsw_index);\n cuvsError_t extend_params_destroy_status = cuvsHnswExtendParamsDestroy(extend_params);\n cuvsError_t res_destroy_status = cuvsResourcesDestroy(res);\n @endcode"]
2454    pub fn cuvsHnswExtend(
2455        res: cuvsResources_t,
2456        params: cuvsHnswExtendParams_t,
2457        additional_dataset: *mut DLManagedTensor,
2458        index: cuvsHnswIndex_t,
2459    ) -> cuvsError_t;
2460}
2461#[doc = " @defgroup hnsw_c_search_params C API for hnswlib wrapper search params\n @{"]
2462#[repr(C)]
2463#[derive(Debug, Copy, Clone)]
2464pub struct cuvsHnswSearchParams {
2465    pub ef: i32,
2466    pub num_threads: i32,
2467}
2468#[allow(clippy::unnecessary_operation, clippy::identity_op)]
2469const _: () = {
2470    ["Size of cuvsHnswSearchParams"][::std::mem::size_of::<cuvsHnswSearchParams>() - 8usize];
2471    ["Alignment of cuvsHnswSearchParams"][::std::mem::align_of::<cuvsHnswSearchParams>() - 4usize];
2472    ["Offset of field: cuvsHnswSearchParams::ef"][::std::mem::offset_of!(cuvsHnswSearchParams, ef) - 0usize];
2473    ["Offset of field: cuvsHnswSearchParams::num_threads"]
2474        [::std::mem::offset_of!(cuvsHnswSearchParams, num_threads) - 4usize];
2475};
2476pub type cuvsHnswSearchParams_t = *mut cuvsHnswSearchParams;
2477unsafe extern "C" {
2478    #[must_use]
2479    #[doc = " @brief Allocate HNSW search params, and populate with default values\n\n @param[in] params cuvsHnswSearchParams_t to allocate\n @return cuvsError_t"]
2480    pub fn cuvsHnswSearchParamsCreate(params: *mut cuvsHnswSearchParams_t) -> cuvsError_t;
2481}
2482unsafe extern "C" {
2483    #[must_use]
2484    #[doc = " @brief De-allocate HNSW search params\n\n @param[in] params cuvsHnswSearchParams_t to de-allocate\n @return cuvsError_t"]
2485    pub fn cuvsHnswSearchParamsDestroy(params: cuvsHnswSearchParams_t) -> cuvsError_t;
2486}
2487unsafe extern "C" {
2488    #[must_use]
2489    #[doc = " @defgroup hnsw_c_index_search C API for CUDA ANN Graph-based nearest neighbor search\n @{\n/\n/**\n @brief Search a HNSW index with a `DLManagedTensor` which has underlying\n        `DLDeviceType` equal to `kDLCPU`, `kDLCUDAHost`, or `kDLCUDAManaged`.\n        It is also important to note that the HNSW Index must have been built\n        with the same type of `queries`, such that `index.dtype.code ==\n        queries.dl_tensor.dtype.code`\n        Supported types for input are:\n        1. `queries`:\n          a. `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 32`\n          b. `kDLDataType.code == kDLInt` and `kDLDataType.bits = 8`\n          c. `kDLDataType.code == kDLUInt` and `kDLDataType.bits = 8`\n        2. `neighbors`: `kDLDataType.code == kDLUInt` and `kDLDataType.bits = 64`\n        3. `distances`: `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 32`\n NOTE: When hierarchy is `NONE`, the HNSW index can only be searched by the hnswlib wrapper in\n cuVS, as the format is not compatible with the original hnswlib.\n\n @code {.c}\n #include <cuvs/core/c_api.h>\n #include <cuvs/neighbors/hnsw.h>\n\n // Create cuvsResources_t\n cuvsResources_t res;\n cuvsError_t res_create_status = cuvsResourcesCreate(&res);\n\n // Assume a populated `DLManagedTensor` type here\n DLManagedTensor dataset;\n DLManagedTensor queries;\n DLManagedTensor neighbors;\n\n // Create default search params\n cuvsHnswSearchParams_t params;\n cuvsError_t params_create_status = cuvsHnswSearchParamsCreate(&params);\n\n // Search the `index` built using `cuvsHnswFromCagra`\n cuvsError_t search_status = cuvsHnswSearch(res, params, index, &queries, &neighbors,\n &distances);\n\n // de-allocate `params` and `res`\n cuvsError_t params_destroy_status = cuvsHnswSearchParamsDestroy(params);\n cuvsError_t res_destroy_status = cuvsResourcesDestroy(res);\n @endcode\n\n @param[in] res cuvsResources_t opaque C handle\n @param[in] params cuvsHnswSearchParams_t used to search Hnsw index\n @param[in] index cuvsHnswIndex which has been returned by `cuvsHnswFromCagra`\n @param[in] queries DLManagedTensor* queries dataset to search\n @param[out] neighbors DLManagedTensor* output `k` neighbors for queries\n @param[out] distances DLManagedTensor* output `k` distances for queries"]
2490    pub fn cuvsHnswSearch(
2491        res: cuvsResources_t,
2492        params: cuvsHnswSearchParams_t,
2493        index: cuvsHnswIndex_t,
2494        queries: *mut DLManagedTensor,
2495        neighbors: *mut DLManagedTensor,
2496        distances: *mut DLManagedTensor,
2497    ) -> cuvsError_t;
2498}
2499unsafe extern "C" {
2500    #[must_use]
2501    #[doc = " @brief Serialize a CAGRA index to a file as an hnswlib index\n NOTE: When hierarchy is `NONE`, the saved hnswlib index is immutable and can only be read by\n the hnswlib wrapper in cuVS, as the serialization format is not compatible with the original\n hnswlib. However, when hierarchy is `CPU`, the saved hnswlib index is compatible with the\n original hnswlib library.\n\n @param[in] res cuvsResources_t opaque C handle\n @param[in] filename the name of the file to save the index\n @param[in] index cuvsHnswIndex_t to serialize\n @return cuvsError_t\n\n @code{.c}\n #include <cuvs/core/c_api.h>\n #include <cuvs/neighbors/cagra.h>\n #include <cuvs/neighbors/hnsw.h>\n\n // Create cuvsResources_t\n cuvsResources_t res;\n cuvsError_t res_create_status = cuvsResourcesCreate(&res);\n\n // create an index with `cuvsCagraBuild`\n\n // Convert the CAGRA index to an HNSW index\n cuvsHnswIndex_t hnsw_index;\n cuvsHnswIndexCreate(&hnsw_index);\n cuvsHnswIndexParams_t hnsw_params;\n cuvsHnswIndexParamsCreate(&hnsw_params);\n cuvsHnswFromCagra(res, hnsw_params, cagra_index, hnsw_index);\n\n // Serialize the HNSW index\n cuvsHnswSerialize(res, \"/path/to/index\", hnsw_index);\n\n // de-allocate `hnsw_params`, `hnsw_index` and `res`\n cuvsError_t hnsw_params_destroy_status = cuvsHnswIndexParamsDestroy(hnsw_params);\n cuvsError_t hnsw_index_destroy_status = cuvsHnswIndexDestroy(hnsw_index);\n cuvsError_t res_destroy_status = cuvsResourcesDestroy(res);\n @endcode"]
2502    pub fn cuvsHnswSerialize(
2503        res: cuvsResources_t,
2504        filename: *const ::std::os::raw::c_char,
2505        index: cuvsHnswIndex_t,
2506    ) -> cuvsError_t;
2507}
2508unsafe extern "C" {
2509    #[must_use]
2510    #[doc = " Load hnswlib index from file which was serialized from a HNSW index.\n NOTE: When hierarchy is `NONE`, the loaded hnswlib index is immutable, and only be read by the\n hnswlib wrapper in cuVS, as the serialization format is not compatible with the original\n hnswlib. Experimental, both the API and the serialization format are subject to change.\n\n @code{.c}\n #include <cuvs/core/c_api.h>\n #include <cuvs/neighbors/cagra.h>\n #include <cuvs/neighbors/hnsw.h>\n\n // Create cuvsResources_t\n cuvsResources_t res;\n cuvsError_t res_create_status = cuvsResourcesCreate(&res);\n\n // create an index with `cuvsCagraBuild`\n cuvsCagraSerializeHnswlib(res, \"/path/to/index\", index);\n\n // Load the serialized CAGRA index from file as an hnswlib index\n // The index should have the same dtype as the one used to build CAGRA the index\n cuvsHnswIndex_t hnsw_index;\n cuvsHnswIndexCreate(&hnsw_index);\n cuvsHnsWIndexParams_t hnsw_params;\n cuvsHnswIndexParamsCreate(&hnsw_params);\n hnsw_params->hierarchy = NONE;\n hnsw_index->dtype = index->dtype;\n cuvsHnswDeserialize(res, hnsw_params, \"/path/to/index\", dim, metric hnsw_index);\n @endcode\n\n @param[in] res cuvsResources_t opaque C handle\n @param[in] params cuvsHnswIndexParams_t used to load Hnsw index\n @param[in] filename the name of the file that stores the index\n @param[in] dim the dimension of the vectors in the index\n @param[in] metric the distance metric used to build the index\n @param[out] index HNSW index loaded disk"]
2511    pub fn cuvsHnswDeserialize(
2512        res: cuvsResources_t,
2513        params: cuvsHnswIndexParams_t,
2514        filename: *const ::std::os::raw::c_char,
2515        dim: ::std::os::raw::c_int,
2516        metric: cuvsDistanceType,
2517        index: cuvsHnswIndex_t,
2518    ) -> cuvsError_t;
2519}
2520#[repr(u32)]
2521#[doc = " @brief Solver algorithm for PCA eigen decomposition."]
2522#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
2523pub enum cuvsPcaSolver {
2524    #[doc = " Covariance + divide-and-conquer eigen decomposition"]
2525    CUVS_PCA_COV_EIG_DQ = 0,
2526    #[doc = " Covariance + Jacobi eigen decomposition"]
2527    CUVS_PCA_COV_EIG_JACOBI = 1,
2528}
2529#[doc = " @brief Parameters for PCA decomposition."]
2530#[repr(C)]
2531#[derive(Debug, Copy, Clone)]
2532pub struct cuvsPcaParams {
2533    #[doc = " Number of principal components to keep."]
2534    pub n_components: ::std::os::raw::c_int,
2535    #[doc = " If false, data passed to fit are overwritten and running fit(X).transform(X) will\n not yield the expected results; use fit_transform(X) instead."]
2536    pub copy: bool,
2537    #[doc = " When true the component vectors are multiplied by the square root of n_samples and then\n divided by the singular values to ensure uncorrelated outputs with unit component-wise\n variances."]
2538    pub whiten: bool,
2539    #[doc = " Solver algorithm to use."]
2540    pub algorithm: cuvsPcaSolver,
2541    #[doc = " Tolerance for singular values (used by Jacobi solver)."]
2542    pub tol: f32,
2543    #[doc = " Number of iterations for the power method (Jacobi solver)."]
2544    pub n_iterations: ::std::os::raw::c_int,
2545}
2546#[allow(clippy::unnecessary_operation, clippy::identity_op)]
2547const _: () = {
2548    ["Size of cuvsPcaParams"][::std::mem::size_of::<cuvsPcaParams>() - 20usize];
2549    ["Alignment of cuvsPcaParams"][::std::mem::align_of::<cuvsPcaParams>() - 4usize];
2550    ["Offset of field: cuvsPcaParams::n_components"][::std::mem::offset_of!(cuvsPcaParams, n_components) - 0usize];
2551    ["Offset of field: cuvsPcaParams::copy"][::std::mem::offset_of!(cuvsPcaParams, copy) - 4usize];
2552    ["Offset of field: cuvsPcaParams::whiten"][::std::mem::offset_of!(cuvsPcaParams, whiten) - 5usize];
2553    ["Offset of field: cuvsPcaParams::algorithm"][::std::mem::offset_of!(cuvsPcaParams, algorithm) - 8usize];
2554    ["Offset of field: cuvsPcaParams::tol"][::std::mem::offset_of!(cuvsPcaParams, tol) - 12usize];
2555    ["Offset of field: cuvsPcaParams::n_iterations"][::std::mem::offset_of!(cuvsPcaParams, n_iterations) - 16usize];
2556};
2557pub type cuvsPcaParams_t = *mut cuvsPcaParams;
2558unsafe extern "C" {
2559    #[must_use]
2560    #[doc = " @brief Allocate PCA params and populate with default values.\n\n @param[out] params cuvsPcaParams_t to allocate\n @return cuvsError_t"]
2561    pub fn cuvsPcaParamsCreate(params: *mut cuvsPcaParams_t) -> cuvsError_t;
2562}
2563unsafe extern "C" {
2564    #[must_use]
2565    #[doc = " @brief De-allocate PCA params.\n\n @param[in] params cuvsPcaParams_t to de-allocate\n @return cuvsError_t"]
2566    pub fn cuvsPcaParamsDestroy(params: cuvsPcaParams_t) -> cuvsError_t;
2567}
2568unsafe extern "C" {
2569    #[must_use]
2570    #[doc = " @brief Perform PCA fit operation.\n\n Computes the principal components, explained variances, singular values, and column means\n from the input data.\n\n The layout of `input` (C-contiguous / row-major or F-contiguous / col-major) is detected\n from its DLPack strides; `components` must use the same layout as `input`.\n\n @code {.c}\n #include <cuvs/core/c_api.h>\n #include <cuvs/preprocessing/pca.h>\n\n // Create cuvsResources_t\n cuvsResources_t res;\n cuvsResourcesCreate(&res);\n\n // Create PCA params\n cuvsPcaParams_t params;\n cuvsPcaParamsCreate(&params);\n params->n_components = 2;\n\n // Assume populated DLManagedTensor objects (float32, device memory)\n DLManagedTensor input;          // [n_rows x n_cols] (C- or F-contiguous)\n DLManagedTensor components;     // [n_components x n_cols] (same layout as input)\n DLManagedTensor explained_var;  // [n_components]\n DLManagedTensor explained_var_ratio; // [n_components]\n DLManagedTensor singular_vals;  // [n_components]\n DLManagedTensor mu;             // [n_cols]\n DLManagedTensor noise_vars;     // [1] (scalar)\n\n cuvsPcaFit(res, params, &input, &components, &explained_var,\n            &explained_var_ratio, &singular_vals, &mu, &noise_vars, false);\n\n // Cleanup\n cuvsPcaParamsDestroy(params);\n cuvsResourcesDestroy(res);\n @endcode\n\n @param[in] res cuvsResources_t opaque C handle\n @param[in] params PCA parameters\n @param[inout] input input data [n_rows x n_cols] (C- or F-contiguous, float32, device)\n @param[out] components principal components [n_components x n_cols] (same layout as input)\n @param[out] explained_var explained variances [n_components] (float32, device)\n @param[out] explained_var_ratio explained variance ratios [n_components] (float32, device)\n @param[out] singular_vals singular values [n_components] (float32, device)\n @param[out] mu column means [n_cols] (float32, device)\n @param[out] noise_vars noise variance [1] (float32, device)\n @param[in] flip_signs_based_on_U whether to determine signs by U (true) or V.T (false)\n @return cuvsError_t"]
2571    pub fn cuvsPcaFit(
2572        res: cuvsResources_t,
2573        params: cuvsPcaParams_t,
2574        input: *mut DLManagedTensor,
2575        components: *mut DLManagedTensor,
2576        explained_var: *mut DLManagedTensor,
2577        explained_var_ratio: *mut DLManagedTensor,
2578        singular_vals: *mut DLManagedTensor,
2579        mu: *mut DLManagedTensor,
2580        noise_vars: *mut DLManagedTensor,
2581        flip_signs_based_on_U: bool,
2582    ) -> cuvsError_t;
2583}
2584unsafe extern "C" {
2585    #[must_use]
2586    #[doc = " @brief Perform PCA fit and transform in a single operation.\n\n Computes the principal components and transforms the input data into the eigenspace.\n The layout of `input` (C- or F-contiguous) is detected from its DLPack strides; all\n other matrix tensors must use the same layout.\n\n @param[in] res cuvsResources_t opaque C handle\n @param[in] params PCA parameters\n @param[inout] input input data [n_rows x n_cols] (C- or F-contiguous, float32, device)\n @param[out] trans_input transformed data [n_rows x n_components] (same layout as input)\n @param[out] components principal components [n_components x n_cols] (same layout as input)\n @param[out] explained_var explained variances [n_components] (float32, device)\n @param[out] explained_var_ratio explained variance ratios [n_components] (float32, device)\n @param[out] singular_vals singular values [n_components] (float32, device)\n @param[out] mu column means [n_cols] (float32, device)\n @param[out] noise_vars noise variance [1] (float32, device)\n @param[in] flip_signs_based_on_U whether to determine signs by U (true) or V.T (false)\n @return cuvsError_t"]
2587    pub fn cuvsPcaFitTransform(
2588        res: cuvsResources_t,
2589        params: cuvsPcaParams_t,
2590        input: *mut DLManagedTensor,
2591        trans_input: *mut DLManagedTensor,
2592        components: *mut DLManagedTensor,
2593        explained_var: *mut DLManagedTensor,
2594        explained_var_ratio: *mut DLManagedTensor,
2595        singular_vals: *mut DLManagedTensor,
2596        mu: *mut DLManagedTensor,
2597        noise_vars: *mut DLManagedTensor,
2598        flip_signs_based_on_U: bool,
2599    ) -> cuvsError_t;
2600}
2601unsafe extern "C" {
2602    #[must_use]
2603    #[doc = " @brief Perform PCA transform operation.\n\n Transforms the input data into the eigenspace using previously computed principal components.\n The layout of `input` (C- or F-contiguous) is detected from its DLPack strides; all other\n matrix tensors must use the same layout.\n\n @param[in] res cuvsResources_t opaque C handle\n @param[in] params PCA parameters\n @param[inout] input data to transform [n_rows x n_cols] (C- or F-contiguous, float32, device)\n @param[in] components principal components [n_components x n_cols] (same layout as input)\n @param[in] singular_vals singular values [n_components] (float32, device)\n @param[in] mu column means [n_cols] (float32, device)\n @param[out] trans_input transformed data [n_rows x n_components] (same layout as input)\n @return cuvsError_t"]
2604    pub fn cuvsPcaTransform(
2605        res: cuvsResources_t,
2606        params: cuvsPcaParams_t,
2607        input: *mut DLManagedTensor,
2608        components: *mut DLManagedTensor,
2609        singular_vals: *mut DLManagedTensor,
2610        mu: *mut DLManagedTensor,
2611        trans_input: *mut DLManagedTensor,
2612    ) -> cuvsError_t;
2613}
2614unsafe extern "C" {
2615    #[must_use]
2616    #[doc = " @brief Perform PCA inverse transform operation.\n\n Transforms data from the eigenspace back to the original space.\n The layout of `trans_input` (C- or F-contiguous) is detected from its DLPack strides;\n all other matrix tensors must use the same layout.\n\n @param[in] res cuvsResources_t opaque C handle\n @param[in] params PCA parameters\n @param[in] trans_input transformed data [n_rows x n_components] (C- or F-contiguous,\n float32, device)\n @param[in] components principal components [n_components x n_cols] (same layout as trans_input)\n @param[in] singular_vals singular values [n_components] (float32, device)\n @param[in] mu column means [n_cols] (float32, device)\n @param[out] output reconstructed data [n_rows x n_cols] (same layout as trans_input)\n @return cuvsError_t"]
2617    pub fn cuvsPcaInverseTransform(
2618        res: cuvsResources_t,
2619        params: cuvsPcaParams_t,
2620        trans_input: *mut DLManagedTensor,
2621        components: *mut DLManagedTensor,
2622        singular_vals: *mut DLManagedTensor,
2623        mu: *mut DLManagedTensor,
2624        output: *mut DLManagedTensor,
2625    ) -> cuvsError_t;
2626}
2627#[repr(u32)]
2628#[doc = " @defgroup preprocessing_c_binary C API for Binary Quantizer\n @{\n/\n/**\n @brief In the cuvsBinaryQuantizerTransform function, a bit is set if the corresponding element in\n the dataset vector is greater than the corresponding element in the threshold vector. The mean\n and sampling_median thresholds are calculated separately for each dimension.\n"]
2629#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
2630pub enum cuvsBinaryQuantizerThreshold {
2631    ZERO = 0,
2632    MEAN = 1,
2633    SAMPLING_MEDIAN = 2,
2634}
2635#[doc = " @brief Binary quantizer parameters."]
2636#[repr(C)]
2637#[derive(Debug, Copy, Clone)]
2638pub struct cuvsBinaryQuantizerParams {
2639    pub threshold: cuvsBinaryQuantizerThreshold,
2640    pub sampling_ratio: f32,
2641}
2642#[allow(clippy::unnecessary_operation, clippy::identity_op)]
2643const _: () = {
2644    ["Size of cuvsBinaryQuantizerParams"][::std::mem::size_of::<cuvsBinaryQuantizerParams>() - 8usize];
2645    ["Alignment of cuvsBinaryQuantizerParams"][::std::mem::align_of::<cuvsBinaryQuantizerParams>() - 4usize];
2646    ["Offset of field: cuvsBinaryQuantizerParams::threshold"]
2647        [::std::mem::offset_of!(cuvsBinaryQuantizerParams, threshold) - 0usize];
2648    ["Offset of field: cuvsBinaryQuantizerParams::sampling_ratio"]
2649        [::std::mem::offset_of!(cuvsBinaryQuantizerParams, sampling_ratio) - 4usize];
2650};
2651pub type cuvsBinaryQuantizerParams_t = *mut cuvsBinaryQuantizerParams;
2652unsafe extern "C" {
2653    #[must_use]
2654    #[doc = " @brief Allocate Binary Quantizer params, and populate with default values\n\n @param[in] params cuvsBinaryQuantizerParams_t to allocate\n @return cuvsError_t"]
2655    pub fn cuvsBinaryQuantizerParamsCreate(params: *mut cuvsBinaryQuantizerParams_t) -> cuvsError_t;
2656}
2657unsafe extern "C" {
2658    #[must_use]
2659    #[doc = " @brief De-allocate Binary Quantizer params\n\n @param[in] params\n @return cuvsError_t"]
2660    pub fn cuvsBinaryQuantizerParamsDestroy(params: cuvsBinaryQuantizerParams_t) -> cuvsError_t;
2661}
2662#[doc = " @brief Defines and stores threshold for quantization upon training\n\n The quantization is performed by a linear mapping of an interval in the\n float data type to the full range of the quantized int type."]
2663#[repr(C)]
2664#[derive(Debug, Copy, Clone)]
2665pub struct cuvsBinaryQuantizer {
2666    pub addr: usize,
2667    pub dtype: DLDataType,
2668}
2669#[allow(clippy::unnecessary_operation, clippy::identity_op)]
2670const _: () = {
2671    ["Size of cuvsBinaryQuantizer"][::std::mem::size_of::<cuvsBinaryQuantizer>() - 16usize];
2672    ["Alignment of cuvsBinaryQuantizer"][::std::mem::align_of::<cuvsBinaryQuantizer>() - 8usize];
2673    ["Offset of field: cuvsBinaryQuantizer::addr"][::std::mem::offset_of!(cuvsBinaryQuantizer, addr) - 0usize];
2674    ["Offset of field: cuvsBinaryQuantizer::dtype"][::std::mem::offset_of!(cuvsBinaryQuantizer, dtype) - 8usize];
2675};
2676pub type cuvsBinaryQuantizer_t = *mut cuvsBinaryQuantizer;
2677unsafe extern "C" {
2678    #[must_use]
2679    #[doc = " @brief Allocate Binary Quantizer and populate with default values\n\n @param[in] quantizer cuvsBinaryQuantizer_t to allocate\n @return cuvsError_t"]
2680    pub fn cuvsBinaryQuantizerCreate(quantizer: *mut cuvsBinaryQuantizer_t) -> cuvsError_t;
2681}
2682unsafe extern "C" {
2683    #[must_use]
2684    #[doc = " @brief De-allocate Binary Quantizer\n\n @param[in] quantizer\n @return cuvsError_t"]
2685    pub fn cuvsBinaryQuantizerDestroy(quantizer: cuvsBinaryQuantizer_t) -> cuvsError_t;
2686}
2687unsafe extern "C" {
2688    #[must_use]
2689    #[doc = " @brief Trains a binary quantizer to be used later for quantizing the dataset.\n\n @param[in] res raft resource\n @param[in] params configure binary quantizer, e.g. threshold\n @param[in] dataset a row-major host or device matrix\n @param[out] quantizer trained binary quantizer"]
2690    pub fn cuvsBinaryQuantizerTrain(
2691        res: cuvsResources_t,
2692        params: cuvsBinaryQuantizerParams_t,
2693        dataset: *mut DLManagedTensor,
2694        quantizer: cuvsBinaryQuantizer_t,
2695    ) -> cuvsError_t;
2696}
2697unsafe extern "C" {
2698    #[must_use]
2699    #[doc = " @brief Applies binary quantization transform to the given dataset\n\n This applies binary quantization to a dataset, changing any positive\n values to a bitwise 1. This is useful for searching with the\n BitwiseHamming distance type.\n\n @param[in] res raft resource\n @param[in] dataset a row-major host or device matrix to transform\n @param[out] out a row-major host or device matrix to store transformed data"]
2700    pub fn cuvsBinaryQuantizerTransform(
2701        res: cuvsResources_t,
2702        dataset: *mut DLManagedTensor,
2703        out: *mut DLManagedTensor,
2704    ) -> cuvsError_t;
2705}
2706unsafe extern "C" {
2707    #[must_use]
2708    #[doc = " @brief Applies binary quantization transform to the given dataset\n\n This applies binary quantization to a dataset, changing any values that are larger than the\n threshold specified in the param to a bitwise 1. This is useful for searching with the\n BitwiseHamming distance type.\n\n @param[in] res raft resource\n @param[in] quantizer binary quantizer\n @param[in] dataset a row-major host or device matrix to transform\n @param[out] out a row-major host or device matrix to store transformed data"]
2709    pub fn cuvsBinaryQuantizerTransformWithParams(
2710        res: cuvsResources_t,
2711        quantizer: cuvsBinaryQuantizer_t,
2712        dataset: *mut DLManagedTensor,
2713        out: *mut DLManagedTensor,
2714    ) -> cuvsError_t;
2715}
2716#[doc = " @defgroup preprocessing_c_pq C API for Product Quantizer\n @{\n/\n/**\n @brief Product quantizer parameters."]
2717#[repr(C)]
2718#[derive(Debug, Copy, Clone)]
2719pub struct cuvsProductQuantizerParams {
2720    #[doc = " The bit length of the vector element after compression by PQ.\n\n Possible values: within [4, 16].\n\n Hint: the smaller the 'pq_bits', the smaller the index size and the better the search\n performance, but the lower the recall."]
2721    pub pq_bits: u32,
2722    #[doc = " The dimensionality of the vector after compression by PQ.\n When zero, an optimal value is selected using a heuristic.\n\n TODO: at the moment `dim` must be a multiple `pq_dim`."]
2723    pub pq_dim: u32,
2724    #[doc = " Whether to use subspaces for product quantization (PQ).\n When true, one PQ codebook is used for each subspace. Otherwise, a single\n PQ codebook is used."]
2725    pub use_subspaces: bool,
2726    #[doc = " Whether to use Vector Quantization (KMeans) before product quantization (PQ).\n When true, VQ is used before PQ. When false, only product quantization is used."]
2727    pub use_vq: bool,
2728    #[doc = " Vector Quantization (VQ) codebook size - number of \"coarse cluster centers\".\n When zero, an optimal value is selected using a heuristic.\n When one, only product quantization is used."]
2729    pub vq_n_centers: u32,
2730    #[doc = " The number of iterations searching for kmeans centers (both VQ & PQ phases)."]
2731    pub kmeans_n_iters: u32,
2732    #[doc = " The type of kmeans algorithm to use for PQ training."]
2733    pub pq_kmeans_type: cuvsKMeansType,
2734    #[doc = " The max number of data points to use per PQ code during PQ codebook training. Using more data\n points per PQ code may increase the quality of PQ codebook but may also increase the build\n time. We will use `pq_n_centers * max_train_points_per_pq_code` training\n points to train each PQ codebook."]
2735    pub max_train_points_per_pq_code: u32,
2736    #[doc = " The max number of data points to use per VQ cluster."]
2737    pub max_train_points_per_vq_cluster: u32,
2738}
2739#[allow(clippy::unnecessary_operation, clippy::identity_op)]
2740const _: () = {
2741    ["Size of cuvsProductQuantizerParams"][::std::mem::size_of::<cuvsProductQuantizerParams>() - 32usize];
2742    ["Alignment of cuvsProductQuantizerParams"][::std::mem::align_of::<cuvsProductQuantizerParams>() - 4usize];
2743    ["Offset of field: cuvsProductQuantizerParams::pq_bits"]
2744        [::std::mem::offset_of!(cuvsProductQuantizerParams, pq_bits) - 0usize];
2745    ["Offset of field: cuvsProductQuantizerParams::pq_dim"]
2746        [::std::mem::offset_of!(cuvsProductQuantizerParams, pq_dim) - 4usize];
2747    ["Offset of field: cuvsProductQuantizerParams::use_subspaces"]
2748        [::std::mem::offset_of!(cuvsProductQuantizerParams, use_subspaces) - 8usize];
2749    ["Offset of field: cuvsProductQuantizerParams::use_vq"]
2750        [::std::mem::offset_of!(cuvsProductQuantizerParams, use_vq) - 9usize];
2751    ["Offset of field: cuvsProductQuantizerParams::vq_n_centers"]
2752        [::std::mem::offset_of!(cuvsProductQuantizerParams, vq_n_centers) - 12usize];
2753    ["Offset of field: cuvsProductQuantizerParams::kmeans_n_iters"]
2754        [::std::mem::offset_of!(cuvsProductQuantizerParams, kmeans_n_iters) - 16usize];
2755    ["Offset of field: cuvsProductQuantizerParams::pq_kmeans_type"]
2756        [::std::mem::offset_of!(cuvsProductQuantizerParams, pq_kmeans_type) - 20usize];
2757    ["Offset of field: cuvsProductQuantizerParams::max_train_points_per_pq_code"]
2758        [::std::mem::offset_of!(cuvsProductQuantizerParams, max_train_points_per_pq_code) - 24usize];
2759    ["Offset of field: cuvsProductQuantizerParams::max_train_points_per_vq_cluster"]
2760        [::std::mem::offset_of!(cuvsProductQuantizerParams, max_train_points_per_vq_cluster) - 28usize];
2761};
2762pub type cuvsProductQuantizerParams_t = *mut cuvsProductQuantizerParams;
2763unsafe extern "C" {
2764    #[must_use]
2765    #[doc = " @brief Allocate Product Quantizer params, and populate with default values\n\n @param[in] params cuvsProductQuantizerParams_t to allocate\n @return cuvsError_t"]
2766    pub fn cuvsProductQuantizerParamsCreate(params: *mut cuvsProductQuantizerParams_t) -> cuvsError_t;
2767}
2768unsafe extern "C" {
2769    #[must_use]
2770    #[doc = " @brief De-allocate Product Quantizer params\n\n @param[in] params\n @return cuvsError_t"]
2771    pub fn cuvsProductQuantizerParamsDestroy(params: cuvsProductQuantizerParams_t) -> cuvsError_t;
2772}
2773#[doc = " @brief Defines and stores product quantizer upon training\n\n The quantization is performed by a linear mapping of an interval in the\n float data type to the full range of the quantized int type."]
2774#[repr(C)]
2775#[derive(Debug, Copy, Clone)]
2776pub struct cuvsProductQuantizer {
2777    pub addr: usize,
2778    pub dtype: DLDataType,
2779}
2780#[allow(clippy::unnecessary_operation, clippy::identity_op)]
2781const _: () = {
2782    ["Size of cuvsProductQuantizer"][::std::mem::size_of::<cuvsProductQuantizer>() - 16usize];
2783    ["Alignment of cuvsProductQuantizer"][::std::mem::align_of::<cuvsProductQuantizer>() - 8usize];
2784    ["Offset of field: cuvsProductQuantizer::addr"][::std::mem::offset_of!(cuvsProductQuantizer, addr) - 0usize];
2785    ["Offset of field: cuvsProductQuantizer::dtype"][::std::mem::offset_of!(cuvsProductQuantizer, dtype) - 8usize];
2786};
2787pub type cuvsProductQuantizer_t = *mut cuvsProductQuantizer;
2788unsafe extern "C" {
2789    #[must_use]
2790    #[doc = " @brief Allocate Product Quantizer\n\n @param[in] quantizer cuvsProductQuantizer_t to allocate\n @return cuvsError_t"]
2791    pub fn cuvsProductQuantizerCreate(quantizer: *mut cuvsProductQuantizer_t) -> cuvsError_t;
2792}
2793unsafe extern "C" {
2794    #[must_use]
2795    #[doc = " @brief De-allocate Product Quantizer\n\n @param[in] quantizer\n @return cuvsError_t"]
2796    pub fn cuvsProductQuantizerDestroy(quantizer: cuvsProductQuantizer_t) -> cuvsError_t;
2797}
2798unsafe extern "C" {
2799    #[must_use]
2800    #[doc = " @brief Builds a product quantizer to be used later for quantizing the dataset.\n\n @param[in] res raft resource\n @param[in] params Parameters for product quantizer training\n @param[in] dataset a row-major host or device matrix\n @param[out] quantizer trained product quantizer"]
2801    pub fn cuvsProductQuantizerBuild(
2802        res: cuvsResources_t,
2803        params: cuvsProductQuantizerParams_t,
2804        dataset: *mut DLManagedTensor,
2805        quantizer: cuvsProductQuantizer_t,
2806    ) -> cuvsError_t;
2807}
2808unsafe extern "C" {
2809    #[must_use]
2810    #[doc = " @brief Applies product quantization transform to the given dataset\n\n This applies product quantization to a dataset.\n\n @param[in] res raft resource\n @param[in] quantizer product quantizer\n @param[in] dataset a row-major host or device matrix to transform\n @param[out] codes_out a row-major device matrix to store transformed data\n @param[out] vq_labels a device vector to store VQ labels.\n   Optional, can be NULL."]
2811    pub fn cuvsProductQuantizerTransform(
2812        res: cuvsResources_t,
2813        quantizer: cuvsProductQuantizer_t,
2814        dataset: *mut DLManagedTensor,
2815        codes_out: *mut DLManagedTensor,
2816        vq_labels: *mut DLManagedTensor,
2817    ) -> cuvsError_t;
2818}
2819unsafe extern "C" {
2820    #[must_use]
2821    #[doc = " @brief Applies product quantization inverse transform to the given quantized codes\n\n This applies product quantization inverse transform to the given quantized codes.\n\n @param[in] res raft resource\n @param[in] quantizer product quantizer\n @param[in] pq_codes a row-major device matrix of quantized codes\n @param[out] out a row-major device matrix to store the original data\n @param[out] vq_labels a device vector containing the VQ labels when VQ is used.\n   Optional, can be NULL."]
2822    pub fn cuvsProductQuantizerInverseTransform(
2823        res: cuvsResources_t,
2824        quantizer: cuvsProductQuantizer_t,
2825        pq_codes: *mut DLManagedTensor,
2826        out: *mut DLManagedTensor,
2827        vq_labels: *mut DLManagedTensor,
2828    ) -> cuvsError_t;
2829}
2830unsafe extern "C" {
2831    #[must_use]
2832    #[doc = " @brief Get the bit length of the vector element after compression by PQ.\n\n @param[in] quantizer product quantizer\n @param[out] pq_bits bit length of the vector element after compression by PQ"]
2833    pub fn cuvsProductQuantizerGetPqBits(quantizer: cuvsProductQuantizer_t, pq_bits: *mut u32) -> cuvsError_t;
2834}
2835unsafe extern "C" {
2836    #[must_use]
2837    #[doc = " @brief Get the dimensionality of the vector after compression by PQ.\n\n @param[in] quantizer product quantizer\n @param[out] pq_dim dimensionality of the vector after compression by PQ"]
2838    pub fn cuvsProductQuantizerGetPqDim(quantizer: cuvsProductQuantizer_t, pq_dim: *mut u32) -> cuvsError_t;
2839}
2840unsafe extern "C" {
2841    #[must_use]
2842    #[doc = " @brief Get the PQ codebook.\n\n @param[in] quantizer product quantizer\n @param[out] pq_codebook PQ codebook"]
2843    pub fn cuvsProductQuantizerGetPqCodebook(
2844        quantizer: cuvsProductQuantizer_t,
2845        pq_codebook: *mut DLManagedTensor,
2846    ) -> cuvsError_t;
2847}
2848unsafe extern "C" {
2849    #[must_use]
2850    #[doc = " @brief Get the VQ codebook.\n\n @param[in] quantizer product quantizer\n @param[out] vq_codebook VQ codebook"]
2851    pub fn cuvsProductQuantizerGetVqCodebook(
2852        quantizer: cuvsProductQuantizer_t,
2853        vq_codebook: *mut DLManagedTensor,
2854    ) -> cuvsError_t;
2855}
2856unsafe extern "C" {
2857    #[must_use]
2858    #[doc = " @brief Get the encoded dimension of the quantized dataset.\n\n @param[in] quantizer product quantizer\n @param[out] encoded_dim encoded dimension of the quantized dataset"]
2859    pub fn cuvsProductQuantizerGetEncodedDim(quantizer: cuvsProductQuantizer_t, encoded_dim: *mut u32) -> cuvsError_t;
2860}
2861unsafe extern "C" {
2862    #[must_use]
2863    #[doc = " @brief Get whether VQ is used.\n\n @param[in] quantizer product quantizer\n @param[out] use_vq whether VQ is used"]
2864    pub fn cuvsProductQuantizerGetUseVq(quantizer: cuvsProductQuantizer_t, use_vq: *mut bool) -> cuvsError_t;
2865}
2866#[doc = " @defgroup preprocessing_c_scalar C API for Scalar Quantizer\n @{\n/\n/**\n @brief Scalar quantizer parameters."]
2867#[repr(C)]
2868#[derive(Debug, Copy, Clone)]
2869pub struct cuvsScalarQuantizerParams {
2870    pub quantile: f32,
2871}
2872#[allow(clippy::unnecessary_operation, clippy::identity_op)]
2873const _: () = {
2874    ["Size of cuvsScalarQuantizerParams"][::std::mem::size_of::<cuvsScalarQuantizerParams>() - 4usize];
2875    ["Alignment of cuvsScalarQuantizerParams"][::std::mem::align_of::<cuvsScalarQuantizerParams>() - 4usize];
2876    ["Offset of field: cuvsScalarQuantizerParams::quantile"]
2877        [::std::mem::offset_of!(cuvsScalarQuantizerParams, quantile) - 0usize];
2878};
2879pub type cuvsScalarQuantizerParams_t = *mut cuvsScalarQuantizerParams;
2880unsafe extern "C" {
2881    #[must_use]
2882    #[doc = " @brief Allocate Scalar Quantizer params, and populate with default values\n\n @param[in] params cuvsScalarQuantizerParams_t to allocate\n @return cuvsError_t"]
2883    pub fn cuvsScalarQuantizerParamsCreate(params: *mut cuvsScalarQuantizerParams_t) -> cuvsError_t;
2884}
2885unsafe extern "C" {
2886    #[must_use]
2887    #[doc = " @brief De-allocate Scalar Quantizer params\n\n @param[in] params\n @return cuvsError_t"]
2888    pub fn cuvsScalarQuantizerParamsDestroy(params: cuvsScalarQuantizerParams_t) -> cuvsError_t;
2889}
2890#[doc = " @brief Defines and stores scalar for quantisation upon training\n\n The quantization is performed by a linear mapping of an interval in the\n float data type to the full range of the quantized int type."]
2891#[repr(C)]
2892#[derive(Debug, Copy, Clone)]
2893pub struct cuvsScalarQuantizer {
2894    pub min_: f64,
2895    pub max_: f64,
2896}
2897#[allow(clippy::unnecessary_operation, clippy::identity_op)]
2898const _: () = {
2899    ["Size of cuvsScalarQuantizer"][::std::mem::size_of::<cuvsScalarQuantizer>() - 16usize];
2900    ["Alignment of cuvsScalarQuantizer"][::std::mem::align_of::<cuvsScalarQuantizer>() - 8usize];
2901    ["Offset of field: cuvsScalarQuantizer::min_"][::std::mem::offset_of!(cuvsScalarQuantizer, min_) - 0usize];
2902    ["Offset of field: cuvsScalarQuantizer::max_"][::std::mem::offset_of!(cuvsScalarQuantizer, max_) - 8usize];
2903};
2904pub type cuvsScalarQuantizer_t = *mut cuvsScalarQuantizer;
2905unsafe extern "C" {
2906    #[must_use]
2907    #[doc = " @brief Allocate Scalar Quantizer and populate with default values\n\n @param[in] quantizer cuvsScalarQuantizer_t to allocate\n @return cuvsError_t"]
2908    pub fn cuvsScalarQuantizerCreate(quantizer: *mut cuvsScalarQuantizer_t) -> cuvsError_t;
2909}
2910unsafe extern "C" {
2911    #[must_use]
2912    #[doc = " @brief De-allocate Scalar Quantizer\n\n @param[in] quantizer\n @return cuvsError_t"]
2913    pub fn cuvsScalarQuantizerDestroy(quantizer: cuvsScalarQuantizer_t) -> cuvsError_t;
2914}
2915unsafe extern "C" {
2916    #[must_use]
2917    #[doc = " @brief Trains a scalar quantizer to be used later for quantizing the dataset.\n\n @param[in] res raft resource\n @param[in] params configure scalar quantizer, e.g. quantile\n @param[in] dataset a row-major host or device matrix\n @param[out] quantizer trained scalar quantizer"]
2918    pub fn cuvsScalarQuantizerTrain(
2919        res: cuvsResources_t,
2920        params: cuvsScalarQuantizerParams_t,
2921        dataset: *mut DLManagedTensor,
2922        quantizer: cuvsScalarQuantizer_t,
2923    ) -> cuvsError_t;
2924}
2925unsafe extern "C" {
2926    #[must_use]
2927    #[doc = " @brief Applies quantization transform to given dataset\n\n @param[in] res raft resource\n @param[in] quantizer a scalar quantizer\n @param[in] dataset a row-major host or device matrix to transform\n @param[out] out a row-major host or device matrix to store transformed data"]
2928    pub fn cuvsScalarQuantizerTransform(
2929        res: cuvsResources_t,
2930        quantizer: cuvsScalarQuantizer_t,
2931        dataset: *mut DLManagedTensor,
2932        out: *mut DLManagedTensor,
2933    ) -> cuvsError_t;
2934}
2935unsafe extern "C" {
2936    #[must_use]
2937    #[doc = " @brief Perform inverse quantization step on previously quantized dataset\n\n Note that depending on the chosen data types train dataset the conversion is\n not lossless.\n\n @param[in] res raft resource\n @param[in] quantizer a scalar quantizer\n @param[in] dataset a row-major host or device matrix\n @param[out] out a row-major host or device matrix\n"]
2938    pub fn cuvsScalarQuantizerInverseTransform(
2939        res: cuvsResources_t,
2940        quantizer: cuvsScalarQuantizer_t,
2941        dataset: *mut DLManagedTensor,
2942        out: *mut DLManagedTensor,
2943    ) -> cuvsError_t;
2944}
2945unsafe extern "C" {
2946    #[must_use]
2947    #[doc = " @brief Select the k smallest values from a flat device array of n candidates.\n\n Treats `in_val` as a matrix of shape [1, n] and selects the `k` smallest\n float values.  `out_idx` receives the int64 column positions of the selected\n values in [0, n), so the caller can recover per-segment identity as:\n\n   segment_index        = out_idx[j] / segment_k\n   position_in_segment  = out_idx[j] % segment_k\n\n @param[in]  res      cuvsResources_t handle\n @param[in]  in_val   DLManagedTensor* shape [1, n], float32, device memory\n @param[out] out_val  DLManagedTensor* shape [1, k], float32, device memory\n @param[out] out_idx  DLManagedTensor* shape [1, k], int64,   device memory\n @return cuvsError_t"]
2948    pub fn cuvsSelectK(
2949        res: cuvsResources_t,
2950        in_val: *mut DLManagedTensor,
2951        out_val: *mut DLManagedTensor,
2952        out_idx: *mut DLManagedTensor,
2953    ) -> cuvsError_t;
2954}
2955unsafe extern "C" {
2956    #[must_use]
2957    #[doc = " @brief Select the k smallest or largest values from each row of a device\n matrix.\n\n Requires batch >= 1 and 1 <= k <= len. Each row of `in_val` has `len` values.\n `out_idx` receives their int64 column positions in [0, len). When `sorted` is\n true, each output row is ordered by\n value (ascending for `select_min`, descending otherwise). The order of equal\n values is unspecified.\n\n @param[in]  res         cuvsResources_t handle\n @param[in]  in_val      DLManagedTensor* shape [batch, len], float32, row-major device\n @param[out] out_val     DLManagedTensor* shape [batch, k], float32, row-major device\n @param[out] out_idx     DLManagedTensor* shape [batch, k], int64, row-major device\n @param[in]  select_min  Select smallest values if true, largest if false\n @param[in]  sorted      Order each output row by value if true\n @return cuvsError_t"]
2958    pub fn cuvsSelectKBatched(
2959        res: cuvsResources_t,
2960        in_val: *mut DLManagedTensor,
2961        out_val: *mut DLManagedTensor,
2962        out_idx: *mut DLManagedTensor,
2963        select_min: bool,
2964        sorted: bool,
2965    ) -> cuvsError_t;
2966}