diff --git a/include/graphblas/reference/blas1.hpp b/include/graphblas/reference/blas1.hpp index ab31e6e3a..853add992 100644 --- a/include/graphblas/reference/blas1.hpp +++ b/include/graphblas/reference/blas1.hpp @@ -374,7 +374,11 @@ namespace grb { const Vector< MaskType, reference, Coords > &mask, const Monoid &monoid ) { - const size_t n = internal::getCoordinates( to_fold ).size(); +#ifdef _DEBUG + std::cout << "Entered fold_from_vector_to_scalar_fullLoopSparse\n"; +#endif + const auto &to_fold_coors = internal::getCoordinates( to_fold ); + const size_t n = to_fold_coors.size(); assert( n > 0 ); RC ret = SUCCESS; #ifdef _H_GRB_REFERENCE_OMP_BLAS1 @@ -400,7 +404,7 @@ namespace grb { internal::getCoordinates( mask ).assigned( i ), internal::getRaw( mask ), i - ); + ) && to_fold_coors.assigned( i ); // if not while( !process_current_i ) { // forward to next element @@ -414,20 +418,26 @@ namespace grb { internal::getCoordinates( mask ).assigned( i ), internal::getRaw( mask ), i - ); + ) && to_fold_coors.assigned( i ); + } + } + if( !masked && i < end ) { + process_current_i = to_fold_coors.assigned( i ); + while( !process_current_i ) { + (void) ++i; + if( i == end ) { + break; + } + process_current_i = to_fold_coors.assigned( i ); } } // whether we have any nonzeroes assigned at all const bool empty = i >= end; - #ifndef _H_GRB_REFERENCE_OMP_BLAS1 - // in the sequential case, the empty case should have been handled earlier - assert( !empty ); - #ifdef NDEBUG (void) empty; - #endif #endif + #ifndef NDEBUG if( i < end ) { assert( i < n ); @@ -439,13 +449,13 @@ namespace grb { monoid.template getIdentity< typename Monoid::D3 >(); if( end > 0 ) { if( i < end ) { +#ifdef _DEBUG + std::cout << "\t processing start index " << i << "\n"; +#endif + local = static_cast< typename Monoid::D3 >( internal::getRaw( to_fold )[ i ] ); - } else { - local = static_cast< typename Monoid::D3 >( - internal::getRaw( to_fold )[ 0 ] - ); } } @@ -465,25 +475,44 @@ namespace grb { internal::getCoordinates( mask ).assigned( i ), internal::getRaw( mask ), i - ); - while( !process_current_i && i + 1 < end ) { + ) && to_fold_coors.assigned( i ); + while( !process_current_i ) { (void) ++i; - if( i < end ) { - assert( i < n ); - process_current_i = utils::interpretMask< descr >( - internal::getCoordinates( mask ).assigned( i ), - internal::getRaw( mask ), - i - ); + if( i == end ) { + break; + } + assert( i < end ); + assert( i < n ); + process_current_i = utils::interpretMask< descr >( + internal::getCoordinates( mask ).assigned( i ), + internal::getRaw( mask ), + i + ) && to_fold_coors.assigned( i ); + } + } + if( !masked && i < end ) { + assert( i < n ); + process_current_i = to_fold_coors.assigned( i ); + while( !process_current_i ) { + (void) ++i; + if( i == end ) { + break; } + assert( i < end ); + assert( i < n ); + process_current_i = to_fold_coors.assigned( i ); } } // stop if past end - if( i >= end || !process_current_i ) { + if( i >= end ) { break; } +#ifdef _DEBUG + std::cout << "\t processing index " << i << "\n"; +#endif + // store result of fold in local variable RC local_rc; diff --git a/tests/unit/launcher/reduce.cpp b/tests/unit/launcher/reduce.cpp index a0e3e4abe..9c5d9192a 100644 --- a/tests/unit/launcher/reduce.cpp +++ b/tests/unit/launcher/reduce.cpp @@ -47,7 +47,6 @@ int expect_mismatch( error = true; } - rc = foldr< descr >( v1, v0, alpha, mon ); if( rc != grb::MISMATCH ) { std::cerr << "\t mismatched call to foldr ([T]->T, masked) " @@ -499,7 +498,7 @@ void grbProgram( const size_t &P, int &exit_status ) { // do similar happy path testing, but now for sparse inputs { - grb::Vector< double > sparse( n ), empty( n ), single( n ); + grb::Vector< double > sparse( n ), empty( n ), single( n ), singleFirst( n ); grb::Vector< bool > empty_mask( n ), odd_mask( n ), half_mask( n ), full( n ); grb::RC rc = grb::set( sparse, even_mask, 1.0 ); assert( rc == grb::SUCCESS ); @@ -507,6 +506,8 @@ void grbProgram( const size_t &P, int &exit_status ) { assert( rc == grb::SUCCESS ); rc = rc ? rc : grb::setElement( single, 3.141, n/2 ); assert( rc == grb::SUCCESS ); + rc = rc ? rc : grb::setElement( singleFirst, -1.7, 0 ); + assert( rc == grb::SUCCESS ); rc = rc ? rc : grb::setElement( half_mask, true, n/2 ); assert( rc == grb::SUCCESS ); for( size_t i = 1; rc == grb::SUCCESS && i < n; i += 2 ) { @@ -628,6 +629,25 @@ void grbProgram( const size_t &P, int &exit_status ) { return; } + { + grb::Vector< bool > tmpMask( n ); + rc = grb::setElement( tmpMask, true, 0 ); + rc = rc ? rc : grb::setElement( tmpMask, false, n / 2 ); + if( rc != grb::SUCCESS ) { + exit_status = 1401; + return; + } + exit_status = expect_sparse_success< + grb::descriptors::structural | grb::descriptors::invert_mask + >( + singleFirst, realm, 0, tmpMask, -1.7 + ); + if( exit_status != 0 ) { + exit_status += 1400; + return; + } + } + // warning: below set of two tests alter half_mask { double expect = (n/2) % 2 == 0 @@ -636,7 +656,7 @@ void grbProgram( const size_t &P, int &exit_status ) { exit_status = expect_sparse_success< grb::descriptors::structural >( sparse, realm, expect, half_mask, grb::nnz(sparse) ); if( exit_status != 0 ) { - exit_status += 1400; + exit_status += 1500; return; } @@ -650,12 +670,12 @@ void grbProgram( const size_t &P, int &exit_status ) { exit_status = expect_sparse_success< grb::descriptors::no_operation >( sparse, realm, expect, half_mask, grb::nnz(sparse) ); } else { - exit_status = 1532; + exit_status = 1632; return; } if( exit_status != 0 ) { - exit_status += 1500; + exit_status += 1600; return; } }