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 REAL 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 REAL ONE
215 parameter( one = 1.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 REAL AJJ
225
226
229 $ pb_topset,
pxerbla, sgebr2d, sgebs2d,
230 $ sgerv2d, sgesd2d, sscal
231
232
233 LOGICAL LSAME
234 INTEGER ILCM, INDXG2P, NUMROC
236
237
238 INTRINSIC 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 ) = 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,
'T' ) )
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,
'PSORM2L', -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 ajj = one - tau( jj )
338 CALL sgebs2d( ictxt, 'Rowwise', ' ', 1, 1, ajj, 1 )
339 CALL sscal( nq-jcc+1, ajj,
340 $ c( icc+(jcc-1)*descc( lld_ ) ),
341 $ descc( lld_ ) )
342 ELSE
343 CALL sgebr2d( ictxt, 'Rowwise', ' ', 1, 1, ajj, 1,
344 $ iarow, iacol )
345 CALL sscal( nq-jcc+1, ajj,
346 $ c( icc+(jcc-1)*descc( lld_ ) ),
347 $ descc( lld_ ) )
348 END IF
349 END IF
350 ELSE
351 IF( mycol.EQ.iacol ) THEN
352 ajj = one - tau( jj )
353 END IF
354
355 IF( iacol.NE.iccol ) THEN
356 IF( mycol.EQ.iacol )
357 $ CALL sgesd2d( ictxt, 1, 1, ajj, 1, myrow, iccol )
358 IF( mycol.EQ.iccol )
359 $ CALL sgerv2d( ictxt, 1, 1, ajj, 1, myrow, iacol )
360 END IF
361
362 IF( mycol.EQ.iccol ) THEN
363 mp =
numroc( ic+m-1, descc( mb_ ), myrow, descc( rsrc_ ),
364 $ nprow )
365 CALL sscal( mp-icc+1, ajj, c( icc+(jcc-1)*
366 $ descc( lld_ ) ), 1 )
367 END IF
368
369 END IF
370
371 ELSE
372
373 CALL pb_topget( ictxt, 'Broadcast', 'Rowwise', rowbtop )
374 CALL pb_topget( ictxt, 'Broadcast', 'Columnwise', colbtop )
375
376 IF( left .AND. notran .OR. .NOT.left .AND. .NOT.notran ) THEN
377 j1 = ja
378 j2 = ja+k-1
379 j3 = 1
380 ELSE
381 j1 = ja+k-1
382 j2 = ja
383 j3 = -1
384 END IF
385
386 IF( left ) THEN
387 ni = n
388 IF( notran ) THEN
389 CALL pb_topset( ictxt, 'Broadcast', 'Rowwise', 'I-ring' )
390 ELSE
391 CALL pb_topset( ictxt, 'Broadcast', 'Rowwise', 'D-ring' )
392 END IF
393 CALL pb_topset( ictxt, 'Broadcast', 'Columnwise', ' ' )
394 ELSE
395 mi = m
396 END IF
397
398 DO 10 j = j1, j2, j3
399
400 IF( left ) THEN
401
402
403
404 mi = m - k + j - ja + 1
405 ELSE
406
407
408
409 ni = n - k + j - ja + 1
410 END IF
411
412
413
414 CALL pselset2( ajj, a, ia+nq-k+j-ja, j, desca, one )
415 CALL pslarf( side, mi, ni, a, ia, j, desca, 1, tau, c, ic,
416 $ jc, descc, work )
417 CALL pselset( a, ia+nq-k+j-ja, j, desca, ajj )
418
419 10 CONTINUE
420
421 CALL pb_topset( ictxt, 'Broadcast', 'Rowwise', rowbtop )
422 CALL pb_topset( ictxt, 'Broadcast', 'Columnwise', colbtop )
423
424 END IF
425
426 work( 1 ) = real( lwmin )
427
428 RETURN
429
430
431
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 pselset2(alpha, a, ia, ja, desca, beta)
subroutine pselset(a, ia, ja, desca, alpha)
subroutine pslarf(side, m, n, v, iv, jv, descv, incv, tau, c, ic, jc, descc, work)
subroutine pxerbla(ictxt, srname, info)