3
4
5
6
7
8
9
10 CHARACTER SIDE, TRANS
11 INTEGER IA, IC, IHI, ILO, 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 INTEGER BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
222 $ LLD_, MB_, M_, NB_, N_, RSRC_
223 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
224 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
225 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
226
227
228 LOGICAL LEFT, LQUERY, NOTRAN
229 INTEGER IAA, IAROW, ICC, ICCOL, ICOFFC, ICROW, ICTXT,
230 $ IINFO, IROFFA, IROFFC, JAA, JCC, LCM, LCMQ,
231 $ LWMIN, MI, MPC0, MYCOL, MYROW, NH, NI, NPA0,
232 $ NPCOL, NPROW, NQ, NQC0
233
234
235 INTEGER IDUM1( 5 ), IDUM2( 5 )
236
237
240
241
242 LOGICAL LSAME
243 INTEGER ILCM, INDXG2P, NUMROC
245
246
247 INTRINSIC ichar,
max,
min, mod, real
248
249
250
251
252
253 ictxt = desca( ctxt_ )
254 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
255
256
257
258 info = 0
259 nh = ihi - ilo
260 IF( nprow.EQ.-1 ) THEN
261 info = -(1000+ctxt_)
262 ELSE
263 left =
lsame( side,
'L' )
264 notran =
lsame( trans,
'N' )
265 iaa = ia + ilo
266 jaa = ja + ilo - 1
267
268
269
270 IF( left ) THEN
271 nq = m
272 mi = nh
273 ni = n
274 icc = ic + ilo
275 jcc = jc
276 CALL chk1mat( m, 3, m, 3, ia, ja, desca, 10, info )
277 ELSE
278 nq = n
279 mi = m
280 ni = nh
281 icc = ic
282 jcc = jc + ilo
283 CALL chk1mat( n, 4, n, 4, ia, ja, desca, 10, info )
284 END IF
285 CALL chk1mat( m, 3, n, 4, ic, jc, descc, 15, info )
286 IF( info.EQ.0 ) THEN
287 iroffa = mod( iaa-1, desca( mb_ ) )
288 iroffc = mod( icc-1, descc( mb_ ) )
289 icoffc = mod( jcc-1, descc( nb_ ) )
290 iarow =
indxg2p( iaa, desca( mb_ ), myrow, desca( rsrc_ ),
291 $ nprow )
292 icrow =
indxg2p( icc, descc( mb_ ), myrow, descc( rsrc_ ),
293 $ nprow )
294 iccol =
indxg2p( jcc, descc( nb_ ), mycol, descc( csrc_ ),
295 $ npcol )
296 mpc0 =
numroc( mi+iroffc, descc( mb_ ), myrow, icrow,
297 $ nprow )
298 nqc0 =
numroc( ni+icoffc, descc( nb_ ), mycol, iccol,
299 $ npcol )
300
301 IF( left ) THEN
302 lwmin =
max( ( desca( nb_ ) * ( desca( nb_ ) - 1 ) ) / 2,
303 $ ( mpc0 + nqc0 ) * desca( nb_ ) ) +
304 $ desca( nb_ ) * desca( nb_ )
305 ELSE
306 npa0 =
numroc( ni+iroffa, desca( mb_ ), myrow, iarow,
307 $ nprow )
308 lcm =
ilcm( nprow, npcol )
309 lcmq = lcm / npcol
310 lwmin =
max( ( desca( nb_ ) * ( desca( nb_ ) - 1 ) )
312 $ ni+icoffc, desca( nb_ ), 0, 0, npcol ),
313 $ desca( nb_ ), 0, 0, lcmq ), mpc0 ) ) *
314 $ desca( nb_ ) ) + desca( nb_ ) * desca( nb_ )
315 END IF
316
317 work( 1 ) = real( lwmin )
318 lquery = ( lwork.EQ.-1 )
319 IF( .NOT.left .AND. .NOT.
lsame( side,
'R' ) )
THEN
320 info = -1
321 ELSE IF( .NOT.
lsame( trans,
'N' ) .AND.
322 $ .NOT.
lsame( trans,
'T' ) )
THEN
323 info = -2
324 ELSE IF( ilo.LT.1 .OR. ilo.GT.
max( 1, nq ) )
THEN
325 info = -5
326 ELSE IF( ihi.LT.
min( ilo, nq ) .OR. ihi.GT.nq )
THEN
327 info = -6
328 ELSE IF( .NOT.left .AND. desca( mb_ ).NE.descc( nb_ ) ) THEN
329 info = -(1000+nb_)
330 ELSE IF( left .AND. iroffa.NE.iroffc ) THEN
331 info = -13
332 ELSE IF( left .AND. iarow.NE.icrow ) THEN
333 info = -13
334 ELSE IF( .NOT.left .AND. iroffa.NE.icoffc ) THEN
335 info = -14
336 ELSE IF( left .AND. desca( mb_ ).NE.descc( mb_ ) ) THEN
337 info = -(1500+mb_)
338 ELSE IF( ictxt.NE.descc( ctxt_ ) ) THEN
339 info = -(1500+ctxt_)
340 ELSE IF( lwork.LT.lwmin .AND. .NOT.lquery ) THEN
341 info = -17
342 END IF
343 END IF
344
345 IF( left ) THEN
346 idum1( 1 ) = ichar( 'L' )
347 ELSE
348 idum1( 1 ) = ichar( 'R' )
349 END IF
350 idum2( 1 ) = 1
351 IF( notran ) THEN
352 idum1( 2 ) = ichar( 'N' )
353 ELSE
354 idum1( 2 ) = ichar( 'T' )
355 END IF
356 idum2( 2 ) = 2
357 idum1( 3 ) = ilo
358 idum2( 3 ) = 5
359 idum1( 4 ) = ihi
360 idum2( 4 ) = 6
361 IF( lwork.EQ.-1 ) THEN
362 idum1( 5 ) = -1
363 ELSE
364 idum1( 5 ) = 1
365 END IF
366 idum2( 5 ) = 17
367 IF( left ) THEN
368 CALL pchk2mat( m, 3, m, 3, ia, ja, desca, 10, m, 3, n, 4,
369 $ ic, jc, descc, 15, 5, idum1, idum2, info )
370 ELSE
371 CALL pchk2mat( n, 4, n, 4, ia, ja, desca, 10, m, 3, n, 4,
372 $ ic, jc, descc, 15, 5, idum1, idum2, info )
373 END IF
374 END IF
375
376 IF( info.NE.0 ) THEN
377 CALL pxerbla( ictxt,
'PSORMHR', -info )
378 RETURN
379 ELSE IF( lquery ) THEN
380 RETURN
381 END IF
382
383
384
385 IF( m.EQ.0 .OR. n.EQ.0 .OR. nh.EQ.0 )
386 $ RETURN
387
388 CALL psormqr( side, trans, mi, ni, nh, a, iaa, jaa, desca, tau,
389 $ c, icc, jcc, descc, work, lwork, iinfo )
390
391 work( 1 ) = real( lwmin )
392
393 RETURN
394
395
396
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 psormqr(side, trans, m, n, k, a, ia, ja, desca, tau, c, ic, jc, descc, work, lwork, info)
subroutine pxerbla(ictxt, srname, info)