2
    3
    4
    5
    6
    7
    8
    9      INTEGER            I, K, L, LWORK
   10      DOUBLE PRECISION   SMLNUM
   11
   12
   13      INTEGER            DESCA( * )
   14      COMPLEX*16         A( * ), BUF( * )
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133
  134
  135
  136
  137
  138
  139
  140
  141
  142      INTEGER            BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
  143     $                   LLD_, MB_, M_, NB_, N_, RSRC_
  144      parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
  145     $                     ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
  146     $                     rsrc_ = 7, csrc_ = 8, lld_ = 9 )
  147      DOUBLE PRECISION   ZERO
  148      parameter( zero = 0.0d+0 )
  149
  150
  151      INTEGER            CONTXT, DOWN, HBL, IBUF1, IBUF2, ICOL1, ICOL2,
  152     $                   II, III, IRCV1, IRCV2, IROW1, IROW2, ISRC,
  153     $                   ISTR1, ISTR2, ITMP1, ITMP2, JJ, JJJ, JSRC, LDA,
  154     $                   LEFT, MODKM1, MYCOL, MYROW, NPCOL, NPROW, NUM,
  155     $                   RIGHT, UP
  156      DOUBLE PRECISION   TST1, ULP
  157      COMPLEX*16         CDUM, H10, H11, H22
  158
  159
  160      INTEGER            ILCM, NUMROC
  161      DOUBLE PRECISION   PDLAMCH
  163
  164
  166     $                   zgerv2d, zgesd2d
  167
  168
  169      INTRINSIC          abs, dble, dimag, 
max, mod
 
  170
  171
  172      DOUBLE PRECISION   CABS1
  173
  174
  175      cabs1( cdum ) = abs( dble( cdum ) ) + abs( dimag( cdum ) )
  176
  177
  178
  179      hbl = desca( mb_ )
  180      contxt = desca( ctxt_ )
  181      lda = desca( lld_ )
  182      ulp = 
pdlamch( contxt, 
'PRECISION' )
 
  183      CALL blacs_gridinfo( contxt, nprow, npcol, myrow, mycol )
  184      left = mod( mycol+npcol-1, npcol )
  185      right = mod( mycol+1, npcol )
  186      up = mod( myrow+nprow-1, nprow )
  187      down = mod( myrow+1, nprow )
  188      num = nprow*npcol
  189
  190
  191
  192
  193      istr1 = 0
  194      istr2 = ( ( i-l ) / hbl )
  195      IF( istr2*hbl.LT.( i-l ) )
  196     $   istr2 = istr2 + 1
  197      ii = istr2 / 
