diff --git a/include/graphblas/reference/compressed_storage.hpp b/include/graphblas/reference/compressed_storage.hpp index 34d2e99f1..fa1aac97c 100644 --- a/include/graphblas/reference/compressed_storage.hpp +++ b/include/graphblas/reference/compressed_storage.hpp @@ -1175,12 +1175,19 @@ namespace grb { /** * \internal copyFrom specialisation for pattern matrices. */ - template< bool use_id, typename InputType, typename UnusedType = void > + template< + bool use_id = false, + typename InputType, + typename UnusedType = void + > void copyFrom( const Compressed_Storage< InputType, IND, SIZE > &other, const size_t nz, const size_t m, const size_t start, size_t end, const UnusedType * __restrict__ = nullptr ) { + // the use_id template is meaningless in the case of pattern matrices, but + // is retained to keep the API the same as with the non-pattern case. + (void) use_id; #ifdef _DEBUG std::cout << "CompressedStorage::copyFrom (void) called with range " << start << "--" << end << "\n"; diff --git a/include/graphblas/reference/matrix.hpp b/include/graphblas/reference/matrix.hpp index b5fbd2b96..3088eab23 100644 --- a/include/graphblas/reference/matrix.hpp +++ b/include/graphblas/reference/matrix.hpp @@ -1360,9 +1360,9 @@ namespace grb { sizes[ 3 ] = internal::Coordinates< reference >::bufferSize( cols ); sizes[ 4 ] = rows * internal::SizeOf< D >::value; sizes[ 5 ] = cols * internal::SizeOf< D >::value; + CRS.getStartAllocSize( &( sizes[ 6 ] ), rows ); + CCS.getStartAllocSize( &( sizes[ 7 ] ), cols ); if( cap_in > 0 ) { - CRS.getStartAllocSize( &( sizes[ 6 ] ), rows ); - CCS.getStartAllocSize( &( sizes[ 7 ] ), cols ); CRS.getAllocSize( &(sizes[ 8 ]), cap_in ); CCS.getAllocSize( &(sizes[ 10 ]), cap_in ); } else { @@ -1576,7 +1576,7 @@ namespace grb { char * alloc[ 4 ] = { nullptr, nullptr, nullptr, nullptr }; size_t sizes[ 4 ]; // cache old allocation data - size_t old_sizes[ 4 ]; + size_t old_sizes[ 4 ] = { 0, 0, 0, 0 }; size_t freed = 0; if( cap > 0 ) { CRS.getAllocSize( &( old_sizes[ 0 ] ), cap ); @@ -1632,7 +1632,6 @@ namespace grb { return SUCCESS; } - /** * @see Matrix::buildMatrixUnique. * diff --git a/tests/unit/CMakeLists.txt b/tests/unit/CMakeLists.txt index 46170dc55..ff9891cb5 100644 --- a/tests/unit/CMakeLists.txt +++ b/tests/unit/CMakeLists.txt @@ -204,6 +204,10 @@ add_grb_executables( zip zip.cpp BACKENDS reference reference_omp bsp1d hybrid hyperdags ) +add_grb_executables( copyVoidMatrices copyVoidMatrices.cpp + BACKENDS reference reference_omp bsp1d hybrid hyperdags +) + add_grb_executables( masked_muladd masked_muladd.cpp BACKENDS reference reference_omp bsp1d hybrid hyperdags ) diff --git a/tests/unit/clearMatrix.cpp b/tests/unit/clearMatrix.cpp index 983077d83..857036b0b 100644 --- a/tests/unit/clearMatrix.cpp +++ b/tests/unit/clearMatrix.cpp @@ -1,4 +1,3 @@ - /* * Copyright 2021 Huawei Technologies Co., Ltd. * @@ -22,6 +21,7 @@ #include + using namespace grb; void grb_program( const size_t &n, grb::RC &rc ) { @@ -29,9 +29,12 @@ void grb_program( const size_t &n, grb::RC &rc ) { grb::Vector< double > vector( n ); rc = grb::set< grb::descriptors::use_index >( vector, 0 ); if( rc == SUCCESS ) { - auto converter = grb::utils::makeVectorToMatrixConverter< double >( vector, []( const size_t &ind, const double &val ) { - return std::make_pair( std::make_pair( ind, ind ), val ); - } ); + auto converter = grb::utils::makeVectorToMatrixConverter< double >( + vector, + []( const size_t &ind, const double &val ) { + return std::make_pair( std::make_pair( ind, ind ), val ); + } + ); auto start = converter.begin(); auto end = converter.end(); rc = grb::buildMatrixUnique( diag, start, end, PARALLEL ); @@ -51,7 +54,8 @@ void grb_program( const size_t &n, grb::RC &rc ) { } if( grb::nnz( diag ) != 0 ) { - std::cerr << "\t unexpected number of nonzeroes in matrix ( " << grb::nnz( diag ) << " ), expected 0\n"; + std::cerr << "\t unexpected number of nonzeroes in matrix " + << "( " << grb::nnz( diag ) << " ), expected 0\n"; rc = FAILED; } @@ -87,8 +91,8 @@ int main( int argc, char ** argv ) { } if( printUsage ) { std::cerr << "Usage: " << argv[ 0 ] << " [n]\n"; - std::cerr << " -n (optional, default is 100): an even integer, the " - "test size.\n"; + std::cerr << " -n (optional, default is 100): an even integer, " + << "the test size.\n"; return 1; } @@ -96,13 +100,15 @@ int main( int argc, char ** argv ) { grb::Launcher< AUTOMATIC > launcher; grb::RC out; if( launcher.exec( &grb_program, in, out, true ) != SUCCESS ) { - std::cerr << "Launching test FAILED\n"; + std::cerr << "Launching test FAILED\n" << std::endl; return 255; } if( out != SUCCESS ) { - std::cerr << "Test FAILED (" << grb::toString( out ) << ")" << std::endl; + std::cerr << std::flush; + std::cout << "Test FAILED (" << grb::toString( out ) << ")\n" << std::endl; } else { - std::cout << "Test OK" << std::endl; + std::cout << "Test OK\n" << std::endl; } return 0; } + diff --git a/tests/unit/copyVoidMatrices.cpp b/tests/unit/copyVoidMatrices.cpp new file mode 100644 index 000000000..0f487fd1b --- /dev/null +++ b/tests/unit/copyVoidMatrices.cpp @@ -0,0 +1,148 @@ +/* + * Copyright 2021 Huawei Technologies Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include + +#include + + +using namespace grb; + +void grb_program( const size_t &n, grb::RC &rc ) { + grb::Matrix< void > A( n, n, n ); + + try { + grb::Matrix< void > C( A ); + } catch( ... ) { + std::cerr << " Copying from empty void matrix failed!\n"; + rc = FAILED; + return; + } + + { + grb::Matrix< double > B( n, n, n ); + grb::Vector< double > vector( n ); + rc = grb::set< grb::descriptors::use_index >( vector, 0 ); + if( rc == SUCCESS ) { + auto converter = grb::utils::makeVectorToMatrixConverter< double >( + vector, + []( const size_t &ind, const double &val ) { + return std::make_pair( std::make_pair( ind, ind ), val ); + } + ); + auto start = converter.begin(); + auto end = converter.end(); + rc = grb::buildMatrixUnique( B, start, end, PARALLEL ); + } + if( rc == SUCCESS ) { + rc = grb::set( A, B ); + } + grb::Matrix< void > C( n, n, 0 ); + if( rc == SUCCESS ) { + rc = grb::set( C, A, RESIZE ); + } + if( rc == SUCCESS ) { + rc = grb::set( C, A ); + } + } + if( rc != SUCCESS || grb::nnz( A ) != n ) { + std::cerr << "\t initialisation FAILED\n"; + if( rc == SUCCESS ) { + rc = FAILED; + } + return; + } + + try { + grb::Matrix< void > C( A ); + } catch( ... ) { + std::cerr << " Copying from non-empty void matrix failed!\n"; + rc = FAILED; + return; + } + + rc = grb::clear( A ); + if( rc != SUCCESS ) { + std::cerr << "\t clear matrix FAILED\n"; + return; + } + + if( grb::nnz( A ) != 0 ) { + std::cerr << "\t unexpected number of nonzeroes in matrix " + << "( " << grb::nnz( A ) << " ), expected 0\n"; + rc = FAILED; + } + + try { + grb::Matrix< void > C( A ); + } catch( ... ) { + std::cerr << " Copying from cleared void matrix failed!\n"; + rc = FAILED; + return; + } + + // done + return; +} + +int main( int argc, char ** argv ) { + // defaults + bool printUsage = false; + size_t in = 100; + + // error checking + if( argc > 2 ) { + printUsage = true; + } + if( argc == 2 ) { + size_t read; + std::istringstream ss( argv[ 1 ] ); + if( ! ( ss >> read ) ) { + std::cerr << "Error parsing first argument\n"; + printUsage = true; + } else if( ! ss.eof() ) { + std::cerr << "Error parsing first argument\n"; + printUsage = true; + } else { + // all OK + in = read; + } + } + if( printUsage ) { + std::cerr << "Usage: " << argv[ 0 ] << " [n]\n"; + std::cerr << " -n (optional, default is 100): an integer test size.\n"; + return 1; + } + + std::cout << "This is functional test " << argv[ 0 ] << "\n"; + grb::Launcher< AUTOMATIC > launcher; + grb::RC out; + if( launcher.exec( &grb_program, in, out, true ) != SUCCESS ) { + std::cerr << "Launching test FAILED\n" << std::endl; + return 255; + } + if( out != SUCCESS ) { + std::cerr << std::flush; + std::cout << "Test FAILED (" << grb::toString( out ) << ")\n" << std::endl; + } else { + std::cout << "Test OK\n" << std::endl; + } + return 0; +} + diff --git a/tests/unit/unittests.sh b/tests/unit/unittests.sh index 1de016563..85105a42f 100755 --- a/tests/unit/unittests.sh +++ b/tests/unit/unittests.sh @@ -228,6 +228,13 @@ for MODE in debug ndebug; do grep 'Test OK' ${TEST_OUT_DIR}/zip_large_${MODE}_${BACKEND}_${P}_${T} || echo "Test FAILED" echo " " + echo ">>> [x] [ ] Testing copy-constructor of square pattern matrices" + echo " of size 1003." + $runner ${TEST_BIN_DIR}/copyVoidMatrices_${MODE}_${BACKEND} 1003 &> ${TEST_OUT_DIR}/copyVoidMatrices_${MODE}_${BACKEND}_${P}_${T} + head -1 ${TEST_OUT_DIR}/copyVoidMatrices_${MODE}_${BACKEND}_${P}_${T} + grep 'Test OK' ${TEST_OUT_DIR}/copyVoidMatrices_${MODE}_${BACKEND}_${P}_${T} || echo "Test FAILED" + echo " " + echo ">>> [x] [x] Testing grb::foldl and grb::foldr reducing dense" echo " vectors into scalars using operators and monoids." $runner ${TEST_BIN_DIR}/fold_to_scalar_${MODE}_${BACKEND} ${P} &> ${TEST_OUT_DIR}/fold_to_scalar_${MODE}_${BACKEND}_${P}_${T}.log