3
4
5
6
7
8
9
10
11
12 CHARACTER UPLO
13 INTEGER BW, IB, INFO, JA, LDBW, LWORK, N, NRHS
14
15
16 INTEGER DESCA( * ), DESCB( * )
17 COMPLEX A( * ), B( * ), WORK( * ), X( * )
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
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319 REAL ONE, ZERO
320 parameter( one = 1.0e+0 )
321 parameter( zero = 0.0e+0 )
322 COMPLEX CONE, CZERO
323 parameter( cone = ( 1.0e+0, 0.0e+0 ) )
324 parameter( czero = ( 0.0e+0, 0.0e+0 ) )
325 INTEGER INT_ONE
326 parameter( int_one = 1 )
327 INTEGER DESCMULT, BIGNUM
328 parameter(descmult = 100, bignum = descmult * descmult)
329 INTEGER BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
330 $ LLD_, MB_, M_, NB_, N_, RSRC_
331 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
332 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
333 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
334
335
336 INTEGER CSRC, DL_N_M, DL_N_N, DL_P_M, DL_P_N,
337 $ FIRST_PROC, I, ICTXT, ICTXT_NEW, ICTXT_SAVE,
338 $ IDUM1, IDUM3, J, JA_NEW, LLDA, LLDB, MYCOL,
339 $ MYROW, MY_NUM_COLS, NB, NP, NPCOL, NPROW,
340 $ NP_SAVE, ODD_SIZE, OFST, PART_OFFSET,
341 $ PART_SIZE, STORE_M_B, STORE_N_A
342 INTEGER NUMROC_SIZE
343
344
345 INTEGER PARAM_CHECK( 16, 3 )
346
347
349
350
351 LOGICAL LSAME
352 INTEGER NUMROC
354
355
356 INTRINSIC ichar,
min, mod
357
358
359
360
361
362 info = 0
363
364 ictxt = desca( ctxt_ )
365 csrc = desca( csrc_ )
366 nb = desca( nb_ )
367 llda = desca( lld_ )
368 store_n_a = desca( n_ )
369 lldb = descb( lld_ )
370 store_m_b = descb( m_ )
371
372
373
374
375
376 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
377 np = nprow * npcol
378
379
380
381 IF(
lsame( uplo,
'U' ) )
THEN
382 idum1 = ichar( 'U' )
383 ELSE IF (
lsame( uplo,
'L' ) )
THEN
384 idum1 = ichar( 'L' )
385 ELSE
386 info = -1
387 END IF
388
389 IF( lwork .LT. -1) THEN
390 info = -14
391 ELSE IF ( lwork .EQ. -1 ) THEN
392 idum3 = -1
393 ELSE
394 idum3 = 1
395 ENDIF
396
397 IF( n .LT. 0 ) THEN
398 info = -2
399 ENDIF
400
401 IF( n+ja-1 .GT. store_n_a ) THEN
402 info = -( 7*100 + 6 )
403 ENDIF
404
405 IF(( bw .GT. n-1 ) .OR.
406 $ ( bw .LT. 0 ) ) THEN
407 info = -3
408 ENDIF
409
410 IF( llda .LT. (bw+1) ) THEN
411 info = -( 7*100 + 6 )
412 ENDIF
413
414 IF( nb .LE. 0 ) THEN
415 info = -( 7*100 + 4 )
416 ENDIF
417
418
419
420 IF( nprow .NE. 1 ) THEN
421 info = -( 7*100+2 )
422 ENDIF
423
424 IF( n .GT. np*nb-mod( ja-1, nb )) THEN
425 info = -( 2 )
427 $ 'PCPBDCMV, D&C alg.: only 1 block per proc',
428 $ -info )
429 RETURN
430 ENDIF
431
432 IF((ja+n-1.GT.nb) .AND. ( nb.LT.2*bw )) THEN
433 info = -( 7*100+4 )
435 $ 'PCPBDCMV, D&C alg.: NB too small',
436 $ -info )
437 RETURN
438 ENDIF
439
440
441
442
443 param_check( 16, 1 ) = descb(5)
444 param_check( 15, 1 ) = descb(4)
445 param_check( 14, 1 ) = descb(3)
446 param_check( 13, 1 ) = descb(2)
447 param_check( 12, 1 ) = descb(1)
448 param_check( 11, 1 ) = ib
449 param_check( 10, 1 ) = desca(5)
450 param_check( 9, 1 ) = desca(4)
451 param_check( 8, 1 ) = desca(3)
452 param_check( 7, 1 ) = desca(1)
453 param_check( 6, 1 ) = ja
454 param_check( 5, 1 ) = nrhs
455 param_check( 4, 1 ) = bw
456 param_check( 3, 1 ) = n
457 param_check( 2, 1 ) = idum3
458 param_check( 1, 1 ) = idum1
459
460 param_check( 16, 2 ) = 1005
461 param_check( 15, 2 ) = 1004
462 param_check( 14, 2 ) = 1003
463 param_check( 13, 2 ) = 1002
464 param_check( 12, 2 ) = 1001
465 param_check( 11, 2 ) = 9
466 param_check( 10, 2 ) = 705
467 param_check( 9, 2 ) = 704
468 param_check( 8, 2 ) = 703
469 param_check( 7, 2 ) = 701
470 param_check( 6, 2 ) = 6
471 param_check( 5, 2 ) = 4
472 param_check( 4, 2 ) = 3
473 param_check( 3, 2 ) = 2
474 param_check( 2, 2 ) = 14
475 param_check( 1, 2 ) = 1
476
477
478
479
480
481 IF( info.GE.0 ) THEN
482 info = bignum
483 ELSE IF( info.LT.-descmult ) THEN
484 info = -info
485 ELSE
486 info = -info * descmult
487 END IF
488
489
490
491 CALL globchk( ictxt, 16, param_check, 16,
492 $ param_check( 1, 3 ), info )
493
494
495
496
497 IF( info.EQ.bignum ) THEN
498 info = 0
499 ELSE IF( mod( info, descmult ) .EQ. 0 ) THEN
500 info = -info / descmult
501 ELSE
502 info = -info
503 END IF
504
505 IF( info.LT.0 ) THEN
506 CALL pxerbla( ictxt,
'PCPBDCMV', -info )
507 RETURN
508 END IF
509
510
511
512 IF( n.EQ.0 )
513 $ RETURN
514
515
516
517
518
519 part_offset = nb*( (ja-1)/(npcol*nb) )
520
521 IF ( (mycol-csrc) .LT. (ja-part_offset-1)/nb ) THEN
522 part_offset = part_offset + nb
523 ENDIF
524
525 IF ( mycol .LT. csrc ) THEN
526 part_offset = part_offset - nb
527 ENDIF
528
529
530
531
532
533
534
535 first_proc = mod( ( ja-1 )/nb+csrc, npcol )
536
537
538
539 ja_new = mod( ja-1, nb ) + 1
540
541
542
543 np_save = np
544 np = ( ja_new+n-2 )/nb + 1
545
546
547
548 CALL reshape( ictxt, int_one, ictxt_new, int_one,
549 $ first_proc, int_one, np )
550
551
552
553 ictxt_save = ictxt
554 ictxt = ictxt_new
555
556
557
558 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
559
560
561
562 IF( myrow .LT. 0 ) THEN
563 GOTO 1234
564 ENDIF
565
566
567
568
569
570
571 part_size = nb
572
573
574
575 my_num_cols =
numroc( n, part_size, mycol, 0, npcol )
576
577
578
579 IF ( mycol .EQ. 0 ) THEN
580 part_offset = part_offset+mod( ja_new-1, part_size )
581 my_num_cols = my_num_cols - mod(ja_new-1, part_size )
582 ENDIF
583
584
585
586 ofst = part_offset*llda
587
588
589
590 odd_size = my_num_cols
591 IF ( mycol .LT. np-1 ) THEN
592 odd_size = odd_size - bw
593 ENDIF
594
595
596
597
598
599 numroc_size =
600 $
numroc( n, part_size, mycol, 0, npcol)
601
602 DO 2279 j=1,nrhs
603 DO 4502 i=1,numroc_size
604 x( (j-1)*lldb + i ) = czero
605 4502 CONTINUE
606 2279 CONTINUE
607
608 DO 5642 i=1, (bw+2)*bw
609 work( i ) = czero
610 5642 CONTINUE
611
612
613
614
615
616
617 IF (
lsame( uplo,
'L' ) )
THEN
618
619
620
621 IF( mycol .GT. 0 ) THEN
622
624 $
numroc( n, part_size, mycol, 0, npcol ) )
626 $
numroc( n, part_size, mycol-1, 0, npcol ) )
627 ENDIF
628
629 IF( mycol .LT. npcol-1 ) THEN
630
632 $
numroc( n, part_size, mycol+1, 0, npcol ) )
634 $
numroc( n, part_size, mycol, 0, npcol ) )
635 ENDIF
636
637
638 IF( mycol .LT. npcol-1 ) THEN
639
640
641
642
644 $ a( llda*( numroc_size-bw )+1+bw ),
645 $ llda-1, work( 1 ), bw )
646
647
648
649 CALL ctrsd2d(ictxt, 'L', 'N',
650 $ bw, bw,
651 $ work( 1 ),
652 $ bw, myrow, mycol+1 )
653
654 ENDIF
655
656
657
658 CALL chbmv( 'L', numroc_size, bw, cone, a( ofst+1 ), llda,
659 $ b(part_offset+1), 1, czero, x( part_offset+1 ), 1 )
660
661
662
663 IF ( mycol .LT. npcol-1 ) THEN
664
665
666
667 CALL ccopy( dl_n_n,
668 $ b( numroc_size-dl_n_n+1 ),
669 $ 1, work( bw*bw+1+bw-dl_n_n ), 1 )
670
671 CALL ctrmv( 'U', 'N', 'N', bw,
672 $ a( llda*( numroc_size-bw )+1+bw ), llda-1,
673 $ work( bw*bw+1 ), 1)
674
675
676
677 IF( dl_n_m .GT. dl_n_n ) THEN
678 DO 10 i = dl_n_m-dl_n_n, dl_n_m
679 work( bw*bw+i ) = 0
680 10 CONTINUE
681 ENDIF
682
683
684
685 CALL cgesd2d( ictxt, bw, 1,
686 $ work( bw*bw+1 ), bw, myrow, mycol+1 )
687
688 ENDIF
689
690 IF ( mycol .GT. 0 ) THEN
691
692 DO 20 i=1, bw*( bw+2 )
693 work( i ) = czero
694 20 CONTINUE
695
696
697
698
699
700 CALL ccopy( dl_p_m, b( 1 ), 1,
701 $ work( bw*bw+1 ), 1)
702
703
704
705 CALL ctrrv2d(ictxt, 'L', 'N',
706 $ bw, bw,
707 $ work( 1 ), bw, myrow, mycol-1 )
708
709 CALL ctrmv(
710 $ 'L',
711 $ 'N',
712 $ 'N', bw,
713 $ work( 1 ), bw,
714 $ work( bw*bw+1 ), 1 )
715
716
717
718 IF( dl_p_m .GT. dl_p_n ) THEN
719 DO 30 i=1, dl_p_m-dl_p_n
720 work( bw*bw+i ) = 0
721 30 CONTINUE
722 ENDIF
723
724
725
726 CALL cgesd2d( ictxt, bw, 1, work(bw*bw+1 ),
727 $ bw, myrow, mycol-1 )
728
729
730
731 CALL cgerv2d( ictxt, bw, 1, work( bw*bw+1 ),
732 $ bw, myrow, mycol-1 )
733
734
735
736 CALL caxpy( bw, cone,
737 $ work( bw*bw+1 ), 1,
738 $ x( 1 ), 1 )
739
740 ENDIF
741
742
743
744 IF( mycol .LT. npcol-1 ) THEN
745
746
747
748 CALL cgerv2d( ictxt, bw, 1, work( bw*bw+1 ),
749 $ bw, myrow, mycol+1 )
750
751
752
753 CALL caxpy( bw, cone,
754 $ work( bw*bw+1 ), 1,
755 $ x( numroc_size-bw+1 ), 1)
756
757 ENDIF
758
759
760 ENDIF
761
762
763
764
765
766 IF (
lsame( uplo,
'U' ) )
THEN
767
768
769
770 IF( mycol .GT. 0 ) THEN
771
773 $
numroc( n, part_size, mycol, 0, npcol ) )
775 $
numroc( n, part_size, mycol-1, 0, npcol ) )
776 ENDIF
777
778 IF( mycol .LT. npcol-1 ) THEN
779
781 $
numroc( n, part_size, mycol+1, 0, npcol ) )
783 $
numroc( n, part_size, mycol, 0, npcol ) )
784 ENDIF
785
786
787 IF( mycol .GT. 0 ) THEN
788
789
790
791
792 CALL clatcpy(
'L', bw, bw, a( ofst+1 ),
793 $ llda-1, work( 1 ), bw )
794
795
796
797 CALL ctrsd2d(ictxt, 'U', 'N',
798 $ bw, bw,
799 $ work( 1 ),
800 $ bw, myrow, mycol-1 )
801
802 ENDIF
803
804
805
806 CALL chbmv( 'U', numroc_size, bw, cone, a( ofst+1 ), llda,
807 $ b(part_offset+1), 1, czero, x( part_offset+1 ), 1 )
808
809
810
811 IF ( mycol .LT. npcol-1 ) THEN
812
813
814
815 CALL ccopy( dl_n_n,
816 $ b( numroc_size-dl_n_n+1 ),
817 $ 1, work( bw*bw+1+bw-dl_n_n ), 1 )
818
819
820
821 CALL ctrrv2d(ictxt, 'U', 'N',
822 $ bw, bw,
823 $ work( 1 ), bw, myrow, mycol+1 )
824
825 CALL ctrmv( 'U', 'N', 'N', bw,
826 $ work( 1 ), bw,
827 $ work( bw*bw+1 ), 1)
828
829
830
831 IF( dl_n_m .GT. dl_n_n ) THEN
832 DO 40 i = dl_n_m-dl_n_n, dl_n_m
833 work( bw*bw+i ) = 0
834 40 CONTINUE
835 ENDIF
836
837
838
839 CALL cgesd2d( ictxt, bw, 1,
840 $ work( bw*bw+1 ), bw, myrow, mycol+1 )
841
842 ENDIF
843
844 IF ( mycol .GT. 0 ) THEN
845
846 DO 50 i=1, bw*( bw+2 )
847 work( i ) = czero
848 50 CONTINUE
849
850
851
852
853
854 CALL ccopy( dl_p_m, b( 1 ), 1,
855 $ work( bw*bw+1 ), 1)
856
857 CALL ctrmv(
858 $ 'L',
859 $ 'N',
860 $ 'N', bw,
861 $ a( 1 ), llda-1,
862 $ work( bw*bw+1 ), 1 )
863
864
865
866 IF( dl_p_m .GT. dl_p_n ) THEN
867 DO 60 i=1, dl_p_m-dl_p_n
868 work( bw*bw+i ) = 0
869 60 CONTINUE
870 ENDIF
871
872
873
874 CALL cgesd2d( ictxt, bw, 1, work(bw*bw+1 ),
875 $ bw, myrow, mycol-1 )
876
877
878
879 CALL cgerv2d( ictxt, bw, 1, work( bw*bw+1 ),
880 $ bw, myrow, mycol-1 )
881
882
883
884 CALL caxpy( bw, cone,
885 $ work( bw*bw+1 ), 1,
886 $ x( 1 ), 1 )
887
888 ENDIF
889
890
891
892 IF( mycol .LT. npcol-1 ) THEN
893
894
895
896 CALL cgerv2d( ictxt, bw, 1, work( bw*bw+1 ),
897 $ bw, myrow, mycol+1 )
898
899
900
901 CALL caxpy( bw, cone,
902 $ work( bw*bw+1 ), 1,
903 $ x( numroc_size-bw+1 ), 1)
904
905 ENDIF
906
907
908 ENDIF
909
910
911
912
913
914
915 IF( ictxt_save .NE. ictxt_new ) THEN
916 CALL blacs_gridexit( ictxt_new )
917 ENDIF
918
919 1234 CONTINUE
920
921
922
923 ictxt = ictxt_save
924 np = np_save
925
926
927 RETURN
928
929
930
subroutine clatcpy(uplo, m, n, a, lda, b, ldb)
integer function numroc(n, nb, iproc, isrcproc, nprocs)
subroutine globchk(ictxt, n, x, ldx, iwork, info)
subroutine pxerbla(ictxt, srname, info)
void reshape(Int *context_in, Int *major_in, Int *context_out, Int *major_out, Int *first_proc, Int *nprow_new, Int *npcol_new)