3
4
5
6
7
8
9
10 INTEGER IA, INFO, JA, N
11 DOUBLE PRECISION AMAX, SCOND
12
13
14 INTEGER DESCA( * )
15 DOUBLE PRECISION A( * ), SC( * ), SR( * )
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 INTEGER BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
150 $ LLD_, MB_, M_, NB_, N_, RSRC_
151 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
152 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
153 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
154 DOUBLE PRECISION ZERO, ONE
155 parameter( zero = 0.0d+0, one = 1.0d+0 )
156
157
158 CHARACTER ALLCTOP, COLCTOP, ROWCTOP
159 INTEGER IACOL, IAROW, ICOFF, ICTXT, ICURCOL, ICURROW,
160 $ IDUMM, II, IIA, IOFFA, IOFFD, IROFF, J, JB, JJ,
161 $ JJA, JN, LDA, LL, MYCOL, MYROW, NP, NPCOL,
162 $ NPROW, NQ
163 DOUBLE PRECISION AII, SMIN
164
165
166 INTEGER DESCSC( DLEN_ ), DESCSR( DLEN_ )
167
168
170 $ dgamx2d, dgsum2d, igamn2d,
infog2l,
172
173
174 INTEGER ICEIL, NUMROC
175 DOUBLE PRECISION PDLAMCH
177
178
179 INTRINSIC max,
min, mod, sqrt
180
181
182
183
184
185 ictxt = desca( ctxt_ )
186 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
187
188
189
190 info = 0
191 IF( nprow.EQ.-1 ) THEN
192 info = -(500+ctxt_)
193 ELSE
194 CALL chk1mat( n, 1, n, 1, ia, ja, desca, 5, info )
195 CALL pchk1mat( n, 1, n, 1, ia, ja, desca, 5, 0, idumm, idumm,
196 $ info )
197 END IF
198
199 IF( info.NE.0 ) THEN
200 CALL pxerbla( ictxt,
'PDPOEQU', -info )
201 RETURN
202 END IF
203
204
205
206 IF( n.EQ.0 ) THEN
207 scond = one
208 amax = zero
209 RETURN
210 END IF
211
212 CALL pb_topget( ictxt, 'Combine', 'All', allctop )
213 CALL pb_topget( ictxt, 'Combine', 'Rowwise', rowctop )
214 CALL pb_topget( ictxt, 'Combine', 'Columnwise', colctop )
215
216
217
218 CALL infog2l( ia, ja, desca, nprow, npcol, myrow, mycol, iia, jja,
219 $ iarow, iacol )
220 iroff = mod( ia-1, desca( mb_ ) )
221 icoff = mod( ja-1, desca( nb_ ) )
222 np =
numroc( n+iroff, desca( mb_ ), myrow, iarow, nprow )
223 nq =
numroc( n+icoff, desca( nb_ ), mycol, iacol, npcol )
224 IF( myrow.EQ.iarow )
225 $ np = np - iroff
226 IF( mycol.EQ.iacol )
227 $ nq = nq - icoff
228 jn =
min(
iceil( ja, desca( nb_ ) ) * desca( nb_ ), ja+n-1 )
229 lda = desca( lld_ )
230
231
232
233 CALL descset( descsr, n, 1, desca( mb_ ), 1, 0, 0, ictxt,
235 CALL descset( descsc, 1, n, 1, desca( nb_ ), 0, 0, ictxt, 1 )
236
237
238
239 DO 10 ii = iia, iia+np-1
240 sr( ii ) = zero
241 10 CONTINUE
242
243 DO 20 jj = jja, jja+nq-1
244 sc( jj ) = zero
245 20 CONTINUE
246
247
248
249
250 ii = iia
251 jj = jja
252 jb = jn-ja+1
253 smin = one /
pdlamch( ictxt,
'S' )
254 amax = zero
255
256 ioffa = ii+(jj-1)*lda
257 IF( myrow.EQ.iarow .AND. mycol.EQ.iacol ) THEN
258 ioffd = ioffa
259 DO 30 ll = 0, jb-1
260 aii = a( ioffd )
261 sr( ii+ll ) = aii
262 sc( jj+ll ) = aii
263 smin =
min( smin, aii )
264 amax =
max( amax, aii )
265 IF( aii.LE.zero .AND. info.EQ.0 )
266 $ info = ll + 1
267 ioffd = ioffd + lda + 1
268 30 CONTINUE
269 END IF
270
271 IF( myrow.EQ.iarow ) THEN
272 ii = ii + jb
273 ioffa = ioffa + jb
274 END IF
275 IF( mycol.EQ.iacol ) THEN
276 jj = jj + jb
277 ioffa = ioffa + jb*lda
278 END IF
279 icurrow = mod( iarow+1, nprow )
280 icurcol = mod( iacol+1, npcol )
281
282
283
284 DO 50 j = jn+1, ja+n-1, desca( nb_ )
285 jb =
min( n-j+ja, desca( nb_ ) )
286
287 IF( myrow.EQ.icurrow .AND. mycol.EQ.icurcol ) THEN
288 ioffd = ioffa
289 DO 40 ll = 0, jb-1
290 aii = a( ioffd )
291 sr( ii+ll ) = aii
292 sc( jj+ll ) = aii
293 smin =
min( smin, aii )
294 amax =
max( amax, aii )
295 IF( aii.LE.zero .AND. info.EQ.0 )
296 $ info = j + ll - ja + 1
297 ioffd = ioffd + lda + 1
298 40 CONTINUE
299 END IF
300
301 IF( myrow.EQ.icurrow ) THEN
302 ii = ii + jb
303 ioffa = ioffa + jb
304 END IF
305 IF( mycol.EQ.icurcol ) THEN
306 jj = jj + jb
307 ioffa = ioffa + jb*lda
308 END IF
309 icurrow = mod( icurrow+1, nprow )
310 icurcol = mod( icurcol+1, npcol )
311
312 50 CONTINUE
313
314
315
316 CALL dgsum2d( ictxt, 'Columnwise', colctop, 1, nq, sc( jja ),
317 $ 1, -1, mycol )
318 CALL dgsum2d( ictxt, 'Rowwise', rowctop, np, 1, sr( iia ),
319 $
max( 1, np ), -1, mycol )
320
321 CALL dgamx2d( ictxt, 'All', allctop, 1, 1, amax, 1, idumm, idumm,
322 $ -1, -1, mycol )
323 CALL dgamn2d( ictxt, 'All', allctop, 1, 1, smin, 1, idumm, idumm,
324 $ -1, -1, mycol )
325
326 IF( smin.LE.zero ) THEN
327
328
329
330 CALL igamn2d( ictxt, 'All', allctop, 1, 1, info, 1, ii, jj, -1,
331 $ -1, mycol )
332 RETURN
333
334 ELSE
335
336
337
338
339 DO 60 ii = iia, iia+np-1
340 sr( ii ) = one / sqrt( sr( ii ) )
341 60 CONTINUE
342
343 DO 70 jj = jja, jja+nq-1
344 sc( jj ) = one / sqrt( sc( jj ) )
345 70 CONTINUE
346
347
348
349 scond = sqrt( smin ) / sqrt( amax )
350
351 END IF
352
353 RETURN
354
355
356
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)
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)