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}