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