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 ) = tau( iiv )
340
341 ELSE
342
343 CALL zgebr2d( ictxt, 'Columnwise', ' ', 1, 1,
344 $ tauloc, 1, ivrow, mycol )
345
346 END IF
347
348 IF( tauloc( 1 ).NE.zero ) THEN
349
350
351
352 IF( mp.GT.0 ) THEN
353 CALL zgemv( 'Conjugate transpose', mp, nq, one,
354 $ c( ioffc ), ldc, work, 1, zero,
355 $ work( ipw ), 1 )
356 ELSE
357 CALL zlaset( 'All', nq, 1, zero, zero,
358 $ work( ipw ),
max( 1, nq ) )
359 END IF
360 CALL zgsum2d( ictxt, 'Columnwise', ' ', nq, 1,
361 $ work( ipw ),
max( 1, nq ), rdest,
362 $ mycol )
363
364
365
366 CALL zgerc( mp, nq, -tauloc( 1 ), work, 1,
367 $ work( ipw ), 1, c( ioffc ), ldc )
368 END IF
369
370 END IF
371
372 ELSE
373
374
375
376 IF( ivcol.EQ.iccol ) THEN
377
378
379
380 IF( mycol.EQ.iccol ) THEN
381
382 tauloc( 1 ) = tau( jjv )
383
384 IF( tauloc( 1 ).NE.zero ) THEN
385
386
387
388 IF( mp.GT.0 ) THEN
389 CALL zgemv( 'Conjugate transpose', mp, nq,
390 $ one, c( ioffc ), ldc, v( ioffv ), 1,
391 $ zero, work, 1 )
392 ELSE
393 CALL zlaset( 'All', nq, 1, zero, zero,
394 $ work,
max( 1, nq ) )
395 END IF
396 CALL zgsum2d( ictxt, 'Columnwise', ' ', nq, 1,
397 $ work,
max( 1, nq ), rdest, mycol )
398
399
400
401 CALL zgerc( mp, nq, -tauloc( 1 ), v( ioffv ), 1,
402 $ work, 1, c( ioffc ), ldc )
403 END IF
404
405 END IF
406
407 ELSE
408
409
410
411 IF( mycol.EQ.ivcol ) THEN
412
413 ipw = mp+1
414 CALL zcopy( mp, v( ioffv ), 1, work, 1 )
415 work( ipw ) = tau( jjv )
416 CALL zgesd2d( ictxt, ipw, 1, work, ipw, myrow,
417 $ iccol )
418
419 ELSE IF( mycol.EQ.iccol ) THEN
420
421 ipw = mp+1
422 CALL zgerv2d( ictxt, ipw, 1, work, ipw, myrow,
423 $ ivcol )
424 tauloc( 1 ) = work( ipw )
425
426 IF( tauloc( 1 ).NE.zero ) THEN
427
428
429
430 IF( mp.GT.0 ) THEN
431 CALL zgemv( 'Conjugate transpose', mp, nq,
432 $ one, c( ioffc ), ldc, work, 1,
433 $ zero, work( ipw ), 1 )
434 ELSE
435 CALL zlaset( 'All', nq, 1, zero, zero,
436 $ work( ipw ),
max( 1, nq ) )
437 END IF
438 CALL zgsum2d( ictxt, 'Columnwise', ' ', nq, 1,
439 $ work( ipw ),
max( 1, nq ), rdest,
440 $ mycol )
441
442
443
444 CALL zgerc( mp, nq, -tauloc( 1 ), work, 1,
445 $ work( ipw ), 1, c( ioffc ), ldc )
446 END IF
447
448 END IF
449
450 END IF
451
452 END IF
453
454 ELSE
455
456
457
458 IF( descv( m_ ).EQ.incv ) THEN
459
460
461
462 ipw = mp+1
463 CALL pbztrnv( ictxt,
'Rowwise',
'Transpose', m,
464 $ descv( nb_ ), iroff, v( ioffv ), ldv, zero,
465 $ work, 1, ivrow, ivcol, icrow, -1,
466 $ work( ipw ) )
467
468
469
470 IF( myrow.EQ.ivrow ) THEN
471
472 CALL zgebs2d( ictxt, 'Columnwise', ' ', 1, 1,
473 $ tau( iiv ), 1 )
474 tauloc( 1 ) = tau( iiv )
475
476 ELSE
477
478 CALL zgebr2d( ictxt, 'Columnwise', ' ', 1, 1, tauloc,
479 $ 1, ivrow, mycol )
480
481 END IF
482
483 IF( tauloc( 1 ).NE.zero ) THEN
484
485
486
487 IF( mp.GT.0 ) THEN
488 IF( ioffc.GT.0 )
489 $ CALL zgemv( 'Conjugate transpose', mp, nq, one,
490 $ c( ioffc ), ldc, work, 1, zero,
491 $ work( ipw ), 1 )
492 ELSE
493 CALL zlaset( 'All', nq, 1, zero, zero,
494 $ work( ipw ),
max( 1, nq ) )
495 END IF
496 CALL zgsum2d( ictxt, 'Columnwise', ' ', nq, 1,
497 $ work( ipw ),
max( 1, nq ), rdest,
498 $ mycol )
499
500
501
502 IF( ioffc.GT.0 )
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 ) = 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 ) = work( ipw )
527
528 END IF
529
530 IF( tauloc( 1 ).NE.zero ) THEN
531
532
533
534 IF( mp.GT.0 ) THEN
535 IF( ioffc.GT.0 )
536 $ CALL zgemv( 'Conjugate transpose', mp, nq, one,
537 $ c( ioffc ), ldc, work, 1, zero,
538 $ work( ipw ), 1 )
539 ELSE
540 CALL zlaset( 'All', nq, 1, zero, zero,
541 $ work( ipw ),
max( 1, nq ) )
542 END IF
543 CALL zgsum2d( ictxt, 'Columnwise', ' ', nq, 1,
544 $ work( ipw ),
max( 1, nq ), rdest,
545 $ mycol )
546
547
548
549 IF( ioffc.GT.0 )
550 $ CALL zgerc( mp, nq, -tauloc( 1 ), work, 1,
551 $ work( ipw ), 1, c( ioffc ), ldc )
552 END IF
553
554 END IF
555
556 END IF
557
558 ELSE
559
560 IF( ccblck ) THEN
561 rdest = myrow
562 ELSE
563 rdest = -1
564 END IF
565
566 IF( crblck ) THEN
567
568
569
570 IF( descv( m_ ).EQ.incv ) THEN
571
572
573
574 IF( ivrow.EQ.icrow ) THEN
575
576
577
578 IF( myrow.EQ.icrow ) THEN
579
580 tauloc( 1 ) = tau( iiv )
581
582 IF( tauloc( 1 ).NE.zero ) THEN
583
584
585
586 IF( nq.GT.0 ) THEN
587 CALL zgemv( 'No transpose', mp, nq, one,
588 $ c( ioffc ), ldc, v( ioffv ), ldv,
589 $ zero, work, 1 )
590 ELSE
591 CALL zlaset( 'All', mp, 1, zero, zero,
592 $ work,
max( 1, mp ) )
593 END IF
594 CALL zgsum2d( ictxt, 'Rowwise', ' ', mp, 1,
595 $ work,
max( 1, mp ), rdest, iccol )
596
597
598
599 IF( ioffv.GT.0 .AND. ioffc.GT.0 )
600 $ CALL zgerc( mp, nq, -tauloc( 1 ), work, 1,
601 $ v( ioffv ), ldv, c( ioffc ),
602 $ ldc )
603 END IF
604
605 END IF
606
607 ELSE
608
609
610
611 IF( myrow.EQ.ivrow ) THEN
612
613 ipw = nq+1
614 CALL zcopy( nq, v( ioffv ), ldv, work, 1 )
615 work(ipw) = tau( iiv )
616 CALL zgesd2d( ictxt, ipw, 1, work, ipw, icrow,
617 $ mycol )
618
619 ELSE IF( myrow.EQ.icrow ) THEN
620
621 ipw = nq+1
622 CALL zgerv2d( ictxt, ipw, 1, work, ipw, ivrow,
623 $ mycol )
624 tauloc( 1 ) = work( ipw )
625
626 IF( tauloc( 1 ).NE.zero ) THEN
627
628
629
630 IF( nq.GT.0 ) THEN
631 CALL zgemv( 'No transpose', mp, nq, one,
632 $ c( ioffc ), ldc, work, 1, zero,
633 $ work( ipw ), 1 )
634 ELSE
635 CALL zlaset( 'All', mp, 1, zero, zero,
636 $ work( ipw ),
max( 1, mp ) )
637 END IF
638 CALL zgsum2d( ictxt, 'Rowwise', ' ', mp, 1,
639 $ work( ipw ),
max( 1, mp ), rdest,
640 $ iccol )
641
642
643
644 CALL zgerc( mp, nq, -tauloc( 1 ), work( ipw ),
645 $ 1, work, 1, c( ioffc ), ldc )
646 END IF
647
648 END IF
649
650 END IF
651
652 ELSE
653
654
655
656 ipw = nq+1
657 CALL pbztrnv( ictxt,
'Columnwise',
'Transpose', n,
658 $ descv( mb_ ), icoff, v( ioffv ), 1, zero,
659 $ work, 1, ivrow, ivcol, icrow, iccol,
660 $ work( ipw ) )
661
662
663
664 IF( myrow.EQ.icrow ) THEN
665
666 IF( mycol.EQ.ivcol ) THEN
667
668 CALL zgebs2d( ictxt, 'Rowwise', ' ', 1, 1,
669 $ tau( jjv ), 1 )
670 tauloc( 1 ) = tau( jjv )
671
672 ELSE
673
674 CALL zgebr2d( ictxt, 'Rowwise', ' ', 1, 1, tauloc,
675 $ 1, myrow, ivcol )
676
677 END IF
678
679 IF( tauloc( 1 ).NE.zero ) THEN
680
681
682
683 IF( nq.GT.0 ) THEN
684 CALL zgemv( 'No transpose', mp, nq, one,
685 $ c( ioffc ), ldc, work, 1, zero,
686 $ work( ipw ), 1 )
687 ELSE
688 CALL zlaset( 'All', mp, 1, zero, zero,
689 $ work( ipw ),
max( 1, mp ) )
690 END IF
691 CALL zgsum2d( ictxt, 'Rowwise', ' ', mp, 1,
692 $ work( ipw ),
max( 1, mp ), rdest,
693 $ iccol )
694
695
696
697 CALL zgerc( mp, nq, -tauloc( 1 ), work( ipw ), 1,
698 $ work, 1, c( ioffc ), ldc )
699 END IF
700
701 END IF
702
703 END IF
704
705 ELSE
706
707
708
709 IF( descv( m_ ).EQ.incv ) THEN
710
711
712
713 CALL pb_topget( ictxt, 'Broadcast', 'Columnwise',
714 $ colbtop )
715 IF( myrow.EQ.ivrow ) THEN
716
717 ipw = nq+1
718 IF( ioffv.GT.0 )
719 $ CALL zcopy( nq, v( ioffv ), ldv, work, 1 )
720 work(ipw) = tau( iiv )
721 CALL zgebs2d( ictxt, 'Columnwise', colbtop, ipw, 1,
722 $ work, ipw )
723 tauloc( 1 ) = tau( iiv )
724
725 ELSE
726
727 ipw = nq+1
728 CALL zgebr2d( ictxt, 'Columnwise', colbtop, ipw, 1,
729 $ work, ipw, ivrow, mycol )
730 tauloc( 1 ) = work( ipw )
731
732 END IF
733
734 IF( tauloc( 1 ).NE.zero ) THEN
735
736
737
738 IF( nq.GT.0 ) THEN
739 CALL zgemv( 'No Transpose', mp, nq, one,
740 $ c( ioffc ), ldc, work, 1, zero,
741 $ work( ipw ), 1 )
742 ELSE
743 CALL zlaset( 'All', mp, 1, zero, zero,
744 $ work( ipw ),
max( 1, mp ) )
745 END IF
746 CALL zgsum2d( ictxt, 'Rowwise', ' ', mp, 1,
747 $ work( ipw ),
max( 1, mp ), rdest,
748 $ iccol )
749
750
751
752 IF( ioffc.GT.0 )
753 $ CALL zgerc( mp, nq, -tauloc( 1 ), work( ipw ), 1,
754 $ work, 1, c( ioffc ), ldc )
755 END IF
756
757 ELSE
758
759
760
761 ipw = nq+1
762 CALL pbztrnv( ictxt,
'Columnwise',
'Transpose', n,
763 $ descv( mb_ ), icoff, v( ioffv ), 1, zero,
764 $ work, 1, ivrow, ivcol, -1, iccol,
765 $ work( ipw ) )
766
767
768
769 IF( mycol.EQ.ivcol ) THEN
770
771 CALL zgebs2d( ictxt, 'Rowwise', ' ', 1, 1, tau( jjv ),
772 $ 1 )
773 tauloc( 1 ) = tau( jjv )
774
775 ELSE
776
777 CALL zgebr2d( ictxt, 'Rowwise', ' ', 1, 1, tauloc, 1,
778 $ myrow, ivcol )
779
780 END IF
781
782 IF( tauloc( 1 ).NE.zero ) THEN
783
784
785
786 IF( nq.GT.0 ) THEN
787 CALL zgemv( 'No transpose', mp, nq, one,
788 $ c( ioffc ), ldc, work, 1, zero,
789 $ work( ipw ), 1 )
790 ELSE
791 CALL zlaset( 'All', mp, 1, zero, zero, work( ipw ),
793 END IF
794 CALL zgsum2d( ictxt, 'Rowwise', ' ', mp, 1,
795 $ work( ipw ),
max( 1, mp ), rdest,
796 $ iccol )
797
798
799
800 CALL zgerc( mp, nq, -tauloc( 1 ), work( ipw ), 1,
801 $ work, 1, c( ioffc ), ldc )
802 END IF
803
804 END IF
805
806 END IF
807
808 END IF
809
810 RETURN
811
812
813
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)