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 COMPLEX 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
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 ) =
cmplx( real( lwmin ) )
318 lquery = ( lwork.EQ.-1 )
319 IF( .NOT.left .AND. .NOT.
lsame( side,
'R' ) )
THEN
320 info = -1
321 ELSE IF( .NOT.notran .AND. .NOT.
lsame( trans,
'C' ) )
THEN
322 info = -2
323 ELSE IF( ilo.LT.1 .OR. ilo.GT.
max( 1, nq ) )
THEN
324 info = -5
325 ELSE IF( ihi.LT.
min( ilo, nq ) .OR. ihi.GT.nq )
THEN
326 info = -6
327 ELSE IF( .NOT.left .AND. desca( mb_ ).NE.descc( nb_ ) ) THEN
328 info = -(1000+nb_)
329 ELSE IF( left .AND. iroffa.NE.iroffc ) THEN
330 info = -13
331 ELSE IF( left .AND. iarow.NE.icrow ) THEN
332 info = -13
333 ELSE IF( .NOT.left .AND. iroffa.NE.icoffc ) THEN
334 info = -14
335 ELSE IF( left .AND. desca( mb_ ).NE.descc( mb_ ) ) THEN
336 info = -(1500+mb_)
337 ELSE IF( ictxt.NE.descc( ctxt_ ) ) THEN
338 info = -(1500+ctxt_)
339 ELSE IF( lwork.LT.lwmin .AND. .NOT.lquery ) THEN
340 info = -17
341 END IF
342 END IF
343
344 IF( left ) THEN
345 idum1( 1 ) = ichar( 'L' )
346 ELSE
347 idum1( 1 ) = ichar( 'R' )
348 END IF
349 idum2( 1 ) = 1
350 IF( notran ) THEN
351 idum1( 2 ) = ichar( 'N' )
352 ELSE
353 idum1( 2 ) = ichar( 'C' )
354 END IF
355 idum2( 2 ) = 2
356 idum1( 3 ) = ilo
357 idum2( 3 ) = 5
358 idum1( 4 ) = ihi
359 idum2( 4 ) = 6
360 IF( lwork.EQ.-1 ) THEN
361 idum1( 5 ) = -1
362 ELSE
363 idum1( 5 ) = 1
364 END IF
365 idum2( 5 ) = 17
366 IF( left ) THEN
367 CALL pchk2mat( m, 3, m, 3, ia, ja, desca, 10, m, 3, n, 4,
368 $ ic, jc, descc, 15, 5, idum1, idum2, info )
369 ELSE
370 CALL pchk2mat( n, 4, n, 4, ia, ja, desca, 10, m, 3, n, 4,
371 $ ic, jc, descc, 15, 5, idum1, idum2, info )
372 END IF
373 END IF
374
375 IF( info.NE.0 ) THEN
376 CALL pxerbla( ictxt,
'PCUNMHR', -info )
377 RETURN
378 ELSE IF( lquery ) THEN
379 RETURN
380 END IF
381
382
383
384 IF( m.EQ.0 .OR. n.EQ.0 .OR. nh.EQ.0 )
385 $ RETURN
386
387 CALL pcunmqr( side, trans, mi, ni, nh, a, iaa, jaa, desca, tau,
388 $ c, icc, jcc, descc, work, lwork, iinfo )
389
390 work( 1 ) =
cmplx( real( lwmin ) )
391
392 RETURN
393
394
395
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 pcunmqr(side, trans, m, n, k, a, ia, ja, desca, tau, c, ic, jc, descc, work, lwork, info)
subroutine pxerbla(ictxt, srname, info)