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