1 SUBROUTINE pcgbdcmv( LDBW, BWL, BWU, TRANS, N, A, JA, DESCA, NRHS,
2 $ B, IB, DESCB, X, WORK, LWORK, INFO )
13 INTEGER BWL, BWU, IB, INFO, JA, LDBW, LWORK, N, NRHS
16 INTEGER DESCA( * ), DESCB( * )
17 COMPLEX A( * ), B( * ), WORK( * ), X( * )
324 parameter( one = 1.0e+0 )
325 parameter( zero = 0.0e+0 )
327 parameter( cone = ( 1.0e+0, 0.0e+0 ) )
328 parameter( czero = ( 0.0e+0, 0.0e+0 ) )
330 parameter( int_one = 1 )
331 INTEGER DESCMULT, BIGNUM
332 parameter(descmult = 100, bignum = descmult * descmult)
333 INTEGER BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
334 $ lld_, mb_, m_, nb_, n_, rsrc_
335 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
336 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
337 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
340 INTEGER CSRC, DL_N_M, DL_N_N, DL_P_M, DL_P_N, DU_N_M,
341 $ du_n_n, du_p_m, du_p_n, first_proc, i, ictxt,
342 $ ictxt_new, ictxt_save, idum2, idum3, j, ja_new,
343 $ llda, lldb, max_bw, mycol, myrow, my_num_cols,
344 $ nb, np, npcol, nprow, np_save, odd_size, ofst,
345 $ part_offset, part_size, store_m_b, store_n_a
349 INTEGER PARAM_CHECK( 17, 3 )
357 EXTERNAL lsame, numroc
360 INTRINSIC ichar,
min, mod
368 ictxt = desca( ctxt_ )
369 csrc = desca( csrc_ )
372 store_n_a = desca( n_ )
374 store_m_b = descb( m_ )
379 max_bw =
max(bwl,bwu)
381 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
386 IF( lsame( trans,
'N' ) )
THEN
388 ELSE IF ( lsame( trans,
'C' ) )
THEN
394 IF( lwork .LT. -1)
THEN
396 ELSE IF ( lwork .EQ. -1 )
THEN
406 IF( n+ja-1 .GT. store_n_a )
THEN
407 info = -( 8*100 + 6 )
410 IF(( bwl .GT. n-1 ) .OR.
411 $ ( bwl .LT. 0 ) )
THEN
415 IF(( bwu .GT. n-1 ) .OR.
416 $ ( bwu .LT. 0 ) )
THEN
420 IF( llda .LT. (bwl+bwu+1) )
THEN
421 info = -( 8*100 + 6 )
425 info = -( 8*100 + 4 )
430 IF( nprow .NE. 1 )
THEN
434 IF( n .GT. np*nb-mod( ja-1, nb ))
THEN
437 $
'PCDBDCMV, D&C alg.: only 1 block per proc',
442 IF((ja+n-1.GT.nb) .AND. ( nb.LT.2*
max(bwl,bwu) ))
THEN
445 $
'PCDBDCMV, D&C alg.: NB too small',
453 param_check( 17, 1 ) = descb(5)
454 param_check( 16, 1 ) = descb(4)
455 param_check( 15, 1 ) = descb(3)
456 param_check( 14, 1 ) = descb(2)
457 param_check( 13, 1 ) = descb(1)
458 param_check( 12, 1 ) = ib
459 param_check( 11, 1 ) = desca(5)
460 param_check( 10, 1 ) = desca(4)
461 param_check( 9, 1 ) = desca(3)
462 param_check( 8, 1 ) = desca(1)
463 param_check( 7, 1 ) = ja
464 param_check( 6, 1 ) = nrhs
465 param_check( 5, 1 ) = bwu
466 param_check( 4, 1 ) = bwl
467 param_check( 3, 1 ) = n
468 param_check( 2, 1 ) = idum3
469 param_check( 1, 1 ) = idum2
471 param_check( 17, 2 ) = 1105
472 param_check( 16, 2 ) = 1104
473 param_check( 15, 2 ) = 1103
474 param_check( 14, 2 ) = 1102
475 param_check( 13, 2 ) = 1101
476 param_check( 12, 2 ) = 10
477 param_check( 11, 2 ) = 805
478 param_check( 10, 2 ) = 804
479 param_check( 9, 2 ) = 803
480 param_check( 8, 2 ) = 801
481 param_check( 7, 2 ) = 7
482 param_check( 6, 2 ) = 5
483 param_check( 5, 2 ) = 4
484 param_check( 4, 2 ) = 3
485 param_check( 3, 2 ) = 2
486 param_check( 2, 2 ) = 15
487 param_check( 1, 2 ) = 1
495 ELSE IF( info.LT.-descmult )
THEN
498 info = -info * descmult
503 CALL globchk( ictxt, 17, param_check, 17,
504 $ param_check( 1, 3 ), info )
509 IF( info.EQ.bignum )
THEN
511 ELSE IF( mod( info, descmult ) .EQ. 0 )
THEN
512 info = -info / descmult
518 CALL pxerbla( ictxt,
'PCDBDCMV', -info )
531 part_offset = nb*( (ja-1)/(npcol*nb) )
533 IF ( (mycol-csrc) .LT. (ja-part_offset-1)/nb )
THEN
534 part_offset = part_offset + nb
537 IF ( mycol .LT. csrc )
THEN
538 part_offset = part_offset - nb
547 first_proc = mod( ( ja-1 )/nb+csrc, npcol )
551 ja_new = mod( ja-1, nb ) + 1
556 np = ( ja_new+n-2 )/nb + 1
560 CALL reshape( ictxt, int_one, ictxt_new, int_one,
561 $ first_proc, int_one, np )
570 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
574 IF( myrow .LT. 0 )
THEN
587 my_num_cols = numroc( n, part_size, mycol, 0, npcol )
591 IF ( mycol .EQ. 0 )
THEN
592 part_offset = part_offset+mod( ja_new-1, part_size )
593 my_num_cols = my_num_cols - mod(ja_new-1, part_size )
598 ofst = part_offset*llda
602 odd_size = my_num_cols
603 IF ( mycol .LT. np-1 )
THEN
604 odd_size = odd_size - max_bw
612 $ numroc( n, part_size, mycol, 0, npcol)
615 DO 4502 i=1,numroc_size
616 x( (j-1)*lldb + i ) = czero
620 DO 5642 i=1, (max_bw+2)*max_bw
629 IF ( lsame( trans,
'N' ) )
THEN
633 IF( mycol .GT. 0 )
THEN
636 $ numroc( n, part_size, mycol, 0, npcol ) )
638 $ numroc( n, part_size, mycol-1, 0, npcol ) )
641 $ numroc( n, part_size, mycol-1, 0, npcol ) )
643 $ numroc( n, part_size, mycol, 0, npcol ) )
646 IF( mycol .LT. npcol-1 )
THEN
649 $ numroc( n, part_size, mycol+1, 0, npcol ) )
651 $ numroc( n, part_size, mycol, 0, npcol ) )
654 $ numroc( n, part_size, mycol, 0, npcol ) )
656 $ numroc( n, part_size, mycol+1, 0, npcol ) )
662 CALL cgbmv( trans, numroc_size, numroc_size, bwl, bwu, cone,
663 $ a( ofst+1 ), llda, b(part_offset+1), 1, czero,
664 $ x( part_offset+1 ), 1 )
668 IF ( mycol .LT. npcol-1 )
THEN
673 $ b( numroc_size-dl_n_n+1 ),
674 $ 1, work( max_bw*max_bw+1+bwl-dl_n_n ), 1 )
676 CALL ctrmv(
'U',
'N',
'N', bwl,
677 $ a( llda*( numroc_size-bwl )+1+bwu+bwl ), llda-1,
678 $ work( max_bw*max_bw+1 ), 1)
682 IF( dl_n_m .GT. dl_n_n )
THEN
683 DO 10 i = dl_n_m-dl_n_n, dl_n_m
684 work( max_bw*max_bw+i ) = 0
690 CALL cgesd2d( ictxt, bwl, 1,
691 $ work( max_bw*max_bw+1 ), bwl, myrow, mycol+1 )
695 IF ( mycol .GT. 0 )
THEN
697 DO 20 i=1, max_bw*( max_bw+2 )
705 CALL ccopy( du_p_n, b( 1 ), 1,
706 $ work( max_bw*max_bw+1 ), 1)
713 $ work( max_bw*max_bw+1 ), 1 )
717 IF( du_p_n .GT. du_p_m )
THEN
718 DO 30 i=1, du_p_n-du_p_m
719 work( max_bw*max_bw+i ) = 0
725 CALL cgesd2d( ictxt, bwu, 1, work(max_bw*max_bw+1 ),
726 $ bwu, myrow, mycol-1 )
730 CALL cgerv2d( ictxt, bwl, 1, work( max_bw*max_bw+1 ),
731 $ bwl, myrow, mycol-1 )
735 CALL caxpy( bwl, cone,
736 $ work( max_bw*max_bw+1 ), 1,
743 IF( mycol .LT. npcol-1 )
THEN
747 CALL cgerv2d( ictxt, bwu, 1, work( max_bw*max_bw+1 ),
748 $ bwu, myrow, mycol+1 )
752 CALL caxpy( bwu, cone,
753 $ work( max_bw*max_bw+1 ), 1,
754 $ x( numroc_size-bwu+1 ), 1)
765 IF ( lsame( trans,
'C' ) )
THEN
769 IF( mycol .GT. 0 )
THEN
772 $ numroc( n, part_size, mycol, 0, npcol ) )
774 $ numroc( n, part_size, mycol-1, 0, npcol ) )
777 $ numroc( n, part_size, mycol-1, 0, npcol ) )
779 $ numroc( n, part_size, mycol, 0, npcol ) )
782 IF( mycol .LT. npcol-1 )
THEN
785 $ numroc( n, part_size, mycol+1, 0, npcol ) )
787 $ numroc( n, part_size, mycol, 0, npcol ) )
790 $ numroc( n, part_size, mycol, 0, npcol ) )
792 $ numroc( n, part_size, mycol+1, 0, npcol ) )
796 IF( mycol .GT. 0 )
THEN
801 CALL clatcpy(
'L', bwu, bwu, a( ofst+1 ),
802 $ llda-1, work( 1 ), max_bw )
806 CALL ctrsd2d(ictxt,
'U',
'N',
809 $ max_bw, myrow, mycol-1 )
813 IF( mycol .LT. npcol-1 )
THEN
819 $ a( llda*( numroc_size-bwl )+1+bwu+bwl ),
820 $ llda-1, work( 1 ), max_bw )
824 CALL ctrsd2d(ictxt,
'L',
'N',
827 $ max_bw, myrow, mycol+1 )
833 CALL cgbmv( trans, numroc_size, numroc_size, bwl, bwu, cone,
834 $ a( ofst+1 ), llda, b(part_offset+1), 1, czero,
835 $ x( part_offset+1 ), 1 )
839 IF ( mycol .LT. npcol-1 )
THEN
844 $ b( numroc_size-dl_n_n+1 ),
845 $ 1, work( max_bw*max_bw+1+bwu-dl_n_n ), 1 )
849 CALL ctrrv2d(ictxt,
'U',
'N',
851 $ work( 1 ), max_bw, myrow, mycol+1 )
853 CALL ctrmv(
'U',
'N',
'N', bwu,
855 $ work( max_bw*max_bw+1 ), 1)
859 IF( dl_n_m .GT. dl_n_n )
THEN
860 DO 40 i = dl_n_m-dl_n_n, dl_n_m
861 work( max_bw*max_bw+i ) = 0
867 CALL cgesd2d( ictxt, bwu, 1,
868 $ work( max_bw*max_bw+1 ), bwu, myrow, mycol+1 )
872 IF ( mycol .GT. 0 )
THEN
874 DO 50 i=1, max_bw*( max_bw+2 )
882 CALL ccopy( du_p_n, b( 1 ), 1,
883 $ work( max_bw*max_bw+1 ), 1)
887 CALL ctrrv2d(ictxt,
'L',
'N',
889 $ work( 1 ), max_bw, myrow, mycol-1 )
896 $ work( max_bw*max_bw+1 ), 1 )
900 IF( du_p_n .GT. du_p_m )
THEN
901 DO 60 i=1, du_p_n-du_p_m
902 work( max_bw*max_bw+i ) = 0
908 CALL cgesd2d( ictxt, bwl, 1, work(max_bw*max_bw+1 ),
909 $ bwl, myrow, mycol-1 )
913 CALL cgerv2d( ictxt, bwu, 1, work( max_bw*max_bw+1 ),
914 $ bwu, myrow, mycol-1 )
918 CALL caxpy( bwu, cone,
919 $ work( max_bw*max_bw+1 ), 1,
926 IF( mycol .LT. npcol-1 )
THEN
930 CALL cgerv2d( ictxt, bwl, 1, work( max_bw*max_bw+1 ),
931 $ bwl, myrow, mycol+1 )
935 CALL caxpy( bwl, cone,
936 $ work( max_bw*max_bw+1 ), 1,
937 $ x( numroc_size-bwl+1 ), 1)
949 IF( ictxt_save .NE. ictxt_new )
THEN
950 CALL blacs_gridexit( ictxt_new )