3
4
5
6
7
8
9
10 INTEGER IA, IASEED, JA, N
11 DOUBLE PRECISION ANORM, FRESID, RCOND
12
13
14 CHARACTER*3 MATTYP
15 INTEGER DESCA( * )
16 COMPLEX*16 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 INTEGER BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
137 $ LLD_, MB_, M_, NB_, N_, RSRC_
138 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
139 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
140 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
141 COMPLEX*16 ZERO, ONE
142 parameter( zero = 0.0d+0, one = 1.0d+0 )
143
144
145 CHARACTER AFORM, DIAG, UPLO
146 INTEGER ICTXT, ICURCOL, ICURROW, II, IIA, IPW, IROFF,
147 $ IW, J, JB, JJA, JN, KK, MYCOL, MYROW, NP,
148 $ NPCOL, NPROW
149 DOUBLE PRECISION AUXNORM, EPS, NRMINVAXA, TEMP
150
151
152 INTEGER DESCW( DLEN_ )
153
154
157
158
159 LOGICAL LSAMEN
160 INTEGER ICEIL, NUMROC
161 DOUBLE PRECISION PDLAMCH, PZLANGE, PZLANHE, PZLANTR
164
165
167
168
169
170 eps =
pdlamch( desca( ctxt_ ),
'eps' )
171
172
173
174 ictxt = desca( ctxt_ )
175 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
176
177
178
179 IF(
lsamen( 1, mattyp( 1:1 ),
'U' ) )
THEN
180 uplo = 'U'
181 ELSE
182 uplo = 'L'
183 END IF
184
185 IF(
lsamen( 3, mattyp,
'GEN' ) )
THEN
186
187 aform = 'N'
188 diag = 'D'
189 auxnorm =
pzlange(
'1', n, n, a, ia, ja, desca, work )
190
191 ELSE IF(
lsamen( 2, mattyp( 2:3 ),
'TR' ) )
THEN
192
193 aform = 'N'
194 diag = 'D'
195 auxnorm =
pzlantr(
'1', uplo,
'Non unit', n, n, a, ia, ja,
196 $ desca, work )
197 ELSE IF(
lsamen( 2, mattyp( 2:3 ),
'PD' ) )
THEN
198
199 aform = 'H'
200 diag = 'D'
201 auxnorm =
pzlanhe(
'1', uplo, n, a, ia, ja, desca, work )
202
203 END IF
204 rcond = anorm*auxnorm
205
206
207
208 CALL infog2l( ia, ja, desca, nprow, npcol, myrow, mycol, iia, jja,
209 $ icurrow, icurcol )
210
211
212
213 iroff = mod( ia-1, desca( mb_ ) )
214 np =
numroc( n+iroff, desca( mb_ ), myrow, icurrow, nprow )
215 CALL descset( descw, n+iroff, desca( nb_ ), desca( mb_ ),
216 $ desca( nb_ ), icurrow, icurcol, desca( ctxt_ ),
218 ipw = descw( lld_ ) * descw( nb_ ) + 1
219
220 IF( myrow.EQ.icurrow ) THEN
221 ii = iroff + 1
222 np = np - iroff
223 ELSE
224 ii = 1
225 END IF
226 jn =
min(
iceil( ja, desca( nb_ ) ) * desca( nb_ ), ja+n-1 )
227 jb = jn - ja + 1
228
229
230
231 iw = iroff + 1
232 IF( mycol.EQ.icurcol ) THEN
233 IF(
lsamen( 2, mattyp( 2:3 ),
'TR' ) )
THEN
234 CALL pzmatgen( ictxt, aform, diag, desca( m_ ), desca( n_ ),
235 $ descw( mb_ ), descw( nb_ ), work,
236 $ descw( lld_ ), desca( rsrc_ ),
237 $ desca( csrc_ ), iaseed, iia-1, np,
238 $ jja-1, jb, myrow, mycol, nprow, npcol )
239 IF(
lsamen( 3, mattyp,
'UTR' ) )
THEN
240 CALL pzlaset(
'Lower', n-1, jb, zero, zero, work, iw+1,
241 $ 1, descw )
242 ELSE
243 CALL pzlaset(
'Upper', jb-1, jb-1, zero, zero, work, iw,
244 $ 2, descw )
245 END IF
246 ELSE
247 CALL pzmatgen( ictxt, aform, diag, desca( m_ ), desca( n_ ),
248 $ descw( mb_ ), descw( nb_ ), work( ipw ),
249 $ descw( lld_ ), desca( rsrc_ ),
250 $ desca( csrc_ ), iaseed,
251 $ iia-1, np, jja-1, jb, myrow, mycol, nprow,
252 $ npcol )
253 END IF
254 END IF
255
256
257
258 IF(
lsamen( 3, mattyp,
'GEN' ) )
THEN
259
260 CALL pzgemm( 'No tranpose', 'No transpose', n, jb, n, one, a,
261 $ ia, ja, desca, work( ipw ), iw, 1, descw, zero,
262 $ work, iw, 1, descw )
263
264 ELSE IF(
lsamen( 2, mattyp( 2:3 ),
'TR' ) )
THEN
265
266 CALL pztrmm( 'Left', uplo, 'No tranpose', 'Non unit', n, jb,
267 $ one, a, ia, ja, desca, work, iw, 1, descw )
268
269 ELSE IF(
lsamen( 2, mattyp( 2:3 ),
'PD' ) )
THEN
270
271 CALL pzhemm( 'Left', uplo, n, jb, one, a, ia, ja, desca,
272 $ work(ipw), iw, 1, descw, zero, work, iw, 1,
273 $ descw )
274
275 END IF
276
277
278
279 IF( myrow.EQ.icurrow .AND. mycol.EQ.icurcol ) THEN
280 DO 10 kk = 0, jb-1
281 work( ii+kk*(descw(lld_)+1) ) =
282 $ work( ii+kk*(descw( lld_ )+1) )-one
283 10 CONTINUE
284 END IF
285
286 nrminvaxa =
pzlange(
'1', n, jb, work, iw, 1, descw, work( ipw ) )
287
288 IF( myrow.EQ.icurrow )
289 $ ii = ii + jb
290 IF( mycol.EQ.icurcol )
291 $ jja = jja + jb
292 icurrow = mod( icurrow+1, nprow )
293 icurcol = mod( icurcol+1, npcol )
294 descw( csrc_ ) = icurcol
295
296 DO 30 j = jn+1, ja+n-1, desca( nb_ )
297
298 jb =
min( n-j+ja, desca( nb_ ) )
299
300
301
302 IF( mycol.EQ.icurcol ) THEN
303 IF(
lsamen( 2, mattyp( 2:3 ),
'TR' ) )
THEN
304 CALL pzmatgen( ictxt, aform, diag, desca( m_ ),
305 $ desca( n_ ), descw( mb_ ), descw( nb_ ),
306 $ work, descw( lld_ ), desca( rsrc_ ),
307 $ desca( csrc_ ),
308 $ iaseed, iia-1, np, jja-1, jb, myrow,
309 $ mycol, nprow, npcol )
310 IF(
lsamen( 3, mattyp,
'UTR' ) )
THEN
311 CALL pzlaset(
'Lower', ja+n-j-1, jb, zero, zero,
312 $ work, iw+j-ja+1, 1, descw )
313 ELSE
314 CALL pzlaset(
'All', j-ja, jb, zero, zero, work, iw,
315 $ 1, descw )
316 CALL pzlaset(
'Upper', jb-1, jb-1, zero, zero,
317 $ work, iw+j-ja, 2, descw )
318 END IF
319 ELSE
320 CALL pzmatgen( ictxt, aform, diag, desca( m_ ),
321 $ desca( n_ ), descw( mb_ ), descw( nb_ ),
322 $ work( ipw ), descw( lld_ ),
323 $ desca( rsrc_ ), desca( csrc_ ), iaseed,
324 $ iia-1, np,
325 $ jja-1, jb, myrow, mycol, nprow, npcol )
326 END IF
327 END IF
328
329
330
331 IF(
lsamen( 3, mattyp,
'GEN' ) )
THEN
332
333 CALL pzgemm( 'No tranpose', 'No transpose', n, jb, n, one,
334 $ a, ia, ja, desca, work( ipw ), iw, 1, descw,
335 $ zero, work, iw, 1, descw )
336
337 ELSE IF(
lsamen( 2, mattyp(2:3),
'TR' ) )
THEN
338
339 CALL pztrmm( 'Left', uplo, 'No tranpose', 'Non unit', n, jb,
340 $ one, a, ia, ja, desca, work, iw, 1, descw )
341
342 ELSE IF(
lsamen( 2, mattyp( 2:3 ),
'PD' ) )
THEN
343
344 CALL pzhemm( 'Left', uplo, n, jb, one, a, ia, ja, desca,
345 $ work(ipw), iw, 1, descw, zero, work, iw, 1,
346 $ descw )
347
348 END IF
349
350
351
352
353 IF( myrow.EQ.icurrow .AND. mycol.EQ.icurcol ) THEN
354 DO 20 kk = 0, jb-1
355 work( ii+kk*(descw( lld_ )+1) ) =
356 $ work( ii+kk*(descw( lld_ )+1) ) - one
357 20 CONTINUE
358 END IF
359
360
361
362 temp =
pzlange(
'1', n, jb, work, iw, 1, descw, work( ipw ) )
363 nrminvaxa =
max( temp, nrminvaxa )
364
365 IF( myrow.EQ.icurrow )
366 $ ii = ii + jb
367 IF( mycol.EQ.icurcol )
368 $ jja = jja + jb
369 icurrow = mod( icurrow+1, nprow )
370 icurcol = mod( icurcol+1, npcol )
371 descw( csrc_ ) = icurcol
372
373 30 CONTINUE
374
375
376
377 fresid = nrminvaxa / ( n * eps * anorm )
378
379 RETURN
380
381
382
subroutine pzmatgen(ictxt, aform, diag, m, n, mb, nb, a, lda, iarow, iacol, iseed, iroff, irnum, icoff, icnum, myrow, mycol, nprow, npcol)
subroutine descset(desc, m, n, mb, nb, irsrc, icsrc, ictxt, lld)
integer function iceil(inum, idenom)
subroutine infog2l(grindx, gcindx, desc, nprow, npcol, myrow, mycol, lrindx, lcindx, rsrc, csrc)
integer function numroc(n, nb, iproc, isrcproc, nprocs)
logical function lsamen(n, ca, cb)
double precision function pdlamch(ictxt, cmach)
subroutine pzlaset(uplo, m, n, alpha, beta, a, ia, ja, desca)
double precision function pzlange(norm, m, n, a, ia, ja, desca, work)
double precision function pzlanhe(norm, uplo, n, a, ia, ja, desca, work)
double precision function pzlansy(norm, uplo, n, a, ia, ja, desca, work)
double precision function pzlantr(norm, uplo, diag, m, n, a, ia, ja, desca, work)