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
//! `SpmdValue` / `SpmdGather`: the foundation for `#[derive(SpmdValue)]`
//! varying structs. A scalar "value type" `S` (a `#[repr(C)]` struct
//! of numeric fields, or a primitive numeric leaf) has an associated SoA
//! varying representation `<S as SpmdValue>::Varying<N>` — for a struct this is
//! the derive-generated `VaryingS<N>` with field-wise varying fields; for a
//! primitive it is `Varying<S, N>`.
//!
//! The derive emits, per struct `S`:
//! - the `VaryingS<N>` SoA struct (each field recurses through `SpmdValue`; a
//! `#[spmd(uniform)]` field stays scalar);
//! - `impl SpmdValue for S` — the `Varying<N>` association and `splat`
//! (splat-from-uniform-`S`), available for every value struct;
//! - `impl SpmdGather for S` and an inherent `select`, ONLY when the struct has
//! no `#[spmd(uniform)]` field (an "all-varying" struct). Gathering or
//! blending a uniform field is ill-defined, so a struct with a uniform field
//! simply lacks these — a compile error at the use site;
//! - `MaskedAssign` for `VaryingS<N>`: all four exec contexts for an
//! all-varying struct; only `AllOn`/`BoolGuard` when a uniform field is
//! present, so a whole-struct assignment under a varying mask is a
//! missing-impl compile error (same rule as a uniform local).
//!
//! The AoS gather ([`SpmdGather::gather_fields`]) is built on
//! [`crate::memory::gather_field`]: indexing `&[S]` with a `Varying<i32, N>`
//! gathers each leaf primitive field with one strided gather (ISPC's AoS
//! behaviour), composing byte offsets through nested `SpmdValue` fields. A
//! downstream `SpmdRead<Varying<i32, N>, E> for [S]` impl is impossible (orphan
//! rule: `[S]` is not a local type) and a blanket one here collides with the
//! primitive gather impl in `memory.rs`; so the derive exposes the gather as an
//! inherent `VaryingS::<N>::gather(base, idx, exec)` rather than the `a[i]`
//! sugar.
use crate;
use crateVarying;
/// A scalar value type with an SoA varying representation. Implemented for the
/// primitive numeric leaves below and, via `#[derive(SpmdValue)]`, for every
/// `#[repr(C)]` struct of `SpmdValue` fields (including ones with
/// `#[spmd(uniform)]` fields).
/// A value type whose AoS layout can be gathered field-by-field. Implemented
/// for the primitive leaves and for `#[derive(SpmdValue)]` structs with NO
/// `#[spmd(uniform)]` field (a uniform field has no per-lane value to gather).