5
6
7
8
9
10
11
12 INTEGER DCOL, DROW, IB1, IB2, ICTXT, K, LDQ, LDQ2, N,
13 $ N1, NB, NN, NN1, NN2, NPCOL
14 REAL RHO
15
16
17 INTEGER COLTYP( * ), CTOT( 0: NPCOL-1, 4 ),
18 $ INDCOL( N ), INDX( * ), INDXC( * ), INDXP( * ),
19 $ PSM( 0: NPCOL-1, 4 )
20 REAL D( * ), DLAMDA( * ), Q( LDQ, * ),
21 $ Q2( LDQ2, * ), QBUF( * ), W( * ), Z( * )
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 REAL MONE, ZERO, ONE, TWO, EIGHT
153 parameter( mone = -1.0e0, zero = 0.0e0, one = 1.0e0,
154 $ two = 2.0e0, eight = 8.0e0 )
155
156
157 INTEGER COL, CT, I, IAM, IE1, IE2, IMAX, INFO, J, JJQ2,
158 $ JJS, JMAX, JS, K2, MYCOL, MYROW, N1P1, N2, NJ,
159 $ NJCOL, NJJ, NP, NPROCS, NPROW, PJ, PJCOL, PJJ
160 REAL C, EPS, S, T, TAU, TOL
161
162
163 INTEGER INDXG2L, INDXL2G, ISAMAX, NUMROC
164 REAL PSLAMCH, SLAPY2
166 $ slapy2
167
168
169 EXTERNAL blacs_gridinfo, blacs_pinfo,
infog1l, scopy,
170 $ sgerv2d, sgesd2d,
slapst, srot, sscal
171
172
173 INTRINSIC abs,
max,
min, mod, sqrt
174
175
176
177
178 INTEGER PTT( 4 )
179
180
181
182
183
184 IF( n.EQ.0 )
185 $ RETURN
186
187 CALL blacs_pinfo( iam, nprocs )
188 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
189 np =
numroc( n, nb, myrow, drow, nprow )
190
191 n2 = n - n1
192 n1p1 = n1 + 1
193
194 IF( rho.LT.zero ) THEN
195 CALL sscal( n2, mone, z( n1p1 ), 1 )
196 END IF
197
198
199
200
201 t = one / sqrt( two )
202 CALL sscal( n, t, z, 1 )
203
204
205
206 rho = abs( two*rho )
207
208
209
210 imax = isamax( n, z, 1 )
211 jmax = isamax( n, d, 1 )
212 eps =
pslamch( ictxt,
'Epsilon' )
213 tol = eight*eps*
max( abs( d( jmax ) ), abs( z( imax ) ) )
214
215
216
217
218
219 IF( rho*abs( z( imax ) ).LE.tol ) THEN
220 k = 0
221 GO TO 220
222 END IF
223
224
225
226
227
228
229
230
231 CALL slapst(
'I', n, d, indx, info )
232
233 DO 10 i = 1, n1
234 coltyp( i ) = 1
235 10 CONTINUE
236 DO 20 i = n1p1, n
237 coltyp( i ) = 3
238 20 CONTINUE
239 col = dcol
240 DO 40 i = 1, n, nb
241 DO 30 j = 0, nb - 1
242 IF( i+j.LE.n )
243 $ indcol( i+j ) = col
244 30 CONTINUE
245 col = mod( col+1, npcol )
246 40 CONTINUE
247
248 k = 0
249 k2 = n + 1
250 DO 50 j = 1, n
251 nj = indx( j )
252 IF( rho*abs( z( nj ) ).LE.tol ) THEN
253
254
255
256 k2 = k2 - 1
257 coltyp( nj ) = 4
258 indxp( k2 ) = nj
259 IF( j.EQ.n )
260 $ GO TO 80
261 ELSE
262 pj = nj
263 GO TO 60
264 END IF
265 50 CONTINUE
266 60 CONTINUE
267 j = j + 1
268 nj = indx( j )
269 IF( j.GT.n )
270 $ GO TO 80
271 IF( rho*abs( z( nj ) ).LE.tol ) THEN
272
273
274
275 k2 = k2 - 1
276 coltyp( nj ) = 4
277 indxp( k2 ) = nj
278 ELSE
279
280
281
282 s = z( pj )
283 c = z( nj )
284
285
286
287
288 tau = slapy2( c, s )
289 t = d( nj ) - d( pj )
290 c = c / tau
291 s = -s / tau
292 IF( abs( t*c*s ).LE.tol ) THEN
293
294
295
296 z( nj ) = tau
297 z( pj ) = zero
298 IF( coltyp( nj ).NE.coltyp( pj ) )
299 $ coltyp( nj ) = 2
300 coltyp( pj ) = 4
301 CALL infog1l( nj, nb, npcol, mycol, dcol, njj, njcol )
302 CALL infog1l( pj, nb, npcol, mycol, dcol, pjj, pjcol )
303 IF( indcol( pj ).EQ.indcol( nj ) .AND. mycol.EQ.njcol ) THEN
304 CALL srot( np, q( 1, pjj ), 1, q( 1, njj ), 1, c, s )
305 ELSE IF( mycol.EQ.pjcol ) THEN
306 CALL sgesd2d( ictxt, np, 1, q( 1, pjj ), np, myrow,
307 $ njcol )
308 CALL sgerv2d( ictxt, np, 1, qbuf, np, myrow, njcol )
309 CALL srot( np, q( 1, pjj ), 1, qbuf, 1, c, s )
310 ELSE IF( mycol.EQ.njcol ) THEN
311 CALL sgesd2d( ictxt, np, 1, q( 1, njj ), np, myrow,
312 $ pjcol )
313 CALL sgerv2d( ictxt, np, 1, qbuf, np, myrow, pjcol )
314 CALL srot( np, qbuf, 1, q( 1, njj ), 1, c, s )
315 END IF
316 t = d( pj )*c**2 + d( nj )*s**2
317 d( nj ) = d( pj )*s**2 + d( nj )*c**2
318 d( pj ) = t
319 k2 = k2 - 1
320 i = 1
321 70 CONTINUE
322 IF( k2+i.LE.n ) THEN
323 IF( d( pj ).LT.d( indxp( k2+i ) ) ) THEN
324 indxp( k2+i-1 ) = indxp( k2+i )
325 indxp( k2+i ) = pj
326 i = i + 1
327 GO TO 70
328 ELSE
329 indxp( k2+i-1 ) = pj
330 END IF
331 ELSE
332 indxp( k2+i-1 ) = pj
333 END IF
334 pj = nj
335 ELSE
336 k = k + 1
337 dlamda( k ) = d( pj )
338 w( k ) = z( pj )
339 indxp( k ) = pj
340 pj = nj
341 END IF
342 END IF
343 GO TO 60
344 80 CONTINUE
345
346
347
348 k = k + 1
349 dlamda( k ) = d( pj )
350 w( k ) = z( pj )
351 indxp( k ) = pj
352
353
354
355
356
357
358 DO 100 j = 1, 4
359 DO 90 i = 0, npcol - 1
360 ctot( i, j ) = 0
361 90 CONTINUE
362 ptt( j ) = 0
363 100 CONTINUE
364 DO 110 j = 1, n
365 ct = coltyp( j )
366 col = indcol( j )
367 ctot( col, ct ) = ctot( col, ct ) + 1
368 110 CONTINUE
369
370
371
372 DO 120 col = 0, npcol - 1
373 psm( col, 1 ) = 1
374 psm( col, 2 ) = 1 + ctot( col, 1 )
375 psm( col, 3 ) = psm( col, 2 ) + ctot( col, 2 )
376 psm( col, 4 ) = psm( col, 3 ) + ctot( col, 3 )
377 120 CONTINUE
378 ptt( 1 ) = 1
379 DO 140 i = 2, 4
380 ct = 0
381 DO 130 j = 0, npcol - 1
382 ct = ct + ctot( j, i-1 )
383 130 CONTINUE
384 ptt( i ) = ptt( i-1 ) + ct
385 140 CONTINUE
386
387
388
389
390
391 DO 150 j = 1, n
392 js = indxp( j )
393 col = indcol( js )
394 ct = coltyp( js )
395 i =
indxl2g( psm( col, ct ), nb, col, dcol, npcol )
396 indx( j ) = i
397 indxc( ptt( ct ) ) = i
398 psm( col, ct ) = psm( col, ct ) + 1
399 ptt( ct ) = ptt( ct ) + 1
400 150 CONTINUE
401 DO 160 j = 1, n
402 js = indxp( j )
403 jjs =
indxg2l( js, nb, j, j, npcol )
404 col = indcol( js )
405 IF( col.EQ.mycol ) THEN
406 i = indx( j )
407 jjq2 =
indxg2l( i, nb, j, j, npcol )
408 CALL scopy( np, q( 1, jjs ), 1, q2( 1, jjq2 ), 1 )
409 END IF
410 160 CONTINUE
411
412
413
414
415
416 CALL scopy( n, d, 1, z, 1 )
417 DO 170 j = k + 1, n
418 js = indxp( j )
419 i = indx( j )
420 d( i ) = z( js )
421 170 CONTINUE
422
423 ptt( 1 ) = 1
424 DO 190 i = 2, 4
425 ct = 0
426 DO 180 j = 0, npcol - 1
427 ct = ct + ctot( j, i-1 )
428 180 CONTINUE
429 ptt( i ) = ptt( i-1 ) + ct
430 190 CONTINUE
431
432
433 ib1 = indxc( 1 )
434 ie1 = ib1
435 ib2 = indxc( ptt( 2 ) )
436 ie2 = ib2
437 DO 200 i = 2, ptt( 3 ) - 1
438 ib1 =
min( ib1, indxc( i ) )
439 ie1 =
max( ie1, indxc( i ) )
440 200 CONTINUE
441 DO 210 i = ptt( 2 ), ptt( 4 ) - 1
442 ib2 =
min( ib2, indxc( i ) )
443 ie2 =
max( ie2, indxc( i ) )
444 210 CONTINUE
445 nn1 = ie1 - ib1 + 1
446 nn2 = ie2 - ib2 + 1
447 nn =
max( ie1, ie2 ) -
min( ib1, ib2 ) + 1
448 220 CONTINUE
449 RETURN
450
451
452
integer function indxg2l(indxglob, nb, iproc, isrcproc, nprocs)
integer function indxl2g(indxloc, nb, iproc, isrcproc, nprocs)
subroutine infog1l(gindx, nb, nprocs, myroc, isrcproc, lindx, rocsrc)
integer function numroc(n, nb, iproc, isrcproc, nprocs)
real function pslamch(ictxt, cmach)
subroutine slapst(id, n, d, indx, info)