ilcm( nprow, npcol )
 
  198      IF( ii*
ilcm( nprow, npcol ).LT.istr2 ) 
THEN 
  199         istr2 = ii + 1
  200      ELSE
  201         istr2 = ii
  202      END IF
  203      IF( lwork.LT.2*istr2 ) THEN
  204
  205
  206
  207         RETURN
  208      END IF
  209      CALL infog2l( i, i, desca, nprow, npcol, myrow, mycol, irow1,
 
  210     $              icol1, ii, jj )
  211      modkm1 = mod( i-1+hbl, hbl )
  212
  213
  214
  215
  216
  217      ibuf1 = 0
  218      ibuf2 = 0
  219      ircv1 = 0
  220      ircv2 = 0
  221      DO 10 k = i, l + 1, -1
  222         IF( ( modkm1.EQ.0 ) .AND. ( down.EQ.ii ) .AND.
  223     $       ( right.EQ.jj ) ) THEN
  224
  225
  226
  227            IF( ( down.NE.myrow ) .OR. ( right.NE.mycol ) ) THEN
  228               CALL infog2l( k-1, k-1, desca, nprow, npcol, myrow,
 
  229     $                       mycol, irow1, icol1, isrc, jsrc )
  230               ibuf1 = ibuf1 + 1
  231               buf( istr1+ibuf1 ) = a( ( icol1-1 )*lda+irow1 )
  232            END IF
  233         END IF
  234         IF( ( modkm1.EQ.0 ) .AND. ( myrow.EQ.ii ) .AND.
  235     $       ( right.EQ.jj ) ) THEN
  236
  237
  238
  239            IF( npcol.GT.1 ) THEN
  240               CALL infog2l( k, k-1, desca, nprow, npcol, myrow, mycol,
 
  241     $                       irow1, icol1, isrc, jsrc )
  242               ibuf2 = ibuf2 + 1
  243               buf( istr2+ibuf2 ) = a( ( icol1-1 )*lda+irow1 )
  244            END IF
  245         END IF
  246
  247
  248
  249         IF( ( myrow.EQ.ii ) .AND. ( mycol.EQ.jj ) ) THEN
  250            IF( ( modkm1.EQ.0 ) .AND. ( ( nprow.GT.1 ) .OR. ( npcol.GT.
  251     $          1 ) ) ) THEN
  252
  253
  254
  255               ircv1 = ircv1 + 1
  256            END IF
  257            IF( ( modkm1.EQ.0 ) .AND. ( npcol.GT.1 ) ) THEN
  258
  259
  260
  261               ircv2 = ircv2 + 1
  262            END IF
  263         END IF
  264
  265
  266
  267         IF( modkm1.EQ.0 ) THEN
  268            ii = ii - 1
  269            jj = jj - 1
  270            IF( ii.LT.0 )
  271     $         ii = nprow - 1
  272            IF( jj.LT.0 )
  273     $         jj = npcol - 1
  274         END IF
  275         modkm1 = modkm1 - 1
  276         IF( modkm1.LT.0 )
  277     $      modkm1 = hbl - 1
  278   10 CONTINUE
  279
  280
  281
  282      IF( ibuf1.GT.0 ) THEN
  283         CALL zgesd2d( contxt, ibuf1, 1, buf( istr1+1 ), ibuf1, down,
  284     $                 right )
  285      END IF
  286      IF( ibuf2.GT.0 ) THEN
  287         CALL zgesd2d( contxt, ibuf2, 1, buf( istr2+1 ), ibuf2, myrow,
  288     $                 right )
  289      END IF
  290
  291
  292
  293      IF( ircv1.GT.0 ) THEN
  294         CALL zgerv2d( contxt, ircv1, 1, buf( istr1+1 ), ircv1, up,
  295     $                 left )
  296      END IF
  297      IF( ircv2.GT.0 ) THEN
  298         CALL zgerv2d( contxt, ircv2, 1, buf( istr2+1 ), ircv2, myrow,
  299     $                 left )
  300      END IF
  301
  302
  303
  304      ibuf1 = 0
  305      ibuf2 = 0
  306      CALL infog2l( i, i, desca, nprow, npcol, myrow, mycol, irow1,
 
  307     $              icol1, ii, jj )
  308      modkm1 = mod( i-1+hbl, hbl )
  309
  310
  311
  312
  313
  314      DO 40 k = i, l + 1, -1
  315         IF( ( myrow.EQ.ii ) .AND. ( mycol.EQ.jj ) ) THEN
  316            IF( modkm1.EQ.0 ) THEN
  317
  318
  319
  320               IF( num.GT.1 ) THEN
  321                  ibuf1 = ibuf1 + 1
  322                  h11 = buf( istr1+ibuf1 )
  323               ELSE
  324                  h11 = a( ( icol1-2 )*lda+irow1-1 )
  325               END IF
  326               IF( npcol.GT.1 ) THEN
  327                  ibuf2 = ibuf2 + 1
  328                  h10 = buf( istr2+ibuf2 )
  329               ELSE
  330                  h10 = a( ( icol1-2 )*lda+irow1 )
  331               END IF
  332            ELSE
  333
  334
  335
  336               h11 = a( ( icol1-2 )*lda+irow1-1 )
  337               h10 = a( ( icol1-2 )*lda+irow1 )
  338            END IF
  339            h22 = a( ( icol1-1 )*lda+irow1 )
  340            tst1 = cabs1( h11 ) + cabs1( h22 )
  341            IF( tst1.EQ.zero ) THEN
  342
  343
  344
  345               CALL infog1l( l, hbl, nprow, myrow, 0, itmp1, iii )
 
  346               irow2 = 
numroc( i, hbl, myrow, 0, nprow )
 
  347               CALL infog1l( l, hbl, npcol, mycol, 0, itmp2, iii )
 
  348               icol2 = 
numroc( i, hbl, mycol, 0, npcol )
 
  349               DO 30 iii = itmp1, irow2
  350                  DO 20 jjj = itmp2, icol2
  351                     tst1 = tst1 + cabs1( a( ( jjj-1 )*lda+iii ) )
  352   20             CONTINUE
  353   30          CONTINUE
  354            END IF
  355            IF( cabs1( h10 ).LE.
max( ulp*tst1, smlnum ) )
 
  356     $         GO TO 50
  357            irow1 = irow1 - 1
  358            icol1 = icol1 - 1
  359         END IF
  360         modkm1 = modkm1 - 1
  361         IF( modkm1.LT.0 )
  362     $      modkm1 = hbl - 1
  363         IF( ( modkm1.EQ.hbl-1 ) .AND. ( k.GT.2 ) ) THEN
  364            ii = mod( ii+nprow-1, nprow )
  365            jj = mod( jj+npcol-1, npcol )
  366            CALL infog2l( k-1, k-1, desca, nprow, npcol, myrow, mycol,
 
  367     $                    irow1, icol1, itmp1, itmp2 )
  368         END IF
  369   40 CONTINUE
  370   50 CONTINUE
  371      CALL igamx2d( contxt, 'ALL', ' ', 1, 1, k, 1, itmp1, itmp2, -1,
  372     $              -1, -1 )
  373      RETURN
  374
  375
  376
integer function ilcm(m, n)
 
subroutine infog1l(gindx, nb, nprocs, myroc, isrcproc, lindx, rocsrc)
 
subroutine infog2l(grindx, gcindx, desc, nprow, npcol, myrow, mycol, lrindx, lcindx, rsrc, csrc)
 
integer function numroc(n, nb, iproc, isrcproc, nprocs)
 
double precision function pdlamch(ictxt, cmach)