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