3
4
5
6
7
8
9
10 CHARACTER UPLO
11 INTEGER IA, INFO, JA, N
12
13
14 INTEGER DESCA( * )
15 REAL A( * ), D( * ), E( * ), TAU( * ), WORK( * )
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
150
151
152
153
154
155
156 INTEGER BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
157 $ LLD_, MB_, M_, NB_, N_, RSRC_
158 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
159 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
160 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
161 REAL EIGHT, HALF, ONE, ZERO
162 parameter( eight = 8.0e+0, half = 0.5e+0, one = 1.0e+0,
163 $ zero = 0.0e+0 )
164
165
166 LOGICAL UPPER
167 INTEGER I, IACOL, IAROW, ICTXT, II, IPT, IPV, IPX,
168 $ IPY, J, JB, JJ, JL, K, MYCOL, MYROW, NB, NP,
169 $ NPCOL, NPROW
170 REAL ADDBND, D1, D2, E1, E2
171
172
173 INTEGER DESCD( DLEN_ ), DESCE( DLEN_ ), DESCV( DLEN_ ),
174 $ DESCT( DLEN_ )
175
176
177 LOGICAL LSAME
178 INTEGER INDXG2P, NUMROC
179 REAL PSLAMCH
181
182
186 $ pssyr2k, pstrmm
187
188
189 INTRINSIC abs,
max,
min, mod
190
191
192
193 ictxt = desca( ctxt_ )
194 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
195
196 info = 0
197 nb = desca( mb_ )
198 upper =
lsame( uplo,
'U' )
199 CALL infog2l( ia, ja, desca, nprow, npcol, myrow, mycol, ii, jj,
200 $ iarow, iacol )
201 np =
numroc( n, nb, myrow, iarow, nprow )
202
203 ipt = 1
204 ipv = nb * nb + ipt
205 ipx = nb * np + ipv
206 ipy = nb * np + ipx
207
208 CALL descset( descd, 1, ja+n-1, 1, desca( nb_ ), myrow,
209 $ desca( csrc_ ), desca( ctxt_ ), 1 )
210
211 addbnd = eight *
pslamch( ictxt,
'eps' )
212
213 IF( upper ) THEN
214
215 CALL descset( desce, 1, ja+n-1, 1, desca( nb_ ), myrow,
216 $ desca( csrc_ ), desca( ctxt_ ), 1 )
217
218 DO 10 j = 0, n-1
219 d1 = zero
220 e1 = zero
221 d2 = zero
222 e2 = zero
223 CALL pselget(
' ',
' ', d2, d, 1, ja+j, descd )
224 CALL pselget(
'Columnwise',
' ', d1, a, ia+j, ja+j, desca )
225 IF( j.LT.(n-1) ) THEN
226 CALL pselget(
' ',
' ', e2, e, 1, ja+j+1, desce )
227 CALL pselget(
'Columnwise',
' ', e1, a, ia+j, ja+j+1,
228 $ desca )
229 END IF
230
231 IF( ( abs( d1 - d2 ).GT.( abs( d2 ) * addbnd ) ) .OR.
232 $ ( abs( e1 - e2 ).GT.( abs( e2 ) * addbnd ) ) )
233 $ info = info + 1
234 10 CONTINUE
235
236
237
238 CALL descset( descv, n, nb, nb, nb, iarow, iacol, ictxt,
240 CALL descset( desct, nb, nb, nb, nb, iarow, iacol, ictxt, nb )
241
242 DO 20 k = 0, n-1, nb
244 i = ia + k
245 j = ja + k
246
247
248
249 CALL pslarft(
'Backward',
'Columnwise', k+jb-1, jb, a, ia,
250 $ j, desca, tau, work( ipt ), work( ipv ) )
251
252
253
254 CALL pslacpy(
'All', k+jb-1, jb, a, ia, j, desca,
255 $ work( ipv ), 1, 1, descv )
256
257 IF( k.GT.0 ) THEN
258 CALL pslaset(
'Lower', jb+1, jb, zero, one, work( ipv ),
259 $ k, 1, descv )
260 ELSE
261 CALL pslaset(
'Lower', jb, jb-1, zero, one, work( ipv ),
262 $ 1, 2, descv )
263 CALL pslaset(
'Ge', jb, 1, zero, zero, work( ipv ), 1,
264 $ 1, descv )
265 END IF
266
267
268
269 IF( k.GT.0 ) THEN
270 CALL pslaset(
'Ge', k-1, jb, zero, zero, a, ia, j,
271 $ desca )
272 CALL pslaset(
'Upper', jb-1, jb-1, zero, zero, a, i-1,
273 $ j+1, desca )
274 ELSE IF( jb.GT.1 ) THEN
275 CALL pslaset(
'Upper', jb-2, jb-2, zero, zero, a, ia,
276 $ j+2, desca )
277 END IF
278
279
280
281 CALL pssymm( 'Left', 'Upper', k+jb, jb, one, a, ia, ja,
282 $ desca, work( ipv ), 1, 1, descv, zero,
283 $ work( ipx ), 1, 1, descv )
284 CALL pstrmm( 'Right', 'Lower', 'Transpose', 'Non-Unit',
285 $ k+jb, jb, one, work( ipt ), 1, 1, desct,
286 $ work( ipx ), 1, 1, descv )
287
288
289
290 CALL psgemm( 'Transpose', 'No transpose', jb, jb, k+jb, one,
291 $ work( ipv ), 1, 1, descv, work( ipx ), 1, 1,
292 $ descv, zero, work( ipy ), 1, 1, desct )
293 CALL pstrmm( 'Left', 'Lower', 'No transpose', 'Non-Unit',
294 $ jb, jb, one, work( ipt ), 1, 1, desct,
295 $ work( ipy ), 1, 1, desct )
296 CALL psgemm( 'No tranpose', 'No transpose', k+jb, jb, jb,
297 $ -half, work( ipv ), 1, 1, descv, work( ipy ),
298 $ 1, 1, desct, one, work( ipx ), 1, 1, descv )
299
300
301
302 CALL pssyr2k( 'Upper', 'No transpose', k+jb, jb, -one,
303 $ work( ipv ), 1, 1, descv, work( ipx ), 1, 1,
304 $ descv, one, a, ia, ja, desca )
305
306 descv( csrc_ ) = mod( descv( csrc_ ) + 1, npcol )
307 desct( csrc_ ) = mod( desct( csrc_ ) + 1, npcol )
308
309 20 CONTINUE
310
311 ELSE
312
313 CALL descset( desce, 1, ja+n-2, 1, desca( nb_ ), myrow,
314 $ desca( csrc_ ), desca( ctxt_ ), 1 )
315
316 DO 30 j = 0, n-1
317 d1 = zero
318 e1 = zero
319 d2 = zero
320 e2 = zero
321 CALL pselget(
' ',
' ', d2, d, 1, ja+j, descd )
322 CALL pselget(
'Columnwise',
' ', d1, a, ia+j, ja+j, desca )
323 IF( j.LT.(n-1) ) THEN
324 CALL pselget(
' ',
' ', e2, e, 1, ja+j, desce )
325 CALL pselget(
'Columnwise',
' ', e1, a, ia+j+1, ja+j,
326 $ desca )
327 END IF
328
329 IF( ( abs( d1 - d2 ).GT.( abs( d2 ) * addbnd ) ) .OR.
330 $ ( abs( e1 - e2 ).GT.( abs( e2 ) * addbnd ) ) )
331 $ info = info + 1
332 30 CONTINUE
333
334
335
336 jl =
max( ( ( ja+n-2 ) / nb ) * nb + 1, ja )
337 iacol =
indxg2p( jl, nb, mycol, desca( csrc_ ), npcol )
338 CALL descset( descv, n, nb, nb, nb, iarow, iacol, ictxt,
341 $ myrow, desca( rsrc_ ), nprow ), iacol, ictxt,
342 $ nb )
343
344 DO 40 j = jl, ja, -nb
345 k = j - ja + 1
346 i = ia + k - 1
347 jb =
min( n-k+1, nb )
348
349
350
351 CALL pslarft(
'Forward',
'Columnwise', n-k, jb, a, i+1, j,
352 $ desca, tau, work( ipt ), work( ipv ) )
353
354
355
356 CALL pslacpy(
'Lower', n-k, jb, a, i+1, j, desca,
357 $ work( ipv ), k+1, 1, descv )
358 CALL pslaset(
'Upper', n-k, jb, zero, one, work( ipv ),
359 $ k+1, 1, descv )
360 CALL pslaset(
'Ge', 1, jb, zero, zero, work( ipv ), k, 1,
361 $ descv )
362
363
364
365 CALL pslaset(
'Lower', n-k-1, jb, zero, zero, a, i+2, j,
366 $ desca )
367
368
369
370 CALL pssymm( 'Left', 'Lower', n-k+1, jb, one, a, i, j,
371 $ desca, work( ipv ), k, 1, descv, zero,
372 $ work( ipx ), k, 1, descv )
373 CALL pstrmm( 'Right', 'Upper', 'Transpose', 'Non-Unit',
374 $ n-k+1, jb, one, work( ipt ), 1, 1, desct,
375 $ work( ipx ), k, 1, descv )
376
377
378
379 CALL psgemm( 'Transpose', 'No transpose', jb, jb, n-k+1,
380 $ one, work( ipv ), k, 1, descv, work( ipx ),
381 $ k, 1, descv, zero, work( ipy ), 1, 1, desct )
382 CALL pstrmm( 'Left', 'Upper', 'No transpose', 'Non-Unit',
383 $ jb, jb, one, work( ipt ), 1, 1, desct,
384 $ work( ipy ), 1, 1, desct )
385 CALL psgemm( 'No transpose', 'No transpose', n-k+1, jb, jb,
386 $ -half, work( ipv ), k, 1, descv, work( ipy ),
387 $ 1, 1, desct, one, work( ipx ), k, 1, descv )
388
389
390
391 CALL pssyr2k( 'Lower', 'No tranpose', n-k+1, jb, -one,
392 $ work( ipv ), k, 1, descv, work( ipx ), k, 1,
393 $ descv, one, a, i, j, desca )
394
395 descv( csrc_ ) = mod( descv( csrc_ ) + npcol - 1, npcol )
396 desct( rsrc_ ) = mod( desct( rsrc_ ) + nprow - 1, nprow )
397 desct( csrc_ ) = mod( desct( csrc_ ) + npcol - 1, npcol )
398
399 40 CONTINUE
400
401 END IF
402
403 CALL igsum2d( ictxt, 'All', ' ', 1, 1, info, 1, -1, 0 )
404
405 RETURN
406
407
408
subroutine descset(desc, m, n, mb, nb, irsrc, icsrc, ictxt, lld)
integer function indxg2p(indxglob, 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 pslaset(uplo, m, n, alpha, beta, a, ia, ja, desca)
subroutine pselget(scope, top, alpha, a, ia, ja, desca)
subroutine pslacpy(uplo, m, n, a, ia, ja, desca, b, ib, jb, descb)
subroutine pslarft(direct, storev, n, k, v, iv, jv, descv, tau, t, work)