1 SUBROUTINE pzgeqpf( M, N, A, IA, JA, DESCA, IPIV, TAU, WORK,
2 $ LWORK, RWORK, LRWORK, INFO )
10 INTEGER IA, JA, INFO, LRWORK, LWORK, M, N
13 INTEGER DESCA( * ), IPIV( * )
14 DOUBLE PRECISION RWORK( * )
15 COMPLEX*16 A( * ), TAU( * ), WORK( * )
202 INTEGER BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
203 $ lld_, mb_, m_, nb_, n_, rsrc_
204 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
205 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
206 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
207 DOUBLE PRECISION ONE, ZERO
208 parameter( one = 1.0d+0, zero = 0.0d+0 )
212 INTEGER I, IACOL, IAROW, ICOFF, ICTXT, ICURROW,
213 $ icurcol, ii, iia, ioffa, ipcol, iroff, itemp,
214 $ j, jb, jj, jja, jjpvt, jn, kb, k, kk, kstart,
215 $ kstep, lda, ll, lrwmin, lwmin, mn, mp, mycol,
216 $ myrow, npcol, nprow, nq, nq0, pvt
217 DOUBLE PRECISION TEMP, TEMP2, TOL3Z
218 COMPLEX*16 AJJ, ALPHA
221 INTEGER DESCN( DLEN_ ), IDUM1( 2 ), IDUM2( 2 )
228 $ zgebs2d, zgerv2d, zgesd2d, zlarfg,
232 INTEGER ICEIL, INDXG2P, NUMROC
233 EXTERNAL iceil, indxg2p, numroc
234 DOUBLE PRECISION DLAMCH
238 INTRINSIC abs, dcmplx, dconjg, idint,
max,
min, mod, sqrt
244 ictxt = desca( ctxt_ )
245 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
250 IF( nprow.EQ.-1 )
THEN
253 CALL chk1mat( m, 1, n, 2, ia, ja, desca, 6, info )
255 iroff = mod( ia-1, desca( mb_ ) )
256 icoff = mod( ja-1, desca( nb_ ) )
257 iarow = indxg2p( ia, desca( mb_ ), myrow, desca( rsrc_ ),
259 iacol = indxg2p( ja, desca( nb_ ), mycol, desca( csrc_ ),
261 mp = numroc( m+iroff, desca( mb_ ), myrow, iarow, nprow )
262 nq = numroc( n+icoff, desca( nb_ ), mycol, iacol, npcol )
263 nq0 = numroc( ja+n-1, desca( nb_ ), mycol, desca( csrc_ ),
265 lwmin =
max( 3, mp + nq )
268 work( 1 ) = dcmplx( dble( lwmin ) )
269 rwork( 1 ) = dble( lrwmin )
270 lquery = ( lwork.EQ.-1 .OR. lrwork.EQ.-1 )
271 IF( lwork.LT.lwmin .AND. .NOT.lquery )
THEN
273 ELSE IF( lrwork.LT.lrwmin .AND. .NOT.lquery )
THEN
277 IF( lwork.EQ.-1 )
THEN
283 IF( lrwork.EQ.-1 )
THEN
289 CALL pchk1mat( m, 1, n, 2, ia, ja, desca, 6, 2, idum1, idum2,
294 CALL pxerbla( ictxt,
'PZGEQPF', -info )
296 ELSE IF( lquery )
THEN
302 IF( m.EQ.0 .OR. n.EQ.0 )
305 CALL infog2l( ia, ja, desca, nprow, npcol, myrow, mycol, iia, jja,
312 tol3z = sqrt( dlamch(
'Epsilon') )
317 jn =
min( iceil( ja, desca( nb_ ) ) * desca( nb_ ), ja+n-1 )
318 kstep = npcol * desca( nb_ )
320 IF( mycol.EQ.iacol )
THEN
325 DO 10 ll = jja, jja+jb-1
326 ipiv( ll ) = ja + ll - jja
328 kstart = jn + kstep - desca( nb_ )
332 DO 30 kk = jja+jb, jja+nq-1, desca( nb_ )
333 kb =
min( jja+nq-kk, desca( nb_ ) )
334 DO 20 ll = kk, kk+kb-1
335 ipiv( ll ) = kstart+ll-kk+1
337 kstart = kstart + kstep
340 kstart = jn + ( mod( mycol-iacol+npcol, npcol )-1 )*
342 DO 50 kk = jja, jja+nq-1, desca( nb_ )
343 kb =
min( jja+nq-kk, desca( nb_ ) )
344 DO 40 ll = kk, kk+kb-1
345 ipiv( ll ) = kstart+ll-kk+1
347 kstart = kstart + kstep
353 CALL descset( descn, 1, desca( n_ ), 1, desca( nb_ ), myrow,
354 $ desca( csrc_ ), ictxt, 1 )
357 IF( mycol.EQ.iacol )
THEN
359 CALL pdznrm2( m, rwork( jj+kk ), a, ia, ja+kk, desca, 1 )
360 rwork( nq+jj+kk ) = rwork( jj+kk )
364 icurcol = mod( iacol+1, npcol )
368 DO 80 j = jn+1, ja+n-1, desca( nb_ )
369 jb =
min( ja+n-j, desca( nb_ ) )
371 IF( mycol.EQ.icurcol )
THEN
373 CALL pdznrm2( m, rwork( jj+kk ), a, ia, j+kk, desca, 1 )
374 rwork( nq+jj+kk ) = rwork( jj+kk )
378 icurcol = mod( icurcol+1, npcol )
383 DO 120 j = ja, ja+mn-1
386 CALL infog1l( j, desca( nb_ ), npcol, mycol, desca( csrc_ ),
390 CALL pdamax( k, temp, pvt, rwork, 1, j, descn,
396 CALL infog1l( pvt, desca( nb_ ), npcol, mycol,
397 $ desca( csrc_ ), jjpvt, ipcol )
398 IF( icurcol.EQ.ipcol )
THEN
399 IF( mycol.EQ.icurcol )
THEN
400 CALL zswap( mp, a( iia+(jj-1)*lda ), 1,
401 $ a( iia+(jjpvt-1)*lda ), 1 )
402 itemp = ipiv( jjpvt )
403 ipiv( jjpvt ) = ipiv( jj )
405 rwork( jjpvt ) = rwork( jj )
406 rwork( nq+jjpvt ) = rwork( nq+jj )
409 IF( mycol.EQ.icurcol )
THEN
411 CALL zgesd2d( ictxt, mp, 1, a( iia+(jj-1)*lda ), lda,
413 work( 1 ) = dcmplx( dble( ipiv( jj ) ) )
414 work( 2 ) = dcmplx( rwork( jj ) )
415 work( 3 ) = dcmplx( rwork( jj + nq ) )
416 CALL zgesd2d( ictxt, 3, 1, work, 3, myrow, ipcol )
418 CALL zgerv2d( ictxt, mp, 1, a( iia+(jj-1)*lda ), lda,
420 CALL igerv2d( ictxt, 1, 1, ipiv( jj ), 1, myrow,
423 ELSE IF( mycol.EQ.ipcol )
THEN
425 CALL zgesd2d( ictxt, mp, 1, a( iia+(jjpvt-1)*lda ),
426 $ lda, myrow, icurcol )
427 CALL igesd2d( ictxt, 1, 1, ipiv( jjpvt ), 1, myrow,
430 CALL zgerv2d( ictxt, mp, 1, a( iia+(jjpvt-1)*lda ),
431 $ lda, myrow, icurcol )
432 CALL zgerv2d( ictxt, 3, 1, work, 3, myrow, icurcol )
433 ipiv( jjpvt ) = idint( dble( work( 1 ) ) )
434 rwork( jjpvt ) = dble( work( 2 ) )
435 rwork( jjpvt+nq ) = dble( work( 3 ) )
445 CALL infog1l( i, desca( mb_ ), nprow, myrow, desca( rsrc_ ),
447 IF( desca( m_ ).EQ.1 )
THEN
448 IF( myrow.EQ.icurrow )
THEN
449 IF( mycol.EQ.icurcol )
THEN
450 ioffa = ii+(jj-1)*desca( lld_ )
452 CALL zlarfg( 1, ajj, a( ioffa ), 1, tau( jj ) )
454 alpha =
cmplx( one ) - dconjg( tau( jj ) )
455 CALL zgebs2d( ictxt,
'Rowwise',
' ', 1, 1, alpha,
457 CALL zscal( nq-jj, alpha, a( ioffa+desca( lld_ ) ),
460 CALL zgebs2d( ictxt,
'Columnwise',
' ', 1, 1,
465 CALL zgebr2d( ictxt,
'Rowwise',
' ', 1, 1, alpha,
466 $ 1, icurrow, icurcol )
467 CALL zscal( nq-jj+1, alpha, a( i ), desca( lld_ ) )
470 ELSE IF( mycol.EQ.icurcol )
THEN
471 CALL zgebr2d( ictxt,
'Columnwise',
' ', 1, 1, tau( jj ),
472 $ 1, icurrow, icurcol )
477 CALL pzlarfg( m-j+ja, ajj, i, j, a,
min( i+1, ia+m-1 ), j,
479 IF( j.LT.ja+n-1 )
THEN
483 CALL pzelset( a, i, j, desca, dcmplx( one ) )
484 CALL pzlarfc(
'Left', m-j+ja, ja+n-1-j, a, i, j, desca,
485 $ 1, tau, a, i, j+1, desca, work )
487 CALL pzelset( a, i, j, desca, ajj )
493 IF( mycol.EQ.icurcol )
495 IF( mod( j, desca( nb_ ) ).EQ.0 )
496 $ icurcol = mod( icurcol+1, npcol )
497 IF( (jja+nq-jj).GT.0 )
THEN
498 IF( myrow.EQ.icurrow )
THEN
499 CALL zgebs2d( ictxt,
'Columnwise',
' ', 1, jja+nq-jj,
500 $ a( ii+(
min( jja+nq-1, jj )-1 )*lda ),
502 CALL zcopy( jja+nq-jj, a( ii+(
min( jja+nq-1, jj )
503 $ -1)*lda ), lda, work(
min( jja+nq-1, jj ) ),
506 CALL zgebr2d( ictxt,
'Columnwise',
' ', jja+nq-jj, 1,
507 $ work(
min( jja+nq-1, jj ) ),
max( 1, nq ),
512 jn =
min( iceil( j+1, desca( nb_ ) ) * desca( nb_ ),
514 IF( mycol.EQ.icurcol )
THEN
515 DO 90 ll = jj, jj + jn - j - 1
516 IF( rwork( ll ).NE.zero )
THEN
517 temp = abs( work( ll ) ) / rwork( ll )
518 temp =
max( zero, ( one+temp )*( one-temp ) )
519 temp2 = temp * ( rwork( ll ) / rwork( nq+ll ) )**2
520 IF( temp2.LE.tol3z )
THEN
521 IF( ia+m-1.GT.i )
THEN
522 CALL pdznrm2( ia+m-i-1, rwork( ll ), a,
523 $ i+1, j+ll-jj+1, desca, 1 )
524 rwork( nq+ll ) = rwork( ll )
527 rwork( nq+ll ) = zero
530 rwork( ll ) = rwork( ll ) * sqrt( temp )
536 icurcol = mod( icurcol+1, npcol )
538 DO 110 k = jn+1, ja+n-1, desca( nb_ )
539 kb =
min( ja+n-k, desca( nb_ ) )
541 IF( mycol.EQ.icurcol )
THEN
542 DO 100 ll = jj, jj+kb-1
543 IF( rwork(ll).NE.zero )
THEN
544 temp = abs( work( ll ) ) / rwork( ll )
545 temp =
max( zero, ( one+temp )*( one-temp ) )
546 temp2 = temp * ( rwork( ll ) / rwork( nq+ll ) )**2
547 IF( temp2.LE.tol3z )
THEN
548 IF( ia+m-1.GT.i )
THEN
549 CALL pdznrm2( ia+m-i-1, rwork( ll ), a,
550 $ i+1, k+ll-jj, desca, 1 )
551 rwork( nq+ll ) = rwork( ll )
554 rwork( nq+ll ) = zero
557 rwork( ll ) = rwork( ll ) * sqrt( temp )
563 icurcol = mod( icurcol+1, npcol )
569 work( 1 ) = dcmplx( dble( lwmin ) )
570 rwork( 1 ) = dble( lrwmin )