3
4
5
6
7
8
9
10 CHARACTER TRANS
11 INTEGER IA, IX, JA, JX, M, N, NRHS
12
13
14 INTEGER DESCA( * ), DESCX( * )
15 COMPLEX*16 A( * ), WORK( * ), X( * )
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 INTEGER BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
174 $ LLD_, MB_, M_, NB_, N_, RSRC_
175 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
176 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
177 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
178 DOUBLE PRECISION ONE, ZERO
179 parameter( zero = 0.0d+0, one = 1.0d+0 )
180
181
182 LOGICAL TPSD
183 INTEGER IACOL, IAROW, ICOFFA, ICTXT, IDUM, IIA, INFO,
184 $ IPTAU, IPW, IPWA, IROFFA, IWA, IWX, J, JJA,
185 $ JWA, JWX, LDW, LWORK, MPWA, MPW, MQW, MYCOL,
186 $ MYROW, NPCOL, NPROW, NPW, NQWA, NQW
187 DOUBLE PRECISION ANRM, ERR, XNRM
188 COMPLEX*16 AMAX
189
190
191 INTEGER DESCW( DLEN_ ), IDUM1( 1 ), IDUM2( 1 )
192 DOUBLE PRECISION RWORK( 1 )
193
194
195 LOGICAL LSAME
196 INTEGER NUMROC
197 DOUBLE PRECISION PDLAMCH, PZLANGE
199
200
204
205
206 INTRINSIC abs, dble,
max,
min, mod
207
208
209
210
211
212 ictxt = desca( ctxt_ )
213 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
214
216
217 ipwa = 1
218 iroffa = mod( ia-1, desca( mb_ ) )
219 icoffa = mod( ja-1, desca( nb_ ) )
220 iwa = iroffa + 1
221 jwa = icoffa + 1
222 CALL infog2l( ia, ja, desca, nprow, npcol, myrow, mycol, iia,
223 $ jja, iarow, iacol )
224 mpwa =
numroc( m+iroffa, desca( mb_ ), myrow, iarow, nprow )
225 nqwa =
numroc( n+icoffa, desca( nb_ ), mycol, iacol, npcol )
226
227 info = 0
228 IF(
lsame( trans,
'N' ) )
THEN
229 IF( n.LE.0 .OR. nrhs.LE.0 )
230 $ RETURN
231 tpsd = .false.
232 mpw =
numroc( m+nrhs+iroffa, desca( mb_ ), myrow, iarow,
233 $ nprow )
234 nqw = nqwa
235
236
237
238
239 iwx = iwa + m
240 jwx = jwa
242 CALL descset( descw, m+nrhs+iroffa, n+icoffa, desca( mb_ ),
243 $ desca( nb_ ), iarow, iacol, ictxt, ldw )
244
245 ELSE IF(
lsame( trans,
'C' ) )
THEN
246 IF( m.LE.0 .OR. nrhs.LE.0 )
247 $ RETURN
248 tpsd = .true.
249 mpw = mpwa
250 nqw =
numroc( n+nrhs+icoffa, desca( nb_ ), mycol, iacol,
251 $ npcol )
252
253
254
255
256 iwx = iwa
257 jwx = jwa + n
259 CALL descset( descw, m+iroffa, n+nrhs+icoffa, desca( mb_ ),
260 $ desca( nb_ ), iarow, iacol, ictxt, ldw )
261 ELSE
262 CALL pxerbla( ictxt,
'PZQRT14', -1 )
263 RETURN
264 END IF
265
266
267
268 iptau = ipwa + mpw*nqw
269 CALL pzlacpy(
'All', m, n, a, ia, ja, desca, work( ipwa ), iwa,
270 $ jwa, descw )
271 rwork( 1 ) = zero
272 anrm =
pzlange(
'M', m, n, work( ipwa ), iwa, jwa, descw, rwork )
273 IF( anrm.NE.zero )
274 $
CALL pzlascl(
'G', anrm, one, m, n, work( ipwa ), iwa,
275 $ jwa, descw, info )
276
277
278
279 IF( tpsd ) THEN
280
281
282
283 DO 10 j = 1, nrhs
284 CALL pzcopy( m, x, ix, jx+j-1, descx, 1, work( ipwa ), iwx,
285 $ jwx+j-1, descw, 1 )
286 10 CONTINUE
287 xnrm =
pzlange(
'M', m, nrhs, work( ipwa ), iwx, jwx, descw,
288 $ rwork )
289 IF( xnrm.NE.zero )
290 $
CALL pzlascl(
'G', xnrm, one, m, nrhs, work( ipwa ), iwx,
291 $ jwx, descw, info )
292
293
294
295 mqw =
numroc( m+icoffa, desca( nb_ ), mycol, iacol, npcol )
296 ipw = iptau +
min( mqw, nqw )
297 lwork = descw( nb_ ) * ( mpw + nqw + descw( nb_ ) )
298 CALL pzgeqrf( m, n+nrhs, work( ipwa ), iwa, jwa, descw,
299 $ work( iptau ), work( ipw ), lwork, info )
300
301
302
303
304 err = zero
305 IF( n.LT.m ) THEN
306 DO 20 j = jwx, jwa+n+nrhs-1
307 CALL pzmax1(
min(m-n,j-jwx+1), amax, idum, work( ipwa ),
308 $ iwa+n, j, descw, 1 )
309 err =
max( err, abs( amax ) )
310 20 CONTINUE
311 END IF
312 CALL dgamx2d( ictxt, 'All', ' ', 1, 1, err, 1, idum1, idum2,
313 $ -1, -1, 0 )
314
315 ELSE
316
317
318
319 DO 30 j = 1, nrhs
320 CALL pzcopy( n, x, ix, jx+j-1, descx, 1, work( ipwa ),
321 $ iwx+j-1, jwx, descw, descw( m_ ) )
322 CALL pzlacgv( n, work( ipwa ), iwx+j-1, jwx, descw,
323 $ descw( m_ ) )
324 30 CONTINUE
325
326 xnrm =
pzlange(
'M', nrhs, n, work( ipwa ), iwx, jwx, descw,
327 $ rwork )
328 IF( xnrm.NE.zero )
329 $
CALL pzlascl(
'G', xnrm, one, nrhs, n, work( ipwa ), iwx,
330 $ jwx, descw, info )
331
332
333
334 npw =
numroc( n+iroffa, desca( mb_ ), myrow, iarow, nprow )
335 ipw = iptau +
min( mpw, npw )
336 lwork = descw( mb_ ) * ( mpw + nqw + descw( mb_ ) )
337 CALL pzgelqf( m+nrhs, n, work( ipwa ), iwa, jwa, descw,
338 $ work( iptau ), work( ipw ), lwork, info )
339
340
341
342
343 err = zero
344 DO 40 j = jwa+m,
min( jwa+n-1, jwa+m+nrhs-1 )
345 CALL pzmax1( jwa+m+nrhs-j, amax, idum, work( ipwa ),
346 $ iwx+j-jwa-m, j, descw, 1 )
347 err =
max( err, abs( amax ) )
348 40 CONTINUE
349 CALL dgamx2d( ictxt, 'All', ' ', 1, 1, err, 1, idum1, idum2,
350 $ -1, -1, 0 )
351
352 END IF
353
355 $
pdlamch( ictxt,
'Epsilon' ) )
356
357 RETURN
358
359
360
subroutine descset(desc, m, n, mb, nb, irsrc, icsrc, ictxt, lld)
subroutine infog2l(grindx, gcindx, desc, nprow, npcol, myrow, mycol, lrindx, lcindx, rsrc, csrc)
integer function numroc(n, nb, iproc, isrcproc, nprocs)
double precision function pdlamch(ictxt, cmach)
subroutine pxerbla(ictxt, srname, info)
subroutine pzgelqf(m, n, a, ia, ja, desca, tau, work, lwork, info)
subroutine pzgeqrf(m, n, a, ia, ja, desca, tau, work, lwork, info)
subroutine pzlacgv(n, x, ix, jx, descx, incx)
subroutine pzlacpy(uplo, m, n, a, ia, ja, desca, b, ib, jb, descb)
double precision function pzlange(norm, m, n, a, ia, ja, desca, work)
subroutine pzlascl(type, cfrom, cto, m, n, a, ia, ja, desca, info)
subroutine pzmax1(n, amax, indx, x, ix, jx, descx, incx)
double precision function pzqrt14(trans, m, n, nrhs, a, ia, ja, desca, x, ix, jx, descx, work)