1 SUBROUTINE pdlaqr4( 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 DOUBLE PRECISION 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 )
201 DOUBLE PRECISION ZERO, ONE
202 PARAMETER ( ZERO = 0.0d+0, one = 1.0d+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, dlaset,
222 $ dlahqr, dlaqr4,
descinit, pdgemm, pdgemr2d,
223 $ dgemm, dlamov, dgesd2d, dgerv2d,
224 $ dgebs2d, dgebr2d, 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 pdgemr2d( nh, nh, a, ilo, ilo, desca, t, 1, 1, desct,
285 IF ( myrow .EQ. ii .AND. mycol .EQ. jj )
THEN
286 CALL dlaset(
'All', nh, nh, zero, one, v, ldv )
287 nmin = ilaenv( 12,
'DLAQR3',
'SV', nh, 1, nh, lwork )
288 IF( nh .GT. nmin )
THEN
289 CALL dlaqr4( .true., .true., nh, 1, nh, t, ldt, wr( ilo ),
290 $ wi( ilo ), 1, nh, v, ldv, work, lwork, info )
292 CALL dlaset(
'L', nh-2, nh-2, zero, zero, t( 3, 1 ), ldt )
294 CALL dlahqr( .true., .true., nh, 1, nh, t, ldt, wr( ilo ),
295 $ wi( ilo ), 1, nh, v, ldv, info )
297 CALL dgebs2d( contxt,
'All',
' ', nh, nh, v, ldv )
298 CALL igebs2d( contxt,
'All',
' ', 1, 1, info, 1 )
300 CALL dgebr2d( 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 pdgemr2d( 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 dgemm(
'T',
'N', nh, kln, nh, one, v,
331 $ ldv, a( irow+(kkcol-1)*lda ), lda, zero, work,
333 CALL dlamov(
'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 dgemm(
'N',
'N', kln, nh, nh, one,
349 $ a( kkrow+(icol-1)*lda ), lda, v, ldv, zero,
351 CALL dlamov(
'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 dgemm(
'N',
'N', kln, nh, nh, one,
369 $ z( kkrow+(icol-1)*ldz ), ldz, v, ldv, zero,
371 CALL dlamov(
'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 dgemm(
'T',
'N', nh, kln, nh, one, v,
400 $ nh, a( irow+(kkcol-1)*lda ), lda, zero,
402 CALL dlamov(
'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 dgemm(
'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 dgesd2d( contxt, d2, kln, work( d1+1 ),
416 CALL dgerv2d( contxt, d1, kln, work, nh, down,
418 CALL dgemm(
'T',
'N', d1, kln, d1, one,
419 $ v, ldv, a( irow+(kkcol-1)*lda ), lda, one,
421 CALL dlamov(
'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 dgemm(
'T',
'N', d1, kln, d2, one,
429 $ v( d1+1, 1 ), ldv, a( irow+(kkcol-1)*lda ),
430 $ lda, zero, work, nh )
431 CALL dgesd2d( contxt, d1, kln, work, nh, up,
433 CALL dgerv2d( contxt, d2, kln, work( d1+1 ),
435 CALL dgemm(
'T',
'N', d2, kln, d2, one,
436 $ v( d1+1, d1+1 ), ldv,
437 $ a( irow+(kkcol-1)*lda ), lda, one,
439 CALL dlamov(
'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 dgemm(
'N',
'N', kln, nh, nh, one,
457 $ a( kkrow+(icol-1)*lda ), lda, v, ldv,
459 CALL dlamov(
'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 dgemm(
'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 dgesd2d( contxt, kln, d2, work( 1+d1*kln ),
474 $ kln, myrow, right )
475 CALL dgerv2d( contxt, kln, d1, work, kln, myrow,
477 CALL dgemm(
'N',
'N', kln, d1, d1, one,
478 $ a( kkrow+(icol-1)*lda ), lda, v, ldv, one,
480 CALL dlamov(
'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 dgemm(
'N',
'N', kln, d1, d2, one,
490 $ a( kkrow+(icol-1)*lda ), lda, v( d1+1, 1 ),
491 $ ldv, zero, work, kln )
492 CALL dgesd2d( contxt, kln, d1, work, kln, myrow,
494 CALL dgerv2d( contxt, kln, d2, work( 1+d1*kln ),
496 CALL dgemm(
'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 dlamov(
'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 dgemm(
'N',
'N', kln, nh, nh, one,
519 $ z( kkrow+(icol-1)*ldz ), ldz, v, ldv, zero,
521 CALL dlamov(
'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 dgemm(
'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 dgesd2d( contxt, kln, d2, work( 1+d1*kln ),
536 $ kln, myrow, right )
537 CALL dgerv2d( contxt, kln, d1, work, kln, myrow,
539 CALL dgemm(
'N',
'N', kln, d1, d1, one,
540 $ z( kkrow+(icol-1)*ldz ), ldz, v, ldv, one,
542 CALL dlamov(
'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 dgemm(
'N',
'N', kln, d1, d2, one,
552 $ z( kkrow+(icol-1)*ldz ), ldz, v( d1+1, 1 ),
553 $ ldv, zero, work, kln )
554 CALL dgesd2d( contxt, kln, d1, work, kln, myrow,
556 CALL dgerv2d( contxt, kln, d2, work( 1+d1*kln ),
558 CALL dgemm(
'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 dlamov(
'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 pdgemm(
'T',
'N', nh, kln, nh, one, v, 1, 1,
591 $ descv, a, ilo, kkcol, desca, zero, work, 1, 1,
593 CALL pdgemr2d( 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 pdgemm(
'N',
'N', kln, nh, nh, one, a, kkrow,
606 $ ilo, desca, v, 1, 1, descv, zero, work, 1, 1,
608 CALL pdgemr2d( 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 pdgemm(
'N',
'N', kln, nh, nh, one, z, kkrow,
623 $ ilo, descz, v, 1, 1, descv, zero, work, 1, 1,
625 CALL pdgemr2d( kln, nh, work, 1, 1, descwv, z,
626 $ kkrow, ilo, descz, contxt )