2
3
4
5
6
7
8
9 INTEGER I, K, L, LWORK
10 REAL SMLNUM
11
12
13 INTEGER DESCA( * )
14 COMPLEX 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 REAL ZERO
148 parameter( zero = 0.0e+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 REAL TST1, ULP
157 COMPLEX CDUM, H10, H11, H22
158
159
160 INTEGER ILCM, NUMROC
161 REAL PSLAMCH
163
164
166 $ cgerv2d, cgesd2d
167
168
169 INTRINSIC abs, real, aimag,
max, mod
170
171
172 REAL CABS1
173
174
175 cabs1( cdum ) = abs( real( cdum ) ) + abs( aimag( cdum ) )
176
177
178
179 hbl = desca( mb_ )
180 contxt = desca( ctxt_ )
181 lda = desca( lld_ )
182 ulp =
pslamch( 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 cgesd2d( contxt, ibuf1, 1, buf( istr1+1 ), ibuf1, down,
284 $ right )
285 END IF
286 IF( ibuf2.GT.0 ) THEN
287 CALL cgesd2d( contxt, ibuf2, 1, buf( istr2+1 ), ibuf2, myrow,
288 $ right )
289 END IF
290
291
292
293 IF( ircv1.GT.0 ) THEN
294 CALL cgerv2d( contxt, ircv1, 1, buf( istr1+1 ), ircv1, up,
295 $ left )
296 END IF
297 IF( ircv2.GT.0 ) THEN
298 CALL cgerv2d( 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)
real function pslamch(ictxt, cmach)