3
4
5
6
7
8
9
10 INTEGER IA, INFO, JA, K, LWORK, M, N
11
12
13 INTEGER DESCA( * )
14 COMPLEX*16 A( * ), TAU( * ), WORK( * )
15
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 INTEGER BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
158 $ LLD_, MB_, M_, NB_, N_, RSRC_
159 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
160 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
161 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
162 COMPLEX*16 ZERO
163 parameter( zero = ( 0.0d+0, 0.0d+0 ) )
164
165
166 LOGICAL LQUERY
167 CHARACTER COLBTOP, ROWBTOP
168 INTEGER I, IACOL, IAROW, IB, ICTXT, IINFO, IL, IN, IPW,
169 $ J, LWMIN, MPA0, MYCOL, MYROW, NPCOL, NPROW,
170 $ NQA0
171
172
173 INTEGER IDUM1( 2 ), IDUM2( 2 )
174
175
179
180
181 INTEGER ICEIL, INDXG2P, NUMROC
183
184
185 INTRINSIC dble, dcmplx,
max,
min, mod
186
187
188
189
190
191 ictxt = desca( ctxt_ )
192 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
193
194
195
196 info = 0
197 IF( nprow.EQ.-1 ) THEN
198 info = -(700+ctxt_)
199 ELSE
200 CALL chk1mat( m, 1, n, 2, ia, ja, desca, 7, info )
201 IF( info.EQ.0 ) THEN
202 iarow =
indxg2p( ia, desca( mb_ ), myrow, desca( rsrc_ ),
203 $ nprow )
204 iacol =
indxg2p( ja, desca( nb_ ), mycol, desca( csrc_ ),
205 $ npcol )
206 mpa0 =
numroc( m+mod( ia-1, desca( mb_ ) ), desca( mb_ ),
207 $ myrow, iarow, nprow )
208 nqa0 =
numroc( n+mod( ja-1, desca( nb_ ) ), desca( nb_ ),
209 $ mycol, iacol, npcol )
210 lwmin = desca( mb_ ) * ( mpa0 + nqa0 + desca( mb_ ) )
211
212 work( 1 ) = dcmplx( dble( lwmin ) )
213 lquery = ( lwork.EQ.-1 )
214 IF( n.LT.m ) THEN
215 info = -2
216 ELSE IF( k.LT.0 .OR. k.GT.m ) THEN
217 info = -3
218 ELSE IF( lwork.LT.lwmin .AND. .NOT.lquery ) THEN
219 info = -10
220 END IF
221 END IF
222 idum1( 1 ) = k
223 idum2( 1 ) = 3
224 IF( lwork.EQ.-1 ) THEN
225 idum1( 2 ) = -1
226 ELSE
227 idum1( 2 ) = 1
228 END IF
229 idum2( 2 ) = 10
230 CALL pchk1mat( m, 1, n, 2, ia, ja, desca, 7, 2, idum1, idum2,
231 $ info )
232 END IF
233
234 IF( info.NE.0 ) THEN
235 CALL pxerbla( ictxt,
'PZUNGLQ', -info )
236 RETURN
237 ELSE IF( lquery ) THEN
238 RETURN
239 END IF
240
241
242
243 IF( m.LE.0 )
244 $ RETURN
245
246 ipw = desca( mb_ ) * desca( mb_ ) + 1
247 in =
min(
iceil( ia, desca( mb_ ) ) * desca( mb_ ), ia+k-1 )
248 il =
max( ( (ia+k-2) / desca( mb_ ) ) * desca( mb_ ) + 1, ia )
249 CALL pb_topget( ictxt, 'Broadcast', 'Rowwise', rowbtop )
250 CALL pb_topget( ictxt, 'Broadcast', 'Columnwise', colbtop )
251 CALL pb_topset( ictxt, 'Broadcast', 'Rowwise', ' ' )
252 CALL pb_topset( ictxt, 'Broadcast', 'Columnwise', 'D-ring' )
253
254 CALL pzlaset(
'All', ia+m-il, il-ia, zero, zero, a, il, ja,
255 $ desca )
256
257
258
259 CALL pzungl2( ia+m-il, n-il+ia, ia+k-il, a, il, ja+il-ia, desca,
260 $ tau, work, lwork, iinfo )
261
262
263
264 IF( il.GT.in+1 ) THEN
265
266
267
268 DO 10 i = il-desca( mb_ ), in+1, -desca( mb_ )
269 ib =
min( desca( mb_ ), ia+m-i )
270 j = ja + i - ia
271
272 IF( i+ib.LE.ia+m-1 ) THEN
273
274
275
276
277 CALL pzlarft(
'Forward',
'Rowwise', n-i+ia, ib, a, i, j,
278 $ desca, tau, work, work( ipw ) )
279
280
281
282 CALL pzlarfb(
'Right',
'Conjugate transpose',
'Forward',
283 $ 'Rowwise', m-i-ib+ia, n-i+ia, ib, a, i, j,
284 $ desca, work, a, i+ib, j, desca,
285 $ work( ipw ) )
286 END IF
287
288
289
290 CALL pzungl2( ib, n-i+ia, ib, a, i, j, desca, tau, work,
291 $ lwork, iinfo )
292
293
294
295 CALL pzlaset(
'All', ib, i-ia, zero, zero, a, i, ja, desca )
296 10 CONTINUE
297
298 END IF
299
300
301
302 IF( il.GT.ia ) THEN
303
304 ib = in - ia + 1
305
306
307
308
309 CALL pzlarft(
'Forward',
'Rowwise', n, ib, a, ia, ja, desca,
310 $ tau, work, work( ipw ) )
311
312
313
314 CALL pzlarfb(
'Right',
'Conjugate transpose',
'Forward',
315 $ 'Rowwise', m-ib, n, ib, a, ia, ja, desca, work,
316 $ a, ia+ib, ja, desca, work( ipw ) )
317
318
319
320 CALL pzungl2( ib, n, ib, a, ia, ja, desca, tau, work, lwork,
321 $ iinfo )
322
323 END IF
324
325 CALL pb_topset( ictxt, 'Broadcast', 'Rowwise', rowbtop )
326 CALL pb_topset( ictxt, 'Broadcast', 'Columnwise', colbtop )
327
328 work( 1 ) = dcmplx( dble( lwmin ) )
329
330 RETURN
331
332
333
subroutine chk1mat(ma, mapos0, na, napos0, ia, ja, desca, descapos0, info)
integer function iceil(inum, idenom)
integer function indxg2p(indxglob, nb, iproc, isrcproc, nprocs)
integer function numroc(n, nb, iproc, isrcproc, nprocs)
subroutine pchk1mat(ma, mapos0, na, napos0, ia, ja, desca, descapos0, nextra, ex, expos, info)
subroutine pxerbla(ictxt, srname, info)
subroutine pzlaset(uplo, m, n, alpha, beta, a, ia, ja, desca)
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 pzungl2(m, n, k, a, ia, ja, desca, tau, work, lwork, info)