1 SUBROUTINE pzgbdcmv( LDBW, BWL, BWU, TRANS, N, A, JA, DESCA, NRHS,
2 $ B, IB, DESCB, X, WORK, LWORK, INFO )
13 INTEGER , BWU, IB, INFO, JA, LDBW, LWORK, N, NRHS
16 INTEGER DESCA( * ), DESCB( * )
17 COMPLEX*16 A( * ), B( * ), WORK( * ), X( * )
323 DOUBLE PRECISION ONE, ZERO
324 parameter( one = 1.0d+0 )
325 parameter( zero = 0.0d+0 )
326 COMPLEX*16 CONE, CZERO
327 parameter( cone = ( 1.0d+0, 0.0d+0 ) )
328 parameter( czero = ( 0.0d+0, 0.0d+0 ) )
330 parameter( int_one = 1 )
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, idum3, j, ja_new,
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.LT.
IF( LWORK -1) THEN
396.EQ.
ELSE IF ( LWORK -1 ) THEN
406.GT.
IF( N+JA-1 STORE_N_A ) THEN
407 INFO = -( 8*100 + 6 )
410.GT..OR.
IF(( BWL N-1 )
411.LT.
$ ( BWL 0 ) ) THEN
415.GT..OR.
IF(( BWU N-1 )
416.LT.
$ ( BWU 0 ) ) THEN
420.LT.
IF( LLDA (BWL+BWU+1) ) THEN
421 INFO = -( 8*100 + 6 )
425 INFO = -( 8*100 + 4 )
430.NE.
IF( NPROW 1 ) THEN
434.GT.
IF( N NP*NB-MOD( JA-1, NB )) THEN
437 $ 'pzdbdcmv, d&c alg.: only 1 block per proc
',
442.GT..AND..LT.
IF((JA+N-1NB) ( NB2*MAX(BWL,BWU) )) THEN
445 $ 'pzdbdcmv, 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, 'pzdbdcmv
', -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 ZGBMV( 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 ZTRMV( 'u',
'N',
'N', bwl,
677 $ a( llda*( numroc_size-bwl )+1+bwu+bwl ), llda-1,
678 $ work( max_bw*max_bw+1 ), 1)
682 IF( dl_n_m .GT. 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 zgesd2d( ictxt, bwl, 1,
691 $ work( max_bw*max_bw+1 ), bwl, myrow, mycol+1 )
695 IF ( mycol .GT. 0 )
THEN
697 DO 20 i=1, max_bw*( max_bw+2 )
705 CALL zcopy( du_p_n, b( 1 ), 1,
706 $ work( max_bw*max_bw+1 ), 1)
713 $ work( max_bw*max_bw+1 ), 1 )
717 IF( du_p_n .GT. 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 zgesd2d( ictxt, bwu, 1, work(max_bw*max_bw+1 ),
726 $ bwu, myrow, mycol-1 )
730 CALL zgerv2d( ictxt, bwl, 1, work( max_bw*max_bw+1 ),
731 $ bwl, myrow, mycol-1 )
735 CALL zaxpy( bwl, cone,
736 $ work( max_bw*max_bw+1 ), 1,
743 IF( mycol .LT. npcol-1 )
THEN
747 CALL zgerv2d( ictxt, bwu, 1, work( max_bw*max_bw+1 ),
748 $ bwu, myrow, mycol+1 )
752 CALL zaxpy( bwu, cone,
753 $ work( max_bw*max_bw+1 ), 1,
754 $ x( numroc_size-bwu+1 ), 1)
765 IF ( lsame( trans,
'C' ) )
THEN
769 IF( mycol .GT. 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 IF( mycol .LT. 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 IF( mycol .GT. 0 )
THEN
801 CALL zlatcpy(
'L', bwu, bwu, a( ofst+1 ),
802 $ llda-1, work( 1 ), max_bw )
806 CALL ztrsd2d(ictxt,
'U',
'N',
809 $ max_bw, myrow, mycol-1 )
813 IF( mycol .LT. npcol-1 )
THEN
819 $ a( llda*( numroc_size-bwl )+1+bwu+bwl ),
820 $ llda-1, work( 1 ), max_bw )
824 CALL ztrsd2d(ictxt,
'L',
'N',
827 $ max_bw, myrow, mycol+1 )
833 CALL zgbmv( 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 IF ( mycol .LT. 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 ztrrv2d(ictxt,
'U',
'N',
851 $ work( 1 ), max_bw, myrow, mycol+1 )
853 CALL ztrmv(
'U',
'N',
'N', bwu,
855 $ work( max_bw*max_bw+1 ), 1)
859 IF( dl_n_m .GT. 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 zgesd2d( ictxt, bwu, 1,
868 $ work( max_bw*max_bw+1 ), bwu, myrow, mycol+1 )
872 IF ( mycol .GT. 0 )
THEN
874 DO 50 i=1, max_bw*( max_bw+2 )
882 CALL zcopy( du_p_n, b( 1 ), 1,
883 $ work( max_bw*max_bw+1 ), 1)
887 CALL ztrrv2d(ictxt,
'L',
'N',
889 $ work( 1 ), max_bw, myrow, mycol-1 )
896 $ work( max_bw*max_bw+1 ), 1 )
900 IF( du_p_n .GT. 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 zgesd2d( ictxt, bwl, 1, work(max_bw*max_bw+1 ),
909 $ bwl, myrow, mycol-1 )
913 CALL zgerv2d( ictxt, bwu, 1, work( max_bw*max_bw+1 ),
914 $ bwu, myrow, mycol-1 )
918 CALL zaxpy( bwu, cone,
919 $ work( max_bw*max_bw+1 ), 1,
926 IF( mycol .LT. npcol-1 )
THEN
930 CALL zgerv2d( ictxt, bwl, 1, work( max_bw*max_bw+1 ),
931 $ bwl, myrow, mycol+1 )
935 CALL zaxpy( bwl, cone,
936 $ work( max_bw*max_bw+1 ), 1,
937 $ x( numroc_size-bwl+1 ), 1)
949 IF( ictxt_save .NE. ictxt_new )
THEN