1 SUBROUTINE psgbdcmv( 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( * ), ( * )
17 REAL A( * ), B( * ), WORK( * ), X( * )
324 parameter( one = 1.0e+0 )
325 parameter( zero = 0.0e+0 )
327 parameter( int_one = 1 )
328 INTEGER DESCMULT, BIGNUM
329 parameter(descmult = 100, bignum = descmult * descmult)
330 INTEGER BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
331 $ lld_, mb_, m_, nb_, n_, rsrc_
332 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
333 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
334 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
337 INTEGER CSRC, DL_N_M, DL_N_N, DL_P_M, DL_P_N, DU_N_M,
338 $ du_n_n, du_p_m, du_p_n, first_proc, i, ictxt,
339 $ ictxt_new, ictxt_save, idum2, idum3, j, ja_new,
340 $ llda, lldb, max_bw, mycol, myrow, my_num_cols,
341 $ nb, np, npcol, nprow, np_save, odd_size, ofst,
342 $ part_offset, part_size, store_m_b, store_n_a
346 INTEGER PARAM_CHECK( 17, 3 )
354 EXTERNAL lsame, numroc
357 INTRINSIC ichar,
min, mod
365 ictxt = desca( ctxt_ )
366 csrc = desca( csrc_ )
369 store_n_a = desca( n_ )
371 store_m_b = descb( m_ )
376 max_bw =
max(bwl,bwu)
383 IF( lsame( trans,
'N' ) )
THEN
385 ELSE IF ( lsame( trans,
'T' ) )
THEN
387 ELSE IF ( lsame( trans,
'C' ) )
THEN
393 IF( lwork .LT. -1)
THEN
395 ELSE IF ( lwork .EQ. -1 )
THEN
405 IF( n+ja-1 .GT. store_n_a )
THEN
406 info = -( 8*100 + 6 )
409 IF(( bwl .GT. n-1 ) .OR.
410 $ ( bwl .LT. 0 ) )
THEN
414 IF(( bwu .GT. n-1 ) .OR.
415 $ ( bwu .LT. 0 ) )
THEN
419 IF( llda .LT. (bwl+bwu+1) )
THEN
420 info = -( 8*100 + 6 )
424 info = -( 8*100 + 4 )
429 IF( nprow .NE. 1 )
THEN
433 IF( n .GT. np*nb-mod( ja-1, nb ))
THEN
436 $
'PSDBDCMV, D&C alg.: only 1 block per proc',
441 IF((ja+n-1.GT.nb) .AND. ( nb.LT.2*
max(bwl,bwu) ))
THEN
444 $
'PSDBDCMV, D&C alg.: NB too small',
452 param_check( 17, 1 ) = descb(5)
453 param_check( 16, 1 ) = descb(4)
454 param_check( 15, 1 ) = descb(3)
455 param_check( 14, 1 ) = descb(2)
456 param_check( 13, 1 ) = descb(1)
457 param_check( 12, 1 ) = ib
458 param_check( 11, 1 ) = desca(5)
459 param_check( 10, 1 ) = desca(4)
460 param_check( 9, 1 ) = desca(3)
461 param_check( 8, 1 ) = desca(1)
462 param_check( 7, 1 ) = ja
463 param_check( 6, 1 ) = nrhs
464 param_check( 5, 1 ) = bwu
465 param_check( 4, 1 ) = bwl
466 param_check( 3, 1 ) = n
467 param_check( 2, 1 ) = idum3
468 param_check( 1, 1 ) = idum2
470 param_check( 17, 2 ) = 1105
471 param_check( 16, 2 ) = 1104
472 param_check( 15, 2 ) = 1103
473 param_check( 14, 2 ) = 1102
474 param_check( 13, 2 ) = 1101
475 param_check( 12, 2 ) = 10
476 param_check( 11, 2 ) = 805
477 param_check( 10, 2 ) = 804
478 param_check( 9, 2 ) = 803
479 param_check( 8, 2 ) = 801
480 param_check( 7, 2 ) = 7
481 param_check( 6, 2 ) = 5
482 param_check( 5, 2 ) = 4
483 param_check( 4, 2 ) = 3
484 param_check( 3, 2 ) = 2
485 param_check( 2, 2 ) = 15
486 param_check( 1, 2 ) = 1
494 ELSE IF( info.LT.-descmult )
THEN
497 info = -info * descmult
502 CALL globchk( ictxt, 17, param_check, 17,
503 $ param_check( 1, 3 ), info )
508 IF( info.EQ.bignum )
THEN
510 ELSE IF( mod( info, descmult ) .EQ. 0 )
THEN
511 info = -info / descmult
517 CALL pxerbla( ictxt,
'PSDBDCMV', -info )
530 part_offset = nb*( (ja-1)/(npcol*nb) )
532 IF ( (mycol-csrc) .LT. (ja-part_offset-1)/nb )
THEN
533 part_offset = part_offset + nb
536 IF ( mycol .LT. csrc )
THEN
537 part_offset = part_offset - nb
546 first_proc = mod( ( ja-1 )/nb+csrc, npcol )
550 ja_new = mod( ja-1, nb ) + 1
555 np = ( ja_new+n-2 )/nb + 1
559 CALL reshape( ictxt, int_one, ictxt_new, int_one,
560 $ first_proc, int_one, np )
573 IF( myrow .LT. 0 )
THEN
586 my_num_cols = numroc( n, part_size, mycol, 0, npcol )
590 IF ( mycol .EQ. 0 )
THEN
591 part_offset = part_offset+mod( ja_new-1, part_size )
592 my_num_cols = my_num_cols - mod(ja_new-1, part_size )
597 ofst = part_offset*llda
601 odd_size = my_num_cols
602 IF ( mycol .LT. np-1 )
THEN
603 odd_size = odd_size - max_bw
611 $ numroc( n, part_size, mycol, 0, npcol)
614 DO 4502 i=1,numroc_size
615 x( (j-1)*lldb + i ) = zero
619 DO 5642 i=1, (max_bw+2)*max_bw
628 IF ( lsame( trans,
'N' ) )
THEN
632 IF( mycol .GT. 0 )
THEN
635 $ numroc( n, part_size, mycol, 0, npcol ) )
637 $ numroc( n, part_size, mycol-1, 0, npcol ) )
640 $ numroc( n, part_size, mycol-1, 0, npcol ) )
642 $ numroc( n, part_size, mycol, 0, npcol ) )
645 IF( mycol .LT. npcol-1 )
THEN
650 $ numroc( n, part_size, mycol, 0, npcol ) )
653 $ numroc( n, part_size, mycol, 0, npcol ) )
655 $ numroc( n, part_size, mycol+1, 0, npcol ) )
661 CALL sgbmv( trans, numroc_size, numroc_size, bwl, bwu, one,
662 $ a( ofst+1 ), llda, b(part_offset+1), 1, zero,
663 $ x( part_offset+1 ), 1 )
667 IF ( mycol .LT. npcol-1 )
THEN
672 $ b( numroc_size-dl_n_n+1 ),
673 $ 1, work( max_bw*max_bw+1+bwl-dl_n_n ), 1 )
675 CALL strmv(
'U',
'N',
'N', bwl,
676 $ a( llda*( numroc_size-bwl )+1+bwu+bwl ), llda-1,
682 DO 10 i = dl_n_m-dl_n_n, dl_n_m
683 work( max_bw*max_bw+i ) = 0
689 CALL sgesd2d( ictxt, bwl, 1,
694 IF ( mycol .GT. 0 )
THEN
696 DO 20 i=1, max_bw*( max_bw+2 )
704 CALL scopy( du_p_n, b( 1 ), 1,
705 $ work( max_bw*max_bw+1 ), 1)
712 $ WORK( MAX_BW*MAX_BW+1 ), 1 )
716.GT.
IF( DU_P_N DU_P_M ) THEN
717 DO 30 I=1, DU_P_N-DU_P_M
718 WORK( MAX_BW*MAX_BW+I ) = 0
724 CALL SGESD2D( ICTXT, BWU, 1, WORK(MAX_BW*MAX_BW+1 ),
725 $ BWU, MYROW, MYCOL-1 )
729 CALL SGERV2D( ICTXT, BWL, 1, WORK( MAX_BW*MAX_BW+1 ),
730 $ BWL, MYROW, MYCOL-1 )
734 CALL SAXPY( BWL, ONE,
735 $ WORK( MAX_BW*MAX_BW+1 ), 1,
742.LT.
IF( MYCOL NPCOL-1 ) THEN
746 CALL SGERV2D( ICTXT, BWU, 1, WORK( MAX_BW*MAX_BW+1 ),
747 $ BWU, MYROW, MYCOL+1 )
751 CALL SAXPY( BWU, ONE,
752 $ WORK( MAX_BW*MAX_BW+1 ), 1,
753 $ X( NUMROC_SIZE-BWU+1 ), 1)
764 IF ( LSAME( TRANS, 't
' ) ) THEN
768.GT.
IF( MYCOL 0 ) THEN
771 $ NUMROC( N, PART_SIZE, MYCOL, 0, NPCOL ) )
773 $ NUMROC( N, PART_SIZE, MYCOL-1, 0, NPCOL ) )
776 $ NUMROC( N, PART_SIZE, MYCOL-1, 0, NPCOL ) )
778 $ NUMROC( N, PART_SIZE, MYCOL, 0, NPCOL ) )
781.LT.
IF( MYCOL NPCOL-1 ) THEN
784 $ NUMROC( N, PART_SIZE, MYCOL+1, 0, NPCOL ) )
786 $ NUMROC( N, PART_SIZE, MYCOL, 0, NPCOL ) )
789 $ NUMROC( N, PART_SIZE, MYCOL, 0, NPCOL ) )
791 $ NUMROC( N, PART_SIZE, MYCOL+1, 0, NPCOL ) )
795.GT.
IF( MYCOL 0 ) THEN
800 CALL SLATCPY( 'l
', BWU, BWU, A( OFST+1 ),
801 $ LLDA-1, WORK( 1 ), MAX_BW )
805 CALL STRSD2D(ICTXT, 'u
', 'n
',
808 $ MAX_BW, MYROW, MYCOL-1 )
812.LT.
IF( MYCOL NPCOL-1 ) THEN
817 CALL SLATCPY( 'u
', BWL, BWL,
818 $ A( LLDA*( NUMROC_SIZE-BWL )+1+BWU+BWL ),
819 $ LLDA-1, WORK( 1 ), MAX_BW )
823 CALL STRSD2D(ICTXT, 'l
', 'n
',
826 $ MAX_BW, MYROW, MYCOL+1 )
832 CALL SGBMV( TRANS, NUMROC_SIZE, NUMROC_SIZE, BWL, BWU, ONE,
833 $ A( OFST+1 ), LLDA, B(PART_OFFSET+1), 1, ZERO,
834 $ X( PART_OFFSET+1 ), 1 )
838.LT.
IF ( MYCOL NPCOL-1 ) THEN
843 $ B( NUMROC_SIZE-DL_N_N+1 ),
844 $ 1, WORK( MAX_BW*MAX_BW+1+BWU-DL_N_N ), 1 )
848 CALL STRRV2D(ICTXT, 'u
', 'n
',
850 $ WORK( 1 ), MAX_BW, MYROW, MYCOL+1 )
852 CALL STRMV( 'u
', 'n
', 'n
', BWU,
854 $ WORK( MAX_BW*MAX_BW+1 ), 1)
858.GT.
IF( DL_N_M DL_N_N ) THEN
859 DO 40 I = DL_N_M-DL_N_N, DL_N_M
860 WORK( MAX_BW*MAX_BW+I ) = 0
866 CALL SGESD2D( ICTXT, BWU, 1,
867 $ WORK( MAX_BW*MAX_BW+1 ), BWU, MYROW, MYCOL+1 )
871.GT.
IF ( MYCOL 0 ) THEN
873 DO 50 I=1, MAX_BW*( MAX_BW+2 )
881 CALL SCOPY( DU_P_N, B( 1 ), 1,
882 $ WORK( MAX_BW*MAX_BW+1 ), 1)
886 CALL STRRV2D(ICTXT, 'l',
'N',
888 $ work( 1 ), max_bw, myrow, mycol-1 )
895 $ work( max_bw*max_bw+1 ), 1 )
899 IF( du_p_n .GT. du_p_m )
THEN
900 DO 60 i=1, du_p_n-du_p_m
901 work( max_bw*max_bw+i ) = 0
907 CALL sgesd2d( ictxt, bwl, 1, work(max_bw*max_bw+1 ),
908 $ bwl, myrow, mycol-1 )
912 CALL sgerv2d( ictxt, bwu, 1, work( max_bw*max_bw+1 ),
913 $ bwu, myrow, mycol-1 )
917 CALL saxpy( bwu, one,
918 $ work( max_bw*max_bw+1 ), 1,
925 IF( mycol .LT. npcol-1 )
THEN
929 CALL sgerv2d( ictxt, bwl, 1, work( max_bw*max_bw+1 ),
930 $ bwl, myrow, mycol+1 )
934 CALL saxpy( bwl, one,
935 $ work( max_bw*max_bw+1 ), 1,
936 $ x( numroc_size-bwl+1 ), 1)
948 IF( ictxt_save .NE. ictxt_new )
THEN