1 SUBROUTINE pcgbtrs( TRANS, N, BWL, BWU, NRHS, A, JA, DESCA, IPIV,
2 $ B, IB, DESCB, AF, LAF, WORK, LWORK, INFO )
10 INTEGER BWU, BWL, IB, INFO, JA, LAF, LWORK, N, NRHS
13 INTEGER DESCA( * ), DESCB( * ), IPIV(*)
14 COMPLEX A( * ), AF( * ), B( * ), WORK( * )
373 parameter( one = 1.0e+0 )
374 parameter( zero = 0.0e+0 )
376 parameter( cone = ( 1.0e+0, 0.0e+0 ) )
377 PARAMETER ( czero = ( 0.0e+0, 0.0e+0 ) )
379 parameter( int_one = 1 )
380 INTEGER DESCMULT, BIGNUM
381 parameter( descmult = 100, bignum = descmult*descmult )
382 INTEGER BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
383 $ lld_, mb_, m_, nb_, n_, rsrc_
384 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
385 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
386 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
390 $ first_proc, ictxt, ictxt_new, ictxt_save,
391 $ idum2, idum3, j, ja_new, l, lbwl, lbwu, ldbb,
392 $ ldw, llda, lldb, lm, lmj, ln, lptr, mycol,
393 $ myrow, nb, neicol, np, npact, npcol, nprow,
394 $ npstr, np_save, odd_size, part_offset,
395 $ recovery_val, return_code, store_m_b,
396 $ store_n_a, work_size_min, wptr
399 INTEGER DESCA_1XP( 7 ), DESCB_PX1( 7 ),
400 $ param_check( 17, 3 )
430 IF( return_code .NE. 0)
THEN
431 info = -( 8*100 + 2 )
436 IF( return_code .NE. 0)
THEN
437 info = -( 11*100 + 2 )
443 IF( desca_1xp( 2 ) .NE. descb_px1( 2 ) )
THEN
444 info = -( 11*100 + 2 )
451 IF( desca_1xp( 4 ) .NE. descb_px1( 4 ) )
THEN
452 info = -( 11*100 + 4 )
457 IF( desca_1xp( 5 ) .NE. descb_px1( 5 ) )
THEN
458 info = -( 11*100 + 5 )
463 ictxt = desca_1xp( 2 )
464 csrc = desca_1xp( 5 )
466 llda = desca_1xp( 6 )
467 store_n_a = desca_1xp( 3 )
468 lldb = descb_px1( 6 )
469 store_m_b = descb_px1( 3 )
479 IF( lsame( trans,
'N' ) )
THEN
481 ELSE IF ( lsame( trans,
'C' ) )
THEN
487 IF( lwork .LT. -1)
THEN
489 ELSE IF ( lwork .EQ. -1 )
THEN
499 IF( n+ja-1 .GT. store_n_a )
THEN
500 info = -( 8*100 + 6 )
503 IF(( bwl .GT. n-1 ) .OR.
504 $ ( bwl .LT. 0 ) )
THEN
508 IF(( bwu .GT. n-1 ) .OR.
509 $ ( bwu .LT. 0 ) )
THEN
513 IF( llda .LT. (2*bwl+2*bwu+1) )
THEN
518 info = -( 8*100 + 4 )
523 IF( n+ib-1 .GT. store_m_b )
THEN
524 info = -( 11*100 + 3 )
527 IF( lldb .LT. nb )
THEN
528 info = -( 11*100 + 6 )
531 IF( nrhs .LT. 0 )
THEN
543 IF( nprow .NE. 1 )
THEN
547 IF( n .GT. np*nb-mod( ja-1, nb ))
THEN
550 $ '
pcgbtrs, d&c alg.: only 1 block per proc
',
555.GT..AND..LT.
IF((JA+N-1NB) ( NB(BWL+BWU+1) )) THEN
558 $ 'pcgbtrs, d&c alg.: nb too small
',
566 WORK_SIZE_MIN = NRHS*(NB+2*BWL+4*BWU)
568 WORK( 1 ) = WORK_SIZE_MIN
570.LT.
IF( LWORK WORK_SIZE_MIN ) THEN
571.NE.
IF( LWORK -1 ) THEN
582 PARAM_CHECK( 17, 1 ) = DESCB(5)
583 PARAM_CHECK( 16, 1 ) = DESCB(4)
584 PARAM_CHECK( 15, 1 ) = DESCB(3)
585 PARAM_CHECK( 14, 1 ) = DESCB(2)
586 PARAM_CHECK( 13, 1 ) = DESCB(1)
587 PARAM_CHECK( 12, 1 ) = IB
588 PARAM_CHECK( 11, 1 ) = DESCA(5)
589 PARAM_CHECK( 10, 1 ) = DESCA(4)
590 PARAM_CHECK( 9, 1 ) = DESCA(3)
591 PARAM_CHECK( 8, 1 ) = DESCA(1)
592 PARAM_CHECK( 7, 1 ) = JA
593 PARAM_CHECK( 6, 1 ) = NRHS
594 PARAM_CHECK( 5, 1 ) = BWU
595 PARAM_CHECK( 4, 1 ) = BWL
596 PARAM_CHECK( 3, 1 ) = N
597 PARAM_CHECK( 2, 1 ) = IDUM3
598 PARAM_CHECK( 1, 1 ) = IDUM2
600 PARAM_CHECK( 17, 2 ) = 1105
601 PARAM_CHECK( 16, 2 ) = 1104
602 PARAM_CHECK( 15, 2 ) = 1103
603 PARAM_CHECK( 14, 2 ) = 1102
604 PARAM_CHECK( 13, 2 ) = 1101
605 PARAM_CHECK( 12, 2 ) = 10
606 PARAM_CHECK( 11, 2 ) = 805
607 PARAM_CHECK( 10, 2 ) = 804
608 PARAM_CHECK( 9, 2 ) = 803
609 PARAM_CHECK( 8, 2 ) = 801
610 PARAM_CHECK( 7, 2 ) = 7
611 PARAM_CHECK( 6, 2 ) = 5
612 PARAM_CHECK( 5, 2 ) = 4
613 PARAM_CHECK( 4, 2 ) = 3
614 PARAM_CHECK( 3, 2 ) = 2
615 PARAM_CHECK( 2, 2 ) = 16
616 PARAM_CHECK( 1, 2 ) = 1
624.LT.
ELSE IF( INFO-DESCMULT ) THEN
627 INFO = -INFO * DESCMULT
632 CALL GLOBCHK( ICTXT, 17, PARAM_CHECK, 17,
633 $ PARAM_CHECK( 1, 3 ), INFO )
638.EQ.
IF( INFOBIGNUM ) THEN
640.EQ.
ELSE IF( MOD( INFO, DESCMULT ) 0 ) THEN
641 INFO = -INFO / DESCMULT
647 CALL PXERBLA( ICTXT, 'pcgbtrs', -INFO )
663 PART_OFFSET = NB*( (JA-1)/(NPCOL*NB) )
665.LT.
IF ( (MYCOL-CSRC) (JA-PART_OFFSET-1)/NB ) THEN
666 PART_OFFSET = PART_OFFSET + NB
669.LT.
IF ( MYCOL CSRC ) THEN
670 PART_OFFSET = PART_OFFSET - NB
679 FIRST_PROC = MOD( ( JA-1 )/NB+CSRC, NPCOL )
683 JA_NEW = MOD( JA-1, NB ) + 1
688 NP = ( JA_NEW+N-2 )/NB + 1
692 CALL RESHAPE( ICTXT, INT_ONE, ICTXT_NEW, INT_ONE,
693 $ FIRST_PROC, INT_ONE, NP )
699 DESCA_1XP( 2 ) = ICTXT_NEW
700 DESCB_PX1( 2 ) = ICTXT_NEW
704 CALL BLACS_GRIDINFO( ICTXT, NPROW, NPCOL, MYROW, MYCOL )
708.LT.
IF( MYROW 0 ) THEN
718.LT.
IF (MYCOL NPCOL-1) THEN
719 CALL CGESD2D( ICTXT, BWU, NRHS, B(NB-BWU+1), LLDB,
723.LT.
IF (MYCOL NPCOL-1) THEN
729.GT.
IF (MYCOL 0) THEN
735 LDW = NB+BWU + 2*BW+BWU
737 CALL CLAMOV( 'g
', LM, NRHS, B(1), LLDB, WORK( WPTR ), LDW )
742 DO 1502 L=WPTR+LM, LDW
743 WORK( (J-1)*LDW+L ) = CZERO
747.GT.
IF (MYCOL 0) THEN
748 CALL CGERV2D( ICTXT, BWU, NRHS, WORK(1), LDW,
758 ODD_SIZE = NUMROC( N, NB, MYCOL, 0, NPCOL )
760.NE.
IF (MYCOL 0) THEN
770.NE.
IF (MYCOL NPCOL-1) THEN
773.NE.
ELSE IF (MYCOL 0) THEN
775 LN = MAX(ODD_SIZE-BW,0)
787 CALL CSWAP(NRHS, WORK(L), LDW, WORK(J), LDW)
790 LPTR = BW+1 + (J-1)*LLDA + APTR
792 CALL CGERU(LMJ,NRHS,-CONE, A(LPTR),1, WORK(J),LDW,
804.NE.
IF (MYCOL NPCOL-1) THEN
808 BM = MIN(BW,ODD_SIZE) + BWU
809 BN = MIN(BW,ODD_SIZE)
815 BBPTR = (NB+BWU)*BW + 1
822 CALL CGETRS( 'n
', N-LN, NRHS, AF(BBPTR+BW*LDBB), LDBB,
823 $ IPIV(LN+1), WORK( LN+1 ), LDW, INFO)
837.LE.
200 IF (NPACT 1) GOTO 300
840.EQ.
IF (MOD(MYCOL,NPSTR) 0) THEN
844.EQ.
IF (MOD(MYCOL,2*NPSTR) 0) THEN
846 NEICOL = MYCOL + NPSTR
848.LE.
IF (NEICOL/NPSTR NPACT-1) THEN
850.LT.
IF (NEICOL/NPSTR NPACT-1) THEN
853 BMN = MIN(BW,NUMROC(N, NB, NEICOL, 0, NPCOL))+BWU
856 CALL CGESD2D( ICTXT, BM, NRHS,
857 $ WORK(LN+1), LDW, 0, NEICOL )
859.NE.
IF( NPACT 2 )THEN
863 CALL CGERV2D(ICTXT, BM+BMN-BW, NRHS,
864 $ WORK( LN+1 ), LDW, 0, NEICOL )
874 NEICOL = MYCOL - NPSTR
876.EQ.
IF (NEICOL 0) THEN
882 CALL CLAMOV( 'g
', BM, NRHS, WORK(LN+1), LDW,
883 $ WORK(NB+BWU+BMN+1), LDW )
885 CALL CGERV2D( ICTXT, BMN, NRHS, WORK( NB+BWU+1 ),
890.NE.
IF (NPACT 2) THEN
894 CALL CLASWP( NRHS, WORK(NB+BWU+1), LDW, 1, BW,
897 CALL CTRSM('l
','l
','n
','u
', BW, NRHS, CONE,
898 $ AF(BBPTR+BW*LDBB), LDBB, WORK(NB+BWU+1), LDW)
902 CALL CGEMM( 'n
', 'n
', BM+BMN-BW, NRHS, BW,
903 $ -CONE, AF(BBPTR+BW*LDBB+BW), LDBB,
904 $ WORK(NB+BWU+1), LDW,
905 $ CONE, WORK(NB+BWU+1+BW), LDW )
909 CALL CGESD2D( ICTXT, BM+BMN-BW, NRHS,
910 $ WORK(NB+BWU+1+BW), LDW, 0, NEICOL )
916 CALL CLASWP( NRHS, WORK(NB+BWU+1), LDW, 1, BM+BMN,
919 CALL CTRSM('l
','l
','n
','u
', BM+BMN, NRHS, CONE,
920 $ AF(BBPTR+BW*LDBB), LDBB, WORK(NB+BWU+1), LDW)
925 NPACT = (NPACT + 1)/2
952 RECOVERY_VAL = NPACT*NPSTR - NPCOL
957.GE.
2200 IF( NPACT NPCOL ) GOTO 2300
965 NPACT = NPACT-MOD( (RECOVERY_VAL/NPSTR), 2 )
969.LT.
IF( MYCOL/NPSTR NPACT-1 ) THEN
972 BN = MIN(BW, NUMROC(N, NB, NPCOL-1, 0, NPCOL) )
977.EQ.
IF( MOD( MYCOL, 2*NPSTR ) 0 ) THEN
981.LE.
IF( NEICOL/NPSTR NPACT-1 ) THEN
983.LT.
IF( NEICOL/NPSTR NPACT-1 ) THEN
987 BMN = MIN(BW,NUMROC(N, NB, NEICOL, 0, NPCOL))+BWU
988 BNN = MIN(BW, NUMROC(N, NB, NEICOL, 0, NPCOL) )
991.GT.
IF( NPACT 2 ) THEN
993 CALL CGESD2D( ICTXT, 2*BW, NRHS, WORK( LN+1 ),
996 CALL CGERV2D( ICTXT, BW, NRHS, WORK( LN+1 ),
1001 CALL CGERV2D( ICTXT, BW, NRHS, WORK( LN+1 ),
1011 NEICOL = MYCOL - NPSTR
1013.EQ.
IF (NEICOL 0) THEN
1019.LT.
IF( NEICOL NPCOL-1 ) THEN
1022 BNN = MIN(BW, NUMROC(N, NB, NEICOL, 0, NPCOL) )
1025.GT.
IF( NPACT 2 ) THEN
1029 CALL CLAMOV( 'g
', BW, NRHS, WORK(NB+BWU+1),
1030 $ LDW, WORK(NB+BWU+BW+1), LDW )
1032 CALL CGERV2D( ICTXT, 2*BW, NRHS, WORK( LN+1 ),
1035 CALL CGEMM( 'n
', 'n
', BW, NRHS, BN,
1036 $ -CONE, AF(BBPTR), LDBB,
1038 $ CONE, WORK(NB+BWU+BW+1), LDW )
1041.GT.
IF( MYCOL NPSTR ) THEN
1043 CALL CGEMM( 'n
', 'n
', BW, NRHS, BW,
1044 $ -CONE, AF(BBPTR+2*BW*LDBB), LDBB,
1045 $ WORK(LN+BW+1), LDW,
1046 $ CONE, WORK(NB+BWU+BW+1), LDW )
1050 CALL CTRSM('l
','u
','n
','n
', BW, NRHS, CONE,
1051 $ AF(BBPTR+BW*LDBB), LDBB, WORK(NB+BWU+BW+1), LDW)
1055 CALL CGESD2D( ICTXT, BW, NRHS,
1056 $ WORK( NB+BWU+BW+1 ), LDW, 0, NEICOL )
1060 CALL CLAMOV( 'g', bw, nrhs, work(nb+bwu+1+bw),
1061 $ ldw, work(ln+bw+1), ldw )
1067 CALL ctrsm(
'L',
'U',
'N',
'N', bn+bnn, nrhs, cone,
1068 $ af(bbptr+bw*ldbb), ldbb, work(nb+bwu+1), ldw)
1072 CALL cgesd2d( ictxt, bw, nrhs,
1073 $ work(nb+bwu+1), ldw, 0, neicol )
1077 CALL clamov(
'G', bnn+bn-bw, nrhs, work(nb+bwu+1+bw),
1078 $ ldw, work(ln+1), ldw )
1086 CALL ccopy( nrhs, work(nb+bwu+j), ldw,
1087 $ work(ln+bw+j), ldw )
1107 IF (mycol .NE. npcol-1)
THEN
1110 bm =
min(bw,odd_size) + bwu
1115 IF( mycol .LT. npcol-1 )
THEN
1117 CALL cgesd2d( ictxt, bw, nrhs, work( nb-bw+1 ),
1122 IF( mycol .GT. 0 )
THEN
1124 CALL cgerv2d( ictxt, bw, nrhs, work( nb+bwu+1 ),
1129 CALL cgemm(
'N',
'N'
1130 $ af( 1 ), lm, work( nb+bwu+1 ), ldw, cone,
1135 DO 2021 j = ln, 1, -1
1137 lmj =
min( bw, odd_size-1 )
1139 lptr = bw-1+j*llda+aptr
1144 CALL cgemv(
'T', lmj, nrhs, -cone, work( j+1), ldw,
1145 $ a( lptr ), llda-1, cone, work( j ), ldw )
1149 CALL cscal( nrhs, cone/a( lptr-llda+1 ),
1155 CALL clamov(
'G', odd_size, nrhs, work( 1 ), ldw,
1161 IF( ictxt .NE. ictxt_new )
THEN
1173 work( 1 ) = work_size_min