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 COMPLEX*16 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 INTEGER BLOCK_CYCLIC_2D, CSRC_, , DLEN_, DTYPE_,
220 $ LLD_, , M_, NB_, N_, RSRC_
221 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
222 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
223 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
224
225
226 LOGICAL LEFT, LQUERY, NOTRAN
227 CHARACTER COLBTOP, ROWBTOP
228 INTEGER IAROW, ICCOL, , ICROW, ICTXT, IINFO, IPW,
229 $ , J2, J3, JB, LCM, LCMQ,
230 $ LWMIN, MI, MPC0, MYCOL, MYROW, NI, , NPCOL,
231 $ NPROW, NQ,
232
233
234 INTEGER IDUM1( 4 ), IDUM2( 4 )
235
236
240
241
242 LOGICAL LSAME
243 INTEGER ICEIL
245
246
247 INTRINSIC dble, dcmplx, ichar,
max,
min, mod
248
249
250
251
252
253 ictxt = desca( ctxt_ )
255
256
257
258 info = 0
259 IF( nprow.EQ.-1 ) THEN
260 info = -(900+ctxt_)
261 ELSE
262 left =
lsame( side, 'l
' )
263 NOTRAN = LSAME( TRANS, 'n' )
264
265
266
267 IF( LEFT ) THEN
268 NQ = M
269 CALL CHK1MAT( M, 3, K, 5, IA, JA, DESCA, 9, INFO )
270 ELSE
271 NQ = N
272 CALL CHK1MAT( N, 4, K, 5, IA, JA, DESCA, 9, INFO )
273 END IF
274 CALL CHK1MAT( M, 3, N, 4, IC, JC, DESCC, 14, INFO )
275.EQ. IF( INFO0 ) THEN
276 IROFFA = MOD( IA-1, DESCA( MB_ ) )
277 IROFFC = MOD( IC-1, DESCC( MB_ ) )
278 ICOFFC = MOD( JC-1, DESCC( NB_ ) )
279 IAROW = INDXG2P( IA, DESCA( MB_ ), MYROW, DESCA( RSRC_ ),
280 $ NPROW )
281 ICROW = INDXG2P( IC, DESCC( MB_ ), MYROW, DESCC( RSRC_ ),
282 $ NPROW )
283 ICCOL = INDXG2P( JC, DESCC( NB_ ), MYCOL, DESCC( CSRC_ ),
284 $ NPCOL )
285 MPC0 = NUMROC( M+IROFFC, DESCC( MB_ ), MYROW, ICROW, NPROW )
286 NQC0 = NUMROC( N+ICOFFC, DESCC( NB_ ), MYCOL, ICCOL, NPCOL )
287
288 IF( LEFT ) THEN
289 LWMIN = MAX( ( DESCA( NB_ ) * ( DESCA( NB_ ) - 1 ) ) / 2,
290 $ ( MPC0 + NQC0 ) * DESCA( NB_ ) ) +
291 $ DESCA( NB_ ) * DESCA( NB_ )
292 ELSE
293 NPA0 = NUMROC( N+IROFFA, DESCA( MB_ ), MYROW, IAROW,
294 $ NPROW )
295 LCM = ILCM( NPROW, NPCOL )
296 LCMQ = LCM / NPCOL
297 LWMIN = MAX( ( DESCA( NB_ ) * ( DESCA( NB_ ) - 1 ) )
298 $ / 2, ( NQC0 + MAX( NPA0 + NUMROC( NUMROC(
299 $ N+ICOFFC, DESCA( NB_ ), 0, 0, NPCOL ),
300 $ DESCA( NB_ ), 0, 0, LCMQ ), MPC0 ) ) *
301 $ DESCA( NB_ ) ) + DESCA( NB_ ) * DESCA( NB_ )
302 END IF
303
304 WORK( 1 ) = DCMPLX( DBLE( LWMIN ) )
305.EQ. LQUERY = ( LWORK-1 )
306.NOT..AND..NOT. IF( LEFT LSAME( SIDE, 'r' ) ) THEN
307 INFO = -1
308.NOT..AND..NOT. ELSE IF( NOTRAN LSAME( TRANS, 'c' ) ) THEN
309 INFO = -2
310.LT..OR..GT. ELSE IF( K0 KNQ ) THEN
311 INFO = -5
312.NOT..AND..NE. ELSE IF( LEFT DESCA( MB_ )DESCC( NB_ ) ) THEN
313 INFO = -(900+NB_)
314.AND..NE. ELSE IF( LEFT IROFFAIROFFC ) THEN
315 INFO = -12
316.AND..NE. ELSE IF( LEFT IAROWICROW ) THEN
317 INFO = -12
318.NOT..AND..NE. ELSE IF( LEFT IROFFAICOFFC ) THEN
319 INFO = -13
320.AND..NE. ELSE IF( LEFT DESCA( MB_ )DESCC( MB_ ) ) THEN
321 INFO = -(1400+MB_)
322.NE. ELSE IF( ICTXTDESCC( CTXT_ ) ) THEN
323 INFO = -(1400+CTXT_)
324.LT..AND..NOT. ELSE IF( LWORKLWMIN LQUERY ) THEN
325 INFO = -16
326 END IF
327 END IF
328
329 IF( LEFT ) THEN
330 IDUM1( 1 ) = ICHAR( 'l' )
331 ELSE
332 IDUM1( 1 ) = ICHAR( 'r' )
333 END IF
334 IDUM2( 1 ) = 1
335 IF( NOTRAN ) THEN
336 IDUM1( 2 ) = ICHAR( 'n' )
337 ELSE
338 IDUM1( 2 ) = ICHAR( 'c' )
339 END IF
340 IDUM2( 2 ) = 2
341 IDUM1( 3 ) = K
342 IDUM2( 3 ) = 5
343.EQ. IF( LWORK-1 ) THEN
344 IDUM1( 4 ) = -1
345 ELSE
346 IDUM1( 4 ) = 1
347 END IF
348 IDUM2( 4 ) = 16
349 IF( LEFT ) THEN
350 CALL PCHK2MAT( M, 3, K, 5, IA, JA, DESCA, 9, M, 3, N, 4, IC,
351 $ JC, DESCC, 14, 4, IDUM1, IDUM2, INFO )
352 ELSE
353 CALL PCHK2MAT( N, 4, K, 5, IA, JA, DESCA, 9, M, 3, N, 4, IC,
354 $ JC, DESCC, 14, 4, IDUM1, IDUM2, INFO )
355 END IF
356 END IF
357
358.NE. IF( INFO0 ) THEN
359 CALL PXERBLA( ICTXT, 'pzunmql', -INFO )
360 RETURN
361 ELSE IF( LQUERY ) THEN
362 RETURN
363 END IF
364
365
366
367.EQ..OR..EQ..OR..EQ. IF( M0 N0 K0 )
368 $ RETURN
369
370 CALL PB_TOPGET( ICTXT, 'broadcast', 'rowwise', ROWBTOP )
371 CALL PB_TOPGET( ICTXT, 'broadcast', 'columnwise', COLBTOP )
372
373.AND..OR. IF( ( LEFT NOTRAN )
374.NOT..AND..NOT. $ ( LEFT NOTRAN ) ) THEN
375 J1 = MIN( ICEIL( JA, DESCA( NB_ ) )*DESCA( NB_ ), JA+K-1 ) + 1
376 J2 = JA+K-1
377 J3 = DESCA( NB_ )
378 ELSE
379 J1 = MAX( ( (JA+K-2) / DESCA( NB_ ) ) * DESCA( NB_ ) + 1, JA )
380 J2 = MIN( ICEIL( JA, DESCA( NB_ ) )*DESCA( NB_ ), JA+K-1 ) + 1
381 J3 = -DESCA( NB_ )
382 END IF
383
384 IF( LEFT ) THEN
385 NI = N
386 IF( NOTRAN ) THEN
387 CALL PB_TOPSET( ICTXT, 'broadcast', 'rowwise', 'i-ring' )
388 ELSE
389 CALL PB_TOPSET( ICTXT, 'broadcast', 'rowwise', 'd-ring' )
390 END IF
391 CALL PB_TOPSET( ICTXT, 'broadcast', 'columnwise', ' ' )
392 ELSE
393 MI = M
394 END IF
395
396
397
398.AND..OR. IF( ( LEFT NOTRAN )
399.NOT..AND..NOT. $ ( LEFT NOTRAN ) ) THEN
400 JB = J1 - JA
401 IF( LEFT ) THEN
402 MI = M - K + JB
403 ELSE
404 NI = N - K + JB
405 END IF
406 CALL PZUNM2L( SIDE, TRANS, MI, NI, JB, A, IA, JA, DESCA, TAU,
407 $ C, IC, JC, DESCC, WORK, LWORK, IINFO )
408 END IF
409
410 IPW = DESCA( NB_ ) * DESCA( NB_ ) + 1
411 DO 10 J = J1, J2, J3
412 JB = MIN( DESCA( NB_ ), K-J+JA )
413
414
415
416
417 CALL PZLARFT( 'backward', 'columnwise', NQ-K+J+JB-JA, JB,
418 $ A, IA, J, DESCA, TAU, WORK, WORK( IPW ) )
419 IF( LEFT ) THEN
420
421
422
423 MI = M - K + J + JB - JA
424 ELSE
425
426
427
428 NI = N - K + J + JB - JA
429 END IF
430
431
432
433 CALL PZLARFB( SIDE, TRANS, 'backward', 'columnwise', MI, NI,
434 $ JB, A, IA, J, DESCA, WORK, C, IC, JC, DESCC,
435 $ WORK( IPW ) )
436 10 CONTINUE
437
438.AND..NOT..OR. IF( ( LEFT NOTRAN )
439.NOT..AND. $ ( LEFT NOTRAN ) ) THEN
440 JB = J2 - JA
441 IF( LEFT ) THEN
442 MI = M - K + JB
443 ELSE
444 NI = N - K + JB
445 END IF
446 CALL PZUNM2L( SIDE, TRANS, MI, NI, JB, A, IA, JA, DESCA, TAU,
447 $ C, IC, JC, DESCC, WORK, LWORK, IINFO )
448 END IF
449
450 CALL PB_TOPSET( ICTXT, 'broadcast', 'rowwise', ROWBTOP )
451 CALL PB_TOPSET( ICTXT, 'broadcast', 'columnwise', COLBTOP )
452
453 WORK( 1 ) = DCMPLX( DBLE( LWMIN ) )
454
455 RETURN
456
457
458
logical function lsame(ca, cb)
LSAME
integer function iceil(inum, idenom)
integer function ilcm(m, n)
integer function indxg2p(indxglob, nb, iproc, isrcproc, nprocs)
subroutine chk1mat(ma, mapos0, na, napos0, ia, ja, desca, descapos0, info)
subroutine pxerbla(contxt, srname, info)
subroutine pchk2mat(ma, mapos0, na, napos0, ia, ja, desca, descapos0, mb, mbpos0, nb, nbpos0, ib, jb, descb, descbpos0, nextra, ex, expos, info)
subroutine blacs_gridinfo(cntxt, nprow, npcol, myrow, mycol)
integer function numroc(n, nb, iproc, isrcproc, nprocs)
subroutine pzlarfb(side, trans, direct, storev, m, n, k, v, iv, jv, descv, t, c, ic, jc, descc, work)
subroutine pzlarft(direct, storev, n, k, v, iv, jv, descv, tau, t, work)
subroutine pzunm2l(side, trans, m, n, k, a, ia, ja, desca, tau, c, ic, jc, descc, work, lwork, info)
subroutine pzunmql(side, trans, m, n, k, a, ia, ja, desca, tau, c, ic, jc, descc, work, lwork, info)