3
4
5
6
7
8
9
10 INTEGER IA, INFO, JA, LWORK, M, N
11
12
13 INTEGER DESCA( * )
14 DOUBLE PRECISION 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
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184 INTEGER BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
185 $ LLD_, MB_, M_, NB_, N_, RSRC_
186 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
187 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
188 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
189 DOUBLE PRECISION ZERO
190 parameter( zero = 0.0d+0 )
191
192
193 LOGICAL LQUERY
194 CHARACTER COLBTOP, ROWBTOP
195 INTEGER I, IACOL, IAROW, IB, ICTXT, IIA, IL, IN, IPW,
196 $ IROFFA, J, JM1, L, LWMIN, MP0, MYCOL, MYROW,
197 $ NPCOL, NPROW, NQ0
198
199
200 INTEGER IDUM1( 1 ), IDUM2( 1 )
201
202
206
207
208 INTEGER ICEIL, INDXG2P, NUMROC
210
211
212 INTRINSIC dble,
max,
min, mod
213
214
215
216
217
218 ictxt = desca( ctxt_ )
219 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
220
221
222
223 info = 0
224 IF( nprow.EQ.-1 ) THEN
225 info = -(600+ctxt_)
226 ELSE
227 CALL chk1mat( m, 1, n, 2, ia, ja, desca, 6, info )
228 IF( info.EQ.0 ) THEN
229 iroffa = mod( ia-1, desca( mb_ ) )
230 iarow =
indxg2p( ia, desca( mb_ ), myrow, desca( rsrc_ ),
231 $ nprow )
232 iacol =
indxg2p( ja, desca( nb_ ), mycol, desca( csrc_ ),
233 $ npcol )
234 mp0 =
numroc( m+iroffa, desca( mb_ ), myrow, iarow, nprow )
235 nq0 =
numroc( n+mod( ja-1, desca( nb_ ) ), desca( nb_ ),
236 $ mycol, iacol, npcol )
237 lwmin = desca( mb_ ) * ( mp0 + nq0 + desca( mb_ ) )
238
239 work( 1 ) = dble( lwmin )
240 lquery = ( lwork.EQ.-1 )
241 IF( n.LT.m ) THEN
242 info = -2
243 ELSE IF( lwork.LT.lwmin .AND. .NOT.lquery ) THEN
244 info = -9
245 END IF
246 END IF
247 IF( lquery ) THEN
248 idum1( 1 ) = -1
249 ELSE
250 idum1( 1 ) = 1
251 END IF
252 idum2( 1 ) = 9
253 CALL pchk1mat( m, 1, n, 2, ia, ja, desca, 6, 1, idum1, idum2,
254 $ info )
255 END IF
256
257 IF( info.NE.0 ) THEN
258 CALL pxerbla( ictxt,
'PDTZRZF', -info )
259 RETURN
260 ELSE IF( lquery ) THEN
261 RETURN
262 END IF
263
264
265
266 IF( m.EQ.0 .OR. n.EQ.0 )
267 $ RETURN
268
269 IF( m.EQ.n ) THEN
270
271 CALL infog1l( ia, desca( mb_ ), nprow, myrow, desca( rsrc_ ),
272 $ iia, iarow )
273 IF( myrow.EQ.iarow )
274 $ mp0 = mp0 - iroffa
275 DO 10 i = iia, iia+mp0-1
276 tau( i ) = zero
277 10 CONTINUE
278
279 ELSE
280
281 l = n-m
282 jm1 = ja +
min( m+1, n ) - 1
283 ipw = desca( mb_ ) * desca( mb_ ) + 1
284 in =
min(
iceil( ia, desca( mb_ ) ) * desca( mb_ ), ia+m-1 )
285 il =
max( ( (ia+m-2) / desca( mb_ ) ) * desca( mb_ ) + 1, ia )
286 CALL pb_topget( ictxt, 'Broadcast', 'Rowwise', rowbtop )
287 CALL pb_topget( ictxt, 'Broadcast', 'Columnwise', colbtop )
288 CALL pb_topset( ictxt, 'Broadcast', 'Rowwise', ' ' )
289 CALL pb_topset( ictxt, 'Broadcast', 'Columnwise', 'D-ring' )
290
291
292
293 DO 20 i = il, in+1, -desca( mb_ )
294 ib =
min( ia+m-i, desca( mb_ ) )
295 j = ja + i - ia
296
297
298
299
300 CALL pdlatrz( ib, ja+n-j, l, a, i, j, desca, tau, work )
301
302 IF( i.GT.ia ) THEN
303
304
305
306
307 CALL pdlarzt(
'Backward',
'Rowwise', l, ib, a, i, jm1,
308 $ desca, tau, work, work( ipw ) )
309
310
311
312 CALL pdlarzb(
'Right',
'No transpose',
'Backward',
313 $ 'Rowwise', i-ia, ja+n-j, ib, l, a, i, jm1,
314 $ desca, work, a, ia, j, desca, work( ipw ) )
315 END IF
316
317 20 CONTINUE
318
319
320
321 CALL pdlatrz( in-ia+1, n, n-m, a, ia, ja, desca, tau, work )
322
323 CALL pb_topset( ictxt, 'Broadcast', 'Rowwise', rowbtop )
324 CALL pb_topset( ictxt, 'Broadcast', 'Columnwise', colbtop )
325
326 END IF
327
328 work( 1 ) = 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)
subroutine infog1l(gindx, nb, nprocs, myroc, isrcproc, lindx, rocsrc)
integer function numroc(n, nb, iproc, isrcproc, nprocs)
subroutine pchk1mat(ma, mapos0, na, napos0, ia, ja, desca, descapos0, nextra, ex, expos, info)
subroutine pdlarzb(side, trans, direct, storev, m, n, k, l, v, iv, jv, descv, t, c, ic, jc, descc, work)
subroutine pdlarzt(direct, storev, n, k, v, iv, jv, descv, tau, t, work)
subroutine pdlatrz(m, n, l, a, ia, ja, desca, tau, work)
subroutine pxerbla(ictxt, srname, info)