1 SUBROUTINE pslaqr2( WANTT, WANTZ, N, KTOP, KBOT, NW, A, DESCA,
2 $ ILOZ, IHIZ, Z, DESCZ, NS, ND, SR, SI, T, LDT,
3 $ V, LDV, WR, WI, WORK, LWORK )
15 INTEGER IHIZ, ILOZ, KBOT, KTOP, LDT, LDV, LWORK, N, ND,
20 INTEGER DESCA( * ), DESCZ( * )
21 REAL A( * ), SI( KBOT ), SR( KBOT ), T( LDT, * ),
22 $ v( ldv, * ), work( * ), wi( * ), wr( * ),
211 INTEGER BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
212 $ LLD_, MB_, M_, NB_, N_, RSRC_
213 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
214 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
215 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
217 PARAMETER ( ZERO = 0.0, one = 1.0 )
220 INTEGER CONTXT, HBL, I, I1, I2, IAFIRST, ICOL, ICOL1,
221 $ ICOL2, INFO, II, IROW, IROW1, IROW2, ITMP1,
222 $ itmp2, j, jafirst, jj, k, l, lda, ldz, lldtmp,
223 $ mycol, myrow, node, npcol, nprow, dblk,
224 $ hstep, vstep, kkrow, kkcol, kln, ltop, left,
225 $ right, up, down, d1, d2
228 INTEGER DESCT( 9 ), DESCV( 9 ), DESCWH( 9 ),
236 EXTERNAL blacs_gridinfo,
infog2l, slaset,
237 $ slaqr3,
descinit, psgemm, psgemr2d, sgemm,
238 $ slamov, sgesd2d, sgerv2d, sgebs2d, sgebr2d,
254 contxt = desca( ctxt_ )
256 iafirst = desca( rsrc_ )
257 jafirst = desca( csrc_ )
259 CALL blacs_gridinfo( contxt, nprow, npcol, myrow, mycol )
260 node = myrow*npcol + mycol
261 left = mod( mycol+npcol-1, npcol )
262 right = mod( mycol+1, npcol )
263 up = mod( myrow+nprow-1, nprow )
264 down = mod( myrow+1, nprow )
284 CALL infog2l( i-dblk+1, i-dblk+1, desca, nprow, npcol, myrow,
285 $ mycol, irow, icol, ii, jj )
286 IF ( myrow .EQ. ii )
THEN
287 CALL descinit( desct, dblk, dblk, dblk, dblk, ii, jj, contxt,
289 CALL descinit( descv, dblk, dblk, dblk, dblk, ii, jj, contxt,
292 CALL descinit( desct, dblk, dblk, dblk, dblk, ii, jj, contxt,
294 CALL descinit( descv, dblk, dblk, dblk, dblk, ii, jj, contxt,
297 CALL psgemr2d( dblk, dblk, a, i-dblk+1, i-dblk+1, desca, t, 1, 1,
299 IF ( myrow .EQ. ii .AND. mycol .EQ. jj )
THEN
300 CALL slaset(
'All', dblk, dblk, zero, one, v, ldv )
301 CALL slaqr3( .true., .true., dblk, 1, dblk, dblk-1, t, ldt, 1,
302 $ dblk, v, ldv, ns, nd, wr, wi, work, dblk, dblk,
303 $ work( dblk*dblk+1 ), dblk, dblk, work( 2*dblk*dblk+1 ),
304 $ dblk, work( 3*dblk*dblk+1 ), lwork-3*dblk*dblk )
305 CALL sgebs2d( contxt,
'All',
' ', dblk, dblk, v, ldv )
306 CALL igebs2d( contxt,
'All',
' ', 1, 1, nd, 1 )
308 CALL sgebr2d( contxt,
'All',
' ', dblk, dblk, v, ldv, ii, jj )
309 CALL igebr2d( contxt,
'All',
' ', 1, 1, nd, 1, ii, jj )
316 CALL psgemr2d( dblk, dblk, t, 1, 1, desct, a, i-dblk+1,
317 $ i-dblk+1, desca, contxt )
321 IF( mod( i-dblk, hbl )+dblk .LE. hbl )
THEN
333 CALL infog2l( i-dblk+1, i+1, desca, nprow, npcol, myrow,
334 $ mycol, irow, icol, ii, jj )
335 IF( myrow .EQ. ii )
THEN
336 icol1 = numroc( n, hbl, mycol, jafirst, npcol )
337 DO 10 kkcol = icol, icol1, hstep
338 kln =
min( hstep, icol1-kkcol+1 )
339 CALL sgemm(
'T',
'N', dblk, kln, dblk, one, v,
340 $ ldv, a( irow+(kkcol-1)*lda ), lda, zero, work,
342 CALL slamov(
'A', dblk, kln, work, dblk,
343 $ a( irow+(kkcol-1)*lda ), lda )
350 CALL infog2l( ltop, i-dblk+1, desca, nprow, npcol, myrow,
351 $ mycol, irow, icol, ii, jj )
352 IF( mycol .EQ. jj )
THEN
353 CALL infog2l( i-dblk, i-dblk+1, desca, nprow, npcol,
354 $ myrow, mycol, irow1, icol1, itmp1, itmp2 )
355 IF( myrow .NE. itmp1 ) irow1 = irow1-1
356 DO 20 kkrow = irow, irow1, vstep
357 kln =
min( vstep, irow1-kkrow+1 )
358 CALL sgemm(
'N',
'N', kln, dblk, dblk, one,
359 $ a( kkrow+(icol-1)*lda ), lda, v, ldv, zero, work,
361 CALL slamov(
'A', kln, dblk, work, kln,
362 $ a( kkrow+(icol-1)*lda ), lda )
369 CALL infog2l( iloz, i-dblk+1, descz, nprow, npcol, myrow,
370 $ mycol, irow, icol, ii, jj )
371 IF( mycol .EQ. jj )
THEN
372 CALL infog2l( ihiz, i-dblk+1, descz, nprow, npcol,
373 $ myrow, mycol, irow1, icol1, itmp1, itmp2 )
374 IF( myrow .NE. itmp1 ) irow1 = irow1-1
375 DO 30 kkrow = irow, irow1, vstep
376 kln =
min( vstep, irow1-kkrow+1 )
377 CALL sgemm(
'N',
'N', kln, dblk, dblk, one,
378 $ z( kkrow+(icol-1)*ldz ), ldz, v, ldv, zero,
380 CALL slamov(
'A', kln, dblk, work, kln,
381 $ z( kkrow+(icol-1)*ldz ), ldz )
386 ELSE IF( mod( i-dblk, hbl )+dblk .LE. 2*hbl )
THEN
392 d1 = hbl - mod( i-dblk, hbl )
400 CALL infog2l( i-dblk+1, i+1, desca, nprow, npcol, myrow,
401 $ mycol, irow, icol, ii, jj )
402 IF( myrow .EQ. up )
THEN
403 IF( myrow .EQ. ii )
THEN
404 icol1 = numroc( n, hbl, mycol, jafirst, npcol )
405 DO 40 kkcol = icol, icol1, hstep
406 kln =
min( hstep, icol1-kkcol+1 )
407 CALL sgemm(
'T',
'N', dblk, kln, dblk, one, v,
408 $ dblk, a( irow+(kkcol-1)*lda ), lda, zero,
410 CALL slamov(
'A', dblk, kln, work, dblk,
411 $ a( irow+(kkcol-1)*lda ), lda )
415 IF( myrow .EQ. ii )
THEN
416 icol1 = numroc( n, hbl, mycol, jafirst, npcol )
417 DO 50 kkcol = icol, icol1, hstep
418 kln =
min( hstep, icol1-kkcol+1 )
419 CALL sgemm(
'T',
'N', d2, kln, d1, one,
420 $ v( 1, d1+1 ), ldv, a( irow+(kkcol-1)*lda ),
421 $ lda, zero, work( d1+1 ), dblk )
422 CALL sgesd2d( contxt, d2, kln, work( d1+1 ),
423 $ dblk, down, mycol )
424 CALL sgerv2d( contxt, d1, kln, work, dblk, down,
426 CALL sgemm(
'T',
'N', d1, kln, d1, one,
427 $ v, ldv, a( irow+(kkcol-1)*lda ), lda, one,
429 CALL slamov(
'A', d1, kln, work, dblk,
430 $ a( irow+(kkcol-1)*lda ), lda )
432 ELSE IF( up .EQ. ii )
THEN
433 icol1 = numroc( n, hbl, mycol, jafirst, npcol )
434 DO 60 kkcol = icol, icol1, hstep
435 kln =
min( hstep, icol1-kkcol+1 )
436 CALL sgemm(
'T',
'N', d1, kln, d2, one,
437 $ v( d1+1, 1 ), ldv, a( irow+(kkcol-1)*lda ),
438 $ lda, zero, work, dblk )
439 CALL sgesd2d( contxt, d1, kln, work, dblk, up,
441 CALL sgerv2d( contxt, d2, kln, work( d1+1 ),
443 CALL sgemm(
'T',
'N', d2, kln, d2, one,
444 $ v( d1+1, d1+1 ), ldv,
445 $ a( irow+(kkcol-1)*lda ), lda, one,
446 $ work( d1+1 ), dblk )
447 CALL slamov(
'A', d2, kln, work( d1+1 ), dblk,
448 $ a( irow+(kkcol-1)*lda ), lda )
456 CALL infog2l( ltop, i-dblk+1, desca, nprow, npcol, myrow,
457 $ mycol, irow, icol, ii, jj )
458 IF( mycol .EQ. left )
THEN
459 IF( mycol .EQ. jj )
THEN
460 CALL infog2l( i-dblk, i-dblk+1, desca, nprow, npcol,
461 $ myrow, mycol, irow1, icol1, itmp1, itmp2 )
462 IF( myrow .NE. itmp1 ) irow1 = irow1-1
463 DO 70 kkrow = irow, irow1, vstep
464 kln =
min( vstep, irow1-kkrow+1 )
465 CALL sgemm(
'N',
'N', kln, dblk, dblk, one,
466 $ a( kkrow+(icol-1)*lda ), lda, v, ldv, zero,
468 CALL slamov(
'A', kln, dblk, work, kln,
469 $ a( kkrow+(icol-1)*lda ), lda )
473 IF( mycol .EQ. jj )
THEN
474 CALL infog2l( i-dblk, i-dblk+1, desca, nprow, npcol,
475 $ myrow, mycol, irow1, icol1, itmp1, itmp2 )
476 IF( myrow .NE. itmp1 ) irow1 = irow1-1
477 DO 80 kkrow = irow, irow1, vstep
478 kln =
min( vstep, irow1-kkrow+1 )
479 CALL sgemm(
'N',
'N', kln, d2, d1, one,
480 $ a( kkrow+(icol-1)*lda ), lda,
481 $ v( 1, d1+1 ), ldv, zero, work( 1+d1*kln ),
483 CALL sgesd2d( contxt, kln, d2, work( 1+d1*kln ),
484 $ kln, myrow, right )
485 CALL sgerv2d( contxt, kln, d1, work, kln, myrow,
487 CALL sgemm(
'N',
'N', kln, d1, d1, one,
488 $ a( kkrow+(icol-1)*lda ), lda, v, ldv, one,
490 CALL slamov(
'A', kln, d1, work, kln,
491 $ a( kkrow+(icol-1)*lda ), lda )
493 ELSE IF ( left .EQ. jj )
THEN
494 CALL infog2l( i-dblk, i-dblk+1, desca, nprow, npcol,
495 $ myrow, mycol, irow1, icol1, itmp1, itmp2 )
496 IF( myrow .NE. itmp1 ) irow1 = irow1-1
497 DO 90 kkrow = irow, irow1, vstep
498 kln =
min( vstep, irow1-kkrow+1 )
499 CALL sgemm(
'N',
'N', kln, d1, d2, one,
500 $ a( kkrow+(icol-1)*lda ), lda, v( d1+1, 1 ),
501 $ ldv, zero, work, kln )
502 CALL sgesd2d( contxt, kln, d1, work, kln, myrow,
504 CALL sgerv2d( contxt, kln, d2, work( 1+d1*kln ),
506 CALL sgemm(
'N',
'N', kln, d2, d2, one,
507 $ a( kkrow+(icol-1)*lda ), lda, v( d1+1, d1+1 ),
508 $ ldv, one, work( 1+d1*kln ), kln )
509 CALL slamov(
'A', kln, d2, work( 1+d1*kln ), kln,
510 $ a( kkrow+(icol-1)*lda ), lda )
518 CALL infog2l( iloz, i-dblk+1, descz, nprow, npcol, myrow,
519 $ mycol, irow, icol, ii, jj )
520 IF( mycol .EQ. left )
THEN
521 IF( mycol .EQ. jj )
THEN
522 CALL infog2l( ihiz, i-dblk+1, descz, nprow, npcol,
523 $ myrow, mycol, irow1, icol1, itmp1, itmp2 )
524 IF( myrow .NE. itmp1 ) irow1 = irow1-1
525 DO 100 kkrow = irow, irow1, vstep
526 kln =
min( vstep, irow1-kkrow+1 )
527 CALL sgemm(
'N',
'N', kln, dblk, dblk, one,
528 $ z( kkrow+(icol-1)*ldz ), ldz, v, ldv, zero,
530 CALL slamov(
'A', kln, dblk, work, kln,
531 $ z( kkrow+(icol-1)*ldz ), ldz )
535 IF( mycol .EQ. jj )
THEN
536 CALL infog2l( ihiz, i-dblk+1, descz, nprow, npcol,
537 $ myrow, mycol, irow1, icol1, itmp1, itmp2 )
538 IF( myrow .NE. itmp1 ) irow1 = irow1-1
539 DO 110 kkrow = irow, irow1, vstep
540 kln =
min( vstep, irow1-kkrow+1 )
541 CALL sgemm(
'N',
'N', kln, d2, d1, one,
542 $ z( kkrow+(icol-1)*ldz ), ldz,
543 $ v( 1, d1+1 ), ldv, zero, work( 1+d1*kln ),
545 CALL sgesd2d( contxt, kln, d2, work( 1+d1*kln ),
546 $ kln, myrow, right )
547 CALL sgerv2d( contxt, kln, d1, work, kln, myrow,
549 CALL sgemm(
'N',
'N', kln, d1, d1, one,
550 $ z( kkrow+(icol-1)*ldz ), ldz, v, ldv, one,
552 CALL slamov(
'A', kln, d1, work, kln,
553 $ z( kkrow+(icol-1)*ldz ), ldz )
555 ELSE IF( left .EQ. jj )
THEN
556 CALL infog2l( ihiz, i-dblk+1, descz, nprow, npcol,
557 $ myrow, mycol, irow1, icol1, itmp1, itmp2 )
558 IF( myrow .NE. itmp1 ) irow1 = irow1-1
559 DO 120 kkrow = irow, irow1, vstep
560 kln =
min( vstep, irow1-kkrow+1 )
561 CALL sgemm(
'N',
'N', kln, d1, d2, one,
562 $ z( kkrow+(icol-1)*ldz ), ldz,
563 $ v( d1+1, 1 ), ldv, zero, work, kln )
564 CALL sgesd2d( contxt, kln, d1, work, kln, myrow,
566 CALL sgerv2d( contxt, kln, d2, work( 1+d1*kln ),
568 CALL sgemm(
'N',
'N', kln, d2, d2, one,
569 $ z( kkrow+(icol-1)*ldz ), ldz,
570 $ v( d1+1, d1+1 ), ldv, one,
571 $ work( 1+d1*kln ), kln )
572 CALL slamov(
'A', kln, d2, work( 1+d1*kln ),
573 $ kln, z( kkrow+(icol-1)*ldz ), ldz )
585 hstep = lwork / dblk * npcol
586 vstep = lwork / dblk * nprow
587 lldtmp = numroc( dblk, dblk, myrow, 0, nprow )
588 lldtmp =
max( 1, lldtmp )
589 CALL descinit( descv, dblk, dblk, dblk, dblk, 0, 0, contxt,
591 CALL descinit( descwh, dblk, hstep, dblk, lwork / dblk, 0,
592 $ 0, contxt, lldtmp, info )
597 DO 130 kkcol = i+1, n, hstep
598 kln =
min( hstep, n-kkcol+1 )
599 CALL psgemm(
'T',
'N', dblk, kln, dblk, one, v, 1, 1,
600 $ descv, a, i-dblk+1, kkcol, desca, zero, work, 1,
602 CALL psgemr2d( dblk, kln, work, 1, 1, descwh, a,
603 $ i-dblk+1, kkcol, desca, contxt )
609 DO 140 kkrow = ltop, i-dblk, vstep
610 kln =
min( vstep, i-dblk-kkrow+1 )
611 lldtmp = numroc( kln, lwork / dblk, myrow, 0, nprow )
612 lldtmp =
max( 1, lldtmp )
613 CALL descinit( descwv, kln, dblk, lwork / dblk, dblk, 0,
614 $ 0, contxt, lldtmp, info )
615 CALL psgemm(
'N',
'N', kln, dblk, dblk, one, a, kkrow,
616 $ i-dblk+1, desca, v, 1, 1, descv, zero, work, 1, 1,
618 CALL psgemr2d( kln, dblk, work, 1, 1, descwv, a, kkrow,
619 $ i-dblk+1, desca, contxt )
625 DO 150 kkrow = iloz, ihiz, vstep
626 kln =
min( vstep, ihiz-kkrow+1 )
627 lldtmp = numroc( kln, lwork / dblk, myrow, 0, nprow )
628 lldtmp =
max( 1, lldtmp )
629 CALL descinit( descwv, kln, dblk, lwork / dblk, dblk,
630 $ 0, 0, contxt, lldtmp, info )
631 CALL psgemm(
'N',
'N', kln, dblk, dblk, one, z, kkrow,
632 $ i-dblk+1, descz, v, 1, 1, descv, zero, work, 1,
634 CALL psgemr2d( kln, dblk, work, 1, 1, descwv, z,
635 $ kkrow, i-dblk+1, descz, contxt )
644 IF( ii .EQ. nd-1 .OR. wi( dblk-ii ) .EQ. zero )
THEN
645 IF( node .EQ. 0 )
THEN
646 sr( i-ii ) = wr( dblk-ii )
653 IF( node .EQ. 0 )
THEN
654 sr( i-ii-1 ) = wr( dblk-ii-1 )
655 sr( i-ii ) = wr( dblk-ii )
656 si( i-ii-1 ) = wi( dblk-ii-1 )
657 si( i-ii ) = wi( dblk-ii )
666 IF( ii .LT. nd )
GOTO 160