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