1 SUBROUTINE pzpbdcmv( LDBW, BW, UPLO, N, A, JA, DESCA, NRHS, B, IB,
2 $ DESCB, X, WORK, LWORK, INFO )
13 INTEGER BW, IB, INFO, JA, LDBW, LWORK, N, NRHS
16 INTEGER DESCA( * ), DESCB( * )
17 COMPLEX*16 A( * ), B( * ), WORK( * ), X( * )
319 DOUBLE PRECISION ONE, ZERO
320 parameter( one = 1.0d+0 )
321 parameter( zero = 0.0d+0 )
322 COMPLEX*16 CONE, CZERO
323 parameter( cone = ( 1.0d+0, 0.0d+0 ) )
324 parameter( czero = ( 0.0d+0, 0.0d+0 ) )
326 parameter( int_one = 1 )
327 INTEGER DESCMULT, BIGNUM
328 parameter(descmult = 100, bignum = descmult * descmult)
329 INTEGER BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
330 $ lld_, mb_, m_, nb_, n_, rsrc_
331 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
332 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
333 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
336 INTEGER CSRC, DL_N_M, DL_N_N, DL_P_M, DL_P_N,
337 $ first_proc, i, ictxt, ictxt_new, ictxt_save,
338 $ idum1, idum3, j, ja_new, llda, lldb, mycol,
339 $ myrow, my_num_cols, nb, np, npcol, nprow,
340 $ np_save, odd_size, ofst, part_offset,
341 $ part_size, store_m_b, store_n_a
345 INTEGER PARAM_CHECK( 16, 3 )
353 EXTERNAL lsame, numroc
356 INTRINSIC ichar,
min, mod
364 ictxt = desca( ctxt_ )
365 csrc = desca( csrc_ )
368 store_n_a = desca( n_ )
370 store_m_b = descb( m_ )
376 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
381 IF( lsame( uplo,
'U' ) )
THEN
383 ELSE IF ( lsame( uplo,
'L' ) )
THEN
389 IF( lwork .LT. -1)
THEN
391 ELSE IF ( lwork .EQ. -1 )
THEN
401 IF( n+ja-1 .GT. store_n_a )
THEN
402 info = -( 7*100 + 6 )
405 IF(( bw .GT. n-1 ) .OR.
406 $ ( bw .LT. 0 ) )
THEN
410 IF( llda .LT. (bw+1) )
THEN
411 info = -( 7*100 + 6 )
415 info = -( 7*100 + 4 )
420 IF( nprow .NE. 1 )
THEN
424 IF( n .GT. np*nb-mod( ja-1, nb ))
THEN
427 $
'PZPBDCMV, D&C alg.: only 1 block per proc',
432 IF((ja+n-1.GT.nb) .AND. ( nb.LT.2*bw ))
THEN
435 $
'PZPBDCMV, D&C alg.: NB too small',
443 param_check( 16, 1 ) = descb(5)
444 param_check( 15, 1 ) = descb(4)
445 param_check( 14, 1 ) = descb(3)
446 param_check( 13, 1 ) = descb(2)
447 param_check( 12, 1 ) = descb(1)
448 param_check( 11, 1 ) = ib
449 param_check( 10, 1 ) = desca(5)
450 param_check( 9, 1 ) = desca(4)
451 param_check( 8, 1 ) = desca(3)
452 param_check( 7, 1 ) = desca(1)
453 param_check( 6, 1 ) = ja
454 param_check( 5, 1 ) = nrhs
455 param_check( 4, 1 ) = bw
456 param_check( 3, 1 ) = n
457 param_check( 2, 1 ) = idum3
458 param_check( 1, 1 ) = idum1
460 param_check( 16, 2 ) = 1005
461 param_check( 15, 2 ) = 1004
462 param_check( 14, 2 ) = 1003
463 param_check( 13, 2 ) = 1002
464 param_check( 12, 2 ) = 1001
465 param_check( 11, 2 ) = 9
466 param_check( 10, 2 ) = 705
467 param_check( 9, 2 ) = 704
468 param_check( 8, 2 ) = 703
469 param_check( 7, 2 ) = 701
470 param_check( 6, 2 ) = 6
471 param_check( 5, 2 ) = 4
472 param_check( 4, 2 ) = 3
473 param_check( 3, 2 ) = 2
474 param_check( 2, 2 ) = 14
475 param_check( 1, 2 ) = 1
483 ELSE IF( info.LT.-descmult )
THEN
486 info = -info * descmult
491 CALL globchk( ictxt, 16, param_check, 16,
492 $ param_check( 1, 3 ), info )
497 IF( info.EQ.bignum )
THEN
499 ELSE IF( mod( info, descmult ) .EQ. 0 )
THEN
500 info = -info / descmult
506 CALL pxerbla( ictxt,
'PZPBDCMV', -info )
519 part_offset = nb*( (ja-1)/(npcol*nb) )
521 IF ( (mycol-csrc) .LT. (ja-part_offset-1)/nb )
THEN
522 part_offset = part_offset + nb
525 IF ( mycol .LT. csrc )
THEN
526 part_offset = part_offset - nb
535 first_proc = mod( ( ja-1 )/nb+csrc, npcol )
539 ja_new = mod( ja-1, nb ) + 1
544 np = ( ja_new+n-2 )/nb + 1
548 CALL reshape( ictxt, int_one, ictxt_new, int_one,
549 $ first_proc, int_one, np )
558 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
562 IF( myrow .LT. 0 )
THEN
575 my_num_cols = numroc( n, part_size, mycol, 0, npcol )
579 IF ( mycol .EQ. 0 )
THEN
580 part_offset = part_offset+mod( ja_new-1, part_size )
581 my_num_cols = my_num_cols - mod(ja_new-1, part_size )
586 ofst = part_offset*llda
590 odd_size = my_num_cols
591 IF ( mycol .LT. np-1 )
THEN
592 odd_size = odd_size - bw
600 $ numroc( n, part_size, mycol, 0, npcol)
603 DO 4502 i=1,numroc_size
604 x( (j-1)*lldb + i ) = czero
608 DO 5642 i=1, (bw+2)*bw
617 IF ( lsame( uplo,
'L' ) )
THEN
621 IF( mycol .GT. 0 )
THEN
624 $ numroc( n, part_size, mycol, 0, npcol ) )
626 $ numroc( n, part_size, mycol-1, 0, npcol ) )
629 IF( mycol .LT. npcol-1 )
THEN
632 $ numroc( n, part_size, mycol+1, 0, npcol ) )
634 $ numroc( n, part_size, mycol, 0, npcol ) )
638 IF( mycol .LT. npcol-1 )
THEN
644 $ a( llda*( numroc_size-bw )+1+bw ),
645 $ llda-1, work( 1 ), bw )
649 CALL ztrsd2d(ictxt,
'L',
'N',
652 $ bw, myrow, mycol+1 )
658 CALL zhbmv(
'L', numroc_size, bw, cone, a( ofst+1 ), llda,
659 $ b(part_offset+1), 1, czero, x( part_offset+1 ), 1 )
663 IF ( mycol .LT. npcol-1 )
THEN
668 $ b( numroc_size-dl_n_n+1 ),
669 $ 1, work( bw*bw+1+bw-dl_n_n ), 1 )
671 CALL ztrmv(
'U',
'N',
'N', bw,
672 $ a( llda*( numroc_size-bw )+1+bw ), llda-1,
673 $ work( bw*bw+1 ), 1)
677 IF( dl_n_m .GT. dl_n_n )
THEN
678 DO 10 i = dl_n_m-dl_n_n, dl_n_m
685 CALL zgesd2d( ictxt, bw, 1,
686 $ work( bw*bw+1 ), bw, myrow, mycol+1 )
690 IF ( mycol .GT. 0 )
THEN
692 DO 20 i=1, bw*( bw+2 )
700 CALL zcopy( dl_p_m, b( 1 ), 1,
701 $ work( bw*bw+1 ), 1)
705 CALL ztrrv2d(ictxt,
'L',
'N',
707 $ work( 1 ), bw, myrow, mycol-1 )
714 $ work( bw*bw+1 ), 1 )
718 IF( dl_p_m .GT. dl_p_n )
THEN
719 DO 30 i=1, dl_p_m-dl_p_n
726 CALL zgesd2d( ictxt, bw, 1, work(bw*bw+1 ),
727 $ bw, myrow, mycol-1 )
731 CALL zgerv2d( ictxt, bw, 1, work( bw*bw+1 ),
732 $ bw, myrow, mycol-1 )
736 CALL zaxpy( bw, cone,
737 $ work( bw*bw+1 ), 1,
744 IF( mycol .LT. npcol-1 )
THEN
748 CALL zgerv2d( ictxt, bw, 1, work( bw*bw+1 ),
749 $ bw, myrow, mycol+1 )
753 CALL zaxpy( bw, cone,
754 $ work( bw*bw+1 ), 1,
755 $ x( numroc_size-bw+1 ), 1)
766 IF ( lsame( uplo,
'U' ) )
THEN
770 IF( mycol .GT. 0 )
THEN
773 $ numroc( n, part_size, mycol, 0, npcol ) )
775 $ numroc( n, part_size, mycol-1, 0, npcol ) )
778 IF( mycol .LT. npcol-1 )
THEN
781 $ numroc( n, part_size, mycol+1, 0, npcol ) )
783 $ numroc( n, part_size, mycol, 0, npcol ) )
787 IF( mycol .GT. 0 )
THEN
792 CALL zlatcpy(
'L', bw, bw, a( ofst+1 ),
793 $ llda-1, work( 1 ), bw )
797 CALL ztrsd2d(ictxt,
'U',
'N',
800 $ bw, myrow, mycol-1 )
806 CALL zhbmv(
'U', numroc_size, bw, cone, a( ofst+1 ), llda,
807 $ b(part_offset+1), 1, czero, x( part_offset+1 ), 1 )
811 IF ( mycol .LT. npcol-1 )
THEN
816 $ b( numroc_size-dl_n_n+1 ),
817 $ 1, work( bw*bw+1+bw-dl_n_n ), 1 )
821 CALL ztrrv2d(ictxt,
'U',
'N',
823 $ work( 1 ), bw, myrow, mycol+1 )
825 CALL ztrmv(
'U',
'N',
'N', bw,
827 $ work( bw*bw+1 ), 1)
831 IF( dl_n_m .GT. dl_n_n )
THEN
832 DO 40 i = dl_n_m-dl_n_n, dl_n_m
839 CALL zgesd2d( ictxt, bw, 1,
840 $ work( bw*bw+1 ), bw, myrow, mycol+1 )
844 IF ( mycol .GT. 0 )
THEN
846 DO 50 i=1, bw*( bw+2 )
854 CALL zcopy( dl_p_m, b( 1 ), 1,
855 $ work( bw*bw+1 ), 1)
862 $ work( bw*bw+1 ), 1 )
866 IF( dl_p_m .GT. dl_p_n )
THEN
867 DO 60 i=1, dl_p_m-dl_p_n
874 CALL zgesd2d( ictxt, bw, 1, work(bw*bw+1 ),
875 $ bw, myrow, mycol-1 )
879 CALL zgerv2d( ictxt, bw, 1, work( bw*bw+1 ),
880 $ bw, myrow, mycol-1 )
884 CALL zaxpy( bw, cone,
885 $ work( bw*bw+1 ), 1,
892 IF( mycol .LT. npcol-1 )
THEN
896 CALL zgerv2d( ictxt, bw, 1, work( bw*bw+1 ),
897 $ bw, myrow, mycol+1 )
901 CALL zaxpy( bw, cone,
902 $ work( bw*bw+1 ), 1,
903 $ x( numroc_size-bw+1 ), 1)
915 IF( ictxt_save .NE. ictxt_new )
THEN
916 CALL blacs_gridexit( ictxt_new )