2
3
4
5
6
7
8
9
10
11 IMPLICIT NONE
12
13
14 CHARACTER JOB
15 INTEGER IHI, ILO, INFO, N
16
17
18 INTEGER DESCA( * )
19 REAL A( * ), SCALE( * )
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 INTEGER BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
173 $ LLD_, MB_, M_, NB_, N_, RSRC_
174 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
175 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
176 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
177 REAL ZERO, ONE
178 parameter( zero = 0.0e+0, one = 1.0e+0 )
179 REAL SCLFAC
180 parameter( sclfac = 2.0e+0 )
181 REAL FACTOR
182 parameter( factor = 0.95e+0 )
183
184
185 LOGICAL NOCONV
186 INTEGER I, ICA, IEXC, IRA, J, K, L, M, LLDA,
187 $ ICTXT, NPROW, NPCOL, MYROW, MYCOL, II, JJ,
188 $ ARSRC, ACSRC
189 REAL C, CA, F, G, R, RA, S, SFMAX1, SFMAX2, SFMIN1,
190 $ SFMIN2, ELEM
191
192
193 REAL CR( 2 )
194
195
196 LOGICAL SISNAN, LSAME
197 INTEGER IDAMAX
198 REAL SLAMCH
200
201
202 EXTERNAL psscal, psswap, psamax,
pxerbla,
203 $ blacs_gridinfo,
chk1mat, sgsum2d,
205
206
208
209
210 info = 0
211 ictxt = desca( ctxt_ )
212 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
213
214
215
216 IF( .NOT.
lsame( job,
'N' ) .AND. .NOT.
lsame( job,
'P' ) .AND.
217 $ .NOT.
lsame( job,
'S' ) .AND. .NOT.
lsame( job,
'B' ) )
THEN
218 info = -1
219 ELSE IF( n.LT.0 ) THEN
220 info = -2
221 ELSE
222 CALL chk1mat( n, 2, n, 2, 1, 1, desca, 4, info )
223 END IF
224 IF( info.NE.0 ) THEN
225 CALL pxerbla( ictxt,
'PSGEBAL', -info )
226 RETURN
227 END IF
228
229
230
231 llda = desca( lld_ )
232
233 k = 1
234 l = n
235
236 IF( n.EQ.0 )
237 $ GO TO 210
238
239 IF(
lsame( job,
'N' ) )
THEN
240 DO 10 i = 1, n
241 scale( i ) = one
242 10 CONTINUE
243 GO TO 210
244 END IF
245
246 IF(
lsame( job,
'S' ) )
247 $ GO TO 120
248
249
250
251 GO TO 50
252
253
254
255 20 CONTINUE
256 scale( m ) = j
257 IF( j.EQ.m )
258 $ GO TO 30
259
260 CALL psswap( l, a, 1, j, desca, 1, a, 1, m, desca, 1 )
261 CALL psswap( n-k+1, a, j, k, desca, desca(m_), a, m, k, desca,
262 $ desca(m_) )
263
264 30 CONTINUE
265 GO TO ( 40, 80 )iexc
266
267
268
269 40 CONTINUE
270 IF( l.EQ.1 )
271 $ GO TO 210
272 l = l - 1
273
274 50 CONTINUE
275 DO 70 j = l, 1, -1
276
277 DO 60 i = 1, l
278 IF( i.EQ.j )
279 $ GO TO 60
280
281
282
283 CALL pselget(
'All',
'1-Tree', elem, a, j, i, desca )
284 IF( elem.NE.zero )
285 $ GO TO 70
286 60 CONTINUE
287
288 m = l
289 iexc = 1
290 GO TO 20
291 70 CONTINUE
292
293 GO TO 90
294
295
296
297 80 CONTINUE
298 k = k + 1
299
300 90 CONTINUE
301 DO 110 j = k, l
302
303 DO 100 i = k, l
304 IF( i.EQ.j )
305 $ GO TO 100
306
307
308
309 CALL pselget(
'All',
'1-Tree', elem, a, i, j, desca )
310 IF( elem.NE.zero )
311 $ GO TO 110
312 100 CONTINUE
313
314 m = k
315 iexc = 2
316 GO TO 20
317 110 CONTINUE
318
319 120 CONTINUE
320 DO 130 i = k, l
321 scale( i ) = one
322 130 CONTINUE
323
324 IF(
lsame( job,
'P' ) )
325 $ GO TO 210
326
327
328
329
330
332 sfmax1 = one / sfmin1
333 sfmin2 = sfmin1*sclfac
334 sfmax2 = one / sfmin2
335 140 CONTINUE
336 noconv = .false.
337
338 DO 200 i = k, l
339 c = zero
340 r = zero
341
342
343
344
345
346 DO 150 j = k, l
347 IF( j.EQ.i )
348 $ GO TO 150
349 CALL infog2l( j, i, desca, nprow, npcol, myrow,
350 $ mycol, ii, jj, arsrc, acsrc )
351 IF( myrow.EQ.arsrc .AND. mycol.EQ.acsrc ) THEN
352 c = c + abs( a( ii + (jj-1)*llda ) )
353 END IF
354 CALL infog2l( i, j, desca, nprow, npcol, myrow,
355 $ mycol, ii, jj, arsrc, acsrc )
356 IF( myrow.EQ.arsrc .AND. mycol.EQ.acsrc ) THEN
357 r = r + abs( a( ii + (jj-1)*llda ) )
358 END IF
359 150 CONTINUE
360 cr( 1 ) = c
361 cr( 2 ) = r
362 CALL sgsum2d( ictxt, 'All', '1-Tree', 2, 1, cr, 2, -1, -1 )
363 c = cr( 1 )
364 r = cr( 2 )
365
366
367
368 CALL psamax( l, ca, ica, a, 1, i, desca, 1 )
369 CALL psamax( n-k+1, ra, ira, a, i, k, desca, desca(m_) )
370
371
372
373 IF( c.EQ.zero .OR. r.EQ.zero )
374 $ GO TO 200
375 g = r / sclfac
376 f = one
377 s = c + r
378 160 CONTINUE
379 IF( c.GE.g .OR.
max( f, c, ca ).GE.sfmax2 .OR.
380 $
min( r, g, ra ).LE.sfmin2 )
GO TO 170
381 IF( sisnan( c+f+ca+r+g+ra ) ) THEN
382
383
384
385 info = -3
386 CALL pxerbla( ictxt,
'PDGEBAL', -info )
387 RETURN
388 END IF
389 f = f*sclfac
390 c = c*sclfac
391 ca = ca*sclfac
392 r = r / sclfac
393 g = g / sclfac
394 ra = ra / sclfac
395 GO TO 160
396
397 170 CONTINUE
398 g = c / sclfac
399 180 CONTINUE
400 IF( g.LT.r .OR.
max( r, ra ).GE.sfmax2 .OR.
401 $
min( f, c, g, ca ).LE.sfmin2 )
GO TO 190
402 f = f / sclfac
403 c = c / sclfac
404 g = g / sclfac
405 ca = ca / sclfac
406 r = r*sclfac
407 ra = ra*sclfac
408 GO TO 180
409
410
411
412 190 CONTINUE
413 IF( ( c+r ).GE.factor*s )
414 $ GO TO 200
415 IF( f.LT.one .AND. scale( i ).LT.one ) THEN
416 IF( f*scale( i ).LE.sfmin1 )
417 $ GO TO 200
418 END IF
419 IF( f.GT.one .AND. scale( i ).GT.one ) THEN
420 IF( scale( i ).GE.sfmax1 / f )
421 $ GO TO 200
422 END IF
423 g = one / f
424 scale( i ) = scale( i )*f
425 noconv = .true.
426
427 CALL psscal( n-k+1, g, a, i, k, desca, desca(m_) )
428 CALL psscal( l, f, a, 1, i, desca, 1 )
429
430 200 CONTINUE
431
432 IF( noconv )
433 $ GO TO 140
434
435 210 CONTINUE
436 ilo = k
437 ihi = l
438
439 RETURN
440
441
442
subroutine chk1mat(ma, mapos0, na, napos0, ia, ja, desca, descapos0, info)
subroutine infog2l(grindx, gcindx, desc, nprow, npcol, myrow, mycol, lrindx, lcindx, rsrc, csrc)
subroutine pselget(scope, top, alpha, a, ia, ja, desca)
subroutine pxerbla(ictxt, srname, info)