Skip to main content

oxicuda_driver/
ffi_launch.rs

1//! Extended launch configuration types for `cuLaunchKernelEx` (CUDA 12.0+).
2//!
3//! Thread block cluster launch attributes, launch configuration, and related
4//! types for the modern CUDA 12.x kernel launch API.
5
6use super::CUstream;
7
8// =========================================================================
9// CuLaunchAttributeId — attribute discriminant
10// =========================================================================
11
12/// Attribute identifier for `CuLaunchAttribute`.
13///
14/// Controls which extended kernel launch feature is configured.
15/// Used with `cuLaunchKernelEx` (CUDA 12.0+).
16#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
17#[repr(u32)]
18pub enum CuLaunchAttributeId {
19    /// No attribute (`CU_LAUNCH_ATTRIBUTE_IGNORE`).
20    Ignore = 0,
21    /// Access-policy window for persisting L2 cache
22    /// (`CU_LAUNCH_ATTRIBUTE_ACCESS_POLICY_WINDOW`).
23    AccessPolicyWindow = 1,
24    /// Cooperative kernel launch (`CU_LAUNCH_ATTRIBUTE_COOPERATIVE`).
25    Cooperative = 2,
26    /// Stream synchronization policy
27    /// (`CU_LAUNCH_ATTRIBUTE_SYNCHRONIZATION_POLICY`).
28    SynchronizationPolicy = 3,
29    /// Specifies thread block cluster dimensions (sm_90+).
30    ClusterDimension = 4,
31    /// Controls cluster scheduling policy preference.
32    ClusterSchedulingPolicyPreference = 5,
33    /// Enables programmatic stream serialization.
34    ProgrammaticStreamSerialization = 6,
35    /// Specifies a programmatic completion event.
36    ProgrammaticEvent = 7,
37    /// Specifies kernel launch priority.
38    Priority = 8,
39    /// Maps memory synchronization domains.
40    MemSyncDomainMap = 9,
41    /// Sets memory synchronization domain.
42    MemSyncDomain = 10,
43    /// Specifies a launch completion event.
44    LaunchCompletionEvent = 12,
45    /// Configures device-updatable kernel node.
46    DeviceUpdatableKernelNode = 13,
47}
48
49// =========================================================================
50// CuLaunchAttributeClusterDim — cluster geometry
51// =========================================================================
52
53/// Cluster dimension for thread block clusters (sm_90+).
54///
55/// Specifies how many thread blocks form one cluster in each dimension.
56/// Used inside [`CuLaunchAttributeValue`] when the attribute id is
57/// [`CuLaunchAttributeId::ClusterDimension`].
58#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
59#[repr(C)]
60pub struct CuLaunchAttributeClusterDim {
61    /// Cluster extent in X dimension.
62    pub x: u32,
63    /// Cluster extent in Y dimension.
64    pub y: u32,
65    /// Cluster extent in Z dimension.
66    pub z: u32,
67}
68
69// =========================================================================
70// CuLaunchAttributeValue — attribute value union
71// =========================================================================
72
73/// Value union for `CuLaunchAttribute`.
74///
75/// # Safety
76///
77/// This is a C union — callers must only read the field that matches
78/// the accompanying [`CuLaunchAttributeId`] discriminant.
79/// Padding ensures the union is always 64 bytes, matching the CUDA ABI.
80#[repr(C)]
81pub union CuLaunchAttributeValue {
82    /// Cluster dimension configuration (when id == `ClusterDimension`).
83    pub cluster_dim: CuLaunchAttributeClusterDim,
84    /// Scalar u32 value (for single-word attributes).
85    pub value_u32: u32,
86    /// Raw padding to maintain 64-byte ABI alignment.
87    pub pad: [u8; 64],
88}
89
90// Manual Clone/Copy for the union (derive cannot handle unions with non-Copy
91// fields, but all union fields here are effectively POD).
92// `Copy` is declared first so that the `Clone` impl can delegate to it.
93impl Copy for CuLaunchAttributeValue {}
94
95impl Clone for CuLaunchAttributeValue {
96    fn clone(&self) -> Self {
97        // Delegate to Copy — canonical approach for Copy types.
98        *self
99    }
100}
101
102// =========================================================================
103// CuLaunchAttribute — single attribute entry
104// =========================================================================
105
106/// A single extended kernel launch attribute (id + value pair).
107///
108/// Used in the `attrs` array of [`CuLaunchConfig`].
109#[repr(C)]
110#[derive(Clone, Copy)]
111pub struct CuLaunchAttribute {
112    /// Which feature this attribute configures.
113    pub id: CuLaunchAttributeId,
114    /// Alignment padding (must be zero).
115    pub pad: [u8; 4],
116    /// The attribute value — interpret according to `id`.
117    pub value: CuLaunchAttributeValue,
118}
119
120// =========================================================================
121// CuLaunchConfig — full launch configuration
122// =========================================================================
123
124/// Extended kernel launch configuration for `cuLaunchKernelEx` (CUDA 12.0+).
125///
126/// Supersedes the individual parameters of `cuLaunchKernel` and adds
127/// support for thread block clusters, launch priorities, and other
128/// CUDA 12.x features.
129///
130/// # Example
131///
132/// ```rust
133/// use oxicuda_driver::ffi::{
134///     CuLaunchConfig, CuLaunchAttribute, CuLaunchAttributeId,
135///     CuLaunchAttributeValue, CuLaunchAttributeClusterDim, CUstream,
136/// };
137///
138/// // Build a cluster-launch config for a 2×1×1 cluster.
139/// let cluster_attr = CuLaunchAttribute {
140///     id: CuLaunchAttributeId::ClusterDimension,
141///     pad: [0u8; 4],
142///     value: CuLaunchAttributeValue {
143///         cluster_dim: CuLaunchAttributeClusterDim { x: 2, y: 1, z: 1 },
144///     },
145/// };
146/// let _config = CuLaunchConfig {
147///     grid_dim_x: 8,
148///     grid_dim_y: 1,
149///     grid_dim_z: 1,
150///     block_dim_x: 256,
151///     block_dim_y: 1,
152///     block_dim_z: 1,
153///     shared_mem_bytes: 0,
154///     stream: CUstream::default(),
155///     attrs: std::ptr::null(),
156///     num_attrs: 0,
157/// };
158/// ```
159#[repr(C)]
160pub struct CuLaunchConfig {
161    /// Grid dimension in X.
162    pub grid_dim_x: u32,
163    /// Grid dimension in Y.
164    pub grid_dim_y: u32,
165    /// Grid dimension in Z.
166    pub grid_dim_z: u32,
167    /// Block dimension in X (threads per block in X).
168    pub block_dim_x: u32,
169    /// Block dimension in Y.
170    pub block_dim_y: u32,
171    /// Block dimension in Z.
172    pub block_dim_z: u32,
173    /// Dynamic shared memory per block in bytes.
174    pub shared_mem_bytes: u32,
175    /// Stream to submit the kernel on.
176    pub stream: CUstream,
177    /// Pointer to an array of `num_attrs` attributes (may be null if zero).
178    pub attrs: *const CuLaunchAttribute,
179    /// Number of entries in `attrs`.
180    pub num_attrs: u32,
181}
182
183// SAFETY: CuLaunchConfig is a plain data structure mirroring the CUDA ABI.
184// The raw pointer `attrs` must be valid for the lifetime of the config, but
185// the struct itself is Send + Sync because no interior mutation occurs.
186unsafe impl Send for CuLaunchConfig {}
187unsafe impl Sync for CuLaunchConfig {}
188
189#[cfg(test)]
190mod tests {
191    use super::CuLaunchAttributeId;
192
193    /// Discriminants must match `CUlaunchAttributeID_enum` from `cuda.h`
194    /// exactly, otherwise `cuLaunchKernelEx` silently misconfigures kernels.
195    #[test]
196    fn launch_attribute_id_matches_header() {
197        assert_eq!(CuLaunchAttributeId::Ignore as u32, 0);
198        assert_eq!(CuLaunchAttributeId::AccessPolicyWindow as u32, 1);
199        assert_eq!(CuLaunchAttributeId::Cooperative as u32, 2);
200        assert_eq!(CuLaunchAttributeId::SynchronizationPolicy as u32, 3);
201        assert_eq!(CuLaunchAttributeId::ClusterDimension as u32, 4);
202        assert_eq!(
203            CuLaunchAttributeId::ClusterSchedulingPolicyPreference as u32,
204            5
205        );
206        assert_eq!(
207            CuLaunchAttributeId::ProgrammaticStreamSerialization as u32,
208            6
209        );
210        assert_eq!(CuLaunchAttributeId::ProgrammaticEvent as u32, 7);
211        assert_eq!(CuLaunchAttributeId::Priority as u32, 8);
212        assert_eq!(CuLaunchAttributeId::MemSyncDomainMap as u32, 9);
213        assert_eq!(CuLaunchAttributeId::MemSyncDomain as u32, 10);
214        assert_eq!(CuLaunchAttributeId::LaunchCompletionEvent as u32, 12);
215        assert_eq!(CuLaunchAttributeId::DeviceUpdatableKernelNode as u32, 13);
216    }
217}