1 SUBROUTINE pdpbdcmv( 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 DOUBLE PRECISION A( * ), B( * ), WORK( * ), X( * )
319 DOUBLE PRECISION ONE, ZERO
320 parameter( one = 1.0d+0 )
321 parameter( zero = 0.0d+0 )
323 parameter( int_one = 1 )
324 INTEGER DESCMULT, BIGNUM
325 parameter(descmult = 100, bignum = descmult * descmult)
326 INTEGER BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
327 $ lld_, mb_, m_, nb_, n_, rsrc_
328 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
329 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
330 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
333 INTEGER CSRC, DL_N_M, DL_N_N, DL_P_M, DL_P_N,
334 $ first_proc, i, ictxt, ictxt_new, ictxt_save,
335 $ idum1, idum3, j, ja_new, llda, lldb, mycol,
336 $ myrow, my_num_cols, nb, np, npcol, nprow,
337 $ np_save, odd_size, ofst, part_offset,
338 $ part_size, store_m_b, store_n_a
342 INTEGER PARAM_CHECK( 16, 3 )
350 EXTERNAL lsame, numroc
353 INTRINSIC ichar,
min, mod
361 ictxt = desca( ctxt_ )
362 csrc = desca( csrc_ )
365 store_n_a = desca( n_ )
367 store_m_b = descb( m_ )
373 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
378 IF( lsame( uplo,
'U' ) )
THEN
380 ELSE IF ( lsame( uplo,
'L' ) )
THEN
386 IF( lwork .LT. -1)
THEN
388 ELSE IF ( lwork .EQ. -1 )
THEN
398 IF( n+ja-1 .GT. store_n_a )
THEN
399 info = -( 7*100 + 6 )
402 IF(( bw .GT. n-1 ) .OR.
403 $ ( bw .LT. 0 ) )
THEN
407 IF( llda .LT. (bw+1) )
THEN
408 info = -( 7*100 + 6 )
412 info = -( 7*100 + 4 )
417 IF( nprow .NE. 1 )
THEN
421 IF( n .GT. np*nb-mod( ja-1, nb ))
THEN
424 $
'PDPBDCMV, D&C alg.: only 1 block per proc',
429 IF((ja+n-1.GT.nb) .AND. ( nb.LT.2*bw ))
THEN
432 $
'PDPBDCMV, D&C alg.: NB too small',
440 param_check( 16, 1 ) = descb(5)
441 param_check( 15, 1 ) = descb(4)
442 param_check( 14, 1 ) = descb(3)
443 param_check( 13, 1 ) = descb(2)
444 param_check( 12, 1 ) = descb(1)
445 param_check( 11, 1 ) = ib
446 param_check( 10, 1 ) = desca(5)
447 param_check( 9, 1 ) = desca(4)
448 param_check( 8, 1 ) = desca(3)
449 param_check( 7, 1 ) = desca(1)
450 param_check( 6, 1 ) = ja
451 param_check( 5, 1 ) = nrhs
452 param_check( 4, 1 ) = bw
453 param_check( 3, 1 ) = n
454 param_check( 2, 1 ) = idum3
455 param_check( 1, 1 ) = idum1
457 param_check( 16, 2 ) = 1005
458 param_check( 15, 2 ) = 1004
459 param_check( 14, 2 ) = 1003
460 param_check( 13, 2 ) = 1002
461 param_check( 12, 2 ) = 1001
462 param_check( 11, 2 ) = 9
463 param_check( 10, 2 ) = 705
464 param_check( 9, 2 ) = 704
465 param_check( 8, 2 ) = 703
466 param_check( 7, 2 ) = 701
467 param_check( 6, 2 ) = 6
468 param_check( 5, 2 ) = 4
469 param_check( 4, 2 ) = 3
470 param_check( 3, 2 ) = 2
471 param_check( 2, 2 ) = 14
472 param_check( 1, 2 ) = 1
480 ELSE IF( info.LT.-descmult )
THEN
483 info = -info * descmult
488 CALL globchk( ictxt, 16, param_check, 16,
489 $ param_check( 1, 3 ), info )
494 IF( info.EQ.bignum )
THEN
496 ELSE IF( mod( info, descmult ) .EQ. 0 )
THEN
497 info = -info / descmult
503 CALL pxerbla( ictxt,
'PDPBDCMV', -info )
516 part_offset = nb*( (ja-1)/(npcol*nb) )
518 IF ( (mycol-csrc) .LT. (ja-part_offset-1)/nb )
THEN
519 part_offset = part_offset + nb
522 IF ( mycol .LT. csrc )
THEN
523 part_offset = part_offset - nb
532 first_proc = mod( ( ja-1 )/nb+csrc, npcol )
536 ja_new = mod( ja-1, nb ) + 1
541 np = ( ja_new+n-2 )/nb + 1
545 CALL reshape( ictxt, int_one, ictxt_new, int_one,
546 $ first_proc, int_one, np )
555 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
559 IF( myrow .LT. 0 )
THEN
572 my_num_cols = numroc( n, part_size, mycol, 0, npcol )
576 IF ( mycol .EQ. 0 )
THEN
577 part_offset = part_offset+mod( ja_new-1, part_size )
578 my_num_cols = my_num_cols - mod(ja_new-1, part_size )
583 ofst = part_offset*llda
587 odd_size = my_num_cols
588 IF ( mycol .LT. np-1 )
THEN
589 odd_size = odd_size - bw
597 $ numroc( n, part_size, mycol, 0, npcol)
600 DO 4502 i=1,numroc_size
601 x( (j-1)*lldb + i ) = zero
605 DO 5642 i=1, (bw+2)*bw
614 IF ( lsame( uplo,
'L' ) )
THEN
618 IF( mycol .GT. 0 )
THEN
621 $ numroc( n, part_size, mycol, 0, npcol ) )
623 $ numroc( n, part_size, mycol-1, 0, npcol ) )
626 IF( mycol .LT. npcol-1 )
THEN
629 $ numroc( n, part_size, mycol+1, 0, npcol ) )
631 $ numroc( n, part_size, mycol, 0, npcol ) )
635 IF( mycol .LT. npcol-1 )
THEN
641 $ a( llda*( numroc_size-bw )+1+bw ),
642 $ llda-1, work( 1 ), bw )
646 CALL dtrsd2d(ictxt,
'L',
'N',
649 $ bw, myrow, mycol+1 )
655 CALL dsbmv(
'L', numroc_size, bw, one, a( ofst+1 ), llda,
656 $ b(part_offset+1), 1, zero, x( part_offset+1 ), 1 )
660 IF ( mycol .LT. npcol-1 )
THEN
665 $ b( numroc_size-dl_n_n+1 ),
666 $ 1, work( bw*bw+1+bw-dl_n_n ), 1 )
668 CALL dtrmv(
'U',
'N',
'N', bw,
669 $ a( llda*( numroc_size-bw )+1+bw ), llda-1,
670 $ work( bw*bw+1 ), 1)
674 IF( dl_n_m .GT. dl_n_n )
THEN
675 DO 10 i = dl_n_m-dl_n_n, dl_n_m
682 CALL dgesd2d( ictxt, bw, 1,
683 $ work( bw*bw+1 ), bw, myrow, mycol+1 )
687 IF ( mycol .GT. 0 )
THEN
689 DO 20 i=1, bw*( bw+2 )
697 CALL dcopy( dl_p_m, b( 1 ), 1,
698 $ work( bw*bw+1 ), 1)
702 CALL dtrrv2d(ictxt,
'L',
'N',
704 $ work( 1 ), bw, myrow, mycol-1 )
711 $ work( bw*bw+1 ), 1 )
715 IF( dl_p_m .GT. dl_p_n )
THEN
716 DO 30 i=1, dl_p_m-dl_p_n
723 CALL dgesd2d( ictxt, bw, 1, work(bw*bw+1 ),
724 $ bw, myrow, mycol-1 )
728 CALL dgerv2d( ictxt, bw, 1, work( bw*bw+1 ),
729 $ bw, myrow, mycol-1 )
734 $ work( bw*bw+1 ), 1,
741 IF( mycol .LT. npcol-1 )
THEN
745 CALL dgerv2d( ictxt, bw, 1, work( bw*bw+1 ),
746 $ bw, myrow, mycol+1 )
751 $ work( bw*bw+1 ), 1,
752 $ x( numroc_size-bw+1 ), 1)
763 IF ( lsame( uplo,
'U' ) )
THEN
767 IF( mycol .GT. 0 )
THEN
770 $ numroc( n, part_size, mycol, 0, npcol ) )
772 $ numroc( n, part_size, mycol-1, 0, npcol ) )
775 IF( mycol .LT. npcol-1 )
THEN
778 $ numroc( n, part_size, mycol+1, 0, npcol ) )
780 $ numroc( n, part_size, mycol, 0, npcol ) )
784 IF( mycol .GT. 0 )
THEN
789 CALL dlatcpy(
'L', bw, bw, a( ofst+1 ),
790 $ llda-1, work( 1 ), bw )
794 CALL dtrsd2d(ictxt,
'U',
'N',
797 $ bw, myrow, mycol-1 )
803 CALL dsbmv(
'U', numroc_size, bw, one, a( ofst+1 ), llda,
804 $ b(part_offset+1), 1, zero, x( part_offset+1 ), 1 )
808 IF ( mycol .LT. npcol-1 )
THEN
813 $ b( numroc_size-dl_n_n+1 ),
814 $ 1, work( bw*bw+1+bw-dl_n_n ), 1 )
818 CALL dtrrv2d(ictxt,
'U',
'N',
820 $ work( 1 ), bw, myrow, mycol+1 )
822 CALL dtrmv(
'U',
'N',
'N', bw,
824 $ work( bw*bw+1 ), 1)
828 IF( dl_n_m .GT. dl_n_n )
THEN
829 DO 40 i = dl_n_m-dl_n_n, dl_n_m
836 CALL dgesd2d( ictxt, bw, 1,
837 $ work( bw*bw+1 ), bw, myrow, mycol+1 )
841 IF ( mycol .GT. 0 )
THEN
843 DO 50 i=1, bw*( bw+2 )
851 CALL dcopy( dl_p_m, b( 1 ), 1,
852 $ work( bw*bw+1 ), 1)
859 $ work( bw*bw+1 ), 1 )
863 IF( dl_p_m .GT. dl_p_n )
THEN
864 DO 60 i=1, dl_p_m-dl_p_n
871 CALL dgesd2d( ictxt, bw, 1, work(bw*bw+1 ),
872 $ bw, myrow, mycol-1 )
876 CALL dgerv2d( ictxt, bw, 1, work( bw*bw+1 ),
877 $ bw, myrow, mycol-1 )
882 $ work( bw*bw+1 ), 1,
889 IF( mycol .LT. npcol-1 )
THEN
893 CALL dgerv2d( ictxt, bw, 1, work( bw*bw+1 ),
894 $ bw, myrow, mycol+1 )
899 $ work( bw*bw+1 ), 1,
900 $ x( numroc_size-bw+1 ), 1)
912 IF( ictxt_save .NE. ictxt_new )
THEN
913 CALL blacs_gridexit( ictxt_new )