Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 23 additions & 19 deletions bindings_generator/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ fn create_modules() -> Vec<ModuleConfig> {
libs: vec!["cudart"],
clang_args: vec![],
raw_lines: vec![],
derive_default: true,
},
ModuleConfig {
cudarc_name: "driver",
Expand All @@ -55,15 +56,13 @@ fn create_modules() -> Vec<ModuleConfig> {
blocklist: Filters {
// NOTE: See https://github.com/coreylowman/cudarc/issues/385
types: vec!["^cuCheckpoint.*"],
functions: vec![
"^cuCheckpoint.*",
"cuDeviceGetNvSciSyncAttributes",
],
functions: vec!["^cuCheckpoint.*", "cuDeviceGetNvSciSyncAttributes"],
vars: vec![],
},
libs: vec!["cuda", "nvcuda"],
clang_args: vec![],
raw_lines: vec![],
derive_default: true,
},
ModuleConfig {
cudarc_name: "cublas",
Expand All @@ -78,6 +77,7 @@ fn create_modules() -> Vec<ModuleConfig> {
libs: vec!["cublas"],
clang_args: vec![],
raw_lines: vec![],
derive_default: true,
},
ModuleConfig {
cudarc_name: "cublaslt",
Expand All @@ -96,6 +96,7 @@ fn create_modules() -> Vec<ModuleConfig> {
libs: vec!["cublasLt"],
clang_args: vec![],
raw_lines: vec![],
derive_default: true,
},
ModuleConfig {
cudarc_name: "curand",
Expand All @@ -108,15 +109,13 @@ fn create_modules() -> Vec<ModuleConfig> {
allowlist_recursively: true,
blocklist: Filters {
types: vec![],
functions: vec![
"curandGenerateBinomial",
"curandGenerateBinomialMethod",
],
functions: vec!["curandGenerateBinomial", "curandGenerateBinomialMethod"],
vars: vec![],
},
libs: vec!["curand"],
clang_args: vec![],
raw_lines: vec![],
derive_default: true,
},
ModuleConfig {
cudarc_name: "nvrtc",
Expand All @@ -142,6 +141,7 @@ fn create_modules() -> Vec<ModuleConfig> {
libs: vec!["nvrtc"],
clang_args: vec![],
raw_lines: vec![],
derive_default: true,
},
ModuleConfig {
cudarc_name: "cudnn",
Expand All @@ -156,6 +156,7 @@ fn create_modules() -> Vec<ModuleConfig> {
libs: vec!["cudnn"],
clang_args: vec![],
raw_lines: vec![],
derive_default: true,
},
ModuleConfig {
cudarc_name: "nccl",
Expand All @@ -170,6 +171,7 @@ fn create_modules() -> Vec<ModuleConfig> {
libs: vec!["nccl"],
clang_args: vec![],
raw_lines: vec![],
derive_default: true,
},
ModuleConfig {
cudarc_name: "cusparse",
Expand Down Expand Up @@ -226,6 +228,7 @@ fn create_modules() -> Vec<ModuleConfig> {
libs: vec!["cusparse"],
clang_args: vec![],
raw_lines: vec![],
derive_default: true,
},
ModuleConfig {
cudarc_name: "cusolver",
Expand All @@ -238,15 +241,13 @@ fn create_modules() -> Vec<ModuleConfig> {
allowlist_recursively: true,
blocklist: Filters {
types: vec!["^cusolverMg.*"],
functions: vec![
"^cusolverMg.*",
"^cusolverDnLogger.*",
],
functions: vec!["^cusolverMg.*", "^cusolverDnLogger.*"],
vars: vec!["^cusolverMg.*"],
},
libs: vec!["cusolver"],
clang_args: vec![],
raw_lines: vec![],
derive_default: true,
},
ModuleConfig {
cudarc_name: "cusolvermg",
Expand All @@ -261,6 +262,7 @@ fn create_modules() -> Vec<ModuleConfig> {
libs: vec!["cusolverMg"],
clang_args: vec![],
raw_lines: vec![],
derive_default: true,
},
ModuleConfig {
cudarc_name: "cufile",
Expand All @@ -275,6 +277,7 @@ fn create_modules() -> Vec<ModuleConfig> {
libs: vec!["cufile"],
clang_args: vec![],
raw_lines: vec![],
derive_default: true,
},
ModuleConfig {
cudarc_name: "nvtx",
Expand All @@ -285,14 +288,15 @@ fn create_modules() -> Vec<ModuleConfig> {
vars: vec!["^nvtx.*"],
},
allowlist_recursively: true,
blocklist: Filters {
blocklist: Filters {
types: vec![],
functions: vec!["nvtxInitialize"],
vars: vec![],
},
libs: vec!["nvToolsExt"],
clang_args: vec!["-DNVTX_NO_IMPL=0", "-DNVTX_DECLSPEC="],
raw_lines: vec![],
derive_default: true,
},
ModuleConfig {
cudarc_name: "cupti",
Expand Down Expand Up @@ -341,10 +345,8 @@ fn create_modules() -> Vec<ModuleConfig> {
},
libs: vec!["cupti"],
clang_args: vec![],
raw_lines: vec![
"use crate::driver::sys::*;",
"use crate::runtime::sys::*;",
],
raw_lines: vec!["use crate::driver::sys::*;", "use crate::runtime::sys::*;"],
derive_default: false,
},
]
}
Expand All @@ -370,6 +372,8 @@ struct ModuleConfig {
allowlist_recursively: bool,
/// Lines of code to add at the beginning of the generated bindings.
raw_lines: Vec<&'static str>,
/// Whether to derive Default implementations for types.
derive_default: bool,
}

impl ModuleConfig {
Expand Down Expand Up @@ -399,7 +403,7 @@ impl ModuleConfig {
.default_enum_style(bindgen::EnumVariation::Rust {
non_exhaustive: false,
})
.derive_default(false)
.derive_default(self.derive_default)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

While enabling derive_default is a great improvement for ergonomics, it introduces a critical soundness issue. For the cublaslt and cusolver modules, bindgen pulls in the _IO_FILE type (also known as FILE in C) and generates a Default implementation for it.

This generated implementation zero-initializes the struct, which is unsound because a zeroed FILE struct is not guaranteed to be valid. Using a default-initialized _IO_FILE could lead to undefined behavior.

To fix this, you can instruct bindgen to not generate a Default implementation for _IO_FILE using .no_default(). I recommend making this configurable in ModuleConfig by adding a no_default_types field.

You could update ModuleConfig like this:

struct ModuleConfig {
    // ...
    /// Whether to derive Default implementations for types.
    derive_default: bool,
    /// Types to not derive `Default` for.
    no_default_types: Vec<&'static str>,
}

Then, in create_modules(), you can specify no_default_types: vec!["_IO_FILE"] for cublaslt and cusolver, and an empty vec![] for the other modules where derive_default is true.

Finally, apply this configuration in ModuleConfig::builder():

// ... in ModuleConfig::builder()
let mut builder = builder.derive_default(self.derive_default);
for ty in &self.no_default_types {
    builder = builder.no_default(*ty);
}
builder
    .derive_eq(true)
// ...

This will resolve the soundness issue while keeping the benefits of derive_default for the other types.

.derive_eq(true)
.derive_hash(true)
.derive_ord(true)
Expand Down Expand Up @@ -530,7 +534,7 @@ fn create_bindings(modules: &[ModuleConfig], cuda_versions: &[&str]) -> Result<(
} else {
vec!["cuda_nvcc"]
};

let archive_pb = multi_progress.add(ProgressBar::new(names.len() as u64));
archive_pb.set_style(
ProgressStyle::default_bar().template("{msg} {wide_bar} {pos}/{len} ({eta})")?,
Expand Down
4 changes: 2 additions & 2 deletions src/cublas/sys/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -459,14 +459,14 @@ pub struct cublasContext {
}
#[repr(C)]
#[repr(align(16))]
#[derive(Debug, Copy, Clone, PartialOrd, PartialEq)]
#[derive(Debug, Default, Copy, Clone, PartialOrd, PartialEq)]
pub struct double2 {
pub x: f64,
pub y: f64,
}
#[repr(C)]
#[repr(align(8))]
#[derive(Debug, Copy, Clone, PartialOrd, PartialEq)]
#[derive(Debug, Default, Copy, Clone, PartialOrd, PartialEq)]
pub struct float2 {
pub x: f32,
pub y: f32,
Expand Down
38 changes: 28 additions & 10 deletions src/cublaslt/sys/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2695,30 +2695,30 @@ pub struct cublasLtContext {
}
#[cfg(any(feature = "cuda-13000"))]
#[repr(C)]
#[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)]
#[derive(Debug, Default, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)]
pub struct cublasLtEmulationDescOpaque_t {
pub data: [u64; 8usize],
}
#[repr(C)]
#[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)]
#[derive(Debug, Default, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)]
pub struct cublasLtMatmulAlgo_t {
pub data: [u64; 8usize],
}
#[cfg(any(feature = "cuda-11040"))]
#[repr(C)]
#[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)]
#[derive(Debug, Default, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)]
pub struct cublasLtMatmulDescOpaque_t {
pub data: [u64; 11usize],
}
#[cfg(any(feature = "cuda-11050", feature = "cuda-11060", feature = "cuda-11070"))]
#[repr(C)]
#[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)]
#[derive(Debug, Default, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)]
pub struct cublasLtMatmulDescOpaque_t {
pub data: [u64; 12usize],
}
#[cfg(any(feature = "cuda-11080", feature = "cuda-12000", feature = "cuda-12010"))]
#[repr(C)]
#[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)]
#[derive(Debug, Default, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)]
pub struct cublasLtMatmulDescOpaque_t {
pub data: [u64; 23usize],
}
Expand All @@ -2733,7 +2733,7 @@ pub struct cublasLtMatmulDescOpaque_t {
feature = "cuda-13000"
))]
#[repr(C)]
#[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)]
#[derive(Debug, Default, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)]
pub struct cublasLtMatmulDescOpaque_t {
pub data: [u64; 32usize],
}
Expand All @@ -2754,7 +2754,7 @@ pub struct cublasLtMatmulHeuristicResult_t {
feature = "cuda-11080"
))]
#[repr(C)]
#[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)]
#[derive(Debug, Default, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)]
pub struct cublasLtMatmulPreferenceOpaque_t {
pub data: [u64; 10usize],
}
Expand All @@ -2771,24 +2771,42 @@ pub struct cublasLtMatmulPreferenceOpaque_t {
feature = "cuda-13000"
))]
#[repr(C)]
#[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)]
#[derive(Debug, Default, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)]
pub struct cublasLtMatmulPreferenceOpaque_t {
pub data: [u64; 8usize],
}
#[repr(C)]
#[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)]
#[derive(Debug, Default, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)]
pub struct cublasLtMatrixLayoutOpaque_t {
pub data: [u64; 8usize],
}
#[repr(C)]
#[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)]
#[derive(Debug, Default, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)]
pub struct cublasLtMatrixTransformDescOpaque_t {
pub data: [u64; 8usize],
}
#[cfg(any(feature = "cuda-12080", feature = "cuda-12090", feature = "cuda-13000"))]
impl cudaDataType_t {
pub const CUDA_R_8F_UE4M3: cudaDataType_t = cudaDataType_t::CUDA_R_8F_E4M3;
}
impl Default for _IO_FILE {
fn default() -> Self {
let mut s = ::core::mem::MaybeUninit::<Self>::uninit();
unsafe {
::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
s.assume_init()
}
}
}
impl Default for cublasLtMatmulHeuristicResult_t {
fn default() -> Self {
let mut s = ::core::mem::MaybeUninit::<Self>::uninit();
unsafe {
::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
s.assume_init()
}
}
}
#[cfg(not(feature = "dynamic-loading"))]
extern "C" {
pub fn cublasLtCreate(lightHandle: *mut cublasLtHandle_t) -> cublasStatus_t;
Expand Down
38 changes: 37 additions & 1 deletion src/cudnn/sys/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1490,7 +1490,7 @@ pub struct cudnnFilterStruct {
_unused: [u8; 0],
}
#[repr(C)]
#[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)]
#[derive(Debug, Default, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)]
pub struct cudnnFractionStruct {
pub numerator: i64,
pub denominator: i64,
Expand Down Expand Up @@ -1589,6 +1589,42 @@ impl cudnnStatus_t {
pub const CUDNN_STATUS_VERSION_MISMATCH: cudnnStatus_t =
cudnnStatus_t::CUDNN_STATUS_SUBLIBRARY_VERSION_MISMATCH;
}
impl Default for cudnnConvolutionBwdDataAlgoPerfStruct {
fn default() -> Self {
let mut s = ::core::mem::MaybeUninit::<Self>::uninit();
unsafe {
::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
s.assume_init()
}
}
}
impl Default for cudnnConvolutionBwdFilterAlgoPerfStruct {
fn default() -> Self {
let mut s = ::core::mem::MaybeUninit::<Self>::uninit();
unsafe {
::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
s.assume_init()
}
}
}
impl Default for cudnnConvolutionFwdAlgoPerfStruct {
fn default() -> Self {
let mut s = ::core::mem::MaybeUninit::<Self>::uninit();
unsafe {
::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
s.assume_init()
}
}
}
impl Default for cudnnDebugStruct {
fn default() -> Self {
let mut s = ::core::mem::MaybeUninit::<Self>::uninit();
unsafe {
::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
s.assume_init()
}
}
}
#[cfg(not(feature = "dynamic-loading"))]
extern "C" {
pub fn cudnnActivationBackward(
Expand Down
Loading
Loading