3
4
5
6
7
8
9
10 CHARACTER UPLO
11 INTEGER IA, INFO, JA, N
12
13
14 INTEGER DESCA( * )
15 DOUBLE PRECISION 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 DOUBLE PRECISION EIGHT, HALF, ONE, ZERO
162 parameter( eight = 8.0d+0, half = 0.5d+0, one = 1.0d+0,
163 $ zero = 0.0d+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 DOUBLE PRECISION 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 DOUBLE PRECISION PDLAMCH
181
182
186 $ pdsyr2k, pdtrmm
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 *
pdlamch( 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 pdelget(
' ',
' ', d2, d, 1, ja+j, descd )
224 CALL pdelget(
'Columnwise',
' ', d1, a, ia+j, ja+j, desca )
225 IF( j.LT.(n-1) ) THEN
226 CALL pdelget(
' ',
' ', e2, e, 1, ja+j+1, desce )
227 CALL pdelget(
'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 pdlarft(
'Backward',
'Columnwise', k+jb-1, jb, a, ia,
250 $ j, desca, tau, work( ipt ), work( ipv ) )
251
252
253
254 CALL pdlacpy(
'All', k+jb-1, jb, a, ia, j, desca,
255 $ work( ipv ), 1, 1, descv )
256
257 IF( k.GT.0 ) THEN
258 CALL pdlaset(
'Lower', jb+1, jb, zero, one, work( ipv ),
259 $ k, 1, descv )
260 ELSE
261 CALL pdlaset(
'Lower', jb, jb-1, zero, one, work( ipv ),
262 $ 1, 2, descv )
263 CALL pdlaset(
'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 pdlaset(
'Ge', k-1, jb, zero, zero, a, ia, j,
271 $ desca )
272 CALL pdlaset(
'Upper', jb-1, jb-1, zero, zero, a, i-1,
273 $ j+1, desca )
274 ELSE IF( jb.GT.1 ) THEN
275 CALL pdlaset(
'Upper', jb-2, jb-2, zero, zero, a, ia,
276 $ j+2, desca )
277 END IF
278
279
280
281 CALL pdsymm( '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 pdtrmm( '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 pdgemm( '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 pdtrmm( 'Left', 'Lower', 'No transpose', 'Non-Unit',
294 $ jb, jb, one, work( ipt ), 1, 1, desct,
295 $ work( ipy ), 1, 1, desct )
296 CALL pdgemm( '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 pdsyr2k( '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 pdelget(
' ',
' ', d2, d, 1, ja+j, descd )
322 CALL pdelget(
'Columnwise',
' ', d1, a, ia+j, ja+j, desca )
323 IF( j.LT.(n-1) ) THEN
324 CALL pdelget(
' ',
' ', e2, e, 1, ja+j, desce )
325 CALL pdelget(
'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 pdlarft(
'Forward',
'Columnwise', n-k, jb, a, i+1, j,
352 $ desca, tau, work( ipt ), work( ipv ) )
353
354
355
356 CALL pdlacpy(
'Lower', n-k, jb, a, i+1, j, desca,
357 $ work( ipv ), k+1, 1, descv )
358 CALL pdlaset(
'Upper', n-k, jb, zero, one, work( ipv ),
359 $ k+1, 1, descv )
360 CALL pdlaset(
'Ge', 1, jb, zero, zero, work( ipv ), k, 1,
361 $ descv )
362
363
364
365 CALL pdlaset(
'Lower', n-k-1, jb, zero, zero, a, i+2, j,
366 $ desca )
367
368
369
370 CALL pdsymm( '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 pdtrmm( '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 pdgemm( '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 pdtrmm( 'Left', 'Upper', 'No transpose', 'Non-Unit',
383 $ jb, jb, one, work( ipt ), 1, 1, desct,
384 $ work( ipy ), 1, 1, desct )
385 CALL pdgemm( '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 pdsyr2k( '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)
subroutine pdlaset(uplo, m, n, alpha, beta, a, ia, ja, desca)
double precision function pdlamch(ictxt, cmach)
subroutine pdelget(scope, top, alpha, a, ia, ja, desca)
subroutine pdlacpy(uplo, m, n, a, ia, ja, desca, b, ib, jb, descb)
subroutine pdlarft(direct, storev, n, k, v, iv, jv, descv, tau, t, work)