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