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