3
4
5
6
7
8
9
10 INTEGER INFO, IA, JA, M, N
11
12
13 INTEGER DESCA( * )
14 DOUBLE PRECISION D( * ), E( * )
15 COMPLEX*16 A( * ), TAUP( * ), TAUQ( * ), 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 INTEGER BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
154 $ LLD_, MB_, M_, NB_, N_, RSRC_
155 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
156 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
157 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
158 DOUBLE PRECISION REIGHT, RZERO
159 parameter( reight = 8.0d+0, rzero = 0.0d+0 )
160 COMPLEX*16 ONE, ZERO
161 parameter( one = ( 1.0d+0, 0.0d+0 ),
162 $ zero = ( 0.0d+0, 0.0d+0 ) )
163
164
165 INTEGER I, IACOL, IAROW, ICTXT, IIA, IL, IPTP, IPTQ,
166 $ IPV, IPW, IPWK, IOFF, IV, J, JB, JJA, JL, JV,
167 $ K, MN, MP, MYCOL, MYROW, NB, NPCOL, NPROW, NQ
168 DOUBLE PRECISION ADDBND, D2, E2
169 COMPLEX*16 D1, E1
170
171
172 INTEGER DESCD( DLEN_ ), DESCE( DLEN_ ), DESCV( DLEN_ ),
173 $ DESCW( DLEN_ )
174
175
179
180
181 INTEGER INDXG2P, NUMROC
182 DOUBLE PRECISION PDLAMCH
184
185
186 INTRINSIC abs, dcmplx,
max,
min, mod
187
188
189
190
191
192 ictxt = desca( ctxt_ )
193 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
194
195 info = 0
196 nb = desca( mb_ )
197 ioff = mod( ia-1, nb )
198 CALL infog2l( ia, ja, desca, nprow, npcol, myrow, mycol, iia, jja,
199 $ iarow, iacol )
200 mp =
numroc( m+ioff, nb, myrow, iarow, nprow )
201 nq =
numroc( n+ioff, nb, mycol, iacol, npcol )
202 ipv = 1
203 ipw = ipv + mp*nb
204 iptp = ipw + nq*nb
205 iptq = iptp + nb*nb
206 ipwk = iptq + nb*nb
207
208 iv = 1
209 jv = 1
211 il =
max( ( (ia+mn-2) / nb )*nb + 1, ia )
212 jl =
max( ( (ja+mn-2) / nb )*nb + 1, ja )
213 iarow =
indxg2p( il, nb, myrow, desca( rsrc_ ), nprow )
214 iacol =
indxg2p( jl, nb, mycol, desca( csrc_ ), npcol )
215 CALL descset( descv, ia+m-il, nb, nb, nb, iarow, iacol, ictxt,
217 CALL descset( descw, nb, ja+n-jl, nb, nb, iarow, iacol, ictxt,
218 $ nb )
219
220 addbnd = reight *
pdlamch( ictxt,
'eps' )
221
222
223
224 IF( m.GE.n ) THEN
225
226 CALL descset( descd, 1, ja+mn-1, 1, desca( nb_ ), myrow,
227 $ desca( csrc_ ), desca( ctxt_ ), 1 )
228 CALL descset( desce, ia+mn-1, 1, desca( mb_ ), 1,
229 $ desca( rsrc_ ), mycol, desca( ctxt_ ),
230 $ desca( lld_ ) )
231
232 DO 10 j = 0, mn-1
233 d1 = zero
234 e1 = zero
235 d2 = rzero
236 e2 = rzero
237 CALL pdelget(
' ',
' ', d2, d, 1, ja+j, descd )
238 CALL pzelget(
'Columnwise',
' ', d1, a, ia+j, ja+j, desca )
239 IF( j.LT.(mn-1) ) THEN
240 CALL pdelget(
' ',
' ', e2, e, ia+j, 1, desce )
241 CALL pzelget(
'Rowwise',
' ', e1, a, ia+j, ja+j+1,
242 $ desca )
243 END IF
244
245 IF( ( abs( d1-dcmplx( d2 ) ).GT.( abs( d2 )*addbnd ) ) .OR.
246 $ ( abs( e1-dcmplx( e2 ) ).GT.( abs( e2 )*addbnd ) ) )
247 $ info = info + 1
248 10 CONTINUE
249
250 DO 20 j = jl, ja+nb-ioff, -nb
251 jb =
min( ja+n-j, nb )
252 i = ia + j - ja
253 k = i - ia + 1
254
255
256
257 CALL pzlarft(
'Forward',
'Columnwise', m-k+1, jb, a, i, j,
258 $ desca, tauq, work( iptq ), work( ipwk ) )
259
260
261
262 CALL pzlacpy(
'Lower', m-k+1, jb, a, i, j, desca,
263 $ work( ipv ), iv, jv, descv )
264 CALL pzlaset(
'Upper', m-k+1, jb, zero, one, work( ipv ),
265 $ iv, jv, descv )
266
267
268
269 CALL pzlaset(
'Lower', m-k, jb, zero, zero, a, i+1, j,
270 $ desca )
271
272
273
274 CALL pzlarft(
'Forward',
'Rowwise', n-k, jb, a, i, j+1,
275 $ desca, taup, work( iptp ), work( ipwk ) )
276
277
278
279 CALL pzlacpy(
'Upper', jb, n-k, a, i, j+1, desca,
280 $ work( ipw ), iv, jv+1, descw )
281 CALL pzlaset(
'Lower', jb, n-k, zero, one, work( ipw ), iv,
282 $ jv+1, descw )
283
284
285
286 CALL pzlaset(
'Upper', jb, n-k-1, zero, zero, a, i, j+2,
287 $ desca )
288
289
290
291 CALL pzlarfb(
'Left',
'No transpose',
'Forward',
292 $ 'Columnwise', m-k+1, n-k+1, jb, work( ipv ),
293 $ iv, jv, descv, work( iptq ), a, i, j, desca,
294 $ work( ipwk ) )
295
296
297
298 CALL pzlarfb(
'Right',
'Conjugate transpose',
'Forward',
299 $ 'Rowwise', m-k+1, n-k, jb, work( ipw ), iv,
300 $ jv+1, descw, work( iptp ), a, i, j+1, desca,
301 $ work( ipwk ) )
302
303 descv( m_ ) = descv( m_ ) + nb
304 descv( rsrc_ ) = mod( descv( rsrc_ ) + nprow - 1, nprow )
305 descv( csrc_ ) = mod( descv( csrc_ ) + npcol - 1, npcol )
306 descw( n_ ) = descw( n_ ) + nb
307 descw( rsrc_ ) = descv( rsrc_ )
308 descw( csrc_ ) = descv( csrc_ )
309
310 20 CONTINUE
311
312
313
314 jb =
min( n, nb - ioff )
315 iv = ioff + 1
316 jv = ioff + 1
317
318
319
320 CALL pzlarft(
'Forward',
'Columnwise', m, jb, a, ia, ja, desca,
321 $ tauq, work( iptq ), work( ipwk ) )
322
323
324
325 CALL pzlacpy(
'Lower', m, jb, a, ia, ja, desca, work( ipv ),
326 $ iv, jv, descv )
327 CALL pzlaset(
'Upper', m, jb, zero, one, work( ipv ), iv, jv,
328 $ descv )
329
330
331
332 CALL pzlaset(
'Lower', m-1, jb, zero, zero, a, ia+1, ja,
333 $ desca )
334
335
336
337 CALL pzlarft(
'Forward',
'Rowwise', n-1, jb, a, ia, ja+1,
338 $ desca, taup, work( iptp ), work( ipwk ) )
339
340
341
342 CALL pzlacpy(
'Upper', jb, n-1, a, ia, ja+1, desca,
343 $ work( ipw ), iv, jv+1, descw )
344 CALL pzlaset(
'Lower', jb, n-1, zero, one, work( ipw ), iv,
345 $ jv+1, descw )
346
347
348
349 CALL pzlaset(
'Upper', jb, n-2, zero, zero, a, ia, ja+2,
350 $ desca )
351
352
353
354 CALL pzlarfb(
'Left',
'No transpose',
'Forward',
'Columnwise',
355 $ m, n, jb, work( ipv ), iv, jv, descv,
356 $ work( iptq ), a, ia, ja, desca, work( ipwk ) )
357
358
359
360 CALL pzlarfb(
'Right',
'Conjugate transpose',
'Forward',
361 $ 'Rowwise', m, n-1, jb, work( ipw ), iv, jv+1,
362 $ descw, work( iptp ), a, ia, ja+1, desca,
363 $ work( ipwk ) )
364
365 ELSE
366
367 CALL descset( descd, ia+mn-1, 1, desca( mb_ ), 1,
368 $ desca( rsrc_ ), mycol, desca( ctxt_ ),
369 $ desca( lld_ ) )
370 CALL descset( desce, 1, ja+mn-2, 1, desca( nb_ ), myrow,
371 $ desca( csrc_ ), desca( ctxt_ ), 1 )
372
373 DO 30 j = 0, mn-1
374 d1 = zero
375 e1 = zero
376 d2 = rzero
377 e2 = rzero
378 CALL pdelget(
' ',
' ', d2, d, ia+j, 1, descd )
379 CALL pzelget(
'Rowwise',
' ', d1, a, ia+j, ja+j, desca )
380 IF( j.LT.(mn-1) ) THEN
381 CALL pdelget(
' ',
' ', e2, e, 1, ja+j, desce )
382 CALL pzelget(
'Columnwise',
' ', e1, a, ia+j+1, ja+j,
383 $ desca )
384 END IF
385
386 IF( ( abs( d1-dcmplx( d2 ) ).GT.( abs( d2 )*addbnd ) ) .OR.
387 $ ( abs( e1-dcmplx( e2 ) ).GT.( abs( e2 )*addbnd ) ) )
388 $ info = info + 1
389 30 CONTINUE
390
391 DO 40 i = il, ia+nb-ioff, -nb
392 jb =
min( ia+m-i, nb )
393 j = ja + i - ia
394 k = j - ja + 1
395
396
397
398 CALL pzlarft(
'Forward',
'Columnwise', m-k, jb, a, i+1, j,
399 $ desca, tauq, work( iptq ), work( ipwk ) )
400
401
402
403 CALL pzlacpy(
'Lower', m-k, jb, a, i+1, j, desca,
404 $ work( ipv ), iv+1, jv, descv )
405 CALL pzlaset(
'Upper', m-k, jb, zero, one, work( ipv ),
406 $ iv+1, jv, descv )
407
408
409
410 CALL pzlaset(
'Lower', m-k-1, jb, zero, zero, a, i+2, j,
411 $ desca )
412
413
414
415 CALL pzlarft(
'Forward',
'Rowwise', n-k+1, jb, a, i, j,
416 $ desca, taup, work( iptp ), work( ipwk ) )
417
418
419
420 CALL pzlacpy(
'Upper', jb, n-k+1, a, i, j, desca,
421 $ work( ipw ), iv, jv, descw )
422 CALL pzlaset(
'Lower', jb, n-k+1, zero, one, work( ipw ),
423 $ iv, jv, descw )
424
425
426
427 CALL pzlaset(
'Upper', jb, n-k, zero, zero, a, i, j+1,
428 $ desca )
429
430
431
432 CALL pzlarfb(
'Left',
'No transpose',
'Forward',
433 $ 'Columnwise', m-k, n-k+1, jb, work( ipv ),
434 $ iv+1, jv, descv, work( iptq ), a, i+1, j,
435 $ desca, work( ipwk ) )
436
437
438
439 CALL pzlarfb(
'Right',
'Conjugate transpose',
'Forward',
440 $ 'Rowwise', m-k+1, n-k+1, jb, work( ipw ), iv,
441 $ jv, descw, work( iptp ), a, i, j, desca,
442 $ work( ipwk ) )
443
444 descv( m_ ) = descv( m_ ) + nb
445 descv( rsrc_ ) = mod( descv( rsrc_ ) + nprow - 1, nprow )
446 descv( csrc_ ) = mod( descv( csrc_ ) + npcol - 1, npcol )
447 descw( n_ ) = descw( n_ ) + nb
448 descw( rsrc_ ) = descv( rsrc_ )
449 descw( csrc_ ) = descv( csrc_ )
450
451 40 CONTINUE
452
453
454
455 jb =
min( m, nb - ioff )
456 iv = ioff + 1
457 jv = ioff + 1
458
459
460
461 CALL pzlarft(
'Forward',
'Columnwise', m-1, jb, a, ia+1, ja,
462 $ desca, tauq, work( iptq ), work( ipwk ) )
463
464
465
466 CALL pzlacpy(
'Lower', m-1, jb, a, ia+1, ja, desca,
467 $ work( ipv ), iv+1, jv, descv )
468 CALL pzlaset(
'Upper', m-1, jb, zero, one, work( ipv ), iv+1,
469 $ jv, descv )
470
471
472
473 CALL pzlaset(
'Lower', m-2, jb, zero, zero, a, ia+2, ja,
474 $ desca )
475
476
477
478 CALL pzlarft(
'Forward',
'Rowwise', n, jb, a, ia, ja, desca,
479 $ taup, work( iptp ), work( ipwk ) )
480
481
482
483 CALL pzlacpy(
'Upper', jb, n, a, ia, ja, desca, work( ipw ),
484 $ iv, jv, descw )
485 CALL pzlaset(
'Lower', jb, n, zero, one, work( ipw ), iv, jv,
486 $ descw )
487
488
489
490 CALL pzlaset(
'Upper', jb, n-1, zero, zero, a, ia, ja+1,
491 $ desca )
492
493
494
495 CALL pzlarfb(
'Left',
'No transpose',
'Forward',
'Columnwise',
496 $ m-1, n, jb, work( ipv ), iv+1, jv, descv,
497 $ work( iptq ), a, ia+1, ja, desca, work( ipwk ) )
498
499
500
501 CALL pzlarfb(
'Right',
'Conjugate transpose',
'Forward',
502 $ 'Rowwise', m, n, jb, work( ipw ), iv, jv, descw,
503 $ work( iptp ), a, ia, ja, desca, work( ipwk ) )
504 END IF
505
506 CALL igsum2d( ictxt, 'All', ' ', 1, 1, info, 1, -1, 0 )
507
508 RETURN
509
510
511
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 pzlarfb(side, trans, direct, storev, m, n, k, v, iv, jv, descv, t, c, ic, jc, descc, work)
subroutine pzlarft(direct, storev, n, k, v, iv, jv, descv, tau, t, work)