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 REAL 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 REAL ONE, ZERO
179 parameter( zero = 0.0e+0, one = 1.0e+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 REAL AMAX, ANRM, ERR, XNRM
188
189
190 INTEGER DESCW( DLEN_ ), IDUM1( 1 ), IDUM2( 1 )
191 REAL RWORK( 1 )
192
193
194 LOGICAL LSAME
195 INTEGER NUMROC
196 REAL PSLANGE, PSLAMCH
198
199
203
204
205 INTRINSIC abs,
max,
min, mod, real
206
207
208
209
210
211 ictxt = desca( ctxt_ )
212 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
213
215
216 ipwa = 1
217 iroffa = mod( ia-1, desca( mb_ ) )
218 icoffa = mod( ja-1, desca( nb_ ) )
219 iwa = iroffa + 1
220 jwa = icoffa + 1
221 CALL infog2l( ia, ja, desca, nprow, npcol, myrow, mycol, iia,
222 $ jja, iarow, iacol )
223 mpwa =
numroc( m+iroffa, desca( mb_ ), myrow, iarow, nprow )
224 nqwa =
numroc( n+icoffa, desca( nb_ ), mycol, iacol, npcol )
225
226 info = 0
227 IF(
lsame( trans,
'N' ) )
THEN
228 IF( n.LE.0 .OR. nrhs.LE.0 )
229 $ RETURN
230 tpsd = .false.
231 mpw =
numroc( m+nrhs+iroffa, desca( mb_ ), myrow, iarow,
232 $ nprow )
233 nqw = nqwa
234
235
236
237
238 iwx = iwa + m
239 jwx = jwa
241 CALL descset( descw, m+nrhs+iroffa, n+icoffa, desca( mb_ ),
242 $ desca( nb_ ), iarow, iacol, ictxt, ldw )
243
244 ELSE IF(
lsame( trans,
'T' ) )
THEN
245 IF( m.LE.0 .OR. nrhs.LE.0 )
246 $ RETURN
247 tpsd = .true.
248 mpw = mpwa
249 nqw =
numroc( n+nrhs+icoffa, desca( nb_ ), mycol, iacol,
250 $ npcol )
251
252
253
254
255 iwx = iwa
256 jwx = jwa + n
258 CALL descset( descw, m+iroffa, n+nrhs+icoffa, desca( mb_ ),
259 $ desca( nb_ ), iarow, iacol, ictxt, ldw )
260 ELSE
261 CALL pxerbla( ictxt,
'PSQRT14', -1 )
262 RETURN
263 END IF
264
265
266
267 iptau = ipwa + mpw*nqw
268 CALL pslacpy(
'All', m, n, a, ia, ja, desca, work( ipwa ), iwa,
269 $ jwa, descw )
270 rwork( 1 ) = zero
271 anrm =
pslange(
'M', m, n, work( ipwa ), iwa, jwa, descw, rwork )
272 IF( anrm.NE.zero )
273 $
CALL pslascl(
'G', anrm, one, m, n, work( ipwa ), iwa,
274 $ jwa, descw, info )
275
276
277
278 IF( tpsd ) THEN
279
280
281
282 DO 10 j = 1, nrhs
283 CALL pscopy( m, x, ix, jx+j-1, descx, 1, work( ipwa ), iwx,
284 $ jwx+j-1, descw, 1 )
285 10 CONTINUE
286 xnrm =
pslange(
'M', m, nrhs, work( ipwa ), iwx, jwx, descw,
287 $ rwork )
288 IF( xnrm.NE.zero )
289 $
CALL pslascl(
'G', xnrm, one, m, nrhs, work( ipwa ), iwx,
290 $ jwx, descw, info )
291
292
293
294 mqw =
numroc( m+icoffa, desca( nb_ ), mycol, iacol, npcol )
295 ipw = iptau +
min( mqw, nqw )
296 lwork = descw( nb_ ) * ( mpw + nqw + descw( nb_ ) )
297 CALL psgeqrf( m, n+nrhs, work( ipwa ), iwa, jwa, descw,
298 $ work( iptau ), work( ipw ), lwork, info )
299
300
301
302
303 err = zero
304 IF( n.LT.m ) THEN
305 DO 20 j = jwx, jwa+n+nrhs-1
306 CALL psamax(
min(m-n,j-jwx+1), amax, idum, work( ipwa ),
307 $ iwa+n, j, descw, 1 )
308 err =
max( err, abs( amax ) )
309 20 CONTINUE
310 END IF
311 CALL sgamx2d( ictxt, 'All', ' ', 1, 1, err, 1, idum1, idum2,
312 $ -1, -1, 0 )
313
314 ELSE
315
316
317
318 DO 30 j = 1, nrhs
319 CALL pscopy( n, x, ix, jx+j-1, descx, 1, work( ipwa ),
320 $ iwx+j-1, jwx, descw, descw( m_ ) )
321 30 CONTINUE
322
323 xnrm =
pslange(
'M', nrhs, n, work( ipwa ), iwx, jwx, descw,
324 $ rwork )
325 IF( xnrm.NE.zero )
326 $
CALL pslascl(
'G', xnrm, one, nrhs, n, work( ipwa ), iwx,
327 $ jwx, descw, info )
328
329
330
331 npw =
numroc( n+iroffa, desca( mb_ ), myrow, iarow, nprow )
332 ipw = iptau +
min( mpw, npw )
333 lwork = descw( mb_ ) * ( mpw + nqw + descw( mb_ ) )
334 CALL psgelqf( m+nrhs, n, work( ipwa ), iwa, jwa, descw,
335 $ work( iptau ), work( ipw ), lwork, info )
336
337
338
339
340 err = zero
341 DO 40 j = jwa+m,
min( jwa+n-1, jwa+m+nrhs-1 )
342 CALL psamax( jwa+m+nrhs-j, amax, idum, work( ipwa ),
343 $ iwx+j-jwa-m, j, descw, 1 )
344 err =
max( err, abs( amax ) )
345 40 CONTINUE
346 CALL sgamx2d( ictxt, 'All', ' ', 1, 1, err, 1, idum1, idum2,
347 $ -1, -1, 0 )
348
349 END IF
350
352 $
pslamch( ictxt,
'Epsilon' ) )
353
354 RETURN
355
356
357
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)
real function pslamch(ictxt, cmach)
subroutine psgelqf(m, n, a, ia, ja, desca, tau, work, lwork, info)
subroutine psgeqrf(m, n, a, ia, ja, desca, tau, work, lwork, info)
subroutine pslacpy(uplo, m, n, a, ia, ja, desca, b, ib, jb, descb)
real function pslange(norm, m, n, a, ia, ja, desca, work)
subroutine pslascl(type, cfrom, cto, m, n, a, ia, ja, desca, info)
real function psqrt14(trans, m, n, nrhs, a, ia, ja, desca, x, ix, jx, descx, work)
subroutine pxerbla(ictxt, srname, info)