Skip to content

Commit aa3dfd7

Browse files
committed
wasm-simd-parity: pin ZGamma codes digest under node
CI's wasm job never runs cargo test, so the zspace golden digest was not enforced on wasm32. selfcheck() now rebuilds the same 8539-value grid, encodes it and compares against GOLDEN_CODES (rc 0x501), plus batch == scalar per element (0x502). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019HnekoM1EidTwQLS3oFVFm
1 parent f2a461a commit aa3dfd7

1 file changed

Lines changed: 38 additions & 0 deletions

File tree

  • crates/wasm-simd-parity/src

‎crates/wasm-simd-parity/src/lib.rs‎

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ pub extern "C" fn selfcheck() -> u32 {
3535
if let Err(code) = check_i32x16_compare() {
3636
return code;
3737
}
38+
if let Err(code) = check_zgamma_golden() {
39+
return code;
40+
}
3841
0
3942
}
4043

@@ -424,3 +427,38 @@ fn check_i32x16_compare() -> Result<(), u32> {
424427
}
425428
Ok(())
426429
}
430+
431+
/// `ZGamma` codes are bit-exact on every target: the same grid and pinned
432+
/// digest as `ndarray::hpc::zspace::golden::GOLDEN_CODES` (keep in sync).
433+
/// Before the deterministic `ln`, 624 of these 8 539 z values differed between
434+
/// x86-64 glibc and wasm32, so this is the target where drift would show.
435+
fn check_zgamma_golden() -> Result<(), u32> {
436+
use ndarray::hpc::zspace::ZGamma;
437+
const GOLDEN_CODES: u64 = 0xfb0b_294d_2a65_3dbb;
438+
let mut grid: Vec<f32> = (-4096..=4096).map(|i| i as f32 / 4096.0).collect();
439+
let mut r = 0.999f32;
440+
while r < 1.0 {
441+
grid.push(r);
442+
grid.push(-r);
443+
r = f32::from_bits(r.to_bits() + 97);
444+
}
445+
if grid.len() != 8539 {
446+
return Err(0x500);
447+
}
448+
let env = ZGamma::fit(&grid);
449+
let mut codes = vec![0i8; grid.len()];
450+
env.encode_batch(&grid, &mut codes);
451+
let mut h = 0xcbf2_9ce4_8422_2325u64;
452+
for &c in &codes {
453+
h = (h ^ u64::from(c as u8)).wrapping_mul(0x0100_0000_01b3);
454+
}
455+
if h != GOLDEN_CODES {
456+
return Err(0x501);
457+
}
458+
for (&c, &k) in grid.iter().zip(&codes) {
459+
if env.encode(c) != k {
460+
return Err(0x502);
461+
}
462+
}
463+
Ok(())
464+
}

0 commit comments

Comments
 (0)