diff --git a/include/graphblas/bsp1d/blas1.hpp b/include/graphblas/bsp1d/blas1.hpp index ac7bb3514..579d02940 100644 --- a/include/graphblas/bsp1d/blas1.hpp +++ b/include/graphblas/bsp1d/blas1.hpp @@ -1477,7 +1477,9 @@ namespace grb { // check if can delegate to dense variant const size_t n = size( z ); - if( (descr & descriptors::dense) || nnz( x ) == n ) { + if( (descr & descriptors::dense) || ( + nnz( x ) == n && nnz( z ) == n + ) ) { return eWiseApply< descr | descriptors::dense >( z, x, beta, monoid.getOperator(), phase ); @@ -1488,7 +1490,7 @@ namespace grb { return MISMATCH; } if( descr & descriptors::dense ) { - if( nnz( x ) < n ) { + if( nnz( x ) < n || nnz( z ) < n ) { return ILLEGAL; } } @@ -1566,7 +1568,9 @@ namespace grb { // check if can delegate to dense variant const size_t n = size( z ); - if( (descr & descriptors::dense) || nnz( y ) == n ) { + if( (descr & descriptors::dense) || ( + nnz( y ) == n && nnz( z ) == n + ) ) { return eWiseApply< descr | descriptors::dense >( z, alpha, y, monoid.getOperator(), phase ); @@ -1577,7 +1581,7 @@ namespace grb { return MISMATCH; } if( descr & descriptors::dense ) { - if( nnz( y ) < n ) { + if( nnz( y ) < n || nnz( z ) < n ) { return ILLEGAL; } } @@ -1657,7 +1661,9 @@ namespace grb { // check if we can delegate to dense variant const size_t n = size( z ); - if( (descr & descriptors::dense) || (nnz( x ) == n && nnz( y ) == n) ) { + if( (descr & descriptors::dense) || ( + nnz( x ) == n && nnz( y ) == n && nnz( z ) == n + ) ) { return eWiseApply< descr | descriptors::dense >( z, x, y, monoid.getOperator(), phase ); @@ -1773,7 +1779,7 @@ namespace grb { return MISMATCH; } if( descr & descriptors::dense ) { - if( nnz( y ) < n || nnz( mask ) < n ) { + if( nnz( y ) < n || nnz( mask ) < n || nnz( z ) < n ) { return ILLEGAL; } } @@ -1879,6 +1885,9 @@ namespace grb { if( nnz( x ) < n ) { return ILLEGAL; } + if( nnz ( z ) < n ) { + return ILLEGAL; + } } // handle trivial resize phase @@ -1979,7 +1988,7 @@ namespace grb { return MISMATCH; } if( descr & descriptors::dense ) { - if( nnz( x ) < n || nnz( y ) < n ) { + if( nnz( x ) < n || nnz( y ) < n || nnz( z ) < n ) { return ILLEGAL; } if( nnz( mask ) < n ) { @@ -2499,7 +2508,7 @@ namespace grb { return MISMATCH; } if( descr & descriptors::dense ) { - if( nnz( x ) < n || nnz( y ) < n ) { + if( nnz( x ) < n || nnz( y ) < n || nnz( z ) < n ) { return ILLEGAL; } } @@ -2563,7 +2572,7 @@ namespace grb { return MISMATCH; } if( descr & descriptors::dense ) { - if( nnz( y ) < n ) { + if( nnz( y ) < n || nnz( z ) < n ) { return ILLEGAL; } } @@ -2624,7 +2633,7 @@ namespace grb { return MISMATCH; } if( descr & descriptors::dense ) { - if( nnz( x ) < n ) { + if( nnz( x ) < n || nnz( z ) < n ) { return ILLEGAL; } } diff --git a/include/graphblas/reference/blas1.hpp b/include/graphblas/reference/blas1.hpp index 853add992..6304a9007 100644 --- a/include/graphblas/reference/blas1.hpp +++ b/include/graphblas/reference/blas1.hpp @@ -3214,17 +3214,19 @@ namespace grb { // part that may or may not be vectorised (can we do something about this??) for( size_t i = 0; i < block_size; ++i ) { if( !masked || mask[ i ] ) { + if( y_m[ i ] || monoid ) { #ifndef _H_GRB_REFERENCE_OMP_BLAS1 - (void) z_coors.assign( offsets[ i ] ); + (void) z_coors.assign( offsets[ i ] ); #else - if( !z_coors.asyncAssign( offsets[ i ], update ) ) { - (void) ++asyncAssigns; + if( !z_coors.asyncAssign( offsets[ i ], update ) ) { + (void) ++asyncAssigns; #ifdef _DEBUG - std::cout << "\t\t now made " << asyncAssigns - << " calls to asyncAssign; " << "added index " << offsets[ i ] << "\n"; + std::cout << "\t\t now made " << asyncAssigns << " calls to " + << "asyncAssign; " << "added index " << offsets[ i ] << "\n"; #endif - } + } #endif + } } } // perform scatter @@ -3242,8 +3244,9 @@ namespace grb { #ifdef _H_GRB_REFERENCE_OMP_BLAS1 if( asyncAssigns > maxAsyncAssigns - block_size ) { #ifdef _DEBUG - std::cout << "\t\t " << omp_get_thread_num() << ": clearing local update at block " - << b << ". It locally holds " << asyncAssigns << " entries. " + std::cout << "\t\t " << omp_get_thread_num() << ": " + << "clearing local update at block " << b << ". " + << "It locally holds " << asyncAssigns << " entries. " << "Update is at " << ( (void *)update ) << "\n"; #endif #ifndef NDEBUG @@ -3514,13 +3517,18 @@ namespace grb { return SUCCESS; } + /** + * \internal Whenever this function is called, the z_coors is assumed to be + * cleared. + */ template< bool left_scalar, bool right_scalar, bool left_sparse, bool right_sparse, Descriptor descr, class OP, typename OutputType, typename MaskType, typename InputType1, typename InputType2 > - RC masked_apply_generic( OutputType * const z_p, + RC masked_apply_generic( + OutputType * const z_p, Coordinates< reference > &z_coors, const MaskType * const mask_p, const Coordinates< reference > &mask_coors, @@ -3549,6 +3557,7 @@ namespace grb { assert( !left_sparse || left_identity != nullptr ); assert( !right_sparse || right_coors != nullptr ); assert( !right_sparse || right_identity != nullptr ); + assert( z_coors.nonzeroes() == 0 ); #ifdef _DEBUG std::cout << "\tinternal::masked_apply_generic called with nnz(mask)=" @@ -3583,9 +3592,6 @@ namespace grb { size_t_block_size : op_block_size; - // whether we have a dense hint - constexpr bool dense = descr & descriptors::dense; - if( bigLoop ) { #ifdef _DEBUG std::cerr << "\t in bigLoop variant\n"; @@ -3677,15 +3683,13 @@ namespace grb { const size_t index = i + k; assert( index < n ); if( mask_b[ k ] ) { - if( !dense ) { #ifdef _H_GRB_REFERENCE_OMP_BLAS1 - if( !z_coors.asyncAssign( index, update ) ) { - (void) ++asyncAssigns; - } + if( !z_coors.asyncAssign( index, update ) ) { + (void) ++asyncAssigns; + } #else - (void) z_coors.assign( index ); + (void) z_coors.assign( index ); #endif - } *( z_p + index ) = z_b[ k ]; } } @@ -3703,19 +3707,22 @@ namespace grb { // scalar coda for( size_t i = end * block_size; i < n; ++i ) { if( mask_coors.template mask< descr >( i, mask_p ) ) { - if( !dense ) { -#ifdef _H_GRB_REFERENCE_OMP_BLAS1 - if( !z_coors.asyncAssign( i, update ) ) { - (void) ++asyncAssigns; - } - if( asyncAssigns == maxAsyncAssigns ) { - (void) z_coors.joinUpdate( update ); - asyncAssigns = 0; + if( left_sparse && right_sparse ) { + if( !left_coors->assigned( i ) && !right_coors->assigned( i ) ) { + continue; } + } +#ifdef _H_GRB_REFERENCE_OMP_BLAS1 + if( !z_coors.asyncAssign( i, update ) ) { + (void) ++asyncAssigns; + } + if( asyncAssigns == maxAsyncAssigns ) { + (void) z_coors.joinUpdate( update ); + asyncAssigns = 0; + } #else - (void) z_coors.assign( i ); + (void) z_coors.assign( i ); #endif - } const InputType1 * const x_e = left_scalar ? x_p : ( @@ -3833,19 +3840,17 @@ namespace grb { } for( size_t t = 0; t < block_size; ++t ) { if( mask_b[ t ] ) { - if( !dense ) { #ifndef _H_GRB_REFERENCE_OMP_BLAS1 - (void) z_coors.assign( indices[ t ] ); + (void) z_coors.assign( indices[ t ] ); #else - if( !z_coors.asyncAssign( indices[ t ], update ) ) { - (void) ++asyncAssigns; + if( !z_coors.asyncAssign( indices[ t ], update ) ) { + (void) ++asyncAssigns; #ifdef _DEBUG - std::cout << "\t\t now made " << asyncAssigns << " calls to asyncAssign; " - << "added index " << indices[ t ] << "\n"; -#endif - } + std::cout << "\t\t now made " << asyncAssigns << " calls to asyncAssign; " + << "added index " << indices[ t ] << "\n"; #endif } +#endif GRB_UTIL_IGNORE_MAYBE_UNINITIALIZED // z_b is computed from x_b and *( z_p + indices[ t ] ) = z_b[ t ]; // y_b, which are both initialised GRB_UTIL_RESTORE_WARNINGS // if mask_b is true @@ -3872,29 +3877,25 @@ namespace grb { continue; } } - if( !dense ) { #ifndef _H_GRB_REFERENCE_OMP_BLAS1 - (void) z_coors.assign( i ); + (void) z_coors.assign( i ); #else - if( !z_coors.asyncAssign( i, update ) ) { - (void) ++asyncAssigns; - } - if( asyncAssigns == maxAsyncAssigns ) { - (void) z_coors.joinUpdate( update ); - asyncAssigns = 0; - } -#endif + if( !z_coors.asyncAssign( i, update ) ) { + (void) ++asyncAssigns; + } + if( asyncAssigns == maxAsyncAssigns ) { + (void) z_coors.joinUpdate( update ); + asyncAssigns = 0; } +#endif const InputType1 * const x_e = left_scalar ? - x_p : - ( + x_p : ( (!left_sparse || left_coors->assigned( i )) ? x_p + i : left_identity - ); + ); const InputType2 * const y_e = right_scalar ? - y_p : - ( + y_p : ( (!right_sparse || right_coors->assigned( i )) ? y_p + i : right_identity @@ -4008,6 +4009,10 @@ namespace grb { if( internal::getCoordinates( x ).size() != n ) { return MISMATCH; } + if( descr & descriptors::dense ) { + if( nnz( z ) < size( z ) ) { return ILLEGAL; } + if( nnz( x ) < size( x ) ) { return ILLEGAL; } + } if( phase == RESIZE ) { return SUCCESS; @@ -4067,6 +4072,9 @@ namespace grb { #ifdef _DEBUG std::cout << "In eWiseApply ([T1]<-T2<-T3), operator variant\n"; #endif + if( (descr & descriptors::dense) && nnz( z ) < size( z ) ) { + return ILLEGAL; + } if( phase == RESIZE ) { return SUCCESS; } @@ -4149,6 +4157,11 @@ namespace grb { if( internal::getCoordinates( mask ).size() != n ) { return MISMATCH; } + if( descr & descriptors::dense ) { + if( nnz( z ) < size( z ) ) { return ILLEGAL; } + if( nnz( x ) < size( x ) ) { return ILLEGAL; } + if( nnz( mask ) < size( mask ) ) { return ILLEGAL; } + } if( phase == RESIZE ) { return SUCCESS; @@ -4227,6 +4240,11 @@ namespace grb { if( internal::getCoordinates( y ).size() != n ) { return MISMATCH; } + if( descr & descriptors::dense ) { + if( nnz( z ) < size( z ) ) { return ILLEGAL; } + if( nnz( x ) < size( x ) ) { return ILLEGAL; } + if( nnz( y ) < size( y ) ) { return ILLEGAL; } + } if( phase == RESIZE ) { return SUCCESS; @@ -4294,6 +4312,10 @@ namespace grb { if( internal::getCoordinates( y ).size() != n ) { return MISMATCH; } + if( descr & descriptors::dense ) { + if( nnz( y ) < size( y ) ) { return ILLEGAL; } + if( nnz( z ) < size( z ) ) { return ILLEGAL; } + } if( phase == RESIZE ) { return SUCCESS; @@ -4334,7 +4356,8 @@ namespace grb { typename OutputType, typename InputType1, typename InputType2, typename Coords > - RC eWiseApply( Vector< OutputType, reference, Coords > &z, + RC eWiseApply( + Vector< OutputType, reference, Coords > &z, const Vector< InputType1, reference, Coords > &x, const InputType2 beta, const Monoid &monoid = Monoid(), @@ -4353,6 +4376,10 @@ namespace grb { if( internal::getCoordinates( x ).size() != n ) { return MISMATCH; } + if( (descr & descriptors::dense) ) { + if( nnz( z ) < size( z ) ) { return ILLEGAL; } + if( nnz( x ) < size( x ) ) { return ILLEGAL; } + } if( phase == RESIZE ) { return SUCCESS; @@ -4393,7 +4420,8 @@ namespace grb { typename InputType1, typename InputType2, typename Coords > - RC eWiseApply( Vector< OutputType, reference, Coords > &z, + RC eWiseApply( + Vector< OutputType, reference, Coords > &z, const Vector< MaskType, reference, Coords > &mask, const Vector< InputType1, reference, Coords > &x, const Vector< InputType2, reference, Coords > &y, @@ -4425,6 +4453,12 @@ namespace grb { if( internal::getCoordinates( mask ).size() != n ) { return MISMATCH; } + if( (descr & descriptors::dense) ) { + if( nnz( z ) < size( z ) ) { return ILLEGAL; } + if( nnz( x ) < size( x ) ) { return ILLEGAL; } + if( nnz( y ) < size( y ) ) { return ILLEGAL; } + if( nnz( mask ) < size( mask ) ) { return ILLEGAL; } + } if( phase == RESIZE ) { return SUCCESS; @@ -4533,6 +4567,11 @@ namespace grb { if( internal::getCoordinates( mask ).size() != n ) { return MISMATCH; } + if( descr & descriptors::dense ) { + if( nnz( z ) < size( z ) ) { return ILLEGAL; } + if( nnz( y ) < size( y ) ) { return ILLEGAL; } + if( nnz( mask ) < size( mask ) ) { return ILLEGAL; } + } if( phase == RESIZE ) { return SUCCESS; @@ -4607,6 +4646,11 @@ namespace grb { if( internal::getCoordinates( mask ).size() != n ) { return MISMATCH; } + if( descr & descriptors::dense ) { + if( nnz( z ) < size( z ) ) { return ILLEGAL; } + if( nnz( x ) < size( x ) ) { return ILLEGAL; } + if( nnz( mask ) < size( mask ) ) { return ILLEGAL; } + } if( phase == RESIZE ) { return SUCCESS; @@ -4723,24 +4767,31 @@ namespace grb { #ifdef _DEBUG std::cout << "In eWiseApply ([T1]<-T2<-[T3]), operator variant\n"; #endif - // sanity check + // dynamic sanity checks const size_t n = internal::getCoordinates( z ).size(); if( internal::getCoordinates( y ).size() != n ) { return MISMATCH; } + if( descr & descriptors::dense ) { + if( nnz( z ) < size( z ) ) { return ILLEGAL; } + if( nnz( y ) < size( y ) ) { return ILLEGAL; } + } - if( phase == RESIZE ) { + // check for trivial op + if( n == 0 ) { return SUCCESS; } - assert( phase == EXECUTE ); // check if we can dispatch - if( static_cast< const void * >( &z ) == - static_cast< const void * >( &y ) - ) { + if( getID( z ) == getID( y ) ) { return foldr< descr >( alpha, z, op ); } + if( phase == RESIZE ) { + return SUCCESS; + } + assert( phase == EXECUTE ); + // check for dense variant if( (descr & descriptors::dense) || internal::getCoordinates( y ).nonzeroes() == n @@ -4754,6 +4805,7 @@ namespace grb { } // we are in the sparse variant + internal::getCoordinates( z ).clear(); const bool * const null_mask = nullptr; const Coords * const null_coors = nullptr; return internal::sparse_apply_generic< false, false, true, false, descr >( @@ -4798,29 +4850,34 @@ namespace grb { return eWiseApply< descr >( z, alpha, y, op ); } - // sanity check - const size_t n = internal::getCoordinates( z ).size(); + // check delegate to unmasked + const size_t n = internal::getCoordinates( mask ).size(); + const auto &mask_coors = internal::getCoordinates( mask ); + if( (descr & descriptors::structural) && + !(descr & descriptors::invert_mask) && + mask_coors.nonzeroes() == n + ) { + return eWiseApply< descr >( z, alpha, y, op ); + } + + // sanity checks if( internal::getCoordinates( y ).size() != n ) { return MISMATCH; } - if( internal::getCoordinates( mask ).size() != n ) { + if( internal::getCoordinates( z ).size() != n ) { return MISMATCH; } + if( descr & descriptors::dense ) { + if( nnz( z ) < size( z ) ) { return ILLEGAL; } + if( nnz( y ) < size( y ) ) { return ILLEGAL; } + if( nnz( mask ) < size( mask ) ) { return ILLEGAL; } + } if( phase == RESIZE ) { return SUCCESS; } assert( phase == EXECUTE ); - // check delegate to unmasked - const auto &mask_coors = internal::getCoordinates( mask ); - if( (descr & descriptors::structural) && - !(descr & descriptors::invert_mask) && - mask_coors.nonzeroes() == n - ) { - return eWiseApply< descr >( z, alpha, y, op ); - } - auto &z_coors = internal::getCoordinates( z ); OutputType * const z_p = internal::getRaw( z ); const MaskType * const mask_p = internal::getRaw( mask ); @@ -4933,7 +4990,7 @@ namespace grb { #ifdef _DEBUG std::cout << "In eWiseApply ([T1]<-[T2]<-[T3]), operator variant\n"; #endif - // sanity check + // dynamic sanity checks auto &z_coors = internal::getCoordinates( z ); const size_t n = z_coors.size(); if( internal::getCoordinates( x ).size() != n || @@ -4944,17 +5001,25 @@ namespace grb { #endif return MISMATCH; } + if( descr & descriptors::dense ) { + if( nnz( z ) < size( z ) ) { return ILLEGAL; } + if( nnz( x ) < size( x ) ) { return ILLEGAL; } + if( nnz( y ) < size( y ) ) { return ILLEGAL; } + } - // check for possible shortcuts - if( static_cast< const void * >( &x ) == static_cast< const void * >( &y ) && - is_idempotent< OP >::value - ) { + // trivial dispatch + if( n == 0 ) { + return SUCCESS; + } + + // check for possible shortcuts, after dynamic checks + if( getID( x ) == getID( y ) && is_idempotent< OP >::value ) { return set< descr >( z, x, phase ); } - if( static_cast< const void * >( &x ) == static_cast< void * >( &z ) ) { + if( getID( x ) == getID( z ) ) { return foldl< descr >( z, y, op, phase ); } - if( static_cast< const void * >( &y ) == static_cast< void * >( &z ) ) { + if( getID( y ) == getID( z ) ) { return foldr< descr >( x, z, op, phase ); } @@ -5048,19 +5113,34 @@ namespace grb { return eWiseApply< descr >( z, x, y, op, phase ); } + // check if can delegate to unmasked variant + const auto &m_coors = internal::getCoordinates( mask ); + const size_t n = m_coors.size(); + if( m_coors.nonzeroes() == n && + (descr & descriptors::structural) && + !(descr & descriptors::invert_mask) + ) { + return eWiseApply< descr >( z, x, y, op ); + } + // other run-time checks auto &z_coors = internal::getCoordinates( z ); const auto &mask_coors = internal::getCoordinates( mask ); - const size_t n = z_coors.size(); if( internal::getCoordinates( x ).size() != n ) { return MISMATCH; } if( internal::getCoordinates( y ).size() != n ) { return MISMATCH; } - if( mask_coors.size() != n ) { + if( z_coors.size() != n ) { return MISMATCH; } + if( descr & descriptors::dense ) { + if( nnz( z ) < size( z ) ) { return ILLEGAL; } + if( nnz( x ) < size( x ) ) { return ILLEGAL; } + if( nnz( y ) < size( y ) ) { return ILLEGAL; } + if( nnz( mask ) < size( mask ) ) { return ILLEGAL; } + } if( phase == RESIZE ) { return SUCCESS; @@ -5073,18 +5153,9 @@ namespace grb { const InputType2 * const y_p = internal::getRaw( y ); const auto &x_coors = internal::getCoordinates( x ); const auto &y_coors = internal::getCoordinates( y ); - const auto &m_coors = internal::getCoordinates( mask ); const size_t sparse_loop = std::min( x_coors.nonzeroes(), y_coors.nonzeroes() ); - // check if can delegate to unmasked variant - if( m_coors.nonzeroes() == n && - (descr & descriptors::structural) && - !(descr & descriptors::invert_mask) - ) { - return eWiseApply< descr >( z, x, y, op ); - } - // the output sparsity structure is unknown a priori z_coors.clear(); diff --git a/tests/unit/ewiseapply.cpp b/tests/unit/ewiseapply.cpp index fccc565b5..20fe590a1 100644 --- a/tests/unit/ewiseapply.cpp +++ b/tests/unit/ewiseapply.cpp @@ -22,7 +22,7 @@ using namespace grb; -void grb_program( const size_t & n, grb::RC & rc ) { +void grb_program( const size_t &n, grb::RC &rc ) { grb::Vector< double > out( n ), left( n ), right( n ); grb::Vector< bool > mask( n ); grb::Vector< size_t > temp( n ); @@ -59,6 +59,7 @@ void grb_program( const size_t & n, grb::RC & rc ) { // test operator versions first, dense vectors only, without masks rc = grb::eWiseApply( out, left, 0.25, plusM.getOperator() ); + assert( rc == SUCCESS ); if( rc == SUCCESS ) { if( nnz( out ) != size( out ) ) { std::cerr << "\tunexpected number of nonzeroes ( " << nnz( out ) << " ), " @@ -81,6 +82,7 @@ void grb_program( const size_t & n, grb::RC & rc ) { } rc = grb::eWiseApply( out, 0.25, left, plusM.getOperator() ); + assert( rc == SUCCESS ); if( rc == SUCCESS ) { if( nnz( out ) != size( out ) ) { std::cerr << "\tunexpected number of nonzeroes ( " << nnz( out ) << ", " @@ -102,6 +104,7 @@ void grb_program( const size_t & n, grb::RC & rc ) { } rc = grb::eWiseApply( out, left, left, plusM.getOperator() ); + assert( rc == SUCCESS ); if( rc == SUCCESS ) { if( nnz( out ) != size( out ) ) { std::cerr << "\tunexpected number of nonzeroes ( " << nnz( out ) << ", " @@ -124,6 +127,7 @@ void grb_program( const size_t & n, grb::RC & rc ) { // operator versions, dense vectors only, with masks rc = grb::eWiseApply( out, mask, left, 0.25, plusM.getOperator() ); + assert( rc == SUCCESS ); if( rc == SUCCESS ) { if( grb::nnz( out ) != grb::nnz( mask ) ) { std::cerr << "\tunexpected number of nonzeroes ( " << grb::nnz( out ) @@ -150,7 +154,9 @@ void grb_program( const size_t & n, grb::RC & rc ) { } else { return; } + rc = grb::eWiseApply( out, mask, 0.25, left, plusM.getOperator() ); + assert( rc == SUCCESS ); if( rc == SUCCESS ) { if( grb::nnz( out ) != grb::nnz( mask ) ) { std::cerr << "\tunexpected number of nonzeroes ( " << grb::nnz( out ) @@ -176,7 +182,9 @@ void grb_program( const size_t & n, grb::RC & rc ) { } else { return; } + rc = grb::eWiseApply( out, mask, left, left, plusM.getOperator() ); + assert( rc == SUCCESS ); if( rc == SUCCESS ) { if( grb::nnz( out ) != grb::nnz( mask ) ) { std::cerr << "\tunexpected number of nonzeroes ( " << grb::nnz( out ) @@ -205,6 +213,7 @@ void grb_program( const size_t & n, grb::RC & rc ) { // monoid version, dense vectors, unmasked rc = grb::eWiseApply( out, left, 0.25, plusM ); + assert( rc == SUCCESS ); if( rc == SUCCESS ) { if( nnz( out ) != size( out ) ) { std::cerr << "\tunexpected number of nonzeroes ( " << nnz( out ) << ", " @@ -226,6 +235,7 @@ void grb_program( const size_t & n, grb::RC & rc ) { } rc = grb::eWiseApply( out, 0.25, left, plusM ); + assert( rc == SUCCESS ); if( rc == SUCCESS ) { if( nnz( out ) != size( out ) ) { std::cerr << "\tunexpected number of nonzeroes ( " << nnz( out ) << ", " @@ -247,6 +257,7 @@ void grb_program( const size_t & n, grb::RC & rc ) { } rc = grb::eWiseApply( out, left, left, plusM.getOperator() ); + assert( rc == SUCCESS ); if( rc == SUCCESS ) { if( nnz( out ) != size( out ) ) { std::cerr << "\tunexpected number of nonzeroes ( " << nnz( out ) @@ -269,6 +280,7 @@ void grb_program( const size_t & n, grb::RC & rc ) { // monoid versions, dense vectors, with masks rc = grb::eWiseApply( out, mask, left, 0.25, plusM ); + assert( rc == SUCCESS ); if( rc == SUCCESS ) { if( grb::nnz( out ) != grb::nnz( mask ) ) { std::cerr << "\tunexpected number of nonzeroes ( " << grb::nnz( out ) @@ -294,7 +306,9 @@ void grb_program( const size_t & n, grb::RC & rc ) { } else { return; } + rc = grb::eWiseApply( out, mask, 0.25, left, plusM ); + assert( rc == SUCCESS ); if( rc == SUCCESS ) { if( grb::nnz( out ) != grb::nnz( mask ) ) { std::cerr << "\tunexpected number of nonzeroes ( " << grb::nnz( out ) @@ -320,7 +334,9 @@ void grb_program( const size_t & n, grb::RC & rc ) { } else { return; } + rc = grb::eWiseApply( out, mask, left, left, plusM ); + assert( rc == SUCCESS ); if( rc == SUCCESS ) { if( grb::nnz( out ) != grb::nnz( mask ) ) { std::cerr << "\tunexpected number of nonzeroes ( " << grb::nnz( out ) @@ -349,6 +365,7 @@ void grb_program( const size_t & n, grb::RC & rc ) { // monoid version, sparse vectors, unmasked rc = grb::eWiseApply( out, right, 0.25, plusM ); + assert( rc == SUCCESS ); if( rc == SUCCESS ) { if( nnz( out ) != size( out ) ) { std::cerr << "\tunexpected number of nonzeroes ( " << nnz( out ) << ", " @@ -378,6 +395,7 @@ void grb_program( const size_t & n, grb::RC & rc ) { } rc = grb::eWiseApply( out, 0.25, right, plusM ); + assert( rc == SUCCESS ); if( rc == SUCCESS ) { if( nnz( out ) != size( out ) ) { std::cerr << "\tunexpected number of nonzeroes ( " << nnz( out ) << " ), " @@ -407,6 +425,7 @@ void grb_program( const size_t & n, grb::RC & rc ) { } rc = grb::eWiseApply( out, left, right, plusM ); + assert( rc == SUCCESS ); if( rc == SUCCESS ) { if( nnz( out ) != size( out ) ) { std::cerr << "\tunexpected number of nonzeroes ( " << nnz( out ) << " ), " @@ -436,6 +455,7 @@ void grb_program( const size_t & n, grb::RC & rc ) { } rc = grb::eWiseApply( out, right, left, plusM ); + assert( rc == SUCCESS ); if( rc == SUCCESS ) { if( nnz( out ) != size( right ) ) { std::cerr << "\tunexpected number of nonzeroes ( " << nnz( out ) << ", " @@ -465,6 +485,7 @@ void grb_program( const size_t & n, grb::RC & rc ) { } rc = grb::eWiseApply( out, right, right, plusM ); + assert( rc == SUCCESS ); if( rc == SUCCESS ) { if( nnz( out ) != nnz( right ) ) { std::cerr << "\tunexpected number of nonzeroes ( " << nnz( out ) << ", " @@ -493,6 +514,7 @@ void grb_program( const size_t & n, grb::RC & rc ) { // monoid version, sparse vectors, with masks rc = grb::eWiseApply( out, mask, right, 0.25, plusM ); + assert( rc == SUCCESS ); if( rc == SUCCESS ) { if( nnz( out ) != size( out ) / 2 ) { std::cerr << "\tunexpected number of nonzeroes ( " << nnz( out ) << ", " @@ -528,6 +550,7 @@ void grb_program( const size_t & n, grb::RC & rc ) { } rc = grb::eWiseApply( out, mask, 0.25, right, plusM ); + assert( rc == SUCCESS ); if( rc == SUCCESS ) { if( nnz( out ) != size( out ) / 2 ) { std::cerr << "\tunexpected number of nonzeroes ( " << nnz( out ) << ", " @@ -563,6 +586,7 @@ void grb_program( const size_t & n, grb::RC & rc ) { } rc = grb::eWiseApply( out, mask, left, right, plusM ); + assert( rc == SUCCESS ); if( rc == SUCCESS ) { if( nnz( out ) != size( out ) / 2 ) { std::cerr << "\tunexpected number of nonzeroes ( " << nnz( out ) << ", " @@ -598,6 +622,7 @@ void grb_program( const size_t & n, grb::RC & rc ) { } rc = grb::eWiseApply( out, mask, right, left, plusM ); + assert( rc == SUCCESS ); if( rc == SUCCESS ) { if( nnz( out ) != size( right ) / 2 ) { std::cerr << "\tunexpected number of nonzeroes ( " << nnz( out ) << ", " @@ -633,6 +658,7 @@ void grb_program( const size_t & n, grb::RC & rc ) { } rc = grb::eWiseApply( out, mask, right, right, plusM ); + assert( rc == SUCCESS ); if( rc == SUCCESS ) { if( nnz( out ) != nnz( right ) / 2 ) { std::cerr << "\tunexpected number of nonzeroes ( " << nnz( out ) << ", "