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 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 ONE
215 parameter( one = ( 1.0e+0, 0.0e+0 ) )
216
217
218 LOGICAL LEFT, LQUERY, NOTRAN
219 CHARACTER COLBTOP, ROWBTOP
220 INTEGER IACOL, IAROW, ICCOL, ICOFFC, ICROW, ICTXT, ICC,
221 $ II, IROFFA, IROFFC, J, J1, J2, J3, JCC, JJ,
222 $ LCM, LCMQ, LWMIN, MI, MP, MPC0, MYCOL, MYROW,
223 $ NI, NPCOL, NPROW, NQ, NQC0
224 COMPLEX AJJ
225
226
227 EXTERNAL blacs_abort, blacs_gridinfo, cgebr2d,
228 $ cgebs2d, cgerv2d, cgesd2d,
chk1mat,
231
232
233 LOGICAL LSAME
234 INTEGER ILCM, INDXG2P, NUMROC
236
237
238 INTRINSIC cmplx, conjg,
max, mod, real
239
240
241
242
243
244 ictxt = desca( ctxt_ )
245 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
246
247
248
249 info = 0
250 IF( nprow.EQ.-1 ) THEN
251 info = -(900+ctxt_)
252 ELSE
253 left =
lsame( side,
'L' )
254 notran =
lsame( trans,
'N' )
255
256
257
258 IF( left ) THEN
259 nq = m
260 CALL chk1mat( m, 3, k, 5, ia, ja, desca, 9, info )
261 ELSE
262 nq = n
263 CALL chk1mat( n, 4, k, 5, ia, ja, desca, 9, info )
264 END IF
265 CALL chk1mat( m, 3, n, 4, ic, jc, descc, 14, info )
266 IF( info.EQ.0 ) THEN
267 iroffa = mod( ia-1, desca( mb_ ) )
268 iroffc = mod( ic-1, descc( mb_ ) )
269 icoffc = mod( jc-1, descc( nb_ ) )
270 iarow =
indxg2p( ia, desca( mb_ ), myrow, desca( rsrc_ ),
271 $ nprow )
272 icrow =
indxg2p( ic, descc( mb_ ), myrow, descc( rsrc_ ),
273 $ nprow )
274 iccol =
indxg2p( jc, descc( nb_ ), mycol, descc( csrc_ ),
275 $ npcol )
276 mpc0 =
numroc( m+iroffc, descc( mb_ ), myrow, icrow, nprow )
277 nqc0 =
numroc( n+icoffc, descc( nb_ ), mycol, iccol, npcol )
278
279 IF( left ) THEN
280 lwmin = mpc0 +
max( 1, nqc0 )
281 ELSE
282 lcm =
ilcm( nprow, npcol )
283 lcmq = lcm / npcol
285 $ n+icoffc, desca( nb_ ), 0, 0, npcol ),
286 $ desca( nb_ ), 0, 0, lcmq ) )
287 END IF
288
289 work( 1 ) =
cmplx( real( lwmin ) )
290 lquery = ( lwork.EQ.-1 )
291 IF( .NOT.left .AND. .NOT.
lsame( side,
'R' ) )
THEN
292 info = -1
293 ELSE IF( .NOT.notran .AND. .NOT.
lsame( trans,
'C' ) )
THEN
294 info = -2
295 ELSE IF( k.LT.0 .OR. k.GT.nq ) THEN
296 info = -5
297 ELSE IF( .NOT.left .AND. desca( mb_ ).NE.descc( nb_ ) ) THEN
298 info = -(900+nb_)
299 ELSE IF( left .AND. iroffa.NE.iroffc ) THEN
300 info = -12
301 ELSE IF( left .AND. iarow.NE.icrow ) THEN
302 info = -12
303 ELSE IF( .NOT.left .AND. iroffa.NE.icoffc ) THEN
304 info = -13
305 ELSE IF( left .AND. desca( mb_ ).NE.descc( mb_ ) ) THEN
306 info = -(1400+mb_)
307 ELSE IF( ictxt.NE.descc( ctxt_ ) ) THEN
308 info = -(1400+ctxt_)
309 ELSE IF( lwork.LT.lwmin .AND. .NOT.lquery ) THEN
310 info = -16
311 END IF
312 END IF
313 END IF
314 IF( info.NE.0 ) THEN
315 CALL pxerbla( ictxt,
'PCUNM2L', -info )
316 CALL blacs_abort( ictxt, 1 )
317 RETURN
318 ELSE IF( lquery ) THEN
319 RETURN
320 END IF
321
322
323
324 IF( m.EQ.0 .OR. n.EQ.0 .OR. k.EQ.0 )
325 $ RETURN
326
327 IF( desca( m_ ).EQ.1 ) THEN
328 CALL infog2l( ia, ja, desca, nprow, npcol, myrow, mycol, ii,
329 $ jj, iarow, iacol )
330 CALL infog2l( ic, jc, descc, nprow, npcol, myrow, mycol, icc,
331 $ jcc, icrow, iccol )
332 IF( left ) THEN
333 IF( myrow.EQ.iarow ) THEN
334 nq =
numroc( jc+n-1, descc( nb_ ), mycol, descc( csrc_ ),
335 $ npcol )
336 IF( mycol.EQ.iacol ) THEN
337 IF( notran ) THEN
338 ajj = one - tau( jj )
339 ELSE
340 ajj = one - conjg( tau( jj ) )
341 END IF
342 CALL cgebs2d( ictxt, 'Rowwise', ' ', 1, 1, ajj, 1 )
343 CALL cscal( nq-jcc+1, ajj,
344 $ c( icc+(jcc-1)*descc( lld_ ) ),
345 $ descc( lld_ ) )
346 ELSE
347 CALL cgebr2d( ictxt, 'Rowwise', ' ', 1, 1, ajj, 1,
348 $ iarow, iacol )
349 CALL cscal( nq-jcc+1, ajj,
350 $ c( icc+(jcc-1)*descc( lld_ ) ),
351 $ descc( lld_ ) )
352 END IF
353 END IF
354 ELSE
355 IF( mycol.EQ.iacol ) THEN
356 IF( notran ) THEN
357 ajj = one - tau( jj )
358 ELSE
359 ajj = one - conjg( tau( jj ) )
360 END IF
361 END IF
362
363 IF( iacol.NE.iccol ) THEN
364 IF( mycol.EQ.iacol )
365 $ CALL cgesd2d( ictxt, 1, 1, ajj, 1, myrow, iccol )
366 IF( mycol.EQ.iccol )
367 $ CALL cgerv2d( ictxt, 1, 1, ajj, 1, myrow, iacol )
368 END IF
369
370 IF( mycol.EQ.iccol ) THEN
371 mp =
numroc( ic+m-1, descc( mb_ ), myrow, descc( rsrc_ ),
372 $ nprow )
373 CALL cscal( mp-icc+1, ajj, c( icc+(jcc-1)*
374 $ descc( lld_ ) ), 1 )
375 END IF
376
377 END IF
378
379 ELSE
380
381 CALL pb_topget( ictxt, 'Broadcast', 'Rowwise', rowbtop )
382 CALL pb_topget( ictxt, 'Broadcast', 'Columnwise', colbtop )
383
384 IF( left .AND. notran .OR. .NOT.left .AND. .NOT.notran ) THEN
385 j1 = ja
386 j2 = ja+k-1
387 j3 = 1
388 ELSE
389 j1 = ja+k-1
390 j2 = ja
391 j3 = -1
392 END IF
393
394 IF( left ) THEN
395 ni = n
396 IF( notran ) THEN
397 CALL pb_topset( ictxt, 'Broadcast', 'Rowwise', 'I-ring' )
398 ELSE
399 CALL pb_topset( ictxt, 'Broadcast', 'Rowwise', 'D-ring' )
400 END IF
401 CALL pb_topset( ictxt, 'Broadcast', 'Columnwise', ' ' )
402 ELSE
403 mi = m
404 END IF
405
406 DO 10 j = j1, j2, j3
407
408 IF( left ) THEN
409
410
411
412 mi = m - k + j - ja + 1
413 ELSE
414
415
416
417 ni = n - k + j - ja + 1
418 END IF
419
420
421
422 CALL pcelset2( ajj, a, ia+nq-k+j-ja, j, desca, one )
423 IF( notran ) THEN
424 CALL pclarf( side, mi, ni, a, ia, j, desca, 1, tau, c,
425 $ ic, jc, descc, work )
426 ELSE
427 CALL pclarfc( side, mi, ni, a, ia, j, desca, 1, tau, c,
428 $ ic, jc, descc, work )
429 END IF
430 CALL pcelset( a, ia+nq-k+j-ja, j, desca, ajj )
431
432 10 CONTINUE
433
434 CALL pb_topset( ictxt, 'Broadcast', 'Rowwise', rowbtop )
435 CALL pb_topset( ictxt, 'Broadcast', 'Columnwise', colbtop )
436
437 END IF
438
439 work( 1 ) =
cmplx( real( lwmin ) )
440
441 RETURN
442
443
444
subroutine chk1mat(ma, mapos0, na, napos0, ia, ja, desca, descapos0, info)
integer function ilcm(m, n)
integer function indxg2p(indxglob, nb, iproc, isrcproc, nprocs)
subroutine infog2l(grindx, gcindx, desc, nprow, npcol, myrow, mycol, lrindx, lcindx, rsrc, csrc)
integer function numroc(n, nb, iproc, isrcproc, nprocs)
subroutine pcelset2(alpha, a, ia, ja, desca, beta)
subroutine pcelset(a, ia, ja, desca, alpha)
subroutine pclarf(side, m, n, v, iv, jv, descv, incv, tau, c, ic, jc, descc, work)
subroutine pclarfc(side, m, n, v, iv, jv, descv, incv, tau, c, ic, jc, descc, work)
subroutine pxerbla(ictxt, srname, info)