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
315 IF( info.NE.0 ) THEN
316 CALL pxerbla( ictxt,
'PCUNM2R', -info )
317 CALL blacs_abort( ictxt, 1 )
318 RETURN
319 ELSE IF( lquery ) THEN
320 RETURN
321 END IF
322
323
324
325 IF( m.EQ.0 .OR. n.EQ.0 .OR. k.EQ.0 )
326 $ RETURN
327
328 IF( desca( m_ ).EQ.1 ) THEN
329 CALL infog2l( ia, ja, desca, nprow, npcol, myrow, mycol, ii,
330 $ jj, iarow, iacol )
331 CALL infog2l( ic, jc, descc, nprow, npcol, myrow, mycol, icc,
332 $ jcc, icrow, iccol )
333 IF( left ) THEN
334 IF( myrow.EQ.iarow ) THEN
335 nq =
numroc( jc+n-1, descc( nb_ ), mycol, descc( csrc_ ),
336 $ npcol )
337 IF( mycol.EQ.iacol ) THEN
338 IF( notran ) THEN
339 ajj = one - tau( jj )
340 ELSE
341 ajj = one - conjg( tau( jj ) )
342 END IF
343 CALL cgebs2d( ictxt, 'Rowwise', ' ', 1, 1, ajj, 1 )
344 CALL cscal( nq-jcc+1, ajj,
345 $ c( icc+(jcc-1)*descc( lld_ ) ),
346 $ descc( lld_ ) )
347 ELSE
348 CALL cgebr2d( ictxt, 'Rowwise', ' ', 1, 1, ajj, 1,
349 $ iarow, iacol )
350 CALL cscal( nq-jcc+1, ajj,
351 $ c( icc+(jcc-1)*descc( lld_ ) ),
352 $ descc( lld_ ) )
353 END IF
354 END IF
355 ELSE
356 IF( mycol.EQ.iacol ) THEN
357 IF( notran ) THEN
358 ajj = one - tau( jj )
359 ELSE
360 ajj = one - conjg( tau( jj ) )
361 END IF
362 END IF
363
364 IF( iacol.NE.iccol ) THEN
365 IF( mycol.EQ.iacol )
366 $ CALL cgesd2d( ictxt, 1, 1, ajj, 1, myrow, iccol )
367 IF( mycol.EQ.iccol )
368 $ CALL cgerv2d( ictxt, 1, 1, ajj, 1, myrow, iacol )
369 END IF
370
371 IF( mycol.EQ.iccol ) THEN
372 mp =
numroc( ic+m-1, descc( mb_ ), myrow, descc( rsrc_ ),
373 $ nprow )
374 CALL cscal( mp-icc+1, ajj, c( icc+(jcc-1)*
375 $ descc( lld_ ) ), 1 )
376 END IF
377
378 END IF
379
380 ELSE
381
382 CALL pb_topget( ictxt, 'Broadcast', 'Rowwise', rowbtop )
383 CALL pb_topget( ictxt, 'Broadcast', 'Columnwise', colbtop )
384
385 IF( left .AND. .NOT.notran .OR. .NOT.left .AND. notran ) THEN
386 j1 = ja
387 j2 = ja+k-1
388 j3 = 1
389 ELSE
390 j1 = ja+k-1
391 j2 = ja
392 j3 = -1
393 END IF
394
395 IF( left ) THEN
396 ni = n
397 jcc = jc
398 IF( notran ) THEN
399 CALL pb_topset( ictxt, 'Broadcast', 'Rowwise', 'D-ring' )
400 ELSE
401 CALL pb_topset( ictxt, 'Broadcast', 'Rowwise', 'I-ring' )
402 END IF
403 CALL pb_topset( ictxt, 'Broadcast', 'Columnwise', ' ' )
404 ELSE
405 mi = m
406 icc = ic
407 END IF
408
409 DO 10 j = j1, j2, j3
410 IF( left ) THEN
411
412
413
414 mi = m - j + ja
415 icc = ic + j - ja
416 ELSE
417
418
419
420 ni = n - j + ja
421 jcc = jc + j - ja
422 END IF
423
424
425
426 CALL pcelset2( ajj, a, ia+j-ja, j, desca, one )
427 IF( notran ) THEN
428 CALL pclarf( side, mi, ni, a, ia+j-ja, j, desca, 1, tau,
429 $ c, icc, jcc, descc, work )
430 ELSE
431 CALL pclarfc( side, mi, ni, a, ia+j-ja, j, desca, 1, tau,
432 $ c, icc, jcc, descc, work )
433 END IF
434 CALL pcelset( a, ia+j-ja, j, desca, ajj )
435
436 10 CONTINUE
437
438 CALL pb_topset( ictxt, 'Broadcast', 'Rowwise', rowbtop )
439 CALL pb_topset( ictxt, 'Broadcast', 'Columnwise', colbtop )
440
441 END IF
442
443 work( 1 ) =
cmplx( real( lwmin ) )
444
445 RETURN
446
447
448
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)