1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
//! [`ValidAsZeroBits`] — safety marker for zero-initializable types.
use crate::;
/// Marker trait for types whose all-zero bit pattern is a valid value.
///
/// Crates that allocate GPU memory often use `cudaMemset(0)` / `cuMemsetD8`
/// to initialize buffers to zero and then treat the allocation as a
/// populated `[T]`. That's only sound for types where all-zero bytes are a
/// valid `T` — e.g. integer primitives and IEEE-754 floating-point types
/// (where `0x00000000` is the representation of `+0.0`).
///
/// Implementing `ValidAsZeroBits` is a promise that:
///
/// 1. Reading a zero-initialized `T` is not undefined behavior.
/// 2. The zero-initialized value is semantically sensible (`0` / `0.0` /
/// `(0, 0, ..., 0)` — *not* a niche-optimized enum where zero means
/// something else).
///
/// # Safety
///
/// This trait is `unsafe` to implement: a wrong impl will lead to UB the
/// first time downstream code zero-initializes a buffer and reads it back.
/// Common counter-examples include:
///
/// - `&T`, `&mut T` (null references are UB).
/// - `NonZero*` from `std::num`.
/// - Enums with a non-zero discriminant for their zero-value variant.
/// - `Box<T>`, `Arc<T>`, `String`, `Vec<T>` (heap-owned data).
///
/// # Supplied impls
///
/// - Every unsigned integer (`u8`..`u128`, `usize`).
/// - Every signed integer (`i8`..`i128`, `isize`).
/// - `f32`, `f64` (zero = `+0.0`).
/// - [`Half`], [`BFloat16`], [`Complex32`], [`Complex64`].
/// - `()` — the unit type.
/// - `bool` — zero = `false`.
/// - Tuples of arity 1–12 where every element is `ValidAsZeroBits`.
/// - Fixed-size arrays `[T; N]` where `T: ValidAsZeroBits`.
///
/// # Example
///
/// ```
/// use baracuda_types::ValidAsZeroBits;
///
/// fn zeroed_vec<T: ValidAsZeroBits>(n: usize) -> Vec<T> {
/// // Safe because T: ValidAsZeroBits guarantees all-zero bytes are a valid T.
/// let mut v = Vec::with_capacity(n);
/// unsafe {
/// core::ptr::write_bytes(v.as_mut_ptr(), 0, n);
/// v.set_len(n);
/// }
/// v
/// }
///
/// let xs: Vec<f32> = zeroed_vec(4);
/// assert_eq!(xs, [0.0, 0.0, 0.0, 0.0]);
/// ```
pub unsafe
// ---- Primitives ---------------------------------------------------------
impl_zero_bits!;
// ---- Fixed-size arrays --------------------------------------------------
unsafe
// ---- Tuples -------------------------------------------------------------
//
// Up to arity 12, matching the `DeviceRepr` / `KernelArg` coverage.
impl_zero_bits_tuple!;
impl_zero_bits_tuple!;
impl_zero_bits_tuple!;
impl_zero_bits_tuple!;
impl_zero_bits_tuple!;
impl_zero_bits_tuple!;
impl_zero_bits_tuple!;
impl_zero_bits_tuple!;
impl_zero_bits_tuple!;
impl_zero_bits_tuple!;
impl_zero_bits_tuple!;
impl_zero_bits_tuple!;