2
3
4
5
6
7
8
9 INTEGER I, K, L, LWORK
10 DOUBLE PRECISION SMLNUM
11
12
13 INTEGER DESCA( * )
14 DOUBLE PRECISION 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 INTEGER BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
141 $ LLD_, MB_, M_, NB_, N_, RSRC_
142 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
143 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
144 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
145 DOUBLE PRECISION ZERO
146 parameter( zero = 0.0d+0 )
147
148
149 INTEGER CONTXT, DOWN, HBL, IAFIRST, IBUF1, IBUF2,
150 $ ICOL1, ICOL2, II, III, IRCV1, IRCV2, IROW1,
151 $ IROW2, ISRC, ISTR1, ISTR2, ITMP1, ITMP2,
152 $ JAFIRST, JJ, JJJ, JSRC, LDA, LEFT, MODKM1,
153 $ MYCOL, MYROW, NPCOL, NPROW, NUM, RIGHT, UP
154 DOUBLE PRECISION H10, H11, H22, TST1, ULP
155
156
157 INTEGER ILCM, NUMROC
158 DOUBLE PRECISION PDLAMCH
160
161
162 EXTERNAL blacs_gridinfo, dgerv2d, dgesd2d, igamx2d,
164
165
166 INTRINSIC abs,
max, mod
167
168
169
170 hbl = desca( mb_ )
171 contxt = desca( ctxt_ )
172 lda = desca( lld_ )
173 iafirst = desca( rsrc_ )
174 jafirst = desca( csrc_ )
175 ulp =
pdlamch( contxt,
'PRECISION' )
176 CALL blacs_gridinfo( contxt, nprow, npcol, myrow, mycol )
177 left = mod( mycol+npcol-1, npcol )
178 right = mod( mycol+1, npcol )
179 up = mod( myrow+nprow-1, nprow )
180 down = mod( myrow+1, nprow )
181 num = nprow*npcol
182
183
184
185
186 istr1 = 0
187 istr2 = ( ( i-l ) / hbl )
188 IF( istr2*hbl.LT.( i-l ) )
189 $ istr2 = istr2 + 1
190 ii = istr2 /
ilcm( nprow, npcol )
191 IF( ii*
ilcm( nprow, npcol ).LT.istr2 )
THEN
192 istr2 = ii + 1
193 ELSE
194 istr2 = ii
195 END IF
196 IF( lwork.LT.2*istr2 ) THEN
197
198
199
200 RETURN
201 END IF
202 CALL infog2l( i, i, desca, nprow, npcol, myrow, mycol, irow1,
203 $ icol1, ii, jj )
204 modkm1 = mod( i-1+hbl, hbl )
205
206
207
208
209
210 ibuf1 = 0
211 ibuf2 = 0
212 ircv1 = 0
213 ircv2 = 0
214 DO 10 k = i, l + 1, -1
215 IF( ( modkm1.EQ.0 ) .AND. ( down.EQ.ii ) .AND.
216 $ ( right.EQ.jj ) ) THEN
217
218
219
220 IF( ( down.NE.myrow ) .OR. ( right.NE.mycol ) ) THEN
221 CALL infog2l( k-1, k-1, desca, nprow, npcol, myrow,
222 $ mycol, irow1, icol1, isrc, jsrc )
223 ibuf1 = ibuf1 + 1
224 buf( istr1+ibuf1 ) = a( ( icol1-1 )*lda+irow1 )
225 END IF
226 END IF
227 IF( ( modkm1.EQ.0 ) .AND. ( myrow.EQ.ii ) .AND.
228 $ ( right.EQ.jj ) ) THEN
229
230
231
232 IF( npcol.GT.1 ) THEN
233 CALL infog2l( k, k-1, desca, nprow, npcol, myrow, mycol,
234 $ irow1, icol1, isrc, jsrc )
235 ibuf2 = ibuf2 + 1
236 buf( istr2+ibuf2 ) = a( ( icol1-1 )*lda+irow1 )
237 END IF
238 END IF
239
240
241
242 IF( ( myrow.EQ.ii ) .AND. ( mycol.EQ.jj ) ) THEN
243 IF( ( modkm1.EQ.0 ) .AND. ( ( nprow.GT.1 ) .OR. ( npcol.GT.
244 $ 1 ) ) ) THEN
245
246
247
248 ircv1 = ircv1 + 1
249 END IF
250 IF( ( modkm1.EQ.0 ) .AND. ( npcol.GT.1 ) ) THEN
251
252
253
254 ircv2 = ircv2 + 1
255 END IF
256 END IF
257
258
259
260 IF( modkm1.EQ.0 ) THEN
261 ii = ii - 1
262 jj = jj - 1
263 IF( ii.LT.0 )
264 $ ii = nprow - 1
265 IF( jj.LT.0 )
266 $ jj = npcol - 1
267 END IF
268 modkm1 = modkm1 - 1
269 IF( modkm1.LT.0 )
270 $ modkm1 = hbl - 1
271 10 CONTINUE
272
273
274
275 IF( ibuf1.GT.0 ) THEN
276 CALL dgesd2d( contxt, ibuf1, 1, buf( istr1+1 ), ibuf1, down,
277 $ right )
278 END IF
279 IF( ibuf2.GT.0 ) THEN
280 CALL dgesd2d( contxt, ibuf2, 1, buf( istr2+1 ), ibuf2, myrow,
281 $ right )
282 END IF
283
284
285
286 IF( ircv1.GT.0 ) THEN
287 CALL dgerv2d( contxt, ircv1, 1, buf( istr1+1 ), ircv1, up,
288 $ left )
289 END IF
290 IF( ircv2.GT.0 ) THEN
291 CALL dgerv2d( contxt, ircv2, 1, buf( istr2+1 ), ircv2, myrow,
292 $ left )
293 END IF
294
295
296
297 ibuf1 = 0
298 ibuf2 = 0
299 CALL infog2l( i, i, desca, nprow, npcol, myrow, mycol, irow1,
300 $ icol1, ii, jj )
301 modkm1 = mod( i-1+hbl, hbl )
302
303
304
305
306
307 DO 40 k = i, l + 1, -1
308 IF( ( myrow.EQ.ii ) .AND. ( mycol.EQ.jj ) ) THEN
309 IF( modkm1.EQ.0 ) THEN
310
311
312
313 IF( num.GT.1 ) THEN
314 ibuf1 = ibuf1 + 1
315 h11 = buf( istr1+ibuf1 )
316 ELSE
317 h11 = a( ( icol1-2 )*lda+irow1-1 )
318 END IF
319 IF( npcol.GT.1 ) THEN
320 ibuf2 = ibuf2 + 1
321 h10 = buf( istr2+ibuf2 )
322 ELSE
323 h10 = a( ( icol1-2 )*lda+irow1 )
324 END IF
325 ELSE
326
327
328
329 h11 = a( ( icol1-2 )*lda+irow1-1 )
330 h10 = a( ( icol1-2 )*lda+irow1 )
331 END IF
332 h22 = a( ( icol1-1 )*lda+irow1 )
333 tst1 = abs( h11 ) + abs( h22 )
334 IF( tst1.EQ.zero ) THEN
335
336
337
338 CALL infog1l( l, hbl, nprow, myrow, iafirst, itmp1, iii )
339 irow2 =
numroc( i, hbl, myrow, iafirst, nprow )
340 CALL infog1l( l, hbl, npcol, mycol, jafirst, itmp2, iii )
341 icol2 =
numroc( i, hbl, mycol, jafirst, npcol )
342 DO 30 iii = itmp1, irow2
343 DO 20 jjj = itmp2, icol2
344 tst1 = tst1 + abs( a( ( jjj-1 )*lda+iii ) )
345 20 CONTINUE
346 30 CONTINUE
347 END IF
348 IF( abs( h10 ).LE.
max( ulp*tst1, smlnum ) )
349 $ GO TO 50
350 irow1 = irow1 - 1
351 icol1 = icol1 - 1
352 END IF
353 modkm1 = modkm1 - 1
354 IF( modkm1.LT.0 )
355 $ modkm1 = hbl - 1
356 IF( ( modkm1.EQ.hbl-1 ) .AND. ( k.GT.2 ) ) THEN
357 ii = mod( ii+nprow-1, nprow )
358 jj = mod( jj+npcol-1, npcol )
359 CALL infog2l( k-1, k-1, desca, nprow, npcol, myrow, mycol,
360 $ irow1, icol1, itmp1, itmp2 )
361 END IF
362 40 CONTINUE
363 50 CONTINUE
364 CALL igamx2d( contxt, 'ALL', ' ', 1, 1, k, 1, itmp1, itmp2, -1,
365 $ -1, -1 )
366 RETURN
367
368
369
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)