3
4
5
6
7
8
9
10 CHARACTER SIDE, TRANS
11 INTEGER IA, IC, INFO, JA, JC, K, L, 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
210
211
212
213
214 INTEGER BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
215 $ LLD_, MB_, M_, NB_, N_, RSRC_
216 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
217 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
218 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
219
220
221 LOGICAL LEFT, LQUERY, NOTRAN
222 CHARACTER COLBTOP, ROWBTOP
223 INTEGER I, I1, I2, I3, IACOL, ICC, ICCOL, ICOFFA,
224 $ ICOFFC, ICROW, ICTXT, IROFFC, JAA, JCC, LCM,
225 $ LCMP, LWMIN, MI, MPC0, MYCOL, MYROW, NI, NPCOL,
226 $ NPROW, NQ, NQC0
227
228
230 $ pb_topget, pb_topset,
pxerbla
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( k, 5, m, 3, ia, ja, desca, 10, info )
261 ELSE
262 nq = n
263 CALL chk1mat( k, 5, n, 4, ia, ja, desca, 10, info )
264 END IF
265 CALL chk1mat( m, 3, n, 4, ic, jc, descc, 15, info )
266 IF( info.EQ.0 ) THEN
267 icoffa = mod( ja-1, desca( nb_ ) )
268 iroffc = mod( ic-1, descc( mb_ ) )
269 icoffc = mod( jc-1, descc( nb_ ) )
270 iacol =
indxg2p( ja, desca( nb_ ), mycol, desca( csrc_ ),
271 $ npcol )
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 lcm =
ilcm( nprow, npcol )
281 lcmp = lcm / nprow
283 $ m+iroffc, desca( mb_ ), 0, 0, nprow ),
284 $ desca( mb_ ), 0, 0, lcmp ) )
285 ELSE
286 lwmin = nqc0 +
max( 1, mpc0 )
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( l.LT.0 .OR. l.GT.nq ) THEN
298 info = -6
299 ELSE IF( left .AND. desca( nb_ ).NE.descc( mb_ ) ) THEN
300 info = -(1000+nb_)
301 ELSE IF( left .AND. icoffa.NE.iroffc ) THEN
302 info = -13
303 ELSE IF( .NOT.left .AND. icoffa.NE.icoffc ) THEN
304 info = -14
305 ELSE IF( .NOT.left .AND. iacol.NE.iccol ) THEN
306 info = -14
307 ELSE IF( .NOT.left .AND. desca( nb_ ).NE.descc( nb_ ) ) THEN
308 info = -(1500+nb_)
309 ELSE IF( ictxt.NE.descc( ctxt_ ) ) THEN
310 info = -(1500+ctxt_)
311 ELSE IF( lwork.LT.lwmin .AND. .NOT.lquery ) THEN
312 info = -17
313 END IF
314 END IF
315 END IF
316
317 IF( info.NE.0 ) THEN
318 CALL pxerbla( ictxt,
'PSORMR3', -info )
319 CALL blacs_abort( ictxt, 1 )
320 RETURN
321 ELSE IF( lquery ) THEN
322 RETURN
323 END IF
324
325
326
327 IF( m.EQ.0 .OR. n.EQ.0 .OR. k.EQ.0 )
328 $ RETURN
329
330 CALL pb_topget( ictxt, 'Broadcast', 'Rowwise', rowbtop )
331 CALL pb_topget( ictxt, 'Broadcast', 'Columnwise', colbtop )
332
333 IF( ( left .AND. .NOT.notran .OR. .NOT.left .AND. notran ) ) THEN
334 i1 = ia
335 i2 = ia + k - 1
336 i3 = 1
337 ELSE
338 i1 = ia + k - 1
339 i2 = ia
340 i3 = -1
341 END IF
342
343 IF( left ) THEN
344 ni = n
345 jcc = jc
346 jaa = ja + m - l
347 ELSE
348 mi = m
349 icc = ic
350 jaa = ja + n - l
351 CALL pb_topset( ictxt, 'Broadcast', 'Rowwise', ' ' )
352 IF( notran ) THEN
353 CALL pb_topset( ictxt, 'Broadcast', 'Columnwise', 'I-ring' )
354 ELSE
355 CALL pb_topset( ictxt, 'Broadcast', 'Columnwise', 'D-ring' )
356 END IF
357 END IF
358
359 DO 10 i = i1, i2, i3
360 IF( left ) THEN
361
362
363
364 mi = m - i + ia
365 icc = ic + i - ia
366 ELSE
367
368
369
370 ni = n - i + ia
371 jcc = jc + i - ia
372 END IF
373
374
375
376 CALL pslarz( side, mi, ni, l, a, i, jaa, desca, desca( m_ ),
377 $ tau, c, icc, jcc, descc, work )
378
379 10 CONTINUE
380
381 CALL pb_topset( ictxt, 'Broadcast', 'Rowwise', rowbtop )
382 CALL pb_topset( ictxt, 'Broadcast', 'Columnwise', colbtop )
383
384 work( 1 ) = real( lwmin )
385
386 RETURN
387
388
389
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 pslarz(side, m, n, l, v, iv, jv, descv, incv, tau, c, ic, jc, descc, work)
subroutine pxerbla(ictxt, srname, info)