Skip to content

ADR-0985: SYCL parity divergence investigation — float_ssim + ssimulacra2 on Arc A380

  • Status: Accepted
  • Date: 2026-06-03 (updated 2026-09-05)
  • Deciders: Lusoris
  • Tags: sycl, parity, ci, gpu, precision, arc

Context

The cross-backend parity matrix run on Intel Arc A380 (Research-0730, 2026-05-27) recorded three FAIL rows in the SYCL matrix:

Feature Max abs diff Tolerance Status
float_ssim 2.68e-04 5.0e-05 FAIL
ssimulacra2 8.72e-02 5.0e-03 FAIL
float_ansnr 1.59e-04 5.0e-05 FAIL

A follow-up investigation (Research-0985, 2026-06-03) and subsequent resolution (2026-09-05) established:

  1. float_ansnr: Stale row. The extractor was removed in PR #38. No ANSNR code exists in the tree. This row is closed.

  2. float_ssim: Two-cause divergence. The primary cause is a formula difference between the CPU (L×C×S with sqrt(var_ref*var_cmp)) and all GPU backends (combined Wang 2004 Eq.(13) with 2*covar). This formula difference is intentional; the same divergence is present for CUDA and Vulkan. The secondary cause is Arc A380's lack of native fp64, which amplifies fp32 accumulation error over the full-frame reduction (~566×314 pixels). Calibrated at places=3 (5.0e-4) under arc:dg2-g10 in scripts/ci/gpu_ulp_calibration.yaml (PR #838 / ADR-0234).

  3. ssimulacra2: Arc A380 lacks native fp64 (ADR-0220). In PR #865 (commit 8b7ae731a), an attempt to reduce round-off added a pseudo-Kahan summation block to core/src/feature/sycl/ssimulacra2_sycl.cpp::launch_blur. Because the 3-pole recursive Gaussian filter has no running accumulator ($o_k = n2_k \cdot \text{sum} - d1_k \cdot \text{prev1}_k - \text{prev2}_k$), adding $\text{prev1}$ to $o$ altered the filter transfer function, making the poles exponentially unstable ($o \sim 10^{25}$, causing NaN / score saturation at 100.0). Reverting the pseudo-Kahan hunk restores numerical stability: unit test delta drops to $4.98\times 10^{-5}$, checkerboard pairs produce bit-exact $0.0$, and the 48-frame src01 benchmark measures max_abs_diff = 1.211e-02. DoubleFloat EFT does not reduce this delta because divergence compounds across the 6-scale pyramid (box downsample, XYB, blur, combine).

Decision

  1. Revert pseudo-Kahan recurrence in ssimulacra2_sycl.cpp: Restore the standard Charalampidis recurrence matching CPU fast_gaussian_1d and CUDA ssimulacra2_blur.cu.

  2. Calibrate Arc A380 tolerance in gpu_ulp_calibration.yaml: Promote sycl:0x8086:0x56a* from placeholder to calibrated with ssimulacra2: 5.0e-2 (places=1), and add ssimulacra2: 5.0e-2 to arc:dg2-g10. The measured max_abs_diff = 1.211e-02 on src01 is safely bounded by this tolerance.

  3. Retain standard GPU execution: Keep GPU execution for the 3-plane elementwise multiply and separable IIR blur. Reject host-routing the blur for fp64-less devices, which would eliminate GPU acceleration.

  4. CI Lane Gating (TODO): A dedicated SYCL device CI workflow lane on Arc hardware remains gated on D4 self-hosted runner deployment.

Alternatives considered

Option Pros Cons Why not chosen / Status
Kahan-compensated IIR recurrence Intended to reduce fp32 round-off Mathematically invalid for IIR recurrence (no accumulator); blew up to $10^{25}$ / NaN / saturation at 100.0 REJECTED & REVERTED (PR #865 bug)
DoubleFloat (EFT) arithmetic in launch_blur fp64-equivalent precision in recurrence state Increases kernel register pressure; does not reduce the 1.21e-2 delta because multi-scale pyramid dominates REJECTED
Move ssimulacra2 IIR blur to host on fp64-less hardware Eliminates fp32 accumulation drift; achieves places=4 Eliminates GPU acceleration for ssimulacra2 on Intel Arc; incurs heavy PCIe readback / host overhead REJECTED
Hardware calibration at places=1 (5.0e-2) in gpu_ulp_calibration.yaml Honest, data-driven tolerance matching measured silicon behavior (1.211e-02 on src01, 0.0 on checkerboard) Relaxes tolerance from default places=2 (5.0e-3) to places=1 (5.0e-2) for Arc DG2-G10 ACCEPTED (Research-0985 §4.4 Option C)

Consequences

  • Positive: ssimulacra2_sycl no longer saturates at 100.0 / blows up to NaN. Both unit tests and cross_backend_parity_gate.py pass against Arc A380 hardware. gpu_ulp_calibration.yaml reflects verified hardware measurements.
  • Negative: None.
  • Neutral / follow-ups: Automated SYCL device CI lane gated on D4 self-hosted runner.

References

  • req — task brief: "investigate SYCL parity failures for float_ssim (2.68e-4), ssimulacra2 (8.72e-2), float_ansnr (1.59e-4); verify float_ansnr fully gone; identify divergence source; patch if high-confidence"
  • Research-0985: SYCL parity divergence investigation (companion document)
  • Research-0730: Cross-backend parity — Intel Arc A380 (2026-05-27)
  • ADR-0214: GPU-parity CI gate — tolerance table and promotion criteria
  • ADR-0234: GPU generation ULP calibration table
  • ADR-0192/ADR-0201/ADR-0206: ssimulacra2 precision contracts and GPU implementations
  • PR #865: commit 8b7ae731a (introduced pseudo-Kahan recurrence)