Skip to content

Commit 7908efa

Browse files
authored
Fix integer overflow in LAPACK DBDSQR, SBDSQR (#1135)
* Fix integer overflow in DBDSQR As noted in lapack issue 135, an integer overflow in the calculation of the iteration limit could lead to an immediate return without any iterations having been performed if the input matrix is sufficiently big. * Fix integer overflow in SBDSQR As noted in lapack issue 135, an integer overflow in the calculation of the iteration limit could lead to an immediate return without any iterations having been performed if the input matrix is sufficiently big. * Fix integer overflow in threshold calculation Related to lapack issue 135, the threshold calculation can overflow as well as the multiplication is evaluated from left to right. Without explicit parentheses, the calculation would overflow for N >= 18919 * Fix integer overflow in threshold calculation Related to lapack issue 135, the threshold calculation can overflow as well as the multiplication is evaluated from left to right. Without explicit parentheses, the calculation would overflow for N >= 18919
1 parent 66dc10b commit 7908efa

File tree

2 files changed

+47
-15
lines changed

2 files changed

+47
-15
lines changed

lapack-netlib/SRC/dbdsqr.f

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,16 @@
214214
*> through the inner loop exceeds MAXITR*N**2.
215215
*> \endverbatim
216216
*
217+
*> \par Note:
218+
* ===========
219+
*>
220+
*> \verbatim
221+
*> Bug report from Cezary Dendek.
222+
*> On March 23rd 2017, the INTEGER variable MAXIT = MAXITR*N**2 is
223+
*> removed since it can overflow pretty easily (for N larger or equal
224+
*> than 18,919). We instead use MAXITDIVN = MAXITR*N.
225+
*> \endverbatim
226+
*
217227
* Authors:
218228
* ========
219229
*
@@ -266,8 +276,8 @@ SUBROUTINE DBDSQR( UPLO, N, NCVT, NRU, NCC, D, E, VT, LDVT, U,
266276
* ..
267277
* .. Local Scalars ..
268278
LOGICAL LOWER, ROTATE
269-
INTEGER I, IDIR, ISUB, ITER, J, LL, LLL, M, MAXIT, NM1,
270-
$ NM12, NM13, OLDLL, OLDM
279+
INTEGER I, IDIR, ISUB, ITER, ITERDIVN, J, LL, LLL, M,
280+
$ MAXITDIVN, NM1, NM12, NM13, OLDLL, OLDM
271281
DOUBLE PRECISION ABSE, ABSS, COSL, COSR, CS, EPS, F, G, H, MU,
272282
$ OLDCS, OLDSN, R, SHIFT, SIGMN, SIGMX, SINL,
273283
$ SINR, SLL, SMAX, SMIN, SMINL, SMINOA,
@@ -300,7 +310,7 @@ SUBROUTINE DBDSQR( UPLO, N, NCVT, NRU, NCC, D, E, VT, LDVT, U,
300310
ELSE IF( NRU.LT.0 ) THEN
301311
INFO = -4
302312
ELSE IF( NCC.LT.0 ) THEN
303-
INFO = -5
313+
INFO = -5
304314
ELSE IF( ( NCVT.EQ.0 .AND. LDVT.LT.1 ) .OR.
305315
$ ( NCVT.GT.0 .AND. LDVT.LT.MAX( 1, N ) ) ) THEN
306316
INFO = -9
@@ -400,20 +410,21 @@ SUBROUTINE DBDSQR( UPLO, N, NCVT, NRU, NCC, D, E, VT, LDVT, U,
400410
40 CONTINUE
401411
50 CONTINUE
402412
SMINOA = SMINOA / SQRT( DBLE( N ) )
403-
THRESH = MAX( TOL*SMINOA, MAXITR*N*N*UNFL )
413+
THRESH = MAX( TOL*SMINOA, MAXITR*(N*(N*UNFL)) )
404414
ELSE
405415
*
406416
* Absolute accuracy desired
407417
*
408-
THRESH = MAX( ABS( TOL )*SMAX, MAXITR*N*N*UNFL )
418+
THRESH = MAX( ABS( TOL )*SMAX, MAXITR*(N*(N*UNFL)) )
409419
END IF
410420
*
411421
* Prepare for main iteration loop for the singular values
412422
* (MAXIT is the maximum number of passes through the inner
413423
* loop permitted before nonconvergence signalled.)
414424
*
415-
MAXIT = MAXITR*N*N
416-
ITER = 0
425+
MAXITDIVN = MAXITR*N
426+
ITERDIVN = 0
427+
ITER = -1
417428
OLDLL = -1
418429
OLDM = -1
419430
*
@@ -429,8 +440,13 @@ SUBROUTINE DBDSQR( UPLO, N, NCVT, NRU, NCC, D, E, VT, LDVT, U,
429440
*
430441
IF( M.LE.1 )
431442
$ GO TO 160
432-
IF( ITER.GT.MAXIT )
443+
*
444+
IF( ITER.GE.N ) THEN
445+
ITER = ITER - N
446+
ITERDIVN = ITERDIVN + 1
447+
IF (ITERDIVN.GE.MAXITDIVN )
433448
$ GO TO 200
449+
END IF
434450
*
435451
* Find diagonal block of matrix to work on
436452
*

lapack-netlib/SRC/sbdsqr.f

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,16 @@
214214
*> through the inner loop exceeds MAXITR*N**2.
215215
*> \endverbatim
216216
*
217+
*> \par Note:
218+
* ===========
219+
*>
220+
*> \verbatim
221+
*> Bug report from Cezary Dendek.
222+
*> On March 23rd 2017, the INTEGER variable MAXIT = MAXITR*N**2 is
223+
*> removed since it can overflow pretty easily (for N larger or equal
224+
*> than 18,919). We instead use MAXITDIVN = MAXITR*N.
225+
*> \endverbatim
226+
*
217227
* Authors:
218228
* ========
219229
*
@@ -266,8 +276,8 @@ SUBROUTINE SBDSQR( UPLO, N, NCVT, NRU, NCC, D, E, VT, LDVT, U,
266276
* ..
267277
* .. Local Scalars ..
268278
LOGICAL LOWER, ROTATE
269-
INTEGER I, IDIR, ISUB, ITER, J, LL, LLL, M, MAXIT, NM1,
270-
$ NM12, NM13, OLDLL, OLDM
279+
INTEGER I, IDIR, ISUB, ITER, ITERDIVN J, LL, LLL, M,
280+
$ MAXITDIVN, NM1, NM12, NM13, OLDLL, OLDM
271281
REAL ABSE, ABSS, COSL, COSR, CS, EPS, F, G, H, MU,
272282
$ OLDCS, OLDSN, R, SHIFT, SIGMN, SIGMX, SINL,
273283
$ SINR, SLL, SMAX, SMIN, SMINL, SMINOA,
@@ -400,20 +410,21 @@ SUBROUTINE SBDSQR( UPLO, N, NCVT, NRU, NCC, D, E, VT, LDVT, U,
400410
40 CONTINUE
401411
50 CONTINUE
402412
SMINOA = SMINOA / SQRT( REAL( N ) )
403-
THRESH = MAX( TOL*SMINOA, MAXITR*N*N*UNFL )
413+
THRESH = MAX( TOL*SMINOA, MAXITR*(N*(N*UNFL)) )
404414
ELSE
405415
*
406416
* Absolute accuracy desired
407417
*
408-
THRESH = MAX( ABS( TOL )*SMAX, MAXITR*N*N*UNFL )
418+
THRESH = MAX( ABS( TOL )*SMAX, MAXITR*(N*(N*UNFL)) )
409419
END IF
410420
*
411421
* Prepare for main iteration loop for the singular values
412422
* (MAXIT is the maximum number of passes through the inner
413423
* loop permitted before nonconvergence signalled.)
414424
*
415-
MAXIT = MAXITR*N*N
416-
ITER = 0
425+
MAXITDIVN = MAXITR*N
426+
ITERDIVN = 0
427+
ITER = -1
417428
OLDLL = -1
418429
OLDM = -1
419430
*
@@ -429,8 +440,13 @@ SUBROUTINE SBDSQR( UPLO, N, NCVT, NRU, NCC, D, E, VT, LDVT, U,
429440
*
430441
IF( M.LE.1 )
431442
$ GO TO 160
432-
IF( ITER.GT.MAXIT )
443+
*
444+
IF( ITER.GE.N ) THEN
445+
ITER = ITER - N
446+
ITERDIVN = ITERDIVN + 1
447+
IF( ITERDIVN.GE.MAXITDIVN )
433448
$ GO TO 200
449+
END IF
434450
*
435451
* Find diagonal block of matrix to work on
436452
*

0 commit comments

Comments
 (0)