Skip to main content

cuvs_sys/
lib.rs

1//! Generated raw FFI bindings to the pinned cuVS 26.08 C API.
2//!
3//! Published as an Algeon implementation dependency. Applications use
4//! [`algeon-datafusion`](https://docs.rs/algeon-datafusion); workspace code
5//! uses this crate for its component contracts. See the
6//! [API documentation boundary](https://algeon.dev/design#api-documentation).
7
8#![allow(clippy::allow_attributes)] // reason = "generated FFI bindings use allow attributes"
9
10use std::{
11    ffi::{c_char, c_int, c_uint, c_void},
12    fmt,
13};
14
15pub const EXPECTED_CUVS_VERSION: (u16, u16, u16) = (26, 8, 1);
16
17#[repr(C)]
18#[derive(Debug, Copy, Clone)]
19pub struct CUstream_st {
20    _private: [u8; 0],
21}
22
23#[allow(non_camel_case_types)]
24pub type cudaStream_t = *mut CUstream_st;
25
26#[allow(non_camel_case_types)]
27#[repr(transparent)]
28#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
29pub struct cudaDataType_t(c_uint);
30
31impl cudaDataType_t {
32    pub const CUDA_R_32F: Self = Self(0);
33    pub const CUDA_R_16F: Self = Self(2);
34    pub const CUDA_R_8I: Self = Self(3);
35    pub const CUDA_R_8U: Self = Self(8);
36
37    pub const fn from_raw(value: c_uint) -> Self {
38        Self(value)
39    }
40
41    pub const fn as_raw(self) -> c_uint {
42        self.0
43    }
44}
45
46#[allow(
47    non_upper_case_globals,
48    non_camel_case_types,
49    non_snake_case,
50    unused_attributes,
51    rustdoc::broken_intra_doc_links,
52    rustdoc::invalid_html_tags
53)]
54mod bindings;
55
56impl Copy for bindings::cuvsIvfPqSearchParams {}
57
58impl Clone for bindings::cuvsIvfPqSearchParams {
59    fn clone(&self) -> Self {
60        *self
61    }
62}
63
64impl fmt::Debug for bindings::cuvsIvfPqSearchParams {
65    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
66        f.debug_struct("cuvsIvfPqSearchParams")
67            .field("n_probes", &self.n_probes)
68            .field("lut_dtype", &self.lut_dtype)
69            .field("internal_distance_dtype", &self.internal_distance_dtype)
70            .field("coarse_search_dtype", &self.coarse_search_dtype)
71            .field("max_internal_batch_size", &self.max_internal_batch_size)
72            .field("preferred_shmem_carveout", &self.preferred_shmem_carveout)
73            .finish()
74    }
75}
76
77pub use bindings::*;
78
79#[allow(non_camel_case_types)]
80pub type cudaError_t = c_int;
81#[allow(non_camel_case_types)]
82pub type cudaMemcpyKind = c_uint;
83
84#[allow(non_upper_case_globals)]
85pub const cudaSuccess: cudaError_t = 0;
86#[allow(non_upper_case_globals)]
87pub const cudaMemcpyHostToDevice: cudaMemcpyKind = 1;
88#[allow(non_upper_case_globals)]
89pub const cudaMemcpyDeviceToHost: cudaMemcpyKind = 2;
90
91#[link(name = "cudart")]
92unsafe extern "C" {
93    pub fn cudaGetErrorString(error: cudaError_t) -> *const c_char;
94    pub fn cudaGetDeviceCount(count: *mut c_int) -> cudaError_t;
95    pub fn cudaDeviceSynchronize() -> cudaError_t;
96    pub fn cudaMalloc(dev_ptr: *mut *mut c_void, size: usize) -> cudaError_t;
97    pub fn cudaFree(dev_ptr: *mut c_void) -> cudaError_t;
98    pub fn cudaMemcpy(dst: *mut c_void, src: *const c_void, count: usize, kind: cudaMemcpyKind) -> cudaError_t;
99    pub fn cudaStreamCreate(stream: *mut cudaStream_t) -> cudaError_t;
100    pub fn cudaStreamDestroy(stream: cudaStream_t) -> cudaError_t;
101    pub fn cudaStreamSynchronize(stream: cudaStream_t) -> cudaError_t;
102}
103
104#[derive(Debug, Clone, Copy, PartialEq, Eq)]
105pub enum RuntimeVersionError {
106    QueryFailed,
107    Incompatible { expected: (u16, u16, u16), actual: (u16, u16, u16) },
108}
109
110impl fmt::Display for RuntimeVersionError {
111    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
112        match self {
113            Self::QueryFailed => write!(f, "cuvsVersionGet failed"),
114            Self::Incompatible { expected, actual } => write!(
115                f,
116                "cuVS runtime version {}.{}.{} does not match required {}.{}.{}",
117                actual.0, actual.1, actual.2, expected.0, expected.1, expected.2
118            ),
119        }
120    }
121}
122
123impl std::error::Error for RuntimeVersionError {}
124
125/// Query and validate the exact native cuVS version required by this binding.
126pub fn validate_runtime_version() -> Result<(u16, u16, u16), RuntimeVersionError> {
127    let mut major = 0;
128    let mut minor = 0;
129    let mut patch = 0;
130    let status = unsafe { cuvsVersionGet(&mut major, &mut minor, &mut patch) };
131    if status != cuvsError_t::CUVS_SUCCESS {
132        return Err(RuntimeVersionError::QueryFailed);
133    }
134    let actual = (major, minor, patch);
135    if actual != EXPECTED_CUVS_VERSION {
136        return Err(RuntimeVersionError::Incompatible { expected: EXPECTED_CUVS_VERSION, actual });
137    }
138    Ok(actual)
139}