3
4
5
6
7
8
9
10 CHARACTER SIDE, TRANS, UPLO
11 INTEGER IA, IC, INFO, JA, JC, 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
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235 INTEGER BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
236 $ LLD_, MB_, M_, NB_, N_, RSRC_
237 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
238 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
239 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
240
241
242 LOGICAL LEFT, LQUERY, NOTRAN, UPPER
243 INTEGER IAA, IAROW, ICC, ICCOL, ICOFFC, ICROW, ICTXT,
244 $ IINFO, IROFFA, IROFFC, JAA, JCC, LCM, LCMQ,
245 $ LWMIN, MI, MPC0, MYCOL, MYROW, NI, NPA0, NPCOL,
246 $ NPROW, NQ, NQC0
247
248
249 INTEGER IDUM1( 4 ), IDUM2( 4 )
250
251
254
255
256 LOGICAL LSAME
257 INTEGER ILCM, INDXG2P, NUMROC
259
260
261 INTRINSIC ichar,
max, mod, real
262
263
264
265
266
267 ictxt = desca( ctxt_ )
268 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
269
270
271
272 info = 0
273 IF( nprow.EQ.-1 ) THEN
274 info = -(900+ctxt_)
275 ELSE
276 left =
lsame( side,
'L' )
277 notran =
lsame( trans,
'N' )
278 upper =
lsame( uplo,
'U' )
279
280 IF( upper ) THEN
281 iaa = ia
282 jaa = ja+1
283 icc = ic
284 jcc = jc
285 ELSE
286 iaa = ia+1
287 jaa = ja
288 IF( left ) THEN
289 icc = ic + 1
290 jcc = jc
291 ELSE
292 icc = ic
293 jcc = jc + 1
294 END IF
295 END IF
296
297
298
299 IF( left ) THEN
300 nq = m
301 mi = m - 1
302 ni = n
303 CALL chk1mat( mi, 4, nq-1, 4, iaa, jaa, desca, 9, info )
304 ELSE
305 nq = n
306 mi = m
307 ni = n - 1
308 CALL chk1mat( ni, 5, nq-1, 5, iaa, jaa, desca, 9, info )
309 END IF
310 CALL chk1mat( mi, 4, ni, 5, icc, jcc, descc, 14, info )
311 IF( info.EQ.0 ) THEN
312 iroffa = mod( iaa-1, desca( mb_ ) )
313 iroffc = mod( icc-1, descc( mb_ ) )
314 icoffc = mod( jcc-1, descc( nb_ ) )
315 iarow =
indxg2p( iaa, desca( mb_ ), myrow, desca( rsrc_ ),
316 $ nprow )
317 icrow =
indxg2p( icc, descc( mb_ ), myrow, descc( rsrc_ ),
318 $ nprow )
319 iccol =
indxg2p( jcc, descc( nb_ ), mycol, descc( csrc_ ),
320 $ npcol )
321 mpc0 =
numroc( mi+iroffc, descc( mb_ ), myrow, icrow,
322 $ nprow )
323 nqc0 =
numroc( ni+icoffc, descc( nb_ ), mycol, iccol,
324 $ npcol )
325
326 IF( left ) THEN
327 lwmin =
max( ( desca( nb_ ) * ( desca( nb_ ) - 1 ) ) / 2,
328 $ ( mpc0 + nqc0 ) * desca( nb_ ) ) +
329 $ desca( nb_ ) * desca( nb_ )
330 ELSE
331 npa0 =
numroc( ni+iroffa, desca( mb_ ), myrow, iarow,
332 $ nprow )
333 lcm =
ilcm( nprow, npcol )
334 lcmq = lcm / npcol
335 lwmin =
max( ( desca( nb_ ) * ( desca( nb_ ) - 1 ) )
337 $ ni+icoffc, desca( nb_ ), 0, 0, npcol ),
338 $ desca( nb_ ), 0, 0, lcmq ), mpc0 ) ) *
339 $ desca( nb_ ) ) + desca( nb_ ) * desca( nb_ )
340 END IF
341
342 work( 1 ) = real( lwmin )
343 lquery = ( lwork.EQ.-1 )
344 IF( .NOT.left .AND. .NOT.
lsame( side,
'R' ) )
THEN
345 info = -1
346 ELSE IF( .NOT.upper .AND. .NOT.
lsame( uplo,
'L' ) )
THEN
347 info = -2
348 ELSE IF( .NOT.
lsame( trans,
'N' ) .AND.
349 $ .NOT.
lsame( trans,
'T' ) )
THEN
350 info = -3
351 ELSE IF( .NOT.left .AND. desca( mb_ ).NE.descc( nb_ ) ) THEN
352 info = -(900+nb_)
353 ELSE IF( left .AND. iroffa.NE.iroffc ) THEN
354 info = -12
355 ELSE IF( left .AND. iarow.NE.icrow ) THEN
356 info = -12
357 ELSE IF( .NOT.left .AND. iroffa.NE.icoffc ) THEN
358 info = -13
359 ELSE IF( left .AND. desca( mb_ ).NE.descc( mb_ ) ) THEN
360 info = -(1400+mb_)
361 ELSE IF( ictxt.NE.descc( ctxt_ ) ) THEN
362 info = -(1400+ctxt_)
363 ELSE IF( lwork.LT.lwmin .AND. .NOT.lquery ) THEN
364 info = -16
365 END IF
366 END IF
367
368 IF( left ) THEN
369 idum1( 1 ) = ichar( 'L' )
370 ELSE
371 idum1( 1 ) = ichar( 'R' )
372 END IF
373 idum2( 1 ) = 1
374 IF( upper ) THEN
375 idum1( 2 ) = ichar( 'U' )
376 ELSE
377 idum1( 2 ) = ichar( 'L' )
378 END IF
379 idum2( 2 ) = 2
380 IF( notran ) THEN
381 idum1( 3 ) = ichar( 'N' )
382 ELSE
383 idum1( 3 ) = ichar( 'T' )
384 END IF
385 idum2( 3 ) = 3
386 IF( lwork.EQ.-1 ) THEN
387 idum1( 4 ) = -1
388 ELSE
389 idum1( 4 ) = 1
390 END IF
391 idum2( 4 ) = 16
392 IF( left ) THEN
393 CALL pchk2mat( mi, 4, nq-1, 4, iaa, jaa, desca, 9, mi, 4,
394 $ ni, 5, icc, jcc, descc, 14, 4, idum1, idum2,
395 $ info )
396 ELSE
397 CALL pchk2mat( ni, 5, nq-1, 5, iaa, jaa, desca, 9, mi, 4,
398 $ ni, 5, icc, jcc, descc, 14, 4, idum1, idum2,
399 $ info )
400 END IF
401 END IF
402
403 IF( info.NE.0 ) THEN
404 CALL pxerbla( ictxt,
'PSORMTR', -info )
405 RETURN
406 ELSE IF( lquery ) THEN
407 RETURN
408 END IF
409
410
411
412 IF( m.EQ.0 .OR. n.EQ.0 .OR. nq.EQ.1 )
413 $ RETURN
414
415 IF( upper ) THEN
416
417
418
419 CALL psormql( side, trans, mi, ni, nq-1, a, iaa, jaa, desca,
420 $ tau, c, icc, jcc, descc, work, lwork, iinfo )
421
422 ELSE
423
424
425
426 CALL psormqr( side, trans, mi, ni, nq-1, a, iaa, jaa, desca,
427 $ tau, c, icc, jcc, descc, work, lwork, iinfo )
428
429 END IF
430
431 work( 1 ) = real( lwmin )
432
433 RETURN
434
435
436
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 pchk2mat(ma, mapos0, na, napos0, ia, ja, desca, descapos0, mb, mbpos0, nb, nbpos0, ib, jb, descb, descbpos0, nextra, ex, expos, info)
subroutine psormql(side, trans, m, n, k, a, ia, ja, desca, tau, c, ic, jc, descc, work, lwork, info)
subroutine psormqr(side, trans, m, n, k, a, ia, ja, desca, tau, c, ic, jc, descc, work, lwork, info)
subroutine pxerbla(ictxt, srname, info)