1 SUBROUTINE pcgbdcmv( LDBW, BWL, BWU, TRANS, N, A, JA, DESCA, NRHS,
2 $ B, IB, DESCB, X, WORK, LWORK, INFO )
13 INTEGER , BWU, IB, , JA, LDBW, LWORK, N, NRHS
16 INTEGER DESCA( * ), DESCB( * )
17 COMPLEX A( * ), B( * ), WORK( * ), ( * )
324 parameter( one = 1.0e+0 )
325 parameter( zero = 0.0e+0 )
327 parameter( cone = ( 1.0e+0, 0.0e+0 ) )
328 parameter( czero = ( 0.0e+0, 0.0e+0 ) )
331 INTEGER DESCMULT, BIGNUM
332 parameter(descmult = 100, bignum = descmult * descmult)
333 INTEGER BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
334 $ lld_, mb_, m_, nb_, n_, rsrc_
335 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
336 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
337 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
340 INTEGER CSRC, DL_N_M, DL_N_N, DL_P_M, DL_P_N, DU_N_M,
341 $ du_n_n, du_p_m, du_p_n, first_proc, i, ictxt,
342 $ ictxt_new, ictxt_save, idum2
343 $ llda, lldb, max_bw, mycol, myrow, my_num_cols,
344 $ nb, np, npcol, nprow, np_save, odd_size, ofst,
345 $ part_offset, part_size, store_m_b, store_n_a
349 INTEGER PARAM_CHECK( 17, 3 )
357 EXTERNAL lsame, numroc
360 INTRINSIC ichar,
min, mod
368 ictxt = desca( ctxt_ )
369 csrc = desca( csrc_ )
372 store_n_a = desca( n_ )
374 store_m_b = descb( m_ )
379 max_bw =
max(bwl,bwu)
386 IF( lsame( trans,
'N' ) )
THEN
388 ELSE IF ( lsame( trans,
'C' ) )
THEN
394 IF( lwork .LT. -1)
THEN
406 IF( n+ja-1 .GT. store_n_a )
THEN
407 info = -( 8*100 + 6 )
410 IF(( bwl .GT. n-1 ) .OR.
411 $ ( bwl .LT. 0 ) )
THEN
415 IF(( bwu .GT. n-1 ) .OR.
416 $ ( bwu .LT. 0 ) )
THEN
420 IF( llda .LT. (bwl+bwu+1) )
THEN
421 info = -( 8*100 + 6 )
425 info = -( 8*100 + 4 )
430 IF( nprow .NE. 1 )
THEN
434 IF( n .GT. np*nb-mod( ja-1, nb ))
THEN
437 $ 'pcdbdcmv, d&c alg.: only 1 block per proc
',
442.GT..AND..LT.
IF((JA+N-1NB) ( NB2*MAX(BWL,BWU) )) THEN
445 $ 'pcdbdcmv, d&c alg.: nb too small
',
453 PARAM_CHECK( 17, 1 ) = DESCB(5)
454 PARAM_CHECK( 16, 1 ) = DESCB(4)
455 PARAM_CHECK( 15, 1 ) = DESCB(3)
456 PARAM_CHECK( 14, 1 ) = DESCB(2)
457 PARAM_CHECK( 13, 1 ) = DESCB(1)
458 PARAM_CHECK( 12, 1 ) = IB
459 PARAM_CHECK( 11, 1 ) = DESCA(5)
460 PARAM_CHECK( 10, 1 ) = DESCA(4)
461 PARAM_CHECK( 9, 1 ) = DESCA(3)
462 PARAM_CHECK( 8, 1 ) = DESCA(1)
463 PARAM_CHECK( 7, 1 ) = JA
464 PARAM_CHECK( 6, 1 ) = NRHS
465 PARAM_CHECK( 5, 1 ) = BWU
466 PARAM_CHECK( 4, 1 ) = BWL
467 PARAM_CHECK( 3, 1 ) = N
468 PARAM_CHECK( 2, 1 ) = IDUM3
469 PARAM_CHECK( 1, 1 ) = IDUM2
471 PARAM_CHECK( 17, 2 ) = 1105
472 PARAM_CHECK( 16, 2 ) = 1104
473 PARAM_CHECK( 15, 2 ) = 1103
474 PARAM_CHECK( 14, 2 ) = 1102
475 PARAM_CHECK( 13, 2 ) = 1101
476 PARAM_CHECK( 12, 2 ) = 10
477 PARAM_CHECK( 11, 2 ) = 805
478 PARAM_CHECK( 10, 2 ) = 804
479 PARAM_CHECK( 9, 2 ) = 803
480 PARAM_CHECK( 8, 2 ) = 801
481 PARAM_CHECK( 7, 2 ) = 7
482 PARAM_CHECK( 6, 2 ) = 5
483 PARAM_CHECK( 5, 2 ) = 4
484 PARAM_CHECK( 4, 2 ) = 3
485 PARAM_CHECK( 3, 2 ) = 2
486 PARAM_CHECK( 2, 2 ) = 15
487 PARAM_CHECK( 1, 2 ) = 1
495.LT.
ELSE IF( INFO-DESCMULT ) THEN
498 INFO = -INFO * DESCMULT
503 CALL GLOBCHK( ICTXT, 17, PARAM_CHECK, 17,
504 $ PARAM_CHECK( 1, 3 ), INFO )
509.EQ.
IF( INFOBIGNUM ) THEN
511.EQ.
ELSE IF( MOD( INFO, DESCMULT ) 0 ) THEN
512 INFO = -INFO / DESCMULT
518 CALL PXERBLA( ICTXT, 'pcdbdcmv
', -INFO )
531 PART_OFFSET = NB*( (JA-1)/(NPCOL*NB) )
533.LT.
IF ( (MYCOL-CSRC) (JA-PART_OFFSET-1)/NB ) THEN
534 PART_OFFSET = PART_OFFSET + NB
537.LT.
IF ( MYCOL CSRC ) THEN
538 PART_OFFSET = PART_OFFSET - NB
547 FIRST_PROC = MOD( ( JA-1 )/NB+CSRC, NPCOL )
551 JA_NEW = MOD( JA-1, NB ) + 1
556 NP = ( JA_NEW+N-2 )/NB + 1
560 CALL RESHAPE( ICTXT, INT_ONE, ICTXT_NEW, INT_ONE,
561 $ FIRST_PROC, INT_ONE, NP )
570 CALL BLACS_GRIDINFO( ICTXT, NPROW, NPCOL, MYROW, MYCOL )
574.LT.
IF( MYROW 0 ) THEN
587 MY_NUM_COLS = NUMROC( N, PART_SIZE, MYCOL, 0, NPCOL )
591.EQ.
IF ( MYCOL 0 ) THEN
592 PART_OFFSET = PART_OFFSET+MOD( JA_NEW-1, PART_SIZE )
593 MY_NUM_COLS = MY_NUM_COLS - MOD(JA_NEW-1, PART_SIZE )
598 OFST = PART_OFFSET*LLDA
602 ODD_SIZE = MY_NUM_COLS
603.LT.
IF ( MYCOL NP-1 ) THEN
604 ODD_SIZE = ODD_SIZE - MAX_BW
612 $ NUMROC( N, PART_SIZE, MYCOL, 0, NPCOL)
615 DO 4502 I=1,NUMROC_SIZE
616 X( (J-1)*LLDB + I ) = CZERO
620 DO 5642 I=1, (MAX_BW+2)*MAX_BW
629 IF ( LSAME( TRANS, 'n
' ) ) THEN
633.GT.
IF( MYCOL 0 ) THEN
636 $ NUMROC( N, PART_SIZE, MYCOL, 0, NPCOL ) )
638 $ NUMROC( N, PART_SIZE, MYCOL-1, 0, NPCOL ) )
641 $ NUMROC( N, PART_SIZE, MYCOL-1, 0, NPCOL ) )
643 $ NUMROC( N, PART_SIZE, MYCOL, 0, NPCOL ) )
646.LT.
IF( MYCOL NPCOL-1 ) THEN
649 $ NUMROC( N, PART_SIZE, MYCOL+1, 0, NPCOL ) )
651 $ NUMROC( N, PART_SIZE, MYCOL, 0, NPCOL ) )
654 $ NUMROC( N, PART_SIZE, MYCOL, 0, NPCOL ) )
656 $ NUMROC( N, PART_SIZE, MYCOL+1, 0, NPCOL ) )
662 CALL CGBMV( TRANS, NUMROC_SIZE, NUMROC_SIZE, BWL, BWU, CONE,
663 $ A( OFST+1 ), LLDA, B(PART_OFFSET+1), 1, CZERO,
664 $ X( PART_OFFSET+1 ), 1 )
668.LT.
IF ( MYCOL NPCOL-1 ) THEN
673 $ B( NUMROC_SIZE-DL_N_N+1 ),
674 $ 1, WORK( MAX_BW*MAX_BW+1+BWL-DL_N_N ), 1 )
676 CALL CTRMV( 'u
', 'n
', 'n
', BWL,
677 $ A( LLDA*( NUMROC_SIZE-BWL )+1+BWU+BWL ), LLDA-1,
678 $ WORK( MAX_BW*MAX_BW+1 ), 1)
682.GT.
IF( DL_N_M DL_N_N ) THEN
683 DO 10 I = DL_N_M-DL_N_N, DL_N_M
684 WORK( MAX_BW*MAX_BW+I ) = 0
690 CALL CGESD2D( ICTXT, BWL, 1,
691 $ WORK( MAX_BW*MAX_BW+1 ), BWL, MYROW, MYCOL+1 )
695.GT.
IF ( MYCOL 0 ) THEN
697 DO 20 I=1, MAX_BW*( MAX_BW+2 )
705 CALL CCOPY( DU_P_N, B( 1 ), 1,
706 $ WORK( MAX_BW*MAX_BW+1 ), 1)
713 $ WORK( MAX_BW*MAX_BW+1 ), 1 )
717.GT.
IF( DU_P_N DU_P_M ) THEN
718 DO 30 I=1, DU_P_N-DU_P_M
719 WORK( MAX_BW*MAX_BW+I ) = 0
725 CALL CGESD2D( ICTXT, BWU, 1, WORK(MAX_BW*MAX_BW+1 ),
726 $ BWU, MYROW, MYCOL-1 )
730 CALL CGERV2D( ICTXT, BWL, 1, WORK( MAX_BW*MAX_BW+1 ),
731 $ BWL, MYROW, MYCOL-1 )
735 CALL CAXPY( BWL, CONE,
736 $ WORK( MAX_BW*MAX_BW+1 ), 1,
743.LT.
IF( MYCOL NPCOL-1 ) THEN
747 CALL CGERV2D( ICTXT, BWU, 1, WORK( MAX_BW*MAX_BW+1 ),
748 $ BWU, MYROW, MYCOL+1 )
752 CALL CAXPY( BWU, CONE,
753 $ WORK( MAX_BW*MAX_BW+1 ), 1,
754 $ X( NUMROC_SIZE-BWU+1 ), 1)
765 IF ( LSAME( TRANS, 'c
' ) ) THEN
769.GT.
IF( MYCOL 0 ) THEN
772 $ NUMROC( N, PART_SIZE, MYCOL, 0, NPCOL ) )
774 $ NUMROC( N, PART_SIZE, MYCOL-1, 0, NPCOL ) )
777 $ NUMROC( N, PART_SIZE, MYCOL-1, 0, NPCOL ) )
779 $ NUMROC( N, PART_SIZE, MYCOL, 0, NPCOL ) )
782.LT.
IF( MYCOL NPCOL-1 ) THEN
785 $ NUMROC( N, PART_SIZE, MYCOL+1, 0, NPCOL ) )
787 $ NUMROC( N, PART_SIZE, MYCOL, 0, NPCOL ) )
790 $ NUMROC( N, PART_SIZE, MYCOL, 0, NPCOL ) )
792 $ NUMROC( N, PART_SIZE, MYCOL+1, 0, NPCOL ) )
796.GT.
IF( MYCOL 0 ) THEN
801 CALL CLATCPY( 'l
', BWU, BWU, A( OFST+1 ),
802 $ LLDA-1, WORK( 1 ), MAX_BW )
806 CALL CTRSD2D(ICTXT, 'u
', 'n
',
809 $ MAX_BW, MYROW, MYCOL-1 )
813.LT.
IF( MYCOL NPCOL-1 ) THEN
818 CALL CLATCPY( 'u
', BWL, BWL,
819 $ A( LLDA*( NUMROC_SIZE-BWL )+1+BWU+BWL ),
820 $ LLDA-1, WORK( 1 ), MAX_BW )
824 CALL CTRSD2D(ICTXT, 'l
', 'n
',
827 $ MAX_BW, MYROW, MYCOL+1 )
833 CALL CGBMV( TRANS, NUMROC_SIZE, NUMROC_SIZE, BWL, BWU, CONE,
834 $ A( OFST+1 ), LLDA, B(PART_OFFSET+1), 1, CZERO,
835 $ X( PART_OFFSET+1 ), 1 )
839.LT.
IF ( MYCOL NPCOL-1 ) THEN
844 $ B( NUMROC_SIZE-DL_N_N+1 ),
845 $ 1, WORK( MAX_BW*MAX_BW+1+BWU-DL_N_N ), 1 )
849 CALL CTRRV2D(ICTXT, 'u
', 'n
',
851 $ WORK( 1 ), MAX_BW, MYROW, MYCOL+1 )
853 CALL CTRMV( 'u
', 'n
', 'n
', BWU,
855 $ WORK( MAX_BW*MAX_BW+1 ), 1)
859.GT.
IF( DL_N_M DL_N_N ) THEN
860 DO 40 I = DL_N_M-DL_N_N, DL_N_M
861 WORK( MAX_BW*MAX_BW+I ) = 0
867 CALL CGESD2D( ICTXT, BWU, 1,
868 $ WORK( MAX_BW*MAX_BW+1 ), BWU, MYROW, MYCOL+1 )
872.GT.
IF ( MYCOL 0 ) THEN
874 DO 50 I=1, MAX_BW*( MAX_BW+2 )
882 CALL CCOPY( DU_P_N, B( 1 ), 1,
883 $ WORK( MAX_BW*MAX_BW+1 ), 1)
887 CALL CTRRV2D(ICTXT, 'l
', 'n
',
889 $ WORK( 1 ), MAX_BW, MYROW, MYCOL-1 )
896 $ WORK( MAX_BW*MAX_BW+1 ), 1 )
900.GT.
IF( DU_P_N DU_P_M ) THEN
901 DO 60 I=1, DU_P_N-DU_P_M
902 WORK( MAX_BW*MAX_BW+I ) = 0
908 CALL CGESD2D( ICTXT, BWL, 1, WORK(MAX_BW*MAX_BW+1 ),
909 $ BWL, MYROW, MYCOL-1 )
913 CALL CGERV2D( ICTXT, BWU, 1, WORK( MAX_BW*MAX_BW+1 ),
914 $ BWU, MYROW, MYCOL-1 )
918 CALL CAXPY( BWU, CONE,
919 $ WORK( MAX_BW*MAX_BW+1 ), 1,
926.LT.
IF( MYCOL NPCOL-1 ) THEN
930 CALL CGERV2D( ICTXT, BWL, 1, WORK( MAX_BW*MAX_BW+1 ),
931 $ BWL, MYROW, MYCOL+1 )
935 CALL CAXPY( BWL, CONE,
936 $ WORK( MAX_BW*MAX_BW+1 ), 1,
937 $ X( NUMROC_SIZE-BWL+1 ), 1)
949.NE.
IF( ICTXT_SAVE ICTXT_NEW ) THEN
950 CALL BLACS_GRIDEXIT( ICTXT_NEW )
subroutine pcgbdcmv(ldbw, bwl, bwu, trans, n, a, ja, desca, nrhs, b, ib, descb, x, work, lwork, info)