1 SUBROUTINE pdgbtrs( TRANS, N, BWL, BWU, NRHS, A, JA, DESCA, IPIV,
2 $ B, IB, DESCB, AF, LAF, WORK, LWORK, INFO )
10 INTEGER BWL, BWU, IB, INFO, JA, , LWORK, N, NRHS
13 INTEGER DESCA( * ), ( * ), IPIV( * )
14 DOUBLE PRECISION A( * ), AF( * ), B( * ), WORK( * )
369 parameter( one = 1.0d+0 )
370 DOUBLE PRECISION ZERO
371 parameter( zero = 0.0d+0 )
373 parameter( int_one = 1 )
374 INTEGER DESCMULT, BIGNUM
375 parameter( descmult = 100, bignum = descmult*descmult )
376 INTEGER BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
377 $ lld_, mb_, m_, nb_, n_, rsrc_
378 PARAMETER ( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
379 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
380 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
383 INTEGER APTR, BBPTR, BM, BMN, BN, BNN, BW, CSRC,
384 $ first_proc, ictxt, ictxt_new, ictxt_save,
385 $ idum2, idum3, j, ja_new, l, lbwl, lbwu, ldbb,
386 $ ldw, llda, lldb, lm, lmj, ln, lptr, mycol,
387 $ myrow, nb, neicol, np, npact, npcol, nprow,
388 $ npstr, np_save, odd_size, part_offset,
389 $ recovery_val, return_code, store_m_b,
390 $ store_n_a, work_size_min, wptr
393 INTEGER DESCA_1XP( 7 ), DESCB_PX1( 7 ),
394 $ param_check( 17, 3 )
405 EXTERNAL lsame, numroc
408 INTRINSIC ichar,
max,
min, mod
425 IF( return_code.NE.0 )
THEN
431 IF( return_code.NE.0 )
THEN
438 IF( desca_1xp( 2 ).NE.descb_px1( 2 ) )
THEN
446 IF( desca_1xp( 4 ).NE.descb_px1( 4 ) )
THEN
452 IF( desca_1xp( 5 ).NE.descb_px1( 5 ) )
THEN
458 ictxt = desca_1xp( 2 )
459 csrc = desca_1xp( 5 )
461 llda = desca_1xp( 6 )
462 store_n_a = desca_1xp( 3 )
463 lldb = descb_px1( 6 )
464 store_m_b = descb_px1( 3 )
474 IF( lsame( trans,
'N' ) )
THEN
476 ELSE IF( lsame( trans,
'T' ) )
THEN
478 ELSE IF( LSAME( TRANS, 'c
' ) ) THEN
484.LT.
IF( LWORK-1 ) THEN
486.EQ.
ELSE IF( LWORK-1 ) THEN
496.GT.
IF( N+JA-1STORE_N_A ) THEN
500.GT..OR..LT.
IF( ( BWLN-1 ) ( BWL0 ) ) THEN
504.GT..OR..LT.
IF( ( BWUN-1 ) ( BWU0 ) ) THEN
508.LT.
IF( LLDA( 2*BWL+2*BWU+1 ) ) THEN
518.GT.
IF( N+IB-1STORE_M_B ) THEN
522.LT.
IF( LLDBNB ) THEN
538.NE.
IF( NPROW1 ) THEN
542.GT.
IF( NNP*NB-MOD( JA-1, NB ) ) THEN
544 CALL PXERBLA( ICTXT, 'pdgbtrs, d&c alg.: only 1 block per proc
'
549.GT..AND..LT.
IF( ( JA+N-1NB ) ( NB( BWL+BWU+1 ) ) ) THEN
551 CALL PXERBLA( ICTXT, 'pdgbtrs, d&c alg.: nb too small
', -INFO )
558 WORK_SIZE_MIN = NRHS*( NB+2*BWL+4*BWU )
560 WORK( 1 ) = WORK_SIZE_MIN
562.LT.
IF( LWORKWORK_SIZE_MIN ) THEN
563.NE.
IF( LWORK-1 ) THEN
565 CALL PXERBLA( ICTXT, 'pdgbtrs: worksize error
', -INFO )
572 PARAM_CHECK( 17, 1 ) = DESCB( 5 )
573 PARAM_CHECK( 16, 1 ) = DESCB( 4 )
574 PARAM_CHECK( 15, 1 ) = DESCB( 3 )
575 PARAM_CHECK( 14, 1 ) = DESCB( 2 )
576 PARAM_CHECK( 13, 1 ) = DESCB( 1 )
577 PARAM_CHECK( 12, 1 ) = IB
578 PARAM_CHECK( 11, 1 ) = DESCA( 5 )
579 PARAM_CHECK( 10, 1 ) = DESCA( 4 )
580 PARAM_CHECK( 9, 1 ) = DESCA( 3 )
581 PARAM_CHECK( 8, 1 ) = DESCA( 1 )
582 PARAM_CHECK( 7, 1 ) = JA
583 PARAM_CHECK( 6, 1 ) = NRHS
584 PARAM_CHECK( 5, 1 ) = BWU
585 PARAM_CHECK( 4, 1 ) = BWL
586 PARAM_CHECK( 3, 1 ) = N
587 PARAM_CHECK( 2, 1 ) = IDUM3
588 PARAM_CHECK( 1, 1 ) = IDUM2
590 PARAM_CHECK( 17, 2 ) = 1105
591 PARAM_CHECK( 16, 2 ) = 1104
592 PARAM_CHECK( 15, 2 ) = 1103
593 PARAM_CHECK( 14, 2 ) = 1102
594 PARAM_CHECK( 13, 2 ) = 1101
595 PARAM_CHECK( 12, 2 ) = 10
596 PARAM_CHECK( 11, 2 ) = 805
597 PARAM_CHECK( 10, 2 ) = 804
598 PARAM_CHECK( 9, 2 ) = 803
599 PARAM_CHECK( 8, 2 ) = 801
600 PARAM_CHECK( 7, 2 ) = 7
601 PARAM_CHECK( 6, 2 ) = 5
602 PARAM_CHECK( 5, 2 ) = 4
603 PARAM_CHECK( 4, 2 ) = 3
604 PARAM_CHECK( 3, 2 ) = 2
605 PARAM_CHECK( 2, 2 ) = 16
606 PARAM_CHECK( 1, 2 ) = 1
614.LT.
ELSE IF( INFO-DESCMULT ) THEN
617 INFO = -INFO*DESCMULT
622 CALL GLOBCHK( ICTXT, 17, PARAM_CHECK, 17, PARAM_CHECK( 1, 3 ),
628.EQ.
IF( INFOBIGNUM ) THEN
630.EQ.
ELSE IF( MOD( INFO, DESCMULT )0 ) THEN
631 INFO = -INFO / DESCMULT
637 CALL PXERBLA( ICTXT, 'pdgbtrs', -INFO )
653 PART_OFFSET = NB*( ( JA-1 ) / ( NPCOL*NB ) )
655.LT.
IF( ( MYCOL-CSRC )( JA-PART_OFFSET-1 ) / NB ) THEN
656 PART_OFFSET = PART_OFFSET + NB
659.LT.
IF( MYCOLCSRC ) THEN
660 PART_OFFSET = PART_OFFSET - NB
669 FIRST_PROC = MOD( ( JA-1 ) / NB+CSRC, NPCOL )
673 JA_NEW = MOD( JA-1, NB ) + 1
678 NP = ( JA_NEW+N-2 ) / NB + 1
682 CALL RESHAPE( ICTXT, INT_ONE, ICTXT_NEW, INT_ONE, FIRST_PROC,
689 DESCA_1XP( 2 ) = ICTXT_NEW
690 DESCB_PX1( 2 ) = ICTXT_NEW
694 CALL BLACS_GRIDINFO( ICTXT, NPROW, NPCOL, MYROW, MYCOL )
698.LT.
IF( MYROW0 ) THEN
708.LT.
IF( MYCOLNPCOL-1 ) THEN
709 CALL DGESD2D( ICTXT, BWU, NRHS, B( NB-BWU+1 ), LLDB, 0,
713.LT.
IF( MYCOLNPCOL-1 ) THEN
719.GT.
IF( MYCOL0 ) THEN
725 LDW = NB + BWU + 2*BW + BWU
727 CALL DLAMOV( 'g
', LM, NRHS, B( 1 ), LLDB, WORK( WPTR ), LDW )
732 DO 10 L = WPTR + LM, LDW
733 WORK( ( J-1 )*LDW+L ) = ZERO
737.GT.
IF( MYCOL0 ) THEN
738 CALL DGERV2D( ICTXT, BWU, NRHS, WORK( 1 ), LDW, 0, MYCOL-1 )
747 ODD_SIZE = NUMROC( N, NB, MYCOL, 0, NPCOL )
749.NE.
IF( MYCOL0 ) THEN
759.NE.
IF( MYCOLNPCOL-1 ) THEN
762.NE.
ELSE IF( MYCOL0 ) THEN
764 LN = MAX( ODD_SIZE-BW, 0 )
772 LMJ = MIN( LBWL, LM-J )
776 CALL DSWAP( NRHS, WORK( L ), LDW, WORK( J ), LDW )
779 LPTR = BW + 1 + ( J-1 )*LLDA + APTR
781 CALL DGER( LMJ, NRHS, -ONE, A( LPTR ), 1, WORK( J ), LDW,
793.NE.
IF( MYCOLNPCOL-1 ) THEN
797 BM = MIN( BW, ODD_SIZE ) + BWU
798 BN = MIN( BW, ODD_SIZE )
804 BBPTR = ( NB+BWU )*BW + 1
807.EQ.
IF( NPCOL1 ) THEN
811 CALL DGETRS( 'n
', N-LN, NRHS, AF( BBPTR+BW*LDBB ), LDBB,
812 $ IPIV( LN+1 ), WORK( LN+1 ), LDW, INFO )
831.EQ.
IF( MOD( MYCOL, NPSTR )0 ) THEN
835.EQ.
IF( MOD( MYCOL, 2*NPSTR )0 ) THEN
837 NEICOL = MYCOL + NPSTR
839.LE.
IF( NEICOL / NPSTRNPACT-1 ) THEN
841.LT.
IF( NEICOL / NPSTRNPACT-1 ) THEN
844 BMN = MIN( BW, NUMROC( N, NB, NEICOL, 0, NPCOL ) ) +
848 CALL DGESD2D( ICTXT, BM, NRHS, WORK( LN+1 ), LDW, 0,
851.NE.
IF( NPACT2 ) THEN
855 CALL DGERV2D( ICTXT, BM+BMN-BW, NRHS, WORK( LN+1 ),
866 NEICOL = MYCOL - NPSTR
868.EQ.
IF( NEICOL0 ) THEN
874 CALL DLAMOV( 'g
', BM, NRHS, WORK( LN+1 ), LDW,
875 $ WORK( NB+BWU+BMN+1 ), LDW )
877 CALL DGERV2D( ICTXT, BMN, NRHS, WORK( NB+BWU+1 ), LDW, 0,
882.NE.
IF( NPACT2 ) THEN
886 CALL DLASWP( NRHS, WORK( NB+BWU+1 ), LDW, 1, BW,
889 CALL DTRSM( 'l
', 'l
', 'n
', 'u
', BW, NRHS, ONE,
890 $ AF( BBPTR+BW*LDBB ), LDBB, WORK( NB+BWU+1 ),
895 CALL DGEMM( 'n
', 'n
', BM+BMN-BW, NRHS, BW, -ONE,
896 $ AF( BBPTR+BW*LDBB+BW ), LDBB,
897 $ WORK( NB+BWU+1 ), LDW, ONE,
898 $ WORK( NB+BWU+1+BW ), LDW )
902 CALL DGESD2D( ICTXT, BM+BMN-BW, NRHS,
903 $ WORK( NB+BWU+1+BW ), LDW, 0, NEICOL )
909 CALL DLASWP( NRHS, WORK( NB+BWU+1 ), LDW, 1, BM+BMN,
912 CALL DTRSM( 'l
', 'l
', 'n
', 'u
', BM+BMN, NRHS, ONE,
913 $ AF( BBPTR+BW*LDBB ), LDBB, WORK( NB+BWU+1 ),
919 NPACT = ( NPACT+1 ) / 2
934.EQ.
IF( NPCOL1 ) THEN
946 RECOVERY_VAL = NPACT*NPSTR - NPCOL
961 NPACT = NPACT - MOD( ( RECOVERY_VAL / NPSTR ), 2 )
965.LT.
IF( MYCOL / NPSTRNPACT-1 ) THEN
968 BN = MIN( BW, NUMROC( N, NB, NPCOL-1, 0, NPCOL ) )
973.EQ.
IF( MOD( MYCOL, 2*NPSTR )0 ) THEN
975 NEICOL = MYCOL + NPSTR
977.LE.
IF( NEICOL / NPSTRNPACT-1 ) THEN
979.LT.
IF( NEICOL / NPSTRNPACT-1 ) THEN
983 BMN = MIN( BW, NUMROC( N, NB, NEICOL, 0, NPCOL ) ) + BWU
984 BNN = MIN( BW, NUMROC( N, NB, NEICOL, 0, NPCOL ) )
987.GT.
IF( NPACT2 ) THEN
989 CALL DGESD2D( ICTXT, 2*BW, NRHS, WORK( LN+1 ), LDW, 0,
992 CALL DGERV2D( ICTXT, BW, NRHS, WORK( LN+1 ), LDW, 0,
997 CALL DGERV2D( ICTXT, BW, NRHS, WORK( LN+1 ), LDW, 0,
1007 NEICOL = MYCOL - NPSTR
1009.EQ.
IF( NEICOL0 ) THEN
1015.LT.
IF( NEICOLNPCOL-1 ) THEN
1018 BNN = MIN( BW, NUMROC( N, NB, NEICOL, 0, NPCOL ) )
1021.GT.
IF( NPACT2 ) THEN
1025 CALL DLAMOV( 'g
', BW, NRHS, WORK( NB+BWU+1 ), LDW,
1026 $ WORK( NB+BWU+BW+1 ), LDW )
1028 CALL DGERV2D( ICTXT, 2*BW, NRHS, WORK( LN+1 ), LDW, 0,
1031 CALL DGEMM( 'n
', 'n
', BW, NRHS, BN, -ONE, AF( BBPTR ), LDBB,
1032 $ WORK( LN+1 ), LDW, ONE, WORK( NB+BWU+BW+1 ),
1036.GT.
IF( MYCOLNPSTR ) THEN
1038 CALL DGEMM( 'n
', 'n
', BW, NRHS, BW, -ONE,
1039 $ AF( BBPTR+2*BW*LDBB ), LDBB, WORK( LN+BW+1 ),
1040 $ LDW, ONE, WORK( NB+BWU+BW+1 ), LDW )
1044 CALL DTRSM( 'l
', 'u
', 'n
', 'n', bw, nrhs, one,
1045 $ af( bbptr+bw*ldbb ), ldbb, work( nb+bwu+bw+1 ),
1050 CALL dgesd2d( ictxt, bw, nrhs, work( nb+bwu+bw+1 ), ldw, 0,
1055 CALL dlamov(
'G', bw, nrhs, work( nb+bwu+1+bw ), ldw,
1056 $ work( ln+bw+1 ), ldw )
1062 CALL dtrsm(
'L',
'U',
'N',
'N', bn+bnn, nrhs, one,
1063 $ af( bbptr+bw*ldbb ), ldbb, work( nb+bwu+1 ),
1068 CALL dgesd2d( ictxt, bw, nrhs, work( nb+bwu+1 ), ldw, 0,
1073 CALL dlamov(
'G', bnn+bn-bw, nrhs, work( nb+bwu+1+bw ), ldw,
1074 $ work( ln+1 ), ldw )
1077 IF( ( nb+bwu+1 ).NE.( ln+1+bw ) )
THEN
1082 CALL dcopy( nrhs, work( nb+bwu+j ), ldw,
1083 $ work( ln+bw+j ), ldw )
1103 IF( mycol.NE.npcol-1 )
THEN
1106 bm =
min( bw, odd_size ) + bwu
1111 IF( mycol.LT.npcol-1 )
THEN
1113 CALL dgesd2d( ictxt, bw, nrhs, work( nb-bw+1 ), ldw, 0,
1118 IF( mycol.GT.0 )
THEN
1120 CALL dgerv2d( ictxt, bw, nrhs, work( nb+bwu+1 ), ldw, 0,
1125 CALL dgemm(
'T',
'N', lm-bm, nrhs, bw, -one, af( 1 ), bw,
1126 $ work( nb+bwu+1 ), ldw, one, work( 1 ), ldw )
1132 lmj =
min( bw, odd_size-1 )
1134 lptr = bw - 1 + j*llda + aptr
1139 CALL dgemv(
'T', lmj, nrhs, -one, work( j+1 ), ldw, a( lptr ),
1140 $ llda-1, one, work( j ), ldw )
1144 CALL dscal( nrhs, one / a( lptr-llda+1 ), work( j ), ldw )
1149 CALL dlamov(
'G', odd_size, nrhs, work( 1 ), ldw, b( 1 ), lldb )
1154 IF( ictxt.NE.ictxt_new )
THEN
1166 work( 1 ) = work_size_min