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