Skip to content

MiniTensor: fix log() failure on ill-conditioned SPD tensors - #15513

Merged
lxmota merged 1 commit into
trilinos:developfrom
lxmota:minitensor-log-iss-det-cancellation
Jul 29, 2026
Merged

MiniTensor: fix log() failure on ill-conditioned SPD tensors#15513
lxmota merged 1 commit into
trilinos:developfrom
lxmota:minitensor-log-iss-det-cancellation

Conversation

@lxmota

@lxmota lxmota commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

@trilinos/minitensor

Motivation

For SPD tensors with condition number above ~1e10, minitensor::log() (inverse scaling and squaring) can abort in debug builds and write out of bounds in release builds. Root cause chain, verified with a debugger on a captured input:

  1. The fully expanded 3x3 determinant used by the Denman–Beavers scaling in sqrt_dbp cancels catastrophically: for the tensor in the added regression test (eigenvalues 1e6, 1, 1e-6; unit determinant) the six terms are of order 1e15 and the computed determinant is exactly 0.0.
  2. The scaling factor g = 1/det^(1/6) becomes Inf and floods the iterates X and M with Inf.
  3. inverse_full_pivotsolve_full_pivot: elimination produces Inf/Inf = NaN, and the next pivot search finds no pivot because NaN comparisons are false.
  4. With asserts enabled, the run aborts at the pivot_row < dimension assert; with -DNDEBUG the subsequent S(pivot_row, j) /= t with pivot_row == dimension is an out-of-bounds write.

In a 500-sample sweep per condition number, log() aborted on 22% of random SPD tensors at condition 1e12 and 39% at 1e14.

Changes

  • sqrt_dbp: skip the determinant scaling when the computed determinant is zero or the scaling factor is non-finite. The scaling only accelerates convergence, so skipping it affects iteration count, not correctness.
  • solve_full_pivot: replace the pivot-search asserts with MT_ERROR_EXIT so a singular or non-finite matrix produces a clean failure instead of memory corruption in release builds.
  • New regression test MiniTensor.LogIllConditioned with the captured tensor whose expanded determinant cancels to exactly zero.

Related Issues

None filed; found during an accuracy/performance study of log() vs log_sym() on SPD tensors.

Testing

  • Full test_01.cc gtest suite (33 tests including the new one) passes on Linux x86-64, GCC 16, serial Kokkos.
  • With the fix, 500-sample sweeps at conditions 1e12 and 1e14 complete 500/500 (previously 391/500 and 307/500), with relative errors identical to the unpatched code on the samples that previously succeeded (median ~1e-6 at 1e12 against an independent 80-bit eigendecomposition reference).
  • The alternative of switching the ISS pipeline to inverse_fast23 was also evaluated and rejected: it divides by the same cancellation-prone determinant, and NaN passes its assert(det != 0), turning the failure into an infinite loop.

@github-actions

Copy link
Copy Markdown

CDash for AT2 results

Reproducing CI builds locally

CI builds can be reproduced locally in a container.

Requirements: Python 3.9+, Podman, CMake

Steps:

  • Check out the branch of the PR locally.
  • Run commonTools/pr_reproducer/reproducer.sh.

@lxmota lxmota self-assigned this Jul 28, 2026
@lxmota
lxmota requested a review from ikalash July 28, 2026 22:35
@lxmota
lxmota enabled auto-merge July 28, 2026 23:20
ikalash
ikalash previously approved these changes Jul 28, 2026
For SPD tensors with condition number above ~1e10, the fully expanded
3x3 determinant used by the Denman-Beavers scaling in sqrt_dbp can
cancel catastrophically and return exactly zero (terms of order 1e15
summing to a true determinant of order 1). The scaling factor
g = 1/det^(1/6) then becomes Inf, the iterates fill with Inf/NaN, and
the pivot search in solve_full_pivot finds no pivot because NaN
comparisons are false. With asserts enabled log() aborts; in release
builds (-DNDEBUG) the subsequent access S(pivot_row, j) with
pivot_row == dimension writes out of bounds.

Two changes:

- sqrt_dbp: skip the determinant scaling when the computed determinant
  is zero or the scaling factor is non-finite. The scaling only
  accelerates convergence, so skipping it affects iteration count, not
  correctness. In a 500-sample sweep per condition number this restores
  a 100% success rate at conditions 1e12 and 1e14 (from 78% and 61%)
  with accuracy unchanged on the samples that previously succeeded.

- solve_full_pivot: replace the pivot-search asserts with an explicit
  error exit so that a singular or non-finite matrix produces a clean
  failure instead of an out-of-bounds write in release builds.

Adds a regression test with an SPD tensor of unit determinant and
condition number 1e12 whose expanded determinant cancels to exactly
zero in double precision.

Signed-off-by: Alejandro Mota <amota@sandia.gov>
@lxmota
lxmota force-pushed the minitensor-log-iss-det-cancellation branch from 02fb402 to 66b96c5 Compare July 29, 2026 01:21
@lxmota
lxmota requested a review from cgcgcg July 29, 2026 01:58
@lxmota
lxmota merged commit 5a4baa2 into trilinos:develop Jul 29, 2026
18 of 19 checks passed
@lxmota
lxmota deleted the minitensor-log-iss-det-cancellation branch July 29, 2026 02:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants