3
4
5
6
7
8
9
10 CHARACTER NORM
11 INTEGER IA, INFO, JA, LIWORK, LWORK, N
12 REAL ANORM, RCOND
13
14
15 INTEGER DESCA( * ), IWORK( * )
16 REAL A( * ), WORK( * )
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 INTEGER BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
176 $ LLD_, MB_, M_, NB_, N_, RSRC_
177 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
178 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
179 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
180 REAL ONE, ZERO
181 parameter( one = 1.0e+0, zero = 0.0e+0 )
182
183
184 LOGICAL LQUERY, ONENRM
185 CHARACTER CBTOP, COLCTOP, NORMIN, ROWCTOP
186 INTEGER IACOL, IAROW, ICOFF, ICTXT, IIA, IPNL, IPNU,
187 $ IPV, IPW, IPX, IROFF, IV, IX, IXX, JJA, JV, JX,
188 $ KASE, KASE1, LIWMIN, LWMIN, MYCOL, MYROW, NP,
189 $ NPCOL, NPMOD, NPROW, NQ, NQMOD
190 REAL AINVNM, SCALE, SL, SMLNUM, SU, WMAX
191
192
193 INTEGER DESCV( DLEN_ ), DESCX( DLEN_ ), IDUM1( 3 ),
194 $ IDUM2( 3 )
195
196
200 $ sgebs2d
201
202
203 LOGICAL LSAME
204 INTEGER ICEIL, INDXG2P, NUMROC
205 REAL PSLAMCH
207
208
209 INTRINSIC abs, ichar,
max, mod, real
210
211
212
213
214
215 ictxt = desca( ctxt_ )
216 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
217
218
219
220 info = 0
221 IF( nprow.EQ.-1 ) THEN
222 info = -( 600 + ctxt_ )
223 ELSE
224 CALL chk1mat( n, 2, n, 2, ia, ja, desca, 6, info )
225 IF( info.EQ.0 ) THEN
226 onenrm = norm.EQ.
'1' .OR.
lsame( norm,
'O' )
227 iarow =
indxg2p( ia, desca( mb_ ), myrow, desca( rsrc_ ),
228 $ nprow )
229 iacol =
indxg2p( ja, desca( nb_ ), mycol, desca( csrc_ ),
230 $ npcol )
231 npmod =
numroc( n + mod( ia-1, desca( mb_ ) ), desca( mb_ ),
232 $ myrow, iarow, nprow )
233 nqmod =
numroc( n + mod( ja-1, desca( nb_ ) ), desca( nb_ ),
234 $ mycol, iacol, npcol )
235 lwmin = 2*npmod + 2*nqmod +
236 $
max( 2,
max( desca( nb_ )*
237 $
max( 1,
iceil( nprow-1, npcol ) ), nqmod +
238 $ desca( nb_ )*
239 $
max( 1,
iceil( npcol-1, nprow ) ) ) )
240 work( 1 ) = real( lwmin )
241 liwmin =
max( 1, npmod )
242 iwork( 1 ) = liwmin
243 lquery = ( lwork.EQ.-1 .OR. liwork.EQ.-1 )
244
245 IF( .NOT.onenrm .AND. .NOT.
lsame( norm,
'I' ) )
THEN
246 info = -1
247 ELSE IF( anorm.LT.zero ) THEN
248 info = -7
249 ELSE IF( lwork.LT.lwmin .AND. .NOT.lquery ) THEN
250 info = -10
251 ELSE IF( liwork.LT.liwmin .AND. .NOT.lquery ) THEN
252 info = -12
253 END IF
254 END IF
255
256 IF( onenrm ) THEN
257 idum1( 1 ) = ichar( '1' )
258 ELSE
259 idum1( 1 ) = ichar( 'I' )
260 END IF
261 idum2( 1 ) = 1
262 IF( lwork.EQ.-1 ) THEN
263 idum1( 2 ) = -1
264 ELSE
265 idum1( 2 ) = 1
266 END IF
267 idum2( 2 ) = 10
268 IF( liwork.EQ.-1 ) THEN
269 idum1( 3 ) = -1
270 ELSE
271 idum1( 3 ) = 1
272 END IF
273 idum2( 3 ) = 12
274 CALL pchk1mat( n, 2, n, 2, ia, ja, desca, 6, 3, idum1, idum2,
275 $ info )
276 END IF
277
278 IF( info.NE.0 ) THEN
279 CALL pxerbla( ictxt,
'PSGECON', -info )
280 RETURN
281 ELSE IF( lquery ) THEN
282 RETURN
283 END IF
284
285
286
287 rcond = zero
288 IF( n.EQ.0 ) THEN
289 rcond = one
290 RETURN
291 ELSE IF( anorm.EQ.zero ) THEN
292 RETURN
293 ELSE IF( n.EQ.1 ) THEN
294 rcond = one
295 RETURN
296 END IF
297
298 CALL pb_topget( ictxt, 'Combine', 'Columnwise', colctop )
299 CALL pb_topget( ictxt, 'Combine', 'Rowwise', rowctop )
300 CALL pb_topset( ictxt, 'Combine', 'Columnwise', '1-tree' )
301 CALL pb_topset( ictxt, 'Combine', 'Rowwise', '1-tree' )
302
303 smlnum =
pslamch( ictxt,
'Safe minimum' )
304 iroff = mod( ia-1, desca( mb_ ) )
305 icoff = mod( ja-1, desca( nb_ ) )
306 CALL infog2l( ia, ja, desca, nprow, npcol, myrow, mycol, iia, jja,
307 $ iarow, iacol )
308 np =
numroc( n+iroff, desca( mb_ ), myrow, iarow, nprow )
309 nq =
numroc( n+icoff, desca( nb_ ), mycol, iacol, npcol )
310 iv = iroff + 1
311 ix = iv
312 jv = icoff + 1
313 jx = jv
314
315 ipx = 1
316 ipv = ipx + np
317 ipnl = ipv + np
318 ipnu = ipnl + nq
319 ipw = ipnu + nq
320
321 CALL descset( descv, n+iroff, 1, desca( mb_ ), 1, iarow, mycol,
322 $ ictxt,
max( 1, np ) )
323 CALL descset( descx, n+iroff, 1, desca( mb_ ), 1, iarow, mycol,
324 $ ictxt,
max( 1, np ) )
325
326
327
328 ainvnm = zero
329 normin = 'N'
330 IF( onenrm ) THEN
331 kase1 = 1
332 ELSE
333 kase1 = 2
334 END IF
335 kase = 0
336
337 10 CONTINUE
338 CALL pslacon( n, work( ipv ), iv, jv, descv, work( ipx ), ix, jx,
339 $ descx, iwork, ainvnm, kase )
340 IF( kase.NE.0 ) THEN
341 IF( kase.EQ.kase1 ) THEN
342
343
344
345 descx( csrc_ ) = iacol
346 CALL pslatrs(
'Lower',
'No transpose',
'Unit', normin,
347 $ n, a, ia, ja, desca, work( ipx ), ix, jx,
348 $ descx, sl, work( ipnl ), work( ipw ) )
349 descx( csrc_ ) = mycol
350
351
352
353 descx( csrc_ ) = iacol
354 CALL pslatrs(
'Upper',
'No transpose',
'Non-unit', normin,
355 $ n, a, ia, ja, desca, work( ipx ), ix, jx,
356 $ descx, su, work( ipnu ), work( ipw ) )
357 descx( csrc_ ) = mycol
358 ELSE
359
360
361
362 descx( csrc_ ) = iacol
363 CALL pslatrs(
'Upper',
'Transpose',
'Non-unit', normin,
364 $ n, a, ia, ja, desca, work( ipx ), ix, jx,
365 $ descx, su, work( ipnu ), work( ipw ) )
366 descx( csrc_ ) = mycol
367
368
369
370 descx( csrc_ ) = iacol
371 CALL pslatrs(
'Lower',
'Transpose',
'Unit', normin,
372 $ n, a, ia, ja, desca, work( ipx ), ix, jx,
373 $ descx, sl, work( ipnl ), work( ipw ) )
374 descx( csrc_ ) = mycol
375 END IF
376
377
378
379 scale = sl*su
380 normin = 'Y'
381 IF( scale.NE.one ) THEN
382 CALL psamax( n, wmax, ixx, work( ipx ), ix, jx, descx, 1 )
383 IF( descx( m_ ).EQ.1 .AND. n.EQ.1 ) THEN
384 CALL pb_topget( ictxt, 'Broadcast', 'Columnwise', cbtop )
385 IF( myrow.EQ.iarow ) THEN
386 CALL sgebs2d( ictxt, 'Column', cbtop, 1, 1, wmax, 1 )
387 ELSE
388 CALL sgebr2d( ictxt, 'Column', cbtop, 1, 1, wmax, 1,
389 $ iarow, mycol )
390 END IF
391 END IF
392 IF( scale.LT.abs( wmax )*smlnum .OR. scale.EQ.zero )
393 $ GO TO 20
394 CALL psrscl( n, scale, work( ipx ), ix, jx, descx, 1 )
395 END IF
396 GO TO 10
397 END IF
398
399
400
401 IF( ainvnm.NE.zero )
402 $ rcond = ( one / ainvnm ) / anorm
403
404 20 CONTINUE
405
406 CALL pb_topset( ictxt, 'Combine', 'Columnwise', colctop )
407 CALL pb_topset( ictxt, 'Combine', 'Rowwise', rowctop )
408
409 RETURN
410
411
412
subroutine chk1mat(ma, mapos0, na, napos0, ia, ja, desca, descapos0, info)
subroutine descset(desc, m, n, mb, nb, irsrc, icsrc, ictxt, lld)
integer function iceil(inum, idenom)
integer function indxg2p(indxglob, nb, iproc, isrcproc, nprocs)
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 pchk1mat(ma, mapos0, na, napos0, ia, ja, desca, descapos0, nextra, ex, expos, info)
subroutine pslacon(n, v, iv, jv, descv, x, ix, jx, descx, isgn, est, kase)
subroutine pslatrs(uplo, trans, diag, normin, n, a, ia, ja, desca, x, ix, jx, descx, scale, cnorm, work)
subroutine psrscl(n, sa, sx, ix, jx, descx, incx)
subroutine pxerbla(ictxt, srname, info)