Skip to content

Enforce bit-for-bit symmetry in gen_spd matrix generation - #33

Merged
ivan-pi merged 2 commits into
mainfrom
claude/potrf-icelake-icpx-failure-07iv79
Aug 7, 2026
Merged

Enforce bit-for-bit symmetry in gen_spd matrix generation#33
ivan-pi merged 2 commits into
mainfrom
claude/potrf-icelake-icpx-failure-07iv79

Conversation

@ivan-pi

@ivan-pi ivan-pi commented Aug 6, 2026

Copy link
Copy Markdown
Owner

Summary

This change ensures that the symmetric positive-definite (SPD) matrix generated by gen_spd() is exactly symmetric bit-for-bit by explicitly mirroring the lower triangle onto the upper triangle after the congruence transformation.

Key Changes

  • Added comprehensive documentation explaining why bit-for-bit symmetry is necessary for correctness of downstream tests
  • Implemented explicit mirroring of the lower triangle to the upper triangle in the column-major matrix representation
  • This enforces exact symmetry regardless of compiler floating-point model settings (e.g., Intel icpx's -fp-model=fast)

Implementation Details

The change addresses a subtle but critical issue: while A = M^T M is mathematically symmetric, the computed dot products for A(i,j) and A(j,i) may differ by one ULP depending on the floating-point model used. Some compilers with aggressive FP optimizations can produce asymmetric results.

The fix mirrors the lower triangle onto the upper triangle after the congruence scaling (D A D), which preserves the symmetry properties while enforcing exact bit-for-bit equality. This is essential for row-major unpacking tests that read the transpose partner and compare A(j,i) against A(i,j) — even sub-ULP asymmetries would otherwise be misinterpreted as kernel errors.

https://claude.ai/code/session_01K4dGBpSViJAgHSxYxzin9L

…under icpx

mkl_potrf_suites failed on Icelake with icpx (default -fp-model=fast) for the
row-major cases at n=30 and n=43:

  row uplo=L V=8 nm=8  n=30 | ... untouched 1e-15 FAIL
  row uplo=U V=8 nm=11 n=43 | ... untouched 2e-15 FAIL

This is not a factorization or tolerance problem: the reconstruction residual,
the elementwise-vs-LAPACK factor and every column-major case pass with wide
margin. The input is at fault. A = M^T M is symmetric in exact arithmetic, but
under a value-unsafe FP model the dot products for A(i,j) and A(j,i) can round a
ULP apart. suite1's row-major "opposite triangle untouched" gate unpacks the
factor row-major, which reads the transpose partner, so it effectively compares
A(j,i) against A(i,j); a sub-ULP asymmetry there masquerades as the kernel
having written the wrong triangle. gcc and clang keep the product bit-symmetric,
so it only surfaced on icpx.

Mirror the lower triangle onto the upper at the end of gen_spd so A(j,i) equals
A(i,j) bit-for-bit on every compiler and FP model. The cond>0 congruence scales
A(i,j) and A(j,i) by the same si*sj, so mirroring last preserves it.

Verified with icpx 2025.2 -O3 -xHOST: gen_spd asymmetry drops from 1.3e-15
(n=30) / 1.8e-15 (n=43) to 0, a faithful MKL-free model of the suite1
pack/factor/unpack path goes from the reported 4 failures to all checks passing,
and portable_potrf still passes under gcc, icpx, and icpx -xHOST.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K4dGBpSViJAgHSxYxzin9L
Comment-only: same explanation, clearer phrasing. No behavior change.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K4dGBpSViJAgHSxYxzin9L
@ivan-pi
ivan-pi merged commit e4bbcc9 into main Aug 7, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants