3
4
5
6
7
8
9
10 INTEGER INFO, IA, JA, M, N
11
12
13 INTEGER DESCA( * )
14 REAL 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 REAL EIGHT, ONE, ZERO
159 parameter( eight = 8.0e+0, one = 1.0e+0, zero = 0.0e+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 REAL 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 REAL PSLAMCH
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 *
pslamch( 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 pselget(
' ',
' ', d2, d, 1, ja+j, descd )
234 CALL pselget(
'Columnwise',
' ', d1, a, ia+j, ja+j, desca )
235 IF( j.LT.(mn-1) ) THEN
236 CALL pselget(
' ',
' ', e2, e, ia+j, 1, desce )
237 CALL pselget(
'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 pslarft(
'Forward',
'Columnwise', m-k+1, jb, a, i, j,
254 $ desca, tauq, work( iptq ), work( ipwk ) )
255
256
257
258 CALL pslacpy(
'Lower', m-k+1, jb, a, i, j, desca,
259 $ work( ipv ), iv, jv, descv )
260 CALL pslaset(
'Upper', m-k+1, jb, zero, one, work( ipv ),
261 $ iv, jv, descv )
262
263
264
265 CALL pslaset(
'Lower', m-k, jb, zero, zero, a, i+1, j,
266 $ desca )
267
268
269
270 CALL pslarft(
'Forward',
'Rowwise', n-k, jb, a, i, j+1,
271 $ desca, taup, work( iptp ), work( ipwk ) )
272
273
274
275 CALL pslacpy(
'Upper', jb, n-k, a, i, j+1, desca,
276 $ work( ipw ), iv, jv+1, descw )
277 CALL pslaset(
'Lower', jb, n-k, zero, one, work( ipw ), iv,
278 $ jv+1, descw )
279
280
281
282 CALL pslaset(
'Upper', jb, n-k-1, zero, zero, a, i, j+2,
283 $ desca )
284
285
286
287 CALL pslarfb(
'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 pslarfb(
'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 pslarft(
'Forward',
'Columnwise', m, jb, a, ia, ja, desca,
316 $ tauq, work( iptq ), work( ipwk ) )
317
318
319
320 CALL pslacpy(
'Lower', m, jb, a, ia, ja, desca, work( ipv ),
321 $ iv, jv, descv )
322 CALL pslaset(
'Upper', m, jb, zero, one, work( ipv ), iv, jv,
323 $ descv )
324
325
326
327 CALL pslaset(
'Lower', m-1, jb, zero, zero, a, ia+1, ja,
328 $ desca )
329
330
331
332 CALL pslarft(
'Forward',
'Rowwise', n-1, jb, a, ia, ja+1,
333 $ desca, taup, work( iptp ), work( ipwk ) )
334
335
336
337 CALL pslacpy(
'Upper', jb, n-1, a, ia, ja+1, desca,
338 $ work( ipw ), iv, jv+1, descw )
339 CALL pslaset(
'Lower', jb, n-1, zero, one, work( ipw ), iv,
340 $ jv+1, descw )
341
342
343
344 CALL pslaset(
'Upper', jb, n-2, zero, zero, a, ia, ja+2,
345 $ desca )
346
347
348
349 CALL pslarfb(
'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 pslarfb(
'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 pselget(
' ',
' ', d2, d, ia+j, 1, descd )
373 CALL pselget(
'Rowwise',
' ', d1, a, ia+j, ja+j, desca )
374 IF( j.LT.(mn-1) ) THEN
375 CALL pselget(
' ',
' ', e2, e, 1, ja+j, desce )
376 CALL pselget(
'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 pslarft(
'Forward',
'Columnwise', m-k, jb, a, i+1, j,
393 $ desca, tauq, work( iptq ), work( ipwk ) )
394
395
396
397 CALL pslacpy(
'Lower', m-k, jb, a, i+1, j, desca,
398 $ work( ipv ), iv+1, jv, descv )
399 CALL pslaset(
'Upper', m-k, jb, zero, one, work( ipv ),
400 $ iv+1, jv, descv )
401
402
403
404 CALL pslaset(
'Lower', m-k-1, jb, zero, zero, a, i+2, j,
405 $ desca )
406
407
408
409 CALL pslarft(
'Forward',
'Rowwise', n-k+1, jb, a, i, j,
410 $ desca, taup, work( iptp ), work( ipwk ) )
411
412
413
414 CALL pslacpy(
'Upper', jb, n-k+1, a, i, j, desca,
415 $ work( ipw ), iv, jv, descw )
416 CALL pslaset(
'Lower', jb, n-k+1, zero, one, work( ipw ),
417 $ iv, jv, descw )
418
419
420
421 CALL pslaset(
'Upper', jb, n-k, zero, zero, a, i, j+1,
422 $ desca )
423
424
425
426 CALL pslarfb(
'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 pslarfb(
'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 pslarft(
'Forward',
'Columnwise', m-1, jb, a, ia+1, ja,
455 $ desca, tauq, work( iptq ), work( ipwk ) )
456
457
458
459 CALL pslacpy(
'Lower', m-1, jb, a, ia+1, ja, desca,
460 $ work( ipv ), iv+1, jv, descv )
461 CALL pslaset(
'Upper', m-1, jb, zero, one, work( ipv ), iv+1,
462 $ jv, descv )
463
464
465
466 CALL pslaset(
'Lower', m-2, jb, zero, zero, a, ia+2, ja,
467 $ desca )
468
469
470
471 CALL pslarft(
'Forward',
'Rowwise', n, jb, a, ia, ja, desca,
472 $ taup, work( iptp ), work( ipwk ) )
473
474
475
476 CALL pslacpy(
'Upper', jb, n, a, ia, ja, desca, work( ipw ),
477 $ iv, jv, descw )
478 CALL pslaset(
'Lower', jb, n, zero, one, work( ipw ), iv, jv,
479 $ descw )
480
481
482
483 CALL pslaset(
'Upper', jb, n-1, zero, zero, a, ia, ja+1,
484 $ desca )
485
486
487
488 CALL pslarfb(
'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 pslarfb(
'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)
real function pslamch(ictxt, cmach)
subroutine pslaset(uplo, m, n, alpha, beta, a, ia, ja, desca)
subroutine pselget(scope, top, alpha, a, ia, ja, desca)
subroutine pslacpy(uplo, m, n, a, ia, ja, desca, b, ib, jb, descb)
subroutine pslarfb(side, trans, direct, storev, m, n, k, v, iv, jv, descv, t, c, ic, jc, descc, work)
subroutine pslarft(direct, storev, n, k, v, iv, jv, descv, tau, t, work)