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 IACOL, IAROW, ICTXT, IINFO, IPW, J, JB, JN,
169 $ LWMIN, MPA0, MYCOL, MYROW, NPCOL, NPROW, NQA0
170
171
172 INTEGER IDUM1( 2 ), IDUM2( 2 )
173
174
178
179
180 INTEGER ICEIL, INDXG2P, NUMROC
182
183
184 INTRINSIC dble, dcmplx,
min, mod
185
186
187
188
189
190 ictxt = desca( ctxt_ )
191 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
192
193
194
195 info = 0
196 IF( nprow.EQ.-1 ) THEN
197 info = -(700+ctxt_)
198 ELSE
199 CALL chk1mat( m, 1, n, 2, ia, ja, desca, 7, info )
200 IF( info.EQ.0 ) THEN
201 iarow =
indxg2p( ia, desca( mb_ ), myrow, desca( rsrc_ ),
202 $ nprow )
203 iacol =
indxg2p( ja, desca( nb_ ), mycol, desca( csrc_ ),
204 $ npcol )
205 mpa0 =
numroc( m+mod( ia-1, desca( mb_ ) ), desca( mb_ ),
206 $ myrow, iarow, nprow )
207 nqa0 =
numroc( n+mod( ja-1, desca( nb_ ) ), desca( nb_ ),
208 $ mycol, iacol, npcol )
209 lwmin = desca( nb_ ) * ( mpa0 + nqa0 + desca( nb_ ) )
210
211 work( 1 ) = dcmplx( dble( lwmin ) )
212 lquery = ( lwork.EQ.-1 )
213 IF( n.GT.m ) THEN
214 info = -2
215 ELSE IF( k.LT.0 .OR. k.GT.n ) THEN
216 info = -3
217 ELSE IF( lwork.LT.lwmin .AND. .NOT.lquery ) THEN
218 info = -10
219 END IF
220 END IF
221 idum1( 1 ) = k
222 idum2( 1 ) = 3
223 IF( lwork.EQ.-1 ) THEN
224 idum1( 2 ) = -1
225 ELSE
226 idum1( 2 ) = 1
227 END IF
228 idum2( 2 ) = 10
229 CALL pchk1mat( m, 1, n, 2, ia, ja, desca, 7, 2, idum1, idum2,
230 $ info )
231 END IF
232 IF( info.NE.0 ) THEN
233 CALL pxerbla( ictxt,
'PZUNGQL', -info )
234 RETURN
235 ELSE IF( lquery ) THEN
236 RETURN
237 END IF
238
239
240
241 IF( n.LE.0 )
242 $ RETURN
243
244 ipw = desca( nb_ )*desca( nb_ ) + 1
245 jn =
min(
iceil( ja+n-k, desca( nb_ ) )*desca( nb_ ), ja+n-1 )
246 CALL pb_topget( ictxt, 'Broadcast', 'Rowwise', rowbtop )
247 CALL pb_topget( ictxt, 'Broadcast', 'Columnwise', colbtop )
248 CALL pb_topset( ictxt, 'Broadcast', 'Rowwise', 'I-ring' )
249 CALL pb_topset( ictxt, 'Broadcast', 'Columnwise', ' ' )
250
251
252
253 CALL pzlaset(
'All', n-jn+ja-1, jn-ja+1, zero, zero, a,
254 $ ia+m-n+jn-ja+1, ja, desca )
255
256
257
258 CALL pzung2l( m-n+jn-ja+1, jn-ja+1, jn-ja-n+k+1, a, ia, ja, desca,
259 $ tau, work, lwork, iinfo )
260
261
262
263 DO 10 j = jn+1, ja+n-1, desca( nb_ )
264 jb =
min( ja+n-j, desca( nb_ ) )
265
266
267
268
269 CALL pzlarft(
'Backward',
'Columnwise', m-n+j+jb-ja, jb,
270 $ a, ia, j, desca, tau, work, work( ipw ) )
271
272
273
274 CALL pzlarfb(
'Left',
'No transpose',
'Backward',
275 $ 'Columnwise', m-n+j+jb-ja, j-ja, jb, a, ia,
276 $ j, desca, work, a, ia, ja, desca, work( ipw ) )
277
278
279
280 CALL pzung2l( m-n+j+jb-ja, jb, jb, a, ia, j, desca, tau, work,
281 $ lwork, iinfo )
282
283
284
285
286 CALL pzlaset(
'All', n-j-jb+ja, jb, zero, zero, a,
287 $ ia+m-n+j+jb-ja, j, desca )
288
289 10 CONTINUE
290
291 CALL pb_topget( ictxt, 'Broadcast', 'Rowwise', rowbtop )
292 CALL pb_topget( ictxt, 'Broadcast', 'Columnwise', colbtop )
293
294 work( 1 ) = dcmplx( dble( lwmin ) )
295
296 RETURN
297
298
299
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 pzung2l(m, n, k, a, ia, ja, desca, tau, work, lwork, info)