Skip to content

TESTING: scale the xGEDMDQ residual check by SINGVQX(KQ) - #1342

Merged
langou merged 1 commit into
Reference-LAPACK:masterfrom
ACSimon33:dmd_test_singvqx_index
Jul 30, 2026
Merged

langou merged 1 commit into
Reference-LAPACK:masterfrom
ACSimon33:dmd_test_singvqx_index

Conversation

@ACSimon33

Copy link
Copy Markdown
Collaborator

Description

dchkdmd/schkdmd scale the xGEDMDQ residual-consistency check by SINGVQX(K),
but SINGVQX is only filled up to KQ:

  • SINGVQX(1:KQ) = WORK(...)KQ is the rank xGEDMDQ returns
    (dchkdmd.f90:574)
  • ... * SINGVQX(K)/(ANORM*SINGVQX(1))K is the rank xGEDMD returns
    (dchkdmd.f90:653)

Whenever K > KQ the scale factor is read from memory that xGEDMDQ never wrote.
The surrounding code already knows the two ranks differ — dchkdmd.f90:577
counts KQ /= K occurrences and the singular-value comparison at
dchkdmd.f90:582 correctly bounds itself with MIN(K,KQ). cchkdmd/zchkdmd
already use SINGVQX(KQ); this brings the real precisions in line.

How it surfaced. The extended-API double-precision DMD test reported 6 fewer
tests than the default API. xdmdeigtstd_64 aborted at the last size
(M=50, N=20) with ................ DGEDMDQ_64 FAILED!Check the code for implementation errors., printing none of the six verdict lines the summary
script counts. Because the STOP at dchkdmd.f90:660 is a bare STOP, the
process exit status was 0 and CTest recorded a pass — the only visible symptom
was the test-count mismatch.

Evidence. Both builds were instrumented to trace all 4608 xGEDMDQ residual
checks:

default API extended API (_64)
RES, RES1, TMP bit-identical to default in all 4608 checks
ranks K, KQ identical in all 4608 checks
checks with K > KQ 48 (K=16–18, KQ=15) 48 (same cases)
SINGVQX(K) there ≈6.15e-313 (denormal) ≈0.358
resulting TMP vs TOL2=2.2e-12 ≈1e-314 → passes 3.6e-2 → fails, STOPs

The arithmetic is identical between the two builds; only the uninitialized value
differs. Filling SINGVQX with a sentinel after ALLOCATE makes both builds
fail the same 48 checks, which confirms the read is uninitialized rather than an
ILP64 numerical difference. Note the consequence: which API fails is down to heap
contents, so on another platform or build type the default API could be the one
that aborts.

schkdmd has the identical wrong index and identical partial fill. It currently
passes only because its uninitialized values happen to be harmless in both APIs.

SINGVQX is only filled to KQ, so SINGVQX(K) read uninitialized memory
whenever DGEDMD's rank K exceeded DGEDMDQ's KQ -- harmless in the
default API by luck, an abort in the _64 build. cchkdmd/zchkdmd
already use KQ.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 30, 2026 13:35

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Comment thread TESTING/EIG/dchkdmd.f90
DO i = 1, KQ
TMP = MAX( TMP, ABS(RES(i) - RES1(i)) * &
SINGVQX(K)/(ANORM*SINGVQX(1)) )
SINGVQX(KQ)/(ANORM*SINGVQX(1)) )

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, 'KQ' here, not 'K', correct.

@langou
langou merged commit fb9b904 into Reference-LAPACK:master Jul 30, 2026
15 of 16 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.

3 participants