Commit 5ee172a
committed
feat(pr-x2): soa_struct! gains #[soa(pad_to_lanes = N)] attribute
Worker B of PR-X2 per .claude/knowledge/pr-x2-design.md § "Worker
decomposition" line 459. SIMD-staged kernels need each SoA field's
underlying Vec to be a multiple of the lane width N so the consumer
walks the buffer with one uniform N-lane loop — no scalar tail-case
branch. Pre-PR-X2 callers achieved this by hand (W3-W6
GaussianBatch::with_capacity + eager-zero fill); this PR makes it
declarative on the field.
Macro surface:
soa_struct! {
pub struct Cells {
#[soa(pad_to_lanes = 8)]
pub palette: u8,
pub label: u32, // unpadded
}
}
let mut c = Cells::new();
c.push(7, 100);
assert_eq!(c.len(), 1); // logical row count
assert_eq!(c.palette.len(), 8); // physical, rounded to lane 8
assert_eq!(c.label.len(), 1); // unpadded: physical == logical
Implementation:
- Added optional `$(#[soa(pad_to_lanes = $pad:literal)])?` per field
in the macro_rules! head — Rust 1.32+ optional-meta repetition.
- Generated struct grows a private `_logical_len: usize` so `len()` /
`is_empty()` return the **semantic** row count independent of any
field's lane padding.
- `push()` dispatches per-field through internal `@push_field` arms:
• padded arm grows the Vec to `(logical+1).div_ceil(N)*N` filling
with `<$ty as Default>::default()`, then writes the new value
at `[logical]`
• plain arm is the pre-PR-X2 `Vec::push` call
The dispatch uses macro_rules! tt-munching with literal-token
separators (`pad = $pad`) so a single repetition handles both shapes.
- Compile-time guard: `const { assert!($pad > 0) }` inside the padded
arm — `pad_to_lanes = 0` is rejected at expansion, not at runtime.
- `with_capacity(cap)` reserves `cap` on each field but does NOT
pre-pad; padding happens lazily on push (matches the original
`with_capacity` semantics modulo the lane-tail).
- `clear()` resets _logical_len + .clear() on each field. Re-pushing
rebuilds padding from scratch.
Breaking change: `len()` no longer mirrors `self.<field>.len()` after
direct field mutation (e.g. `s.x.push(...)` bypasses `_logical_len`).
The canonical entry point is the macro-generated `push`. Pre-existing
`macro_public_visibility_passthrough` test updated to use `push`.
New tests (`src/hpc/soa.rs`, 5 added):
- pad_to_lanes_single_push_grows_to_lane — mixed cadence 8+16+none
- pad_to_lanes_crosses_lane_boundary — 9 pushes against lane 8
- pad_to_lanes_clear_resets_both — clear() round-trips
- pad_to_lanes_uniform_cadence — all-padded variant
- pad_to_lanes_with_capacity_empty — empty state invariants
Plus a `# Example — #[soa(pad_to_lanes = N)] field attribute` doctest
on the `soa_struct!` macro itself.
Verified:
cargo test -p ndarray --lib hpc::soa 38 passed
cargo test --doc -p ndarray hpc::soa 14 passed
cargo fmt --check clean
cargo clippy --features approx,serde,rayon -- -D warnings clean1 parent fb95cb3 commit 5ee172a
1 file changed
Lines changed: 231 additions & 19 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
323 | 323 | | |
324 | 324 | | |
325 | 325 | | |
| 326 | + | |
| 327 | + | |
| 328 | + | |
| 329 | + | |
| 330 | + | |
| 331 | + | |
| 332 | + | |
| 333 | + | |
| 334 | + | |
| 335 | + | |
| 336 | + | |
| 337 | + | |
| 338 | + | |
| 339 | + | |
| 340 | + | |
| 341 | + | |
| 342 | + | |
| 343 | + | |
| 344 | + | |
| 345 | + | |
| 346 | + | |
| 347 | + | |
| 348 | + | |
| 349 | + | |
| 350 | + | |
| 351 | + | |
| 352 | + | |
| 353 | + | |
| 354 | + | |
| 355 | + | |
| 356 | + | |
326 | 357 | | |
327 | 358 | | |
328 | 359 | | |
329 | 360 | | |
330 | 361 | | |
331 | | - | |
| 362 | + | |
| 363 | + | |
| 364 | + | |
| 365 | + | |
332 | 366 | | |
333 | 367 | | |
334 | 368 | | |
335 | 369 | | |
336 | | - | |
| 370 | + | |
| 371 | + | |
| 372 | + | |
| 373 | + | |
| 374 | + | |
| 375 | + | |
337 | 376 | | |
338 | 377 | | |
339 | 378 | | |
340 | 379 | | |
341 | 380 | | |
342 | | - | |
| 381 | + | |
| 382 | + | |
| 383 | + | |
| 384 | + | |
343 | 385 | | |
344 | 386 | | |
345 | 387 | | |
| 388 | + | |
| 389 | + | |
| 390 | + | |
| 391 | + | |
| 392 | + | |
346 | 393 | | |
347 | | - | |
| 394 | + | |
| 395 | + | |
| 396 | + | |
| 397 | + | |
348 | 398 | | |
349 | 399 | | |
350 | 400 | | |
| 401 | + | |
| 402 | + | |
| 403 | + | |
| 404 | + | |
| 405 | + | |
| 406 | + | |
351 | 407 | | |
352 | 408 | | |
353 | | - | |
| 409 | + | |
| 410 | + | |
| 411 | + | |
| 412 | + | |
| 413 | + | |
| 414 | + | |
| 415 | + | |
| 416 | + | |
354 | 417 | | |
355 | 418 | | |
356 | | - | |
| 419 | + | |
| 420 | + | |
| 421 | + | |
| 422 | + | |
| 423 | + | |
357 | 424 | | |
358 | | - | |
359 | | - | |
360 | | - | |
361 | | - | |
362 | | - | |
363 | | - | |
| 425 | + | |
364 | 426 | | |
365 | 427 | | |
366 | | - | |
367 | | - | |
| 428 | + | |
| 429 | + | |
368 | 430 | | |
369 | | - | |
| 431 | + | |
| 432 | + | |
| 433 | + | |
| 434 | + | |
| 435 | + | |
370 | 436 | | |
371 | 437 | | |
| 438 | + | |
372 | 439 | | |
373 | 440 | | |
374 | 441 | | |
375 | 442 | | |
376 | 443 | | |
377 | 444 | | |
378 | 445 | | |
| 446 | + | |
| 447 | + | |
| 448 | + | |
| 449 | + | |
| 450 | + | |
| 451 | + | |
| 452 | + | |
| 453 | + | |
| 454 | + | |
| 455 | + | |
| 456 | + | |
| 457 | + | |
| 458 | + | |
| 459 | + | |
| 460 | + | |
| 461 | + | |
| 462 | + | |
| 463 | + | |
| 464 | + | |
379 | 465 | | |
380 | 466 | | |
381 | 467 | | |
| |||
791 | 877 | | |
792 | 878 | | |
793 | 879 | | |
794 | | - | |
| 880 | + | |
| 881 | + | |
| 882 | + | |
795 | 883 | | |
796 | | - | |
797 | | - | |
798 | | - | |
| 884 | + | |
799 | 885 | | |
| 886 | + | |
| 887 | + | |
| 888 | + | |
| 889 | + | |
800 | 890 | | |
801 | 891 | | |
802 | 892 | | |
| |||
994 | 1084 | | |
995 | 1085 | | |
996 | 1086 | | |
| 1087 | + | |
| 1088 | + | |
| 1089 | + | |
| 1090 | + | |
| 1091 | + | |
| 1092 | + | |
| 1093 | + | |
| 1094 | + | |
| 1095 | + | |
| 1096 | + | |
| 1097 | + | |
| 1098 | + | |
| 1099 | + | |
| 1100 | + | |
| 1101 | + | |
| 1102 | + | |
| 1103 | + | |
| 1104 | + | |
| 1105 | + | |
| 1106 | + | |
| 1107 | + | |
| 1108 | + | |
| 1109 | + | |
| 1110 | + | |
| 1111 | + | |
| 1112 | + | |
| 1113 | + | |
| 1114 | + | |
| 1115 | + | |
| 1116 | + | |
| 1117 | + | |
| 1118 | + | |
| 1119 | + | |
| 1120 | + | |
| 1121 | + | |
| 1122 | + | |
| 1123 | + | |
| 1124 | + | |
| 1125 | + | |
| 1126 | + | |
| 1127 | + | |
| 1128 | + | |
| 1129 | + | |
| 1130 | + | |
| 1131 | + | |
| 1132 | + | |
| 1133 | + | |
| 1134 | + | |
| 1135 | + | |
| 1136 | + | |
| 1137 | + | |
| 1138 | + | |
| 1139 | + | |
| 1140 | + | |
| 1141 | + | |
| 1142 | + | |
| 1143 | + | |
| 1144 | + | |
| 1145 | + | |
| 1146 | + | |
| 1147 | + | |
| 1148 | + | |
| 1149 | + | |
| 1150 | + | |
| 1151 | + | |
| 1152 | + | |
| 1153 | + | |
| 1154 | + | |
| 1155 | + | |
| 1156 | + | |
| 1157 | + | |
| 1158 | + | |
| 1159 | + | |
| 1160 | + | |
| 1161 | + | |
| 1162 | + | |
| 1163 | + | |
| 1164 | + | |
| 1165 | + | |
| 1166 | + | |
| 1167 | + | |
| 1168 | + | |
| 1169 | + | |
| 1170 | + | |
| 1171 | + | |
| 1172 | + | |
| 1173 | + | |
| 1174 | + | |
| 1175 | + | |
| 1176 | + | |
| 1177 | + | |
| 1178 | + | |
| 1179 | + | |
| 1180 | + | |
| 1181 | + | |
| 1182 | + | |
| 1183 | + | |
| 1184 | + | |
| 1185 | + | |
| 1186 | + | |
| 1187 | + | |
| 1188 | + | |
| 1189 | + | |
| 1190 | + | |
| 1191 | + | |
| 1192 | + | |
| 1193 | + | |
| 1194 | + | |
| 1195 | + | |
| 1196 | + | |
| 1197 | + | |
| 1198 | + | |
| 1199 | + | |
| 1200 | + | |
| 1201 | + | |
| 1202 | + | |
| 1203 | + | |
| 1204 | + | |
| 1205 | + | |
| 1206 | + | |
| 1207 | + | |
| 1208 | + | |
997 | 1209 | | |
998 | 1210 | | |
999 | 1211 | | |
| |||
0 commit comments