1 SUBROUTINE psgeqpf( M, N, A, IA, JA, DESCA, IPIV, TAU, WORK,
10 INTEGER IA, JA, INFO, LWORK, M,
13 INTEGER DESCA( * ), IPIV( * )
186 INTEGER BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
187 $ lld_, mb_, m_, nb_, n_, rsrc_
188 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
189 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
190 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
192 parameter( one = 1.0e+0, zero = 0.0e+0 )
196 INTEGER I, IACOL, IAROW, ICOFF, ICTXT, ICURROW,
197 $ icurcol, ii, iia, ioffa, ipn, ipcol, ipw,
198 $ iroff, itemp, j, jb, jj, jja, jjpvt, jn, kb,
199 $ k, kk, kstart, kstep, lda, ll, lwmin, mn, mp,
200 $ mycol, myrow, npcol, nprow, nq, nq0, pvt
201 REAL AJJ, ALPHA, TEMP, TEMP2, TOL3Z
204 INTEGER DESCN( DLEN_ ), IDUM1( 1 ), IDUM2( 1 )
214 INTEGER , INDXG2P, NUMROC
215 EXTERNAL iceil, indxg2p, numroc
220 INTRINSIC abs, ifix,
max,
min, mod, real, sqrt
226 ictxt = desca( ctxt_ )
232 IF( nprow.EQ.-1 )
THEN
235 CALL chk1mat( m, 1, n, 2, ia, ja, desca, 6, info )
237 iroff = mod( ia-1, desca( mb_ ) )
238 icoff = mod( ja-1, desca( nb_ ) )
239 iarow = indxg2p( ia, desca( mb_ ), myrow, desca( rsrc_ ),
241 iacol = indxg2p( ja, desca( nb_ ), mycol, desca( csrc_ ),
243 mp = numroc( m+iroff, desca( mb_ ), myrow, iarow, nprow )
244 nq = numroc( n+icoff, desca( nb_ ), mycol, iacol, npcol )
245 nq0 = numroc( ja+n-1, desca( nb_ ), mycol, desca( csrc_ ),
247 lwmin =
max( 3, mp + nq ) + nq0 + nq
249 work( 1 ) = real( lwmin )
250 lquery = ( lwork.EQ.-1 )
251 IF( lwork.LT.lwmin .AND. .NOT.lquery )
254 IF( lwork.EQ.-1 )
THEN
260 CALL pchk1mat( m, 1, n, 2, ia, ja, desca, 6, 1, idum1, idum2,
265 CALL pxerbla( ictxt,
'PSGEQPF', -info )
267 ELSE IF( lquery )
THEN
273 IF( m.EQ.0 .OR. n.EQ.0 )
276 CALL infog2l( ia, ja, desca, nprow, npcol, myrow, mycol, iia, jja,
283 tol3z = sqrt( slamch(
'Epsilon') )
288 jn =
min(
iceil( ja, desca( nb_ ) ) * desca( nb_ ), ja+n-1 )
289 kstep = npcol * desca( nb_ )
291 IF( mycol.EQ.iacol )
THEN
296 DO 10 ll = jja, jja+jb-1
297 ipiv( ll ) = ja + ll - jja
299 kstart = jn + kstep - desca( nb_ )
303 DO 30 kk = jja+jb, jja+nq-1, desca( nb_ )
304 kb =
min( jja+nq-kk, desca( nb_ ) )
305 DO 20 ll = kk, kk+kb-1
306 ipiv( ll ) = kstart+ll-kk+1
308 kstart = kstart + kstep
311 kstart = jn + ( mod( mycol-iacol+npcol, npcol )-1 )*
313 DO 50 kk = jja, jja+nq-1, desca( nb_ )
314 kb =
min( jja+nq-kk, desca( nb_ ) )
315 DO 40 ll = kk, kk+kb-1
316 ipiv( ll ) = kstart+ll-kk+1
318 kstart = kstart + kstep
324 CALL descset( descn, 1, desca( n_ ), 1, desca( nb_ ), myrow,
325 $ desca( csrc_ ), ictxt, 1 )
330 IF( mycol.EQ.iacol )
THEN
332 CALL psnrm2( m, work( jj+kk ), a, ia, ja+kk, desca, 1 )
333 work( nq+jj+kk ) = work( jj+kk )
337 icurcol = mod( iacol+1, npcol )
341 DO 80 j = jn+1, ja+n-1, desca( nb_ )
342 jb =
min( ja+n-j, desca( nb_ ) )
344 IF( mycol.EQ.icurcol )
THEN
346 CALL psnrm2( m, work( jj+kk ), a, ia, j+kk, desca, 1 )
347 work( nq+jj+kk ) = work( jj+kk )
351 icurcol = mod( icurcol+1, npcol )
356 DO 120 j = ja, ja+mn-1
359 CALL infog1l( j, desca( nb_ ), npcol, mycol, desca( csrc_
363 CALL psamax( k, temp, pvt, work( ipn ), 1, j, descn,
369 CALL infog1l( pvt, desca( nb_ ), npcol, mycol,
370 $ desca( csrc_ ), jjpvt, ipcol )
371 IF( icurcol.EQ.ipcol )
THEN
372 IF( mycol.EQ.icurcol )
THEN
373 CALL sswap( mp, a( iia+(jj-1)*lda ), 1,
374 $ a( iia+(jjpvt-1)*lda ), 1 )
376 ipiv( jjpvt ) = ipiv( jj )
379 work( ipn+nq+jjpvt-1 ) = work( ipn+nq+jj-1 )
382 IF( mycol.EQ.icurcol )
THEN
384 CALL sgesd2d( ictxt, mp, 1, a( iia+(jj-1)*lda ), lda
386 work( ipw ) = real( ipiv( jj ) )
387 work( ipw+1 ) = work( ipn + jj - 1 )
388 work( ipw+2 ) = work( ipn + nq + jj - 1 )
389 CALL sgesd2d( ictxt, 3, 1, work( ipw ), 3, myrow,
392 CALL sgerv2d( ictxt, mp, 1, a( iia+(jj-1)*lda ), lda,
394 CALL igerv2d( ictxt, 1, 1, ipiv( jj ), 1, myrow,
397 ELSE IF( mycol.EQ.ipcol )
THEN
399 CALL sgesd2d( ictxt, mp, 1, a( iia+(jjpvt-1)*lda ),
400 $ lda, myrow, icurcol )
401 CALL igesd2d( ictxt, 1, 1,
404 CALL sgerv2d( ictxt, mp, 1, a( iia+(jjpvt-1)*lda ),
406 CALL sgerv2d( ictxt, 3, 1, work( ipw ), 3, myrow,
408 ipiv( jjpvt ) = ifix( work( ipw ) )
409 work( ipn+jjpvt-1 )= work( ipw+1 )
410 work( ipn+nq+jjpvt-1 ) = work( ipw+2 )
420 CALL infog1l( i, desca( mb_ ), nprow, myrow, desca( rsrc_ ),
422 IF( desca( m_ ).EQ.1 )
THEN
423 IF( myrow.EQ.icurrow )
THEN
424 IF( mycol.EQ.icurcol )
THEN
425 ioffa = ii+(jj-1)*desca( lld_ )
427 CALL slarfg( 1, ajj, a( ioffa ), 1, tau( jj ) )
429 alpha = one - tau( jj )
430 CALL sgebs2d( ictxt,
'Rowwise',
' ', 1, 1, alpha,
432 CALL sscal( nq-jj, alpha, a( ioffa+desca( lld_ ) ),
435 CALL sgebs2d( ictxt,
'Columnwise',
' ', 1, 1,
440 CALL sgebr2d( ictxt, 'rowwise
', ' ', 1, 1, ALPHA,
441 $ 1, ICURROW, ICURCOL )
442 CALL SSCAL( NQ-JJ+1, ALPHA, A( I ), DESCA( LLD_ ) )
445.EQ.
ELSE IF( MYCOLICURCOL ) THEN
446 CALL SGEBR2D( ICTXT, 'columnwise
', ' ', 1, 1, TAU( JJ ),
447 $ 1, ICURROW, ICURCOL )
452 CALL PSLARFG( M-J+JA, AJJ, I, J, A, MIN( I+1, IA+M-1 ), J,
454.LT.
IF( JJA+N-1 ) THEN
458 CALL PSELSET( A, I, J, DESCA, ONE )
459 CALL PSLARF( 'left
', M-J+JA, JA+N-1-J, A, I, J, DESCA,
460 $ 1, TAU, A, I, J+1, DESCA, WORK( IPW ) )
462 CALL PSELSET( A, I, J, DESCA, AJJ )
468.EQ.
IF( MYCOLICURCOL )
470.EQ.
IF( MOD( J, DESCA( NB_ ) )0 )
471 $ ICURCOL = MOD( ICURCOL+1, NPCOL )
472.GT.
IF( (JJA+NQ-JJ)0 ) THEN
473.EQ.
IF( MYROWICURROW ) THEN
474 CALL SGEBS2D( ICTXT, 'columnwise
', ' ', 1, JJA+NQ-JJ,
475 $ A( II+( MIN( JJA+NQ-1, JJ )-1 )*LDA ),
477 CALL SCOPY( JJA+NQ-JJ, A( II+( MIN( JJA+NQ-1, JJ )
478 $ -1)*LDA ), LDA, WORK( IPW+MIN( JJA+NQ-1,
481 CALL SGEBR2D( ICTXT, 'columnwise
', ' ', JJA+NQ-JJ, 1,
482 $ WORK( IPW+MIN( JJA+NQ-1, JJ )-1 ),
483 $ MAX( 1, NQ ), ICURROW, MYCOL )
487 JN = MIN( ICEIL( J+1, DESCA( NB_ ) ) * DESCA( NB_ ),
489.EQ.
IF( MYCOLICURCOL ) THEN
490 DO 90 LL = JJ-1, JJ + JN - J - 2
491.NE.
IF( WORK( IPN+LL )ZERO ) THEN
492 TEMP = ABS( WORK( IPW+LL ) ) / WORK( IPN+LL )
493 TEMP = MAX( ZERO, ( ONE+TEMP )*( ONE-TEMP ) )
494 TEMP2 = TEMP*( WORK( IPN+LL ) / WORK( IPN+NQ+LL ) )**2
495.LE.
IF( TEMP2TOL3Z ) THEN
496.GT.
IF( IA+M-1I ) THEN
497 CALL PSNRM2( IA+M-I-1, WORK( IPN+LL ), A, I+1,
498 $ J+LL-JJ+2, DESCA, 1 )
499 WORK( IPN+NQ+LL ) = WORK( IPN+LL )
501 WORK( IPN+LL ) = ZERO
502 WORK( IPN+NQ+LL ) = ZERO
505 WORK( IPN+LL ) = WORK( IPN+LL ) * SQRT( TEMP )
511 ICURCOL = MOD( ICURCOL+1, NPCOL )
513 DO 110 K = JN+1, JA+N-1, DESCA( NB_ )
514 KB = MIN( JA+N-K, DESCA( NB_ ) )
516.EQ.
IF( MYCOLICURCOL ) THEN
517 DO 100 LL = JJ-1, JJ+KB-2
518.NE.
IF( WORK( IPN+LL )ZERO ) THEN
519 TEMP = ABS( WORK( IPW+LL ) ) / WORK( IPN+LL )
520 TEMP = MAX( ZERO, ( ONE+TEMP )*( ONE-TEMP ) )
522 $ ( WORK( IPN+LL ) / WORK( IPN+NQ+LL ) )**2
523.LE.
IF( TEMP2TOL3Z ) THEN
524.GT.
IF( IA+M-1I ) THEN
525 CALL PSNRM2( IA+M-I-1, WORK( IPN+LL ), A,
526 $ I+1, K+LL-JJ+1, DESCA, 1 )
527 WORK( IPN+NQ+LL ) = WORK( IPN+LL )
529 WORK( IPN+LL ) = ZERO
530 WORK( IPN+NQ+LL ) = ZERO
533 WORK( IPN+LL ) = WORK( IPN+LL ) * SQRT( TEMP )
539 ICURCOL = MOD( ICURCOL+1, NPCOL )
545 WORK( 1 ) = REAL( LWMIN )