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