Skip to content

Commit 8f88d0f

Browse files
committed
fix(kpm): use combined absolute+relative tolerance in M6-2 dual-mode tests
The fixed 1e-5 absolute tolerance in solve_linear_system_2x2_matches_cpp and solve_symmetric_linear_system_3x3_matches_cpp is too tight for f32 values with magnitude > ~10. Apple Silicon ARM64 uses FMA differently from x86_64, producing tiny precision differences that exceed 1e-5 for larger results. Example failure on macOS ARM64: rust=-40.826614, cpp=-40.8266, diff=1.5e-5 The diff of 1.5e-5 represents a relative error of ~3.7e-7, which is well within f32 precision but exceeds the absolute tolerance. Fix: use combined tolerance: tol = max(1e-5, |value| * 1e-6) This gives: - |x| <= 10: tolerance unchanged at 1e-5 (preserves existing strictness) - |x| = 100: tolerance 1e-4 (~1e-6 relative) - |x| = 1000: tolerance 1e-3 (~1e-6 relative) These bounds are consistent with f32's ~7-digit precision and accommodate platform-specific FMA rounding without losing test sensitivity for typical values. Surfaced now because PR #117's new dual-mode CI step exposed this pre-existing issue on macOS runners. The math itself is correct; only the test tolerance was too strict. Refs #116
1 parent 76c3552 commit 8f88d0f

1 file changed

Lines changed: 16 additions & 6 deletions

File tree

crates/core/src/kpm/freak/math.rs

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2112,13 +2112,20 @@ mod dual_mode_tests {
21122112
if diff > max_diff {
21132113
max_diff = diff;
21142114
}
2115+
// Combined absolute + relative tolerance: f32 has ~7
2116+
// decimal digits, so values around magnitude M need
2117+
// tolerance ~ M * 1e-6. The 1e-5 floor handles values
2118+
// near zero. This accommodates platform-specific FMA
2119+
// rounding differences (Apple Silicon vs x86_64).
2120+
let tol = 1e-5_f32.max(x_rust[i].abs() * 1e-6);
21152121
assert!(
2116-
diff < 1e-5,
2117-
"solve_linear_system_2x2 diverged at x[{}]: rust={}, cpp={}, diff={}",
2122+
diff < tol,
2123+
"solve_linear_system_2x2 diverged at x[{}]: rust={}, cpp={}, diff={}, tol={}",
21182124
i,
21192125
x_rust[i],
21202126
x_cpp[i],
2121-
diff
2127+
diff,
2128+
tol
21222129
);
21232130
}
21242131
compared += 1;
@@ -2183,13 +2190,16 @@ mod dual_mode_tests {
21832190
if diff > max_diff {
21842191
max_diff = diff;
21852192
}
2193+
// See solve_linear_system_2x2_matches_cpp for tolerance rationale.
2194+
let tol = 1e-5_f32.max(x_rust[i].abs() * 1e-6);
21862195
assert!(
2187-
diff < 1e-5,
2188-
"solve_symmetric_linear_system_3x3 diverged at x[{}]: rust={}, cpp={}, diff={}",
2196+
diff < tol,
2197+
"solve_symmetric_linear_system_3x3 diverged at x[{}]: rust={}, cpp={}, diff={}, tol={}",
21892198
i,
21902199
x_rust[i],
21912200
x_cpp[i],
2192-
diff
2201+
diff,
2202+
tol
21932203
);
21942204
}
21952205
compared += 1;

0 commit comments

Comments
 (0)