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