3
4
5
6
7
8
9
10 CHARACTER DIRECT, STOREV
11 INTEGER IV, JV, K, N
12
13
14 INTEGER DESCV( * )
15 COMPLEX TAU( * ), T( * ), V( * ), 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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173 INTEGER BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
174 $ LLD_, MB_, M_, NB_, N_, RSRC_
175 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
176 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
177 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
178 COMPLEX ONE, ZERO
179 parameter( one = ( 1.0e+0, 0.0e+0 ),
180 $ zero = ( 0.0e+0, 0.0e+0 ) )
181
182
183 LOGICAL FORWARD
184 INTEGER ICOFF, ICTXT, II, IIV, IROFF, IVCOL, IVROW,
185 $ ITMP0, ITMP1, IW, JJ, JJV, LDV, MICOL, MIROW,
186 $ MYCOL, MYROW, NP, NPCOL, NPROW, NQ
187 COMPLEX VII
188
189
190 EXTERNAL blacs_gridinfo, ccopy, cgemv, cgsum2d,
191 $ clacgv, claset, ctrmv,
infog2l
192
193
194 LOGICAL LSAME
195 INTEGER INDXG2P, NUMROC
197
198
199 INTRINSIC mod
200
201
202
203
204
205 IF( n.LE.0 .OR. k.LE.0 )
206 $ RETURN
207
208 ictxt = descv( ctxt_ )
209 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
210
211 forward =
lsame( direct,
'F' )
212 CALL infog2l( iv, jv, descv, nprow, npcol, myrow, mycol,
213 $ iiv, jjv, ivrow, ivcol )
214
215 IF(
lsame( storev,
'C' ) .AND. mycol.EQ.ivcol )
THEN
216
217 iw = 1
218 ldv = descv( lld_ )
219 iroff = mod( iv-1, descv( mb_ ) )
220
221 IF( forward ) THEN
222
223
224
225 np =
numroc( n+iroff, descv( mb_ ), myrow, ivrow, nprow )
226 IF( myrow.EQ.ivrow ) THEN
227 np = np - iroff
228 ii = iiv + 1
229 ELSE
230 ii = iiv
231 END IF
232 IF( iroff+1.EQ.descv( mb_ ) ) THEN
233 mirow = mod( ivrow+1, nprow )
234 ELSE
235 mirow = ivrow
236 END IF
237 itmp0 = 0
238
239 DO 10 jj = jjv+1, jjv+k-1
240
241 IF( myrow.EQ.mirow ) THEN
242 vii = v( ii+(jj-1)*ldv )
243 v( ii+(jj-1)*ldv ) = one
244 END IF
245
246
247
248
249 itmp0 = itmp0 + 1
250 IF( np-ii+iiv.GT.0 ) THEN
251 CALL cgemv( 'Conjugate transpose', np-ii+iiv, itmp0,
252 $ -tau( jj ), v( ii+(jjv-1)*ldv ), ldv,
253 $ v( ii+(jj-1)*ldv ), 1, zero,
254 $ work( iw ), 1 )
255 ELSE
256 CALL claset( 'All', itmp0, 1, zero, zero, work( iw ),
257 $ itmp0 )
258 END IF
259
260 iw = iw + itmp0
261 IF( myrow.EQ.mirow ) THEN
262 v( ii+(jj-1)*ldv ) = vii
263 ii = ii + 1
264 END IF
265
266 IF( mod( iv+itmp0, descv( mb_ ) ).EQ.0 )
267 $ mirow = mod( mirow+1, nprow )
268
269 10 CONTINUE
270
271 CALL cgsum2d( ictxt, 'Columnwise', ' ', iw-1, 1, work, iw-1,
272 $ ivrow, mycol )
273
274 IF( myrow.EQ.ivrow ) THEN
275
276 iw = 1
277 itmp0 = 0
278 itmp1 = 1
279
280 t( itmp1 ) = tau( jjv )
281
282 DO 20 jj = jjv+1, jjv+k-1
283
284
285
286 itmp0 = itmp0 + 1
287 itmp1 = itmp1 + descv( nb_ )
288 CALL ccopy( itmp0, work( iw ), 1, t( itmp1 ), 1 )
289 iw = iw + itmp0
290
291 CALL ctrmv( 'Upper', 'No transpose', 'Non-unit',
292 $ itmp0, t, descv( nb_ ), t( itmp1 ), 1 )
293 t(itmp1+itmp0) = tau( jj )
294
295 20 CONTINUE
296
297 END IF
298
299 ELSE
300
301
302
303 np =
numroc( n+iroff-1, descv( mb_ ), myrow, ivrow, nprow )
304 IF( myrow.EQ.ivrow )
305 $ np = np - iroff
306 mirow =
indxg2p( iv+n-2, descv( mb_ ), myrow,
307 $ descv( rsrc_ ), nprow )
308 ii = iiv + np - 1
309 itmp0 = 0
310
311 DO 30 jj = jjv+k-2, jjv, -1
312
313 IF( myrow.EQ.mirow ) THEN
314 vii = v( ii+(jj-1)*ldv )
315 v( ii+(jj-1)*ldv ) = one
316 END IF
317
318
319
320
321 itmp0 = itmp0 + 1
322 IF( ii-iiv+1.GT.0 ) THEN
323 CALL cgemv( 'Conjugate transpose', ii-iiv+1, itmp0,
324 $ -tau( jj ), v( iiv+jj*ldv ), ldv,
325 $ v( iiv+(jj-1)*ldv ), 1, zero,
326 $ work( iw ), 1 )
327 ELSE
328 CALL claset( 'All', itmp0, 1, zero, zero, work( iw ),
329 $ itmp0 )
330 END IF
331
332 iw = iw + itmp0
333 IF( myrow.EQ.mirow ) THEN
334 v( ii+(jj-1)*ldv ) = vii
335 ii = ii - 1
336 END IF
337
338 IF( mod( iv+n-itmp0-2, descv(mb_) ).EQ.0 )
339 $ mirow = mod( mirow+nprow-1, nprow )
340
341 30 CONTINUE
342
343 CALL cgsum2d( ictxt, 'Columnwise', ' ', iw-1, 1, work, iw-1,
344 $ ivrow, mycol )
345
346 IF( myrow.EQ.ivrow ) THEN
347
348 iw = 1
349 itmp0 = 0
350 itmp1 = k + 1 + (k-1) * descv( nb_ )
351
352 t( itmp1-1 ) = tau( jjv+k-1 )
353
354 DO 40 jj = jjv+k-2, jjv, -1
355
356
357
358 itmp0 = itmp0 + 1
359 itmp1 = itmp1 - descv( nb_ ) - 1
360 CALL ccopy( itmp0, work( iw ), 1, t( itmp1 ), 1 )
361 iw = iw + itmp0
362
363 CALL ctrmv( 'Lower', 'No transpose', 'Non-unit',
364 $ itmp0, t( itmp1+descv( nb_ ) ),
365 $ descv( nb_ ), t( itmp1 ), 1 )
366 t( itmp1-1 ) = tau( jj )
367
368 40 CONTINUE
369
370 END IF
371
372 END IF
373
374 ELSE IF(
lsame( storev,
'R' ) .AND. myrow.EQ.ivrow )
THEN
375
376 iw = 1
377 ldv = descv( lld_ )
378 icoff = mod( jv-1, descv( nb_ ) )
379
380 IF( forward ) THEN
381
382
383
384 nq =
numroc( n+icoff, descv( nb_ ), mycol, ivcol, npcol )
385 IF( mycol.EQ.ivcol ) THEN
386 nq = nq - icoff
387 jj = jjv + 1
388 ELSE
389 jj = jjv
390 END IF
391 IF( icoff+1.EQ.descv( nb_ ) ) THEN
392 micol = mod( ivcol+1, npcol )
393 ELSE
394 micol = ivcol
395 END IF
396 itmp0 = 0
397
398 DO 50 ii = iiv+1, iiv+k-1
399
400 IF( mycol.EQ.micol ) THEN
401 vii = v( ii+(jj-1)*ldv )
402 v( ii+(jj-1)*ldv ) = one
403 END IF
404
405
406
407
408 itmp0 = itmp0 + 1
409 IF( nq-jj+jjv.GT.0 ) THEN
410 CALL clacgv( nq-jj+jjv, v( ii+(jj-1)*ldv ), ldv )
411 CALL cgemv( 'No transpose', itmp0, nq-jj+jjv,
412 $ -tau(ii), v( iiv+(jj-1)*ldv ), ldv,
413 $ v( ii+(jj-1)*ldv ), ldv, zero,
414 $ work( iw ), 1 )
415 CALL clacgv( nq-jj+jjv, v( ii+(jj-1)*ldv ), ldv )
416 ELSE
417 CALL claset( 'All', itmp0, 1, zero, zero,
418 $ work( iw ), itmp0 )
419 END IF
420
421 iw = iw + itmp0
422 IF( mycol.EQ.micol ) THEN
423 v( ii+(jj-1)*ldv ) = vii
424 jj = jj + 1
425 END IF
426
427 IF( mod( jv+itmp0, descv( nb_ ) ).EQ.0 )
428 $ micol = mod( micol+1, npcol )
429
430 50 CONTINUE
431
432 CALL cgsum2d( ictxt, 'Rowwise', ' ', iw-1, 1, work, iw-1,
433 $ myrow, ivcol )
434
435 IF( mycol.EQ.ivcol ) THEN
436
437 iw = 1
438 itmp0 = 0
439 itmp1 = 1
440
441 t( itmp1 ) = tau( iiv )
442
443 DO 60 ii = iiv+1, iiv+k-1
444
445
446
447 itmp0 = itmp0 + 1
448 itmp1 = itmp1 + descv( mb_ )
449 CALL ccopy( itmp0, work( iw ), 1, t( itmp1 ), 1 )
450 iw = iw + itmp0
451
452 CALL ctrmv( 'Upper', 'No transpose', 'Non-unit',
453 $ itmp0, t, descv( mb_ ), t( itmp1 ), 1 )
454 t( itmp1+itmp0 ) = tau( ii )
455
456 60 CONTINUE
457
458 END IF
459
460 ELSE
461
462
463
464 nq =
numroc( n+icoff-1, descv( nb_ ), mycol, ivcol, npcol )
465 IF( mycol.EQ.ivcol )
466 $ nq = nq - icoff
467 micol =
indxg2p( jv+n-2, descv( nb_ ), mycol,
468 $ descv( csrc_ ), npcol )
469 jj = jjv + nq - 1
470 itmp0 = 0
471
472 DO 70 ii = iiv+k-2, iiv, -1
473
474 IF( mycol.EQ.micol ) THEN
475 vii = v( ii+(jj-1)*ldv )
476 v( ii+(jj-1)*ldv ) = one
477 END IF
478
479
480
481
482 itmp0 = itmp0 + 1
483 IF( jj-jjv+1.GT.0 ) THEN
484 CALL clacgv( jj-jjv+1, v( ii+(jjv-1)*ldv ), ldv )
485 CALL cgemv( 'No transpose', itmp0, jj-jjv+1,
486 $ -tau( ii ), v( ii+1+(jjv-1)*ldv ), ldv,
487 $ v( ii+(jjv-1)*ldv ), ldv, zero,
488 $ work( iw ), 1 )
489 CALL clacgv( jj-jjv+1, v( ii+(jjv-1)*ldv ), ldv )
490 ELSE
491 CALL claset( 'All', itmp0, 1, zero, zero,
492 $ work( iw ), itmp0 )
493 END IF
494
495 iw = iw + itmp0
496 IF( mycol.EQ.micol ) THEN
497 v( ii+(jj-1)*ldv ) = vii
498 jj = jj - 1
499 END IF
500
501 IF( mod( jv+n-itmp0-2, descv( nb_ ) ).EQ.0 )
502 $ micol = mod( micol+npcol-1, npcol )
503
504 70 CONTINUE
505
506 CALL cgsum2d( ictxt, 'Rowwise', ' ', iw-1, 1, work, iw-1,
507 $ myrow, ivcol )
508
509 IF( mycol.EQ.ivcol ) THEN
510
511 iw = 1
512 itmp0 = 0
513 itmp1 = k + 1 + (k-1) * descv( mb_ )
514
515 t( itmp1-1 ) = tau( iiv+k-1 )
516
517 DO 80 ii = iiv+k-2, iiv, -1
518
519
520
521 itmp0 = itmp0 + 1
522 itmp1 = itmp1 - descv( mb_ ) - 1
523 CALL ccopy( itmp0, work( iw ), 1, t( itmp1 ), 1 )
524 iw = iw + itmp0
525
526 CALL ctrmv( 'Lower', 'No transpose', 'Non-unit',
527 $ itmp0, t( itmp1+descv( mb_ ) ),
528 $ descv( mb_ ), t( itmp1 ), 1 )
529 t( itmp1-1 ) = tau( ii )
530
531 80 CONTINUE
532
533 END IF
534
535 END IF
536
537 END IF
538
539 RETURN
540
541
542
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)