Skip to content

Gate SGGEV3 workspace query on ILV, not ILVL#1274

Merged
langou merged 1 commit into
Reference-LAPACK:masterfrom
kyungminlee:fix-sggev3-query
May 11, 2026
Merged

Gate SGGEV3 workspace query on ILV, not ILVL#1274
langou merged 1 commit into
Reference-LAPACK:masterfrom
kyungminlee:fix-sggev3-query

Conversation

@kyungminlee
Copy link
Copy Markdown
Contributor

The actual SLAQZ0 call uses 'S' when ILV is true and 'E' otherwise, but the query gated that choice on ILVL, undersizing LWORK for JOBVL='N', JOBVR='V'. Mirror DGGEV3: gate SLAQZ0 and SGGHD3 on ILV, SORGQR on ILVL.

lapack/SRC/dggev3.f

Lines 329 to 351 in 5da5348

CALL DORMQR( 'L', 'T', N, N, N, B, LDB, WORK, A, LDA,
$ WORK, -1, IERR )
LWKOPT = MAX( LWKOPT, 3*N+INT( WORK( 1 ) ) )
IF( ILVL ) THEN
CALL DORGQR( N, N, N, VL, LDVL, WORK, WORK, -1, IERR )
LWKOPT = MAX( LWKOPT, 3*N+INT( WORK( 1 ) ) )
END IF
IF( ILV ) THEN
CALL DGGHD3( JOBVL, JOBVR, N, 1, N, A, LDA, B, LDB, VL,
$ LDVL, VR, LDVR, WORK, -1, IERR )
LWKOPT = MAX( LWKOPT, 3*N+INT( WORK ( 1 ) ) )
CALL DLAQZ0( 'S', JOBVL, JOBVR, N, 1, N, A, LDA, B, LDB,
$ ALPHAR, ALPHAI, BETA, VL, LDVL, VR, LDVR,
$ WORK, -1, 0, IERR )
LWKOPT = MAX( LWKOPT, 2*N+INT( WORK( 1 ) ) )
ELSE
CALL DGGHD3( 'N', 'N', N, 1, N, A, LDA, B, LDB, VL, LDVL,
$ VR, LDVR, WORK, -1, IERR )
LWKOPT = MAX( LWKOPT, 3*N+INT( WORK( 1 ) ) )
CALL DLAQZ0( 'E', JOBVL, JOBVR, N, 1, N, A, LDA, B, LDB,
$ ALPHAR, ALPHAI, BETA, VL, LDVL, VR, LDVR,
$ WORK, -1, 0, IERR )
LWKOPT = MAX( LWKOPT, 2*N+INT( WORK( 1 ) ) )

Reproducer

  ! Workspace query -- JOBVL='N', JOBVR='V' (right eigenvectors only).
  ! Pre-patch: SGGEV3 gates the SLAQZ0 query on ILVL, so it queries with
  ! 'E' (eigenvalues-only) -- but the actual run gates on ILV and calls
  ! SLAQZ0('S',...), which needs more workspace.
  CALL SGGEV3('N', 'V', N, A, N, B, N, ALPHAR, ALPHAI, BETA, &
              VL, 1, VR, N, WQ, -1, INFO)
  IF (INFO /= 0) THEN
     PRINT *, 'query failed, INFO =', INFO
     STOP 1
  END IF
  LWORK = INT(WQ(1))
  PRINT *, 'query returned LWORK =', LWORK
  ALLOCATE(WORK(LWORK))

  ! Actual call. Pre-patch: under-sized WORK -> INFO=-17 from inner
  ! SLAQZ0 guard, or silent OOB write. Post-patch: INFO=0.
  CALL SGGEV3('N', 'V', N, A, N, B, N, ALPHAR, ALPHAI, BETA, &
              VL, 1, VR, N, WORK, LWORK, INFO)
  PRINT *, 'compute INFO =', INFO

The actual SLAQZ0 call uses 'S' when ILV is true and 'E' otherwise,
but the query gated that choice on ILVL, undersizing LWORK for
JOBVL='N', JOBVR='V'. Mirror DGGEV3: gate SLAQZ0 and SGGHD3 on ILV,
SORGQR on ILVL.
@kyungminlee kyungminlee deleted the fix-sggev3-query branch May 11, 2026 12:41
@kyungminlee kyungminlee restored the fix-sggev3-query branch May 11, 2026 12:41
@kyungminlee kyungminlee reopened this May 11, 2026
@langou langou merged commit 67c7c8a into Reference-LAPACK:master May 11, 2026
23 checks passed
@kyungminlee kyungminlee deleted the fix-sggev3-query branch May 11, 2026 16:20
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