3
4
5
6
7
8
9
10 INTEGER INFO, IA, JA, M, N
11
12
13 INTEGER DESCA( * )
14 REAL D( * ), E( * )
15 COMPLEX 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 REAL REIGHT, RZERO
159 parameter( reight = 8.0e+0, rzero = 0.0e+0 )
160 COMPLEX ONE, ZERO
161 parameter( one = ( 1.0e+0, 0.0e+0 ),
162 $ zero = ( 0.0e+0, 0.0e+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 REAL ADDBND, D2, E2
169 COMPLEX D1, E1
170
171
172 INTEGER DESCD( DLEN_ ), DESCE( DLEN_ ), DESCV( DLEN_ ),
173 $ DESCW( DLEN_ )
174
175
179
180
181 INTEGER INDXG2P, NUMROC
182 REAL PSLAMCH
184
185
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 *
pslamch( 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 pselget(
' ',
' ', d2, d, 1, ja+j, descd )
238 CALL pcelget(
'Columnwise',
' ', d1, a, ia+j, ja+j, desca )
239 IF( j.LT.(mn-1) ) THEN
240 CALL pselget(
' ',
' ', e2, e, ia+j, 1, desce )
241 CALL pcelget(
'Rowwise',
' ', e1, a, ia+j, ja+j+1,
242 $ desca )
243 END IF
244
245 IF( ( abs( d1 -
cmplx( d2 ) ).GT.( abs( d2 )*addbnd ) ) .OR.
246 $ ( abs( e1 -
cmplx( 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 pclarft(
'Forward',
'Columnwise', m-k+1, jb, a, i, j,
258 $ desca, tauq, work( iptq ), work( ipwk ) )
259
260
261
262 CALL pclacpy(
'Lower', m-k+1, jb, a, i, j, desca,
263 $ work( ipv ), iv, jv, descv )
264 CALL pclaset(
'Upper', m-k+1, jb, zero, one, work( ipv ),
265 $ iv, jv, descv )
266
267
268
269 CALL pclaset(
'Lower', m-k, jb, zero, zero, a, i+1, j,
270 $ desca )
271
272
273
274 CALL pclarft(
'Forward',
'Rowwise', n-k, jb, a, i, j+1,
275 $ desca, taup, work( iptp ), work( ipwk ) )
276
277
278
279 CALL pclacpy(
'Upper', jb, n-k, a, i, j+1, desca,
280 $ work( ipw ), iv, jv+1, descw )
281 CALL pclaset(
'Lower', jb, n-k, zero, one, work( ipw ), iv,
282 $ jv+1, descw )
283
284
285
286 CALL pclaset(
'Upper', jb, n-k-1, zero, zero, a, i, j+2,
287 $ desca )
288
289
290
291 CALL pclarfb(
'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 pclarfb(
'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 pclarft(
'Forward',
'Columnwise', m, jb, a, ia, ja, desca,
321 $ tauq, work( iptq ), work( ipwk ) )
322
323
324
325 CALL pclacpy(
'Lower', m, jb, a, ia, ja, desca, work( ipv ),
326 $ iv, jv, descv )
327 CALL pclaset(
'Upper', m, jb, zero, one, work( ipv ), iv, jv,
328 $ descv )
329
330
331
332 CALL pclaset(
'Lower', m-1, jb, zero, zero, a, ia+1, ja,
333 $ desca )
334
335
336
337 CALL pclarft(
'Forward',
'Rowwise', n-1, jb, a, ia, ja+1,
338 $ desca, taup, work( iptp ), work( ipwk ) )
339
340
341
342 CALL pclacpy(
'Upper', jb, n-1, a, ia, ja+1, desca,
343 $ work( ipw ), iv, jv+1, descw )
344 CALL pclaset(
'Lower', jb, n-1, zero, one, work( ipw ), iv,
345 $ jv+1, descw )
346
347
348
349 CALL pclaset(
'Upper', jb, n-2, zero, zero, a, ia, ja+2,
350 $ desca )
351
352
353
354 CALL pclarfb(
'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 pclarfb(
'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 pselget(
' ',
' ', d2, d, ia+j, 1, descd )
379 CALL pcelget(
'Rowwise',
' ', d1, a, ia+j, ja+j, desca )
380 IF( j.LT.(mn-1) ) THEN
381 CALL pselget(
' ',
' ', e2, e, 1, ja+j, desce )
382 CALL pcelget(
'Columnwise',
' ', e1, a, ia+j+1, ja+j,
383 $ desca )
384 END IF
385
386 IF( ( abs( d1 -
cmplx( d2 ) ).GT.( abs( d2 )*addbnd ) ) .OR.
387 $ ( abs( e1 -
cmplx( 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 pclarft(
'Forward',
'Columnwise', m-k, jb, a, i+1, j,
399 $ desca, tauq, work( iptq ), work( ipwk ) )
400
401
402
403 CALL pclacpy(
'Lower', m-k, jb, a, i+1, j, desca,
404 $ work( ipv ), iv+1, jv, descv )
405 CALL pclaset(
'Upper', m-k, jb, zero, one, work( ipv ),
406 $ iv+1, jv, descv )
407
408
409
410 CALL pclaset(
'Lower', m-k-1, jb, zero, zero, a, i+2, j,
411 $ desca )
412
413
414
415 CALL pclarft(
'Forward',
'Rowwise', n-k+1, jb, a, i, j,
416 $ desca, taup, work( iptp ), work( ipwk ) )
417
418
419
420 CALL pclacpy(
'Upper', jb, n-k+1, a, i, j, desca,
421 $ work( ipw ), iv, jv, descw )
422 CALL pclaset(
'Lower', jb, n-k+1, zero, one, work( ipw ),
423 $ iv, jv, descw )
424
425
426
427 CALL pclaset(
'Upper', jb, n-k, zero, zero, a, i, j+1,
428 $ desca )
429
430
431
432 CALL pclarfb(
'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 pclarfb(
'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 pclarft(
'Forward',
'Columnwise', m-1, jb, a, ia+1, ja,
462 $ desca, tauq, work( iptq ), work( ipwk ) )
463
464
465
466 CALL pclacpy(
'Lower', m-1, jb, a, ia+1, ja, desca,
467 $ work( ipv ), iv+1, jv, descv )
468 CALL pclaset(
'Upper', m-1, jb, zero, one, work( ipv ), iv+1,
469 $ jv, descv )
470
471
472
473 CALL pclaset(
'Lower', m-2, jb, zero, zero, a, ia+2, ja,
474 $ desca )
475
476
477
478 CALL pclarft(
'Forward',
'Rowwise', n, jb, a, ia, ja, desca,
479 $ taup, work( iptp ), work( ipwk ) )
480
481
482
483 CALL pclacpy(
'Upper', jb, n, a, ia, ja, desca, work( ipw ),
484 $ iv, jv, descw )
485 CALL pclaset(
'Lower', jb, n, zero, one, work( ipw ), iv, jv,
486 $ descw )
487
488
489
490 CALL pclaset(
'Upper', jb, n-1, zero, zero, a, ia, ja+1,
491 $ desca )
492
493
494
495 CALL pclarfb(
'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 pclarfb(
'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)
subroutine pclaset(uplo, m, n, alpha, beta, a, ia, ja, desca)
real function pslamch(ictxt, cmach)
subroutine pcelget(scope, top, alpha, a, ia, ja, desca)
subroutine pclacpy(uplo, m, n, a, ia, ja, desca, b, ib, jb, descb)
subroutine pclarfb(side, trans, direct, storev, m, n, k, v, iv, jv, descv, t, c, ic, jc, descc, work)
subroutine pclarft(direct, storev, n, k, v, iv, jv, descv, tau, t, work)
subroutine pselget(scope, top, alpha, a, ia, ja, desca)