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