3
4
5
6
7
8
9
10 CHARACTER SIDE
11 INTEGER IC, INCV, IV, JC, JV, M, N
12
13
14 INTEGER DESCC( * ), DESCV( * )
15 COMPLEX*16 C( * ), TAU( * ), 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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229 INTEGER BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
230 $ LLD_, MB_, M_, NB_, N_, RSRC_
231 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
232 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
233 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
234 COMPLEX*16 ONE, ZERO
235 parameter( one = ( 1.0d+0, 0.0d+0 ),
236 $ zero = ( 0.0d+0, 0.0d+0 ) )
237
238
239 LOGICAL CCBLCK, CRBLCK
240 CHARACTER COLBTOP, ROWBTOP
241 INTEGER ICCOL, ICOFF, ICROW, ICTXT, IIC, IIV, IOFFC,
242 $ IOFFV, IPW, IROFF, IVCOL, IVROW, JJC, JJV, LDC,
243 $ LDV, MYCOL, MYROW, MP, NCC, NCV, NPCOL, NPROW,
244 $ NQ, RDEST
245 COMPLEX*16 TAULOC( 1 )
246
247
249 $ zcopy, zgebr2d, zgebs2d, zgemv,
250 $ zgerc, zgerv2d, zgesd2d, zgsum2d,
251 $ zlaset
252
253
254 LOGICAL LSAME
255 INTEGER NUMROC
257
258
260
261
262
263
264
265 IF( m.LE.0 .OR. n.LE.0 )
266 $ RETURN
267
268
269
270 ictxt = descc( ctxt_ )
271 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
272
273
274
275 CALL infog2l( ic, jc, descc, nprow, npcol, myrow, mycol, iic, jjc,
276 $ icrow, iccol )
277 CALL infog2l( iv, jv, descv, nprow, npcol, myrow, mycol, iiv, jjv,
278 $ ivrow, ivcol )
279 ncc =
numroc( descc( n_ ), descc( nb_ ), mycol, descc( csrc_ ),
280 $ npcol )
281 ncv =
numroc( descv( n_ ), descv( nb_ ), mycol, descv( csrc_ ),
282 $ npcol )
283 ldc = descc( lld_ )
284 ldv = descv( lld_ )
285 iic =
min( iic, ldc )
286 iiv =
min( iiv, ldv )
287 jjc =
min( jjc, ncc )
288 jjv =
min( jjv, ncv )
289 ioffc = iic+(jjc-1)*ldc
290 ioffv = iiv+(jjv-1)*ldv
291
292 iroff = mod( ic-1, descc( mb_ ) )
293 icoff = mod( jc-1, descc( nb_ ) )
294 mp =
numroc( m+iroff, descc( mb_ ), myrow, icrow, nprow )
295 nq =
numroc( n+icoff, descc( nb_ ), mycol, iccol, npcol )
296 IF( myrow.EQ.icrow )
297 $ mp = mp - iroff
298 IF( mycol.EQ.iccol )
299 $ nq = nq - icoff
300
301
302
303 crblck = ( m.LE.(descc( mb_ )-iroff) )
304
305
306
307 ccblck = ( n.LE.(descc( nb_ )-icoff) )
308
309 IF(
lsame( side,
'L' ) )
THEN
310
311 IF( crblck ) THEN
312 rdest = icrow
313 ELSE
314 rdest = -1
315 END IF
316
317 IF( ccblck ) THEN
318
319
320
321 IF( descv( m_ ).EQ.incv ) THEN
322
323
324
325 ipw = mp+1
326 CALL pbztrnv( ictxt,
'Rowwise',
'Transpose', m,
327 $ descv( nb_ ), iroff, v( ioffv ), ldv, zero,
328 $ work, 1, ivrow, ivcol, icrow, iccol,
329 $ work( ipw ) )
330
331
332
333 IF( mycol.EQ.iccol ) THEN
334
335 IF( myrow.EQ.ivrow ) THEN
336
337 CALL zgebs2d( ictxt, 'Columnwise', ' ', 1, 1,
338 $ tau( iiv ), 1 )
339 tauloc( 1 ) = dconjg( tau( iiv ) )
340
341 ELSE
342
343 CALL zgebr2d( ictxt, 'Columnwise', ' ', 1, 1,
344 $ tauloc, 1, ivrow, mycol )
345 tauloc( 1 ) = dconjg( tauloc( 1 ) )
346
347 END IF
348
349 IF( tauloc( 1 ).NE.zero ) THEN
350
351
352
353 IF( mp.GT.0 ) THEN
354 CALL zgemv( 'Conjugate transpose', mp, nq, one,
355 $ c( ioffc ), ldc, work, 1, zero,
356 $ work( ipw ), 1 )
357 ELSE
358 CALL zlaset( 'All', nq, 1, zero, zero,
359 $ work( ipw ),
max( 1, nq ) )
360 END IF
361 CALL zgsum2d( ictxt, 'Columnwise', ' ', nq, 1,
362 $ work( ipw ),
max( 1, nq ), rdest,
363 $ mycol )
364
365
366
367 CALL zgerc( mp, nq, -tauloc( 1 ), work, 1,
368 $ work( ipw ), 1, c( ioffc ), ldc )
369 END IF
370
371 END IF
372
373 ELSE
374
375
376
377 IF( ivcol.EQ.iccol ) THEN
378
379
380
381 IF( mycol.EQ.iccol ) THEN
382
383 tauloc( 1 ) = dconjg( tau( jjv ) )
384
385 IF( tauloc( 1 ).NE.zero ) THEN
386
387
388
389 IF( mp.GT.0 ) THEN
390 CALL zgemv( 'Conjugate transpose', mp, nq,
391 $ one, c( ioffc ), ldc, v( ioffv ), 1,
392 $ zero, work, 1 )
393 ELSE
394 CALL zlaset( 'All', nq, 1, zero, zero,
395 $ work,
max( 1, nq ) )
396 END IF
397 CALL zgsum2d( ictxt, 'Columnwise', ' ', nq, 1,
398 $ work,
max( 1, nq ), rdest, mycol )
399
400
401
402 CALL zgerc( mp, nq, -tauloc( 1 ), v( ioffv ), 1,
403 $ work, 1, c( ioffc ), ldc )
404 END IF
405
406 END IF
407
408 ELSE
409
410
411
412 IF( mycol.EQ.ivcol ) THEN
413
414 ipw = mp+1
415 CALL zcopy( mp, v( ioffv ), 1, work, 1 )
416 work( ipw ) = tau( jjv )
417 CALL zgesd2d( ictxt, ipw, 1, work, ipw, myrow,
418 $ iccol )
419
420 ELSE IF( mycol.EQ.iccol ) THEN
421
422 ipw = mp+1
423 CALL zgerv2d( ictxt, ipw, 1, work, ipw, myrow,
424 $ ivcol )
425 tauloc( 1 ) = dconjg( work( ipw ) )
426
427 IF( tauloc( 1 ).NE.zero ) THEN
428
429
430
431 IF( mp.GT.0 ) THEN
432 CALL zgemv( 'Conjugate transpose', mp, nq,
433 $ one, c( ioffc ), ldc, work, 1,
434 $ zero, work( ipw ), 1 )
435 ELSE
436 CALL zlaset( 'All', nq, 1, zero, zero,
437 $ work( ipw ),
max( 1, nq ) )
438 END IF
439 CALL zgsum2d( ictxt, 'Columnwise', ' ', nq, 1,
440 $ work( ipw ),
max( 1, nq ), rdest,
441 $ mycol )
442
443
444
445 CALL zgerc( mp, nq, -tauloc( 1 ), work, 1,
446 $ work( ipw ), 1, c( ioffc ), ldc )
447 END IF
448
449 END IF
450
451 END IF
452
453 END IF
454
455 ELSE
456
457
458
459 IF( descv( m_ ).EQ.incv ) THEN
460
461
462
463 ipw = mp+1
464 CALL pbztrnv( ictxt,
'Rowwise',
'Transpose', m,
465 $ descv( nb_ ), iroff, v( ioffv ), ldv, zero,
466 $ work, 1, ivrow, ivcol, icrow, -1,
467 $ work( ipw ) )
468
469
470
471 IF( myrow.EQ.ivrow ) THEN
472
473 CALL zgebs2d( ictxt, 'Columnwise', ' ', 1, 1,
474 $ tau( iiv ), 1 )
475 tauloc( 1 ) = dconjg( tau( iiv ) )
476
477 ELSE
478
479 CALL zgebr2d( ictxt, 'Columnwise', ' ', 1, 1, tauloc,
480 $ 1, ivrow, mycol )
481 tauloc( 1 ) = dconjg( tauloc( 1 ) )
482
483 END IF
484
485 IF( tauloc( 1 ).NE.zero ) THEN
486
487
488
489 IF( mp.GT.0 ) THEN
490 CALL zgemv( 'Conjugate transpose', mp, nq, one,
491 $ c( ioffc ), ldc, work, 1, zero,
492 $ work( ipw ), 1 )
493 ELSE
494 CALL zlaset( 'All', nq, 1, zero, zero,
495 $ work( ipw ),
max( 1, nq ) )
496 END IF
497 CALL zgsum2d( ictxt, 'Columnwise', ' ', nq, 1,
498 $ work( ipw ),
max( 1, nq ), rdest,
499 $ mycol )
500
501
502
503 CALL zgerc( mp, nq, -tauloc( 1 ), work, 1,
504 $ work( ipw ), 1, c( ioffc ), ldc )
505 END IF
506
507 ELSE
508
509
510
511 CALL pb_topget( ictxt, 'Broadcast', 'Rowwise', rowbtop )
512 IF( mycol.EQ.ivcol ) THEN
513
514 ipw = mp+1
515 CALL zcopy( mp, v( ioffv ), 1, work, 1 )
516 work(ipw) = tau( jjv )
517 CALL zgebs2d( ictxt, 'Rowwise', rowbtop, ipw, 1,
518 $ work, ipw )
519 tauloc( 1 ) = dconjg( tau( jjv ) )
520
521 ELSE
522
523 ipw = mp+1
524 CALL zgebr2d( ictxt, 'Rowwise', rowbtop, ipw, 1, work,
525 $ ipw, myrow, ivcol )
526 tauloc( 1 ) = dconjg( work( ipw ) )
527
528 END IF
529
530 IF( tauloc( 1 ).NE.zero ) THEN
531
532
533
534 IF( mp.GT.0 ) THEN
535 CALL zgemv( 'Conjugate transpose', mp, nq, one,
536 $ c( ioffc ), ldc, work, 1, zero,
537 $ work( ipw ), 1 )
538 ELSE
539 CALL zlaset( 'All', nq, 1, zero, zero,
540 $ work( ipw ),
max( 1, nq ) )
541 END IF
542 CALL zgsum2d( ictxt, 'Columnwise', ' ', nq, 1,
543 $ work( ipw ),
max( 1, nq ), rdest,
544 $ mycol )
545
546
547
548 CALL zgerc( mp, nq, -tauloc( 1 ), work, 1,
549 $ work( ipw ), 1, c( ioffc ), ldc )
550 END IF
551
552 END IF
553
554 END IF
555
556 ELSE
557
558 IF( ccblck ) THEN
559 rdest = myrow
560 ELSE
561 rdest = -1
562 END IF
563
564 IF( crblck ) THEN
565
566
567
568 IF( descv( m_ ).EQ.incv ) THEN
569
570
571
572 IF( ivrow.EQ.icrow ) THEN
573
574
575
576 IF( myrow.EQ.icrow ) THEN
577
578 tauloc( 1 ) = dconjg( tau( iiv ) )
579
580 IF( tauloc( 1 ).NE.zero ) THEN
581
582
583
584 IF( nq.GT.0 ) THEN
585 CALL zgemv( 'No transpose', mp, nq, one,
586 $ c( ioffc ), ldc, v( ioffv ), ldv,
587 $ zero, work, 1 )
588 ELSE
589 CALL zlaset( 'All', mp, 1, zero, zero,
590 $ work,
max( 1, mp ) )
591 END IF
592 CALL zgsum2d( ictxt, 'Rowwise', ' ', mp, 1,
593 $ work,
max( 1, mp ), rdest, iccol )
594
595
596
597 CALL zgerc( mp, nq, -tauloc( 1 ), work, 1,
598 $ v( ioffv ), ldv, c( ioffc ), ldc )
599 END IF
600
601 END IF
602
603 ELSE
604
605
606
607 IF( myrow.EQ.ivrow ) THEN
608
609 ipw = nq+1
610 CALL zcopy( nq, v( ioffv ), ldv, work, 1 )
611 work(ipw) = tau( iiv )
612 CALL zgesd2d( ictxt, ipw, 1, work, ipw, icrow,
613 $ mycol )
614
615 ELSE IF( myrow.EQ.icrow ) THEN
616
617 ipw = nq+1
618 CALL zgerv2d( ictxt, ipw, 1, work, ipw, ivrow,
619 $ mycol )
620 tauloc( 1 ) = dconjg( work( ipw ) )
621
622 IF( tauloc( 1 ).NE.zero ) THEN
623
624
625
626 IF( nq.GT.0 ) THEN
627 CALL zgemv( 'No transpose', mp, nq, one,
628 $ c( ioffc ), ldc, work, 1, zero,
629 $ work( ipw ), 1 )
630 ELSE
631 CALL zlaset( 'All', mp, 1, zero, zero,
632 $ work( ipw ),
max( 1, mp ) )
633 END IF
634 CALL zgsum2d( ictxt, 'Rowwise', ' ', mp, 1,
635 $ work( ipw ),
max( 1, mp ), rdest,
636 $ iccol )
637
638
639
640 CALL zgerc( mp, nq, -tauloc( 1 ), work( ipw ),
641 $ 1, work, 1, c( ioffc ), ldc )
642 END IF
643
644 END IF
645
646 END IF
647
648 ELSE
649
650
651
652 ipw = nq+1
653 CALL pbztrnv( ictxt,
'Columnwise',
'Transpose', n,
654 $ descv( mb_ ), icoff, v( ioffv ), 1, zero,
655 $ work, 1, ivrow, ivcol, icrow, iccol,
656 $ work( ipw ) )
657
658
659
660 IF( myrow.EQ.icrow ) THEN
661
662 IF( mycol.EQ.ivcol ) THEN
663
664 CALL zgebs2d( ictxt, 'Rowwise', ' ', 1, 1,
665 $ tau( jjv ), 1 )
666 tauloc( 1 ) = dconjg( tau( jjv ) )
667
668 ELSE
669
670 CALL zgebr2d( ictxt, 'Rowwise', ' ', 1, 1, tauloc,
671 $ 1, myrow, ivcol )
672 tauloc( 1 ) = dconjg( tauloc( 1 ) )
673
674 END IF
675
676 IF( tauloc( 1 ).NE.zero ) THEN
677
678
679
680 IF( nq.GT.0 ) THEN
681 CALL zgemv( 'No transpose', mp, nq, one,
682 $ c( ioffc ), ldc, work, 1, zero,
683 $ work( ipw ), 1 )
684 ELSE
685 CALL zlaset( 'All', mp, 1, zero, zero,
686 $ work( ipw ),
max( 1, mp ) )
687 END IF
688 CALL zgsum2d( ictxt, 'Rowwise', ' ', mp, 1,
689 $ work( ipw ),
max( 1, mp ), rdest,
690 $ iccol )
691
692
693
694 CALL zgerc( mp, nq, -tauloc( 1 ), work( ipw ), 1,
695 $ work, 1, c( ioffc ), ldc )
696 END IF
697
698 END IF
699
700 END IF
701
702 ELSE
703
704
705
706 IF( descv( m_ ).EQ.incv ) THEN
707
708
709
710 CALL pb_topget( ictxt, 'Broadcast', 'Columnwise',
711 $ colbtop )
712 IF( myrow.EQ.ivrow ) THEN
713
714 ipw = nq+1
715 CALL zcopy( nq, v( ioffv ), ldv, work, 1 )
716 work(ipw) = tau( iiv )
717 CALL zgebs2d( ictxt, 'Columnwise', colbtop, ipw, 1,
718 $ work, ipw )
719 tauloc( 1 ) = dconjg( tau( iiv ) )
720
721 ELSE
722
723 ipw = nq+1
724 CALL zgebr2d( ictxt, 'Columnwise', colbtop, ipw, 1,
725 $ work, ipw, ivrow, mycol )
726 tauloc( 1 ) = dconjg( work( ipw ) )
727
728 END IF
729
730 IF( tauloc( 1 ).NE.zero ) THEN
731
732
733
734 IF( nq.GT.0 ) THEN
735 CALL zgemv( 'No Transpose', mp, nq, one,
736 $ c( ioffc ), ldc, work, 1, zero,
737 $ work( ipw ), 1 )
738 ELSE
739 CALL zlaset( 'All', mp, 1, zero, zero,
740 $ work( ipw ),
max( 1, mp ) )
741 END IF
742 CALL zgsum2d( ictxt, 'Rowwise', ' ', mp, 1,
743 $ work( ipw ),
max( 1, mp ), rdest,
744 $ iccol )
745
746
747
748 CALL zgerc( mp, nq, -tauloc( 1 ), work( ipw ), 1,
749 $ work, 1, c( ioffc ), ldc )
750 END IF
751
752 ELSE
753
754
755
756 ipw = nq+1
757 CALL pbztrnv( ictxt,
'Columnwise',
'Transpose', n,
758 $ descv( mb_ ), icoff, v( ioffv ), 1, zero,
759 $ work, 1, ivrow, ivcol, -1, iccol,
760 $ work( ipw ) )
761
762
763
764 IF( mycol.EQ.ivcol ) THEN
765
766 CALL zgebs2d( ictxt, 'Rowwise', ' ', 1, 1, tau( jjv ),
767 $ 1 )
768 tauloc( 1 ) = dconjg( tau( jjv ) )
769
770 ELSE
771
772 CALL zgebr2d( ictxt, 'Rowwise', ' ', 1, 1, tauloc, 1,
773 $ myrow, ivcol )
774 tauloc( 1 ) = dconjg( tauloc( 1 ) )
775
776 END IF
777
778 IF( tauloc( 1 ).NE.zero ) THEN
779
780
781
782 IF( nq.GT.0 ) THEN
783 CALL zgemv( 'No transpose', mp, nq, one,
784 $ c( ioffc ), ldc, work, 1, zero,
785 $ work( ipw ), 1 )
786 ELSE
787 CALL zlaset( 'All', mp, 1, zero, zero, work( ipw ),
789 END IF
790 CALL zgsum2d( ictxt, 'Rowwise', ' ', mp, 1,
791 $ work( ipw ),
max( 1, mp ), rdest,
792 $ iccol )
793
794
795
796 CALL zgerc( mp, nq, -tauloc( 1 ), work( ipw ), 1,
797 $ work, 1, c( ioffc ), ldc )
798 END IF
799
800 END IF
801
802 END IF
803
804 END IF
805
806 RETURN
807
808
809
subroutine infog2l(grindx, gcindx, desc, nprow, npcol, myrow, mycol, lrindx, lcindx, rsrc, csrc)
integer function numroc(n, nb, iproc, isrcproc, nprocs)
subroutine pbztrnv(icontxt, xdist, trans, n, nb, nz, x, incx, beta, y, incy, ixrow, ixcol, iyrow, iycol, work)