3
4
5
6
7
8
9
10 CHARACTER SIDE, TRANS
11 INTEGER IA, IC, INFO, JA, JC, K, LWORK, M, N
12
13
14 INTEGER DESCA( * ), DESCC( * )
15 COMPLEX*16 A( * ), C( * ), TAU( * ), WORK( * )
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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209 INTEGER BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
210 $ LLD_, MB_, M_, NB_, N_, RSRC_
211 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
212 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
213 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
214 COMPLEX*16 ONE
215 parameter( one = ( 1.0d+0, 0.0d+0 ) )
216
217
218 LOGICAL LEFT, LQUERY, NOTRAN
219 CHARACTER COLBTOP, ROWBTOP
220 INTEGER I, I1, I2, I3, IACOL, ICC, ICCOL, ICOFFA,
221 $ ICOFFC, ICROW, ICTXT, IROFFC, JCC, LCM, LCMP,
222 $ LWMIN, MI, MPC0, MYCOL, MYROW, NI, NPCOL,
223 $ NPROW, NQ, NQC0
224 COMPLEX*16 AII
225
226
227 EXTERNAL blacs_abort, blacs_gridinfo,
chk1mat,
230
231
232 LOGICAL LSAME
233 INTEGER ILCM, INDXG2P, NUMROC
235
236
237 INTRINSIC dble, dcmplx,
max, mod
238
239
240
241
242
243 ictxt = desca( ctxt_ )
244 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
245
246
247
248 info = 0
249 IF( nprow.EQ.-1 ) THEN
250 info = -(900+ctxt_)
251 ELSE
252 left =
lsame( side,
'L' )
253 notran =
lsame( trans,
'N' )
254
255
256
257 IF( left ) THEN
258 nq = m
259 CALL chk1mat( k, 5, m, 3, ia, ja, desca, 9, info )
260 ELSE
261 nq = n
262 CALL chk1mat( k, 5, n, 4, ia, ja, desca, 9, info )
263 END IF
264 CALL chk1mat( m, 3, n, 4, ic, jc, descc, 14, info )
265 IF( info.EQ.0 ) THEN
266 icoffa = mod( ja-1, desca( nb_ ) )
267 iroffc = mod( ic-1, descc( mb_ ) )
268 icoffc = mod( jc-1, descc( nb_ ) )
269 iacol =
indxg2p( ja, desca( nb_ ), mycol, desca( csrc_ ),
270 $ npcol )
271 icrow =
indxg2p( ic, descc( mb_ ), myrow, descc( rsrc_ ),
272 $ nprow )
273 iccol =
indxg2p( jc, descc( nb_ ), mycol, descc( csrc_ ),
274 $ npcol )
275 mpc0 =
numroc( m+iroffc, descc( mb_ ), myrow, icrow, nprow )
276 nqc0 =
numroc( n+icoffc, descc( nb_ ), mycol, iccol, npcol )
277
278 IF( left ) THEN
279 lcm =
ilcm( nprow, npcol )
280 lcmp = lcm / nprow
282 $ m+iroffc, desca( mb_ ), 0, 0, nprow ),
283 $ desca( mb_ ), 0, 0, lcmp ) )
284 ELSE
285 nqc0 =
numroc( n+icoffc, descc( nb_ ), mycol, iccol,
286 $ npcol )
287 mpc0 =
numroc( m+iroffc, descc( mb_ ), myrow, icrow,
288 $ nprow )
289 lwmin = nqc0 +
max( 1, mpc0 )
290 END IF
291
292 work( 1 ) = dcmplx( dble( lwmin ) )
293 lquery = ( lwork.EQ.-1 )
294 IF( .NOT.left .AND. .NOT.
lsame( side,
'R' ) )
THEN
295 info = -1
296 ELSE IF( .NOT.notran .AND. .NOT.
lsame( trans,
'C' ) )
THEN
297 info = -2
298 ELSE IF( k.LT.0 .OR. k.GT.nq ) THEN
299 info = -5
300 ELSE IF( left .AND. desca( nb_ ).NE.descc( mb_ ) ) THEN
301 info = -(900+nb_)
302 ELSE IF( left .AND. icoffa.NE.iroffc ) THEN
303 info = -12
304 ELSE IF( .NOT.left .AND. icoffa.NE.icoffc ) THEN
305 info = -13
306 ELSE IF( .NOT.left .AND. iacol.NE.iccol ) THEN
307 info = -13
308 ELSE IF( .NOT.left .AND. desca( nb_ ).NE.descc( nb_ ) ) THEN
309 info = -(1400+nb_)
310 ELSE IF( ictxt.NE.descc( ctxt_ ) ) THEN
311 info = -(1400+ctxt_)
312 ELSE IF( lwork.LT.lwmin .AND. .NOT.lquery ) THEN
313 info = -16
314 END IF
315 END IF
316 END IF
317
318 IF( info.NE.0 ) THEN
319 CALL pxerbla( ictxt,
'PZUNML2', -info )
320 CALL blacs_abort( ictxt, 1 )
321 RETURN
322 ELSE IF( lquery ) THEN
323 RETURN
324 END IF
325
326
327
328 IF( m.EQ.0 .OR. n.EQ.0 .OR. k.EQ.0 )
329 $ RETURN
330
331 CALL pb_topget( ictxt, 'Broadcast', 'Rowwise', rowbtop )
332 CALL pb_topget( ictxt, 'Broadcast', 'Columnwise', colbtop )
333
334 IF( ( left .AND. notran .OR. .NOT.left .AND. .NOT.notran ) ) THEN
335 i1 = ia
336 i2 = ia + k - 1
337 i3 = 1
338 ELSE
339 i1 = ia + k -1
340 i2 = ia
341 i3 = -1
342 END IF
343
344 IF( left ) THEN
345 ni = n
346 jcc = jc
347 ELSE
348 mi = m
349 icc = ic
350 CALL pb_topset( ictxt, 'Broadcast', 'Rowwise', ' ' )
351 IF( notran ) THEN
352 CALL pb_topset( ictxt, 'Broadcast', 'Columnwise', 'D-ring' )
353 ELSE
354 CALL pb_topset( ictxt, 'Broadcast', 'Columnwise', 'I-ring' )
355 END IF
356 END IF
357
358 DO 10 i = i1, i2, i3
359 IF( left ) THEN
360
361
362
363 mi = m - i + ia
364 icc = ic + i - ia
365 ELSE
366
367
368
369 ni = n - i + ia
370 jcc = jc + i - ia
371 END IF
372
373
374
375 IF( i-ia+1.LT.nq )
376 $
CALL pzlacgv( nq-i+ia-1, a, i, ja+i-ia+1, desca,
377 $ desca( m_ ) )
378 CALL pzelset2( aii, a, i, ja+i-ia, desca, one )
379 IF( notran ) THEN
380 CALL pzlarfc( side, mi, ni, a, i, ja+i-ia, desca,
381 $ desca( m_ ), tau, c, icc, jcc, descc, work )
382 ELSE
383 CALL pzlarf( side, mi, ni, a, i, ja+i-ia, desca,
384 $ desca( m_ ), tau, c, icc, jcc, descc, work )
385 END IF
386 CALL pzelset( a, i, ja+i-ia, desca, aii )
387 IF( i-ia+1.LT.nq )
388 $
CALL pzlacgv( nq-i+ia-1, a, i, ja+i-ia+1, desca,
389 $ desca( m_ ) )
390
391 10 CONTINUE
392
393 CALL pb_topget( ictxt, 'Broadcast', 'Rowwise', rowbtop )
394 CALL pb_topget( ictxt, 'Broadcast', 'Columnwise', colbtop )
395
396 work( 1 ) = dcmplx( dble( lwmin ) )
397
398 RETURN
399
400
401
subroutine chk1mat(ma, mapos0, na, napos0, ia, ja, desca, descapos0, info)
integer function ilcm(m, n)
integer function indxg2p(indxglob, nb, iproc, isrcproc, nprocs)
integer function numroc(n, nb, iproc, isrcproc, nprocs)
subroutine pxerbla(ictxt, srname, info)
subroutine pzelset2(alpha, a, ia, ja, desca, beta)
subroutine pzelset(a, ia, ja, desca, alpha)
subroutine pzlacgv(n, x, ix, jx, descx, incx)
subroutine pzlarf(side, m, n, v, iv, jv, descv, incv, tau, c, ic, jc, descc, work)
subroutine pzlarfc(side, m, n, v, iv, jv, descv, incv, tau, c, ic, jc, descc, work)