1 SUBROUTINE pslaqr4( WANTT, WANTZ, N, ILO, IHI, A, DESCA, WR, WI,
2 $ ILOZ, IHIZ, Z, DESCZ, T, LDT, V, LDV, WORK,
16 INTEGER IHI, IHIZ, ILO, ILOZ, INFO, LDT, LDV, LWORK, N
19 INTEGER DESCA( * ), DESCZ( * )
20 REAL A( * ), T( LDT, * ), V( LDV, * ), WI( * ),
21 $ work( * ), wr( * ), z( * )
196 INTEGER BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
197 $ LLD_, MB_, M_, NB_, N_, RSRC_
198 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
199 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
200 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
202 PARAMETER ( ZERO = 0.0, one = 1.0 )
205 INTEGER CONTXT, HBL, I, I1, I2, IAFIRST, ICOL, ICOL1,
206 $ ICOL2, II, IROW, IROW1, IROW2, ITMP1, ITMP2,
207 $ ierr, j, jafirst, jj, k, l, lda, ldz, lldtmp,
208 $ mycol, myrow, node, npcol, nprow, nh, nmin, nz,
209 $ hstep, vstep, kkrow, kkcol, kln, ltop, left,
210 $ right, up, down, d1, d2
213 INTEGER DESCT( 9 ), DESCV( 9 ), DESCWH( 9 ),
217 INTEGER NUMROC, ILAENV
218 EXTERNAL NUMROC, ILAENV
221 EXTERNAL blacs_gridinfo,
infog2l, slaset,
222 $ slahqr, slaqr4,
descinit, psgemm, psgemr2d,
223 $ sgemm, slamov, sgesd2d, sgerv2d,
224 $ sgebs2d, sgebr2d, igebs2d, igebr2d
235 IF( n.EQ.0 .OR. nh.EQ.0 )
241 contxt = desca( ctxt_ )
243 iafirst = desca( rsrc_ )
244 jafirst = desca( csrc_ )
246 CALL blacs_gridinfo( contxt, nprow, npcol, myrow, mycol )
247 node = myrow*npcol + mycol
248 left = mod( mycol+npcol-1, npcol )
249 right = mod( mycol+1, npcol )
250 up = mod( myrow+nprow-1, nprow )
251 down = mod( myrow+1, nprow )
270 CALL infog2l( ilo, ilo, desca, nprow, npcol, myrow, mycol,
271 $ irow, icol, ii, jj )
272 IF ( myrow .EQ. ii )
THEN
273 CALL descinit( desct, nh, nh, nh, nh, ii, jj, contxt,
275 CALL descinit( descv, nh, nh, nh, nh, ii, jj, contxt,
278 CALL descinit( desct, nh, nh, nh, nh, ii, jj, contxt,
280 CALL descinit( descv, nh, nh, nh, nh, ii, jj, contxt,
283 CALL psgemr2d( nh, nh, a, ilo, ilo, desca, t, 1, 1, desct,
285 IF ( myrow .EQ. ii .AND. mycol .EQ. jj )
THEN
286 CALL slaset(
'All', nh, nh, zero, one, v, ldv )
287 nmin = ilaenv( 12,
'SLAQR3',
'SV', nh, 1, nh, lwork )
288 IF( nh .GT. nmin )
THEN
289 CALL slaqr4( .true., .true., nh, 1, nh, t, ldt, wr( ilo ),
290 $ wi( ilo ), 1, nh, v, ldv, work, lwork, info )
292 CALL slaset(
'L', nh-2, nh-2, zero, zero, t( 3, 1 ), ldt )
294 CALL slahqr( .true., .true., nh, 1, nh, t, ldt, wr( ilo ),
295 $ wi( ilo ), 1, nh, v, ldv, info )
297 CALL sgebs2d( contxt,
'All',
' ', nh, nh, v, ldv )
298 CALL igebs2d( contxt,
'All',
' ', 1, 1, info, 1 )
300 CALL sgebr2d( contxt,
'All',
' ', nh, nh, v, ldv, ii, jj )
301 CALL igebr2d( contxt,
'All',
' ', 1, 1, info, 1, ii, jj )
303 IF( info .NE. 0 ) info = info+ilo-1
307 CALL psgemr2d( nh, nh, t, 1, 1, desct, a, ilo, ilo, desca,
312 IF( mod( ilo-1, hbl )+nh .LE. hbl )
THEN
324 CALL infog2l( ilo, i+1, desca, nprow, npcol, myrow,
325 $ mycol, irow, icol, ii, jj )
326 IF( myrow .EQ. ii )
THEN
327 icol1 = numroc( n, hbl, mycol, jafirst, npcol )
328 DO 10 kkcol = icol, icol1, hstep
329 kln =
min( hstep, icol1-kkcol+1 )
330 CALL sgemm(
'T',
'N', nh, kln, nh, one, v,
331 $ ldv, a( irow+(kkcol-1)*lda ), lda, zero, work,
333 CALL slamov(
'A', nh, kln, work, nh,
334 $ a( irow+(kkcol-1)*lda ), lda )
340 CALL infog2l( ltop, ilo, desca, nprow, npcol, myrow,
341 $ mycol, irow, icol, ii, jj )
342 IF( mycol .EQ. jj )
THEN
343 CALL infog2l( ilo-1, ilo, desca, nprow, npcol,
344 $ myrow, mycol, irow1, icol1, itmp1, itmp2 )
345 IF( myrow .NE. itmp1 ) irow1 = irow1-1
346 DO 20 kkrow = irow, irow1, vstep
347 kln =
min( vstep, irow1-kkrow+1 )
348 CALL sgemm(
'N',
'N', kln, nh, nh, one,
349 $ a( kkrow+(icol-1)*lda ), lda, v, ldv, zero,
351 CALL slamov(
'A', kln, nh, work, kln,
352 $ a( kkrow+(icol-1)*lda ), lda )
360 CALL infog2l( iloz, ilo, descz, nprow, npcol, myrow,
361 $ mycol, irow, icol, ii, jj )
362 IF( mycol .EQ. jj )
THEN
363 CALL infog2l( ihiz, ilo, descz, nprow, npcol,
364 $ myrow, mycol, irow1, icol1, itmp1, itmp2 )
365 IF( myrow .NE. itmp1 ) irow1 = irow1-1
366 DO 30 kkrow = irow, irow1, vstep
367 kln =
min( vstep, irow1-kkrow+1 )
368 CALL sgemm(
'N',
'N', kln, nh, nh, one,
369 $ z( kkrow+(icol-1)*ldz ), ldz, v, ldv, zero,
371 CALL slamov(
'A', kln, nh, work, kln,
372 $ z( kkrow+(icol-1)*ldz ), ldz )
377 ELSE IF( mod( ilo-1, hbl )+nh .LE. 2*hbl )
THEN
383 d1 = hbl - mod( ilo-1, hbl )
392 CALL infog2l( ilo, i+1, desca, nprow, npcol, myrow,
393 $ mycol, irow, icol, ii, jj )
394 IF( myrow .EQ. up )
THEN
395 IF( myrow .EQ. ii )
THEN
396 icol1 = numroc( n, hbl, mycol, jafirst, npcol )
397 DO 40 kkcol = icol, icol1, hstep
398 kln =
min( hstep, icol1-kkcol+1 )
399 CALL sgemm(
'T',
'N', nh, kln, nh, one, v,
400 $ nh, a( irow+(kkcol-1)*lda ), lda, zero,
402 CALL slamov(
'A', nh, kln, work, nh,
403 $ a( irow+(kkcol-1)*lda ), lda )
407 IF( myrow .EQ. ii )
THEN
408 icol1 = numroc( n, hbl, mycol, jafirst, npcol )
409 DO 50 kkcol = icol, icol1, hstep
410 kln =
min( hstep, icol1-kkcol+1 )
411 CALL sgemm(
'T',
'N', d2, kln, d1, one,
412 $ v( 1, d1+1 ), ldv, a( irow+(kkcol-1)*lda ),
413 $ lda, zero, work( d1+1 ), nh )
414 CALL sgesd2d( contxt, d2, kln, work( d1+1 ),
416 CALL sgerv2d( contxt, d1, kln, work, nh, down,
418 CALL sgemm(
'T',
'N', d1, kln, d1, one,
419 $ v, ldv, a( irow+(kkcol-1)*lda ), lda, one,
421 CALL slamov(
'A', d1, kln, work, nh,
422 $ a( irow+(kkcol-1)*lda ), lda )
424 ELSE IF( up .EQ. ii )
THEN
425 icol1 = numroc( n, hbl, mycol, jafirst, npcol )
426 DO 60 kkcol = icol, icol1, hstep
427 kln =
min( hstep, icol1-kkcol+1 )
428 CALL sgemm(
'T',
'N', d1, kln, d2, one,
429 $ v( d1+1, 1 ), ldv, a( irow+(kkcol-1)*lda ),
430 $ lda, zero, work, nh )
431 CALL sgesd2d( contxt, d1, kln, work, nh, up,
433 CALL sgerv2d( contxt, d2, kln, work( d1+1 ),
435 CALL sgemm(
'T',
'N', d2, kln, d2, one,
436 $ v( d1+1, d1+1 ), ldv,
437 $ a( irow+(kkcol-1)*lda ), lda, one,
439 CALL slamov(
'A', d2, kln, work( d1+1 ), nh,
440 $ a( irow+(kkcol-1)*lda ), lda )
447 CALL infog2l( ltop, ilo, desca, nprow, npcol, myrow,
448 $ mycol, irow, icol, ii, jj )
449 IF( mycol .EQ. left )
THEN
450 IF( mycol .EQ. jj )
THEN
451 CALL infog2l( ilo-1, ilo, desca, nprow, npcol,
452 $ myrow, mycol, irow1, icol1, itmp1, itmp2 )
453 IF( myrow .NE. itmp1 ) irow1 = irow1-1
454 DO 70 kkrow = irow, irow1, vstep
455 kln =
min( vstep, irow1-kkrow+1 )
456 CALL sgemm(
'N',
'N', kln, nh, nh, one,
457 $ a( kkrow+(icol-1)*lda ), lda, v, ldv,
459 CALL slamov(
'A', kln, nh, work, kln,
460 $ a( kkrow+(icol-1)*lda ), lda )
464 IF( mycol .EQ. jj )
THEN
465 CALL infog2l( ilo-1, ilo, desca, nprow, npcol,
466 $ myrow, mycol, irow1, icol1, itmp1, itmp2 )
467 IF( myrow .NE. itmp1 ) irow1 = irow1-1
468 DO 80 kkrow = irow, irow1, vstep
469 kln =
min( vstep, irow1-kkrow+1 )
470 CALL sgemm(
'N',
'N', kln, d2, d1, one,
471 $ a( kkrow+(icol-1)*lda ), lda, v( 1, d1+1 ),
472 $ ldv, zero, work( 1+d1*kln ), kln )
473 CALL sgesd2d( contxt, kln, d2, work( 1+d1*kln ),
474 $ kln, myrow, right )
475 CALL sgerv2d( contxt, kln, d1, work, kln, myrow,
477 CALL sgemm(
'N',
'N', kln, d1, d1, one,
478 $ a( kkrow+(icol-1)*lda ), lda, v, ldv, one,
480 CALL slamov(
'A', kln, d1, work, kln,
481 $ a( kkrow+(icol-1)*lda ), lda )
483 ELSE IF ( left .EQ. jj )
THEN
484 CALL infog2l( ilo-1, ilo, desca, nprow, npcol,
485 $ myrow, mycol, irow1, icol1, itmp1, itmp2 )
486 IF( myrow .NE. itmp1 ) irow1 = irow1-1
487 DO 90 kkrow = irow, irow1, vstep
488 kln =
min( vstep, irow1-kkrow+1 )
489 CALL sgemm(
'N',
'N', kln, d1, d2, one,
490 $ a( kkrow+(icol-1)*lda ), lda, v( d1+1, 1 ),
491 $ ldv, zero, work, kln )
492 CALL sgesd2d( contxt, kln, d1, work, kln, myrow,
494 CALL sgerv2d( contxt, kln, d2, work( 1+d1*kln ),
496 CALL sgemm(
'N',
'N', kln, d2, d2, one,
497 $ a( kkrow+(icol-1)*lda ), lda, v( d1+1, d1+1 ),
498 $ ldv, one, work( 1+d1*kln ), kln )
499 CALL slamov(
'A', kln, d2, work( 1+d1*kln ), kln,
500 $ a( kkrow+(icol-1)*lda ), lda )
509 CALL infog2l( iloz, ilo, descz, nprow, npcol, myrow,
510 $ mycol, irow, icol, ii, jj )
511 IF( mycol .EQ. left )
THEN
512 IF( mycol .EQ. jj )
THEN
513 CALL infog2l( ihiz, ilo, descz, nprow, npcol,
514 $ myrow, mycol, irow1, icol1, itmp1, itmp2 )
515 IF( myrow .NE. itmp1 ) irow1 = irow1-1
516 DO 100 kkrow = irow, irow1, vstep
517 kln =
min( vstep, irow1-kkrow+1 )
518 CALL sgemm(
'N',
'N', kln, nh, nh, one,
519 $ z( kkrow+(icol-1)*ldz ), ldz, v, ldv, zero,
521 CALL slamov(
'A', kln, nh, work, kln,
522 $ z( kkrow+(icol-1)*ldz ), ldz )
526 IF( mycol .EQ. jj )
THEN
527 CALL infog2l( ihiz, ilo, descz, nprow, npcol,
528 $ myrow, mycol, irow1, icol1, itmp1, itmp2 )
529 IF( myrow .NE. itmp1 ) irow1 = irow1-1
530 DO 110 kkrow = irow, irow1, vstep
531 kln =
min( vstep, irow1-kkrow+1 )
532 CALL sgemm(
'N',
'N', kln, d2, d1, one,
533 $ z( kkrow+(icol-1)*ldz ), ldz, v( 1, d1+1 ),
534 $ ldv, zero, work( 1+d1*kln ), kln )
535 CALL sgesd2d( contxt, kln, d2, work( 1+d1*kln ),
536 $ kln, myrow, right )
537 CALL sgerv2d( contxt, kln, d1, work, kln, myrow,
539 CALL sgemm(
'N',
'N', kln, d1, d1, one,
540 $ z( kkrow+(icol-1)*ldz ), ldz, v, ldv, one,
542 CALL slamov(
'A', kln, d1, work, kln,
543 $ z( kkrow+(icol-1)*ldz ), ldz )
545 ELSE IF( left .EQ. jj )
THEN
546 CALL infog2l( ihiz, ilo, descz, nprow, npcol,
547 $ myrow, mycol, irow1, icol1, itmp1, itmp2 )
548 IF( myrow .NE. itmp1 ) irow1 = irow1-1
549 DO 120 kkrow = irow, irow1, vstep
550 kln =
min( vstep, irow1-kkrow+1 )
551 CALL sgemm(
'N',
'N', kln, d1, d2, one,
552 $ z( kkrow+(icol-1)*ldz ), ldz, v( d1+1, 1 ),
553 $ ldv, zero, work, kln )
554 CALL sgesd2d( contxt, kln, d1, work, kln, myrow,
556 CALL sgerv2d( contxt, kln, d2, work( 1+d1*kln ),
558 CALL sgemm(
'N',
'N', kln, d2, d2, one,
559 $ z( kkrow+(icol-1)*ldz ), ldz,
560 $ v( d1+1, d1+1 ), ldv, one, work( 1+d1*kln ),
562 CALL slamov(
'A', kln, d2, work( 1+d1*kln ),
563 $ kln, z( kkrow+(icol-1)*ldz ), ldz )
575 hstep = lwork / nh * npcol
576 vstep = lwork / nh * nprow
577 lldtmp = numroc( nh, nh, myrow, 0, nprow )
578 lldtmp =
max( 1, lldtmp )
579 CALL descinit( descv, nh, nh, nh, nh, 0, 0, contxt,
581 CALL descinit( descwh, nh, hstep, nh, lwork / nh, 0, 0,
582 $ contxt, lldtmp, ierr )
588 DO 130 kkcol = i+1, n, hstep
589 kln =
min( hstep, n-kkcol+1 )
590 CALL psgemm(
'T',
'N', nh, kln, nh, one, v, 1, 1,
591 $ descv, a, ilo, kkcol, desca, zero, work, 1, 1,
593 CALL psgemr2d( nh, kln, work, 1, 1, descwh, a,
594 $ ilo, kkcol, desca, contxt )
599 DO 140 kkrow = ltop, ilo-1, vstep
600 kln =
min( vstep, ilo-kkrow )
601 lldtmp = numroc( kln, lwork / nh, myrow, 0, nprow )
602 lldtmp =
max( 1, lldtmp )
603 CALL descinit( descwv, kln, nh, lwork / nh, nh, 0, 0,
604 $ contxt, lldtmp, ierr )
605 CALL psgemm(
'N',
'N', kln, nh, nh, one, a, kkrow,
606 $ ilo, desca, v, 1, 1, descv, zero, work, 1, 1,
608 CALL psgemr2d( kln, nh, work, 1, 1, descwv, a, kkrow,
609 $ ilo, desca, contxt )
616 DO 150 kkrow = iloz, ihiz, vstep
617 kln =
min( vstep, ihiz-kkrow+1 )
618 lldtmp = numroc( kln, lwork / nh, myrow, 0, nprow )
619 lldtmp =
max( 1, lldtmp )
620 CALL descinit( descwv, kln, nh, lwork / nh, nh, 0, 0,
621 $ contxt, lldtmp, ierr )
622 CALL psgemm(
'N',
'N', kln, nh, nh, one, z, kkrow,
623 $ ilo, descz, v, 1, 1, descv, zero, work, 1, 1,
625 CALL psgemr2d( kln, nh, work, 1, 1, descwv, z,
626 $ kkrow, ilo, descz, contxt )