3
4
5
6
7
8
9
10 INTEGER IV, IX, JV, JX, KASE, N
11 REAL EST
12
13
14 INTEGER DESCV( * ), DESCX( * ), ISGN( * )
15 REAL V( * ), X( * )
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 INTEGER ITMAX
155 parameter( itmax = 5 )
156 REAL ZERO, ONE, TWO
157 parameter( zero = 0.0e+0, one = 1.0e+0, two = 2.0e+0 )
158
159
160 INTEGER I, ICTXT, IFLAG, IIVX, IMAXROW, IOFFVX, IROFF,
161 $ ITER, IVXCOL, IVXROW, J, JLAST, JJVX, JUMP,
162 $ K, MYCOL, MYROW, NP, NPCOL, NPROW
163 REAL ALTSGN, ESTOLD, JLMAX, XMAX
164
165
166 REAL WORK( 2 )
167 REAL ESTWORK( 1 )
168 REAL TEMP( 1 )
169
170
171 EXTERNAL blacs_gridinfo, igsum2d,
infog2l, psamax,
173 $ sgebs2d, scopy
174
175
176 INTEGER INDXG2L, INDXG2P, INDXL2G, NUMROC
178
179
180 INTRINSIC abs, mod, nint, real, sign
181
182
183 SAVE
184
185
186
187
188
189 estwork( 1 ) = est
190 ictxt = descx( ctxt_ )
191 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
192
193 CALL infog2l( ix, jx, descx, nprow, npcol, myrow, mycol,
194 $ iivx, jjvx, ivxrow, ivxcol )
195 IF( mycol.NE.ivxcol )
196 $ RETURN
197 iroff = mod( ix-1, descx( mb_ ) )
198 np =
numroc( n+iroff, descx( mb_ ), myrow, ivxrow, nprow )
199 IF( myrow.EQ.ivxrow )
200 $ np = np - iroff
201 ioffvx = iivx + (jjvx-1)*descx( lld_ )
202
203 IF( kase.EQ.0 ) THEN
204 DO 10 i = ioffvx, ioffvx+np-1
205 x( i ) = one / real( n )
206 10 CONTINUE
207 kase = 1
208 jump = 1
209 RETURN
210 END IF
211
212 GO TO ( 20, 40, 70, 110, 140 )jump
213
214
215
216
217 20 CONTINUE
218 IF( n.EQ.1 ) THEN
219 IF( myrow.EQ.ivxrow ) THEN
220 v( ioffvx ) = x( ioffvx )
221 estwork( 1 ) = abs( v( ioffvx ) )
222 CALL sgebs2d( ictxt, 'Columnwise', ' ', 1, 1, estwork, 1 )
223 ELSE
224 CALL sgebr2d( ictxt, 'Columnwise', ' ', 1, 1, estwork, 1,
225 $ ivxrow, mycol )
226 END IF
227
228 GO TO 150
229 END IF
230 CALL psasum( n, estwork( 1 ), x, ix, jx, descx, 1 )
231 IF( descx( m_ ).EQ.1 .AND. n.EQ.1 ) THEN
232 IF( myrow.EQ.ivxrow ) THEN
233 CALL sgebs2d( ictxt, 'Columnwise', ' ', 1, 1, estwork, 1 )
234 ELSE
235 CALL sgebr2d( ictxt, 'Columnwise', ' ', 1, 1, estwork, 1,
236 $ ivxrow, mycol )
237 END IF
238 END IF
239
240 DO 30 i = ioffvx, ioffvx+np-1
241 x( i ) = sign( one, x( i ) )
242 isgn( i ) = nint( x( i ) )
243 30 CONTINUE
244 kase = 2
245 jump = 2
246 RETURN
247
248
249
250
251 40 CONTINUE
252 CALL psamax( n, xmax, j, x, ix, jx, descx, 1 )
253 IF( descx( m_ ).EQ.1 .AND. n.EQ.1 ) THEN
254 IF( myrow.EQ.ivxrow ) THEN
255 work( 1 ) = xmax
256 work( 2 ) = real( j )
257 CALL sgebs2d( ictxt, 'Columnwise', ' ', 2, 1, work, 2 )
258 ELSE
259 CALL sgebr2d( ictxt, 'Columnwise', ' ', 2, 1, work, 2,
260 $ ivxrow, mycol )
261 xmax = work( 1 )
262 j = nint( work( 2 ) )
263 END IF
264 END IF
265 iter = 2
266
267
268
269 50 CONTINUE
270 DO 60 i = ioffvx, ioffvx+np-1
271 x( i ) = zero
272 60 CONTINUE
273 imaxrow =
indxg2p( j, descx( mb_ ), myrow, descx( rsrc_ ), nprow )
274 IF( myrow.EQ.imaxrow ) THEN
275 i =
indxg2l( j, descx( mb_ ), myrow, descx( rsrc_ ), nprow )
276 x( i ) = one
277 END IF
278 kase = 1
279 jump = 3
280 RETURN
281
282
283
284
285 70 CONTINUE
286 CALL scopy( np, x( ioffvx ), 1, v( ioffvx ), 1 )
287 estold = estwork( 1 )
288 CALL psasum( n, estwork( 1 ), v, iv, jv, descv, 1 )
289 IF( descv( m_ ).EQ.1 .AND. n.EQ.1 ) THEN
290 IF( myrow.EQ.ivxrow ) THEN
291 CALL sgebs2d( ictxt, 'Columnwise', ' ', 1, 1, estwork, 1 )
292 ELSE
293 CALL sgebr2d( ictxt, 'Columnwise', ' ', 1, 1, estwork, 1,
294 $ ivxrow, mycol )
295 END IF
296 END IF
297 iflag = 0
298 DO 80 i = ioffvx, ioffvx+np-1
299 IF( nint( sign( one, x( i ) ) ).NE.isgn( i ) ) THEN
300 iflag = 1
301 GO TO 90
302 END IF
303 80 CONTINUE
304
305 90 CONTINUE
306 CALL igsum2d( ictxt, 'C', ' ', 1, 1, iflag, 1, -1, mycol )
307
308
309
310
311 IF( iflag.EQ.0 .OR. estwork( 1 ).LE.estold )
312 $ GO TO 120
313
314 DO 100 i = ioffvx, ioffvx+np-1
315 x( i ) = sign( one, x( i ) )
316 isgn( i ) = nint( x( i ) )
317 100 CONTINUE
318 kase = 2
319 jump = 4
320 RETURN
321
322
323
324
325 110 CONTINUE
326 jlast = j
327 CALL psamax( n, xmax, j, x, ix, jx, descx, 1 )
328 IF( descx( m_ ).EQ.1 .AND. n.EQ.1 ) THEN
329 IF( myrow.EQ.ivxrow ) THEN
330 work( 1 ) = xmax
331 work( 2 ) = real( j )
332 CALL sgebs2d( ictxt, 'Columnwise', ' ', 2, 1, work, 2 )
333 ELSE
334 CALL sgebr2d( ictxt, 'Columnwise', ' ', 2, 1, work, 2,
335 $ ivxrow, mycol )
336 xmax = work( 1 )
337 j = nint( work( 2 ) )
338 END IF
339 END IF
340 CALL pselget(
'Columnwise',
' ', jlmax, x, jlast, jx, descx )
341 IF( ( jlmax.NE.abs( xmax ) ).AND.( iter.LT.itmax ) ) THEN
342 iter = iter + 1
343 GO TO 50
344 END IF
345
346
347
348 120 CONTINUE
349 DO 130 i = ioffvx, ioffvx+np-1
350 k =
indxl2g( i-ioffvx+iivx, descx( mb_ ), myrow,
351 $ descx( rsrc_ ), nprow )-ix+1
352 IF( mod( k, 2 ).EQ.0 ) THEN
353 altsgn = -one
354 ELSE
355 altsgn = one
356 END IF
357 x( i ) = altsgn*( one+real( k-1 ) / real( n-1 ) )
358 130 CONTINUE
359 kase = 1
360 jump = 5
361 RETURN
362
363
364
365
366 140 CONTINUE
367 CALL psasum( n, temp( 1 ), x, ix, jx, descx, 1 )
368 IF( descx( m_ ).EQ.1 .AND. n.EQ.1 ) THEN
369 IF( myrow.EQ.ivxrow ) THEN
370 CALL sgebs2d( ictxt, 'Columnwise', ' ', 1, 1, temp, 1 )
371 ELSE
372 CALL sgebr2d( ictxt, 'Columnwise', ' ', 1, 1, temp, 1,
373 $ ivxrow, mycol )
374 END IF
375 END IF
376 temp( 1 ) = two*( temp( 1 ) / real( 3*n ) )
377 IF( temp( 1 ).GT.estwork( 1 ) ) THEN
378 CALL scopy( np, x( ioffvx ), 1, v( ioffvx ), 1 )
379 estwork( 1 ) = temp( 1 )
380 END IF
381
382 150 CONTINUE
383 kase = 0
384
385 est = estwork( 1 )
386 RETURN
387
388
389
integer function indxg2l(indxglob, nb, iproc, isrcproc, nprocs)
integer function indxg2p(indxglob, nb, iproc, isrcproc, nprocs)
integer function indxl2g(indxloc, 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 pselget(scope, top, alpha, a, ia, ja, desca)