3
4
5
6
7
8
9
10 CHARACTER DIREC, ROWCOL
11 INTEGER IA, IP, JA, JP, M, N
12
13
14 INTEGER DESCA( * ), DESCIP( * ), IPIV( * )
15 COMPLEX*16 A( * )
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
143
144
145
146 INTEGER BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
147 $ LLD_, MB_, M_, NB_, N_, RSRC_
148 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
149 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
150 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
151
152
153 LOGICAL FORWRD, ROWPVT
154 INTEGER I, IB, ICTXT, ICURCOL, ICURROW, IIP, IP1, ITMP,
155 $ IPVWRK, J, JB, JJP, JP1, K, MA, MBA, MYCOL,
156 $ MYROW, NBA, NPCOL, NPROW
157
158
159 EXTERNAL blacs_gridinfo, igebs2d, igebr2d,
infog2l,
160 $ pzswap
161
162
163 LOGICAL LSAME
164 INTEGER ICEIL, NUMROC
166
167
169
170
171
172 rowpvt =
lsame( rowcol,
'R' )
173 IF( rowpvt ) THEN
174 IF( m.LE.1 .OR. n.LT.1 )
175 $ RETURN
176 ELSE
177 IF( m.LT.1 .OR. n.LE.1 )
178 $ RETURN
179 END IF
180 forwrd =
lsame( direc,
'F' )
181
182
183
184
185 ma = desca( m_ )
186 mba = desca( mb_ )
187 nba = desca( nb_ )
188 ictxt = desca( ctxt_ )
189 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
190
191
192
193
194 IF( forwrd ) THEN
195 CALL infog2l( ip, jp, descip, nprow, npcol, myrow, mycol,
196 $ iip, jjp, icurrow, icurcol )
197
198
199
200 IF( rowpvt ) THEN
201 ipvwrk =
numroc( descip( m_ ), descip( mb_ ), myrow,
202 $ descip( rsrc_ ), nprow ) + 1 -
203 $ descip( mb_ )
204
205
206
207 i = ia
208 ib =
min( m,
iceil( ia, mba ) * mba - ia + 1 )
209 10 CONTINUE
210
211
212
213
214 IF( myrow.EQ.icurrow ) THEN
215 CALL igebs2d( ictxt, 'Columnwise', ' ', ib, 1,
216 $ ipiv( iip ), ib )
217 itmp = iip
218 iip = iip + ib
219 ELSE
220 itmp = ipvwrk
221 CALL igebr2d( ictxt, 'Columnwise', ' ', ib, 1,
222 $ ipiv( itmp ), ib, icurrow, mycol )
223 END IF
224
225
226
227 DO 20 k = i, i+ib-1
228 ip1 = ipiv( itmp ) - ip + ia
229 IF( ip1.NE.k )
230 $ CALL pzswap( n, a, k, ja, desca, ma, a, ip1, ja,
231 $ desca, ma )
232 itmp = itmp + 1
233 20 CONTINUE
234
235
236
237
238 icurrow = mod( icurrow+1, nprow )
239 i = i + ib
240 ib =
min( mba, m-i+ia )
241 IF( ib .GT. 0 ) GOTO 10
242
243
244
245 ELSE
246 ipvwrk =
numroc( descip( n_ ), descip( nb_ ), mycol,
247 $ descip( csrc_ ), npcol ) + 1 -
248 $ descip( nb_ )
249
250
251
252 j = ja
253 jb =
min( n,
iceil( ja, nba ) * nba - ja + 1 )
254 30 CONTINUE
255
256
257
258
259 IF( mycol.EQ.icurcol ) THEN
260 CALL igebs2d( ictxt, 'Rowwise', ' ', jb, 1,
261 $ ipiv( jjp ), jb )
262 itmp = jjp
263 jjp = jjp + jb
264 ELSE
265 itmp = ipvwrk
266 CALL igebr2d( ictxt, 'Rowwise', ' ', jb, 1,
267 $ ipiv( itmp ), jb, myrow, icurcol )
268 END IF
269
270
271
272 DO 40 k = j, j+jb-1
273 jp1 = ipiv( itmp ) - jp + ja
274 IF( jp1.NE.k )
275 $ CALL pzswap( m, a, ia, k, desca, 1, a, ia, jp1,
276 $ desca, 1 )
277 itmp = itmp + 1
278 40 CONTINUE
279
280
281
282
283 icurcol = mod( icurcol+1, npcol )
284 j = j + jb
285 jb =
min( nba, n-j+ja )
286 IF( jb .GT. 0 ) GOTO 30
287 END IF
288
289
290
291
292
293 ELSE
294
295
296
297 IF( rowpvt ) THEN
298 CALL infog2l( ip+m-1, jp, descip, nprow, npcol, myrow,
299 $ mycol, iip, jjp, icurrow, icurcol )
300
301 ipvwrk =
numroc( descip( m_ ), descip( mb_ ), myrow,
302 $ descip( rsrc_ ), nprow ) + 1 -
303 $ descip( mb_ )
304
305
306
307
308
309 IF( myrow.NE.icurrow ) iip = iip - 1
310
311
312
313 i = ia + m - 1
314 ib = mod( i, mba )
315 IF( ib .EQ. 0 ) ib = mba
317 50 CONTINUE
318
319
320
321
322 IF( myrow.EQ.icurrow ) THEN
323 itmp = iip
324 iip = iip - ib
325 CALL igebs2d( ictxt, 'Columnwise', ' ', ib, 1,
326 $ ipiv( iip+1 ), ib )
327 ELSE
328 CALL igebr2d( ictxt, 'Columnwise', ' ', ib, 1,
329 $ ipiv( ipvwrk ), ib, icurrow, mycol )
330 itmp = ipvwrk + ib - 1
331 END IF
332
333
334
335 DO 60 k = i, i-ib+1, -1
336 ip1 = ipiv( itmp ) - ip + ia
337 IF( ip1.NE.k )
338 $ CALL pzswap( n, a, k, ja, desca, ma, a, ip1, ja,
339 $ desca, ma )
340 itmp = itmp - 1
341 60 CONTINUE
342
343
344
345
346 icurrow = mod( nprow+icurrow-1, nprow )
347 i = i - ib
348 ib =
min( mba, i-ia+1 )
349 IF( ib .GT. 0 ) GOTO 50
350
351
352
353 ELSE
354 CALL infog2l( ip, jp+n-1, descip, nprow, npcol, myrow,
355 $ mycol, iip, jjp, icurrow, icurcol )
356 ipvwrk =
numroc( descip( n_ ), descip( nb_ ), mycol,
357 $ descip( csrc_ ), npcol ) + 1 -
358 $ descip( nb_ )
359
360
361
362
363
364 IF( mycol.NE.icurcol ) jjp = jjp - 1
365
366
367
368 j = ja + n - 1
369 jb = mod( j, nba )
370 IF( jb .EQ. 0 ) jb = nba
372 70 CONTINUE
373
374
375
376
377 IF( mycol.EQ.icurcol ) THEN
378 itmp = jjp
379 jjp = jjp - jb
380 CALL igebs2d( ictxt, 'Rowwise', ' ', jb, 1,
381 $ ipiv( jjp+1 ), jb )
382 ELSE
383 CALL igebr2d( ictxt, 'Rowwise', ' ', jb, 1,
384 $ ipiv( ipvwrk ), jb, myrow, icurcol )
385 itmp = ipvwrk + jb - 1
386 END IF
387
388
389
390 DO 80 k = j, j-jb+1, -1
391 jp1 = ipiv( itmp ) - jp + ja
392 IF( jp1.NE.k )
393 $ CALL pzswap( m, a, ia, k, desca, 1, a, ia, jp1,
394 $ desca, 1 )
395 itmp = itmp - 1
396 80 CONTINUE
397
398
399
400
401 icurcol = mod( npcol+icurcol-1, npcol )
402 j = j - jb
403 jb =
min( nba, j-ja+1 )
404 IF( jb .GT. 0 ) GOTO 70
405 END IF
406
407 END IF
408
409 RETURN
410
411
412
integer function iceil(inum, idenom)
subroutine infog2l(grindx, gcindx, desc, nprow, npcol, myrow, mycol, lrindx, lcindx, rsrc, csrc)
integer function numroc(n, nb, iproc, isrcproc, nprocs)