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