use baracuda_cuda_sys::types::{
CUaccessPolicyWindow, CUlaunchAttribute, CUlaunchAttributeID, CUlaunchAttributeValue,
};
use baracuda_cuda_sys::CUevent;
pub use baracuda_cuda_sys::types::CUaccessPolicyWindow as AccessPolicyWindow;
#[derive(Copy, Clone)]
#[repr(transparent)]
pub struct LaunchAttr(CUlaunchAttribute);
impl core::fmt::Debug for LaunchAttr {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("LaunchAttr")
.field("id", &self.0.id)
.finish_non_exhaustive()
}
}
impl LaunchAttr {
#[inline]
pub fn into_raw(self) -> CUlaunchAttribute {
self.0
}
#[inline]
pub fn as_raw(&self) -> &CUlaunchAttribute {
&self.0
}
fn empty(id: u32) -> Self {
Self(CUlaunchAttribute {
id,
pad: [0; 4],
value: CUlaunchAttributeValue([0u8; 64]),
})
}
#[inline]
fn with_value<T: Copy>(mut self, value: T) -> Self {
assert!(
core::mem::size_of::<T>() <= 64,
"launch attribute payload too large ({} > 64)",
core::mem::size_of::<T>()
);
unsafe {
let p = self.0.value.0.as_mut_ptr() as *mut T;
p.write_unaligned(value);
}
self
}
pub fn cluster_dim(x: u32, y: u32, z: u32) -> Self {
#[repr(C)]
#[derive(Copy, Clone)]
struct ClusterDim {
x: u32,
y: u32,
z: u32,
}
Self::empty(CUlaunchAttributeID::CLUSTER_DIMENSION).with_value(ClusterDim { x, y, z })
}
pub fn priority(priority: i32) -> Self {
Self::empty(CUlaunchAttributeID::PRIORITY).with_value(priority)
}
pub fn cooperative() -> Self {
Self::empty(CUlaunchAttributeID::COOPERATIVE).with_value(1i32)
}
pub fn programmatic_stream_serialization(enabled: bool) -> Self {
Self::empty(CUlaunchAttributeID::PROGRAMMATIC_STREAM_SERIALIZATION).with_value(if enabled {
1i32
} else {
0i32
})
}
pub fn cluster_scheduling_policy(policy: i32) -> Self {
Self::empty(CUlaunchAttributeID::CLUSTER_SCHEDULING_POLICY_PREFERENCE).with_value(policy)
}
pub fn synchronization_policy(policy: i32) -> Self {
Self::empty(CUlaunchAttributeID::SYNCHRONIZATION_POLICY).with_value(policy)
}
pub fn access_policy_window(window: CUaccessPolicyWindow) -> Self {
Self::empty(CUlaunchAttributeID::ACCESS_POLICY_WINDOW).with_value(window)
}
pub fn programmatic_event(event: CUevent, flags: i32, trigger_at_block_start: bool) -> Self {
#[repr(C)]
#[derive(Copy, Clone)]
struct ProgEvent {
event: CUevent,
flags: i32,
trigger_at_block_start: i32,
}
Self::empty(CUlaunchAttributeID::PROGRAMMATIC_EVENT).with_value(ProgEvent {
event,
flags,
trigger_at_block_start: if trigger_at_block_start { 1 } else { 0 },
})
}
pub fn launch_completion_event(event: CUevent, flags: i32) -> Self {
#[repr(C)]
#[derive(Copy, Clone)]
struct LaunchEvent {
event: CUevent,
flags: i32,
}
Self::empty(CUlaunchAttributeID::LAUNCH_COMPLETION_EVENT)
.with_value(LaunchEvent { event, flags })
}
pub unsafe fn raw<T: Copy>(id: u32, payload: T) -> Self {
Self::empty(id).with_value(payload)
}
}
pub fn into_raw_vec(attrs: &[LaunchAttr]) -> Vec<CUlaunchAttribute> {
attrs.iter().map(|a| a.into_raw()).collect()
}