3
4
5
6
7
8
9
10 INTEGER IA, INFO, JA, 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
158
159
160
161
162
163
164 INTEGER BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
165 $ LLD_, MB_, M_, NB_, N_, RSRC_
166 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
167 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
168 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
169
170
171 LOGICAL LQUERY
172 CHARACTER COLBTOP, ROWBTOP
173 INTEGER I, IACOL, IAROW, IB, ICTXT, IINFO, IL, IN, IPW,
174 $ K, LWMIN, MP0, MU, MYCOL, MYROW, NPCOL, NPROW,
175 $ NQ0, NU
176
177
178 INTEGER IDUM1( 1 ), IDUM2( 1 )
179
180
184
185
186 INTEGER ICEIL, INDXG2P, NUMROC
188
189
190 INTRINSIC dble, dcmplx,
max,
min, mod
191
192
193
194
195
196 ictxt = desca( ctxt_ )
197 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
198
199
200
201 info = 0
202 IF( nprow.EQ.-1 ) THEN
203 info = -(600+ctxt_)
204 ELSE
205 CALL chk1mat( m, 1, n, 2, ia, ja, desca, 6, info )
206 IF( info.EQ.0 ) THEN
207 iarow =
indxg2p( ia, desca( mb_ ), myrow, desca( rsrc_ ),
208 $ nprow )
209 iacol =
indxg2p( ja, desca( nb_ ), mycol, desca( csrc_ ),
210 $ npcol )
211 mp0 =
numroc( m+mod( ia-1, desca( mb_ ) ), desca( mb_ ),
212 $ myrow, iarow, nprow )
213 nq0 =
numroc( n+mod( ja-1, desca( nb_ ) ), desca( nb_ ),
214 $ mycol, iacol, npcol )
215 lwmin = desca( mb_ ) * ( mp0 + nq0 + desca( mb_ ) )
216
217 work( 1 ) = dcmplx( dble( lwmin ) )
218 lquery = ( lwork.EQ.-1 )
219 IF( lwork.LT.lwmin .AND. .NOT.lquery )
220 $ info = -9
221 END IF
222 IF( lquery ) THEN
223 idum1( 1 ) = -1
224 ELSE
225 idum1( 1 ) = 1
226 END IF
227 idum2( 1 ) = 9
228 CALL pchk1mat( m, 1, n, 2, ia, ja, desca, 6, 1, idum1, idum2,
229 $ info )
230 END IF
231
232 IF( info.NE.0 ) THEN
233 CALL pxerbla( ictxt,
'PZGERQF', -info )
234 RETURN
235 ELSE IF( lquery ) THEN
236 RETURN
237 END IF
238
239
240
241 IF( m.EQ.0 .OR. n.EQ.0 )
242 $ RETURN
243
245 ipw = desca( mb_ ) * desca( mb_ ) + 1
246 in =
min(
iceil( ia+m-k, desca( mb_ ) ) * desca( mb_ ), ia+m-1 )
247 il =
max( ( (ia+m-2) / desca( mb_ ) ) * desca( mb_ ) + 1, ia )
248 CALL pb_topget( ictxt, 'Broadcast', 'Rowwise', rowbtop )
249 CALL pb_topget( ictxt, 'Broadcast', 'Columnwise', colbtop )
250 CALL pb_topset( ictxt, 'Broadcast', 'Rowwise', ' ' )
251 CALL pb_topset( ictxt, 'Broadcast', 'Columnwise', 'D-ring' )
252
253 IF( il.GE.in+1 ) THEN
254
255
256
257 DO 10 i = il, in+1, -desca( mb_ )
258 ib =
min( ia+m-i, desca( mb_ ) )
259
260
261
262
263 CALL pzgerq2( ib, n-m+i+ib-ia, a, i, ja, desca, tau, work,
264 $ lwork, iinfo )
265
266 IF( i.GT.ia ) THEN
267
268
269
270
271 CALL pzlarft(
'Backward',
'Rowwise', n-m+i+ib-ia, ib, a,
272 $ i, ja, desca, tau, work, work( ipw ) )
273
274
275
276
277 CALL pzlarfb(
'Right',
'No transpose',
'Backward',
278 $ 'Rowwise', i-ia, n-m+i+ib-ia, ib, a, i, ja,
279 $ desca, work, a, ia, ja, desca,
280 $ work( ipw ) )
281 END IF
282
283 10 CONTINUE
284
285 mu = in - ia + 1
286 nu = n - m + in - ia + 1
287
288 ELSE
289
290 mu = m
291 nu = n
292
293 END IF
294
295
296
297 IF( mu.GT.0 .AND. nu.GT.0 )
298 $
CALL pzgerq2( mu, nu, a, ia, ja, desca, tau, work, lwork,
299 $ iinfo )
300
301 CALL pb_topset( ictxt, 'Broadcast', 'Rowwise', rowbtop )
302 CALL pb_topset( ictxt, 'Broadcast', 'Columnwise', colbtop )
303
304 work( 1 ) = dcmplx( dble( lwmin ) )
305
306 RETURN
307
308
309
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 pzgerq2(m, n, a, ia, ja, desca, tau, work, lwork, info)
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)