1 SUBROUTINE pzgbtrf( N, BWL, BWU, A, JA, DESCA, IPIV, AF, LAF,
9 INTEGER BWL, BWU, INFO, JA, LAF, LWORK, N
12 INTEGER DESCA( * ), IPIV( * )
13 COMPLEX*16 A( * ), AF( * ), WORK( * )
357 DOUBLE PRECISION ONE, ZERO
358 parameter( one = 1.0d+0 )
359 parameter( zero = 0.0d+0 )
360 COMPLEX*16 CONE, CZERO
361 parameter( cone = ( 1.0d+0, 0.0d+0 ) )
362 parameter( czero = ( 0.0d+0, 0.0d+0 ) )
364 parameter( int_one = 1 )
365 INTEGER DESCMULT, BIGNUM
366 parameter( descmult = 100, bignum = descmult*descmult )
367 INTEGER BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
368 $ lld_, mb_, m_, nb_, n_, rsrc_
369 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
370 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
371 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
374 INTEGER APTR, BBPTR, BIPTR, BM, BM1, BM2, BMN, BN, BW,
375 $ csrc, dbptr, first_proc, i, ictxt, ictxt_new,
376 $ ictxt_save, idum3, j, ja_new, jptr, l, laf_min,
377 $ lbwl, lbwu, ldb, ldbb, llda, lm, lmj, ln, lnj,
378 $ lptr, mycol, myrow, my_num_cols, nb, neicol,
379 $ np, npact, npcol, nprow, npstr, np_save, nrhs,
380 $ odd_n, odd_size, odptr, ofst, part_offset,
381 $ part_size, return_code, store_n_a,
385 INTEGER DESCA_1XP( 7 ), PARAM_CHECK( 9, 3 )
390 $ zgerv2d, zgesd2d, zlamov,
zlatcpy, zpbtrf,
391 $ zpotrf, zsyrk, ztbtrs, ztrmm, ztrrv2d, ztrsd2d,
397 EXTERNAL lsame, numroc
400 INTRINSIC ichar,
min, mod
416 IF( return_code .NE. 0)
THEN
417 info = -( 6*100 + 2 )
422 ictxt = desca_1xp( 2 )
423 csrc = desca_1xp( 5 )
425 llda = desca_1xp( 6 )
426 store_n_a = desca_1xp( 3 )
431 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
436 IF( lwork .LT. -1)
THEN
438 ELSE IF ( lwork .EQ. -1 )
THEN
448 IF( n+ja-1 .GT. store_n_a )
THEN
449 info = -( 6*100 + 6 )
452 IF(( bwl .GT. n-1 ) .OR.
453 $ ( bwl .LT. 0 ) )
THEN
457 IF(( bwu .GT. n-1 ) .OR.
458 $ ( bwu .LT. 0 ) )
THEN
462 IF( llda .LT. (2*bwl+2*bwu+1) )
THEN
463 info = -( 6*100 + 6 )
467 info = -( 6*100 + 4 )
474 IF( nprow .NE. 1 )
THEN
478 IF( n .GT. np*nb-mod( ja-1, nb ))
THEN
481 $
'PZGBTRF, D&C alg.: only 1 block per proc',
486 IF((ja+n-1.GT.nb) .AND. ( nb.LT.(bwl+bwu+1) ))
THEN
489 $
'PZGBTRF, D&C alg.: NB too small',
497 laf_min = (nb+bwu)*(bwl+bwu)+6*(bwl+bwu)*(bwl+2*bwu)
499 IF( laf .LT. laf_min )
THEN
504 $
'PZGBTRF: auxiliary storage error ',
513 work( 1 ) = work_size_min
515 IF( lwork .LT. work_size_min )
THEN
516 IF( lwork .NE. -1 )
THEN
519 work( 1 ) = work_size_min
521 $
'PZGBTRF: worksize error ',
529 param_check( 9, 1 ) = desca(5)
530 param_check( 8, 1 ) = desca(4)
531 param_check( 7, 1 ) = desca(3)
532 param_check( 6, 1 ) = desca(1)
533 param_check( 5, 1 ) = ja
534 param_check( 4, 1 ) = bwu
535 param_check( 3, 1 ) = bwl
536 param_check( 2, 1 ) = n
537 param_check( 1, 1 ) = idum3
539 param_check( 9, 2 ) = 605
540 param_check( 8, 2 ) = 604
541 param_check( 7, 2 ) = 603
542 param_check( 6, 2 ) = 601
543 param_check( 5, 2 ) = 5
544 param_check( 4, 2 ) = 3
545 param_check( 3, 2 ) = 2
546 param_check( 2, 2 ) = 1
547 param_check( 1, 2 ) = 11
555 ELSE IF( info.LT.-descmult )
THEN
558 info = -info * descmult
563 CALL globchk( ictxt, 9, param_check, 9,
564 $ param_check( 1, 3 ), info )
569 IF( info.EQ.bignum )
THEN
571 ELSE IF( mod( info, descmult ) .EQ. 0 )
THEN
572 info = -info / descmult
578 CALL pxerbla( ictxt,
'PZGBTRF', -info )
591 part_offset = nb*( (ja-1)/(npcol*nb) )
593 IF ( (mycol-csrc) .LT. (ja-part_offset-1)/nb )
THEN
594 part_offset = part_offset + nb
597 IF ( mycol .LT. csrc )
THEN
598 part_offset = part_offset - nb
607 first_proc = mod( ( ja-1 )/nb+csrc, npcol )
611 ja_new = mod( ja-1, nb ) + 1
616 np = ( ja_new+n-2 )/nb + 1
620 CALL reshape( ictxt, int_one, ictxt_new, int_one,
621 $ first_proc, int_one, np )
627 desca_1xp( 2 ) = ictxt_new
631 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
635 IF( myrow .LT. 0 )
THEN
648 my_num_cols = numroc( n, part_size, mycol, 0, npcol )
652 IF ( mycol .EQ. 0 )
THEN
653 part_offset = part_offset+mod( ja_new-1, part_size )
654 my_num_cols = my_num_cols - mod(ja_new-1, part_size )
659 ofst = part_offset*llda
663 odd_size = numroc( n, part_size, mycol, 0, npcol )
674 a( i+(j-1)*llda ) = czero
688 IF (mycol .LE. npcol-2)
THEN
692 biptr = (nb-bw)*llda + 2*bw+1
694 CALL ztrsd2d( ictxt,
'U',
'N',
695 $
min( bw, bwu+numroc( n, nb, mycol+1, 0, npcol ) ),
696 $ bw, a(biptr), llda-1, 0, mycol+1)
711 IF (mycol .NE. 0)
THEN
721 IF (mycol .NE. npcol-1)
THEN
724 ELSE IF (mycol .NE. 0)
THEN
726 ln =
max(odd_size-bw,0)
734 CALL zgbtrf(lm,ln, lbwl,lbwu, a(aptr),llda, ipiv, info)
737 info = info + nb*mycol
749 DO 23 j =
max(ln-bw+1,1), ln
751 lmj =
min( lbwl, lm-j )
752 lnj =
min( bw, j+bw-ln+aptr-1 )
756 jptr = j-(ln+1)+2*bw+1-lbwl + ln*llda
765 lptr = l-(ln+1)+2*bw+1-lbwl + ln*llda
767 CALL zswap( lnj, a(lptr),ldb, a(jptr), ldb )
774 lptr = bw+1+aptr + (j-1)*llda
776 CALL zgeru(lmj,lnj,-cone, a(lptr),1, a(jptr),ldb,
786 IF (mycol .GT. 0)
THEN
788 CALL ztrrv2d( ictxt,
'U',
'N',
min(bw, lm), bw, af( 1 ),
796 lmj =
min( lbwl, lm-j )
801 CALL zswap(nrhs, af(l), lm, af(j), lm )
804 lptr = bw+1+aptr + (j-1)*llda
806 CALL zgeru( lmj,nrhs, -cone, a(lptr),1,
807 $ af(j), lm, af(j+1), lm)
822 IF (mycol .NE. npcol-1)
THEN
826 bm =
min(bw,odd_size) + bwu
827 bn =
min(bw,odd_size)
833 bbptr = (nb+bwu)*bw + 1
839 dbptr = bw+1 + lbwu + ln*llda
841 CALL zlamov(
'G',bm,bn, a(dbptr),llda-1,
842 $ af(bbptr + bw*ldbb),ldbb)
847 DO 880 i=j+lbwl, bm-1
848 af( bbptr+bw*ldbb+(j-1)*ldbb+i ) = czero
852 IF (mycol .NE. 0)
THEN
857 CALL zlamov(
'G',bm,bw, af(odptr),lm,
858 $ af(bbptr +2*bw*ldbb),ldbb)
865 CALL zgetrf( n-ln, n-ln, af(bbptr+bw*ldbb), ldbb,
881 200
IF (npact .LE. 1)
GOTO 300
885 IF (mod(mycol,npstr) .EQ. 0)
THEN
890 IF (mod(mycol,2*npstr) .EQ. 0)
THEN
894 neicol = mycol + npstr
896 IF (neicol/npstr .LT. npact-1)
THEN
898 ELSE IF (neicol/npstr .EQ. npact-1)
THEN
899 odd_n = numroc(n, nb, npcol-1, 0, npcol)
900 bmn =
min(bw,odd_n) + bwu
912 IF (neicol/npstr .LE. npact-1 )
THEN
914 CALL zgesd2d( ictxt, bm, 2*bw, af(bbptr+bw*ldbb),
917 CALL zgerv2d( ictxt, bmn, 2*bw, af(bbptr+bm),
920 IF( npact .EQ. 2 )
THEN
924 CALL zlamov(
'G', bmn, bw, af( bbptr+bm ),
925 $ ldbb, af( bbptr+2*bw*ldbb+bm ), ldbb )
936 neicol = mycol - npstr
938 IF (neicol .EQ. 0)
THEN
947 CALL zgesd2d( ictxt, bm, 2*bw, af(bbptr+bw*ldbb),
950 CALL zlamov(
'G',bm, 2*bw, af(bbptr+bw*ldbb),ldbb,
951 $ af(bbptr+bmn),ldbb)
953 DO 31 j=bbptr+2*bw*ldbb, bbptr+3*bw*ldbb-1, ldbb
959 CALL zgerv2d( ictxt, bmn, 2*bw, af(bbptr+bw*ldbb),
962 IF( npact .EQ. 2 )
THEN
966 CALL zlamov(
'G', bm, bw, af( bbptr+bmn ),
967 $ ldbb, af( bbptr+2*bw*ldbb+bmn ), ldbb )
974 IF (npact .NE. 2)
THEN
976 CALL zgetrf(bm+bmn, bw, af(bbptr+bw*ldbb), ldbb,
981 DO 301 j=bbptr,bbptr+bw*ldbb-1, ldbb
987 CALL zlaswp(bw, af(bbptr), ldbb, 1, bw,
990 CALL ztrsm(
'L',
'L',
'N',
'U', bw, bw, cone,
991 $ af(bbptr+bw*ldbb), ldbb, af(bbptr), ldbb)
995 CALL zgemm(
'N',
'N', bm+bmn-bw, bw, bw,
996 $ -cone, af(bbptr+bw*ldbb+bw), ldbb,
997 $ af( bbptr ), ldbb, cone,
998 $ af( bbptr+bw ), ldbb )
1004 CALL zlaswp(nrhs, af(bbptr+2*bw*ldbb), ldbb, 1, bw,
1007 CALL ztrsm(
'L',
'L',
'N',
'U', bw, nrhs, cone,
1008 $ af(bbptr+bw*ldbb), ldbb, af(bbptr+2*bw*ldbb), ldbb)
1012 CALL zgemm(
'N',
'N', bm+bmn-bw, nrhs, bw,
1013 $ -cone, af(bbptr+bw*ldbb+bw), ldbb,
1014 $ af( bbptr+2*bw*ldbb ), ldbb, cone,
1015 $ af( bbptr+2*bw*ldbb+bw ), ldbb )
1020 IF (mod(mycol,2*npstr) .EQ. 0)
THEN
1029 CALL zlamov(
'G',bm,bw,
1031 $ ldbb, af(bbptr+bw*ldbb), ldbb)
1032 CALL zlamov(
'G',bm,bw,
1033 $ af(bbptr+2*bw*ldbb+bw),
1034 $ ldbb, af(bbptr+2*bw*ldbb), ldbb)
1040 af(bbptr+2*bw*ldbb+bw+j*ldbb+i) = czero
1050 CALL zgetrf(bm+bmn,bm+bmn, af(bbptr+bw*ldbb), ldbb,
1060 npact = (npact + 1)/2
1073 IF( ictxt.NE.ictxt_new )
THEN
1074 CALL blacs_gridexit( ictxt_new )
1088 work( 1 ) = work_size_min
1092 CALL igamx2d( ictxt,
'A',
' ', 1, 1, info, 1, info, info,
1095 IF( mycol.EQ.0 )
THEN
1096 CALL igebs2d( ictxt,
'A',
' ', 1, 1, info, 1 )
1098 CALL igebr2d( ictxt,
'A',
' ', 1, 1, info, 1, 0, 0 )