diff --git a/CMakeLists.txt b/CMakeLists.txt index 03eb9e72..b64a563c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,7 +31,7 @@ if( ENABLE_CHAI ) set( lvarray_dependencies ${lvarray_dependencies} chai umpire ) endif() -if( ${ENABLE_MPI} ) +if( ENABLE_MPI ) set( lvarray_dependencies ${lvarray_dependencies} mpi ) endif() diff --git a/benchmarks/benchmarkArray1DR2TensorMultiplication.cpp b/benchmarks/benchmarkArray1DR2TensorMultiplication.cpp index f5ba1af7..f9fdd5e1 100644 --- a/benchmarks/benchmarkArray1DR2TensorMultiplication.cpp +++ b/benchmarks/benchmarkArray1DR2TensorMultiplication.cpp @@ -193,7 +193,8 @@ INDEX_TYPE const SERIAL_SIZE = (2 << 18) - 87; INDEX_TYPE const OMP_SIZE = (2 << 22) - 87; #endif -#if defined(USE_CUDA) +// The non Array benchmarks could be run without chai, but then what's the point. +#if defined(USE_CUDA) && defined(USE_CHAI) constexpr INDEX_TYPE CUDA_SIZE = (2 << 24) - 87; #endif @@ -240,7 +241,7 @@ void registerBenchmarks() , std::make_tuple( OMP_SIZE, RAJA::PERM_IJK {}, parallelHostPolicy {} ) , std::make_tuple( OMP_SIZE, RAJA::PERM_KJI {}, parallelHostPolicy {} ) #endif - #if defined(USE_CUDA) + #if defined(USE_CUDA) && defined(USE_CHAI) , std::make_tuple( CUDA_SIZE, RAJA::PERM_IJK {}, parallelDevicePolicy< THREADS_PER_BLOCK > {} ) , std::make_tuple( CUDA_SIZE, RAJA::PERM_KJI {}, parallelDevicePolicy< THREADS_PER_BLOCK > {} ) #endif @@ -264,7 +265,7 @@ int main( int argc, char * * argv ) LVARRAY_LOG( "OMP problems of size ( " << LvArray::benchmarking::OMP_SIZE << ", 3, 3 )." ); #endif -#if defined(USE_CUDA) +#if defined(USE_CUDA) && defined(USE_CHAI) LVARRAY_LOG( "CUDA problems of size ( " << LvArray::benchmarking::CUDA_SIZE << ", 3, 3 )." ); #endif diff --git a/benchmarks/benchmarkArray1DR2TensorMultiplicationKernels.cpp b/benchmarks/benchmarkArray1DR2TensorMultiplicationKernels.cpp index 96ce003e..42353036 100644 --- a/benchmarks/benchmarkArray1DR2TensorMultiplicationKernels.cpp +++ b/benchmarks/benchmarkArray1DR2TensorMultiplicationKernels.cpp @@ -64,10 +64,10 @@ namespace benchmarking template< typename VALUE_TYPE_CONST, int USD > -RAJA_INLINE LVARRAY_HOST_DEVICE constexpr -void R2TensorMultiply( LvArray::ArraySlice< VALUE_TYPE_CONST, 2, USD > const & a, - LvArray::ArraySlice< VALUE_TYPE_CONST, 2, USD > const & b, - LvArray::ArraySlice< VALUE_TYPE, 2, USD > const & c ) +inline LVARRAY_HOST_DEVICE constexpr +void R2TensorMultiply( LvArray::ArraySlice< VALUE_TYPE_CONST, 2, USD, INDEX_TYPE > const & a, + LvArray::ArraySlice< VALUE_TYPE_CONST, 2, USD, INDEX_TYPE > const & b, + LvArray::ArraySlice< VALUE_TYPE, 2, USD, INDEX_TYPE > const & c ) { INNER_LOOP( a( j, l ), b( l, k ), c( j, k ) ) } @@ -265,7 +265,7 @@ template class ArrayOfR2TensorsRAJA< RAJA::PERM_IJK, parallelHostPolicy >; template class ArrayOfR2TensorsRAJA< RAJA::PERM_KJI, parallelHostPolicy >; #endif -#if defined(USE_CUDA) +#if defined(USE_CUDA) && defined(USE_CHAI) template class ArrayOfR2TensorsRAJA< RAJA::PERM_IJK, RAJA::cuda_exec< THREADS_PER_BLOCK > >; template class ArrayOfR2TensorsRAJA< RAJA::PERM_KJI, RAJA::cuda_exec< THREADS_PER_BLOCK > >; #endif diff --git a/benchmarks/benchmarkArray1DR2TensorMultiplicationKernels.hpp b/benchmarks/benchmarkArray1DR2TensorMultiplicationKernels.hpp index 8b9e2aab..f6e4cda0 100644 --- a/benchmarks/benchmarkArray1DR2TensorMultiplicationKernels.hpp +++ b/benchmarks/benchmarkArray1DR2TensorMultiplicationKernels.hpp @@ -220,7 +220,7 @@ class ArrayOfR2TensorsRAJA : private ArrayOfR2TensorsNative< PERMUTATION > } ~ArrayOfR2TensorsRAJA() - { this->m_c.move( chai::CPU ); } + { this->m_c.move( MemorySpace::CPU ); } void fortranView() const { diff --git a/benchmarks/benchmarkCommon.hpp b/benchmarks/benchmarkCommon.hpp deleted file mode 100644 index cb85122c..00000000 --- a/benchmarks/benchmarkCommon.hpp +++ /dev/null @@ -1,53 +0,0 @@ -/* - *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * Copyright (c) 2019, Lawrence Livermore National Security, LLC. - * - * Produced at the Lawrence Livermore National Laboratory - * - * LLNL-CODE-746361 - * - * All rights reserved. See COPYRIGHT for details. - * - * This file is part of the GEOSX Simulation Framework. - * - * GEOSX is a free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (as published by the - * Free Software Foundation) version 2.1 dated February 1999. - *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - */ - -#pragma once - -#include "Array.hpp" - -namespace LvArray -{ - -namespace benchmarking -{ - -#define ACCESS_IJ( N, M, i, j ) M * i + j -#define ACCESS_JI( N, M, i, j ) N * j + i - -#define ACCESS_IJK( N, M, P, i, j, k ) M * P * i + P * j + k -#define ACCESS_KJI( N, M, P, i, j, k ) M * N * k + N * j + i - -using INDEX_TYPE = std::ptrdiff_t; - -template< typename T, typename PERMUTATION > -using Array = LvArray::Array< T, getDimension( PERMUTATION {} ), PERMUTATION, INDEX_TYPE >; - -template< typename T, typename PERMUTATION, int LENGTH > -using StackArray = LvArray::StackArray< T, getDimension( PERMUTATION {} ), PERMUTATION, INDEX_TYPE, LENGTH >; - -template< typename T, typename PERMUTATION > -using ArrayView = LvArray::ArrayView< T, getDimension( PERMUTATION {} ), getStrideOneDimension( PERMUTATION {} ), INDEX_TYPE >; - -template< typename T, typename PERMUTATION > -using ArraySlice = LvArray::ArraySlice< T, getDimension( PERMUTATION {} ), getStrideOneDimension( PERMUTATION {} ), INDEX_TYPE >; - -template< typename T, typename PERMUTATION > -using RajaView = RAJA::View< T, RAJA::Layout< getDimension( PERMUTATION {} ), INDEX_TYPE, getStrideOneDimension( PERMUTATION {} ) >>; - -} // namespace benchmarking -} // namespace LvArray diff --git a/benchmarks/benchmarkHelpers.hpp b/benchmarks/benchmarkHelpers.hpp index fc7698c3..49a168ab 100644 --- a/benchmarks/benchmarkHelpers.hpp +++ b/benchmarks/benchmarkHelpers.hpp @@ -15,12 +15,12 @@ * Free Software Foundation) version 2.1 dated February 1999. *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -/* *UNCRUSTIFY-OFF* */ + #pragma once // Source includes -#include "benchmarkCommon.hpp" #include "../unitTests/testUtils.hpp" +#include "StringUtilities.hpp" // System includes #include @@ -30,8 +30,8 @@ #if defined(USE_CALIPER) #include -#define LVARRAY_MARK_FUNCTION_TAG( name ) cali::Function __cali_ann##__LINE__( STRINGIZE_NX( name ) ) -#define LVARRAY_MARK_FUNCTION_TAG_STRING( string ) cali::Function __cali_ann##__LINE__( ( string ).data() ) +#define LVARRAY_MARK_FUNCTION_TAG( name ) cali::Function __cali_ann ## __LINE__( STRINGIZE_NX( name ) ) +#define LVARRAY_MARK_FUNCTION_TAG_STRING( string ) cali::Function __cali_ann ## __LINE__( ( string ).data() ) #else @@ -45,6 +45,12 @@ namespace LvArray using namespace testing; + +#if defined(USE_CHAI) +static_assert( std::is_same_v< DEFAULT_BUFFER< int >, NewChaiBuffer< int > >, + "The default buffer should be NewChaiBuffer when chai is enabled." ); +#endif + namespace benchmarking { @@ -65,6 +71,36 @@ inline std::string typeToString( RAJA::PERM_KJI const & ) { return "RAJA::PERM_K } // namespace internal +#define ACCESS_IJ( N, M, i, j ) M * i + j +#define ACCESS_JI( N, M, i, j ) N * j + i + +#define ACCESS_IJK( N, M, P, i, j, k ) M * P * i + P * j + k +#define ACCESS_KJI( N, M, P, i, j, k ) M * N * k + N * j + i + +using INDEX_TYPE = std::ptrdiff_t; + +template< typename T, typename PERMUTATION > +using Array = LvArray::Array< T, getDimension( PERMUTATION {} ), PERMUTATION, INDEX_TYPE, DEFAULT_BUFFER >; + +template< typename T, typename PERMUTATION > +using ArrayView = LvArray::ArrayView< T, +getDimension( PERMUTATION {} ), +getStrideOneDimension( PERMUTATION {} ), +INDEX_TYPE, +DEFAULT_BUFFER >; + +template< typename T, typename PERMUTATION > +using ArraySlice = LvArray::ArraySlice< T, +getDimension( PERMUTATION {} ), +getStrideOneDimension( PERMUTATION {} ), +INDEX_TYPE >; + +template< typename T, typename PERMUTATION > +using RajaView = RAJA::View< T, +RAJA::Layout< getDimension( PERMUTATION {} ), +INDEX_TYPE, +getStrideOneDimension( PERMUTATION {} ) >>; + template< typename ARG0 > std::string typeListToString() { return internal::typeToString( ARG0 {} ); } @@ -77,12 +113,12 @@ std::string typeListToString() #define REGISTER_BENCHMARK( args, func ) \ { \ ::benchmark::RegisterBenchmark( STRINGIZE( func ), func ) \ - ->Args( args ) \ - ->UseRealTime() \ - ->ComputeStatistics( "min", []( std::vector< double > const & times ) \ - { return *std::min_element( times.begin(), times.end() ); } ) \ - ->ComputeStatistics( "max", []( std::vector< double > const & times ) \ - { return *std::max_element( times.begin(), times.end() ); } ); \ + ->Args( args ) \ + ->UseRealTime() \ + ->ComputeStatistics( "min", []( std::vector< double > const & times ) \ +{ return *std::min_element( times.begin(), times.end() ); } ) \ + ->ComputeStatistics( "max", []( std::vector< double > const & times ) \ +{ return *std::max_element( times.begin(), times.end() ); } ); \ } @@ -91,12 +127,12 @@ std::string typeListToString() std::string functionName = STRINGIZE( func ) "< "; \ functionName += typeListToString< __VA_ARGS__ >() + " >"; \ ::benchmark::RegisterBenchmark( functionName.c_str(), func< __VA_ARGS__ > ) \ - ->Args( args ) \ - ->UseRealTime() \ - ->ComputeStatistics( "min", []( std::vector< double > const & times ) \ - { return *std::min_element( times.begin(), times.end() ); } ) \ - ->ComputeStatistics( "max", []( std::vector< double > const & times ) \ - { return *std::max_element( times.begin(), times.end() ); } ); \ + ->Args( args ) \ + ->UseRealTime() \ + ->ComputeStatistics( "min", []( std::vector< double > const & times ) \ +{ return *std::min_element( times.begin(), times.end() ); } ) \ + ->ComputeStatistics( "max", []( std::vector< double > const & times ) \ +{ return *std::max_element( times.begin(), times.end() ); } ); \ } @@ -135,7 +171,7 @@ RajaView< T, PERMUTATION > makeRajaView( Array< T, PERMUTATION > const & array ) constexpr int NDIM = getDimension( PERMUTATION {} ); std::array< INDEX_TYPE, NDIM > sizes; - for( int i = 0 ; i < NDIM ; ++i ) + for( int i = 0; i < NDIM; ++i ) { sizes[ i ] = array.dims()[ i ]; } @@ -215,7 +251,7 @@ inline int verifyResults( ResultsMap< T, N > const & benchmarkResults ) std::cout << "### The benchmarks produced different results with arguments "; std::cout << args[ 0 ]; - for( unsigned long i = 1 ; i < N ; ++i ) + for( unsigned long i = 1; i < N; ++i ) { std::cout << ", " << args[ i ]; } @@ -261,4 +297,3 @@ inline int verifyResults( ResultsMap< T, N > const & benchmarkResults ) } // namespace benchmarking } // namespace LvArray -/* *UNCRUSITIFY-ON* */ diff --git a/benchmarks/benchmarkInnerProduct.cpp b/benchmarks/benchmarkInnerProduct.cpp index 07955390..31d69687 100644 --- a/benchmarks/benchmarkInnerProduct.cpp +++ b/benchmarks/benchmarkInnerProduct.cpp @@ -133,7 +133,9 @@ INDEX_TYPE const SERIAL_SIZE = (2 << 20) + 573; #if defined(USE_OPENMP) INDEX_TYPE const OMP_SIZE = SERIAL_SIZE; #endif -#if defined(USE_CUDA) + +// The non Array benchmarks could be run without chai, but then what's the point. +#if defined(USE_CUDA) && defined(USE_CHAI) INDEX_TYPE const CUDA_SIZE = SERIAL_SIZE; #endif @@ -165,7 +167,7 @@ void registerBenchmarks() #if defined(USE_OPENMP) , std::make_tuple( OMP_SIZE, parallelHostPolicy {} ) #endif - #if defined(USE_CUDA) + #if defined(USE_CUDA) && defined(USE_CHAI) , std::make_tuple( CUDA_SIZE, parallelDevicePolicy< THREADS_PER_BLOCK > {} ) #endif ); @@ -191,7 +193,7 @@ int main( int argc, char * * argv ) LVARRAY_LOG( "OMP problems of size ( " << LvArray::benchmarking::OMP_SIZE << " )." ); #endif -#if defined(USE_CUDA) +#if defined(USE_CUDA) && defined(USE_CHAI) LVARRAY_LOG( "CUDA problems of size ( " << LvArray::benchmarking::CUDA_SIZE << " )." ); #endif diff --git a/benchmarks/benchmarkInnerProductKernels.cpp b/benchmarks/benchmarkInnerProductKernels.cpp index f7c12d8a..6350e241 100644 --- a/benchmarks/benchmarkInnerProductKernels.cpp +++ b/benchmarks/benchmarkInnerProductKernels.cpp @@ -124,7 +124,7 @@ template class InnerProductRAJA< serialPolicy >; template class InnerProductRAJA< parallelHostPolicy >; #endif -#if defined(USE_CUDA) +#if defined(USE_CUDA) && defined(USE_CHAI) template class InnerProductRAJA< RAJA::cuda_exec< THREADS_PER_BLOCK > >; #endif diff --git a/benchmarks/benchmarkMatrixMatrix.cpp b/benchmarks/benchmarkMatrixMatrix.cpp index cc7951ac..048a6cf1 100644 --- a/benchmarks/benchmarkMatrixMatrix.cpp +++ b/benchmarks/benchmarkMatrixMatrix.cpp @@ -138,7 +138,7 @@ INDEX_TYPE const OMP_L = SERIAL_L; INDEX_TYPE const OMP_M = SERIAL_M; #endif -#if defined(USE_CUDA) +#if defined(USE_CUDA) && defined(USE_CHAI) INDEX_TYPE const CUDA_N = SERIAL_N; INDEX_TYPE const CUDA_L = SERIAL_L; INDEX_TYPE const CUDA_M = SERIAL_M; @@ -184,7 +184,7 @@ void registerBenchmarks() , std::make_tuple( OMP_N, SERIAL_L, OMP_M, RAJA::PERM_IJ {}, parallelHostPolicy {} ) , std::make_tuple( OMP_N, SERIAL_L, OMP_M, RAJA::PERM_JI {}, parallelHostPolicy {} ) #endif - #if defined(USE_CUDA) + #if defined(USE_CUDA) && defined(USE_CHAI) , std::make_tuple( CUDA_N, SERIAL_L, CUDA_M, RAJA::PERM_IJ {}, parallelDevicePolicy< THREADS_PER_BLOCK > {} ) , std::make_tuple( CUDA_N, SERIAL_L, CUDA_M, RAJA::PERM_JI {}, parallelDevicePolicy< THREADS_PER_BLOCK > {} ) #endif @@ -212,7 +212,7 @@ int main( int argc, char * * argv ) LvArray::benchmarking::OMP_L << ", " << LvArray::benchmarking::OMP_M << " )." ); #endif -#if defined(USE_CUDA) +#if defined(USE_CUDA) && defined(USE_CHAI) LVARRAY_LOG( "CUDA problems of size ( " << LvArray::benchmarking::CUDA_N << ", " << LvArray::benchmarking::CUDA_L << ", " << LvArray::benchmarking::CUDA_M << " )." ); #endif diff --git a/benchmarks/benchmarkMatrixMatrixKernels.cpp b/benchmarks/benchmarkMatrixMatrixKernels.cpp index 66f55128..0da2f65e 100644 --- a/benchmarks/benchmarkMatrixMatrixKernels.cpp +++ b/benchmarks/benchmarkMatrixMatrixKernels.cpp @@ -222,7 +222,7 @@ template class MatrixMatrixRAJA< RAJA::PERM_JI, parallelHostPolicy >; #endif -#if defined(USE_CUDA) +#if defined(USE_CUDA) && defined(USE_CHAI) template class MatrixMatrixRAJA< RAJA::PERM_IJ, RAJA::cuda_exec< THREADS_PER_BLOCK > >; template class MatrixMatrixRAJA< RAJA::PERM_JI, RAJA::cuda_exec< THREADS_PER_BLOCK > >; diff --git a/benchmarks/benchmarkMatrixVector.cpp b/benchmarks/benchmarkMatrixVector.cpp index 015282d5..a8b41242 100644 --- a/benchmarks/benchmarkMatrixVector.cpp +++ b/benchmarks/benchmarkMatrixVector.cpp @@ -176,7 +176,7 @@ void registerBenchmarks() , std::make_tuple( OMP_N, OMP_M, RAJA::PERM_IJ {}, parallelHostPolicy {} ) , std::make_tuple( OMP_N, OMP_M, RAJA::PERM_JI {}, parallelHostPolicy {} ) #endif - #if defined(USE_CUDA) + #if defined(USE_CUDA) && defined(USE_CHAI) , std::make_tuple( CUDA_N, CUDA_M, RAJA::PERM_IJ {}, parallelDevicePolicy< THREADS_PER_BLOCK > {} ) , std::make_tuple( CUDA_N, CUDA_M, RAJA::PERM_JI {}, parallelDevicePolicy< THREADS_PER_BLOCK > {} ) #endif @@ -204,7 +204,7 @@ int main( int argc, char * * argv ) LvArray::benchmarking::OMP_M << " )." ); #endif -#if defined(USE_CUDA) +#if defined(USE_CUDA) && defined(USE_CHAI) LVARRAY_LOG( "CUDA problems of size ( " << LvArray::benchmarking::CUDA_N << ", " << LvArray::benchmarking::CUDA_M << " )." ); #endif diff --git a/benchmarks/benchmarkMatrixVectorKernels.cpp b/benchmarks/benchmarkMatrixVectorKernels.cpp index a9155671..3aed3c67 100644 --- a/benchmarks/benchmarkMatrixVectorKernels.cpp +++ b/benchmarks/benchmarkMatrixVectorKernels.cpp @@ -189,7 +189,7 @@ template class MatrixVectorRAJA< RAJA::PERM_JI, parallelHostPolicy >; #endif -#if defined(USE_CUDA) +#if defined(USE_CUDA) && defined(USE_CHAI) template class MatrixVectorRAJA< RAJA::PERM_IJ, RAJA::cuda_exec< THREADS_PER_BLOCK > >; template class MatrixVectorRAJA< RAJA::PERM_JI, RAJA::cuda_exec< THREADS_PER_BLOCK > >; diff --git a/benchmarks/benchmarkOuterProduct.cpp b/benchmarks/benchmarkOuterProduct.cpp index b1911b5c..f6fa782e 100644 --- a/benchmarks/benchmarkOuterProduct.cpp +++ b/benchmarks/benchmarkOuterProduct.cpp @@ -136,7 +136,7 @@ INDEX_TYPE const OMP_N = (2 << 9) + 73; INDEX_TYPE const OMP_M = (2 << 9) - 71; #endif -#if defined(USE_CUDA) +#if defined(USE_CUDA) && defined(USE_CHAI) INDEX_TYPE const CUDA_N = (2 << 9) + 73; INDEX_TYPE const CUDA_M = (2 << 9) - 71; #endif @@ -180,7 +180,7 @@ void registerBenchmarks() , std::make_tuple( OMP_N, OMP_M, RAJA::PERM_IJ {}, parallelHostPolicy {} ) , std::make_tuple( OMP_N, OMP_M, RAJA::PERM_JI {}, parallelHostPolicy {} ) #endif - #if defined(USE_CUDA) + #if defined(USE_CUDA) && defined(USE_CHAI) , std::make_tuple( CUDA_N, CUDA_M, RAJA::PERM_IJ {}, parallelDevicePolicy< THREADS_PER_BLOCK > {} ) , std::make_tuple( CUDA_N, CUDA_M, RAJA::PERM_JI {}, parallelDevicePolicy< THREADS_PER_BLOCK > {} ) #endif @@ -208,7 +208,7 @@ int main( int argc, char * * argv ) LvArray::benchmarking::OMP_M << " )." ); #endif -#if defined(USE_CUDA) +#if defined(USE_CUDA) && defined(USE_CHAI) LVARRAY_LOG( "CUDA problems of size ( " << LvArray::benchmarking::CUDA_N << ", " << LvArray::benchmarking::CUDA_M << " )." ); #endif diff --git a/benchmarks/benchmarkOuterProductKernels.cpp b/benchmarks/benchmarkOuterProductKernels.cpp index 8bd5431a..9d5cf918 100644 --- a/benchmarks/benchmarkOuterProductKernels.cpp +++ b/benchmarks/benchmarkOuterProductKernels.cpp @@ -186,7 +186,7 @@ template class OuterProductRAJA< RAJA::PERM_IJ, parallelHostPolicy >; template class OuterProductRAJA< RAJA::PERM_JI, parallelHostPolicy >; #endif -#if defined(USE_CUDA) +#if defined(USE_CUDA) && defined(USE_CHAI) template class OuterProductRAJA< RAJA::PERM_IJ, RAJA::cuda_exec< THREADS_PER_BLOCK > >; template class OuterProductRAJA< RAJA::PERM_JI, RAJA::cuda_exec< THREADS_PER_BLOCK > >; #endif diff --git a/benchmarks/benchmarkReduce.cpp b/benchmarks/benchmarkReduce.cpp index 2defb51a..6e4840c5 100644 --- a/benchmarks/benchmarkReduce.cpp +++ b/benchmarks/benchmarkReduce.cpp @@ -131,7 +131,7 @@ INDEX_TYPE const SERIAL_SIZE = (2 << 20) + 573; #if defined(USE_OPENMP) INDEX_TYPE const OMP_SIZE = SERIAL_SIZE; #endif -#if defined(USE_CUDA) +#if defined(USE_CUDA) && defined(USE_CHAI) INDEX_TYPE const CUDA_SIZE = SERIAL_SIZE; #endif @@ -163,7 +163,7 @@ void registerBenchmarks() #if defined(USE_OPENMP) , std::make_tuple( OMP_SIZE, parallelHostPolicy {} ) #endif - #if defined(USE_CUDA) + #if defined(USE_CUDA) && defined(USE_CHAI) , std::make_tuple( CUDA_SIZE, parallelDevicePolicy< THREADS_PER_BLOCK > {} ) #endif ); @@ -190,7 +190,7 @@ int main( int argc, char * * argv ) LVARRAY_LOG( "OMP problems of size ( " << LvArray::benchmarking::OMP_SIZE << " )." ); #endif -#if defined(USE_CUDA) +#if defined(USE_CUDA) && defined(USE_CHAI) LVARRAY_LOG( "CUDA problems of size ( " << LvArray::benchmarking::CUDA_SIZE << " )." ); #endif diff --git a/benchmarks/benchmarkReduceKernels.cpp b/benchmarks/benchmarkReduceKernels.cpp index 6358e543..ec3b45d0 100644 --- a/benchmarks/benchmarkReduceKernels.cpp +++ b/benchmarks/benchmarkReduceKernels.cpp @@ -96,7 +96,7 @@ template class ReduceRAJA< serialPolicy >; template class ReduceRAJA< parallelHostPolicy >; #endif -#if defined(USE_CUDA) +#if defined(USE_CUDA) && defined(USE_CHAI) template class ReduceRAJA< RAJA::cuda_exec< THREADS_PER_BLOCK > >; #endif diff --git a/benchmarks/benchmarkSparsityGeneration.cpp b/benchmarks/benchmarkSparsityGeneration.cpp index 009fcd65..19c648b1 100644 --- a/benchmarks/benchmarkSparsityGeneration.cpp +++ b/benchmarks/benchmarkSparsityGeneration.cpp @@ -109,7 +109,7 @@ int const SERIAL_SIZE = 100; int const OMP_SIZE = 100; #endif -#if defined(USE_CUDA) +#if defined(USE_CUDA) && defined(USE_CHAI) int const CUDA_SIZE = 100; #endif @@ -135,7 +135,7 @@ void registerBenchmarks() #if defined(USE_OPENMP) , std::make_tuple( OMP_SIZE, parallelHostPolicy {} ) #endif - #if defined(USE_CUDA) + #if defined(USE_CUDA) && defined(USE_CHAI) , std::make_tuple( CUDA_SIZE, parallelDevicePolicy< THREADS_PER_BLOCK > {} ) #endif ); @@ -151,7 +151,7 @@ void registerBenchmarks() #if defined(USE_OPENMP) , std::make_tuple( OMP_SIZE, parallelHostPolicy {} ) #endif - #if defined(USE_CUDA) + #if defined(USE_CUDA) && defined(USE_CHAI) , std::make_tuple( CUDA_SIZE, parallelDevicePolicy< THREADS_PER_BLOCK > {} ) #endif ); @@ -178,7 +178,7 @@ int main( int argc, char * * argv ) LVARRAY_LOG( "OMP problems of size ( " << size << " )." ); #endif -#if defined(USE_CUDA) +#if defined(USE_CUDA) && defined(USE_CHAI) size = std::pow( LvArray::benchmarking::CUDA_SIZE, 3 ); LVARRAY_LOG( "CUDA problems of size ( " << size << " )." ); #endif diff --git a/benchmarks/benchmarkSparsityGenerationKernels.cpp b/benchmarks/benchmarkSparsityGenerationKernels.cpp index 6899be75..5ee17800 100644 --- a/benchmarks/benchmarkSparsityGenerationKernels.cpp +++ b/benchmarks/benchmarkSparsityGenerationKernels.cpp @@ -79,7 +79,7 @@ void insertEntriesForNode( SPARSITY_TYPE & sparsity, void SparsityGenerationNative::resize( INDEX_TYPE const initialCapacity ) { LVARRAY_MARK_FUNCTION_TAG( "resize" ); - m_sparsity = SparsityPattern< COLUMN_TYPE, INDEX_TYPE >( NDIM * m_numNodes, NDIM * m_numNodes, initialCapacity ); + m_sparsity = SparsityPatternT( NDIM * m_numNodes, NDIM * m_numNodes, initialCapacity ); } void SparsityGenerationNative::resizeExact() @@ -102,7 +102,7 @@ void SparsityGenerationNative::resizeExact() template< typename POLICY > void SparsityGenerationNative::resizeFromNNZPerRow( std::vector< INDEX_TYPE > const & nnzPerRow ) { - SparsityPattern< COLUMN_TYPE, INDEX_TYPE > newSparsity; + SparsityPatternT newSparsity; newSparsity.resizeFromRowCapacities< POLICY >( NDIM * m_numNodes, NDIM * m_numNodes, nnzPerRow.data() ); m_sparsity = std::move( newSparsity ); } @@ -137,7 +137,7 @@ void SparsityGenerationNative::generateElemLoop( SPARSITY_TYPE & sparsity, template< typename SPARSITY_TYPE > void SparsityGenerationNative::generateNodeLoop( SPARSITY_TYPE & sparsity, ArrayView< INDEX_TYPE const, ELEM_TO_NODE_PERM > const & elemToNodeMap, - ArrayOfArraysView< INDEX_TYPE const, INDEX_TYPE const, true > const & nodeToElemMap ) + ArrayOfArraysViewT< INDEX_TYPE const, true > const & nodeToElemMap ) { /// Iterate over all the nodes. for( INDEX_TYPE nodeID = 0; nodeID < nodeToElemMap.size(); ++nodeID ) @@ -160,7 +160,7 @@ resizeExact() #endif ArrayView< INDEX_TYPE const, ELEM_TO_NODE_PERM > const & elemToNodeMap = m_elemToNodeMap.toViewConst(); - ArrayOfArraysView< INDEX_TYPE const, INDEX_TYPE const, true > const & nodeToElemMap = m_nodeToElemMap.toViewConst(); + ArrayOfArraysViewT< INDEX_TYPE const, true > const & nodeToElemMap = m_nodeToElemMap.toViewConst(); forall< RESIZE_POLICY >( m_numNodes, [&nnzPerRow, elemToNodeMap, nodeToElemMap] ( INDEX_TYPE const nodeID ) { INDEX_TYPE neighborNodes[ MAX_ELEMS_PER_NODE * NODES_PER_ELEM ]; @@ -177,9 +177,9 @@ resizeExact() // Note this shoule be protected but cuda won't let you put an extended lambda in a protected or private method. template< typename POLICY > void SparsityGenerationRAJA< POLICY >:: -generateNodeLoop( SparsityPatternView< COLUMN_TYPE, INDEX_TYPE const > const & sparsity, +generateNodeLoop( SparsityPatternViewT const & sparsity, ArrayView< INDEX_TYPE const, ELEM_TO_NODE_PERM > const & elemToNodeMap, - ArrayOfArraysView< INDEX_TYPE const, INDEX_TYPE const, true > const & nodeToElemMap, + ArrayOfArraysViewT< INDEX_TYPE const, true > const & nodeToElemMap, ::benchmark::State & state ) { LVARRAY_MARK_FUNCTION_TAG( "generateNodeLoop" ); @@ -205,13 +205,12 @@ generateNodeLoop( SparsityPatternView< COLUMN_TYPE, INDEX_TYPE const > const & s template< typename POLICY > void CRSMatrixAddToRow< POLICY >:: -addKernel( CRSMatrixView< ENTRY_TYPE, COLUMN_TYPE const, INDEX_TYPE const > const & matrix, - ArrayView< INDEX_TYPE const, ELEM_TO_NODE_PERM > const & elemToNodeMap, - ArrayOfArraysView< INDEX_TYPE const, INDEX_TYPE const, true > const & nodeToElemMap ) +addKernel( CRSMatrixViewConstSizesT const & matrix, + ArrayView< INDEX_TYPE const, ELEM_TO_NODE_PERM > const & elemToNodeMap ) { LVARRAY_MARK_FUNCTION_TAG( "addKernel" ); - forall< POLICY >( elemToNodeMap.size( 0 ), [matrix, elemToNodeMap, nodeToElemMap] LVARRAY_HOST_DEVICE ( INDEX_TYPE const elemID ) + forall< POLICY >( elemToNodeMap.size( 0 ), [matrix, elemToNodeMap] LVARRAY_HOST_DEVICE ( INDEX_TYPE const elemID ) { COLUMN_TYPE dofNumbers[ NODES_PER_ELEM * NDIM ]; ENTRY_TYPE additions[ NODES_PER_ELEM * NDIM ][ NODES_PER_ELEM * NDIM ]; @@ -246,23 +245,23 @@ addKernel( CRSMatrixView< ENTRY_TYPE, COLUMN_TYPE const, INDEX_TYPE const > cons } // Explicit instantiation of the templated SparsityGenerationNative static methods. -template void SparsityGenerationNative::generateElemLoop< SparsityPattern< COLUMN_TYPE, INDEX_TYPE > >( - SparsityPattern< COLUMN_TYPE, INDEX_TYPE > &, +template void SparsityGenerationNative::generateElemLoop< SparsityPatternT >( + SparsityPatternT &, ArrayView< INDEX_TYPE const, ELEM_TO_NODE_PERM > const & ); -template void SparsityGenerationNative::generateElemLoop< SparsityPatternView< COLUMN_TYPE, INDEX_TYPE const > const >( - SparsityPatternView< COLUMN_TYPE, INDEX_TYPE const > const &, +template void SparsityGenerationNative::generateElemLoop< SparsityPatternViewT const >( + SparsityPatternViewT const &, ArrayView< INDEX_TYPE const, ELEM_TO_NODE_PERM > const & ); -template void SparsityGenerationNative::generateNodeLoop< SparsityPattern< COLUMN_TYPE, INDEX_TYPE > >( - SparsityPattern< COLUMN_TYPE, INDEX_TYPE > &, +template void SparsityGenerationNative::generateNodeLoop< SparsityPatternT >( + SparsityPatternT &, ArrayView< INDEX_TYPE const, ELEM_TO_NODE_PERM > const &, - ArrayOfArraysView< INDEX_TYPE const, INDEX_TYPE const, true > const & nodeToElemMap ); + ArrayOfArraysViewT< INDEX_TYPE const, true > const & nodeToElemMap ); -template void SparsityGenerationNative::generateNodeLoop< SparsityPatternView< COLUMN_TYPE, INDEX_TYPE const > const >( - SparsityPatternView< COLUMN_TYPE, INDEX_TYPE const > const &, +template void SparsityGenerationNative::generateNodeLoop< SparsityPatternViewT const >( + SparsityPatternViewT const &, ArrayView< INDEX_TYPE const, ELEM_TO_NODE_PERM > const &, - ArrayOfArraysView< INDEX_TYPE const, INDEX_TYPE const, true > const & nodeToElemMap ); + ArrayOfArraysViewT< INDEX_TYPE const, true > const & nodeToElemMap ); // Explicit instantiation of SparsityGenerationRAJA. template class SparsityGenerationRAJA< serialPolicy >; @@ -273,7 +272,7 @@ template class SparsityGenerationRAJA< parallelHostPolicy >; template class CRSMatrixAddToRow< parallelHostPolicy >; #endif -#if defined(USE_CUDA) +#if defined(USE_CUDA) && defined(USE_CHAI) template class SparsityGenerationRAJA< parallelDevicePolicy< THREADS_PER_BLOCK > >; template class CRSMatrixAddToRow< parallelDevicePolicy< THREADS_PER_BLOCK > >; #endif diff --git a/benchmarks/benchmarkSparsityGenerationKernels.hpp b/benchmarks/benchmarkSparsityGenerationKernels.hpp index b3a5c638..5f0fac7d 100644 --- a/benchmarks/benchmarkSparsityGenerationKernels.hpp +++ b/benchmarks/benchmarkSparsityGenerationKernels.hpp @@ -44,6 +44,20 @@ using ELEM_TO_NODE_PERM = RAJA::PERM_JI; using ELEM_TO_NODE_PERM = RAJA::PERM_JI; #endif +template< typename T > +using ArrayOfArraysT = ArrayOfArrays< T, INDEX_TYPE, DEFAULT_BUFFER >; + +template< typename T, bool CONST_SIZES > +using ArrayOfArraysViewT = ArrayOfArraysView< T, INDEX_TYPE const, CONST_SIZES, DEFAULT_BUFFER >; + +using SparsityPatternT = SparsityPattern< COLUMN_TYPE, INDEX_TYPE, DEFAULT_BUFFER >; + +using SparsityPatternViewT = SparsityPatternView< COLUMN_TYPE, INDEX_TYPE const, DEFAULT_BUFFER >; + +using CRSMatrixT = CRSMatrix< ENTRY_TYPE, COLUMN_TYPE, INDEX_TYPE, DEFAULT_BUFFER >; + +using CRSMatrixViewConstSizesT = CRSMatrixView< ENTRY_TYPE, COLUMN_TYPE const, INDEX_TYPE const, DEFAULT_BUFFER >; + constexpr int NDIM = 3; constexpr int NODES_PER_ELEM = 8; constexpr int MAX_ELEMS_PER_NODE = 8; @@ -113,7 +127,7 @@ class SparsityGenerationNative if( k + dk < 0 || k + dk >= m_numElemsZ ) continue; INDEX_TYPE const elemIndex = ( i + di ) + elemJp * ( j + dj ) + elemKp * ( k + dk ); - m_nodeToElemMap.appendToArray( nodeIndex, elemIndex ); + m_nodeToElemMap.emplaceBack( nodeIndex, elemIndex ); } } } @@ -122,7 +136,7 @@ class SparsityGenerationNative } for( INDEX_TYPE nodeID = 0; nodeID < m_numNodes; ++nodeID ) - { sortedArrayManipulation::makeSorted( m_nodeToElemMap.getIterableArray( nodeID ).begin(), m_nodeToElemMap.getIterableArray( nodeID ).end() ); } + { sortedArrayManipulation::makeSorted( m_nodeToElemMap[ nodeID ].begin(), m_nodeToElemMap[ nodeID ].end() ); } m_nodeToElemMap.compress(); } @@ -137,7 +151,7 @@ class SparsityGenerationNative INDEX_TYPE const nodeKp = nodeJp * ( m_numElemsY + 1 ); /// Iterate over all the nodes. - m_sparsity.move( chai::CPU ); + m_sparsity.move( MemorySpace::CPU ); #if defined(USE_OPENMP) using EXEC_POLICY = parallelHostPolicy; @@ -214,7 +228,7 @@ class SparsityGenerationNative template< typename SPARSITY_TYPE > static void generateNodeLoop( SPARSITY_TYPE & sparsity, ArrayView< INDEX_TYPE const, ELEM_TO_NODE_PERM > const & elemToNodeMap, - ArrayOfArraysView< INDEX_TYPE const, INDEX_TYPE const, true > const & nodeToElemMap ); + ArrayOfArraysViewT< INDEX_TYPE const, true > const & nodeToElemMap ); ::benchmark::State & m_state; @@ -225,8 +239,8 @@ class SparsityGenerationNative INDEX_TYPE m_numNodes; Array< INDEX_TYPE, ELEM_TO_NODE_PERM > m_elemToNodeMap; - ArrayOfArrays< INDEX_TYPE, INDEX_TYPE > m_nodeToElemMap; - SparsityPattern< COLUMN_TYPE, INDEX_TYPE > m_sparsity; + ArrayOfArraysT< INDEX_TYPE > m_nodeToElemMap; + SparsityPatternT m_sparsity; bool const m_destructorCheck; }; @@ -248,9 +262,9 @@ class SparsityGenerationRAJA : public SparsityGenerationNative void resizeExact(); // Note this shoule be protected but cuda won't let you put an extended lambda in a protected or private method. - static void generateNodeLoop( SparsityPatternView< COLUMN_TYPE, INDEX_TYPE const > const & sparsity, + static void generateNodeLoop( SparsityPatternViewT const & sparsity, ArrayView< INDEX_TYPE const, ELEM_TO_NODE_PERM > const & elemToNodeMap, - ArrayOfArraysView< INDEX_TYPE const, INDEX_TYPE const, true > const & nodeToElemMap, + ArrayOfArraysViewT< INDEX_TYPE const, true > const & nodeToElemMap, ::benchmark::State & state ); }; @@ -282,8 +296,8 @@ class CRSMatrixAddToRow : public SparsityGenerationRAJA< POLICY > INDEX_TYPE const nodeJp = this->m_numElemsX + 1; INDEX_TYPE const nodeKp = nodeJp * ( this->m_numElemsY + 1 ); - m_matrix.move( chai::CPU, false ); - this->m_nodeToElemMap.move( chai::CPU, false ); + m_matrix.move( MemorySpace::CPU, false ); + this->m_nodeToElemMap.move( MemorySpace::CPU, false ); #if defined(USE_OPENMP) using EXEC_POLICY = parallelHostPolicy; @@ -316,8 +330,8 @@ class CRSMatrixAddToRow : public SparsityGenerationRAJA< POLICY > std::vector< INDEX_TYPE > sharedElems; - std::set_intersection( this->m_nodeToElemMap.getIterableArray( nodeID ).begin(), this->m_nodeToElemMap.getIterableArray( nodeID ).end(), - this->m_nodeToElemMap.getIterableArray( nodeIndex1 ).begin(), this->m_nodeToElemMap.getIterableArray( nodeIndex1 ).end(), + std::set_intersection( this->m_nodeToElemMap[ nodeID ].begin(), this->m_nodeToElemMap[ nodeID ].end(), + this->m_nodeToElemMap[ nodeIndex1 ].begin(), this->m_nodeToElemMap[ nodeIndex1 ].end(), std::back_inserter( sharedElems ) ); INDEX_TYPE const numSharedElems = sharedElems.size(); @@ -358,15 +372,14 @@ class CRSMatrixAddToRow : public SparsityGenerationRAJA< POLICY > } void add() const - { addKernel( m_matrix.toViewConstSizes(), this->m_elemToNodeMap.toViewConst(), this->m_nodeToElemMap.toViewConst() ); } + { addKernel( m_matrix.toViewConstSizes(), this->m_elemToNodeMap.toViewConst() ); } // Note this shoule be protected but cuda won't let you put an extended lambda in a protected or private method. - static void addKernel( CRSMatrixView< ENTRY_TYPE, COLUMN_TYPE const, INDEX_TYPE const > const & matrix, - ArrayView< INDEX_TYPE const, ELEM_TO_NODE_PERM > const & elemToNodeMap, - ArrayOfArraysView< INDEX_TYPE const, INDEX_TYPE const, true > const & nodeToElemMap ); + static void addKernel( CRSMatrixViewConstSizesT const & matrix, + ArrayView< INDEX_TYPE const, ELEM_TO_NODE_PERM > const & elemToNodeMap ); private: - CRSMatrix< ENTRY_TYPE, COLUMN_TYPE, INDEX_TYPE > m_matrix; + CRSMatrixT m_matrix; }; } // namespace benchmarking diff --git a/cmake/FindCHAI.cmake b/cmake/FindCHAI.cmake deleted file mode 100644 index e86a665b..00000000 --- a/cmake/FindCHAI.cmake +++ /dev/null @@ -1,53 +0,0 @@ -############################################################################### -# -# Setup CHAI -# This file defines: -# CHAI_FOUND - If CHAI was found -# CHAI_INCLUDE_DIRS - The CHAI include directories -# CHAI_LIBRARY - The CHAI library - -# first Check for CHAI_DIR - -if (NOT EXISTS ${CHAI_DIR}) - message(STATUS "Using chai from thirdPartyLibs") - set(CHAI_DIR "${GEOSX_TPL_DIR}/chai" CACHE PATH "") -endif() - -if (EXISTS ${CHAI_DIR}) - message(STATUS "Using chai found at ${CHAI_DIR}") - - find_library( CHAI_LIBRARY NAMES chai libchai libumpire libumpire_op libumpire_resource libumpire_strategy libumpire_tpl_judy libumpire_util - PATHS ${CHAI_DIR}/lib - NO_DEFAULT_PATH - NO_CMAKE_ENVIRONMENT_PATH - NO_CMAKE_PATH - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - - include("${CHAI_DIR}/share/umpire/cmake/umpire-targets.cmake") - include("${CHAI_DIR}/share/chai/cmake/chai-targets.cmake") - - # handle the QUIETLY and REQUIRED arguments and set CHAI_FOUND to TRUE - # if all listed variables are TRUE - set(CHAI_INCLUDE_DIRS ${CHAI_DIR}/include) - include(FindPackageHandleStandardArgs) - find_package_handle_standard_args( CHAI DEFAULT_MSG - CHAI_INCLUDE_DIRS - CHAI_LIBRARY ) - - if (NOT CHAI_FOUND) - message(FATAL_ERROR "CHAI not found in ${CHAI_DIR}. Maybe you need to build it") - endif() - - blt_register_library( NAME chai - INCLUDES ${CHAI_INCLUDE_DIRS} - LIBRARIES ${CHAI_LIBRARY} - TREAT_INCLUDES_AS_SYSTEM ON ) - - set(ENABLE_CHAI ON CACHE BOOL "") - set(thirdPartyLibs ${thirdPartyLibs} chai) -else() - set(CHAI_FOUND FALSE) - set(ENABLE_CHAI OFF CACHE BOOL "") - message(STATUS "Not using chai") -endif() diff --git a/cmake/SetupTPL.cmake b/cmake/SetupTPL.cmake index 8fedcfed..f0126b3e 100644 --- a/cmake/SetupTPL.cmake +++ b/cmake/SetupTPL.cmake @@ -1,13 +1,6 @@ set( thirdPartyLibs "") - -################################ -# CHAI -################################ -include(${CMAKE_SOURCE_DIR}/cmake/FindCHAI.cmake) - - ################################ # RAJA ################################ @@ -21,8 +14,8 @@ endif() include(${CMAKE_SOURCE_DIR}/cmake/FindRAJA.cmake) if (NOT RAJA_FOUND) message(FATAL_ERROR "RAJA not found in ${RAJA_DIR}. Maybe you need to build it") -endif() -blt_register_library( NAME raja +endif() +blt_register_library( NAME RAJA INCLUDES ${RAJA_INCLUDE_DIRS} LIBRARIES ${RAJA_LIBRARY} TREAT_INCLUDES_AS_SYSTEM ON ) @@ -32,6 +25,58 @@ set(ENABLE_RAJA ON CACHE BOOL "") set( thirdPartyLibs ${thirdPartyLibs} raja ) +############################### +# UMPIRE +############################### +if(ENABLE_UMPIRE) + if(NOT EXISTS ${UMPIRE_DIR}) + set(UMPIRE_DIR ${GEOSX_TPL_DIR}/chai) + endif() + + message(STATUS "Using umpire at ${UMPIRE_DIR}") + + find_package(umpire REQUIRED + PATHS ${UMPIRE_DIR}/share/umpire/cmake/) + + set(thirdPartyLibs ${thirdPartyLibs} umpire) +else() + message(STATUS "Not using umpire.") +endif() + +################################ +# CHAI +################################ +# include(cmake/FindCHAI.cmake) +if(ENABLE_CHAI) + if(NOT ENABLE_UMPIRE) + message(FATAL_ERROR "umpire must be enabled to use chai.") + endif() + + if(NOT ENABLE_RAJA) + message(FATAL_ERROR "RAJA must be enabled to use chai.") + endif() + + if(NOT EXISTS ${CHAI_DIR}) + set(CHAI_DIR ${GEOSX_TPL_DIR}/chai) + endif() + + message(STATUS "Using chai at ${CHAI_DIR}") + + find_package(chai REQUIRED + PATHS ${CHAI_DIR}/share/chai/cmake/) + + # If this isn't done chai will add -lRAJA to the link line, but we don't link to RAJA like that. + get_target_property(CHAI_LINK_LIBRARIES chai INTERFACE_LINK_LIBRARIES) + list(REMOVE_ITEM CHAI_LINK_LIBRARIES RAJA) + set_target_properties(chai + PROPERTIES INTERFACE_LINK_LIBRARIES ${CHAI_LINK_LIBRARIES}) + + set(thirdPartyLibs ${thirdPartyLibs} chai) +else() + message(STATUS "Not using chai.") +endif() + + ################################ # CALIPER and Adiak ################################ diff --git a/host-configs/LLNL/lassen-clang@upstream.cmake b/host-configs/LLNL/lassen-clang@upstream.cmake index 1e012008..edc202d1 100644 --- a/host-configs/LLNL/lassen-clang@upstream.cmake +++ b/host-configs/LLNL/lassen-clang@upstream.cmake @@ -2,7 +2,10 @@ set(CONFIG_NAME "lassen-clang@upstream" CACHE PATH "") # Set up the tpls set(GEOSX_TPL_ROOT_DIR /usr/gapps/GEOSX/thirdPartyLibs CACHE PATH "") -set(GEOSX_TPL_DIR ${GEOSX_TPL_ROOT_DIR}/2020-06-16/install-${CONFIG_NAME}-release CACHE PATH "") +set(GEOSX_TPL_DIR ${GEOSX_TPL_ROOT_DIR}/2020-06-17/install-${CONFIG_NAME}-release CACHE PATH "") + +set(ENABLE_UMPIRE ON CACHE BOOL "") +set(ENABLE_CHAI ON CACHE BOOL "") # C options set(CMAKE_C_COMPILER /usr/tce/packages/clang/clang-upstream-2019.03.26/bin/clang CACHE PATH "") diff --git a/host-configs/LLNL/lassen-gcc@8.3.1.cmake b/host-configs/LLNL/lassen-gcc@8.3.1.cmake index a053fa2a..b8f0d98f 100644 --- a/host-configs/LLNL/lassen-gcc@8.3.1.cmake +++ b/host-configs/LLNL/lassen-gcc@8.3.1.cmake @@ -3,14 +3,15 @@ set(CONFIG_NAME "lassen-gcc@8.3.1" CACHE PATH "") # Set up the tpls # These were probably built with clang (no guarantee that they would work) set(GEOSX_TPL_ROOT_DIR /usr/gapps/GEOSX/thirdPartyLibs CACHE PATH "") -set(GEOSX_TPL_DIR ${GEOSX_TPL_ROOT_DIR}/2020-06-16/install-${CONFIG_NAME}-release CACHE PATH "") +set(GEOSX_TPL_DIR ${GEOSX_TPL_ROOT_DIR}/2020-06-17/install-${CONFIG_NAME}-release CACHE PATH "") + +set(ENABLE_UMPIRE ON CACHE BOOL "") +set(ENABLE_CHAI ON CACHE BOOL "") set(CMAKE_C_COMPILER /usr/tce/packages/gcc/gcc-8.3.1/bin/gcc CACHE PATH "") set(CMAKE_CXX_COMPILER /usr/tce/packages/gcc/gcc-8.3.1/bin/g++ CACHE PATH "") set(CMAKE_Fortran_COMPILER /usr/tce/packages/gcc/gcc-8.3.1/bin/gfortran CACHE PATH "") -# These flags should be set for the TPL build but they break some of our numerically sensitive code. -# This needs to be fixed. set(CMAKE_C_FLAGS_RELEASE "-O3 -DNDEBUG -mcpu=power9 -mtune=power9" CACHE STRING "") set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG -mcpu=power9 -mtune=power9" CACHE STRING "") set(CMAKE_Fortran_FLAGS_RELEASE "-O3 -DNDEBUG -mcpu=power9 -mtune=power9" CACHE STRING "") diff --git a/host-configs/LLNL/quartz-base.cmake b/host-configs/LLNL/quartz-base.cmake index 9172d952..46f85a0d 100644 --- a/host-configs/LLNL/quartz-base.cmake +++ b/host-configs/LLNL/quartz-base.cmake @@ -23,7 +23,10 @@ set(MPIEXEC /usr/bin/srun CACHE PATH "") set(MPIEXEC_NUMPROC_FLAG "-n" CACHE STRING "") set(GEOSX_TPL_ROOT_DIR /usr/gapps/GEOSX/thirdPartyLibs CACHE PATH "") -set(GEOSX_TPL_DIR ${GEOSX_TPL_ROOT_DIR}/2020-06-16/install-${CONFIG_NAME}-release CACHE PATH "") +set(GEOSX_TPL_DIR ${GEOSX_TPL_ROOT_DIR}/2020-06-17/install-${CONFIG_NAME}-release CACHE PATH "") + +set(ENABLE_UMPIRE ON CACHE BOOL "") +set(ENABLE_CHAI ON CACHE BOOL "") set(SPHINX_EXECUTABLE /collab/usr/gapps/python/build/spack-toss3.2/opt/spack/linux-rhel7-x86_64/gcc-4.9.3/python-2.7.14-7rci3jkmuht2uiwp433afigveuf4ocnu/bin/sphinx-build CACHE PATH "") set(DOXYGEN_EXECUTABLE ${GEOSX_TPL_ROOT_DIR}/doxygen/bin/doxygen CACHE PATH "") diff --git a/host-configs/LLNL/quartz-clang@10.0.0.cmake b/host-configs/LLNL/quartz-clang@10.0.0.cmake new file mode 100644 index 00000000..5b061a85 --- /dev/null +++ b/host-configs/LLNL/quartz-clang@10.0.0.cmake @@ -0,0 +1,14 @@ +set(CONFIG_NAME "quartz-clang@10.0.0" CACHE PATH "") + +set(COMPILER_DIR /usr/tce/packages/clang/clang-10.0.0/ ) +set(CMAKE_C_COMPILER ${COMPILER_DIR}/bin/clang CACHE PATH "") +set(CMAKE_CXX_COMPILER ${COMPILER_DIR}/bin/clang++ CACHE PATH "") +set(CMAKE_Fortran_COMPILER /usr/tce/packages/gcc/gcc-4.9.3/bin/gfortran CACHE PATH "") + +set(CMAKE_C_FLAGS_RELEASE "-O3 -DNDEBUG -march=native -mtune=native" CACHE STRING "") +set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG -march=native -mtune=native" CACHE STRING "") +set(CMAKE_Fortran_FLAGS_RELEASE "-O3 -DNDEBUG -march=native -mtune=native" CACHE STRING "") + +set(MPI_HOME /usr/tce/packages/mvapich2/mvapich2-2.3-clang-10.0.0 CACHE PATH "") + +include(${CMAKE_CURRENT_LIST_DIR}/../../host-configs/LLNL/quartz-base.cmake) diff --git a/src/Array.hpp b/src/Array.hpp index 27ae210c..f19995cb 100644 --- a/src/Array.hpp +++ b/src/Array.hpp @@ -29,14 +29,6 @@ #include "bufferManipulation.hpp" #include "StackBuffer.hpp" -// TPL includes -#include - -// System includes -#include -#include - - namespace LvArray { @@ -65,9 +57,9 @@ namespace LvArray */ template< typename T, int NDIM, - typename PERMUTATION=camp::make_idx_seq_t< NDIM >, - typename INDEX_TYPE=std::ptrdiff_t, - template< typename > class BUFFER_TYPE=NewChaiBuffer > + typename PERMUTATION, + typename INDEX_TYPE, + template< typename > class BUFFER_TYPE > class Array : public ArrayView< T, NDIM, getStrideOneDimension( PERMUTATION {} ), @@ -78,26 +70,29 @@ class Array : public ArrayView< T, // Check that the template arguments are valid. static_assert( NDIM >= 0, "The dimension of the Array must be positive." ); - static_assert( getDimension( PERMUTATION {} ) == NDIM, "The dimension of the permutation must match the dimension of the Array." ); static_assert( isValidPermutation( PERMUTATION {} ), "The permutation must be valid." ); + static_assert( getDimension( PERMUTATION {} ) == NDIM, "The dimension of the permutation must match the dimension of the Array." ); static_assert( std::is_integral< INDEX_TYPE >::value, "INDEX_TYPE must be integral." ); /// The dimensionality of the array. static constexpr int ndim = NDIM; + /// The permutation of the array. + using permutation = PERMUTATION; + /// The dimension with unit stride. static constexpr int USD = getStrideOneDimension( PERMUTATION {} ); /// Alias for the parent class. - using ParentType = ArrayView< T, NDIM, USD, INDEX_TYPE, BUFFER_TYPE >; + using ParentClass = ArrayView< T, NDIM, USD, INDEX_TYPE, BUFFER_TYPE >; // Aliasing public methods of ArrayView so we don't have to use this->size etc. - using ParentType::toSlice; - using ParentType::size; - using ParentType::empty; - using ParentType::data; - using ParentType::operator[]; - using ParentType::operator(); + using ParentClass::toSlice; + using ParentClass::size; + using ParentClass::empty; + using ParentClass::data; + using ParentClass::operator[]; + using ParentClass::operator(); /// The type when all nested arrays are converted to const views to mutable values. using ViewType = ArrayView< typename GetViewType< T >::type, NDIM, USD, INDEX_TYPE, BUFFER_TYPE > const; @@ -110,7 +105,7 @@ class Array : public ArrayView< T, */ LVARRAY_HOST_DEVICE inline Array(): - ParentType( true ) + ParentClass( true ) { CalculateStrides(); #if !defined(__CUDA_ARCH__) @@ -125,16 +120,13 @@ class Array : public ArrayView< T, * @brief Constructor that takes in the dimensions as a variadic parameter list * @param dims the dimensions of the array in form ( n0, n1,..., n(NDIM-1) ) */ - template< typename ... DIMS > + template< typename ... DIMS, + typename=std::enable_if_t< sizeof ... ( DIMS ) == NDIM && + conjunction< std::is_integral< DIMS >::value ... > > > LVARRAY_HOST_DEVICE - inline explicit Array( DIMS... dims ): + inline explicit Array( DIMS const ... dims ): Array() - { - static_assert( std::is_integral< INDEX_TYPE >::value, "INDEX_TYPE needs to be integral." ); - static_assert( sizeof ... (DIMS) == NDIM, "Calling Array::Array with incorrect number of arguments." ); - - resize( dims ... ); - } + { resize( dims ... ); } /** * @brief Copy constructor. @@ -164,7 +156,7 @@ class Array : public ArrayView< T, { #if !defined(__CUDA_ARCH__) if( !std::is_trivially_destructible< T >::value ) - { this->move( chai::CPU ); } + { this->move( MemorySpace::CPU ); } #endif bufferManipulation::free( m_dataBuffer, size() ); @@ -185,7 +177,7 @@ class Array : public ArrayView< T, { return reinterpret_cast< ViewTypeConst & >( *this ); } /** - * @brief Assignment operator, performs a deep copy of rhs. + * @brief Copy assignment operator, performs a deep copy of rhs. * @param rhs Source for the assignment. * @return *this. */ @@ -204,6 +196,18 @@ class Array : public ArrayView< T, return *this; } + /** + * @brief Move assignment operator, performs a shallow copy of rhs. + * @param rhs Source for the assignment. + * @return *this. + */ + LVARRAY_HOST_DEVICE + Array & operator=( Array && rhs ) + { + ParentClass::operator=( std::move( rhs ) ); + return *this; + } + /** * @brief Assignment operator to assign the entire array to single value. * @param rhs value to set array. @@ -211,11 +215,7 @@ class Array : public ArrayView< T, */ Array & operator=( T const & rhs ) { - INDEX_TYPE const length = size(); - for( INDEX_TYPE a = 0; a < length; ++a ) - { - this->data()[a] = rhs; - } + ParentClass::operator=( rhs ); return *this; } @@ -223,8 +223,7 @@ class Array : public ArrayView< T, * @brief Resize the dimensions of the Array to match the given dimensions. * @param numDims must equal NDIMS. * @param dims the new size of the dimensions, must be of length NDIM. - * @note This does not preserve the values in the Array unless the default permutation - * is used. + * @note This does not preserve the values in the Array NDIM == 1. */ template< typename DIMS_TYPE > LVARRAY_HOST_DEVICE @@ -236,6 +235,7 @@ class Array : public ArrayView< T, for( int i = 0; i < NDIM; ++i ) { m_dims[ i ] = LvArray::integerConversion< INDEX_TYPE >( dims[ i ] ); + LVARRAY_ERROR_IF_LT( m_dims[ i ], 0 ); } CalculateStrides(); @@ -243,28 +243,16 @@ class Array : public ArrayView< T, bufferManipulation::resize( m_dataBuffer, oldSize, size() ); } - /** - * @brief Resize the dimensions of the Array to match the given dimensions. - * @param numDims must equal NDIMS. - * @param dims the new size of the dimensions, must be of length NDIM. - * @note This does not preserve the values in the Array unless the default permutation is used. - * @note this is required due to an issue where some compilers may prefer the full variadic - * parameter pack template resize( DIMS... newDims ) - */ - template< typename DIMS_TYPE > - LVARRAY_HOST_DEVICE - void resize( int const numDims, DIMS_TYPE * const dims ) - { resize( numDims, const_cast< DIMS_TYPE const * >(dims) ); } - /** * @brief function to resize the array. * @tparam DIMS Variadic list of integral types. * @param newDims The new dimensions, must be of length NDIM. - * @note This does not preserve the values in the Array unless the default permutation is used. + * @note This does not preserve the values in the Array unless NDIM == 1. */ template< typename ... DIMS > LVARRAY_HOST_DEVICE - void resize( DIMS... newDims ) + std::enable_if_t< sizeof ... ( DIMS ) == NDIM && conjunction< std::is_integral< DIMS >::value ... > > + resize( DIMS... newDims ) { static_assert( sizeof ... ( DIMS ) == NDIM, "The number of arguments provided does not equal NDIM!" ); INDEX_TYPE const oldSize = size(); @@ -273,6 +261,7 @@ class Array : public ArrayView< T, forEachArg( [&curDim, dims=m_dims]( auto const newDim ) { dims[ curDim++ ] = LvArray::integerConversion< INDEX_TYPE >( newDim ); + LVARRAY_ERROR_IF_LT( dims[ curDim ], 0 ); }, newDims ... ); CalculateStrides(); @@ -282,22 +271,25 @@ class Array : public ArrayView< T, /** * @brief Resize the array without initializing any new values or destroying any old values. - * Only safe on POD data, however it is much faster for large allocations. + * Only safe on POD data, however it is much faster for large allocations. * @tparam DIMS Variadic list of integral types. * @param newDims The new dimensions, must be of length NDIM. - * @note This does not preserve the values in the Array unless the default permutation is used. + * @note This does not preserve the values in the Array unless NDIM == 1. */ template< typename ... DIMS > LVARRAY_HOST_DEVICE void resizeWithoutInitializationOrDestruction( DIMS const ... newDims ) { static_assert( sizeof ... ( DIMS ) == NDIM, "The number of arguments provided does not equal NDIM!" ); + static_assert( std::is_trivially_destructible< T >::value, "This function is only safe if T is trivially destructable." ); + INDEX_TYPE const oldSize = size(); int i = 0; forEachArg( [&i, dims=m_dims]( auto const newDim ) { dims[ i++ ] = LvArray::integerConversion< INDEX_TYPE >( newDim ); + LVARRAY_ERROR_IF_LT( dims[ i ], 0 ); }, newDims ... ); CalculateStrides(); @@ -307,11 +299,11 @@ class Array : public ArrayView< T, /** * @brief Resize specific dimensions of the array. - * @tparam INDICES the indices of the dimensions to resize. + * @tparam INDICES the indices of the dimensions to resize, should be sorted an unique. * @tparam DIMS variadic pack containing the dimension types * @param newDims the new dimensions. newDims[ 0 ] will be the new size of * dimensions INDICES[ 0 ]. - * @note This does not preserve the values in the Array. + * @note This does not preserve the values in the Array unless NDIM == 1. */ template< INDEX_TYPE... INDICES, typename ... DIMS > LVARRAY_HOST_DEVICE @@ -327,6 +319,7 @@ class Array : public ArrayView< T, forEachArg( [&]( auto const & pair ) { m_dims[ camp::get< 0 >( pair ) ] = LvArray::integerConversion< INDEX_TYPE >( camp::get< 1 >( pair ) ); + LVARRAY_ERROR_IF_LT( m_dims[ camp::get< 0 >( pair ) ], 0 ); }, camp::make_tuple( INDICES, newDims )... ); CalculateStrides(); @@ -385,91 +378,61 @@ class Array : public ArrayView< T, } /** - * @brief Append a value to the end of the array. - * @param value the value to append via a copy. - * @note This method is only available on 1D arrays. - * @return void. - */ - template< int N=NDIM > - std::enable_if_t< N == 1 > - push_back( T const & value ) - { - bufferManipulation::pushBack( m_dataBuffer, size(), value ); - ++m_dims[ 0 ]; - } - - /** - * @brief Append a value to the end of the array. - * @param value the value to append via a move. + * @brief Construct a value in place at the end of the array. + * @tparam ARGS A variadic pack of the types to construct the new value from. + * @param args A variadic pack of values to construct the new value from. * @note This method is only available on 1D arrays. * @return void. - * */ - template< int N=NDIM > - std::enable_if_t< N == 1 > - push_back( T && value ) + template< typename ... ARGS, int _NDIM=NDIM > + std::enable_if_t< _NDIM == 1 > + emplace_back( ARGS && ... args ) { - bufferManipulation::pushBack( m_dataBuffer, size(), std::move( value ) ); + bufferManipulation::emplaceBack( m_dataBuffer, size(), std::forward< ARGS >( args ) ... ); ++m_dims[ 0 ]; } /** - * @brief Remove the last value in the array. - * @note This method is only available on 1D arrays. - * @return void. - */ - template< int N=NDIM > - std::enable_if_t< N == 1 > - pop_back() - { - bufferManipulation::popBack( m_dataBuffer, size() ); - --m_dims[ 0 ]; - } - - /** - * @brief Insert a value into the array at the given position. + * @brief Insert a value into the array constructing it in place. + * @tparam ARGS A variadic pack of the types to construct the new value from. * @param pos the position to insert at. - * @param value the value to insert via a copy. + * @param args A variadic pack of values to construct the new value from. * @note This method is only available on 1D arrays. * @return void. */ - template< int N=NDIM > - std::enable_if_t< N == 1 > - insert( INDEX_TYPE const pos, T const & value ) + template< typename ... ARGS, int _NDIM=NDIM > + std::enable_if_t< _NDIM == 1 > + emplace( INDEX_TYPE const pos, ARGS && ... args ) { - bufferManipulation::insert( m_dataBuffer, size(), pos, value ); + bufferManipulation::emplace( m_dataBuffer, size(), pos, std::forward< ARGS >( args ) ... ); ++m_dims[ 0 ]; } /** - * @brief Insert a value into the array at the given position. - * @param pos the position to insert at. - * @param value the value to insert via a move. + * @brief Insert values into the array at the given position. + * @tparam ITER An iterator type, they type of @p first and @p last. + * @param pos The position to insert at. + * @param first An iterator to the first value to insert. + * @param last An iterator to the last value to insert. * @note This method is only available on 1D arrays. - * @return void. + * @return None. */ - template< int N=NDIM > - std::enable_if_t< N == 1 > - insert( INDEX_TYPE const pos, T && value ) - { - bufferManipulation::insert( m_dataBuffer, size(), pos, std::move( value ) ); - ++m_dims[ 0 ]; - } + template< typename ITER, int _NDIM=NDIM > + std::enable_if_t< _NDIM == 1 > + insert( INDEX_TYPE const pos, ITER const first, ITER const last ) + { m_dims[ 0 ] += bufferManipulation::insert( m_dataBuffer, size(), pos, first, last ); } /** - * @brief Insert values into the array at the given position. - * @param pos the position to insert at. - * @param values a pointer to the values to insert via copies. - * @param n the number of values to insert. + * @brief Remove the last value in the array. * @note This method is only available on 1D arrays. * @return void. */ - template< int N=NDIM > - std::enable_if_t< N == 1 > - insert( INDEX_TYPE const pos, T const * const values, INDEX_TYPE const n ) + template< int _NDIM=NDIM > + std::enable_if_t< _NDIM == 1 > + pop_back() { - bufferManipulation::insert( m_dataBuffer, size(), pos, values, n ); - m_dims[ 0 ] += n; + bufferManipulation::popBack( m_dataBuffer, size() ); + --m_dims[ 0 ]; } /** @@ -478,9 +441,9 @@ class Array : public ArrayView< T, * @note This method is only available on 1D arrays. * @return void. */ - template< int N=NDIM > - std::enable_if_t< N == 1 > - erase( INDEX_TYPE pos ) + template< int _NDIM=NDIM > + std::enable_if_t< _NDIM == 1 > + erase( INDEX_TYPE const pos ) { bufferManipulation::erase( m_dataBuffer, size(), pos ); --m_dims[ 0 ]; @@ -520,17 +483,17 @@ class Array : public ArrayView< T, */ static int TV_ttf_display_type( Array const * av ) { - return ParentType::TV_ttf_display_type( av ); + return ParentClass::TV_ttf_display_type( av ); } #endif private: // Aliasing the protected members of ArrayView. - using ParentType::m_dataBuffer; - using ParentType::m_dims; - using ParentType::m_strides; - using ParentType::m_singleParameterResizeIndex; + using ParentClass::m_dataBuffer; + using ParentClass::m_dims; + using ParentClass::m_strides; + using ParentClass::m_singleParameterResizeIndex; /** * @brief Calculate the strides given the dimensions and permutation. @@ -539,7 +502,7 @@ class Array : public ArrayView< T, LVARRAY_HOST_DEVICE void CalculateStrides() { - constexpr CArray< camp::idx_t, NDIM > permutation = asArray( PERMUTATION {} ); + constexpr CArray< camp::idx_t, NDIM > perm = asArray( PERMUTATION {} ); INDEX_TYPE foldedStrides[ NDIM ]; for( int i = 0; i < NDIM; ++i ) @@ -547,13 +510,13 @@ class Array : public ArrayView< T, foldedStrides[ i ] = 1; for( int j = i + 1; j < NDIM; ++j ) { - foldedStrides[ i ] *= m_dims[ permutation[ j ] ]; + foldedStrides[ i ] *= m_dims[ perm[ j ] ]; } } for( int i = 0; i < NDIM; ++i ) { - m_strides[ permutation[ i ] ] = foldedStrides[ i ]; + m_strides[ perm[ i ] ] = foldedStrides[ i ]; } } @@ -561,7 +524,7 @@ class Array : public ArrayView< T, * @brief Resize the default dimension of the Array. * @tparam ARGS variadic pack containing the types to initialize the new values with. * @param newDimLength the new size of the default dimension. - * @param ARGS arguments to initialize the new values with. + * @param args arguments to initialize the new values with. * @note This preserves the values in the Array. * @note The default dimension is given by m_singleParameterResizeIndex. */ @@ -570,6 +533,19 @@ class Array : public ArrayView< T, LVARRAY_HOST_DEVICE void resizeDefaultDimension( INDEX_TYPE const newDimLength, ARGS && ... args ) { + LVARRAY_ERROR_IF_LT( newDimLength, 0 ); + + // If m_singleParameterResizeIndex is the first dimension in memory than a simple 1D resizing is sufficient. The + // check if NDIM == 1 is to give the compiler compile time knowledge that this path is always taken for 1D arrays. + if( NDIM == 1 || asArray( PERMUTATION {} )[ 0 ] == m_singleParameterResizeIndex ) + { + INDEX_TYPE const oldSize = size(); + m_dims[ m_singleParameterResizeIndex ] = newDimLength; + CalculateStrides(); + bufferManipulation::resize( m_dataBuffer, oldSize, size(), std::forward< ARGS >( args )... ); + return; + } + // Get the current length and stride of the dimension as well as the size of the whole Array. INDEX_TYPE const curDimLength = m_dims[ m_singleParameterResizeIndex ]; INDEX_TYPE const curDimStride = m_strides[ m_singleParameterResizeIndex ]; @@ -609,7 +585,7 @@ class Array : public ArrayView< T, T * const startOfNewValues = startOfShift + valuesToShiftPerIteration + valuesLeftToInsert; for( INDEX_TYPE j = 0; j < valuesToAddPerIteration; ++j ) { - new ( startOfNewValues + j ) T( std::forward< ARGS >( args )... ); + new ( startOfNewValues + j ) T( args ... ); } } } @@ -640,7 +616,6 @@ class Array : public ArrayView< T, } } } - }; /** @@ -651,24 +626,32 @@ constexpr bool isArray = false; /** * @tparam T The type contained in the Array. - * @tparam NDIM The number of dimensions of the Array. + * @tparam NDIM The number of dimensions in the Array. * @tparam PERMUTATION The way that the data is layed out in memory. * @tparam INDEX_TYPE The integral type used as in index. - * @tparam DATA_VECTOR_TYPE The type used to manage the underlying allocation. + * @tparam BUFFER_TYPE The type used to manage the underlying allocation. * @brief Specialization of isArray for the Array class. */ template< typename T, int NDIM, typename PERMUTATION, typename INDEX_TYPE, - template< typename > class DATA_VECTOR_TYPE > -constexpr bool isArray< Array< T, NDIM, PERMUTATION, INDEX_TYPE, DATA_VECTOR_TYPE > > = true; + template< typename > class BUFFER_TYPE > +constexpr bool isArray< Array< T, NDIM, PERMUTATION, INDEX_TYPE, BUFFER_TYPE > > = true; namespace internal { // Since Array expects the BUFFER to only except a single template parameter we need to // create an alias for a StackBuffer with a given length. +/** + * @struct StackArrayHelper + * @tparam T The type stored in the Array. + * @tparam NDIM The number of dimensions in the Array. + * @tparam PERMUTATION The dimension and permutation of the Array. + * @tparam INDEX_TYPE The integer used to index the Array. + * @tparam LENGTH The capacity of the underlying StackBuffer. + */ template< typename T, int NDIM, typename PERMUTATION, @@ -676,9 +659,14 @@ template< typename T, int LENGTH > struct StackArrayHelper { + /** + * @brief An alias for a StackBuffer with the given length. + * @tparam U The type contained in the StackBuffer. + */ template< typename U > using BufferType = StackBuffer< U, LENGTH >; + /// An alias for the Array type. using type = Array< T, NDIM, PERMUTATION, INDEX_TYPE, BufferType >; }; diff --git a/src/ArrayOfArrays.hpp b/src/ArrayOfArrays.hpp index 56b007f6..31b8eedd 100644 --- a/src/ArrayOfArrays.hpp +++ b/src/ArrayOfArrays.hpp @@ -28,7 +28,7 @@ namespace LvArray { // Forward declaration of the ArrayOfSets class so that we can define the stealFrom method. -template< class T, class INDEX_TYPE > +template< typename T, typename INDEX_TYPE, template< typename > class BUFFER_TYPE > class ArrayOfSets; /** @@ -37,13 +37,26 @@ class ArrayOfSets; * @tparam T the type stored in the arrays. * @tparam INDEX_TYPE the integer to use for indexing. */ -template< class T, typename INDEX_TYPE=std::ptrdiff_t > -class ArrayOfArrays : protected ArrayOfArraysView< T, INDEX_TYPE > +template< typename T, + typename INDEX_TYPE, + template< typename > class BUFFER_TYPE > +class ArrayOfArrays : protected ArrayOfArraysView< T, INDEX_TYPE, false, BUFFER_TYPE > { + /// An alias for the parent class. + using ParentClass = ArrayOfArraysView< T, INDEX_TYPE, false, BUFFER_TYPE >; + public: + /// An alias for the type contained in the arrays. + using value_type = T; + + /// An alias for the view type. Supports adding/removing values from arrays and modifying existing values. + using ViewType = ArrayOfArraysView< T, INDEX_TYPE const, false, BUFFER_TYPE >; + + /// An alias for the view type with const sizes. Supports modifying existing values. + using ViewTypeConstSizes = ArrayOfArraysView< T, INDEX_TYPE const, true, BUFFER_TYPE >; - /// An alias for the parent class ArrayOfArraysView< T, INDEX_TYPE >. - using ParentClass = ArrayOfArraysView< T, INDEX_TYPE >; + /// An alias for the const view type. Only accessing existing values is supported. + using ViewTypeConst = ArrayOfArraysView< T const, INDEX_TYPE const, true, BUFFER_TYPE >; // Aliasing public methods of ArrayOfArraysView. using ParentClass::sizeOfArray; @@ -52,8 +65,7 @@ class ArrayOfArrays : protected ArrayOfArraysView< T, INDEX_TYPE > using ParentClass::capacityOfArray; using ParentClass::operator[]; using ParentClass::operator(); - using ParentClass::getIterableArray; - using ParentClass::atomicAppendToArray; + using ParentClass::emplaceBackAtomic; using ParentClass::eraseFromArray; /** @@ -124,7 +136,7 @@ class ArrayOfArrays : protected ArrayOfArraysView< T, INDEX_TYPE > * @param src the ArrayOfSets to convert. */ inline - void stealFrom( ArrayOfSets< T, INDEX_TYPE > && src ) + void stealFrom( ArrayOfSets< T, INDEX_TYPE, BUFFER_TYPE > && src ) { ParentClass::free(); ParentClass::stealFrom( reinterpret_cast< ParentClass && >( src ) ); @@ -135,15 +147,15 @@ class ArrayOfArrays : protected ArrayOfArraysView< T, INDEX_TYPE > * @note Duplicated for SFINAE needs. */ constexpr inline - ArrayOfArraysView< T, INDEX_TYPE const > const & toView() const LVARRAY_RESTRICT_THIS - { return reinterpret_cast< ArrayOfArraysView< T, INDEX_TYPE const > const & >( *this ); } + ArrayOfArraysView< T, INDEX_TYPE const, false, BUFFER_TYPE > const & toView() const LVARRAY_RESTRICT_THIS + { return reinterpret_cast< ArrayOfArraysView< T, INDEX_TYPE const, false, BUFFER_TYPE > const & >( *this ); } /** * @brief @return Return a reference to *this converted to ArrayOfArraysView. * @note Duplicated for SFINAE needs. */ LVARRAY_HOST_DEVICE constexpr inline - ArrayOfArraysView< T, INDEX_TYPE const, true > const & toViewConstSizes() const LVARRAY_RESTRICT_THIS + ArrayOfArraysView< T, INDEX_TYPE const, true, BUFFER_TYPE > const & toViewConstSizes() const LVARRAY_RESTRICT_THIS { return ParentClass::toViewConstSizes(); } /** @@ -151,7 +163,7 @@ class ArrayOfArrays : protected ArrayOfArraysView< T, INDEX_TYPE > * @note Duplicated for SFINAE needs. */ LVARRAY_HOST_DEVICE constexpr inline - ArrayOfArraysView< T const, INDEX_TYPE const, true > const & toViewConst() const LVARRAY_RESTRICT_THIS + ArrayOfArraysView< T const, INDEX_TYPE const, true, BUFFER_TYPE > const & toViewConst() const LVARRAY_RESTRICT_THIS { return ParentClass::toViewConst(); } /** @@ -205,8 +217,8 @@ class ArrayOfArrays : protected ArrayOfArraysView< T, INDEX_TYPE > LVARRAY_ASSERT( arrayManipulation::isPositive( n ) ); INDEX_TYPE const maxOffset = m_offsets[ m_numArrays ]; - bufferManipulation::pushBack( m_offsets, m_numArrays + 1, maxOffset ); - bufferManipulation::pushBack( m_sizes, m_numArrays, 0 ); + bufferManipulation::emplaceBack( m_offsets, m_numArrays + 1, maxOffset ); + bufferManipulation::emplaceBack( m_sizes, m_numArrays, 0 ); ++m_numArrays; resizeArray( m_numArrays - 1, n ); @@ -214,39 +226,41 @@ class ArrayOfArrays : protected ArrayOfArraysView< T, INDEX_TYPE > /** * @brief Append an array. - * @param values the values of the array to append. - * @param n the number of values. + * @tparam ITER An iterator, the type of @p first and @p last. + * @param first An iterator to the first value of the array to append. + * @param last An iterator to the end of the array to append. */ - void appendArray( T const * const values, INDEX_TYPE const n ) LVARRAY_RESTRICT_THIS + template< typename ITER > + void appendArray( ITER const first, ITER const last ) LVARRAY_RESTRICT_THIS { INDEX_TYPE const maxOffset = m_offsets[ m_numArrays ]; - bufferManipulation::pushBack( m_offsets, m_numArrays + 1, maxOffset ); - bufferManipulation::pushBack( m_sizes, m_numArrays, 0 ); + bufferManipulation::emplaceBack( m_offsets, m_numArrays + 1, maxOffset ); + bufferManipulation::emplaceBack( m_sizes, m_numArrays, 0 ); ++m_numArrays; - appendToArray( m_numArrays - 1, values, n ); + appendToArray( m_numArrays - 1, first, last ); } /** * @brief Insert an array. + * @tparam ITER An iterator, the type of @p first and @p last. * @param i the position to insert the array. - * @param values the values of the array to insert. - * @param n the number of values. + * @param first An iterator to the first value of the array to insert. + * @param last An iterator to the end of the array to insert. */ - void insertArray( INDEX_TYPE const i, T const * const values, INDEX_TYPE const n ) + template< typename ITER > + void insertArray( INDEX_TYPE const i, ITER const first, ITER const last ) { ARRAYOFARRAYS_CHECK_INSERT_BOUNDS( i ); - LVARRAY_ASSERT( arrayManipulation::isPositive( n ) ); - LVARRAY_ASSERT( n == 0 || values != nullptr ); // Insert an array of capacity zero at the given location - INDEX_TYPE const offset = m_offsets[i]; - bufferManipulation::insert( m_offsets, m_numArrays + 1, i + 1, offset ); - bufferManipulation::insert( m_sizes, m_numArrays, i, 0 ); + INDEX_TYPE const offset = m_offsets[ i ]; + bufferManipulation::emplace( m_offsets, m_numArrays + 1, i + 1, offset ); + bufferManipulation::emplace( m_sizes, m_numArrays, i, 0 ); ++m_numArrays; // Append to the new array - appendToArray( i, values, n ); + appendToArray( i, first, last ); } /** @@ -271,74 +285,61 @@ class ArrayOfArrays : protected ArrayOfArraysView< T, INDEX_TYPE > { ParentClass::compress(); } /** - * @brief Append a value to an array. + * @brief Append a value to an array constructing it in place with the given arguments. + * @tparam ARGS Variadic pack of types used to construct T. * @param i the array to append to. - * @param value the value to append. + * @param args A variadic pack of arguments that are forwarded to construct the new value. */ - void appendToArray( INDEX_TYPE const i, T const & value ) LVARRAY_RESTRICT_THIS + template< typename ... ARGS > + void emplaceBack( INDEX_TYPE const i, ARGS && ... args ) LVARRAY_RESTRICT_THIS { dynamicallyGrowArray( i, 1 ); - ParentClass::appendToArray( i, value ); - } - - /** - * @brief Append a value to an array. - * @param i the array to append to. - * @param value the value to append. - */ - void appendToArray( INDEX_TYPE const i, T && value ) LVARRAY_RESTRICT_THIS - { - dynamicallyGrowArray( i, 1 ); - ParentClass::appendToArray( i, std::move( value ) ); + ParentClass::emplaceBack( i, std::forward< ARGS >( args )... ); } /** * @brief Append values to an array. + * @tparam ITER An iterator, the type of @p first and @p last. * @param i the array to append to. - * @param values the values to append. - * @param n the number of values to append. + * @param first An iterator to the first value to append. + * @param last An iterator to the end of the values to append. */ - void appendToArray( INDEX_TYPE const i, T const * const values, INDEX_TYPE const n ) LVARRAY_RESTRICT_THIS + template< typename ITER > + void appendToArray( INDEX_TYPE const i, ITER const first, ITER const last ) LVARRAY_RESTRICT_THIS { + INDEX_TYPE const n = iterDistance( first, last ); dynamicallyGrowArray( i, n ); - ParentClass::appendToArray( i, values, n ); - } - - /** - * @brief Insert a value into an array. - * @param i the array to insert into. - * @param j the position at which to insert. - * @param value the value to insert. - */ - void insertIntoArray( INDEX_TYPE const i, INDEX_TYPE const j, T const & value ) - { - dynamicallyGrowArray( i, 1 ); - ParentClass::insertIntoArray( i, j, value ); + ParentClass::appendToArray( i, first, last ); } /** - * @brief Insert a value into an array. + * @brief Insert a value into an array constructing it in place. + * @tparam ARGS Variadic pack of types used to construct T. * @param i the array to insert into. * @param j the position at which to insert. - * @param value the value to insert. + * @param args A variadic pack of arguments that are forwarded to construct the new value. */ - void insertIntoArray( INDEX_TYPE const i, INDEX_TYPE const j, T && value ) + template< typename ... ARGS > + void emplace( INDEX_TYPE const i, INDEX_TYPE const j, ARGS && ... args ) { dynamicallyGrowArray( i, 1 ); - ParentClass::insertIntoArray( i, j, std::move( value ) ); + ParentClass::emplace( i, j, std::forward< ARGS >( args )... ); } /** * @brief Insert values into an array. + * @tparam ITER An iterator, the type of @p first and @p last. * @param i the array to insert into. * @param j the position at which to insert. - * @param values the values to insert. - * @param n the number of values to insert. + * @param first An iterator to the first value to insert. + * @param last An iterator to the end of the values to insert. */ - void insertIntoArray( INDEX_TYPE const i, INDEX_TYPE const j, T const * const values, INDEX_TYPE const n ) + template< typename ITER > + void insertIntoArray( INDEX_TYPE const i, INDEX_TYPE const j, ITER const first, ITER const last ) { + INDEX_TYPE const n = iterDistance( first, last ); dynamicallyGrowArray( i, n ); - ParentClass::insertIntoArray( i, j, values, n ); + ParentClass::insertIntoArray( i, j, first, last ); } /** @@ -394,7 +395,7 @@ class ArrayOfArrays : protected ArrayOfArraysView< T, INDEX_TYPE > * @note When moving to the GPU since the offsets can't be modified on device they are not touched. * @note Duplicated for SFINAE needs. */ - void move( chai::ExecutionSpace const space, bool touch=true ) const + void move( MemorySpace const space, bool touch=true ) const { ParentClass::move( space, touch ); } private: diff --git a/src/ArrayOfArraysView.hpp b/src/ArrayOfArraysView.hpp index 54e388cb..b0bef2e5 100644 --- a/src/ArrayOfArraysView.hpp +++ b/src/ArrayOfArraysView.hpp @@ -23,7 +23,6 @@ #pragma once // Source includes -#include "NewChaiBuffer.hpp" #include "bufferManipulation.hpp" #include "arrayManipulation.hpp" #include "ArraySlice.hpp" @@ -32,6 +31,9 @@ // TPL includes #include +// System includes +#include + #ifdef USE_ARRAY_BOUNDS_CHECK /** @@ -155,12 +157,6 @@ namespace LvArray { -namespace internal -{ -template< class U > -using PairOfBuffers = std::pair< NewChaiBuffer< U > &, NewChaiBuffer< U > const & >; -} - /** * @class ArrayOfArraysView * @brief This class provides a view into an array of arrays like object. @@ -174,7 +170,10 @@ using PairOfBuffers = std::pair< NewChaiBuffer< U > &, NewChaiBuffer< U > const * * When CONST_SIZES is true m_sizes is not copied between memory spaces. */ -template< class T, class INDEX_TYPE=std::ptrdiff_t, bool CONST_SIZES=false > +template< class T, + class INDEX_TYPE, + bool CONST_SIZES, + template< typename > class BUFFER_TYPE > class ArrayOfArraysView { public: @@ -236,22 +235,25 @@ class ArrayOfArraysView * @brief This is included for SFINAE needs. */ LVARRAY_HOST_DEVICE constexpr inline - ArrayOfArraysView< T, INDEX_TYPE, CONST_SIZES > const & toView() const LVARRAY_RESTRICT_THIS + ArrayOfArraysView< T, INDEX_TYPE, CONST_SIZES, BUFFER_TYPE > const & + toView() const LVARRAY_RESTRICT_THIS { return *this; } /** * @brief @return Return a reference to *this reinterpreted as an ArrayOfArraysView. */ LVARRAY_HOST_DEVICE constexpr inline - ArrayOfArraysView< T, INDEX_TYPE const, true > const & toViewConstSizes() const LVARRAY_RESTRICT_THIS - { return reinterpret_cast< ArrayOfArraysView< T, INDEX_TYPE const, true > const & >( *this ); } + ArrayOfArraysView< T, INDEX_TYPE const, true, BUFFER_TYPE > const & + toViewConstSizes() const LVARRAY_RESTRICT_THIS + { return reinterpret_cast< ArrayOfArraysView< T, INDEX_TYPE const, true, BUFFER_TYPE > const & >( *this ); } /** * @brief @return Return a reference to *this reinterpreted as an ArrayOfArraysView. */ LVARRAY_HOST_DEVICE constexpr inline - ArrayOfArraysView< T const, INDEX_TYPE const, true > const & toViewConst() const LVARRAY_RESTRICT_THIS - { return reinterpret_cast< ArrayOfArraysView< T const, INDEX_TYPE const, true > const & >( *this ); } + ArrayOfArraysView< T const, INDEX_TYPE const, true, BUFFER_TYPE > const & + toViewConst() const LVARRAY_RESTRICT_THIS + { return reinterpret_cast< ArrayOfArraysView< T const, INDEX_TYPE const, true, BUFFER_TYPE > const & >( *this ); } /** * @brief @return Return the number of arrays. @@ -322,89 +324,38 @@ class ArrayOfArraysView return m_values[m_offsets[i] + j]; } - /** - * @class IterableArray - * @brief Presents a container interface to an inner array. - * @note This class will be removed once `begin` and `end` are added to ArraySlice. - */ - class IterableArray - { -public: - - /** - * @brief Constructor. - * @param data A pointer to the data to iterate over. - * @param size The size of the array. - */ - LVARRAY_HOST_DEVICE constexpr inline - IterableArray( T * const data, INDEX_TYPE const size ): - m_data( data ), - m_size( size ) - {} - - /** - * @brief @return Return a pointer to the beginning of the array. - */ - LVARRAY_HOST_DEVICE constexpr inline - T * begin() const LVARRAY_RESTRICT_THIS - { return m_data; } - - /** - * @brief @return Return a pointer to the end of the array. - */ - LVARRAY_HOST_DEVICE constexpr inline - T * end() const LVARRAY_RESTRICT_THIS - { return m_data + m_size; } - -private: - - /// A pointer to the data to iterate over. - T * const m_data; - - /// The size. - INDEX_TYPE const m_size; - }; - - /** - * @brief @return Return an iterable object representing array @p i. - * @param i The array to access. - */ - LVARRAY_HOST_DEVICE CONSTEXPR_WITHOUT_BOUNDS_CHECK inline - IterableArray getIterableArray( INDEX_TYPE const i ) const LVARRAY_RESTRICT_THIS - { - ARRAYOFARRAYS_CHECK_BOUNDS( i ); - return IterableArray( m_values.data() + m_offsets[i], m_sizes[i] ); - } - /** * @brief Append a value to an array. + * @tparam ARGS A variadic pack of types used to construct the new T, the types of @p args. * @param i the array to append to. - * @param value the value to append. + * @param args The variadic pack of arguments forwared to construct the new value. * @pre Since the ArrayOfArraysView can't do reallocation or shift the offsets it is * up to the user to ensure that the given array has enough space for the new values. */ + template< typename ... ARGS > LVARRAY_HOST_DEVICE inline - void appendToArray( INDEX_TYPE const i, T const & value ) const LVARRAY_RESTRICT_THIS + void emplaceBack( INDEX_TYPE const i, ARGS && ... args ) const LVARRAY_RESTRICT_THIS { ARRAYOFARRAYS_CHECK_BOUNDS( i ); ARRAYOFARRAYS_CAPACITY_CHECK( i, 1 ); T * const ptr = m_values.data() + m_offsets[ i ]; - arrayManipulation::append( ptr, sizeOfArray( i ), value ); + arrayManipulation::emplaceBack( ptr, sizeOfArray( i ), std::forward< ARGS >( args ) ... ); m_sizes[i] += 1; } /** - * @tparam POLICY The RAJA atomic policy to use to increment the size of the array. * @brief Append a value to an array in a thread safe manner. + * @tparam POLICY The RAJA atomic policy to use to increment the size of the array. + * @tparam ARGS A variadic pack of types used to construct the new T, the types of @p args. * @param i the array to append to. - * @param value the value to append. + * @param args The variadic pack of arguments forwared to construct the new value. * @pre Since the ArrayOfArraysView can't do reallocation or shift the offsets it is * up to the user to ensure that the given array has enough space for the new values. */ - template< class POLICY > + template< typename POLICY, typename ... ARGS > LVARRAY_HOST_DEVICE inline - void atomicAppendToArray( POLICY, INDEX_TYPE const i, T const & value ) const LVARRAY_RESTRICT_THIS + void emplaceBackAtomic( INDEX_TYPE const i, ARGS && ... args ) const LVARRAY_RESTRICT_THIS { ARRAYOFARRAYS_CHECK_BOUNDS( i ); @@ -412,104 +363,75 @@ class ArrayOfArraysView INDEX_TYPE const previousSize = RAJA::atomicInc< POLICY >( &m_sizes[ i ] ); ARRAYOFARRAYS_ATOMIC_CAPACITY_CHECK( i, previousSize, 1 ); - arrayManipulation::append( ptr, previousSize, value ); - } - - /** - * @brief Append a value to an array. - * @param i the array to append to. - * @param value the value to append. - * - * @pre Since the ArrayOfArraysView can't do reallocation or shift the offsets it is - * up to the user to ensure that the given array has enough space for the new values. - */ - LVARRAY_HOST_DEVICE inline - void appendToArray( INDEX_TYPE const i, T && value ) const LVARRAY_RESTRICT_THIS - { - ARRAYOFARRAYS_CHECK_BOUNDS( i ); - ARRAYOFARRAYS_CAPACITY_CHECK( i, 1 ); - - T * const ptr = m_values.data() + m_offsets[ i ]; - arrayManipulation::append( ptr, sizeOfArray( i ), std::move( value ) ); - m_sizes[i]++; + arrayManipulation::emplaceBack( ptr, previousSize, std::forward< ARGS >( args ) ... ); } /** * @brief Append values to an array. + * @tparam ITER An iterator, they type of @p first and @p last. * @param i the array to append to. - * @param values the values to append. - * @param n the number of values to append. - * + * @param first An iterator to the first value to append. + * @param last An iterator to the end of the values to append. * @pre Since the ArrayOfArraysView can't do reallocation or shift the offsets it is * up to the user to ensure that the given array has enough space for the new values. */ + template< typename ITER > LVARRAY_HOST_DEVICE inline - void appendToArray( INDEX_TYPE const i, T const * const values, INDEX_TYPE const n ) const LVARRAY_RESTRICT_THIS + void appendToArray( INDEX_TYPE const i, ITER const first, ITER const last ) const LVARRAY_RESTRICT_THIS { ARRAYOFARRAYS_CHECK_BOUNDS( i ); - ARRAYOFARRAYS_CAPACITY_CHECK( i, n ); T * const ptr = m_values.data() + m_offsets[ i ]; - arrayManipulation::append( ptr, sizeOfArray( i ), values, n ); - m_sizes[i] += n; - } - - /** - * @brief Insert a value into an array. - * @param i the array to insert into. - * @param j the position at which to insert. - * @param value the value to insert. - * @pre Since the ArrayOfArraysView can't do reallocation or shift the offsets it is - * up to the user to ensure that the given array has enough space for the new values. - */ - LVARRAY_HOST_DEVICE inline - void insertIntoArray( INDEX_TYPE const i, INDEX_TYPE const j, T const & value ) const LVARRAY_RESTRICT_THIS - { - ARRAYOFARRAYS_CHECK_INSERT_BOUNDS2( i, j ); - ARRAYOFARRAYS_CAPACITY_CHECK( i, 1 ); - - T * const ptr = m_values.data() + m_offsets[ i ]; - arrayManipulation::insert( ptr, sizeOfArray( i ), j, value ); - m_sizes[i]++; + INDEX_TYPE const n = arrayManipulation::append( ptr, sizeOfArray( i ), first, last ); + ARRAYOFARRAYS_CAPACITY_CHECK( i, n ); + m_sizes[ i ] += n; } /** * @brief Insert a value into an array. + * @tparam ARGS A variadic pack of types used to construct the new T, the types of @p args. * @param i the array to insert into. * @param j the position at which to insert. - * @param value the value to insert. + * @param args The variadic pack of arguments forwared to construct the new value. * @pre Since the ArrayOfArraysView can't do reallocation or shift the offsets it is * up to the user to ensure that the given array has enough space for the new values. */ + template< typename ... ARGS > LVARRAY_HOST_DEVICE inline - void insertIntoArray( INDEX_TYPE const i, INDEX_TYPE const j, T && value ) const LVARRAY_RESTRICT_THIS + void emplace( INDEX_TYPE const i, INDEX_TYPE const j, ARGS && ... args ) const LVARRAY_RESTRICT_THIS { ARRAYOFARRAYS_CHECK_INSERT_BOUNDS2( i, j ); ARRAYOFARRAYS_CAPACITY_CHECK( i, 1 ); T * const ptr = m_values.data() + m_offsets[ i ]; - arrayManipulation::insert( ptr, sizeOfArray( i ), j, std::move( value ) ); + arrayManipulation::emplace( ptr, sizeOfArray( i ), j, std::forward< ARGS >( args )... ); m_sizes[i]++; } /** * @brief Insert values into an array. + * @tparam ITER An iterator, they type of @p first and @p last. * @param i the array to insert into. * @param j the position at which to insert. - * @param values the values to insert. - * @param n the number of values to insert. + * @param first An iterator to the first value to insert. + * @param last An iterator to the end of the values to insert. * @pre Since the ArrayOfArraysView can't do reallocation or shift the offsets it is * up to the user to ensure that the given array has enough space for the new values. */ + template< typename ITER > LVARRAY_HOST_DEVICE inline - void insertIntoArray( INDEX_TYPE const i, INDEX_TYPE const j, T const * const values, INDEX_TYPE const n ) const LVARRAY_RESTRICT_THIS + void insertIntoArray( INDEX_TYPE const i, + INDEX_TYPE const j, + ITER const first, + ITER const last ) const LVARRAY_RESTRICT_THIS { ARRAYOFARRAYS_CHECK_INSERT_BOUNDS2( i, j ); + INDEX_TYPE const n = iterDistance( first, last ); ARRAYOFARRAYS_CAPACITY_CHECK( i, n ); T * const ptr = m_values.data() + m_offsets[ i ]; - arrayManipulation::insert( ptr, sizeOfArray( i ), j, values, n ); - m_sizes[i] += n; + arrayManipulation::insert( ptr, sizeOfArray( i ), j, first, n ); + m_sizes[ i ] += n; } /** @@ -534,19 +456,26 @@ class ArrayOfArraysView * @param touch If true touch the values, sizes and offsets in the new space. * @note When moving to the GPU since the offsets can't be modified on device they are not touched. */ - void move( chai::ExecutionSpace const space, bool touch=true ) const + void move( MemorySpace const space, bool touch=true ) const { m_values.move( space, touch ); m_sizes.move( space, touch ); #if defined(USE_CUDA) - if( space == chai::GPU ) touch = false; + if( space == MemorySpace::GPU ) touch = false; #endif m_offsets.move( space, touch ); } protected: + /** + * @brief Alias for a std::pair of buffers. + * @tparam U The type contained in the buffers. + */ + template< typename U > + using PairOfBuffers = std::pair< BUFFER_TYPE< U > &, BUFFER_TYPE< U > const & >; + /** * @brief Default constructor. */ @@ -561,16 +490,16 @@ class ArrayOfArraysView * @brief Steal the resources of @p src, clearing it in the process. * @param src The ArrayOfArraysView to steal from. */ - void stealFrom( ArrayOfArraysView< T, INDEX_TYPE, CONST_SIZES > && src ) + void stealFrom( ArrayOfArraysView< T, INDEX_TYPE, CONST_SIZES, BUFFER_TYPE > && src ) { *this = std::move( src ); } /** * @brief Set the number of arrays. - * @tparam BUFFERS variadic template where each type is a NewChaiBuffer. + * @tparam BUFFERS variadic template where each type is BUFFER_TYPE. * @param newSize the new number of arrays. * @param defaultArrayCapacity the default capacity for each new array. - * @param buffers variadic parameter pack where each argument is a NewChaiBuffer that should be treated - * similarly to m_values. + * @param buffers variadic parameter pack where each argument is a BUFFER_TYPE that should be treated + * similarly to m_values. * @note This is to be use by the non-view derived classes. */ template< typename ... BUFFERS > @@ -662,8 +591,8 @@ class ArrayOfArraysView /** * @brief Destroy all the objects held by this array and free all associated memory. - * @tparam BUFFERS variadic template where each type is a NewChaiBuffer. - * @param buffers variadic parameter pack where each argument is a NewChaiBuffer that should be treated + * @tparam BUFFERS variadic template where each type is a BUFFER_TYPE. + * @param buffers variadic parameter pack where each argument is a BUFFER_TYPE that should be treated * similarly to m_values. * @note This is to be use by the non-view derived classes. */ @@ -681,24 +610,24 @@ class ArrayOfArraysView } /** - * @tparam PAIRS_OF_BUFFERS variadic template where each type is an internal::PairOfBuffers. + * @tparam PAIRS_OF_BUFFERS variadic template where each type is an PairOfBuffers. * @brief Set this ArrayOfArraysView equal to the provided arrays. * @param srcNumArrays The number of arrays in source. * @param srcMaxOffset The maximum offset in the source. * @param srcOffsets the source offsets array. * @param srcSizes the source sizes array. * @param srcValues the source values array. - * @param pairs variadic parameter pack where each argument is an internal::PairOfBuffers where each pair - * should be treated similarly to {m_values, srcValues}. + * @param pairs variadic parameter pack where each argument is an PairOfBuffers where each pair + * should be treated similarly to {m_values, srcValues}. * @note This is to be use by the non-view derived classes. */ template< class ... PAIRS_OF_BUFFERS > void setEqualTo( INDEX_TYPE const srcNumArrays, INDEX_TYPE const srcMaxOffset, - NewChaiBuffer< INDEX_TYPE > const & srcOffsets, - NewChaiBuffer< INDEX_TYPE > const & srcSizes, - NewChaiBuffer< T > const & srcValues, - PAIRS_OF_BUFFERS & ... pairs ) + BUFFER_TYPE< INDEX_TYPE > const & srcOffsets, + BUFFER_TYPE< INDEX_TYPE > const & srcSizes, + BUFFER_TYPE< T > const & srcValues, + PAIRS_OF_BUFFERS && ... pairs ) { destroyValues( 0, m_numArrays, pairs.first ... ); @@ -715,8 +644,6 @@ class ArrayOfArraysView m_numArrays = srcNumArrays; - internal::PairOfBuffers< T > valuesPair( m_values, srcValues ); - forEachArg( [this] ( auto & pair ) { auto & dstBuffer = pair.first; @@ -728,14 +655,14 @@ class ArrayOfArraysView INDEX_TYPE const arraySize = sizeOfArray( i ); arrayManipulation::uninitializedCopy( &srcBuffer[ offset ], &srcBuffer[ offset ] + arraySize, &dstBuffer[ offset ] ); } - }, valuesPair, pairs ... ); + }, PairOfBuffers< T >( m_values, srcValues ), pairs ... ); } /** * @brief Compress the arrays so that the values of each array are contiguous with no extra capacity in between. - * @tparam BUFFERS variadic template where each type is a NewChaiBuffer. - * @param buffers variadic parameter pack where each argument is a NewChaiBuffer that should be treated - * similarly to m_values. + * @tparam BUFFERS variadic template where each type is a BUFFER_TYPE. + * @param buffers variadic parameter pack where each argument is a BUFFER_TYPE that should be treated + * similarly to m_values. * @note This is to be use by the non-view derived classes. * @note This method doesn't free any memory. */ @@ -777,9 +704,9 @@ class ArrayOfArraysView /** * @brief Reserve space for the given number of values. - * @tparam BUFFERS variadic template where each type is a NewChaiBuffer. + * @tparam BUFFERS variadic template where each type is a BUFFER_TYPE. * @param newValueCapacity the new minimum capacity for the number of values across all arrays. - * @param buffers variadic parameter pack where each argument is a NewChaiBuffer that should be treated + * @param buffers variadic parameter pack where each argument is a BUFFER_TYPE that should be treated * similarly to m_values. */ template< class ... BUFFERS > @@ -794,10 +721,10 @@ class ArrayOfArraysView /** * @brief Set the capacity of the given array. - * @tparam BUFFERS variadic template where each type is a NewChaiBuffer. + * @tparam BUFFERS variadic template where each type is a BUFFER_TYPE. * @param i the array to set the capacity of. * @param newCapacity the value to set the capacity of the given array to. - * @param buffers variadic parameter pack where each argument is a NewChaiBuffer that should be treated + * @param buffers variadic parameter pack where each argument is a BUFFER_TYPE that should be treated * similarly to m_values. * @note This is to be use by the non-view derived classes. */ @@ -867,7 +794,7 @@ class ArrayOfArraysView // We need to touch the offsets on the CPU because since it contains const data // when the ArrayOfArraysView gets copy constructed it doesn't get touched even though // it can then be modified via this method when called from a parent non-view class. - m_offsets.registerTouch( chai::CPU ); + m_offsets.registerTouch( MemorySpace::CPU ); } /** @@ -888,23 +815,23 @@ class ArrayOfArraysView /// Holds the offset of each array, of length m_numArrays + 1. Array i begins at /// m_offsets[i] and has capacity m_offsets[i+1] - m_offsets[i]. - NewChaiBuffer< INDEX_TYPE > m_offsets; + BUFFER_TYPE< INDEX_TYPE > m_offsets; /// Holds the size of each array. - NewChaiBuffer< SIZE_TYPE > m_sizes; + BUFFER_TYPE< SIZE_TYPE > m_sizes; /// Holds the values of each array. Values in the range [m_offsets[i], m_offsets[i] + m_sizes[i]) /// are valid. All other entries contain uninitialized values. - NewChaiBuffer< T > m_values; + BUFFER_TYPE< T > m_values; private: /** * @brief Destroy the values in arrays in the range [begin, end). - * @tparam BUFFERS variadic template where each type is a NewChaiBuffer. + * @tparam BUFFERS variadic template where each type is a BUFFER_TYPE. * @param begin the array to start with. * @param end where to stop destroying values. - * @param buffers variadic parameter pack where each argument is a NewChaiBuffer that should be treated + * @param buffers variadic parameter pack where each argument is a BUFFER_TYPE that should be treated * similarly to m_values. * @note This is to be use by the non-view derived classes. * @note This method doesn't free any memory. @@ -919,13 +846,13 @@ class ArrayOfArraysView // This moves sizes, offsets and values. BUFFERS ... buffers are moved inside the loop. if( !conjunction< std::is_trivially_destructible< T >::value, std::is_trivially_destructible< typename BUFFERS::value_type >::value ... > ) - { move( chai::CPU, true ); } + { move( MemorySpace::CPU, true ); } forEachArg( [this, begin, end] ( auto & buffer ) { if( !std::is_trivially_destructible< decltype( buffer[ 0 ] ) >::value ) { - buffer.move( chai::CPU, true ); + buffer.move( MemorySpace::CPU, true ); for( INDEX_TYPE i = begin; i < end; ++i ) { INDEX_TYPE const offset = m_offsets[ i ]; diff --git a/src/ArrayOfSets.hpp b/src/ArrayOfSets.hpp index 53885a5f..cdd9c733 100644 --- a/src/ArrayOfSets.hpp +++ b/src/ArrayOfSets.hpp @@ -28,7 +28,7 @@ namespace LvArray { // Forward declaration of the ArrayOfArrays class so that we can define the stealFrom method. -template< class T, typename INDEX_TYPE > +template< typename T, typename INDEX_TYPE, template< typename > class BUFFER_TYPE > class ArrayOfArrays; @@ -38,14 +38,18 @@ class ArrayOfArrays; * @tparam T the type stored in the sets. * @tparam INDEX_TYPE the integer to use for indexing. */ -template< class T, class INDEX_TYPE=std::ptrdiff_t > -class ArrayOfSets : protected ArrayOfSetsView< T, INDEX_TYPE > +template< typename T, + typename INDEX_TYPE, + template< typename > class BUFFER_TYPE > +class ArrayOfSets : protected ArrayOfSetsView< T, INDEX_TYPE, BUFFER_TYPE > { /// An alias for the parent class. - using ParentClass = ArrayOfSetsView< T, INDEX_TYPE >; + using ParentClass = ArrayOfSetsView< T, INDEX_TYPE, BUFFER_TYPE >; public: + /// An alias for the type contained in the sets. + using value_type = T; // Aliasing public methods of ArrayOfSetsView. using ParentClass::capacity; @@ -55,8 +59,6 @@ class ArrayOfSets : protected ArrayOfSetsView< T, INDEX_TYPE > using ParentClass::operator(); using ParentClass::operator[]; using ParentClass::getSetValues; - - using ParentClass::getIterableSet; using ParentClass::removeFromSet; using ParentClass::contains; using ParentClass::consistencyCheck; @@ -68,7 +70,7 @@ class ArrayOfSets : protected ArrayOfSetsView< T, INDEX_TYPE > */ inline ArrayOfSets( INDEX_TYPE const nsets=0, INDEX_TYPE defaultSetCapacity=0 ) LVARRAY_RESTRICT_THIS: - ArrayOfSetsView< T, INDEX_TYPE >() + ParentClass() { resize( nsets, defaultSetCapacity ); setName( "" ); @@ -80,7 +82,7 @@ class ArrayOfSets : protected ArrayOfSetsView< T, INDEX_TYPE > */ inline ArrayOfSets( ArrayOfSets const & src ) LVARRAY_RESTRICT_THIS: - ArrayOfSetsView< T, INDEX_TYPE >() + ParentClass() { *this = src; } /** @@ -130,15 +132,17 @@ class ArrayOfSets : protected ArrayOfSetsView< T, INDEX_TYPE > * @brief @return A reference to *this reinterpreted as an ArrayOfSetsView< T, INDEX_TYPE const >. */ inline - ArrayOfSetsView< T, INDEX_TYPE const > const & toView() const LVARRAY_RESTRICT_THIS - { return reinterpret_cast< ArrayOfSetsView< T, INDEX_TYPE const > const & >(*this); } + ArrayOfSetsView< T, INDEX_TYPE const, BUFFER_TYPE > const & + toView() const LVARRAY_RESTRICT_THIS + { return reinterpret_cast< ArrayOfSetsView< T, INDEX_TYPE const, BUFFER_TYPE > const & >(*this); } /** * @brief @return A reference to *this reinterpreted as an ArrayOfSetsView< T const, INDEX_TYPE const >. * @note Duplicated for SFINAE needs. */ LVARRAY_HOST_DEVICE constexpr inline - ArrayOfSetsView< T const, INDEX_TYPE const > const & toViewConst() const LVARRAY_RESTRICT_THIS + ArrayOfSetsView< T const, INDEX_TYPE const, BUFFER_TYPE > const & + toViewConst() const LVARRAY_RESTRICT_THIS { return ParentClass::toViewConst(); } /** @@ -146,7 +150,8 @@ class ArrayOfSets : protected ArrayOfSetsView< T, INDEX_TYPE > * @note Duplicated for SFINAE needs. */ LVARRAY_HOST_DEVICE constexpr inline - ArrayOfArraysView< T const, INDEX_TYPE const, true > const & toArrayOfArraysView() const LVARRAY_RESTRICT_THIS + ArrayOfArraysView< T const, INDEX_TYPE const, true, BUFFER_TYPE > const & + toArrayOfArraysView() const LVARRAY_RESTRICT_THIS { return ParentClass::toArrayOfArraysView(); } /** @@ -164,10 +169,11 @@ class ArrayOfSets : protected ArrayOfSetsView< T, INDEX_TYPE > * @note This would be prime for omp parallelism. */ inline - void stealFrom( ArrayOfArrays< T, INDEX_TYPE > && src, sortedArrayManipulation::Description const desc ) LVARRAY_RESTRICT_THIS + void stealFrom( ArrayOfArrays< T, INDEX_TYPE, BUFFER_TYPE > && src, + sortedArrayManipulation::Description const desc ) LVARRAY_RESTRICT_THIS { ParentClass::free(); - ParentClass::stealFrom( reinterpret_cast< ArrayOfArraysView< T, INDEX_TYPE > && >( src ) ); + ParentClass::stealFrom( reinterpret_cast< ArrayOfArraysView< T, INDEX_TYPE, false, BUFFER_TYPE > && >( src ) ); INDEX_TYPE const numSets = size(); if( desc == sortedArrayManipulation::UNSORTED_NO_DUPLICATES ) @@ -284,8 +290,8 @@ class ArrayOfSets : protected ArrayOfSetsView< T, INDEX_TYPE > void appendSet( INDEX_TYPE const setCapacity=0 ) LVARRAY_RESTRICT_THIS { INDEX_TYPE const maxOffset = m_offsets[ m_numArrays ]; - bufferManipulation::pushBack( m_offsets, m_numArrays + 1, maxOffset ); - bufferManipulation::pushBack( m_sizes, m_numArrays, 0 ); + bufferManipulation::emplaceBack( m_offsets, m_numArrays + 1, maxOffset ); + bufferManipulation::emplaceBack( m_sizes, m_numArrays, 0 ); ++m_numArrays; setCapacityOfSet( m_numArrays - 1, setCapacity ); @@ -304,8 +310,8 @@ class ArrayOfSets : protected ArrayOfSetsView< T, INDEX_TYPE > // Insert an set of capacity zero at the given location INDEX_TYPE const offset = m_offsets[i]; - bufferManipulation::insert( m_offsets, m_numArrays + 1, i + 1, offset ); - bufferManipulation::insert( m_sizes, m_numArrays, i, 0 ); + bufferManipulation::emplace( m_offsets, m_numArrays + 1, i + 1, offset ); + bufferManipulation::emplace( m_sizes, m_numArrays, i, 0 ); ++m_numArrays; // Set the capacity of the new set @@ -356,7 +362,7 @@ class ArrayOfSets : protected ArrayOfSetsView< T, INDEX_TYPE > * @param name the name to display. */ void setName( std::string const & name ) - { ArrayOfArraysView< T, INDEX_TYPE >::template setName< decltype( *this ) >( name ); } + { ParentClass::template setName< decltype( *this ) >( name ); } /** * @brief Move this ArrayOfSetsView to the given memory space and touch the values, sizes and offsets. @@ -365,7 +371,7 @@ class ArrayOfSets : protected ArrayOfSetsView< T, INDEX_TYPE > * @note When moving to the GPU since the offsets can't be modified on device they are not touched. * @note Duplicated for SFINAE needs. */ - void move( chai::ExecutionSpace const space, bool const touch=true ) const + void move( MemorySpace const space, bool const touch=true ) const { return ParentClass::move( space, touch ); } private: @@ -380,12 +386,12 @@ class ArrayOfSets : protected ArrayOfSetsView< T, INDEX_TYPE > /** * @brief Constructor. - * @param aos the ArrayOfSets this CallBacks is associated with. - * @param i the set this CallBacks is associated with. + * @param aos The ArrayOfSets this CallBacks is associated with. + * @param i The set this CallBacks is associated with. */ inline - CallBacks( ArrayOfSets< T, INDEX_TYPE > & sp, INDEX_TYPE const i ): - m_aos( sp ), + CallBacks( ArrayOfSets & aos, INDEX_TYPE const i ): + m_aos( aos ), m_i( i ) {} @@ -398,9 +404,9 @@ class ArrayOfSets : protected ArrayOfSetsView< T, INDEX_TYPE > * @return a pointer to the sets values. */ inline - T * incrementSize( T * const LVARRAY_UNUSED_ARG( curPtr ), - INDEX_TYPE const nToAdd ) const LVARRAY_RESTRICT_THIS + T * incrementSize( T * const curPtr, INDEX_TYPE const nToAdd ) const LVARRAY_RESTRICT_THIS { + LVARRAY_UNUSED_VARIABLE( curPtr ); INDEX_TYPE const newNNZ = m_aos.sizeOfSet( m_i ) + nToAdd; if( newNNZ > m_aos.capacityOfSet( m_i ) ) { @@ -412,7 +418,7 @@ class ArrayOfSets : protected ArrayOfSetsView< T, INDEX_TYPE > private: /// A reference to the associated ArrayOfSets. - ArrayOfSets< T, INDEX_TYPE > & m_aos; + ArrayOfSets & m_aos; /// The index of the associated set. INDEX_TYPE const m_i; diff --git a/src/ArrayOfSetsView.hpp b/src/ArrayOfSetsView.hpp index ffa0411a..8af828cb 100644 --- a/src/ArrayOfSetsView.hpp +++ b/src/ArrayOfSetsView.hpp @@ -20,10 +20,9 @@ * @file ArrayOfSetsView.hpp */ -#ifndef ARRAYOFSETSVIEW_HPP_ -#define ARRAYOFSETSVIEW_HPP_ +#pragma once -#include +// Source includes #include "ArrayOfArraysView.hpp" #include "arrayManipulation.hpp" #include "sortedArrayManipulation.hpp" @@ -45,11 +44,13 @@ namespace LvArray * When T is const and INDEX_TYPE is const you cannot insert or remove from the View * and neither the offsets, sizes, or values are touched when copied between memory spaces. */ -template< typename T, typename INDEX_TYPE=std::ptrdiff_t > -class ArrayOfSetsView : protected ArrayOfArraysView< T, INDEX_TYPE, std::is_const< T >::value > +template< typename T, + typename INDEX_TYPE, + template< typename > class BUFFER_TYPE > +class ArrayOfSetsView : protected ArrayOfArraysView< T, INDEX_TYPE, std::is_const< T >::value, BUFFER_TYPE > { - // Alias for the parent class - using ParentClass = ArrayOfArraysView< T, INDEX_TYPE, std::is_const< T >::value >; + /// Alias for the parent class + using ParentClass = ArrayOfArraysView< T, INDEX_TYPE, std::is_const< T >::value, BUFFER_TYPE >; public: @@ -91,31 +92,26 @@ class ArrayOfSetsView : protected ArrayOfArraysView< T, INDEX_TYPE, std::is_cons * @brief This is included for SFINAE needs. */ LVARRAY_HOST_DEVICE constexpr inline - ArrayOfSetsView< T, INDEX_TYPE > const & toView() const LVARRAY_RESTRICT_THIS + ArrayOfSetsView< T, INDEX_TYPE, BUFFER_TYPE > const & + toView() const LVARRAY_RESTRICT_THIS { return *this; } /** * @brief @return Return a reference to *this reinterpreted as an ArrayOfSetsView< T const, INDEX_TYPE const >. */ LVARRAY_HOST_DEVICE constexpr inline - ArrayOfSetsView< T const, INDEX_TYPE const > const & toViewConst() const LVARRAY_RESTRICT_THIS - { return reinterpret_cast< ArrayOfSetsView< T const, INDEX_TYPE const > const & >(*this); } + ArrayOfSetsView< T const, INDEX_TYPE const, BUFFER_TYPE > const & + toViewConst() const LVARRAY_RESTRICT_THIS + { return reinterpret_cast< ArrayOfSetsView< T const, INDEX_TYPE const, BUFFER_TYPE > const & >(*this); } /** * @brief @return Return a reference to *this reinterpreted as an ArrayOfArraysView< T const, INDEX_TYPE const, true *>. */ LVARRAY_HOST_DEVICE constexpr inline - ArrayOfArraysView< T const, INDEX_TYPE const, true > const & toArrayOfArraysView() const LVARRAY_RESTRICT_THIS - { return reinterpret_cast< ArrayOfArraysView< T const, INDEX_TYPE const, true > const & >( *this ); } - - /** - * @brief @return Return an object provides an iterable interface to the given set. - * @param i The set to get an iterator for. - */ - LVARRAY_HOST_DEVICE constexpr inline - typename ParentClass::IterableArray getIterableSet( INDEX_TYPE const i ) const LVARRAY_RESTRICT_THIS - { return ParentClass::getIterableArray( i ); } + ArrayOfArraysView< T const, INDEX_TYPE const, true, BUFFER_TYPE > const & + toArrayOfArraysView() const LVARRAY_RESTRICT_THIS + { return reinterpret_cast< ArrayOfArraysView< T const, INDEX_TYPE const, true, BUFFER_TYPE > const & >( *this ); } /** * @brief @return Return the size of the given set. @@ -247,7 +243,7 @@ class ArrayOfSetsView : protected ArrayOfArraysView< T, INDEX_TYPE, std::is_cons * @param touch If true touch the values, sizes and offsets in the new space. * @note When moving to the GPU since the offsets can't be modified on device they are not touched. */ - void move( chai::ExecutionSpace const space, bool const touch=true ) const + void move( MemorySpace const space, bool const touch=true ) const { return ParentClass::move( space, touch ); } protected: @@ -398,7 +394,7 @@ class ArrayOfSetsView : protected ArrayOfArraysView< T, INDEX_TYPE, std::is_cons * @param i the set this CallBacks is associated with. */ LVARRAY_HOST_DEVICE inline - CallBacks( ArrayOfSetsView< T, INDEX_TYPE > const & aos, INDEX_TYPE const i ): + CallBacks( ArrayOfSetsView const & aos, INDEX_TYPE const i ): m_aos( aos ), m_indexOfSet( i ) {} @@ -412,9 +408,9 @@ class ArrayOfSetsView : protected ArrayOfArraysView< T, INDEX_TYPE, std::is_cons * @return a pointer to the sets values. */ LVARRAY_HOST_DEVICE inline - T * incrementSize( T * const LVARRAY_UNUSED_ARG( curPtr ), - INDEX_TYPE const nToAdd ) const LVARRAY_RESTRICT_THIS + T * incrementSize( T * const curPtr, INDEX_TYPE const nToAdd ) const LVARRAY_RESTRICT_THIS { + LVARRAY_UNUSED_VARIABLE( curPtr ); #ifdef USE_ARRAY_BOUNDS_CHECK LVARRAY_ERROR_IF_GT_MSG( m_aos.sizeOfSet( m_indexOfSet ) + nToAdd, m_aos.capacityOfSet( m_indexOfSet ), "ArrayOfSetsView cannot do reallocation." ); @@ -425,11 +421,12 @@ class ArrayOfSetsView : protected ArrayOfArraysView< T, INDEX_TYPE, std::is_cons } private: - ArrayOfSetsView< T, INDEX_TYPE > const & m_aos; + /// The ArrayOfSetsView the call back is associated with. + ArrayOfSetsView const & m_aos; + + /// The index of the set the call back is associated with. INDEX_TYPE const m_indexOfSet; }; }; -} /* namespace LvArray */ - -#endif /* ARRAYOFSETSVIEW_HPP_ */ +} // namespace LvArray diff --git a/src/ArraySlice.hpp b/src/ArraySlice.hpp index 3faa24ea..d492983f 100644 --- a/src/ArraySlice.hpp +++ b/src/ArraySlice.hpp @@ -53,11 +53,6 @@ DEFINE_GDB_PY_SCRIPT( "scripts/gdb-printers.py" ); #include "Macros.hpp" // System includes -#include -#include -#include -#include - #ifndef NDEBUG #include "totalview/tv_data_display.h" #include "totalview/tv_helpers.hpp" @@ -106,7 +101,7 @@ namespace LvArray * In general, instantiations of ArraySlice should only result either taking a slice of an an Array or * an ArrayView via operator[] or from a direct creation via the toSlice/toSliceConst method. */ -template< typename T, int NDIM, int USD=NDIM-1, typename INDEX_TYPE=std::ptrdiff_t > +template< typename T, int NDIM, int USD, typename INDEX_TYPE > class ArraySlice { public: @@ -264,10 +259,12 @@ class ArraySlice std::enable_if_t< ( _USD >= 0), bool > isContiguous() const { + if( NDIM == 1 && USD == 0 ) return true; + bool rval = true; for( int i = 0; i < NDIM; ++i ) { - if( i == _USD ) continue; + if( i == USD ) continue; INDEX_TYPE prod = 1; for( int j = 0; j < NDIM; ++j ) { @@ -301,6 +298,14 @@ class ArraySlice return m_data; } + LVARRAY_HOST_DEVICE inline constexpr + T * begin() const + { return dataIfContiguous(); } + + LVARRAY_HOST_DEVICE inline constexpr + T * end() const + { return dataIfContiguous() + size(); } + #if defined(USE_TOTALVIEW_OUTPUT) && !defined(__CUDA_ARCH__) && defined(USE_ARRAY_BOUNDS_CHECK) /** * @brief Static function that will be used by Totalview to display the array contents. diff --git a/src/ArrayView.hpp b/src/ArrayView.hpp index 0ebe23e0..87d3a82d 100644 --- a/src/ArrayView.hpp +++ b/src/ArrayView.hpp @@ -30,6 +30,7 @@ #include "arrayHelpers.hpp" #include "IntegerConversion.hpp" #include "sliceHelpers.hpp" +#include "bufferManipulation.hpp" /// System includes #if defined(USE_TOTALVIEW_OUTPUT) && !defined(__CUDA_ARCH__) @@ -72,9 +73,9 @@ namespace LvArray */ template< typename T, int NDIM, - int USD=NDIM-1, - typename INDEX_TYPE=std::ptrdiff_t, - template< typename > class BUFFER_TYPE=NewChaiBuffer > + int USD, + typename INDEX_TYPE, + template< typename > class BUFFER_TYPE > class ArrayView { public: @@ -92,6 +93,12 @@ class ArrayView /// const. using ViewTypeConst = ArrayView< typename GetViewTypeConst< T >::type const, NDIM, USD, INDEX_TYPE, BUFFER_TYPE > const; + /// The type of the ArrayView when converted to an ArraySlice. + using SliceType = ArraySlice< T, NDIM, USD, INDEX_TYPE > const; + + /// The type of the ArrayView when converted to an immutable ArraySlice. + using SliceTypeConst = ArraySlice< T const, NDIM, USD, INDEX_TYPE > const; + /// The type of the value in the ArraySlice. using value_type = T; @@ -101,12 +108,6 @@ class ArrayView /// The type of the const iterator used. using const_iterator = T const *; - /// The pointer type. - using pointer = T *; - - /// The const_pointer type. - using const_pointer = T const *; - /** * @brief A constructor to create an uninitialized ArrayView. * @note An uninitialized ArrayView should not be used until it is assigned to. @@ -116,11 +117,11 @@ class ArrayView /** * @brief Copy Constructor. * @param source The object to copy. - * @note The copy constructor will trigger the copy constructor for @tparam BUFFER_TYPE. When using - * the NewChaiBuffer this can move the underlying buffer to a new memory space if the execution context - * is set. + * @note The copy constructor will trigger the copy constructor for @tparam BUFFER_TYPE. When using the + * NewChaiBuffer this can move the underlying buffer to a new memory space if the execution context is set. * @return *this */ + DISABLE_HD_WARNING inline LVARRAY_HOST_DEVICE constexpr ArrayView( ArrayView const & source ) noexcept: m_dims{ 0 }, @@ -137,8 +138,20 @@ class ArrayView /** * @brief Move constructor, creates a shallow copy and invalidates the source. - * @param source object to move - * @return *this + * @param source object to move. + * @return *this. + * @note Since this invalidates the source this should not be used when @p source is + * the parent of an Array. Do not do this: + * @code + * Array< int, RAJA::PERM_I, std::ptrdiff_t, MallocBuffer > array( 10 ); + * ArrayView< int, 1, 0, std::ptrdiff_t, MallocBuffer > view = std::move( array.toView() ); + * @endcode + * However this is ok: + * @code + * Array< int, RAJA::PERM_I, std::ptrdiff_t, MallocBuffer > array( 10 ); + * ArrayView< int, 1, 0, std::ptrdiff_t, MallocBuffer > view = array.toView(); + * ArrayView< int, 1, 0, std::ptrdiff_t, MallocBuffer > anotherView = std::move( view ); + * @endcode */ inline LVARRAY_HOST_DEVICE constexpr ArrayView( ArrayView && source ): @@ -158,33 +171,50 @@ class ArrayView } /** - * @brief Copy assignment operator, creates a shallow copy. - * @param rhs object to copy. - * @return *this + * @brief Move assignment operator, creates a shallow copy and invalidates the source. + * @param rhs The object to copy. + * @return *this. + * @note Since this invalidates the source this should not be used when @p rhs is + * the parent of an Array. Do not do this: + * @code + * Array< int, RAJA::PERM_I, std::ptrdiff_t, MallocBuffer > array( 10 ); + * ArrayView< int, 1, 0, std::ptrdiff_t, MallocBuffer > view; + * view = std::move( array.toView() ); + * @endcode + * However this is ok: + * @code + * Array< int, RAJA::PERM_I, std::ptrdiff_t, MallocBuffer > array( 10 ); + * ArrayView< int, 1, 0, std::ptrdiff_t, MallocBuffer > view = array.toView(); + * ArrayView< int, 1, 0, std::ptrdiff_t, MallocBuffer > anotherView; + * anotherView = std::move( view ); + * @endcode */ - inline constexpr - ArrayView & operator=( ArrayView const & rhs ) noexcept + inline LVARRAY_HOST_DEVICE constexpr + ArrayView & operator=( ArrayView && rhs ) { - m_dataBuffer = rhs.m_dataBuffer; + m_dataBuffer = std::move( rhs.m_dataBuffer ); m_singleParameterResizeIndex = rhs.m_singleParameterResizeIndex; for( int i = 0; i < NDIM; ++i ) { m_dims[ i ] = rhs.m_dims[ i ]; m_strides[ i ] = rhs.m_strides[ i ]; + + rhs.m_dims[ i ] = 0; + rhs.m_strides[ i ] = 0; } return *this; } /** - * @brief Move assignment operator, creates a shallow copy and invalidates the source. - * @param rhs The object to copy. + * @brief Copy assignment operator, creates a shallow copy. + * @param rhs object to copy. * @return *this */ - inline LVARRAY_HOST_DEVICE constexpr - ArrayView & operator=( ArrayView && rhs ) + inline constexpr + ArrayView & operator=( ArrayView const & rhs ) noexcept { - m_dataBuffer = std::move( rhs.m_dataBuffer ); + m_dataBuffer = rhs.m_dataBuffer; m_singleParameterResizeIndex = rhs.m_singleParameterResizeIndex; for( int i = 0; i < NDIM; ++i ) { @@ -201,10 +231,8 @@ class ArrayView * @return *this. */ DISABLE_HD_WARNING - template< typename U = T > inline LVARRAY_HOST_DEVICE constexpr - std::enable_if_t< !(std::is_const< U >::value), ArrayView const & > - operator=( T const & rhs ) const noexcept + ArrayView const & operator=( T const & rhs ) const noexcept { INDEX_TYPE const length = size(); T * const data_ptr = data(); @@ -271,16 +299,6 @@ class ArrayView () const noexcept { return toSliceConst(); } - /** - * @brief @return A a raw pointer. - * @note This method is only active when NDIM == 1 and USD == 0. - */ - template< int _NDIM=NDIM, int _USD=USD > - LVARRAY_HOST_DEVICE constexpr inline - operator std::enable_if_t< _NDIM == 1 && _USD == 0, T * const LVARRAY_RESTRICT > - () const noexcept LVARRAY_RESTRICT_THIS - { return data(); } - /** * @brief @return Return the allocated size. */ @@ -312,14 +330,14 @@ class ArrayView * @brief @return Return an iterator to the begining of the data. */ LVARRAY_HOST_DEVICE inline constexpr - iterator begin() const + T * begin() const { return data(); } /** * @brief @return Return an iterator to the end of the data. */ LVARRAY_HOST_DEVICE inline constexpr - iterator end() const + T * end() const { return data() + size(); } /** @@ -388,7 +406,7 @@ class ArrayView */ template< typename ... INDICES > LVARRAY_HOST_DEVICE inline CONSTEXPR_WITHOUT_BOUNDS_CHECK - INDEX_TYPE linearIndex( INDICES... indices ) const + INDEX_TYPE linearIndex( INDICES const ... indices ) const { static_assert( sizeof ... (INDICES) == NDIM, "number of indices does not match NDIM" ); #ifdef USE_ARRAY_BOUNDS_CHECK @@ -408,43 +426,6 @@ class ArrayView T * data() const { return m_dataBuffer.data(); } - /** - * @brief Copy the values from one slice in this array to another. - * @param destIndex The index of the slice to copy data into. - * @param sourceIndex The index of the slice to copy data from. - */ - void copy( INDEX_TYPE const destIndex, INDEX_TYPE const sourceIndex ) - { - forValuesInSliceWithIndices( (*this)[ sourceIndex ], - [destIndex, this]( T const & sourceVal, auto const ... indices ) - { - (*this)( destIndex, indices ... ) = sourceVal; - } ); - } - - /** - * @brief function to copy values of another array to a location in this array - * @param destIndex the index where the source data is to be inserted - * @param source the source of the data - * - * This function will copy the data from source, to a location in *this. It is intended to allow - * for collection of multiple data arrays into a single array. All dims should be the same except - * for m_singleParameterResizeIndex; - */ - void copy( INDEX_TYPE const destIndex, ViewTypeConst const & source ) - { - INDEX_TYPE offset = destIndex * m_strides[m_singleParameterResizeIndex]; - - LVARRAY_ERROR_IF( source.size() > this->size() - offset, - "Insufficient storage space to copy source (size="<size() - offset = "<size() - offset ); - for( INDEX_TYPE i=0; i +template< typename COL_TYPE, typename INDEX_TYPE, template< typename > class BUFFER_TYPE > class SparsityPattern; /** @@ -39,15 +39,21 @@ class SparsityPattern; * @class CRSMatrix * @brief This class implements a compressed row storage matrix. */ -template< typename T, typename COL_TYPE=int, typename INDEX_TYPE=std::ptrdiff_t > -class CRSMatrix : protected CRSMatrixView< T, COL_TYPE, INDEX_TYPE > +template< typename T, + typename COL_TYPE, + typename INDEX_TYPE, + template< typename > class BUFFER_TYPE > +class CRSMatrix : protected CRSMatrixView< T, COL_TYPE, INDEX_TYPE, BUFFER_TYPE > { /// An alias for the parent class. - using ParentClass = CRSMatrixView< T, COL_TYPE, INDEX_TYPE >; + using ParentClass = CRSMatrixView< T, COL_TYPE, INDEX_TYPE, BUFFER_TYPE >; public: + /// An alias for the type of the entries in the matrix. + using value_type = T; + // Aliasing public methods of CRSMatrixView. using ParentClass::numRows; using ParentClass::numColumns; @@ -110,13 +116,12 @@ class CRSMatrix : protected CRSMatrixView< T, COL_TYPE, INDEX_TYPE > CRSMatrix & operator=( CRSMatrix const & src ) LVARRAY_RESTRICT_THIS { m_numCols = src.m_numCols; - internal::PairOfBuffers< T > entriesPair( m_entries, src.m_entries ); ParentClass::setEqualTo( src.m_numArrays, src.m_offsets[ src.m_numArrays ], src.m_offsets, src.m_sizes, src.m_values, - entriesPair ); + typename ParentClass::template PairOfBuffers< T >( m_entries, src.m_entries ) ); return *this; } @@ -138,7 +143,7 @@ class CRSMatrix : protected CRSMatrixView< T, COL_TYPE, INDEX_TYPE > * @param src the SparsityPattern to convert. */ inline - void stealFrom( SparsityPattern< COL_TYPE, INDEX_TYPE > && src ) + void stealFrom( SparsityPattern< COL_TYPE, INDEX_TYPE, BUFFER_TYPE > && src ) { // Destroy the current entries. for( INDEX_TYPE row = 0; row < numRows(); ++row ) @@ -151,7 +156,7 @@ class CRSMatrix : protected CRSMatrixView< T, COL_TYPE, INDEX_TYPE > // Reallocate to the appropriate length bufferManipulation::reserve( m_entries, 0, src.nonZeroCapacity() ); - ParentClass::stealFrom( reinterpret_cast< SparsityPatternView< COL_TYPE, INDEX_TYPE > && >( src ) ); + ParentClass::stealFrom( reinterpret_cast< SparsityPatternView< COL_TYPE, INDEX_TYPE, BUFFER_TYPE > && >( src ) ); for( INDEX_TYPE row = 0; row < numRows(); ++row ) { @@ -169,15 +174,17 @@ class CRSMatrix : protected CRSMatrixView< T, COL_TYPE, INDEX_TYPE > * @brief @return A reference to *this reinterpreted as a CRSMatrixView< T, COL_TYPE, INDEX_TYPE const >. */ constexpr inline - CRSMatrixView< T, COL_TYPE, INDEX_TYPE const > const & toView() const LVARRAY_RESTRICT_THIS - { return reinterpret_cast< CRSMatrixView< T, COL_TYPE, INDEX_TYPE const > const & >( *this ); } + CRSMatrixView< T, COL_TYPE, INDEX_TYPE const, BUFFER_TYPE > const & + toView() const LVARRAY_RESTRICT_THIS + { return reinterpret_cast< CRSMatrixView< T, COL_TYPE, INDEX_TYPE const, BUFFER_TYPE > const & >( *this ); } /** * @brief @return A reference to *this reinterpreted as a CRSMatrixView< T, COL_TYPE const, INDEX_TYPE const >. * @note Duplicated for SFINAE needs. */ LVARRAY_HOST_DEVICE constexpr inline - CRSMatrixView< T, COL_TYPE const, INDEX_TYPE const > const & toViewConstSizes() const LVARRAY_RESTRICT_THIS + CRSMatrixView< T, COL_TYPE const, INDEX_TYPE const, BUFFER_TYPE > const & + toViewConstSizes() const LVARRAY_RESTRICT_THIS { return ParentClass::toViewConstSizes(); } /** @@ -185,7 +192,8 @@ class CRSMatrix : protected CRSMatrixView< T, COL_TYPE, INDEX_TYPE > * @note Duplicated for SFINAE needs. */ LVARRAY_HOST_DEVICE constexpr inline - CRSMatrixView< T const, COL_TYPE const, INDEX_TYPE const > const & toViewConst() const LVARRAY_RESTRICT_THIS + CRSMatrixView< T const, COL_TYPE const, INDEX_TYPE const, BUFFER_TYPE > const & + toViewConst() const LVARRAY_RESTRICT_THIS { return ParentClass::toViewConst(); } /** @@ -193,7 +201,8 @@ class CRSMatrix : protected CRSMatrixView< T, COL_TYPE, INDEX_TYPE > * @note Duplicated for SFINAE needs. */ LVARRAY_HOST_DEVICE constexpr inline - SparsityPatternView< COL_TYPE const, INDEX_TYPE const > const & toSparsityPatternView() const + SparsityPatternView< COL_TYPE const, INDEX_TYPE const, BUFFER_TYPE > const & + toSparsityPatternView() const { return ParentClass::toSparsityPatternView(); } /** @@ -202,9 +211,7 @@ class CRSMatrix : protected CRSMatrixView< T, COL_TYPE, INDEX_TYPE > */ inline void reserveNonZeros( INDEX_TYPE const nnz ) LVARRAY_RESTRICT_THIS - { - SparsityPatternView< COL_TYPE, INDEX_TYPE >::reserveValues( nnz, m_entries ); - } + { ParentClass::reserveValues( nnz, m_entries ); } /** * @brief Reserve space to hold at least the given number of non zero entries in the given row. @@ -300,7 +307,7 @@ class CRSMatrix : protected CRSMatrixView< T, COL_TYPE, INDEX_TYPE > * @note When moving to the GPU since the offsets can't be modified on device they are not touched. * @note Duplicated for SFINAE needs. */ - void move( chai::ExecutionSpace const space, bool const touch=true ) const + void move( MemorySpace const space, bool const touch=true ) const { ParentClass::move( space, touch ); } private: @@ -329,7 +336,7 @@ class CRSMatrix : protected CRSMatrixView< T, COL_TYPE, INDEX_TYPE > * @param row the row this CallBacks is associated with. * @param entriesToInsert pointer to the entries to insert. */ - CallBacks( CRSMatrix< T, COL_TYPE, INDEX_TYPE > & crsM, + CallBacks( CRSMatrix & crsM, INDEX_TYPE const row, T const * const entriesToInsert ): m_crsM( crsM ), m_row( row ), @@ -345,12 +352,12 @@ class CRSMatrix : protected CRSMatrixView< T, COL_TYPE, INDEX_TYPE > * @param nToAdd the increase in the size. * @return a pointer to the rows columns. * @note This method doesn't actually change the size, but it does potentially - * do an allocation. + * do an allocation. */ inline - COL_TYPE * incrementSize( COL_TYPE * const LVARRAY_UNUSED_ARG( curPtr ), - INDEX_TYPE const nToAdd ) + COL_TYPE * incrementSize( COL_TYPE * const curPtr, INDEX_TYPE const nToAdd ) { + LVARRAY_UNUSED_VARIABLE( curPtr ); if( m_rowNNZ + nToAdd > m_rowCapacity ) { m_crsM.dynamicallyGrowRow( m_row, m_rowNNZ + nToAdd ); @@ -368,7 +375,7 @@ class CRSMatrix : protected CRSMatrixView< T, COL_TYPE, INDEX_TYPE > */ inline void insert( INDEX_TYPE const pos ) const - { arrayManipulation::insert( m_entries, m_rowNNZ, pos, m_entriesToInsert[0] ); } + { arrayManipulation::emplace( m_entries, m_rowNNZ, pos, m_entriesToInsert[0] ); } /** * @brief Used with the sortedArrayManipulation::insertSorted routine this callback @@ -403,11 +410,22 @@ class CRSMatrix : protected CRSMatrixView< T, COL_TYPE, INDEX_TYPE > } private: - CRSMatrix< T, COL_TYPE, INDEX_TYPE > & m_crsM; + /// The CRSMatrix the call back is associated with. + CRSMatrix & m_crsM; + + /// The row the call back is assocated with. INDEX_TYPE const m_row; + + /// The number of non zeros in the row. INDEX_TYPE const m_rowNNZ; + + /// The non zero capacity of the row. INDEX_TYPE const m_rowCapacity; + + /// A pointer to the entries of the row. T * m_entries; + + /// A pointer to the entries to insert. T const * const m_entriesToInsert; }; diff --git a/src/CRSMatrixView.hpp b/src/CRSMatrixView.hpp index b7d17a49..a2864c90 100644 --- a/src/CRSMatrixView.hpp +++ b/src/CRSMatrixView.hpp @@ -62,12 +62,16 @@ void atomicAdd( RAJA::seq_atomic, T * acc, T const & val ) * @note When T, COL_TYPE and INDEX_TYPE are const you cannot modify the matrix in any way * and nothing is copied back from the device. */ -template< class T, class COL_TYPE=unsigned int, class INDEX_TYPE=std::ptrdiff_t > -class CRSMatrixView : protected SparsityPatternView< COL_TYPE, INDEX_TYPE > +template< typename T, + typename COL_TYPE, + typename INDEX_TYPE, + template< typename > class BUFFER_TYPE + > +class CRSMatrixView : protected SparsityPatternView< COL_TYPE, INDEX_TYPE, BUFFER_TYPE > { /// An alias for the parent class. - using ParentClass = SparsityPatternView< COL_TYPE, INDEX_TYPE >; + using ParentClass = SparsityPatternView< COL_TYPE, INDEX_TYPE, BUFFER_TYPE >; public: static_assert( !std::is_const< T >::value || @@ -110,29 +114,32 @@ class CRSMatrixView : protected SparsityPatternView< COL_TYPE, INDEX_TYPE > * @brief This is included for SFINAE needs. */ LVARRAY_HOST_DEVICE constexpr inline - CRSMatrixView< T, COL_TYPE, INDEX_TYPE > const & toView() const LVARRAY_RESTRICT_THIS + CRSMatrixView< T, COL_TYPE, INDEX_TYPE, BUFFER_TYPE > const & toView() const LVARRAY_RESTRICT_THIS { return *this; } /** * @brief @return A reference to *this reinterpreted as a CRSMatrixView< T, COL_TYPE const, INDEX_TYPE const >. */ LVARRAY_HOST_DEVICE constexpr inline - CRSMatrixView< T, COL_TYPE const, INDEX_TYPE const > const & toViewConstSizes() const LVARRAY_RESTRICT_THIS - { return reinterpret_cast< CRSMatrixView< T, COL_TYPE const, INDEX_TYPE const > const & >( *this ); } + CRSMatrixView< T, COL_TYPE const, INDEX_TYPE const, BUFFER_TYPE > const & + toViewConstSizes() const LVARRAY_RESTRICT_THIS + { return reinterpret_cast< CRSMatrixView< T, COL_TYPE const, INDEX_TYPE const, BUFFER_TYPE > const & >( *this ); } /** * @brief @return A reference to *this reinterpreted as a CRSMatrixView< T const, COL_TYPE const, INDEX_TYPE const >. */ LVARRAY_HOST_DEVICE constexpr inline - CRSMatrixView< T const, COL_TYPE const, INDEX_TYPE const > const & toViewConst() const LVARRAY_RESTRICT_THIS - { return reinterpret_cast< CRSMatrixView< T const, COL_TYPE const, INDEX_TYPE const > const & >(*this); } + CRSMatrixView< T const, COL_TYPE const, INDEX_TYPE const, BUFFER_TYPE > const & + toViewConst() const LVARRAY_RESTRICT_THIS + { return reinterpret_cast< CRSMatrixView< T const, COL_TYPE const, INDEX_TYPE const, BUFFER_TYPE > const & >(*this); } /** * @brief @return A reference to *this reinterpreted as a SparsityPatternView< COL_TYPE const, INDEX_TYPE const >. */ LVARRAY_HOST_DEVICE constexpr inline - SparsityPatternView< COL_TYPE const, INDEX_TYPE const > const & toSparsityPatternView() const - { return reinterpret_cast< SparsityPatternView< COL_TYPE const, INDEX_TYPE const > const & >(*this); } + SparsityPatternView< COL_TYPE const, INDEX_TYPE const, BUFFER_TYPE > const & + toSparsityPatternView() const + { return reinterpret_cast< SparsityPatternView< COL_TYPE const, INDEX_TYPE const, BUFFER_TYPE > const & >(*this); } /** * @brief @return Return an ArraySlice1d to the matrix entries of the given row. @@ -381,7 +388,7 @@ class CRSMatrixView : protected SparsityPatternView< COL_TYPE, INDEX_TYPE > * @param touch If true touch the values, sizes and offsets in the new space. * @note When moving to the GPU since the offsets can't be modified on device they are not touched. */ - void move( chai::ExecutionSpace const space, bool const touch=true ) const + void move( MemorySpace const space, bool const touch=true ) const { ParentClass::move( space, touch ); m_entries.move( space, touch ); @@ -418,7 +425,7 @@ class CRSMatrixView : protected SparsityPatternView< COL_TYPE, INDEX_TYPE > using ParentClass::m_values; /// Holds the entries of the matrix, of length numNonZeros(). - NewChaiBuffer< T > m_entries; + BUFFER_TYPE< T > m_entries; private: @@ -437,7 +444,7 @@ class CRSMatrixView : protected SparsityPatternView< COL_TYPE, INDEX_TYPE > * @param entriesToInsert pointer to the entries to insert. */ LVARRAY_HOST_DEVICE inline - CallBacks( CRSMatrixView< T, COL_TYPE, INDEX_TYPE > const & crsMV, + CallBacks( CRSMatrixView const & crsMV, INDEX_TYPE const row, T const * const entriesToInsert ): m_crsMV( crsMV ), m_row( row ), @@ -452,13 +459,13 @@ class CRSMatrixView : protected SparsityPatternView< COL_TYPE, INDEX_TYPE > * @param curPtr the current pointer to the array. * @param nToAdd the increase in the size. * @note This method doesn't actually change the size, it just checks that the new - * size doesn't exceed the capacity since the CRSMatrixView can't do allocation. + * size doesn't exceed the capacity since the CRSMatrixView can't do allocation. * @return a pointer to the rows columns. */ LVARRAY_HOST_DEVICE inline - COL_TYPE * incrementSize( COL_TYPE * const LVARRAY_UNUSED_ARG( curPtr ), - INDEX_TYPE const nToAdd ) const + COL_TYPE * incrementSize( COL_TYPE * const curPtr, INDEX_TYPE const nToAdd ) const { + LVARRAY_UNUSED_VARIABLE( curPtr ); #ifdef USE_ARRAY_BOUNDS_CHECK LVARRAY_ERROR_IF_GT_MSG( m_rowNNZ + nToAdd, m_rowCapacity, "CRSMatrixView cannot do reallocation." ); #else @@ -475,7 +482,7 @@ class CRSMatrixView : protected SparsityPatternView< COL_TYPE, INDEX_TYPE > */ LVARRAY_HOST_DEVICE inline void insert( INDEX_TYPE const insertPos ) const - { arrayManipulation::insert( m_entries, m_rowNNZ, insertPos, m_entriesToInsert[0] ); } + { arrayManipulation::emplace( m_entries, m_rowNNZ, insertPos, m_entriesToInsert[0] ); } /** * @brief Used with the sortedArrayManipulation::insertSorted routine this callback @@ -487,18 +494,16 @@ class CRSMatrixView : protected SparsityPatternView< COL_TYPE, INDEX_TYPE > DISABLE_HD_WARNING LVARRAY_HOST_DEVICE inline void set( INDEX_TYPE const pos, INDEX_TYPE const colPos ) const - { new (&m_entries[pos]) T( m_entriesToInsert[colPos] ); } + { new (&m_entries[ pos ]) T( m_entriesToInsert[ colPos ] ); } /** - * @brief Used with the sortedArrayManipulation::insertSorted routine this callback - * signals that the given column was inserted at the given position. Further information - * is provided in order to make the insertion efficient. This means that we need to perform - * the same operation on the entries. + * @brief Used with the sortedArrayManipulation::insertSorted routine this callback signals that the + * given column was inserted at the given position. Further information is provided in order to make + * the insertion efficient. This means that we need to perform the same operation on the entries. * @param nLeftToInsert the number of insertions that occur after this one. * @param colPos the position of the column that was inserted. - * @param insertPos the position the column was inserted at. - * @param prevPos the position the previous column was inserted at or m_rowNNZ - * if it is the first insertion. + * @param pos The position the column was inserted at. + * @param prevPos The position the previous column was inserted at or m_rowNNZ if it is the first insertion. */ DISABLE_HD_WARNING LVARRAY_HOST_DEVICE inline @@ -539,7 +544,7 @@ class CRSMatrixView : protected SparsityPatternView< COL_TYPE, INDEX_TYPE > private: /// A reference to the associated CRSMatrixView. - CRSMatrixView< T, COL_TYPE, INDEX_TYPE > const & m_crsMV; + CRSMatrixView const & m_crsMV; /// The associated row. INDEX_TYPE const m_row; diff --git a/src/IntegerConversion.hpp b/src/IntegerConversion.hpp index a257852d..6d94be11 100644 --- a/src/IntegerConversion.hpp +++ b/src/IntegerConversion.hpp @@ -39,10 +39,19 @@ namespace LvArray namespace internal { +/** + * @struct IntegerTraits + * @tparam INTEGER The integer type to get the traits of. + * @note This just wraps the methods in std::numeric_limits< INTEGER > but it makes them + * available on device. + */ template< typename INTEGER > struct IntegerTraits { + /// The minimum value representable by INTEGER. static constexpr INTEGER min = std::numeric_limits< INTEGER >::min(); + + /// The maximum value representable by INTEGER. static constexpr INTEGER max = std::numeric_limits< INTEGER >::max(); }; diff --git a/src/MallocBuffer.hpp b/src/MallocBuffer.hpp index e3fb3964..6b1d0cc6 100644 --- a/src/MallocBuffer.hpp +++ b/src/MallocBuffer.hpp @@ -16,8 +16,7 @@ *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -#ifndef MALLOC_BUFFER_HPP_ -#define MALLOC_BUFFER_HPP_ +#pragma once // Source includes #include "LvArrayConfig.hpp" @@ -55,7 +54,7 @@ class MallocBuffer : public bufferManipulation::VoidBuffer * @note An uninitialized MallocBuffer is equivalent to an empty MallocBuffer and does * not need to be free'd. */ - LVARRAY_HOST_DEVICE RAJA_INLINE constexpr + LVARRAY_HOST_DEVICE inline constexpr MallocBuffer( bool=true ): m_data( nullptr ), m_capacity( 0 ) @@ -78,7 +77,7 @@ class MallocBuffer : public bufferManipulation::VoidBuffer * @brief Move constructor, creates a shallow copy. * @param src The buffer to be moved from, is empty after the move. */ - LVARRAY_HOST_DEVICE RAJA_INLINE constexpr + LVARRAY_HOST_DEVICE inline constexpr MallocBuffer( MallocBuffer && src ): m_data( src.m_data ), m_capacity( src.m_capacity ) @@ -92,7 +91,7 @@ class MallocBuffer : public bufferManipulation::VoidBuffer * @param src The buffer to be copied. * @return *this. */ - LVARRAY_HOST_DEVICE RAJA_INLINE constexpr + LVARRAY_HOST_DEVICE inline constexpr MallocBuffer & operator=( MallocBuffer const & src ) { m_capacity = src.m_capacity; @@ -105,7 +104,7 @@ class MallocBuffer : public bufferManipulation::VoidBuffer * @param src The buffer to be moved from, is empty after the move. * @return *this. */ - LVARRAY_HOST_DEVICE RAJA_INLINE constexpr + LVARRAY_HOST_DEVICE inline constexpr MallocBuffer & operator=( MallocBuffer && src ) { m_capacity = src.m_capacity; @@ -181,5 +180,3 @@ class MallocBuffer : public bufferManipulation::VoidBuffer }; } // namespace LvArray - -#endif // MALLOC_BUFFER_HPP_ diff --git a/src/NewChaiBuffer.hpp b/src/NewChaiBuffer.hpp index 42f711e2..4c92085b 100644 --- a/src/NewChaiBuffer.hpp +++ b/src/NewChaiBuffer.hpp @@ -16,8 +16,7 @@ *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -#ifndef NEW_CHAI_BUFFER_HPP -#define NEW_CHAI_BUFFER_HPP +#pragma once // Source includes #include "LvArrayConfig.hpp" @@ -49,6 +48,38 @@ inline chai::ArrayManager & getArrayManager() // CHAI is not threadsafe so we use a lock to serialize access. static std::mutex chaiLock; +inline chai::ExecutionSpace toChaiExecutionSpace( MemorySpace const space ) +{ + if( space == MemorySpace::NONE ) + return chai::NONE; + if( space == MemorySpace::CPU ) + return chai::CPU; +#if defined(USE_CUDA) + if( space == MemorySpace::GPU ) + return chai::GPU; +#endif + + LVARRAY_ERROR( "Unrecognized memory space " << static_cast< int >( space ) ); + + return chai::NONE; +} + +inline MemorySpace toMemorySpace( chai::ExecutionSpace const space ) +{ + if( space == chai::NONE ) + return MemorySpace::NONE; + if( space == chai::CPU ) + return MemorySpace::CPU; +#if defined(USE_CUDA) + if( space == chai::GPU ) + return MemorySpace::GPU; +#endif + + LVARRAY_ERROR( "Unrecognized execution space " << static_cast< int >( space ) ); + + return MemorySpace::NONE; +} + } // namespace internal /** @@ -83,7 +114,7 @@ class NewChaiBuffer * @details An uninitialized NewChaiBuffer is an undefined state and may only be assigned to. * An uninitialized NewChaiBuffer holds no recources and does not need to be free'd. */ - LVARRAY_HOST_DEVICE RAJA_INLINE constexpr + LVARRAY_HOST_DEVICE inline constexpr NewChaiBuffer(): m_pointer( nullptr ), m_capacity( 0 ), @@ -105,7 +136,7 @@ class NewChaiBuffer for( int space = chai::CPU; space < chai::NUM_EXECUTION_SPACES; ++space ) { - m_pointer_record->m_allocators[ space ] = internal::getArrayManager().getAllocatorId( chai::ExecutionSpace( space )); + m_pointer_record->m_allocators[ space ] = internal::getArrayManager().getAllocatorId( chai::ExecutionSpace( space ) ); } } @@ -115,14 +146,14 @@ class NewChaiBuffer * @details In addition to performing a shallow copy of @p src if the chai execution space * is set *this will contain a pointer the the allocation in that space. */ - LVARRAY_HOST_DEVICE RAJA_INLINE + LVARRAY_HOST_DEVICE inline NewChaiBuffer( NewChaiBuffer const & src ): m_pointer( src.m_pointer ), m_capacity( src.m_capacity ), m_pointer_record( src.m_pointer_record ) { #if defined(USE_CUDA) && !defined(__CUDA_ARCH__) - move( internal::getArrayManager().getExecutionSpace(), true ); + move( internal::toMemorySpace( internal::getArrayManager().getExecutionSpace() ), true ); #endif } @@ -132,14 +163,14 @@ class NewChaiBuffer * @note This method should be preffered over the copy constructor when the size information * is available. */ - LVARRAY_HOST_DEVICE RAJA_INLINE + LVARRAY_HOST_DEVICE inline NewChaiBuffer( NewChaiBuffer const & src, std::ptrdiff_t const size ): m_pointer( src.m_pointer ), m_capacity( src.m_capacity ), m_pointer_record( src.m_pointer_record ) { #if defined(USE_CUDA) && !defined(__CUDA_ARCH__) - move( internal::getArrayManager().getExecutionSpace(), size, true ); + move( internal::toMemorySpace( internal::getArrayManager().getExecutionSpace() ), size, true ); #else LVARRAY_UNUSED_VARIABLE( size ); #endif @@ -149,7 +180,7 @@ class NewChaiBuffer * @brief Move constructor. * @param src The NewChaiBuffer to be moved from, is uninitialized after this call. */ - LVARRAY_HOST_DEVICE RAJA_INLINE constexpr + LVARRAY_HOST_DEVICE inline constexpr NewChaiBuffer( NewChaiBuffer && src ): m_pointer( src.m_pointer ), m_capacity( src.m_capacity ), @@ -165,7 +196,7 @@ class NewChaiBuffer * @param src The NewChaiBuffer to be copied. * @return *this. */ - LVARRAY_HOST_DEVICE RAJA_INLINE constexpr + LVARRAY_HOST_DEVICE inline constexpr NewChaiBuffer & operator=( NewChaiBuffer const & src ) { m_capacity = src.m_capacity; @@ -179,7 +210,7 @@ class NewChaiBuffer * @param src The NewChaiBuffer to be moved from, is uninitialized after this call. * @return *this. */ - LVARRAY_HOST_DEVICE RAJA_INLINE constexpr + LVARRAY_HOST_DEVICE inline constexpr NewChaiBuffer & operator=( NewChaiBuffer && src ) { m_capacity = src.m_capacity; @@ -226,7 +257,7 @@ class NewChaiBuffer m_capacity = newCapacity; m_pointer = newPointer; m_pointer_record = newRecord; - registerTouch( chai::CPU ); + registerTouch( MemorySpace::CPU ); } /** @@ -246,14 +277,14 @@ class NewChaiBuffer /** * @brief @return Return the capacity of the buffer. */ - LVARRAY_HOST_DEVICE RAJA_INLINE constexpr + LVARRAY_HOST_DEVICE inline constexpr std::ptrdiff_t capacity() const { return m_capacity; } /** * @brief @return Return a pointer to the beginning of the buffer. */ - LVARRAY_HOST_DEVICE RAJA_INLINE constexpr + LVARRAY_HOST_DEVICE inline constexpr T * data() const { return m_pointer; } @@ -264,7 +295,7 @@ class NewChaiBuffer * @note No bounds checks are performed. */ template< typename INDEX_TYPE > - LVARRAY_HOST_DEVICE RAJA_INLINE constexpr + LVARRAY_HOST_DEVICE inline constexpr T & operator[]( INDEX_TYPE const i ) const { return m_pointer[ i ]; } @@ -275,29 +306,30 @@ class NewChaiBuffer * @param touch If the buffer should be touched in the new space or not. */ inline - void move( chai::ExecutionSpace const space, std::ptrdiff_t const size, bool const touch ) const + void move( MemorySpace const space, std::ptrdiff_t const size, bool const touch ) const { #if defined(USE_CUDA) + chai::ExecutionSpace const chaiSpace = internal::toChaiExecutionSpace( space ); if( m_pointer_record == nullptr || m_capacity == 0 || - space == chai::NONE ) return; + chaiSpace == chai::NONE ) return; chai::ExecutionSpace const prevSpace = m_pointer_record->m_last_space; - if( prevSpace == chai::CPU && prevSpace != space ) moveInnerData( space, size, touch ); + if( prevSpace == chai::CPU && prevSpace != chaiSpace ) moveInnerData( space, size, touch ); const_cast< T * & >( m_pointer ) = static_cast< T * >( internal::getArrayManager().move( const_cast< T_non_const * >( m_pointer ), m_pointer_record, - space ) ); + chaiSpace ) ); - if( !std::is_const< T >::value && touch ) m_pointer_record->m_touched[ space ] = true; - m_pointer_record->m_last_space = space; + if( !std::is_const< T >::value && touch ) m_pointer_record->m_touched[ chaiSpace ] = true; + m_pointer_record->m_last_space = chaiSpace; - if( prevSpace == chai::GPU && prevSpace != space ) moveInnerData( space, size, touch ); + if( prevSpace == chai::GPU && prevSpace != chaiSpace ) moveInnerData( space, size, touch ); #else - LVARRAY_ERROR_IF_NE( space, chai::CPU ); + LVARRAY_ERROR_IF_NE( space, MemorySpace::CPU ); LVARRAY_UNUSED_VARIABLE( size ); LVARRAY_UNUSED_VARIABLE( touch ); #endif @@ -307,23 +339,24 @@ class NewChaiBuffer * @brief Move the buffer to the given execution space, optionally touching it. * @param space The space to move the buffer to. * @param touch If the buffer should be touched in the new space or not. - * @note This method is only active when the type T itself does not have a method move( chai::ExecutionSpace ). + * @note This method is only active when the type T itself does not have a method move( MemorySpace ). * @return Nothing. */ template< typename U=T_non_const > std::enable_if_t< !bufferManipulation::HasMemberFunction_move< U > > - move( chai::ExecutionSpace const space, bool const touch ) const + move( MemorySpace const space, bool const touch ) const { move( space, capacity(), touch ); } /** * @brief Touch the buffer in the given space. * @param space the space to touch. */ - RAJA_INLINE constexpr - void registerTouch( chai::ExecutionSpace const space ) const + inline constexpr + void registerTouch( MemorySpace const space ) const { - m_pointer_record->m_touched[ space ] = true; - m_pointer_record->m_last_space = space; + chai::ExecutionSpace const chaiSpace = internal::toChaiExecutionSpace( space ); + m_pointer_record->m_touched[ chaiSpace ] = true; + m_pointer_record->m_last_space = chaiSpace; } /** @@ -335,12 +368,12 @@ class NewChaiBuffer void setName( std::string const & name ) { std::string const typeString = LvArray::demangle( typeid( U ).name() ); - m_pointer_record->m_user_callback = \ - [name, typeString]( chai::Action act, chai::ExecutionSpace s, size_t bytes ) + m_pointer_record->m_user_callback = + [name, typeString]( chai::PointerRecord const * const record, chai::Action const act, chai::ExecutionSpace const s ) { if( act == chai::ACTION_MOVE ) { - std::string const size = LvArray::calculateSize( bytes ); + std::string const size = LvArray::calculateSize( record->m_size ); std::string const paddedSize = std::string( 9 - size.size(), ' ' ) + size; char const * const spaceStr = ( s == chai::CPU ) ? "HOST " : "DEVICE"; LVARRAY_LOG( "Moved " << paddedSize << " to the " << spaceStr << ": " << typeString << " " << name ); @@ -356,13 +389,13 @@ class NewChaiBuffer * @param space The memory space to move to. * @param size The number of values to move. * @param touch If the inner values should be touched or not. - * @note This method is only active when T has a method move( chai::ExecutionSpace ). + * @note This method is only active when T has a method move( MemorySpace ). */ template< typename U=T_non_const > std::enable_if_t< bufferManipulation::HasMemberFunction_move< U > > - moveInnerData( chai::ExecutionSpace const space, std::ptrdiff_t const size, bool const touch ) const + moveInnerData( MemorySpace const space, std::ptrdiff_t const size, bool const touch ) const { - if( space == chai::NONE ) return; + if( space == MemorySpace::NONE ) return; for( std::ptrdiff_t i = 0; i < size; ++i ) { @@ -373,11 +406,11 @@ class NewChaiBuffer /** * @tparam U A dummy parameter to enable SFINAE, do not specify. * @brief Move inner allocations to the memory space @p space. - * @note This method is only active when T does not have a method move( chai::ExecutionSpace ). + * @note This method is only active when T does not have a method move( MemorySpace ). */ template< typename U=T_non_const > std::enable_if_t< !bufferManipulation::HasMemberFunction_move< U > > - moveInnerData( chai::ExecutionSpace const, std::ptrdiff_t const, bool const ) const + moveInnerData( MemorySpace const, std::ptrdiff_t const, bool const ) const {} /// A pointer to the data. @@ -391,5 +424,3 @@ class NewChaiBuffer }; } /* namespace LvArray */ - -#endif /* NEW_CHAI_BUFFER_HPP */ diff --git a/src/SetSignalHandling.cpp b/src/SetSignalHandling.cpp index 69e24d05..1a472120 100644 --- a/src/SetSignalHandling.cpp +++ b/src/SetSignalHandling.cpp @@ -17,7 +17,7 @@ */ /** - * @file FloatingPointExceptions.cpp + * @file SetSignalHandling.cpp */ #include "SetSignalHandling.hpp" @@ -29,7 +29,10 @@ namespace LvArray { -typedef void ( *handle_type )( int ); +/// An alias for a function that takes an int and returns nothing. +using handle_type = void ( * )( int ); + +/// A map containing the initial signal handlers. static std::map< int, handle_type > initialHandler; void setSignalHandling( void (* handler)( int ) ) diff --git a/src/SortedArray.hpp b/src/SortedArray.hpp index f311f455..f173bade 100644 --- a/src/SortedArray.hpp +++ b/src/SortedArray.hpp @@ -20,11 +20,9 @@ * @file SortedArray.hpp */ -#ifndef SRC_COMMON_SORTEDARRAY -#define SRC_COMMON_SORTEDARRAY +#pragma once #include "SortedArrayView.hpp" -#include "sortedArrayManipulation.hpp" namespace LvArray { @@ -41,31 +39,43 @@ namespace LvArray * The derivation from SortedArrayView is protected to control the conversion to * SortedArrayView. Specifically only conversion to SortedArrayView is allowed. */ -template< class T, class INDEX_TYPE=std::ptrdiff_t > -class SortedArray : protected SortedArrayView< T, INDEX_TYPE > +template< typename T, + typename INDEX_TYPE, + template< typename > class BUFFER_TYPE > +class SortedArray : protected SortedArrayView< T, INDEX_TYPE, BUFFER_TYPE > { public: + /// Alias for the parent class + using ParentClass = SortedArrayView< T, INDEX_TYPE, BUFFER_TYPE >; + // Alias public typedefs of SortedArrayView. - using typename SortedArrayView< T, INDEX_TYPE >::value_type; - using typename SortedArrayView< T, INDEX_TYPE >::iterator; - using typename SortedArrayView< T, INDEX_TYPE >::const_iterator; - using typename SortedArrayView< T, INDEX_TYPE >::pointer; - using typename SortedArrayView< T, INDEX_TYPE >::const_pointer; + using typename ParentClass::value_type; + using typename ParentClass::iterator; + using typename ParentClass::const_iterator; + using typename ParentClass::pointer; + using typename ParentClass::const_pointer; + + /// The view type. + using ViewType = SortedArrayView< T const, INDEX_TYPE, BUFFER_TYPE > const; + + /// The const view type, this is the same as the view type since SortedArrayView can't + /// modify the data. + using ViewTypeConst = SortedArrayView< T const, INDEX_TYPE, BUFFER_TYPE > const; // Alias public methods of SortedArrayView. - using SortedArrayView< T, INDEX_TYPE >::operator[]; - using SortedArrayView< T, INDEX_TYPE >::begin; - using SortedArrayView< T, INDEX_TYPE >::end; - using SortedArrayView< T, INDEX_TYPE >::contains; - using SortedArrayView< T, INDEX_TYPE >::count; + using ParentClass::operator[]; + using ParentClass::begin; + using ParentClass::end; + using ParentClass::contains; + using ParentClass::count; /** * @brief Default constructor. */ inline SortedArray(): - SortedArrayView< T, INDEX_TYPE >() + ParentClass() { setName( "" ); } /** @@ -74,7 +84,7 @@ class SortedArray : protected SortedArrayView< T, INDEX_TYPE > */ inline SortedArray( SortedArray const & src ): - SortedArrayView< T, INDEX_TYPE >() + ParentClass() { *this = src; } /** @@ -116,15 +126,15 @@ class SortedArray : protected SortedArrayView< T, INDEX_TYPE > * @brief @return A reference to *this reinterpreted as a SortedArrayView const. */ LVARRAY_HOST_DEVICE inline - SortedArrayView< T const, INDEX_TYPE > const & toView() const LVARRAY_RESTRICT_THIS - { return SortedArrayView< T, INDEX_TYPE >::toViewConst(); } + SortedArrayView< T const, INDEX_TYPE, BUFFER_TYPE > const & toView() const LVARRAY_RESTRICT_THIS + { return ParentClass::toViewConst(); } /** * @brief @return A reference to *this reinterpreted as a SortedArrayView const. */ LVARRAY_HOST_DEVICE inline - SortedArrayView< T const, INDEX_TYPE > const & toViewConst() const LVARRAY_RESTRICT_THIS - { return SortedArrayView< T, INDEX_TYPE >::toViewConst(); } + SortedArrayView< T const, INDEX_TYPE, BUFFER_TYPE > const & toViewConst() const LVARRAY_RESTRICT_THIS + { return ParentClass::toViewConst(); } /** * @brief @return Return true iff the SortedArray contains not values. @@ -132,7 +142,7 @@ class SortedArray : protected SortedArrayView< T, INDEX_TYPE > */ constexpr inline bool empty() const - { return SortedArrayView< T, INDEX_TYPE >::empty(); } + { return ParentClass::empty(); } /** * @brief @return Return the number of values in the SortedArray. @@ -140,7 +150,7 @@ class SortedArray : protected SortedArrayView< T, INDEX_TYPE > */ constexpr inline INDEX_TYPE size() const - { return SortedArrayView< T, INDEX_TYPE >::size(); } + { return ParentClass::size(); } /** * @brief @return Return a pointer to the values. @@ -148,7 +158,7 @@ class SortedArray : protected SortedArrayView< T, INDEX_TYPE > */ LVARRAY_HOST_DEVICE constexpr inline T const * data() const - { return SortedArrayView< T, INDEX_TYPE >::data(); } + { return ParentClass::data(); } /** * @brief Remove all the values from the array. @@ -242,8 +252,8 @@ class SortedArray : protected SortedArrayView< T, INDEX_TYPE > * @note Duplicated for SFINAE needs. */ inline - void move( chai::ExecutionSpace const space, bool touch=true ) const LVARRAY_RESTRICT_THIS - { return SortedArrayView< T, INDEX_TYPE >::move( space, touch ); } + void move( MemorySpace const space, bool touch=true ) const LVARRAY_RESTRICT_THIS + { return ParentClass::move( space, touch ); } private: @@ -257,11 +267,12 @@ class SortedArray : protected SortedArrayView< T, INDEX_TYPE > /** * @brief Constructor. - * @param cv the NewChaiBuffer associated with the SortedArray. + * @param buffer The buffer associated with the SortedArray. + * @param size The size of the SortedArray. */ inline - CallBacks( NewChaiBuffer< T > & cb, INDEX_TYPE const size ): - m_cb( cb ), + CallBacks( BUFFER_TYPE< T > & buffer, INDEX_TYPE const size ): + m_buffer( buffer ), m_size( size ) {} @@ -273,26 +284,25 @@ class SortedArray : protected SortedArrayView< T, INDEX_TYPE > * @return A pointer to the new array. */ inline - T * incrementSize( T * const LVARRAY_UNUSED_ARG( curPtr ), + T * incrementSize( T * const curPtr, INDEX_TYPE const nToAdd ) const LVARRAY_RESTRICT_THIS { - bufferManipulation::dynamicReserve( m_cb, m_size, m_size + nToAdd ); - return m_cb.data(); + LVARRAY_UNUSED_VARIABLE( curPtr ); + bufferManipulation::dynamicReserve( m_buffer, m_size, m_size + nToAdd ); + return m_buffer.data(); } private: /// The buffer associated with the callback. - NewChaiBuffer< T > & m_cb; + BUFFER_TYPE< T > & m_buffer; /// The number of values in the buffer. INDEX_TYPE const m_size; }; // Alias the protected members of SortedArrayView. - using SortedArrayView< T, INDEX_TYPE >::m_values; - using SortedArrayView< T, INDEX_TYPE >::m_size; + using ParentClass::m_values; + using ParentClass::m_size; }; } // namespace LvArray - -#endif // SRC_COMMON_SORTEDARRAY diff --git a/src/SortedArrayView.hpp b/src/SortedArrayView.hpp index 61a24ba0..018353e0 100644 --- a/src/SortedArrayView.hpp +++ b/src/SortedArrayView.hpp @@ -23,7 +23,7 @@ #ifndef SRC_COMMON_SORTEDARRAYVIEW #define SRC_COMMON_SORTEDARRAYVIEW -#include "NewChaiBuffer.hpp" +// Source includes #include "bufferManipulation.hpp" #include "sortedArrayManipulation.hpp" @@ -62,7 +62,9 @@ namespace LvArray * since the View has no way of modifying the values. This also prevents unnecessary * memory movement. */ -template< class T, class INDEX_TYPE=std::ptrdiff_t > +template< typename T, + typename INDEX_TYPE, + template< typename > class BUFFER_TYPE > class SortedArrayView { public: @@ -127,15 +129,15 @@ class SortedArrayView * @brief @return A reference to *this. */ LVARRAY_HOST_DEVICE inline - SortedArrayView< T > const & toView() const LVARRAY_RESTRICT_THIS + SortedArrayView const & toView() const LVARRAY_RESTRICT_THIS { return *this; } /** * @brief @return A reference to *this. */ LVARRAY_HOST_DEVICE inline - SortedArrayView< T const > const & toViewConst() const LVARRAY_RESTRICT_THIS - { return reinterpret_cast< SortedArrayView< T const, INDEX_TYPE > const & >( *this ); } + SortedArrayView< T const, INDEX_TYPE, BUFFER_TYPE > const & toViewConst() const LVARRAY_RESTRICT_THIS + { return reinterpret_cast< SortedArrayView< T const, INDEX_TYPE, BUFFER_TYPE > const & >( *this ); } /** * @brief @return Return a pointer to the values. @@ -208,10 +210,10 @@ class SortedArrayView * to the GPU @p touch is set to false. */ inline - void move( chai::ExecutionSpace const space, bool touch=true ) const LVARRAY_RESTRICT_THIS + void move( MemorySpace const space, bool touch=true ) const LVARRAY_RESTRICT_THIS { #if defined(USE_CUDA) - if( space == chai::GPU ) touch = false; + if( space == MemorySpace::GPU ) touch = false; #endif m_values.move( space, touch ); } @@ -228,7 +230,7 @@ class SortedArrayView {} /// Holds the array of values. - NewChaiBuffer< T > m_values; + BUFFER_TYPE< T > m_values; /// The number of values INDEX_TYPE m_size = 0; diff --git a/src/SparsityPattern.hpp b/src/SparsityPattern.hpp index 9805d5f5..bdec5c3b 100644 --- a/src/SparsityPattern.hpp +++ b/src/SparsityPattern.hpp @@ -34,15 +34,20 @@ namespace LvArray * @tparam COL_TYPE the integer used to enumerate the columns. * @tparam INDEX_TYPE the integer to use for indexing. */ -template< class COL_TYPE=int, typename INDEX_TYPE=std::ptrdiff_t > -class SparsityPattern : protected SparsityPatternView< COL_TYPE, INDEX_TYPE > +template< typename COL_TYPE, + typename INDEX_TYPE, + template< typename > class BUFFER_TYPE > +class SparsityPattern : protected SparsityPatternView< COL_TYPE, INDEX_TYPE, BUFFER_TYPE > { /// An alias for the parent class. - using ParentClass = SparsityPatternView< COL_TYPE, INDEX_TYPE >; + using ParentClass = SparsityPatternView< COL_TYPE, INDEX_TYPE, BUFFER_TYPE >; public: + /// An alias for the column type. + using column_type = COL_TYPE; + // Aliasing public methods of SparsityPatternView. using ParentClass::numRows; using ParentClass::numColumns; @@ -66,7 +71,7 @@ class SparsityPattern : protected SparsityPatternView< COL_TYPE, INDEX_TYPE > SparsityPattern( INDEX_TYPE const nrows=0, INDEX_TYPE const ncols=0, INDEX_TYPE initialRowCapacity=0 ) LVARRAY_RESTRICT_THIS: - SparsityPatternView< COL_TYPE, INDEX_TYPE >() + ParentClass() { resize( nrows, ncols, initialRowCapacity ); setName( "" ); @@ -78,7 +83,7 @@ class SparsityPattern : protected SparsityPatternView< COL_TYPE, INDEX_TYPE > */ inline SparsityPattern( SparsityPattern const & src ) LVARRAY_RESTRICT_THIS: - SparsityPatternView< COL_TYPE, INDEX_TYPE >() + ParentClass() { *this = src; } /** @@ -129,15 +134,17 @@ class SparsityPattern : protected SparsityPatternView< COL_TYPE, INDEX_TYPE > * @note Duplicated for SFINAE needs. */ constexpr inline - SparsityPatternView< COL_TYPE, INDEX_TYPE const > const & toView() const LVARRAY_RESTRICT_THIS - { return reinterpret_cast< SparsityPatternView< COL_TYPE, INDEX_TYPE const > const & >( *this ); } + SparsityPatternView< COL_TYPE, INDEX_TYPE const, BUFFER_TYPE > const & + toView() const LVARRAY_RESTRICT_THIS + { return reinterpret_cast< SparsityPatternView< COL_TYPE, INDEX_TYPE const, BUFFER_TYPE > const & >( *this ); } /** * @brief @return A reference to *this reinterpreted as a SparsityPatternView< COL_TYPE const, INDEX_TYPE const >. * @note Duplicated for SFINAE needs. */ LVARRAY_HOST_DEVICE constexpr inline - SparsityPatternView< COL_TYPE const, INDEX_TYPE const > const & toViewConst() const LVARRAY_RESTRICT_THIS + SparsityPatternView< COL_TYPE const, INDEX_TYPE const, BUFFER_TYPE > const & + toViewConst() const LVARRAY_RESTRICT_THIS { return ParentClass::toViewConst(); } /** @@ -238,8 +245,8 @@ class SparsityPattern : protected SparsityPatternView< COL_TYPE, INDEX_TYPE > void appendRow( INDEX_TYPE const nzCapacity=0 ) LVARRAY_RESTRICT_THIS { INDEX_TYPE const maxOffset = m_offsets[ m_numArrays ]; - bufferManipulation::pushBack( m_offsets, m_numArrays + 1, maxOffset ); - bufferManipulation::pushBack( m_sizes, m_numArrays, 0 ); + bufferManipulation::emplaceBack( m_offsets, m_numArrays + 1, maxOffset ); + bufferManipulation::emplaceBack( m_sizes, m_numArrays, 0 ); ++m_numArrays; setRowCapacity( m_numArrays - 1, nzCapacity ); @@ -283,7 +290,7 @@ class SparsityPattern : protected SparsityPatternView< COL_TYPE, INDEX_TYPE > * @note When moving to the GPU since the offsets can't be modified on device they are not touched. * @note Duplicated for SFINAE needs. */ - void move( chai::ExecutionSpace const space, bool const touch=true ) const + void move( MemorySpace const space, bool const touch=true ) const { return ParentClass::move( space, touch ); } private: @@ -313,7 +320,7 @@ class SparsityPattern : protected SparsityPatternView< COL_TYPE, INDEX_TYPE > * @param row the row in the SparsityPattern this CallBacks is associated with. */ inline - CallBacks( SparsityPattern< COL_TYPE, INDEX_TYPE > & sp, INDEX_TYPE const row ): + CallBacks( SparsityPattern & sp, INDEX_TYPE const row ): m_sp( sp ), m_row( row ) {} @@ -326,9 +333,9 @@ class SparsityPattern : protected SparsityPatternView< COL_TYPE, INDEX_TYPE > * @return a pointer to the columns of the associated row. */ inline - COL_TYPE * incrementSize( COL_TYPE * const LVARRAY_UNUSED_ARG( curPtr ), - INDEX_TYPE const nToAdd ) const LVARRAY_RESTRICT_THIS + COL_TYPE * incrementSize( COL_TYPE * const curPtr, INDEX_TYPE const nToAdd ) const LVARRAY_RESTRICT_THIS { + LVARRAY_UNUSED_VARIABLE( curPtr ); INDEX_TYPE const newNNZ = m_sp.numNonZeros( m_row ) + nToAdd; if( newNNZ > m_sp.nonZeroCapacity( m_row ) ) { @@ -339,7 +346,10 @@ class SparsityPattern : protected SparsityPatternView< COL_TYPE, INDEX_TYPE > } private: - SparsityPattern< COL_TYPE, INDEX_TYPE > & m_sp; + /// The SparsityPattern the call back is associated with. + SparsityPattern & m_sp; + + /// The row the call back is associated with. INDEX_TYPE const m_row; }; diff --git a/src/SparsityPatternView.hpp b/src/SparsityPatternView.hpp index 78d4ad89..9b97514b 100644 --- a/src/SparsityPatternView.hpp +++ b/src/SparsityPatternView.hpp @@ -20,12 +20,14 @@ * @file SparsityPatternView.hpp */ -#ifndef SPARSITYPATTERNVIEW_HPP_ -#define SPARSITYPATTERNVIEW_HPP_ +#pragma once -#include +// Source includes #include "ArrayOfSetsView.hpp" +// System includes +#include + #ifdef USE_ARRAY_BOUNDS_CHECK /** @@ -63,12 +65,14 @@ namespace LvArray * When COL_TYPE is const and INDEX_TYPE is const you cannot insert or remove from the View * and neither the offsets, sizes, or columns are copied between memory spaces. */ -template< class COL_TYPE=unsigned int, class INDEX_TYPE=std::ptrdiff_t > -class SparsityPatternView : protected ArrayOfSetsView< COL_TYPE, INDEX_TYPE > +template< typename COL_TYPE, + typename INDEX_TYPE, + template< typename > class BUFFER_TYPE > +class SparsityPatternView : protected ArrayOfSetsView< COL_TYPE, INDEX_TYPE, BUFFER_TYPE > { /// An alias for the parent class. - using ParentClass = ArrayOfSetsView< COL_TYPE, INDEX_TYPE >; + using ParentClass = ArrayOfSetsView< COL_TYPE, INDEX_TYPE, BUFFER_TYPE >; public: static_assert( std::is_integral< COL_TYPE >::value, "COL_TYPE must be integral." ); @@ -81,7 +85,7 @@ class SparsityPatternView : protected ArrayOfSetsView< COL_TYPE, INDEX_TYPE > /** * @brief Default copy constructor. Performs a shallow copy and calls the - * chai::ManagedArray copy constructor. + * BUFFER_TYPE copy constructor. */ inline SparsityPatternView( SparsityPatternView const & ) = default; @@ -129,15 +133,17 @@ class SparsityPatternView : protected ArrayOfSetsView< COL_TYPE, INDEX_TYPE > * @brief This is included for SFINAE needs. */ LVARRAY_HOST_DEVICE constexpr inline - SparsityPatternView< COL_TYPE, INDEX_TYPE > const & toView() const LVARRAY_RESTRICT_THIS + SparsityPatternView< COL_TYPE, INDEX_TYPE, BUFFER_TYPE > const & + toView() const LVARRAY_RESTRICT_THIS { return *this; } /** * @brief @return A reference to *this reinterpreted as a SparsityPatternView< COL_TYPE const, INDEX_TYPE const >. */ LVARRAY_HOST_DEVICE constexpr inline - SparsityPatternView< COL_TYPE const, INDEX_TYPE const > const & toViewConst() const LVARRAY_RESTRICT_THIS - { return reinterpret_cast< SparsityPatternView< COL_TYPE const, INDEX_TYPE const > const & >( *this ); } + SparsityPatternView< COL_TYPE const, INDEX_TYPE const, BUFFER_TYPE > const & + toViewConst() const LVARRAY_RESTRICT_THIS + { return reinterpret_cast< SparsityPatternView< COL_TYPE const, INDEX_TYPE const, BUFFER_TYPE > const & >( *this ); } /** * @brief @return Return the number of rows in the matrix. @@ -328,7 +334,7 @@ class SparsityPatternView : protected ArrayOfSetsView< COL_TYPE, INDEX_TYPE > * @param touch If true touch the values, sizes and offsets in the new space. * @note When moving to the GPU since the offsets can't be modified on device they are not touched. */ - void move( chai::ExecutionSpace const space, bool const touch=true ) const + void move( MemorySpace const space, bool const touch=true ) const { return ParentClass::move( space, touch ); } protected: @@ -349,7 +355,10 @@ class SparsityPatternView : protected ArrayOfSetsView< COL_TYPE, INDEX_TYPE > * @param buffers A variadic pack of buffers to resize along with the columns. */ template< class ... BUFFERS > - void resize( INDEX_TYPE const nrows, INDEX_TYPE const ncols, INDEX_TYPE_NC initialRowCapacity, BUFFERS & ... buffers ) + void resize( INDEX_TYPE const nrows, + INDEX_TYPE const ncols, + INDEX_TYPE_NC initialRowCapacity, + BUFFERS & ... buffers ) { LVARRAY_ERROR_IF( !arrayManipulation::isPositive( nrows ), "nrows must be positive." ); LVARRAY_ERROR_IF( !arrayManipulation::isPositive( ncols ), "ncols must be positive." ); @@ -369,6 +378,4 @@ class SparsityPatternView : protected ArrayOfSetsView< COL_TYPE, INDEX_TYPE > INDEX_TYPE_NC m_numCols; }; -} /* namespace LvArray */ - -#endif /* SPARSITYPATTERNVIEW_HPP_ */ +} // namespace LvArray diff --git a/src/arrayHelpers.hpp b/src/arrayHelpers.hpp index e569a1bf..5e2886d9 100644 --- a/src/arrayHelpers.hpp +++ b/src/arrayHelpers.hpp @@ -20,13 +20,11 @@ * @file arrayHelpers.hpp */ -#ifndef SRC_SRC_ARRAY_HELPERS_HPP_ -#define SRC_SRC_ARRAY_HELPERS_HPP_ +#pragma once // Source includes #include "Macros.hpp" #include "Permutation.hpp" -#include "NewChaiBuffer.hpp" #include "templateHelpers.hpp" #include "IntegerConversion.hpp" @@ -81,7 +79,7 @@ struct ConditionalMultiply< true > * @param values A pointer to the values to multiply together. */ template< int SIZE, typename T > -LVARRAY_HOST_DEVICE RAJA_INLINE constexpr +LVARRAY_HOST_DEVICE inline constexpr std::enable_if_t< (SIZE == 1), T > multiplyAll( T const * const LVARRAY_RESTRICT values ) { return values[ 0 ]; } @@ -93,7 +91,7 @@ multiplyAll( T const * const LVARRAY_RESTRICT values ) * @param values A pointer to the values to multiply together. */ template< int SIZE, typename T > -LVARRAY_HOST_DEVICE RAJA_INLINE constexpr +LVARRAY_HOST_DEVICE inline constexpr std::enable_if_t< (SIZE > 1), T > multiplyAll( T const * const LVARRAY_RESTRICT values ) { return values[ 0 ] * multiplyAll< SIZE - 1 >( values + 1 ); } @@ -109,7 +107,7 @@ multiplyAll( T const * const LVARRAY_RESTRICT values ) * @return The product of index with strides[ 0 ]. */ template< int USD, typename INDEX_TYPE, typename INDEX > -LVARRAY_HOST_DEVICE RAJA_INLINE constexpr +LVARRAY_HOST_DEVICE inline constexpr INDEX_TYPE getLinearIndex( INDEX_TYPE const * const LVARRAY_RESTRICT strides, INDEX const index ) { return ConditionalMultiply< USD == 0 >::multiply( index, strides[ 0 ] ); } @@ -126,7 +124,7 @@ INDEX_TYPE getLinearIndex( INDEX_TYPE const * const LVARRAY_RESTRICT strides, IN * @return The dot product of @p strides with ( @p index, @p indices ... ). */ template< int USD, typename INDEX_TYPE, typename INDEX, typename ... REMAINING_INDICES > -LVARRAY_HOST_DEVICE RAJA_INLINE constexpr +LVARRAY_HOST_DEVICE inline constexpr INDEX_TYPE getLinearIndex( INDEX_TYPE const * const LVARRAY_RESTRICT strides, INDEX const index, REMAINING_INDICES const ... indices ) { return ConditionalMultiply< USD == 0 >::multiply( index, strides[ 0 ] ) + @@ -216,5 +214,3 @@ void checkIndices( INDEX_TYPE const * const LVARRAY_RESTRICT dims, INDICES const { LVARRAY_ERROR_IF( invalidIndices( dims, indices ... ), "Invalid indices. " << printDimsAndIndices( dims, indices ... ) ); } } /* namespace LvArray */ - -#endif // SRC_SRC_ARRAY_HELPERS_HPP_ diff --git a/src/arrayManipulation.hpp b/src/arrayManipulation.hpp index d930b353..75c5e6eb 100644 --- a/src/arrayManipulation.hpp +++ b/src/arrayManipulation.hpp @@ -95,8 +95,8 @@ isPositive( INDEX_TYPE ) /** * @tparam T the storage type of the array. * @brief Destory the values in the array. - * @param ptr pointer to the array. - * @param size the size of the array. + * @param ptr Pointer to the array. + * @param size The size of the array. */ DISABLE_HD_WARNING template< typename T > @@ -141,7 +141,7 @@ void uninitializedCopy( ITER first, * @tparam T the storage type of the array. * @brief Move construct values from the source to the destination. * @param dst pointer to the destination array, must be uninitialized memory. - * @param size the number of values to copy. + * @param size The number of values to copy. * @param src pointer to the source array. */ DISABLE_HD_WARNING @@ -164,7 +164,7 @@ void uninitializedMove( T * const LVARRAY_RESTRICT dst, /** * @tparam T the storage type of the array. * @brief Shift values down into uninitialized memory. - * @param ptr pointer to the begining of the shift, values before this must be uninitialized. + * @param ptr Pointer to the begining of the shift, values before this must be uninitialized. * @param size number of values to shift. * @param amount the amount to shift by. */ @@ -192,7 +192,7 @@ void uninitializedShiftDown( T * const LVARRAY_RESTRICT ptr, /** * @tparam T the storage type of the array. * @brief Shift values up into uninitialized memory. - * @param ptr pointer to the begining of the shift. + * @param ptr Pointer to the begining of the shift. * @param size number of values to shift, values after this must be uninitialized. * @param amount the amount to shift by. */ @@ -221,8 +221,8 @@ void uninitializedShiftUp( T * const LVARRAY_RESTRICT ptr, * @tparam T the storage type of the array. * @tparam ARGS the types of the arguments to forward to the constructor. * @brief Resize the give array. - * @param ptr pointer to the array. - * @param size the size of the array. + * @param ptr Pointer to the array. + * @param size The size of the array. * @param newSize the new size. * @param args the arguments to forward to construct any new elements with. */ @@ -252,8 +252,8 @@ void resize( T * const LVARRAY_RESTRICT ptr, * @tparam T the storage type of the array. * @brief Shift the values in the array at or above the given position up by the given amount. * New uninitialized values take their place. - * @param ptr pointer to the array. - * @param size the size of the array. + * @param ptr Pointer to the array. + * @param size The size of the array. * @param index the index at which to begin the shift. * @param n the number of places to shift. */ @@ -285,42 +285,12 @@ void shiftUp( T * const LVARRAY_RESTRICT ptr, destroy( ptr + index, bounds - index ); } -/** - * @tparam T the storage type of the array. - * @brief Shift the values in the array at or above the given position up by the given amount. - * New values take their place. - * @param ptr pointer to the array. - * @param size the size of the array. - * @param index the index at which to begin the shift. - * @param n the number of places to shift. - * @param defaultValue the value to initialize the new entries with. - */ -DISABLE_HD_WARNING -template< typename T > -LVARRAY_HOST_DEVICE inline -void emplace( T * const LVARRAY_RESTRICT ptr, - std::ptrdiff_t const size, - std::ptrdiff_t const index, - std::ptrdiff_t const n=1, - T const & defaultValue=T() ) -{ - ARRAYMANIPULATION_CHECK_INSERT_BOUNDS( index ); - - shiftUp( ptr, size, index, n ); - - // Initialize the empty values to the default value. - for( std::ptrdiff_t i = index; i < index + n; ++i ) - { - new( ptr + i ) T( defaultValue ); - } -} - /** * @tparam T the storage type of the array. * @brief Shift the values in the array at or above the given position down by the given amount overwriting * the existing values. The n entries at the end of the array are not destroyed. - * @param ptr pointer to the array. - * @param size the size of the array. + * @param ptr Pointer to the array. + * @param size The size of the array. * @param index the index at which to begin the shift. * @param n the number of places to shift. */ @@ -352,8 +322,8 @@ void shiftDown( T * const LVARRAY_RESTRICT ptr, * @tparam T the storage type of the array. * @brief Shift the values in the array at or above the given position down by the given amount overwriting * the existing values. The n entries at the end of the array are then destroyed. - * @param ptr pointer to the array. - * @param size the size of the array. + * @param ptr Pointer to the array. + * @param size The size of the array. * @param index the index at which to begin the shift. * @param n the number of places to shift. */ @@ -379,135 +349,99 @@ void erase( T * const LVARRAY_RESTRICT ptr, } /** - * @tparam T the storage type of the array. - * @brief Append the given value to the array. - * @param ptr pointer to the array. - * @param size the size of the array. - * @param value the value to append. + * @brief Append the to the array constructing the new value in place. + * @tparam T The storage type of the array. + * @tparam ARGS Variadic pack of types to construct T with, the types of @p args. + * @param ptr Pointer to the array. + * @param size The size of the array. + * @param args The arguments to forward to construct the new value. */ DISABLE_HD_WARNING -template< typename T > -LVARRAY_HOST_DEVICE inline -void append( T * const LVARRAY_RESTRICT ptr, - std::ptrdiff_t const size, - T const & value ) -{ - LVARRAY_ASSERT( ptr != nullptr ); - LVARRAY_ASSERT( isPositive( size ) ); - new ( ptr + size ) T( value ); -} - -/** - * @tparam T the storage type of the array. - * @brief Append the given value to the array. - * @param ptr pointer to the array. - * @param size the size of the array. - * @param value the value to append. - */ -DISABLE_HD_WARNING -template< typename T > +template< typename T, typename ... ARGS > LVARRAY_HOST_DEVICE inline -void append( T * const LVARRAY_RESTRICT ptr, - std::ptrdiff_t const size, - T && value ) +void emplaceBack( T * const LVARRAY_RESTRICT ptr, + std::ptrdiff_t const size, + ARGS && ... args ) { LVARRAY_ASSERT( ptr != nullptr ); LVARRAY_ASSERT( isPositive( size ) ); - new ( ptr + size ) T( std::move( value ) ); + new ( ptr + size ) T( std::forward< ARGS >( args ) ... ); } /** - * @tparam T the storage type of the array. * @brief Append the given values to the array. - * @param ptr pointer to the array. - * @param size the size of the array. - * @param values the values to append. - * @param n the number of values to append. + * @tparam T The storage type of the array. + * @tparam ITER The type of the iterators @p first and @p last. + * @param ptr Pointer to the array. + * @param size The size of the array. + * @param first An iterator to the first value to append. + * @param last An iterator to the end of the values to append. */ DISABLE_HD_WARNING -template< typename T > +template< typename T, typename ITER > LVARRAY_HOST_DEVICE inline -void append( T * const LVARRAY_RESTRICT ptr, - std::ptrdiff_t const size, - T const * const LVARRAY_RESTRICT values, - std::ptrdiff_t const n ) +std::ptrdiff_t append( T * const LVARRAY_RESTRICT ptr, + std::ptrdiff_t const size, + ITER first, + ITER const last ) { - LVARRAY_ASSERT( ptr != nullptr || (size == 0 && n == 0) ); + LVARRAY_ASSERT( ptr != nullptr || (size == 0 && first == last) ); LVARRAY_ASSERT( isPositive( size ) ); - LVARRAY_ASSERT( isPositive( n ) ); - LVARRAY_ASSERT( values != nullptr || n == 0 ); - for( std::ptrdiff_t i = 0; i < n; ++i ) + std::ptrdiff_t i = 0; + while( first != last ) { - new ( ptr + size + i ) T( values[i] ); + new( ptr + size + i ) T( *first ); + ++first; + ++i; } -} - -/** - * @tparam T the storage type of the array. - * @brief Insert the given value into the array at the given position. - * @param ptr pointer to the array. - * @param size the size of the array. - * @param index the position to insert the value at. - * @param value the value to insert. - */ -DISABLE_HD_WARNING -template< typename T > -LVARRAY_HOST_DEVICE inline -void insert( T * const LVARRAY_RESTRICT ptr, - std::ptrdiff_t const size, - std::ptrdiff_t const index, - T const & value ) -{ - LVARRAY_ASSERT( ptr != nullptr ); - LVARRAY_ASSERT( isPositive( size ) ); - ARRAYMANIPULATION_CHECK_INSERT_BOUNDS( index ); - // Create space for the new value. - shiftUp( ptr, size, index, std::ptrdiff_t( 1 ) ); - new ( ptr + index ) T( value ); + return i; } /** - * @tparam T the storage type of the array. - * @brief Insert the given value into the array at the given position. - * @param ptr pointer to the array. - * @param size the size of the array. - * @param index the position to insert the value at. - * @param value the value to insert. + * @brief Insert into the array constructing the new value in place. + * @tparam T The storage type of the array. + * @tparam ARGS Variadic pack of types to construct T with, the types of @p args. + * @param ptr Pointer to the array. + * @param size The size of the array. + * @param index The position to insert at. + * @param args The arguments to forward to construct the new value. */ DISABLE_HD_WARNING -template< typename T > +template< typename T, typename ... ARGS > LVARRAY_HOST_DEVICE inline -void insert( T * const LVARRAY_RESTRICT ptr, - std::ptrdiff_t const size, - std::ptrdiff_t const index, - T && value ) +void emplace( T * const LVARRAY_RESTRICT ptr, + std::ptrdiff_t const size, + std::ptrdiff_t const index, + ARGS && ... args ) { LVARRAY_ASSERT( ptr != nullptr ); LVARRAY_ASSERT( isPositive( size ) ); ARRAYMANIPULATION_CHECK_INSERT_BOUNDS( index ); + // Create space for the new value. shiftUp( ptr, size, index, std::ptrdiff_t( 1 ) ); - new ( ptr + index ) T( std::move( value ) ); + new ( ptr + index ) T( std::forward< ARGS >( args ) ... ); } /** - * @tparam T the storage type of the array. * @brief Insert the given values into the array at the given position. - * @param ptr pointer to the array. - * @param size the size of the array. - * @param index the position to insert the value at. - * @param values the values to insert. - * @param n the number of values to insert. + * @tparam T The storage type of the array. + * @tparam ITERATOR An iterator type, the type of @p first. + * @param ptr Pointer to the array. + * @param size The size of the array. + * @param index The position to insert the value at. + * @param first Iterator to the first value to insert. + * @param n The number of values to insert. */ DISABLE_HD_WARNING -template< typename T > +template< typename T, typename ITERATOR > LVARRAY_HOST_DEVICE inline void insert( T * const LVARRAY_RESTRICT ptr, std::ptrdiff_t const size, std::ptrdiff_t const index, - T const * const LVARRAY_RESTRICT values, + ITERATOR first, std::ptrdiff_t const n ) { LVARRAY_ASSERT( ptr != nullptr ); @@ -518,15 +452,16 @@ void insert( T * const LVARRAY_RESTRICT ptr, for( std::ptrdiff_t i = 0; i < n; ++i ) { - new ( ptr + index + i ) T( values[ i ] ); + new ( ptr + index + i ) T( *first ); + ++first; } } /** * @tparam T the storage type of the array. * @brief Destroy the value at the end of the array. - * @param ptr pointer to the array. - * @param size the size of the array. + * @param ptr Pointer to the array. + * @param size The size of the array. */ DISABLE_HD_WARNING template< typename T > diff --git a/src/bufferManipulation.hpp b/src/bufferManipulation.hpp index 0880e6db..aae23fcf 100644 --- a/src/bufferManipulation.hpp +++ b/src/bufferManipulation.hpp @@ -16,8 +16,7 @@ *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -#ifndef BUFFER_MANIPULATION_HPP_ -#define BUFFER_MANIPULATION_HPP_ +#pragma once // Source includes #include "LvArrayConfig.hpp" @@ -25,23 +24,52 @@ #include "templateHelpers.hpp" #include "arrayManipulation.hpp" -// TPL includes -#include - // System includes #include namespace LvArray { + +/** + * @enum MemorySpace + * @brief An enum containing the available memory spaces. + */ +enum class MemorySpace +{ + NONE + , CPU +#if defined(USE_CUDA) + , GPU +#endif +}; + +/** + * @brief Output a MemorySpace enum to a stream. + * @param os The output stream to write to. + * @param space The MemorySpace to output. + */ +inline std::ostream & operator<<( std::ostream & os, MemorySpace const space ) +{ + if( space == MemorySpace::NONE ) + os << "NONE"; + if( space == MemorySpace::CPU ) + os << "CPU"; +#if defined(USE_CUDA) + if( space == MemorySpace::GPU ) + os << "GPU"; +#endif + return os; +} + namespace bufferManipulation { /** * @brief Defines a static constexpr bool HasMemberFunction_move< @p CLASS > - * that is true iff the method @p CLASS ::move(chai::ExecutionSpace, bool) exists. + * that is true iff the method @p CLASS ::move(MemorySpace, bool) exists. * @tparam CLASS The type to test. */ -IS_VALID_EXPRESSION( HasMemberFunction_move, CLASS, std::declval< CLASS >().move( chai::CPU, true ) ); +IS_VALID_EXPRESSION( HasMemberFunction_move, CLASS, std::declval< CLASS >().move( MemorySpace::CPU, true ) ); /** * @class VoidBuffer @@ -59,11 +87,11 @@ struct VoidBuffer * @note The default behavior is that the Buffer can only exist on the CPU and an error * occurs if you try to move it to a different space. */ - void move( chai::ExecutionSpace const space, std::ptrdiff_t const size, bool const touch ) const + void move( MemorySpace const space, std::ptrdiff_t const size, bool const touch ) const { LVARRAY_UNUSED_VARIABLE( size ); LVARRAY_UNUSED_VARIABLE( touch ); - LVARRAY_ERROR_IF_NE_MSG( space, chai::CPU, "This Buffer type can only be used on the CPU." ); + LVARRAY_ERROR_IF_NE_MSG( space, MemorySpace::CPU, "This Buffer type can only be used on the CPU." ); } /** @@ -73,10 +101,10 @@ struct VoidBuffer * @note The default behavior is that the Buffer can only exist on the CPU and an error * occurs if you try to move it to a different space. */ - void move( chai::ExecutionSpace const space, bool const touch ) + void move( MemorySpace const space, bool const touch ) const { LVARRAY_UNUSED_VARIABLE( touch ); - LVARRAY_ERROR_IF_NE_MSG( space, chai::CPU, "This Buffer type can only be used on the CPU." ); + LVARRAY_ERROR_IF_NE_MSG( space, MemorySpace::CPU, "This Buffer type can only be used on the CPU." ); } /** @@ -85,8 +113,8 @@ struct VoidBuffer * @note The default behavior is that the Buffer can only exist on the CPU and an error * occurs if you try to move it to a different space. */ - void registerTouch( chai::ExecutionSpace const space ) - { LVARRAY_ERROR_IF_NE_MSG( space, chai::CPU, "This Buffer type can only be used on the CPU." ); } + void registerTouch( MemorySpace const space ) const + { LVARRAY_ERROR_IF_NE_MSG( space, MemorySpace::CPU, "This Buffer type can only be used on the CPU." ); } /** * @tparam The type of the owning object. @@ -105,7 +133,6 @@ struct VoidBuffer * @param buf the buffer to check. * @param size the size of the buffer. * @note This method is a no-op when USE_ARRAY_BOUNDS_CHECK is not defined. - * @note See MallocBuffer for the standard buffer interface. */ template< typename BUFFER > inline LVARRAY_HOST_DEVICE CONSTEXPR_WITHOUT_BOUNDS_CHECK @@ -128,7 +155,6 @@ void check( BUFFER const & buf, std::ptrdiff_t const size ) * @param size the size of the buffer. * @param pos the insertion position. * @note This method is a no-op when USE_ARRAY_BOUNDS_CHECK is not defined. - * @note See MallocBuffer for the standard buffer interface. */ template< typename BUFFER > inline @@ -150,7 +176,6 @@ void checkInsert( BUFFER const & buf, std::ptrdiff_t const size, std::ptrdiff_t * @tparam BUFFER the buffer type. * @param buf the buffer to free. * @param size the size of the buffer. - * @note See MallocBuffer for the standard buffer interface. */ DISABLE_HD_WARNING template< typename BUFFER > @@ -165,7 +190,7 @@ void free( BUFFER & buf, std::ptrdiff_t const size ) #if !defined(__CUDA_ARCH__ ) if( HasMemberFunction_move< T > ) { - buf.move( chai::CPU, size, true ); + buf.move( MemorySpace::CPU, size, true ); } #endif @@ -184,7 +209,6 @@ void free( BUFFER & buf, std::ptrdiff_t const size ) * @param buf the buffer to set the capacity of. * @param size the size of the buffer. * @param newCapacity the new capacity of the buffer. - * @note See MallocBuffer for the standard buffer interface. */ DISABLE_HD_WARNING template< typename BUFFER > @@ -201,7 +225,6 @@ void setCapacity( BUFFER & buf, std::ptrdiff_t const size, std::ptrdiff_t const * @param buf the buffer to reserve space in. * @param size the size of the buffer. * @param newCapacity the new minimum capacity of the buffer. - * @note See MallocBuffer for the standard buffer interface. */ template< typename BUFFER > LVARRAY_HOST_DEVICE @@ -217,14 +240,13 @@ void reserve( BUFFER & buf, std::ptrdiff_t const size, std::ptrdiff_t const newC /** * @brief If the buffer's capacity is greater than newCapacity this is a no-op. - * Otherwise the buffer's capacity is increased to at least 2 * newCapacity. + * Otherwise the buffer's capacity is increased to at least 2 * newCapacity. * @tparam BUFFER the buffer type. * @param buf the buffer to reserve space in. * @param size the size of the buffer. * @param newCapacity the new minimum capacity of the buffer. * @note Use this in methods which increase the size of the buffer to efficiently grow - * the capacity. - * @note See MallocBuffer for the standard buffer interface. + * the capacity. */ template< typename BUFFER > void dynamicReserve( BUFFER & buf, std::ptrdiff_t const size, std::ptrdiff_t const newCapacity ) @@ -246,8 +268,7 @@ void dynamicReserve( BUFFER & buf, std::ptrdiff_t const size, std::ptrdiff_t con * @param newSize the new size of the buffer. * @param args the arguments to initialize the new values with. * @note Use this in methods which increase the size of the buffer to efficiently grow - * the capacity. - * @note See MallocBuffer for the standard buffer interface. + * the capacity. */ template< typename BUFFER, typename ... ARGS > LVARRAY_HOST_DEVICE @@ -262,121 +283,69 @@ void resize( BUFFER & buf, std::ptrdiff_t const size, std::ptrdiff_t const newSi #if !defined(__CUDA_ARCH__) if( newSize > 0 ) { - buf.registerTouch( chai::CPU ); + buf.registerTouch( MemorySpace::CPU ); } #endif } -/** - * @brief Append a value to the end of the buffer. - * @tparam BUFFER the buffer type. - * @param buf the buffer to append to. - * @param size the current size of the buffer. - * @param value the value to append via a copy. - * @note See MallocBuffer for the standard buffer interface. - */ -template< typename BUFFER > -void pushBack( BUFFER & buf, std::ptrdiff_t const size, typename BUFFER::value_type const & value ) -{ - check( buf, size ); - - dynamicReserve( buf, size, size + 1 ); - arrayManipulation::append( buf.data(), size, value ); -} -/** - * @brief Append a value to the end of the buffer. - * @tparam BUFFER the buffer type. - * @param buf the buffer to append to. - * @param size the current size of the buffer. - * @note See MallocBuffer for the standard buffer interface. - */ -template< typename BUFFER > -void pushBack( BUFFER & buf, std::ptrdiff_t const size, typename BUFFER::value_type && value ) +template< typename BUFFER, typename ... ARGS > +void emplaceBack( BUFFER & buf, std::ptrdiff_t const size, ARGS && ... args ) { check( buf, size ); dynamicReserve( buf, size, size + 1 ); - arrayManipulation::append( buf.data(), size, std::move( value ) ); + arrayManipulation::emplaceBack( buf.data(), size, std::forward< ARGS >( args ) ... ); } -/** - * @brief Remove a value from the end of the buffer. - * @tparam BUFFER the buffer type. - * @param buf the buffer to remove from. - * @param size the current size of the buffer. - * @note See MallocBuffer for the standard buffer interface. - */ -template< typename BUFFER > -void popBack( BUFFER & buf, std::ptrdiff_t const size ) -{ - check( buf, size ); - arrayManipulation::popBack( buf.data(), size ); -} - -/** - * @brief Insert a value into the buffer. - * @tparam BUFFER the buffer type. - * @param buf the buffer to insert into. - * @param size the current size of the buffer. - * @param pos the position to insert the value at. - * @param value the value to insert via a copy. - * @note See MallocBuffer for the standard buffer interface. - */ -template< typename BUFFER > -void insert( BUFFER & buf, - std::ptrdiff_t const size, - std::ptrdiff_t const pos, - typename BUFFER::value_type const & value ) +template< typename BUFFER, typename ... ARGS > +void emplace( BUFFER & buf, + std::ptrdiff_t const size, + std::ptrdiff_t const pos, + ARGS && ... args ) { checkInsert( buf, size, pos ); dynamicReserve( buf, size, size + 1 ); - arrayManipulation::insert( buf.data(), size, pos, value ); + arrayManipulation::emplace( buf.data(), size, pos, std::forward< ARGS >( args ) ... ); } /** - * @brief Insert a value into the buffer. + * @brief Insert multiple values into the buffer. * @tparam BUFFER the buffer type. * @param buf the buffer to insert into. * @param size the current size of the buffer. - * @param pos the position to insert the value at. - * @param value the value to insert via a move. - * @note See MallocBuffer for the standard buffer interface. + * @param pos the position to insert the values at. + * @param values a pointer to the values to insert via a copy. + * @param nVals the number of values to insert. + * @return The number of values inserted. */ -template< typename BUFFER > -void insert( BUFFER & buf, - std::ptrdiff_t const size, - std::ptrdiff_t const pos, - typename BUFFER::value_type && value ) +template< typename BUFFER, typename ITERATOR > +std::ptrdiff_t insert( BUFFER & buf, + std::ptrdiff_t const size, + std::ptrdiff_t const pos, + ITERATOR const first, + ITERATOR const last ) { checkInsert( buf, size, pos ); - dynamicReserve( buf, size, size + 1 ); - arrayManipulation::insert( buf.data(), size, pos, std::move( value ) ); + std::ptrdiff_t const nVals = iterDistance( first, last ); + dynamicReserve( buf, size, size + nVals ); + arrayManipulation::insert( buf.data(), size, pos, first, nVals ); + return nVals; } /** - * @brief Insert multiple values into the buffer. + * @brief Remove a value from the end of the buffer. * @tparam BUFFER the buffer type. - * @param buf the buffer to insert into. + * @param buf the buffer to remove from. * @param size the current size of the buffer. - * @param pos the position to insert the values at. - * @param values a pointer to the values to insert via a copy. - * @param nVals the number of values to insert. - * @note See MallocBuffer for the standard buffer interface. */ template< typename BUFFER > -void insert( BUFFER & buf, - std::ptrdiff_t const size, - std::ptrdiff_t const pos, - typename BUFFER::value_type const * const values, - std::ptrdiff_t nVals ) +void popBack( BUFFER & buf, std::ptrdiff_t const size ) { - checkInsert( buf, size, pos ); - - dynamicReserve( buf, size, size + nVals ); - arrayManipulation::insert( buf.data(), size, pos, values, nVals ); + check( buf, size ); + arrayManipulation::popBack( buf.data(), size ); } /** @@ -385,7 +354,6 @@ void insert( BUFFER & buf, * @param buf the buffer to erase from. * @param size the current size of the buffer. * @param pos the position to erase. - * @note See MallocBuffer for the standard buffer interface. */ template< typename BUFFER > void erase( BUFFER & buf, std::ptrdiff_t const size, std::ptrdiff_t const pos ) @@ -430,5 +398,3 @@ void copyInto( DST_BUFFER & dst, } // namespace bufferManipulations } // namespace LvArray - -#endif /* BUFFER_MANIPULATION_HPP_ */ diff --git a/src/sortedArrayManipulation.hpp b/src/sortedArrayManipulation.hpp index 383604c8..46ada8d2 100644 --- a/src/sortedArrayManipulation.hpp +++ b/src/sortedArrayManipulation.hpp @@ -646,7 +646,7 @@ bool insert( T * const LVARRAY_RESTRICT ptr, // Otherwise call the incrementSize callback, get the new pointer, insert and call the insert callback. T * const newPtr = callBacks.incrementSize( ptr, 1 ); - arrayManipulation::insert( newPtr, size, insertPos, value ); + arrayManipulation::emplace( newPtr, size, insertPos, value ); callBacks.insert( insertPos ); return true; } diff --git a/src/sortedArrayManipulationHelpers.hpp b/src/sortedArrayManipulationHelpers.hpp index 8361e681..bc596dc4 100644 --- a/src/sortedArrayManipulationHelpers.hpp +++ b/src/sortedArrayManipulationHelpers.hpp @@ -103,7 +103,10 @@ struct DualIteratorAccessor */ inline Temporary & operator=( Temporary && ) = delete; + /// A copy of type A. A m_a; + + /// A copy of type B. B m_b; }; @@ -163,7 +166,10 @@ struct DualIteratorAccessor return *this; } + /// A reference to the first value. A & m_a; + + /// A reference to the second value. B & m_b; }; @@ -175,7 +181,7 @@ struct DualIteratorAccessor * @brief This class is used to make a comparison method that takes in DualIteratorAccessor from * a comparison method that takes in objects of type A. */ -template< class A, class B, class Compare > +template< typename A, typename B, typename Compare > struct DualIteratorComparator { /** @@ -208,6 +214,7 @@ struct DualIteratorComparator { return m_compare( lhs.m_a, rhs.m_a ); } private: + /// The comparator that compares objects of type A. Compare m_compare; }; @@ -220,13 +227,12 @@ struct DualIteratorComparator template< class RandomAccessIteratorA, class RandomAccessIteratorB > class DualIterator { -private: - RandomAccessIteratorA m_itA; - RandomAccessIteratorB m_itB; - public: - using A = typename std::remove_reference< decltype(*m_itA) >::type; - using B = typename std::remove_reference< decltype(*m_itB) >::type; + /// An alias for the type pointed to by RandomAccessIteratorA. + using A = typename std::remove_reference< decltype( *std::declval< RandomAccessIteratorA >() ) >::type; + + /// An alias for the type pointed to by RandomAccessIteratorB. + using B = typename std::remove_reference< decltype( *std::declval< RandomAccessIteratorB >() ) >::type; /** * @brief Default constructor. @@ -371,6 +377,14 @@ class DualIterator template< class Compare > LVARRAY_HOST_DEVICE inline DualIteratorComparator< A, B, Compare > createComparator( Compare comp ) const LVARRAY_RESTRICT_THIS { return DualIteratorComparator< A, B, Compare >( comp ); } + +private: + /// The first iterator. + RandomAccessIteratorA m_itA; + + /// The second iterator. + RandomAccessIteratorB m_itB; + }; /** diff --git a/src/stackTrace.cpp b/src/stackTrace.cpp index fd9acbce..494a3733 100644 --- a/src/stackTrace.cpp +++ b/src/stackTrace.cpp @@ -149,6 +149,7 @@ std::string stackTrace( ) return ( oss.str() ); } +/// @return Return a string representing the current floating point exception. std::string getFpeDetails() { std::ostringstream oss; diff --git a/src/streamIO.hpp b/src/streamIO.hpp index 903d0252..3b1ee836 100644 --- a/src/streamIO.hpp +++ b/src/streamIO.hpp @@ -67,7 +67,7 @@ struct stringToArrayHelper INDEX_TYPE const *, std::istringstream & inputStream ) { - inputStream>>arrayValue; + inputStream >> arrayValue; LVARRAY_ERROR_IF( inputStream.fail(), "Invalid value of type " << typeid(T).name() << " in: " << @@ -124,11 +124,10 @@ template< typename T, int NDIM, typename PERMUTATION, typename INDEX_TYPE, - template< typename > class DATA_VECTOR_TYPE > -static void stringToArray( Array< T, NDIM, PERMUTATION, INDEX_TYPE, DATA_VECTOR_TYPE > & array, + template< typename > class BUFFER_TYPE > +static void stringToArray( Array< T, NDIM, PERMUTATION, INDEX_TYPE, BUFFER_TYPE > & array, std::string valueString ) { - // Check to make sure there are no space delimited values. The assumption is anything that is not // a '{' or '}' or ',' or ' ' is part of a value. Loope over the string and keep track of whether // or not there is a value on the left of the char. If there is a value to the left, with a space @@ -354,8 +353,9 @@ std::ostream & operator<<( std::ostream & stream, * @param view The SortedArrayView to output. * @return @p stream . */ -template< typename T, typename INDEX_TYPE > -std::ostream & operator<< ( std::ostream & stream, SortedArrayView< T const, INDEX_TYPE > const & view ) +template< typename T, typename INDEX_TYPE, template< typename > class BUFFER_TYPE > +std::ostream & operator<< ( std::ostream & stream, + SortedArrayView< T const, INDEX_TYPE, BUFFER_TYPE > const & view ) { if( view.size() == 0 ) { @@ -385,8 +385,9 @@ std::ostream & operator<< ( std::ostream & stream, SortedArrayView< T const, IND * @param array The SortedArray to output. * @return @p stream . */ -template< typename T, typename INDEX_TYPE > -std::ostream & operator<< ( std::ostream & stream, SortedArray< T, INDEX_TYPE > const & array ) +template< typename T, typename INDEX_TYPE, template< typename > class BUFFER_TYPE > +std::ostream & operator<< ( std::ostream & stream, + SortedArray< T, INDEX_TYPE, BUFFER_TYPE > const & array ) { return stream << array.toViewConst(); } /** @@ -397,8 +398,9 @@ std::ostream & operator<< ( std::ostream & stream, SortedArray< T, INDEX_TYPE > * @param view The ArrayOfArraysView to output. * @return @p stream . */ -template< typename T, typename INDEX_TYPE > -std::ostream & operator<< ( std::ostream & stream, ArrayOfArraysView< T const, INDEX_TYPE const, true > const & view ) +template< typename T, typename INDEX_TYPE, template< typename > class BUFFER_TYPE > +std::ostream & operator<< ( std::ostream & stream, + ArrayOfArraysView< T const, INDEX_TYPE const, true, BUFFER_TYPE > const & view ) { stream << "{" << std::endl; @@ -430,8 +432,9 @@ std::ostream & operator<< ( std::ostream & stream, ArrayOfArraysView< T const, I * @param array The ArrayOfArrays to output. * @return @p stream . */ -template< typename T, typename INDEX_TYPE, bool CONST_SIZES > -std::ostream & operator<< ( std::ostream & stream, ArrayOfArrays< T, INDEX_TYPE > const & array ) +template< typename T, typename INDEX_TYPE, template< typename > class BUFFER_TYPE > +std::ostream & operator<< ( std::ostream & stream, + ArrayOfArrays< T, INDEX_TYPE, BUFFER_TYPE > const & array ) { return stream << array.toViewConst(); } /** diff --git a/src/tensorOps.hpp b/src/tensorOps.hpp index 58f21a7c..99953298 100644 --- a/src/tensorOps.hpp +++ b/src/tensorOps.hpp @@ -99,6 +99,7 @@ namespace tensorOps namespace internal { +/// The size of a symmetric MxM matrix in Voigt notation. template< int M > constexpr std::ptrdiff_t SYM_SIZE = ( M * ( M + 1 ) ) / 2; @@ -350,6 +351,10 @@ struct SquareMatrixOps }; +/** + * @struct SquareMatrixOps< 2 > + * @brief Performs operations on 2x2 square matrices. + */ template<> struct SquareMatrixOps< 2 > { @@ -537,6 +542,10 @@ struct SquareMatrixOps< 2 > } }; +/** + * @struct SquareMatrixOps< 3 > + * @brief Performs operations on 3x3 square matrices. + */ template<> struct SquareMatrixOps< 3 > { diff --git a/unitTests/CMakeLists.txt b/unitTests/CMakeLists.txt index 40dd5103..f717c597 100644 --- a/unitTests/CMakeLists.txt +++ b/unitTests/CMakeLists.txt @@ -2,11 +2,48 @@ # Specify list of tests # set(testSources - testArray.cpp + testArray_defaultConstructor.cpp + testArray_sizedConstructor.cpp + testArray_copyConstructor.cpp + testArray_moveConstructor.cpp + testArray_toView.cpp + testArray_toViewConst.cpp + testArray_copyAssignmentOperator.cpp + testArray_moveAssignmentOperator.cpp + testArray_scalarAssignmentOperator.cpp + testArray_getSetSingleParameterResizeIndex.cpp + testArray_resizeFromPointer.cpp + testArray_resizeFromArgs.cpp + testArray_resizeDimension.cpp + testArray_resize.cpp + testArray_resizeDefault.cpp + testArray_reserveAndCapacity.cpp + testArray_clear.cpp + testArray_indexing.cpp + testArray_resizeWithoutInitializationOrDestruction.cpp + testArray1D.cpp + testArrayView_defaultConstructor.cpp + testArrayView_copyConstructor.cpp + testArrayView_copyAssignmentOperator.cpp + testArrayView_toView.cpp + testArrayView_toViewConst.cpp + testArrayView_udcToViewConst.cpp + testArrayView_toSlice.cpp + testArrayView_udcToSlice.cpp + testArrayView_toSliceConst.cpp + testArrayView_udcToSliceConst.cpp + testArrayView_modifyInKernel.cpp + testArrayView_readInKernel.cpp + testArrayView_move.cpp + testArrayView_moveNoTouch.cpp + testArrayView_modifyInMultipleKernels.cpp + testArrayView_moveMultipleTimes.cpp + testArrayView_emptyMove.cpp + testArray1DOfArray1D.cpp + testArray1DOfArray1DOfArray1D.cpp testArrayOfArrays.cpp testArrayOfSets.cpp testArrayUtilities.cpp - testArrayView.cpp testArraySlice.cpp testCRSMatrix.cpp testArrayHelpers.cpp @@ -49,7 +86,7 @@ target_include_directories( testFloatingPointExceptions PUBLIC ${CMAKE_CURRENT_L blt_add_test( NAME testFloatingPointExceptions COMMAND testFloatingPointExceptions ) -# Add testTensorOpsThreeSizes which has multiple translation units to speed up compilation. +# Add testTensorOps which has multiple translation units to speed up compilation. blt_add_executable( NAME testTensorOps SOURCES testTensorOps.cpp testTensorOpsNoSize.cpp @@ -65,7 +102,6 @@ blt_add_executable( NAME testTensorOps testTensorOpsThreeSizes4.cpp testTensorOpsThreeSizes5.cpp testTensorOpsThreeSizes6.cpp - OUTPUT_DIR ${TEST_OUTPUT_DIRECTORY} DEPENDS_ON gtest lvarray ${lvarray_dependencies} ) diff --git a/unitTests/testArray.cpp b/unitTests/testArray.cpp deleted file mode 100644 index 3d17bb6e..00000000 --- a/unitTests/testArray.cpp +++ /dev/null @@ -1,1451 +0,0 @@ -/* - *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * Copyright (c) 2019, Lawrence Livermore National Security, LLC. - * - * Produced at the Lawrence Livermore National Laboratory - * - * LLNL-CODE-746361 - * - * All rights reserved. See COPYRIGHT for details. - * - * This file is part of the GEOSX Simulation Framework. - * - * GEOSX is a free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (as published by the - * Free Software Foundation) version 2.1 dated February 1999. - *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - */ - -// Source includes -#include "Array.hpp" -#include "testUtils.hpp" - -// TPL includes -#include - -// System includes -#include - -namespace LvArray -{ -namespace testing -{ - -using INDEX_TYPE = std::ptrdiff_t; - -template< typename T > -using array = Array< T, 1 >; - -template< typename T > -using array2D = Array< T, 2 >; - -template< typename T > -using arrayView = ArrayView< T, 1 >; - -template< typename T > -using arrayView2D = ArrayView< T, 2 >; - -/** - * @brief Check that the Array is equivalent to the std::vector. Checks equality using the - * operator[], operator(), the iterator interface and the raw pointer. - * @param [in] v the Array to check. - * @param [in] v_ref the std::vector to check against. - */ -template< class T > -void compare_to_reference( const array< T > & v, const std::vector< T > & v_ref ) -{ - ASSERT_EQ( v.size(), v_ref.size() ); - ASSERT_EQ( v.empty(), v_ref.empty() ); - if( v.empty() ) - { - ASSERT_EQ( v.size(), 0 ); - return; - } - - for( INDEX_TYPE i = 0; i < v.size(); ++i ) - { - ASSERT_EQ( v[ i ], v_ref[ i ] ); - ASSERT_EQ( v( i ), v_ref[ i ] ); - } - - const T * v_ptr = v.data(); - const T * ref_ptr = v_ref.data(); - for( INDEX_TYPE i = 0; i < v.size(); ++i ) - { - ASSERT_EQ( v_ptr[ i ], ref_ptr[ i ] ); - } -} - -/** - * @brief Check that the Array is equivalent to the std::vector. Checks equality using the - * operator[], operator(), the iterator interface and the raw pointer. - * @param [in] v the Array to check. - * @param [in] v_ref the std::vector to check against. - */ -template< class T > -void compare_to_reference( const array< array< T > > & v, - const std::vector< std::vector< T > > & v_ref ) -{ - ASSERT_EQ( v.size(), v_ref.size() ); - ASSERT_EQ( v.empty(), v_ref.empty() ); - if( v.empty() ) - { - ASSERT_EQ( v.size(), 0 ); - return; - } - - for( INDEX_TYPE i = 0; i < v.size(); ++i ) - { - compare_to_reference( v[ i ], v_ref[ i ] ); - } -} - -template< class T > -void compare_to_view( array< T > const & v, arrayView< T > const & v_view ) -{ - ASSERT_EQ( v.size(), v_view.size() ); - ASSERT_EQ( v.empty(), v_view.empty() ); - if( v.empty() ) - { - ASSERT_EQ( v.size(), 0 ); - return; - } - - for( INDEX_TYPE i = 0; i < v.size(); ++i ) - { - ASSERT_EQ( v[ i ], v_view[ i ] ); - ASSERT_EQ( v( i ), v_view( i ) ); - } - - const T * v_ptr = v.data(); - const T * ref_ptr = v_view.data(); - for( INDEX_TYPE i = 0; i < v.size(); ++i ) - { - ASSERT_EQ( v_ptr[ i ], ref_ptr[ i ] ); - } -} - -template< class T > -void compare_to_view( array2D< T > const & v, arrayView2D< T > const & v_view ) -{ - ASSERT_EQ( v.size(), v_view.size() ); - ASSERT_EQ( v.size( 0 ), v_view.size( 0 ) ); - ASSERT_EQ( v.size( 1 ), v_view.size( 1 ) ); - ASSERT_EQ( v.empty(), v_view.empty() ); - if( v.empty() ) - { - ASSERT_EQ( v.size(), 0 ); - return; - } - - INDEX_TYPE pos = 0; - const T * v_ptr = v.data(); - const T * ref_ptr = v_view.data(); - for( INDEX_TYPE i = 0; i < v.size( 0 ); ++i ) - { - const T * v_ptr_cur = v.data(); - const T * ref_ptr_cur = v_view.data(); - for( INDEX_TYPE j = 0; j < v.size( 1 ); ++j ) - { - ASSERT_EQ( v[ i ][ j ], v_view[ i ][ j ] ); - ASSERT_EQ( v( i, j ), v_view( i, j ) ); - ASSERT_EQ( v_ptr[ pos ], ref_ptr[ pos ] ); - ASSERT_EQ( v_ptr_cur[ j ], ref_ptr_cur[ j ] ); - ++pos; - } - } -} - - -template< class T > -void create_2D_test( array2D< T > & v, INDEX_TYPE N, INDEX_TYPE M ) -{ - EXPECT_TRUE( v.empty() ); - - v.resize( N, M ); - EXPECT_EQ( v.size(), N * M ); - EXPECT_EQ( v.size( 0 ), N ); - EXPECT_EQ( v.size( 1 ), M ); - - INDEX_TYPE pos = 0; - for( INDEX_TYPE i = 0; i < N; ++i ) - { - for( INDEX_TYPE j = 0; j < M; ++j ) - { - v[i][j] = T( pos ); - pos++; - } - } - - pos = 0; - T const * data_ptr = v.data(); - for( INDEX_TYPE i = 0; i < N; ++i ) - { - for( INDEX_TYPE j = 0; j < M; ++j ) - { - const T value = T( pos ); - EXPECT_EQ( v[i][j], value ); - EXPECT_EQ( v( i, j ), value ); - EXPECT_EQ( data_ptr[ pos ], value ); - ++pos; - } - } -} - -/** - * @brief Test the push_back method of the Array. - * @param [in/out] v the Array to check. - * @param [in] n the number of values to append. - * @return the std::vector compared against. - */ -template< class T > -std::vector< T > push_back_test( array< T > & v, INDEX_TYPE n ) -{ - EXPECT_TRUE( v.empty() ); - - std::vector< T > v_ref; - for( INDEX_TYPE i = 0; i < n; ++i ) - { - const T & val = T( i ); - v.push_back( val ); - v_ref.push_back( val ); - } - - compare_to_reference( v, v_ref ); - return v_ref; -} - -/** - * @brief Test the push_back method of the Array. - * @param [in/out] v the Array to check. - * @param [in] n the number of values to append. - * @return the std::vector compared against. - */ -template< class T > -std::vector< std::vector< T > > -push_back_array_test( array< array< T > > & v, INDEX_TYPE n, INDEX_TYPE m ) -{ - EXPECT_TRUE( v.empty() ); - - std::vector< std::vector< T > > v_ref; - array< T > v_append( m ); - std::vector< T > v_ref_append( m ); - for( INDEX_TYPE i = 0; i < n; ++i ) - { - for( INDEX_TYPE j = 0; j < m; ++j ) - { - const T val = T( m * i + j ); - v_append[ j ] = val; - v_ref_append[ j ] = val; - } - - v.push_back( v_append ); - v_ref.push_back( v_ref_append ); - } - - compare_to_reference( v, v_ref ); - return v_ref; -} - -/** - * @brief Test the insert method of the ChaiVector by inserting multiple values at once. - * @param [in/out] v the ChaiVector to check. - * @param [in] n the number of insertions to do. - * @param [in] m the number of values to insert per iteration. - * @return the std::vector compared against. - */ -template< class T > -std::vector< T > insert_test( array< T > & v, INDEX_TYPE n, INDEX_TYPE m ) -{ - EXPECT_TRUE( v.empty() ); - - std::vector< T > v_ref; - std::vector< T > v_insert( m ); - for( INDEX_TYPE i = 0; i < n; ++i ) - { - for( INDEX_TYPE j = 0; j < m; ++j ) - { - v_insert[ j ] = T( m * i + j ); - } - - if( i % 3 == 0 ) /* Insert at the beginning. */ - { - v.insert( 0, v_insert.data(), v_insert.size() ); - v_ref.insert( v_ref.begin(), v_insert.begin(), v_insert.end() ); - } - else if( i % 3 == 1 ) /* Insert at the end. */ - { - v.insert( v.size(), v_insert.data(), v_insert.size() ); - v_ref.insert( v_ref.end(), v_insert.begin(), v_insert.end() ); - } - else /* Insert in the middle. */ - { - v.insert( v.size() / 2, v_insert.data(), v_insert.size() ); - v_ref.insert( v_ref.begin() + v_ref.size() / 2, v_insert.begin(), v_insert.end() ); - } - } - - compare_to_reference( v, v_ref ); - return v_ref; -} - -/** - * @brief Test the insert method of the ChaiVector by inserting multiple values at once. - * @param [in/out] v the ChaiVector to check. - * @param [in] n the number of insertions to do. - * @param [in] m the number of values to insert per iteration. - * @return the std::vector compared against. - */ -template< class T > -std::vector< std::vector< T > > -insert_array_test( array< array< T > > & v, INDEX_TYPE n, INDEX_TYPE m, INDEX_TYPE p ) -{ - EXPECT_TRUE( v.empty() ); - - std::vector< std::vector< T > > v_ref; - array< array< T > > v_insert; - std::vector< std::vector< T > > v_ref_insert; - for( INDEX_TYPE i = 0; i < n; ++i ) - { - v_insert.clear(); - v_ref_insert.clear(); - - for( INDEX_TYPE j = 0; j < m; ++j ) - { - array< T > temp( p ); - std::vector< T > temp_ref( p ); - for( INDEX_TYPE k = 0; k < p; ++k ) - { - const T val = T( m * p * i + p * j + k ); - temp[ k ] = val; - temp_ref[ k ] = val; - } - v_insert.push_back( temp ); - v_ref_insert.push_back( temp_ref ); - } - - if( i % 3 == 0 ) /* Insert at the beginning. */ - { - v.insert( 0, v_insert.data(), v_insert.size() ); - v_ref.insert( v_ref.begin(), v_ref_insert.begin(), v_ref_insert.end() ); - } - else if( i % 3 == 1 ) /* Insert at the end. */ - { - v.insert( v.size(), v_insert.data(), v_insert.size() ); - v_ref.insert( v_ref.end(), v_ref_insert.begin(), v_ref_insert.end() ); - } - else /* Insert in the middle. */ - { - v.insert( v.size() / 2, v_insert.data(), v_insert.size() ); - v_ref.insert( v_ref.begin() + v_ref.size() / 2, v_ref_insert.begin(), v_ref_insert.end() ); - } - } - compare_to_reference( v, v_ref ); - return v_ref; -} - -/** - * @brief Test the erase method of the ChaiVector. - * @param [in/out] v the ChaiVector to check. - * @param [in] v_ref the std::vector to compare against. - */ -template< class T, class U > -void erase_test( array< T > & v, std::vector< U > & v_ref ) -{ - const INDEX_TYPE n_elems = v.size(); - for( INDEX_TYPE i = 0; i < n_elems; ++i ) - { - if( i % 3 == 0 ) /* erase the beginning. */ - { - v.erase( 0 ); - v_ref.erase( v_ref.begin() ); - } - else if( i % 3 == 1 ) /* erase at the end. */ - { - v.erase( v.size() - 1 ); - v_ref.erase( v_ref.end() - 1 ); - } - else /* erase the middle. */ - { - v.erase( v.size() / 2 ); - v_ref.erase( v_ref.begin() + v_ref.size() / 2 ); - } - - if( i % 10 == 0 ) - { - compare_to_reference( v, v_ref ); - } - } - - ASSERT_TRUE( v.empty() ); - compare_to_reference( v, v_ref ); -} - -/** - * @brief Test the pop_back method of the ChaiVector. - * @param [in/out] v the ChaiVector to check. - * @param [in] v_ref the std::vector to compare against. - */ -template< class T, class U > -void pop_back_test( array< T > & v, std::vector< U > & v_ref ) -{ - const INDEX_TYPE n_elems = v.size(); - for( INDEX_TYPE i = 0; i < n_elems; ++i ) - { - v.pop_back(); - v_ref.pop_back(); - - if( i % 10 == 0 ) - { - compare_to_reference( v, v_ref ); - } - } - - ASSERT_TRUE( v.empty() ); - compare_to_reference( v, v_ref ); -} - -/** - * @brief Test the resize method of the Array. - * @param [in/out] v the Array to check. - * @param [in] n the end size of the vector. - */ -template< class T > -void resize_test( array< T > & v, INDEX_TYPE const n ) -{ - ASSERT_TRUE( v.empty() ); - - v.resize( n / 2 ); - - ASSERT_EQ( v.size(), n / 2 ); - ASSERT_EQ( v.capacity(), n / 2 ); - - T * data_ptr = v.data(); - for( INDEX_TYPE i = 0; i < n / 2; ++i ) - { - ASSERT_EQ( data_ptr[ i ], T() ); - const T val = T( i ); - data_ptr[ i ] = val; - } - - /* No reallocation should have occurred. */ - ASSERT_EQ( data_ptr, v.data() ); - - v.resize( n / 4 ); - - ASSERT_EQ( v.size(), n / 4 ); - ASSERT_EQ( v.capacity(), n / 2 ); - - for( INDEX_TYPE i = 0; i < n / 4; ++i ) - { - ASSERT_EQ( v[ i ], T( i ) ); - } - - v.resize( n ); - - ASSERT_EQ( v.size(), n ); - ASSERT_EQ( v.capacity(), n ); - - for( INDEX_TYPE i = 0; i < n; ++i ) - { - const T val = T( 2 * i ); - v[ i ] = val; - } - - for( INDEX_TYPE i = 0; i < n; ++i ) - { - ASSERT_EQ( v[ i ], T( 2 * i ) ); - } -} - -template< class T > -void resizeNoInitOrDestroy_test( array< T > & v, INDEX_TYPE n ) -{ - ASSERT_TRUE( v.empty() ); - - v.resizeWithoutInitializationOrDestruction( n / 2 ); - - ASSERT_EQ( v.size(), n / 2 ); - ASSERT_EQ( v.capacity(), n / 2 ); - - T * data_ptr = v.data(); - for( INDEX_TYPE i = 0; i < n / 2; ++i ) - { - const T val = T( i ); - data_ptr[ i ] = val; - } - - // No reallocation should have occurred. - ASSERT_EQ( data_ptr, v.data() ); - - v.resizeWithoutInitializationOrDestruction( n / 4 ); - - ASSERT_EQ( v.size(), n / 4 ); - ASSERT_EQ( v.capacity(), n / 2 ); - - for( INDEX_TYPE i = 0; i < n / 4; ++i ) - { - ASSERT_EQ( v[ i ], T( i ) ); - } - - v.resizeWithoutInitializationOrDestruction( n ); - - ASSERT_EQ( v.size(), n ); - ASSERT_EQ( v.capacity(), n ); - - for( INDEX_TYPE i = 0; i < n; ++i ) - { - const T val = T( 2 * i ); - v[ i ] = val; - } - - for( INDEX_TYPE i = 0; i < n; ++i ) - { - ASSERT_EQ( v[ i ], T( 2 * i ) ); - } -} - -/** - * @brief Test the resize method of the Array. - * @param [in/out] v the Array to check. - * @param [in] n the end size of the vector. - */ -template< class T > -void resize_array_test( array< array< T > > & v, INDEX_TYPE n, INDEX_TYPE m ) -{ - ASSERT_TRUE( v.empty() ); - - v.resize( n / 2 ); - - ASSERT_EQ( v.size(), n / 2 ); - ASSERT_EQ( v.capacity(), n / 2 ); - - array< T > * data_ptr = v.data(); - for( INDEX_TYPE i = 0; i < n / 2; ++i ) - { - for( INDEX_TYPE j = 0; j < m; ++j ) - { - data_ptr[ i ].push_back( T( m * i + j ) ); - } - } - - /* No reallocation should have occured. */ - ASSERT_EQ( data_ptr, v.data() ); - - v.resize( n / 4 ); - - ASSERT_EQ( v.size(), n / 4 ); - ASSERT_EQ( v.capacity(), n / 2 ); - - for( INDEX_TYPE i = 0; i < n / 4; ++i ) - { - for( INDEX_TYPE j = 0; j < m; ++j ) - { - ASSERT_EQ( v[ i ][ j ], T( m * i + j ) ); - } - } - - v.resize( n ); - - ASSERT_EQ( v.size(), n ); - ASSERT_EQ( v.capacity(), n ); - - for( INDEX_TYPE i = 0; i < n / 4; ++i ) - { - for( INDEX_TYPE j = 0; j < m; ++j ) - { - v[ i ][ j ] = T( 2 * ( m * i + j ) ); - } - } - - for( INDEX_TYPE i = n / 4; i < n; ++i ) - { - for( INDEX_TYPE j = 0; j < m; ++j ) - { - v[ i ].push_back( T( 2 * ( m * i + j ) ) ); - } - } - - for( INDEX_TYPE i = 0; i < n; ++i ) - { - ASSERT_EQ( v[ i ].size(), m ); - for( INDEX_TYPE j = 0; j < m; ++j ) - { - ASSERT_EQ( v[ i ][ j ], T( 2 * ( m * i + j ) ) ); - } - } -} - -/** - * @brief Test the reserve method of the ChaiVector. - * @param [in/out] v the ChaiVector to check. - * @param [in] n the end size of the vector. - */ -template< class T > -void reserve_test( array< T > & v, INDEX_TYPE n ) -{ - ASSERT_TRUE( v.empty() ); - - v.reserve( n / 2 ); - - ASSERT_EQ( v.size(), 0 ); - ASSERT_EQ( v.capacity(), n / 2 ); - - T * data_ptr = v.data(); - for( INDEX_TYPE i = 0; i < n / 2; ++i ) - { - v.push_back( T( i ) ); - } - - /* No reallocation should have occured. */ - ASSERT_EQ( data_ptr, v.data() ); - - v.reserve( n ); - - ASSERT_EQ( v.size(), n / 2 ); - ASSERT_EQ( v.capacity(), n ); - - for( INDEX_TYPE i = 0; i < n / 2; ++i ) - { - ASSERT_EQ( v[ i ], T( i ) ); - } - - data_ptr = v.data(); - for( INDEX_TYPE i = n / 2; i < n; ++i ) - { - v.push_back( T ( i ) ); - } - - /* No reallocation should have occured. */ - ASSERT_EQ( data_ptr, v.data() ); - - for( INDEX_TYPE i = 0; i < n; ++i ) - { - ASSERT_EQ( v[ i ], T( i ) ); - } -} - -/** - * @brief Test the reserve method of the ChaiVector. - * @param [in/out] v the ChaiVector to check. - * @param [in] n the end size of the vector. - */ -template< class T > -void reserve_array_test( array< array< T > > & v, INDEX_TYPE n, INDEX_TYPE m ) -{ - ASSERT_TRUE( v.empty() ); - - v.reserve( n / 2 ); - - ASSERT_EQ( v.size(), 0 ); - ASSERT_EQ( v.capacity(), n / 2 ); - - array< T > * data_ptr = v.data(); - for( INDEX_TYPE i = 0; i < n / 2; ++i ) - { - array< T > temp( m ); - for( INDEX_TYPE j = 0; j < m; ++j ) - { - temp[ j ] = T( m * i + j ); - } - - v.push_back( temp ); - } - - /* No reallocation should have occured. */ - ASSERT_EQ( data_ptr, v.data() ); - - v.reserve( n ); - - ASSERT_EQ( v.size(), n / 2 ); - ASSERT_EQ( v.capacity(), n ); - - for( INDEX_TYPE i = 0; i < n / 2; ++i ) - { - for( INDEX_TYPE j = 0; j < m; ++j ) - { - ASSERT_EQ( v[ i ][ j ], T( m * i + j ) ); - } - } - - data_ptr = v.data(); - for( INDEX_TYPE i = n / 2; i < n; ++i ) - { - array< T > temp( m ); - for( INDEX_TYPE j = 0; j < m; ++j ) - { - temp[ j ] = T( m * i + j ); - } - - v.push_back( temp ); - } - - /* No reallocation should have occured. */ - ASSERT_EQ( data_ptr, v.data() ); - - for( INDEX_TYPE i = 0; i < n; ++i ) - { - for( INDEX_TYPE j = 0; j < m; ++j ) - { - ASSERT_EQ( v[ i ][ j ], T( m * i + j ) ); - } - } -} - -/** - * @brief Test the deep_copy method of the ChaiVector. - * @param [in/out] v the ChaiVector to copy. - */ -template< class T > -void deep_copy_test( const array< T > & v ) -{ - array< T > v_cpy( v ); - - ASSERT_EQ( v.size(), v_cpy.size() ); - - ASSERT_NE( v.data(), v_cpy.data() ); - - for( INDEX_TYPE i = 0; i < v.size(); ++i ) - { - ASSERT_EQ( v[ i ], v_cpy[ i ] ); - ASSERT_EQ( v[ i ], T( i ) ); - } - - for( INDEX_TYPE i = 0; i < v.size(); ++i ) - { - v_cpy[ i ] = T( 2 * i ); - } - - for( INDEX_TYPE i = 0; i < v.size(); ++i ) - { - ASSERT_EQ( v_cpy[ i ], T( 2 * i ) ); - ASSERT_EQ( v[ i ], T( i ) ); - } -} - -/** - * @brief Test the deep_copy method of the ChaiVector. - * @param [in/out] v the ChaiVector to copy. - */ -template< class T > -void deep_copy_array_test( const array< array< T > > & v ) -{ - array< array< T > > v_cpy( v ); - - ASSERT_EQ( v.size(), v_cpy.size() ); - - ASSERT_NE( v.data(), v_cpy.data() ); - - for( INDEX_TYPE i = 0; i < v.size(); ++i ) - { - ASSERT_EQ( v[ i ].size(), v_cpy[ i ].size() ); - - for( INDEX_TYPE j = 0; j < v[ i ].size(); ++j ) - { - ASSERT_EQ( v[ i ][ j ], v_cpy[ i ][ j ] ); - ASSERT_EQ( v[ i ][ j ], T( v[ i ].size() * i + j ) ); - } - } - - for( INDEX_TYPE i = 0; i < v.size(); ++i ) - { - for( INDEX_TYPE j = 0; j < v[ i ].size(); ++j ) - { - v_cpy[ i ][ j ] = T( 2 * ( v[ i ].size() * i + j ) ); - } - } - - for( INDEX_TYPE i = 0; i < v.size(); ++i ) - { - ASSERT_EQ( v[ i ].size(), v_cpy[ i ].size() ); - - for( INDEX_TYPE j = 0; j < v[ i ].size(); ++j ) - { - ASSERT_EQ( v[ i ][ j ], T( v[ i ].size() * i + j ) ); - ASSERT_EQ( v_cpy[ i ][ j ], T( 2 * ( v[ i ].size() * i + j ) ) ); - } - } -} - -/** - * @brief Test the shallow copy copy-constructor of the ChaiVector. - * @param [in/out] v the ChaiVector to copy. - */ -template< class T > -void shallow_copy_test( const array< T > & v ) -{ - { - arrayView< T > v_cpy( v.toView() ); - ASSERT_EQ( v.size(), v_cpy.size() ); - ASSERT_EQ( v.data(), v_cpy.data() ); - - for( INDEX_TYPE i = 0; i < v.size(); ++i ) - { - ASSERT_EQ( v[ i ], v_cpy[ i ] ); - ASSERT_EQ( v[ i ], T( i ) ); - v_cpy[ i ] = T( 2 * i ); - } - } - - for( INDEX_TYPE i = 0; i < v.size(); ++i ) - { - ASSERT_EQ( v[ i ], T( 2 * i ) ); - } -} - -/** - * @brief Test the shallow copy copy-constructor of the ChaiVector. - * @param [in/out] v the ChaiVector to copy. - */ -template< class T > -void shallow_copy_array_test( const array< array< T > > & v ) -{ - { - arrayView< array< T > > v_cpy( static_cast< arrayView< array< T > > const & >(v) ); - ASSERT_EQ( v.size(), v_cpy.size() ); - ASSERT_EQ( v.data(), v_cpy.data() ); - - for( INDEX_TYPE i = 0; i < v.size(); ++i ) - { - ASSERT_EQ( v[ i ].size(), v_cpy[ i ].size() ); - - for( INDEX_TYPE j = 0; j < v[ i ].size(); ++j ) - { - ASSERT_EQ( v[ i ][ j ], v_cpy[ i ][ j ] ); - ASSERT_EQ( v[ i ][ j ], T( v[ i ].size() * i + j ) ); - v_cpy[ i ][ j ] = T( 2 * ( v[ i ].size() * i + j ) ); - } - } - } - - for( INDEX_TYPE i = 0; i < v.size(); ++i ) - { - for( INDEX_TYPE j = 0; j < v[ i ].size(); ++j ) - { - ASSERT_EQ( v[ i ][ j ], T( 2 * ( v[ i ].size() * i + j ) ) ); - } - } -} - -TEST( Array, push_back ) -{ - constexpr INDEX_TYPE N = 1000; /* Number of values to push_back */ - - { - array< int > v; - push_back_test( v, N ); - } - - { - array< Tensor > v; - push_back_test( v, N ); - } - - { - array< TestString > v; - push_back_test( v, N ); - } -} - -TEST( Array, push_back_array ) -{ - constexpr INDEX_TYPE N = 100; /* Number of arrays to push_back */ - constexpr INDEX_TYPE M = 10; /* Size of each array */ - - { - array< array< int > > v; - push_back_array_test( v, N, M ); - } - - { - array< array< Tensor > > v; - push_back_array_test( v, N, M ); - } - - { - array< array< TestString > > v; - push_back_array_test( v, N, M ); - } -} - -TEST( Array, insert ) -{ - constexpr INDEX_TYPE N = 100; /* Number of times to call insert */ - constexpr INDEX_TYPE M = 10; /* Number of values inserted at each call */ - - { - array< int > v; - insert_test( v, N, M ); - } - - { - array< Tensor > v; - insert_test( v, N, M ); - } - - { - array< TestString > v; - insert_test( v, N, M ); - } -} - -TEST( Array, insert_array ) -{ - constexpr INDEX_TYPE N = 10; /* Number of times to call insert */ - constexpr INDEX_TYPE M = 10; /* Number of arrays inserted at each call */ - constexpr INDEX_TYPE P = 10; /* Size of each array inserted */ - - { - array< array< int > > v; - insert_array_test( v, N, M, P ); - } - - { - array< array< Tensor > > v; - insert_array_test( v, N, M, P ); - } - - { - array< array< TestString > > v; - insert_array_test( v, N, M, P ); - } -} - -TEST( Array, erase ) -{ - constexpr INDEX_TYPE N = 200; /* Size of the array */ - - { - array< int > v; - std::vector< int > v_ref = push_back_test( v, N ); - erase_test( v, v_ref ); - } - - { - array< Tensor > v; - std::vector< Tensor > v_ref = push_back_test( v, N ); - erase_test( v, v_ref ); - } - - { - array< TestString > v; - std::vector< TestString > v_ref = push_back_test( v, N ); - erase_test( v, v_ref ); - } - -} - -TEST( Array, erase_array ) -{ - constexpr INDEX_TYPE N = 100; /* Number of arrays to push_back */ - constexpr INDEX_TYPE M = 10; /* Size of each array */ - - { - array< array< int > > v; - std::vector< std::vector< int > > v_ref = push_back_array_test( v, N, M ); - erase_test( v, v_ref ); - } - - { - array< array< Tensor > > v; - std::vector< std::vector< Tensor > > v_ref = push_back_array_test( v, N, M ); - erase_test( v, v_ref ); - } - - { - array< array< TestString > > v; - std::vector< std::vector< TestString > > v_ref = push_back_array_test( v, N, M ); - erase_test( v, v_ref ); - } -} - -TEST( Array, pop_back ) -{ - constexpr INDEX_TYPE N = 300; /* Size of the array */ - - { - array< int > v; - std::vector< int > v_ref = push_back_test( v, N ); - pop_back_test( v, v_ref ); - } - - { - array< Tensor > v; - std::vector< Tensor > v_ref = push_back_test( v, N ); - pop_back_test( v, v_ref ); - } - - { - array< TestString > v; - std::vector< TestString > v_ref = push_back_test( v, N ); - pop_back_test( v, v_ref ); - } -} - -TEST( Array, pop_back_array ) -{ - constexpr INDEX_TYPE N = 50; /* Number of arrays to push_back */ - constexpr INDEX_TYPE M = 10; /* Size of each array */ - - { - array< array< int > > v; - std::vector< std::vector< int > > v_ref = push_back_array_test( v, N, M ); - pop_back_test( v, v_ref ); - } - - { - array< array< Tensor > > v; - std::vector< std::vector< Tensor > > v_ref = push_back_array_test( v, N, M ); - pop_back_test( v, v_ref ); - } - - { - array< array< TestString > > v; - std::vector< std::vector< TestString > > v_ref = push_back_array_test( v, N, M ); - pop_back_test( v, v_ref ); - } -} - -TEST( Array, resize ) -{ - constexpr INDEX_TYPE N = 1000; /* Size of each array */ - - { - array< int > v; - resize_test( v, N ); - } - - { - array< Tensor > v; - resize_test( v, N ); - } - - { - array< TestString > v; - resize_test( v, N ); - } -} - -TEST( Array, resizeNoInitOrDestroy ) -{ - constexpr INDEX_TYPE N = 1000; /* Size of each array */ - - { - array< int > v; - resizeNoInitOrDestroy_test( v, N ); - } - - { - array< Tensor > v; - resizeNoInitOrDestroy_test( v, N ); - } -} - -TEST( Array, resize_array ) -{ - constexpr INDEX_TYPE N = 100; /* Size of each array */ - constexpr INDEX_TYPE M = 10; /* Size of each array */ - - { - array< array< int > > v; - resize_array_test( v, N, M ); - } - - { - array< array< Tensor > > v; - resize_array_test( v, N, M ); - } - - { - array< array< TestString > > v; - resize_array_test( v, N, M ); - } -} - -TEST( Array, reserve ) -{ - constexpr INDEX_TYPE N = 1000; /* Size of the array */ - - { - array< int > v; - reserve_test( v, N ); - } - - { - array< Tensor > v; - reserve_test( v, N ); - } - - { - array< TestString > v; - reserve_test( v, N ); - } -} - -TEST( Array, reserve_array ) -{ - constexpr INDEX_TYPE N = 100; /* Number of arrays */ - constexpr INDEX_TYPE M = 10; /* Size of each array */ - - { - array< array< int > > v; - reserve_array_test( v, N, M ); - } - - { - array< array< Tensor > > v; - reserve_array_test( v, N, M ); - } - - { - array< array< TestString > > v; - reserve_array_test( v, N, M ); - } -} - -TEST( Array, deep_copy ) -{ - constexpr INDEX_TYPE N = 1000; /* Size of the array */ - - { - array< int > v; - push_back_test( v, N ); - deep_copy_test( v ); - } - - { - array< Tensor > v; - push_back_test( v, N ); - deep_copy_test( v ); - } - - { - array< TestString > v; - push_back_test( v, N ); - deep_copy_test( v ); - } -} - -TEST( Array, deep_copy_array ) -{ - constexpr INDEX_TYPE N = 100; /* Number of arrays */ - constexpr INDEX_TYPE M = 10; /* Size of each array */ - - { - array< array< int > > v; - push_back_array_test( v, N, M ); - deep_copy_array_test( v ); - } - - { - array< array< Tensor > > v; - push_back_array_test( v, N, M ); - deep_copy_array_test( v ); - } - - { - array< array< TestString > > v; - push_back_array_test( v, N, M ); - deep_copy_array_test( v ); - } -} - -TEST( Array, shallow_copy ) -{ - constexpr INDEX_TYPE N = 1000; /* Size of the array */ - - { - array< int > v; - push_back_test( v, N ); - shallow_copy_test( v ); - } - - { - array< Tensor > v; - push_back_test( v, N ); - shallow_copy_test( v ); - } - - { - array< TestString > v; - push_back_test( v, N ); - shallow_copy_test( v ); - } -} - -TEST( Array, shallow_copy_array ) -{ - constexpr INDEX_TYPE N = 100; /* Number of arrays */ - constexpr INDEX_TYPE M = 10; /* Size of each array */ - - { - array< array< int > > v; - push_back_array_test( v, N, M ); - shallow_copy_array_test( v ); - } - - { - array< array< Tensor > > v; - push_back_array_test( v, N, M ); - shallow_copy_array_test( v ); - } - - { - array< array< TestString > > v; - push_back_array_test( v, N, M ); - shallow_copy_array_test( v ); - } -} - -TEST( Array, test_upcast ) -{ - constexpr INDEX_TYPE N = 1000; /* Number of values to push_back */ - - { - array< int > v; - push_back_test( v, N ); - arrayView< int > & vView = v; - compare_to_view( v, vView ); - } - - { - array< Tensor > v; - push_back_test( v, N ); - arrayView< Tensor > & vView = v; - compare_to_view( v, vView ); - } - - { - array< TestString > v; - push_back_test( v, N ); - arrayView< TestString > & vView = v; - compare_to_view( v, vView ); - } -} - -TEST( Array, test_array2D ) -{ - constexpr INDEX_TYPE N = 53; - constexpr INDEX_TYPE M = 47; - - { - array2D< int > v; - create_2D_test( v, N, M ); - arrayView2D< int > & vView = v; - compare_to_view( v, vView ); - } - - { - array2D< Tensor > v; - create_2D_test( v, N, M ); - arrayView2D< Tensor > & vView = v; - compare_to_view( v, vView ); - } - - { - array2D< TestString > v; - create_2D_test( v, N, M ); - arrayView2D< TestString > & vView = v; - compare_to_view( v, vView ); - } -} - -template< typename T > -class ArrayResizeTest : public ::testing::Test -{ -public: - - template< int USD > - void print( ArrayView< T const, 2, USD > const & v ) - { - for( INDEX_TYPE i = 0; i < v.size( 0 ); ++i ) - { - for( INDEX_TYPE j = 0; j < v.size( 1 ); ++j ) - { - std::cout << v( i, j ) << " "; - } - std::cout << std::endl; - } - std::cout << std::endl; - } - - template< typename PERMUTATION > - void resize( PERMUTATION ) - { - constexpr int NDIM = getDimension( PERMUTATION {} ); - static_assert( NDIM < 5, "dimension must be less than 4" ); - - Array< T, NDIM, PERMUTATION > a; - - INDEX_TYPE const maxDimSize = getMaxDimSize( NDIM ); - INDEX_TYPE initialSizes[ NDIM ]; - - // Iterate over randomly generated sizes. - for( int i = 0; i < 10; ++i ) - { - for( int d = 0; d < NDIM; ++d ) - { - initialSizes[ d ] = rand( 1, maxDimSize / 2 ); - } - - // Iterate over the dimensions - for( int d = 0; d < NDIM; ++d ) - { - a.setSingleParameterResizeIndex( d ); - - populate( a, initialSizes ); - - // Increase the size - INDEX_TYPE const largerDefaultSize = rand( initialSizes[ d ], maxDimSize ); - a.resizeDefault( largerDefaultSize, T( -1 ) ); - validate( a.toViewConst(), initialSizes, T( -1 ) ); - - // Decrease the size - INDEX_TYPE const smallerDefaultSize = rand( 0, initialSizes[ d ] ); - a.resize( smallerDefaultSize ); - validate( a.toViewConst(), a.dims() ); - } - } - } - - -private: - - INDEX_TYPE getTestingLinearIndex( INDEX_TYPE const i ) - { - return i; - } - - INDEX_TYPE getTestingLinearIndex( INDEX_TYPE const i, INDEX_TYPE const j ) - { - INDEX_TYPE const maxDimSize = getMaxDimSize( 2 ); - return maxDimSize * i + j; - } - - INDEX_TYPE getTestingLinearIndex( INDEX_TYPE const i, INDEX_TYPE const j, INDEX_TYPE const k ) - { - INDEX_TYPE const maxDimSize = getMaxDimSize( 3 ); - return maxDimSize * maxDimSize * i + maxDimSize * j + k; - } - - INDEX_TYPE getTestingLinearIndex( INDEX_TYPE const i, INDEX_TYPE const j, INDEX_TYPE const k, INDEX_TYPE const l ) - { - INDEX_TYPE const maxDimSize = getMaxDimSize( 4 ); - return maxDimSize * maxDimSize * maxDimSize * i + maxDimSize * maxDimSize * j + maxDimSize * k + l; - } - - - template< int NDIM, typename PERMUTATION > - void populate( Array< T, NDIM, PERMUTATION > & a, - INDEX_TYPE const * const initialSizes ) - { - a.resize( NDIM, initialSizes ); - for( int d = 0; d < NDIM; ++d ) - { - ASSERT_EQ( initialSizes[ d ], a.size( d ) ); - } - - forValuesInSliceWithIndices( a.toSlice(), - [this]( T & value, auto const... indices ) - { - INDEX_TYPE const idx = this->getTestingLinearIndex( indices ... ); - value = T( idx ); - } - ); - - validate( a.toViewConst(), initialSizes ); - } - - template< int NDIM, int USD > - void validate( ArrayView< T const, NDIM, USD > const & v, - INDEX_TYPE const * const initialSizes, - T const & defaultValue = T() ) - { - forValuesInSliceWithIndices( v.toSlice(), - [initialSizes, defaultValue, this]( T const & value, auto const... indices ) - { - if( !invalidIndices( initialSizes, indices ... ) ) - { - INDEX_TYPE const idx = this->getTestingLinearIndex( indices ... ); - EXPECT_EQ( value, T( idx ) ); - } - else - { - EXPECT_EQ( value, defaultValue ); - } - } - ); - } - - INDEX_TYPE getMaxDimSize( int const d ) - { return m_maxDimSizes[ d - 1 ]; } - - INDEX_TYPE rand( INDEX_TYPE const min, INDEX_TYPE const max ) - { return std::uniform_int_distribution< INDEX_TYPE >( min, max )( m_gen ); } - - INDEX_TYPE const m_maxDimSizes[ 4 ] = { 1000, 40, 20, 10 }; - std::mt19937_64 m_gen; -}; - -using TestTypes = ::testing::Types< INDEX_TYPE, Tensor, TestString >; -TYPED_TEST_SUITE( ArrayResizeTest, TestTypes, ); - -TYPED_TEST( ArrayResizeTest, resize1D ) -{ - this->resize( RAJA::PERM_I {} ); -} - -TYPED_TEST( ArrayResizeTest, resize2D ) -{ - this->resize( RAJA::PERM_IJ {} ); - this->resize( RAJA::PERM_JI {} ); -} - -TYPED_TEST( ArrayResizeTest, resize3D ) -{ - this->resize( RAJA::PERM_IJK {} ); - this->resize( RAJA::PERM_JIK {} ); - this->resize( RAJA::PERM_IKJ {} ); - this->resize( RAJA::PERM_KIJ {} ); - this->resize( RAJA::PERM_KJI {} ); - this->resize( RAJA::PERM_JKI {} ); -} - -TYPED_TEST( ArrayResizeTest, resize4D ) -{ - this->resize( RAJA::PERM_IJKL {} ); - this->resize( RAJA::PERM_JIKL {} ); - this->resize( RAJA::PERM_IKJL {} ); - this->resize( RAJA::PERM_KIJL {} ); - this->resize( RAJA::PERM_JKIL {} ); - this->resize( RAJA::PERM_KJIL {} ); - this->resize( RAJA::PERM_IJLK {} ); - this->resize( RAJA::PERM_JILK {} ); - this->resize( RAJA::PERM_ILJK {} ); - this->resize( RAJA::PERM_LIJK {} ); - this->resize( RAJA::PERM_JLIK {} ); - this->resize( RAJA::PERM_LJIK {} ); - this->resize( RAJA::PERM_IKLJ {} ); - this->resize( RAJA::PERM_KILJ {} ); - this->resize( RAJA::PERM_ILKJ {} ); - this->resize( RAJA::PERM_LIKJ {} ); - this->resize( RAJA::PERM_KLIJ {} ); - this->resize( RAJA::PERM_LKIJ {} ); - this->resize( RAJA::PERM_JKLI {} ); - this->resize( RAJA::PERM_KJLI {} ); - this->resize( RAJA::PERM_JLKI {} ); - this->resize( RAJA::PERM_LJKI {} ); - this->resize( RAJA::PERM_KLJI {} ); - this->resize( RAJA::PERM_LKJI {} ); -} - -} // namespace testing -} // namespace LvArray - -// This is the default gtest main method. It is included for ease of debugging. -int main( int argc, char * * argv ) -{ - ::testing::InitGoogleTest( &argc, argv ); - int const result = RUN_ALL_TESTS(); - return result; -} diff --git a/unitTests/testArray.hpp b/unitTests/testArray.hpp new file mode 100644 index 00000000..1a031961 --- /dev/null +++ b/unitTests/testArray.hpp @@ -0,0 +1,922 @@ +/* + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Copyright (c) 2019, Lawrence Livermore National Security, LLC. + * + * Produced at the Lawrence Livermore National Laboratory + * + * LLNL-CODE-746361 + * + * All rights reserved. See COPYRIGHT for details. + * + * This file is part of the GEOSX Simulation Framework. + * + * GEOSX is a free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License (as published by the + * Free Software Foundation) version 2.1 dated February 1999. + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +// Source includes +#include "Array.hpp" +#include "streamIO.hpp" +#include "testUtils.hpp" +#include "MallocBuffer.hpp" + +// TPL includes +#include + +// System includes +#include + +namespace LvArray +{ +namespace testing +{ + +using INDEX_TYPE = std::ptrdiff_t; + +inline INDEX_TYPE randomInteger( INDEX_TYPE const min, INDEX_TYPE const max ) +{ + static std::mt19937_64 gen; + return std::uniform_int_distribution< INDEX_TYPE >( min, max )( gen ); +} + +template< typename ARRAY > +class ArrayTest : public ::testing::Test +{ +public: + using T = typename ARRAY::value_type; + static constexpr int NDIM = ARRAY::ndim; + using PERMUTATION = typename ARRAY::permutation; + + + static void defaultConstructor() + { + ARRAY array; + EXPECT_TRUE( array.empty() ); + EXPECT_EQ( array.getSingleParameterResizeIndex(), 0 ); + + for( int i = 0; i < NDIM; ++i ) + { + EXPECT_EQ( array.size( i ), 0 ); + } + + EXPECT_EQ( array.size(), 0 ); + EXPECT_EQ( array.capacity(), 0 ); + EXPECT_EQ( array.data(), nullptr ); + } + + static std::unique_ptr< ARRAY > sizedConstructor() + { + std::array< INDEX_TYPE, NDIM > sizes; + for( int dim = 0; dim < NDIM; ++dim ) + { sizes[ dim ] = randomInteger( 1, getMaxDimSize() ); } + + std::unique_ptr< ARRAY > array = forwardArrayAsArgs( sizes, + [] ( auto const ... args ) + { return std::make_unique< ARRAY >( args ... ); } ); + EXPECT_FALSE( array->empty() ); + EXPECT_EQ( array->getSingleParameterResizeIndex(), 0 ); + + INDEX_TYPE totalSize = 1; + for( int i = 0; i < NDIM; ++i ) + { + EXPECT_EQ( array->size( i ), sizes[ i ] ); + totalSize *= sizes[ i ]; + } + + EXPECT_EQ( array->size(), totalSize ); + EXPECT_EQ( array->capacity(), totalSize ); + EXPECT_NE( array->data(), nullptr ); + + fill( *array ); + + return array; + } + + static void copyConstructor() + { + std::unique_ptr< ARRAY > array = sizedConstructor(); + ARRAY copy = *array; + compare( *array, copy ); + } + + static void moveConstructor() + { + std::unique_ptr< ARRAY > array = sizedConstructor(); + ARRAY copy = *array; + ARRAY movedCopy = std::move( *array ); + + EXPECT_TRUE( array->empty() ); + EXPECT_EQ( array->size(), 0 ); + EXPECT_EQ( array->capacity(), 0 ); + EXPECT_EQ( array->data(), nullptr ); + + for( int dim = 0; dim < NDIM; ++dim ) + { + EXPECT_EQ( array->size( dim ), 0 ); + } + + array.reset(); + + compare( copy, movedCopy ); + } + + static void toView() + { + std::unique_ptr< ARRAY > array = sizedConstructor(); + EXPECT_EQ( array.get(), &array->toView() ); + compare( *array, array->toView(), true ); + } + + static void toViewConst() + { + std::unique_ptr< ARRAY > array = sizedConstructor(); + EXPECT_EQ( static_cast< void * >( array.get() ), static_cast< const void * >( &array->toViewConst() ) ); + compare( *array, array->toViewConst(), true ); + } + + static void copyAssignmentOperator() + { + std::unique_ptr< ARRAY > array = sizedConstructor(); + ARRAY copy; + EXPECT_TRUE( copy.empty() ); + + copy = *array; + compare( *array, copy ); + } + + static void moveAssignmentOperator() + { + std::unique_ptr< ARRAY > array = sizedConstructor(); + ARRAY copy = *array; + ARRAY movedCopy; + EXPECT_TRUE( movedCopy.empty() ); + + movedCopy = std::move( *array ); + + EXPECT_TRUE( array->empty() ); + EXPECT_EQ( array->size(), 0 ); + EXPECT_EQ( array->capacity(), 0 ); + EXPECT_EQ( array->data(), nullptr ); + + for( int dim = 0; dim < NDIM; ++dim ) + { + EXPECT_EQ( array->size( dim ), 0 ); + } + + array.reset(); + + compare( copy, movedCopy ); + } + + static void scalarAssignmentOperator() + { + T const value = T( 3.14 ); + + std::unique_ptr< ARRAY > array = sizedConstructor(); + + T const * const initialPtr = array->data(); + INDEX_TYPE totalSize = 1; + std::array< INDEX_TYPE, NDIM > sizes; + for( int dim = 0; dim < NDIM; ++dim ) + { + sizes[ dim ] = array->size( dim ); + totalSize *= array->size( dim ); + } + + *array = value; + EXPECT_EQ( array->size(), totalSize ); + EXPECT_EQ( array->capacity(), totalSize ); + EXPECT_EQ( array->data(), initialPtr ); + + for( INDEX_TYPE i = 0; i < array->size(); ++i ) + { + EXPECT_EQ( array->data()[ i ], value ); + } + } + + static void getSetSingleParameterResizeIndex() + { + std::unique_ptr< ARRAY > array = sizedConstructor(); + + for( int dim = 0; dim < NDIM; ++dim ) + { + array->setSingleParameterResizeIndex( dim ); + EXPECT_EQ( array->getSingleParameterResizeIndex(), dim ); + } + } + + static void resizeFromPointer() + { + std::unique_ptr< ARRAY > array = sizedConstructor(); + + std::array< INDEX_TYPE, NDIM > newSizes; + std::array< INDEX_TYPE, NDIM > oldSizes; + + for( int dim = 0; dim < NDIM; ++dim ) + { + oldSizes[ dim ] = array->size( dim ); + newSizes[ dim ] = randomInteger( 1, getMaxDimSize() ); + } + array->resize( NDIM, newSizes.data() ); + checkResize( *array, oldSizes, newSizes, NDIM == 1, true ); + + for( int dim = 0; dim < NDIM; ++dim ) + { + oldSizes[ dim ] = array->size( dim ); + newSizes[ dim ] = randomInteger( 1, getMaxDimSize() ); + } + array->resize( NDIM, newSizes.data() ); + checkResize( *array, oldSizes, newSizes, NDIM == 1, true ); + } + + static void resizeFromArgs() + { + std::unique_ptr< ARRAY > array = sizedConstructor(); + + std::array< INDEX_TYPE, NDIM > newSizes; + std::array< INDEX_TYPE, NDIM > oldSizes; + + for( int dim = 0; dim < NDIM; ++dim ) + { + oldSizes[ dim ] = array->size( dim ); + newSizes[ dim ] = randomInteger( 1, getMaxDimSize() ); + } + forwardArrayAsArgs( newSizes, [&array]( auto const ... indices ) + { + return array->resize( indices ... ); + } ); + checkResize( *array, oldSizes, newSizes, NDIM == 1, true ); + + // Increase the size of every dimension. + for( int dim = 0; dim < NDIM; ++dim ) + { + oldSizes[ dim ] = array->size( dim ); + newSizes[ dim ] = randomInteger( 1, getMaxDimSize() ); + } + forwardArrayAsArgs( newSizes, [&array]( auto const ... indices ) + { + return array->resize( indices ... ); + } ); + checkResize( *array, oldSizes, newSizes, NDIM == 1, true ); + } + + template< int _NDIM=NDIM > + static std::enable_if_t< _NDIM == 1 > + resizeDimension() + { + ARRAY array( 10 ); + fill( array ); + + resizeOneDimension< 0 >( array ); + } + + template< int _NDIM=NDIM > + static std::enable_if_t< _NDIM == 2 > + resizeDimension() + { + ARRAY array( 20, 20 ); + fill( array ); + + resizeOneDimension< 0 >( array ); + resizeOneDimension< 1 >( array ); + + resizeTwoDimensions< 0, 1 >( array ); + } + + template< int _NDIM=NDIM > + static std::enable_if_t< _NDIM == 3 > + resizeDimension() + { + ARRAY array( 8, 8, 8 ); + fill( array ); + + resizeOneDimension< 0 >( array ); + resizeOneDimension< 1 >( array ); + resizeOneDimension< 2 >( array ); + + resizeTwoDimensions< 0, 1 >( array ); + resizeTwoDimensions< 0, 2 >( array ); + resizeTwoDimensions< 1, 2 >( array ); + + resizeThreeDimensions< 0, 1, 2 >( array ); + } + + template< int _NDIM=NDIM > + static std::enable_if_t< _NDIM == 4 > + resizeDimension() + { + ARRAY array( 3, 3, 3, 3 ); + fill( array ); + + resizeOneDimension< 0 >( array ); + resizeOneDimension< 1 >( array ); + resizeOneDimension< 2 >( array ); + resizeOneDimension< 3 >( array ); + + resizeTwoDimensions< 0, 1 >( array ); + resizeTwoDimensions< 0, 2 >( array ); + resizeTwoDimensions< 0, 3 >( array ); + resizeTwoDimensions< 1, 2 >( array ); + resizeTwoDimensions< 1, 3 >( array ); + resizeTwoDimensions< 2, 3 >( array ); + + resizeThreeDimensions< 0, 1, 2 >( array ); + resizeThreeDimensions< 0, 1, 3 >( array ); + resizeThreeDimensions< 0, 2, 3 >( array ); + resizeThreeDimensions< 1, 2, 3 >( array ); + } + + static void resize( bool const useDefault ) + { + ARRAY array; + + INDEX_TYPE const maxDimSize = getMaxDimSize(); + + // Iterate over randomly generated sizes. + for( int i = 0; i < 10; ++i ) + { + // Iterate over the dimensions + for( int dim = 0; dim < NDIM; ++dim ) + { + array.setSingleParameterResizeIndex( dim ); + + std::array< INDEX_TYPE, NDIM > oldSizes; + for( int d = 0; d < NDIM; ++d ) + { oldSizes[ d ] = randomInteger( 1, maxDimSize / 2 ); } + + std::array< INDEX_TYPE, NDIM > newSizes = oldSizes; + + array.resize( NDIM, oldSizes.data() ); + + fill( array ); + + // Increase the size + newSizes[ dim ] = randomInteger( oldSizes[ dim ], maxDimSize ); + if( useDefault ) + { + array.resizeDefault( newSizes[ dim ], T( -i * dim ) ); + checkResize( array, oldSizes, newSizes, true, true, T( -i * dim ) ); + } + else + { + array.resize( newSizes[ dim ] ); + checkResize( array, oldSizes, newSizes, true, true ); + } + oldSizes = newSizes; + + // Decrease the size + newSizes[ dim ] = randomInteger( 0, oldSizes[ dim ] ); + if( useDefault ) + { + array.resizeDefault( newSizes[ dim ], T( -i * dim - 1 ) ); + checkResize( array, oldSizes, newSizes, true, true, T( -i * dim -1 ) ); + } + else + { + array.resize( newSizes[ dim ] ); + checkResize( array, oldSizes, newSizes, true, true ); + } + } + } + } + + static void reserveAndCapacity() + { + std::unique_ptr< ARRAY > array = sizedConstructor(); + INDEX_TYPE const initialSize = array->size(); + EXPECT_EQ( array->capacity(), initialSize ); + + INDEX_TYPE const defaultDimSize = array->size( array->getSingleParameterResizeIndex() ); + array->reserve( 2 * initialSize ); + T const * const pointerAfterReserve = array->data(); + + EXPECT_EQ( array->size(), initialSize ); + EXPECT_EQ( array->capacity(), 2 * initialSize ); + + array->resize( 1.5 * defaultDimSize ); + fill( *array ); + + EXPECT_EQ( array->capacity(), 2 * initialSize ); + EXPECT_EQ( array->data(), pointerAfterReserve ); + + array->resize( 2 * defaultDimSize ); + fill( *array ); + + EXPECT_EQ( array->capacity(), 2 * initialSize ); + EXPECT_EQ( array->data(), pointerAfterReserve ); + + array->resize( 0.5 * defaultDimSize ); + fill( *array ); + + EXPECT_EQ( array->capacity(), 2 * initialSize ); + EXPECT_EQ( array->data(), pointerAfterReserve ); + } + + static void clear() + { + std::unique_ptr< ARRAY > array = sizedConstructor(); + + std::array< INDEX_TYPE, NDIM > oldSizes; + for( int dim = 0; dim < NDIM; ++dim ) + { oldSizes[ dim ] = array->size( dim ); } + + INDEX_TYPE const oldSize = array->size(); + INDEX_TYPE const oldCapacity = array->capacity(); + T const * const oldPointer = array->data(); + + array->clear(); + + EXPECT_EQ( array->size(), 0 ); + EXPECT_EQ( array->capacity(), oldCapacity ); + EXPECT_EQ( array->data(), oldPointer ); + for( int dim = 0; dim < NDIM; ++dim ) + { + if( dim == array->getSingleParameterResizeIndex() ) + { + EXPECT_EQ( array->size( dim ), 0 ); + } + else + { + EXPECT_EQ( array->size( dim ), oldSizes[ dim ] ); + } + } + + array->resize( oldSizes[ array->getSingleParameterResizeIndex() ] ); + + EXPECT_EQ( array->size(), oldSize ); + EXPECT_EQ( array->capacity(), oldCapacity ); + EXPECT_EQ( array->data(), oldPointer ); + + for( int dim = 0; dim < NDIM; ++dim ) + { + EXPECT_EQ( array->size( dim ), oldSizes[ dim ] ); + } + + fill( *array ); + } + + static void checkIndexing() + { + ARRAY array; + + std::array< INDEX_TYPE, NDIM > dimensions; + for( int i = 0; i < NDIM; ++i ) + { dimensions[ i ] = randomInteger( 1, getMaxDimSize() ); } + + array.resize( NDIM, dimensions.data() ); + fill( array ); + + RAJA::View< T, RAJA::Layout< NDIM > > view( array.data(), + RAJA::make_permuted_layout( dimensions, + RAJA::as_array< PERMUTATION >::get() ) ); + + EXPECT_EQ( array.data(), view.data ); + for( int dim = 0; dim < NDIM; ++dim ) + { + EXPECT_EQ( array.size( dim ), view.layout.sizes[ dim ] ); + EXPECT_EQ( array.strides()[ dim ], view.layout.strides[ dim ] ); + } + + compareToRAJAView( array, view ); + } + +protected: + + static LVARRAY_HOST_DEVICE INDEX_TYPE + getTestingLinearIndex( INDEX_TYPE const i ) + { return i; } + + static LVARRAY_HOST_DEVICE INDEX_TYPE + getTestingLinearIndex( INDEX_TYPE const i, INDEX_TYPE const j ) + { return getMaxDimSize() * i + j; } + + static LVARRAY_HOST_DEVICE INDEX_TYPE + getTestingLinearIndex( INDEX_TYPE const i, INDEX_TYPE const j, INDEX_TYPE const k ) + { + INDEX_TYPE const maxDimSize = getMaxDimSize(); + return maxDimSize * maxDimSize * i + maxDimSize * j + k; + } + + static LVARRAY_HOST_DEVICE INDEX_TYPE + getTestingLinearIndex( INDEX_TYPE const i, INDEX_TYPE const j, INDEX_TYPE const k, INDEX_TYPE const l ) + { + INDEX_TYPE const maxDimSize = getMaxDimSize(); + return maxDimSize * maxDimSize * maxDimSize * i + maxDimSize * maxDimSize * j + maxDimSize * k + l; + } + + static void fill( ARRAY const & array ) + { + forValuesInSliceWithIndices( array.toSlice(), [] ( T & value, auto const ... indices ) + { + value = T( getTestingLinearIndex( indices ... ) ); + } ); + + checkFill( array ); + } + + static void checkFill( ARRAY const & array ) + { + forValuesInSliceWithIndices( array.toSliceConst(), [&array] ( T const & value, auto const ... indices ) + { + EXPECT_EQ( value, T( getTestingLinearIndex( indices ... ) ) ); + EXPECT_EQ( &value, &array( indices ... ) ); + EXPECT_EQ( &value - array.data(), array.linearIndex( indices ... ) ); + } ); + + // Check using the iterator interface + INDEX_TYPE offset = 0; + for( T const & val : array ) + { + EXPECT_EQ( val, array.data()[ offset ] ); + ++offset; + } + } + + static void checkFill( ARRAY const & array, + std::array< INDEX_TYPE, NDIM > const & oldSizes, + bool const defaultInitialized, + T const defaultValue ) + { + forValuesInSliceWithIndices( array.toSliceConst(), + [&array, oldSizes, defaultInitialized, defaultValue] ( T const & value, auto const ... indices ) + { + if( !invalidIndices( oldSizes.data(), indices ... ) ) + { + EXPECT_EQ( value, T( getTestingLinearIndex( indices ... ) ) ); + EXPECT_EQ( &value, &array( indices ... ) ); + } + else if( defaultInitialized ) + { + EXPECT_EQ( value, defaultValue ); + EXPECT_EQ( &value, &array( indices ... ) ); + } + } ); + } + + template< typename ARRAY_A, typename ARRAY_B > + static void compare( ARRAY_A const & a, ARRAY_B const & b, bool const shallowCopy=false ) + { + for( int dim = 0; dim < NDIM; ++dim ) + { + EXPECT_EQ( a.size( dim ), b.size( dim ) ); + } + + EXPECT_EQ( a.size(), b.size() ); + + forValuesInSliceWithIndices( a.toSliceConst(), [&a, &b, shallowCopy]( T const & val, auto const ... indices ) + { + EXPECT_EQ( val, a( indices ... ) ); + EXPECT_EQ( val, b( indices ... ) ); + + if( shallowCopy ) + { EXPECT_EQ( &a( indices ... ), &b( indices ... ) ); } + else + { EXPECT_NE( &a( indices ... ), &b( indices ... ) ); } + } ); + } + + static void checkResize( ARRAY const & array, + std::array< INDEX_TYPE, NDIM > const & oldSizes, + std::array< INDEX_TYPE, NDIM > const & newSizes, + bool const valuesPreserved, + bool const defaultInitialized, + T const defaultValue=T() ) + { + INDEX_TYPE totalSize = 1; + for( int dim = 0; dim < NDIM; ++dim ) + { + EXPECT_EQ( array.size( dim ), newSizes[ dim ] ); + totalSize *= newSizes[ dim ]; + } + + EXPECT_EQ( array.size(), totalSize ); + EXPECT_GE( array.capacity(), totalSize ); + + if( valuesPreserved ) + { checkFill( array, oldSizes, defaultInitialized, defaultValue ); } + + fill( array ); + } + + template< int DIM0 > + static void resizeOneDimension( ARRAY & array ) + { + std::array< INDEX_TYPE, NDIM > oldSizes; + for( int dim = 0; dim < NDIM; ++dim ) + { oldSizes[ dim ] = array.size( dim ); } + + std::array< INDEX_TYPE, NDIM > newSizes = oldSizes; + + // Increase the size + newSizes[ DIM0 ] = oldSizes[ DIM0 ] + 3; + array.template resizeDimension< DIM0 >( newSizes[ DIM0 ] ); + checkResize( array, oldSizes, newSizes, NDIM == 1, true ); + oldSizes = newSizes; + + // Shrink the size + newSizes[ DIM0 ] = oldSizes[ DIM0 ] - 5; + array.template resizeDimension< DIM0 >( newSizes[ DIM0 ] ); + checkResize( array, oldSizes, newSizes, NDIM == 1, true ); + oldSizes = newSizes; + + // Return to the original size + newSizes[ DIM0 ] = oldSizes[ DIM0 ] + 2; + array.template resizeDimension< DIM0 >( newSizes[ DIM0 ] ); + checkResize( array, oldSizes, newSizes, NDIM == 1, true ); + } + + template< int DIM0, int DIM1 > + static void resizeTwoDimensions( ARRAY & array ) + { + std::array< INDEX_TYPE, NDIM > oldSizes; + for( int dim = 0; dim < NDIM; ++dim ) + { oldSizes[ dim ] = array.size( dim ); } + + std::array< INDEX_TYPE, NDIM > newSizes = oldSizes; + + // Increase the size of both dimension + newSizes[ DIM0 ] = oldSizes[ DIM0 ] + 3; + newSizes[ DIM1 ] = oldSizes[ DIM1 ] + 2; + array.template resizeDimension< DIM0, DIM1 >( newSizes[ DIM0 ], newSizes[ DIM1 ] ); + checkResize( array, oldSizes, newSizes, false, true ); + oldSizes = newSizes; + + // Shrink the size of both dimension + newSizes[ DIM0 ] = oldSizes[ DIM0 ] - 4; + newSizes[ DIM1 ] = oldSizes[ DIM1 ] - 1; + array.template resizeDimension< DIM0, DIM1 >( newSizes[ DIM0 ], newSizes[ DIM1 ] ); + checkResize( array, oldSizes, newSizes, false, true ); + oldSizes = newSizes; + + // Grow the first dimension and shrink the second. + newSizes[ DIM0 ] = oldSizes[ DIM0 ] + 2; + newSizes[ DIM1 ] = oldSizes[ DIM1 ] - 4; + array.template resizeDimension< DIM0, DIM1 >( newSizes[ DIM0 ], newSizes[ DIM1 ] ); + checkResize( array, oldSizes, newSizes, false, true ); + oldSizes = newSizes; + + // Shrink the first dimension and grow the second. + newSizes[ DIM0 ] = oldSizes[ DIM0 ] - 1; + newSizes[ DIM1 ] = oldSizes[ DIM1 ] + 3; + array.template resizeDimension< DIM0, DIM1 >( newSizes[ DIM0 ], newSizes[ DIM1 ] ); + checkResize( array, oldSizes, newSizes, false, true ); + oldSizes = newSizes; + } + + template< int DIM0, int DIM1, int DIM2 > + static void resizeThreeDimensions( ARRAY & array ) + { + std::array< INDEX_TYPE, NDIM > oldSizes; + for( int dim = 0; dim < NDIM; ++dim ) + { oldSizes[ dim ] = array.size( dim ); } + + std::array< INDEX_TYPE, NDIM > newSizes = oldSizes; + + // Increase the size of all dimension + newSizes[ DIM0 ] = oldSizes[ DIM0 ] + 3; + newSizes[ DIM1 ] = oldSizes[ DIM1 ] + 1; + newSizes[ DIM2 ] = oldSizes[ DIM2 ] + 2; + array.template resizeDimension< DIM0, DIM1, DIM2 >( newSizes[ DIM0 ], newSizes[ DIM1 ], newSizes[ DIM2 ] ); + checkResize( array, oldSizes, newSizes, false, true ); + oldSizes = newSizes; + + // Shrink the size of all dimension + newSizes[ DIM0 ] = oldSizes[ DIM0 ] - 4; + newSizes[ DIM1 ] = oldSizes[ DIM1 ] - 2; + newSizes[ DIM2 ] = oldSizes[ DIM2 ] - 1; + array.template resizeDimension< DIM0, DIM1, DIM2 >( newSizes[ DIM0 ], newSizes[ DIM1 ], newSizes[ DIM2 ] ); + checkResize( array, oldSizes, newSizes, false, true ); + oldSizes = newSizes; + + // Shrink the first, grow the rest. + newSizes[ DIM0 ] = oldSizes[ DIM0 ] - 1; + newSizes[ DIM1 ] = oldSizes[ DIM1 ] + 3; + newSizes[ DIM2 ] = oldSizes[ DIM2 ] + 2; + array.template resizeDimension< DIM0, DIM1, DIM2 >( newSizes[ DIM0 ], newSizes[ DIM1 ], newSizes[ DIM2 ] ); + checkResize( array, oldSizes, newSizes, false, true ); + oldSizes = newSizes; + + // Shrink the second, grow the rest. + newSizes[ DIM0 ] = oldSizes[ DIM0 ] + 3; + newSizes[ DIM1 ] = oldSizes[ DIM1 ] - 3; + newSizes[ DIM2 ] = oldSizes[ DIM2 ] + 1; + array.template resizeDimension< DIM0, DIM1, DIM2 >( newSizes[ DIM0 ], newSizes[ DIM1 ], newSizes[ DIM2 ] ); + checkResize( array, oldSizes, newSizes, false, true ); + oldSizes = newSizes; + + // Shrink the third, grow the rest. + newSizes[ DIM0 ] = oldSizes[ DIM0 ] + 3; + newSizes[ DIM1 ] = oldSizes[ DIM1 ] + 4; + newSizes[ DIM2 ] = oldSizes[ DIM2 ] - 4; + array.template resizeDimension< DIM0, DIM1, DIM2 >( newSizes[ DIM0 ], newSizes[ DIM1 ], newSizes[ DIM2 ] ); + checkResize( array, oldSizes, newSizes, false, true ); + oldSizes = newSizes; + + // Grow the first, shrink the rest. + newSizes[ DIM0 ] = oldSizes[ DIM0 ] + 2; + newSizes[ DIM1 ] = oldSizes[ DIM1 ] - 2; + newSizes[ DIM2 ] = oldSizes[ DIM2 ] - 2; + array.template resizeDimension< DIM0, DIM1, DIM2 >( newSizes[ DIM0 ], newSizes[ DIM1 ], newSizes[ DIM2 ] ); + checkResize( array, oldSizes, newSizes, false, true ); + oldSizes = newSizes; + + // Grow the second, shrink the rest. + newSizes[ DIM0 ] = oldSizes[ DIM0 ] - 4; + newSizes[ DIM1 ] = oldSizes[ DIM1 ] + 3; + newSizes[ DIM2 ] = oldSizes[ DIM2 ] - 1; + array.template resizeDimension< DIM0, DIM1, DIM2 >( newSizes[ DIM0 ], newSizes[ DIM1 ], newSizes[ DIM2 ] ); + checkResize( array, oldSizes, newSizes, false, true ); + oldSizes = newSizes; + + // Grow the third, shrink the rest. + newSizes[ DIM0 ] = oldSizes[ DIM0 ] - 2; + newSizes[ DIM1 ] = oldSizes[ DIM1 ] - 4; + newSizes[ DIM2 ] = oldSizes[ DIM2 ] + 3; + array.template resizeDimension< DIM0, DIM1, DIM2 >( newSizes[ DIM0 ], newSizes[ DIM1 ], newSizes[ DIM2 ] ); + checkResize( array, oldSizes, newSizes, false, true ); + oldSizes = newSizes; + } + + static void compareToRAJAView( ARRAY const & array, + RAJA::View< T, RAJA::Layout< 1 > > const & view ) + { + for( INDEX_TYPE i = 0; i < array.size( 0 ); ++i ) + { + EXPECT_EQ( &view( i ), &array[ i ] ); + EXPECT_EQ( &view( i ), &array( i ) ); + } + } + + static void compareToRAJAView( ARRAY const & array, + RAJA::View< T, RAJA::Layout< 2 > > const & view ) + { + for( INDEX_TYPE i = 0; i < array.size( 0 ); ++i ) + { + for( INDEX_TYPE j = 0; j < array.size( 1 ); ++j ) + { + EXPECT_EQ( &view( i, j ), &array[ i ][ j ] ); + EXPECT_EQ( &view( i, j ), &array( i, j ) ); + } + } + } + + static void compareToRAJAView( ARRAY const & array, + RAJA::View< T, RAJA::Layout< 3 > > const & view ) + { + for( INDEX_TYPE i = 0; i < array.size( 0 ); ++i ) + { + for( INDEX_TYPE j = 0; j < array.size( 1 ); ++j ) + { + for( INDEX_TYPE k = 0; k < array.size( 2 ); ++k ) + { + EXPECT_EQ( &view( i, j, k ), &array[ i ][ j ][ k ] ); + EXPECT_EQ( &view( i, j, k ), &array( i, j, k ) ); + } + } + } + } + + static void compareToRAJAView( ARRAY const & array, + RAJA::View< T, RAJA::Layout< 4 > > const & view ) + { + for( INDEX_TYPE i = 0; i < array.size( 0 ); ++i ) + { + for( INDEX_TYPE j = 0; j < array.size( 1 ); ++j ) + { + for( INDEX_TYPE k = 0; k < array.size( 2 ); ++k ) + { + for( INDEX_TYPE l = 0; l < array.size( 3 ); ++l ) + { + EXPECT_EQ( &view( i, j, k, l ), &array[ i ][ j ][ k ][ l ] ); + EXPECT_EQ( &view( i, j, k, l ), &array( i, j, k, l ) ); + } + } + } + } + } + + + template< typename LAMBDA > + static auto forwardArrayAsArgs( std::array< INDEX_TYPE, 1 > const & sizes, LAMBDA && lambda ) + { return lambda( sizes[ 0 ] ); } + + template< typename LAMBDA > + static auto forwardArrayAsArgs( std::array< INDEX_TYPE, 2 > const & sizes, LAMBDA && lambda ) + { return lambda( sizes[ 0 ], sizes[ 1 ] ); } + + template< typename LAMBDA > + static auto forwardArrayAsArgs( std::array< INDEX_TYPE, 3 > const & sizes, LAMBDA && lambda ) + { return lambda( sizes[ 0 ], sizes[ 1 ], sizes[ 2 ] ); } + + template< typename LAMBDA > + static auto forwardArrayAsArgs( std::array< INDEX_TYPE, 4 > const & sizes, LAMBDA && lambda ) + { return lambda( sizes[ 0 ], sizes[ 1 ], sizes[ 2 ], sizes[ 3 ] ); } + + static LVARRAY_HOST_DEVICE INDEX_TYPE getMaxDimSize() + { + INDEX_TYPE const maxDimSizes[ 4 ] = { 1000, 50, 20, 10 }; + return maxDimSizes[ NDIM - 1 ]; + } +}; + +using ArrayTestTypes = ::testing::Types< + Array< int, 1, RAJA::PERM_I, INDEX_TYPE, DEFAULT_BUFFER > + , Array< int, 2, RAJA::PERM_IJ, INDEX_TYPE, DEFAULT_BUFFER > + , Array< int, 2, RAJA::PERM_JI, INDEX_TYPE, DEFAULT_BUFFER > + , Array< int, 3, RAJA::PERM_IJK, INDEX_TYPE, DEFAULT_BUFFER > + , Array< int, 3, RAJA::PERM_IKJ, INDEX_TYPE, DEFAULT_BUFFER > + , Array< int, 3, RAJA::PERM_JIK, INDEX_TYPE, DEFAULT_BUFFER > + , Array< int, 3, RAJA::PERM_JKI, INDEX_TYPE, DEFAULT_BUFFER > + , Array< int, 3, RAJA::PERM_KIJ, INDEX_TYPE, DEFAULT_BUFFER > + , Array< int, 3, RAJA::PERM_KJI, INDEX_TYPE, DEFAULT_BUFFER > + , Array< int, 4, RAJA::PERM_IJKL, INDEX_TYPE, DEFAULT_BUFFER > + , Array< int, 4, RAJA::PERM_LKJI, INDEX_TYPE, DEFAULT_BUFFER > + , Array< Tensor, 1, RAJA::PERM_I, INDEX_TYPE, DEFAULT_BUFFER > + , Array< Tensor, 2, RAJA::PERM_IJ, INDEX_TYPE, DEFAULT_BUFFER > + , Array< Tensor, 2, RAJA::PERM_JI, INDEX_TYPE, DEFAULT_BUFFER > + , Array< Tensor, 3, RAJA::PERM_IJK, INDEX_TYPE, DEFAULT_BUFFER > + , Array< Tensor, 3, RAJA::PERM_KJI, INDEX_TYPE, DEFAULT_BUFFER > + , Array< Tensor, 4, RAJA::PERM_IJKL, INDEX_TYPE, DEFAULT_BUFFER > + , Array< Tensor, 4, RAJA::PERM_LKJI, INDEX_TYPE, DEFAULT_BUFFER > + , Array< TestString, 1, RAJA::PERM_I, INDEX_TYPE, DEFAULT_BUFFER > + , Array< TestString, 2, RAJA::PERM_IJ, INDEX_TYPE, DEFAULT_BUFFER > + , Array< TestString, 2, RAJA::PERM_JI, INDEX_TYPE, DEFAULT_BUFFER > + , Array< TestString, 3, RAJA::PERM_IJK, INDEX_TYPE, DEFAULT_BUFFER > + , Array< TestString, 3, RAJA::PERM_KJI, INDEX_TYPE, DEFAULT_BUFFER > + , Array< TestString, 4, RAJA::PERM_IJKL, INDEX_TYPE, DEFAULT_BUFFER > + , Array< TestString, 4, RAJA::PERM_LKJI, INDEX_TYPE, DEFAULT_BUFFER > + >; + +TYPED_TEST_SUITE( ArrayTest, ArrayTestTypes, ); + +template< typename ARRAY > +class ArrayOfTrivialObjectsTest : public ArrayTest< ARRAY > +{ +public: + using ArrayTest< ARRAY >::NDIM; + using ArrayTest< ARRAY >::sizedConstructor; + + static void resizeWithoutInitializationOrDestruction() + { + std::unique_ptr< ARRAY > array = sizedConstructor(); + + std::array< INDEX_TYPE, NDIM > newSizes; + std::array< INDEX_TYPE, NDIM > oldSizes; + + // Shrink the size of each dimension. + for( int dim = 0; dim < NDIM; ++dim ) + { + newSizes[ dim ] = dim + 5; + oldSizes[ dim ] = array->size( dim ); + } + forwardArrayAsArgs( newSizes, [&array]( auto const ... indices ) + { + return array->resizeWithoutInitializationOrDestruction( indices ... ); + } ); + checkResize( *array, oldSizes, newSizes, NDIM == 1, false ); + + // Increase the size of every dimension. + for( int dim = 0; dim < NDIM; ++dim ) + { + newSizes[ dim ] = dim + 15; + oldSizes[ dim ] = array->size( dim ); + } + forwardArrayAsArgs( newSizes, [&array]( auto const ... indices ) + { + return array->resizeWithoutInitializationOrDestruction( indices ... ); + } ); + checkResize( *array, oldSizes, newSizes, NDIM == 1, false ); + } + +protected: + using ArrayTest< ARRAY >::forwardArrayAsArgs; + using ArrayTest< ARRAY >::checkResize; +}; + +using ArrayOfTrivialObjectsTestTypes = ::testing::Types< + Array< int, 1, RAJA::PERM_I, INDEX_TYPE, DEFAULT_BUFFER > + , Array< int, 2, RAJA::PERM_IJ, INDEX_TYPE, DEFAULT_BUFFER > + , Array< int, 2, RAJA::PERM_JI, INDEX_TYPE, DEFAULT_BUFFER > + , Array< int, 3, RAJA::PERM_IJK, INDEX_TYPE, DEFAULT_BUFFER > + , Array< int, 3, RAJA::PERM_IKJ, INDEX_TYPE, DEFAULT_BUFFER > + , Array< int, 3, RAJA::PERM_JIK, INDEX_TYPE, DEFAULT_BUFFER > + , Array< int, 3, RAJA::PERM_JKI, INDEX_TYPE, DEFAULT_BUFFER > + , Array< int, 3, RAJA::PERM_KIJ, INDEX_TYPE, DEFAULT_BUFFER > + , Array< int, 3, RAJA::PERM_KJI, INDEX_TYPE, DEFAULT_BUFFER > + , Array< int, 4, RAJA::PERM_IJKL, INDEX_TYPE, DEFAULT_BUFFER > + , Array< int, 4, RAJA::PERM_LKJI, INDEX_TYPE, DEFAULT_BUFFER > + , Array< Tensor, 1, RAJA::PERM_I, INDEX_TYPE, DEFAULT_BUFFER > + , Array< Tensor, 2, RAJA::PERM_IJ, INDEX_TYPE, DEFAULT_BUFFER > + , Array< Tensor, 2, RAJA::PERM_JI, INDEX_TYPE, DEFAULT_BUFFER > + , Array< Tensor, 3, RAJA::PERM_IJK, INDEX_TYPE, DEFAULT_BUFFER > + , Array< Tensor, 3, RAJA::PERM_KJI, INDEX_TYPE, DEFAULT_BUFFER > + , Array< Tensor, 4, RAJA::PERM_IJKL, INDEX_TYPE, DEFAULT_BUFFER > + , Array< Tensor, 4, RAJA::PERM_LKJI, INDEX_TYPE, DEFAULT_BUFFER > + >; + +TYPED_TEST_SUITE( ArrayOfTrivialObjectsTest, ArrayOfTrivialObjectsTestTypes, ); + +} // namespace testing +} // namespace LvArray diff --git a/unitTests/testArray1D.cpp b/unitTests/testArray1D.cpp new file mode 100644 index 00000000..06a10de4 --- /dev/null +++ b/unitTests/testArray1D.cpp @@ -0,0 +1,255 @@ +/* + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Copyright (c) 2019, Lawrence Livermore National Security, LLC. + * + * Produced at the Lawrence Livermore National Laboratory + * + * LLNL-CODE-746361 + * + * All rights reserved. See COPYRIGHT for details. + * + * This file is part of the GEOSX Simulation Framework. + * + * GEOSX is a free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License (as published by the + * Free Software Foundation) version 2.1 dated February 1999. + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +// Source includes +#include "Array.hpp" +#include "streamIO.hpp" +#include "testUtils.hpp" +#include "MallocBuffer.hpp" + +// TPL includes +#include + +// System includes +#include + +namespace LvArray +{ +namespace testing +{ + +using INDEX_TYPE = std::ptrdiff_t; + +inline INDEX_TYPE randomInteger( INDEX_TYPE const min, INDEX_TYPE const max ) +{ + static std::mt19937_64 gen; + return std::uniform_int_distribution< INDEX_TYPE >( min, max )( gen ); +} +template< typename ARRAY1D > +class Array1DTest : public ::testing::Test +{ +public: + using T = typename ARRAY1D::value_type; + + void compareToReference() const + { + EXPECT_EQ( m_array.size(), m_ref.size() ); + EXPECT_EQ( m_array.empty(), m_ref.empty() ); + if( m_array.empty() ) + { + EXPECT_EQ( m_array.size(), 0 ); + return; + } + + for( INDEX_TYPE i = 0; i < m_array.size(); ++i ) + { + EXPECT_EQ( m_array[ i ], m_ref[ i ] ); + EXPECT_EQ( m_array( i ), m_ref[ i ] ); + } + + const T * ptr = m_array.data(); + const T * refPtr = m_ref.data(); + for( INDEX_TYPE i = 0; i < m_array.size(); ++i ) + { + EXPECT_EQ( ptr[ i ], refPtr[ i ] ); + } + } + + #define COMPARE_TO_REFERENCE { SCOPED_TRACE( "" ); compareToReference(); \ + } + + void emplace_back( INDEX_TYPE const nVals ) + { + COMPARE_TO_REFERENCE + + LVARRAY_ERROR_IF_NE( nVals % 2, 0 ); + + for( INDEX_TYPE i = 0; i < nVals / 2; ++i ) + { + T const val( randomInteger( 0, 1000 ) ); + m_array.emplace_back( val ); + m_ref.emplace_back( val ); + + INDEX_TYPE const seed = randomInteger( 0, 1000 ); + m_array.emplace_back( seed ); + m_ref.emplace_back( seed ); + } + + COMPARE_TO_REFERENCE + } + + void emplace( INDEX_TYPE const nToInsert ) + { + COMPARE_TO_REFERENCE + + LVARRAY_ERROR_IF_NE( nToInsert % 2, 0 ); + + for( INDEX_TYPE i = 0; i < nToInsert / 2; ++i ) + { + { + T const val( randomInteger( 0, 1000 ) ); + INDEX_TYPE const position = randomInteger( 0, m_array.size() ); + m_array.emplace( position, val ); + m_ref.emplace( m_ref.begin() + position, val ); + } + + { + INDEX_TYPE const seed = randomInteger( 0, 1000 ); + INDEX_TYPE const position = randomInteger( 0, m_array.size() ); + m_array.emplace( position, seed ); + m_ref.emplace( m_ref.begin() + position, seed ); + } + } + + COMPARE_TO_REFERENCE + } + + void insert( INDEX_TYPE const nToInsert ) + { + COMPARE_TO_REFERENCE + + constexpr INDEX_TYPE MAX_VALS_PER_INSERT = 20; + + INDEX_TYPE nInserted = 0; + while( nInserted < nToInsert ) + { + // Insert from a std::vector + { + INDEX_TYPE const nToInsertThisIter = randomInteger( 0, min( MAX_VALS_PER_INSERT, nToInsert - nInserted ) ); + std::vector< T > valsToInsert( nToInsertThisIter ); + + for( T & val : valsToInsert ) + { val = T( randomInteger( 0, 1000 ) ); } + + INDEX_TYPE const position = randomInteger( 0, m_array.size() ); + m_array.insert( position, valsToInsert.begin(), valsToInsert.end() ); + m_ref.insert( m_ref.begin() + position, valsToInsert.begin(), valsToInsert.end() ); + + nInserted += nToInsertThisIter; + } + + // Insert from a std::list + { + INDEX_TYPE const nToInsertThisIter = randomInteger( 0, min( MAX_VALS_PER_INSERT, nToInsert - nInserted ) ); + std::list< T > valsToInsert( nToInsertThisIter ); + for( T & val : valsToInsert ) + { val = T( randomInteger( 0, 1000 ) ); } + + INDEX_TYPE const position = randomInteger( 0, m_array.size() ); + m_array.insert( position, valsToInsert.begin(), valsToInsert.end() ); + m_ref.insert( m_ref.begin() + position, valsToInsert.begin(), valsToInsert.end() ); + + nInserted += nToInsertThisIter; + } + } + + LVARRAY_ERROR_IF_NE( nInserted, nToInsert ); + COMPARE_TO_REFERENCE + } + + void pop_back( INDEX_TYPE const nToPop ) + { + COMPARE_TO_REFERENCE + + LVARRAY_ERROR_IF_GT( nToPop, m_array.size() ); + + for( INDEX_TYPE i = 0; i < nToPop; ++i ) + { + m_array.pop_back(); + m_ref.pop_back(); + + if( i % 10 == 0 ) + { COMPARE_TO_REFERENCE } + } + + COMPARE_TO_REFERENCE + } + + void erase( std::ptrdiff_t const nToErase ) + { + COMPARE_TO_REFERENCE + + LVARRAY_ERROR_IF_GT( nToErase, m_array.size() ); + + for( std::ptrdiff_t i = 0; i < nToErase; ++i ) + { + std::ptrdiff_t const position = randomInteger( 0, m_array.size() - 1 ); + m_array.erase( position ); + m_ref.erase( m_ref.begin() + position ); + } + + COMPARE_TO_REFERENCE + } + +protected: + + ARRAY1D m_array; + std::vector< T > m_ref; + + #undef COMPARE_TO_REFERENCE +}; + +using Array1DTestTypes = ::testing::Types< + Array< int, 1, RAJA::PERM_I, INDEX_TYPE, MallocBuffer > + , Array< Tensor, 1, RAJA::PERM_I, INDEX_TYPE, MallocBuffer > + , Array< TestString, 1, RAJA::PERM_I, INDEX_TYPE, MallocBuffer > +#if defined(USE_CHAI) + , Array< int, 1, RAJA::PERM_I, INDEX_TYPE, NewChaiBuffer > + , Array< Tensor, 1, RAJA::PERM_I, INDEX_TYPE, NewChaiBuffer > + , Array< TestString, 1, RAJA::PERM_I, INDEX_TYPE, NewChaiBuffer > +#endif + >; + +TYPED_TEST_SUITE( Array1DTest, Array1DTestTypes, ); + +TYPED_TEST( Array1DTest, emplace_back ) +{ + this->emplace_back( 1000 ); +} + +TYPED_TEST( Array1DTest, emplace ) +{ + this->emplace( 100 ); +} + +TYPED_TEST( Array1DTest, pop_back ) +{ + this->emplace_back( 1000 ); + this->pop_back( 400 ); +} + +TYPED_TEST( Array1DTest, erase ) +{ + this->emplace_back( 1000 ); + this->erase( 400 ); +} + +TYPED_TEST( Array1DTest, combinedOperations ) +{ + for( int i = 0; i < 3; ++i ) + { + this->emplace_back( 100 ); + this->erase( 25 ); + this->emplace( 50 ); + this->pop_back( 50 ); + this->erase( 75 ); + } +} + +} // namespace testing +} // namespace LvArray diff --git a/unitTests/testArray1DOfArray1D.cpp b/unitTests/testArray1DOfArray1D.cpp new file mode 100644 index 00000000..47126347 --- /dev/null +++ b/unitTests/testArray1DOfArray1D.cpp @@ -0,0 +1,277 @@ +/* + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Copyright (c) 2019, Lawrence Livermore National Security, LLC. + * + * Produced at the Lawrence Livermore National Laboratory + * + * LLNL-CODE-746361 + * + * All rights reserved. See COPYRIGHT for details. + * + * This file is part of the GEOSX Simulation Framework. + * + * GEOSX is a free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License (as published by the + * Free Software Foundation) version 2.1 dated February 1999. + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +// Source includes +#include "Array.hpp" +#include "streamIO.hpp" +#include "testUtils.hpp" +#include "MallocBuffer.hpp" + +// TPL includes +#include + +// System includes +#include + +namespace LvArray +{ +namespace testing +{ + +using INDEX_TYPE = std::ptrdiff_t; + +inline INDEX_TYPE randomInteger( INDEX_TYPE const min, INDEX_TYPE const max ) +{ + static std::mt19937_64 gen; + return std::uniform_int_distribution< INDEX_TYPE >( min, max )( gen ); +} + +template< typename ARRAY1D_POLICY_PAIR > +class Array1DOfArray1DTest : public ::testing::Test +{ +public: + using ARRAY1D = typename ARRAY1D_POLICY_PAIR::first_type; + using POLICY = typename ARRAY1D_POLICY_PAIR::second_type; + + using T = typename ARRAY1D::value_type; + + template< typename U > + using Array1D = typename ArrayConverter< ARRAY1D >::template Array< U, 1, RAJA::PERM_I >; + + template< typename U > + using ArrayView1D = typename ArrayConverter< ARRAY1D >::template ArrayView< U, 1, 0 >; + + void modifyInKernel() + { + Array1D< Array1D< T > > array; + init( array ); + + ArrayView1D< ArrayView1D< T > const > const & view = array.toView(); + forall< POLICY >( array.size(), [view] LVARRAY_HOST_DEVICE ( INDEX_TYPE const i ) + { + for( INDEX_TYPE j = 0; j < view[ i ].size(); ++j ) + { + view[ i ][ j ] += view[ i ][ j ]; + } + } ); + + forall< serialPolicy >( array.size(), [view] LVARRAY_HOST_DEVICE ( INDEX_TYPE const i ) + { + for( INDEX_TYPE j = 0; j < view[ i ].size(); ++j ) + { + T val( MAX_SIZE * i + j ); + val += val; + PORTABLE_EXPECT_EQ( view[ i ][ j ], val ); + } + } ); + } + + void readInKernel() + { + Array1D< Array1D< T > > array; + init( array ); + + // Create a shallow copy of the inner arrays that we can modify later. + Array1D< ArrayView1D< T > > copy( array.size() ); + for( INDEX_TYPE i = 0; i < array.size(); ++i ) + { copy[ i ] = array[ i ].toView(); } + + // Create a const view and launch a kernel checking the values. + ArrayView1D< ArrayView1D< T const > const > const & viewConst = array.toViewConst(); + forall< POLICY >( array.size(), [viewConst] LVARRAY_HOST_DEVICE ( INDEX_TYPE const i ) + { + for( INDEX_TYPE j = 0; j < viewConst[ i ].size(); ++j ) + { + PORTABLE_EXPECT_EQ( viewConst[ i ][ j ], T( MAX_SIZE * i + j ) ); + } + } ); + + // Modify the copy. We can't directly modify the array since the inner arrays may be on device. + for( INDEX_TYPE i = 0; i < copy.size(); ++i ) + { + for( INDEX_TYPE j = 0; j < copy[ i ].size(); ++j ) + { + copy[ i ][ j ] += copy[ i ][ j ]; + } + } + + // Check that the modifications are present in the original array after launching a host kernel. + forall< serialPolicy >( array.size(), [viewConst] LVARRAY_HOST_DEVICE ( INDEX_TYPE const i ) + { + for( INDEX_TYPE j = 0; j < viewConst[ i ].size(); ++j ) + { + T val( MAX_SIZE * i + j ); + val += val; + PORTABLE_EXPECT_EQ( viewConst[ i ][ j ], val ); + } + } ); + } + + void move() + { + Array1D< Array1D< T > > array; + init( array ); + + array.move( RAJAHelper< POLICY >::space ); + Array1D< T > const * dataPointer = array.data(); + forall< POLICY >( array.size(), [dataPointer] LVARRAY_HOST_DEVICE ( INDEX_TYPE const i ) + { + for( INDEX_TYPE j = 0; j < dataPointer[ i ].size(); ++j ) + { + dataPointer[ i ][ j ] += dataPointer[ i ][ j ]; + } + } ); + + array.move( MemorySpace::CPU ); + dataPointer = array.data(); + forall< serialPolicy >( array.size(), [dataPointer] LVARRAY_HOST_DEVICE ( INDEX_TYPE const i ) + { + for( INDEX_TYPE j = 0; j < dataPointer[ i ].size(); ++j ) + { + T val( MAX_SIZE * i + j ); + val += val; + PORTABLE_EXPECT_EQ( dataPointer[ i ][ j ], val ); + } + } ); + } + + void moveNoTouch() + { + Array1D< Array1D< T > > array; + init( array ); + + // Create a shallow copy of the inner arrays that we can modify later. + Array1D< ArrayView1D< T > > copy( array.size() ); + for( INDEX_TYPE i = 0; i < array.size(); ++i ) + { copy[ i ] = array[ i ].toView(); } + + // Create a const view and launch a kernel checking the values. + array.move( RAJAHelper< POLICY >::space, false ); + Array1D< T > const * dataPointer = array.data(); + forall< POLICY >( array.size(), [dataPointer] LVARRAY_HOST_DEVICE ( INDEX_TYPE const i ) + { + for( INDEX_TYPE j = 0; j < dataPointer[ i ].size(); ++j ) + { + PORTABLE_EXPECT_EQ( dataPointer[ i ][ j ], T( MAX_SIZE * i + j ) ); + } + } ); + + // Modify the copy. We can't directly modify the array since the inner arrays may be on device. + for( INDEX_TYPE i = 0; i < copy.size(); ++i ) + { + for( INDEX_TYPE j = 0; j < copy[ i ].size(); ++j ) + { + copy[ i ][ j ] += copy[ i ][ j ]; + } + } + + // Check that the modifications are present in the original array after launching a host kernel. + array.move( MemorySpace::CPU ); + dataPointer = array.data(); + forall< serialPolicy >( array.size(), [dataPointer] LVARRAY_HOST_DEVICE ( INDEX_TYPE const i ) + { + for( INDEX_TYPE j = 0; j < dataPointer[ i ].size(); ++j ) + { + T val( MAX_SIZE * i + j ); + val += val; + PORTABLE_EXPECT_EQ( dataPointer[ i ][ j ], val ); + } + } ); + } + + void emptyMove() + { + Array1D< Array1D< T > > array( 10 ); + array.move( RAJAHelper< POLICY >::space ); + array.move( MemorySpace::CPU ); + } + +private: + void init( Array1D< Array1D< T > > & array ) + { + array.resize( randomInteger( 1, MAX_SIZE ) ); + + for( INDEX_TYPE i = 0; i < array.size(); ++i ) + { + array[ i ].resize( randomInteger( 0, MAX_SIZE ) ); + + for( INDEX_TYPE j = 0; j < array[ i ].size(); ++j ) + { + array[ i ][ j ] = T( MAX_SIZE * i + j ); + } + } + } + + static constexpr INDEX_TYPE MAX_SIZE = 20; +}; + +template< typename T, template< typename > class BUFFER_TYPE > +using Array1D = Array< T, 1, RAJA::PERM_I, INDEX_TYPE, BUFFER_TYPE >; + +using Array1DOfArray1DTestTypes = ::testing::Types< + std::pair< Array1D< int, MallocBuffer >, serialPolicy > + , std::pair< Array1D< Tensor, MallocBuffer >, serialPolicy > + , std::pair< Array1D< TestString, MallocBuffer >, serialPolicy > +#if defined(USE_CHAI) + , std::pair< Array1D< int, NewChaiBuffer >, serialPolicy > + , std::pair< Array1D< Tensor, NewChaiBuffer >, serialPolicy > + , std::pair< Array1D< TestString, NewChaiBuffer >, serialPolicy > +#endif +#if defined(USE_CUDA) && defined(USE_CHAI) + , std::pair< Array1D< int, NewChaiBuffer >, parallelDevicePolicy< 32 > > + , std::pair< Array1D< Tensor, NewChaiBuffer >, parallelDevicePolicy< 32 > > +#endif + >; + +TYPED_TEST_SUITE( Array1DOfArray1DTest, Array1DOfArray1DTestTypes, ); + +TYPED_TEST( Array1DOfArray1DTest, modifyInKernel ) +{ + this->modifyInKernel(); +} + +TYPED_TEST( Array1DOfArray1DTest, readInKernel ) +{ + this->readInKernel(); +} + +TYPED_TEST( Array1DOfArray1DTest, move ) +{ + this->move(); +} + +TYPED_TEST( Array1DOfArray1DTest, moveNoTouch ) +{ + this->moveNoTouch(); +} + +TYPED_TEST( Array1DOfArray1DTest, emptyMove ) +{ + this->emptyMove(); +} + +} // namespace testing +} // namespace LvArray + +// This is the default gtest main method. It is included for ease of debugging. +int main( int argc, char * * argv ) +{ + ::testing::InitGoogleTest( &argc, argv ); + int const result = RUN_ALL_TESTS(); + return result; +} diff --git a/unitTests/testArray1DOfArray1DOfArray1D.cpp b/unitTests/testArray1DOfArray1DOfArray1D.cpp new file mode 100644 index 00000000..4e9c9ceb --- /dev/null +++ b/unitTests/testArray1DOfArray1DOfArray1D.cpp @@ -0,0 +1,311 @@ +/* + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Copyright (c) 2019, Lawrence Livermore National Security, LLC. + * + * Produced at the Lawrence Livermore National Laboratory + * + * LLNL-CODE-746361 + * + * All rights reserved. See COPYRIGHT for details. + * + * This file is part of the GEOSX Simulation Framework. + * + * GEOSX is a free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License (as published by the + * Free Software Foundation) version 2.1 dated February 1999. + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +// Source includes +#include "Array.hpp" +#include "streamIO.hpp" +#include "testUtils.hpp" +#include "MallocBuffer.hpp" + +// TPL includes +#include + +// System includes +#include + +namespace LvArray +{ +namespace testing +{ + +using INDEX_TYPE = std::ptrdiff_t; + +inline INDEX_TYPE randomInteger( INDEX_TYPE const min, INDEX_TYPE const max ) +{ + static std::mt19937_64 gen; + return std::uniform_int_distribution< INDEX_TYPE >( min, max )( gen ); +} + +template< typename ARRAY1D_POLICY_PAIR > +class Array1DOfArray1DOfArray1DTest : public ::testing::Test +{ +public: + using ARRAY1D = typename ARRAY1D_POLICY_PAIR::first_type; + using POLICY = typename ARRAY1D_POLICY_PAIR::second_type; + + using T = typename ARRAY1D::value_type; + + template< typename U > + using Array1D = typename ArrayConverter< ARRAY1D >::template Array< U, 1, RAJA::PERM_I >; + + template< typename U > + using ArrayView1D = typename ArrayConverter< ARRAY1D >::template ArrayView< U, 1, 0 >; + + void modifyInKernel() + { + Array1D< Array1D< Array1D< T > > > array; + init( array ); + + ArrayView1D< ArrayView1D< ArrayView1D< T > const > const > const & view = array.toView(); + forall< POLICY >( array.size(), [view] LVARRAY_HOST_DEVICE ( INDEX_TYPE const i ) + { + for( INDEX_TYPE j = 0; j < view[ i ].size(); ++j ) + { + for( INDEX_TYPE k = 0; k < view[ i ][ j ].size(); ++k ) + { + view[ i ][ j ][ k ] += view[ i ][ j ][ k ]; + } + } + } ); + + forall< serialPolicy >( array.size(), [view] LVARRAY_HOST_DEVICE ( INDEX_TYPE const i ) + { + for( INDEX_TYPE j = 0; j < view[ i ].size(); ++j ) + { + for( INDEX_TYPE k = 0; k < view[ i ][ j ].size(); ++k ) + { + T val( MAX_SIZE * MAX_SIZE * i + MAX_SIZE * j + k ); + val += val; + PORTABLE_EXPECT_EQ( view[ i ][ j ][ k ], val ); + } + } + } ); + } + + void readInKernel() + { + Array1D< Array1D< Array1D< T > > > array; + init( array ); + + // Create a shallow copy of the inner arrays that we can modify later. + Array1D< Array1D< ArrayView1D< T > > > copy( array.size() ); + for( INDEX_TYPE i = 0; i < array.size(); ++i ) + { + copy[ i ].resize( array[ i ].size() ); + for( INDEX_TYPE j = 0; j < array[ i ].size(); ++j ) + { + copy[ i ][ j ] = array[ i ][ j ].toView(); + } + } + + // Create a const view and launch a kernel checking the values. + ArrayView1D< ArrayView1D< ArrayView1D< T const > const > const > const & viewConst = array.toViewConst(); + forall< POLICY >( array.size(), [viewConst] LVARRAY_HOST_DEVICE ( INDEX_TYPE const i ) + { + for( INDEX_TYPE j = 0; j < viewConst[ i ].size(); ++j ) + { + for( INDEX_TYPE k = 0; k < viewConst[ i ][ j ].size(); ++k ) + { + PORTABLE_EXPECT_EQ( viewConst[ i ][ j ][ k ], T( MAX_SIZE * MAX_SIZE * i + MAX_SIZE * j + k ) ); + } + } + } ); + + // Modify the copy. We can't directly modify the array since the inner arrays may be on device. + for( INDEX_TYPE i = 0; i < copy.size(); ++i ) + { + for( INDEX_TYPE j = 0; j < copy[ i ].size(); ++j ) + { + for( INDEX_TYPE k = 0; k < copy[ i ][ j ].size(); ++k ) + { + copy[ i ][ j ][ k ] += copy[ i ][ j ][ k ]; + } + } + } + + // Check that the modifications are present in the original array after launching a host kernel. + forall< serialPolicy >( array.size(), [viewConst] LVARRAY_HOST_DEVICE ( INDEX_TYPE const i ) + { + for( INDEX_TYPE j = 0; j < viewConst[ i ].size(); ++j ) + { + for( INDEX_TYPE k = 0; k < viewConst[ i ][ j ].size(); ++k ) + { + T val( MAX_SIZE * MAX_SIZE * i + MAX_SIZE * j + k ); + val += val; + PORTABLE_EXPECT_EQ( viewConst[ i ][ j ][ k ], val ); + } + } + } ); + } + + void move() + { + Array1D< Array1D< Array1D< T > > > array; + init( array ); + + array.move( RAJAHelper< POLICY >::space ); + Array1D< Array1D< T > > const * dataPointer = array.data(); + forall< POLICY >( array.size(), [dataPointer] LVARRAY_HOST_DEVICE ( INDEX_TYPE const i ) + { + for( INDEX_TYPE j = 0; j < dataPointer[ i ].size(); ++j ) + { + for( INDEX_TYPE k = 0; k < dataPointer[ i ][ j ].size(); ++k ) + { + dataPointer[ i ][ j ][ k ] += dataPointer[ i ][ j ][ k ]; + } + } + } ); + + array.move( MemorySpace::CPU ); + dataPointer = array.data(); + forall< serialPolicy >( array.size(), [dataPointer] LVARRAY_HOST_DEVICE ( INDEX_TYPE const i ) + { + for( INDEX_TYPE j = 0; j < dataPointer[ i ].size(); ++j ) + { + for( INDEX_TYPE k = 0; k < dataPointer[ i ][ j ].size(); ++k ) + { + T val( MAX_SIZE * MAX_SIZE * i + MAX_SIZE * j + k ); + val += val; + PORTABLE_EXPECT_EQ( dataPointer[ i ][ j ][ k ], val ); + } + } + } ); + } + + void moveNoTouch() + { + Array1D< Array1D< Array1D< T > > > array; + init( array ); + + // Create a shallow copy of the inner arrays that we can modify later. + Array1D< Array1D< ArrayView1D< T > > > copy( array.size() ); + for( INDEX_TYPE i = 0; i < array.size(); ++i ) + { + copy[ i ].resize( array[ i ].size() ); + for( INDEX_TYPE j = 0; j < array[ i ].size(); ++j ) + { + copy[ i ][ j ] = array[ i ][ j ].toView(); + } + } + + // Create a const view and launch a kernel checking the values. + array.move( RAJAHelper< POLICY >::space, false ); + Array1D< Array1D< T > > const * dataPointer = array.data(); + forall< POLICY >( array.size(), [dataPointer] LVARRAY_HOST_DEVICE ( INDEX_TYPE const i ) + { + for( INDEX_TYPE j = 0; j < dataPointer[ i ].size(); ++j ) + { + for( INDEX_TYPE k = 0; k < dataPointer[ i ][ j ].size(); ++k ) + { + PORTABLE_EXPECT_EQ( dataPointer[ i ][ j ][ k ], T( MAX_SIZE * MAX_SIZE * i + MAX_SIZE * j + k ) ); + } + } + } ); + + // Modify the copy. We can't directly modify the array since the inner arrays may be on device. + for( INDEX_TYPE i = 0; i < copy.size(); ++i ) + { + for( INDEX_TYPE j = 0; j < copy[ i ].size(); ++j ) + { + for( INDEX_TYPE k = 0; k < copy[ i ][ j ].size(); ++k ) + { + copy[ i ][ j ][ k ] += copy[ i ][ j ][ k ]; + } + } + } + + // Check that the modifications are present in the original array after launching a host kernel. + array.move( MemorySpace::CPU, false ); + dataPointer = array.data(); + forall< serialPolicy >( array.size(), [dataPointer] LVARRAY_HOST_DEVICE ( INDEX_TYPE const i ) + { + for( INDEX_TYPE j = 0; j < dataPointer[ i ].size(); ++j ) + { + for( INDEX_TYPE k = 0; k < dataPointer[ i ][ j ].size(); ++k ) + { + T val( MAX_SIZE * MAX_SIZE * i + MAX_SIZE * j + k ); + val += val; + PORTABLE_EXPECT_EQ( dataPointer[ i ][ j ][ k ], val ); + } + } + } ); + } + +private: + void init( Array1D< Array1D< Array1D< T > > > & array ) + { + array.resize( randomInteger( 1, MAX_SIZE ) ); + + for( INDEX_TYPE i = 0; i < array.size(); ++i ) + { + array[ i ].resize( randomInteger( 0, MAX_SIZE ) ); + + for( INDEX_TYPE j = 0; j < array[ i ].size(); ++j ) + { + array[ i ][ j ].resize( randomInteger( 0, MAX_SIZE ) ); + for( INDEX_TYPE k = 0; k < array[ i ][ j ].size(); ++k ) + { + array[ i ][ j ][ k ] = T( MAX_SIZE * MAX_SIZE * i + MAX_SIZE * j + k ); + } + } + } + } + + static constexpr INDEX_TYPE MAX_SIZE = 20; +}; + +template< typename T, template< typename > class BUFFER_TYPE > +using Array1D = Array< T, 1, RAJA::PERM_I, INDEX_TYPE, BUFFER_TYPE >; + +using Array1DOfArray1DOfArray1DTestTypes = ::testing::Types< + std::pair< Array1D< int, MallocBuffer >, serialPolicy > + , std::pair< Array1D< Tensor, MallocBuffer >, serialPolicy > + , std::pair< Array1D< TestString, MallocBuffer >, serialPolicy > +#if defined(USE_CHAI) + , std::pair< Array1D< int, NewChaiBuffer >, serialPolicy > + , std::pair< Array1D< Tensor, NewChaiBuffer >, serialPolicy > + , std::pair< Array1D< TestString, NewChaiBuffer >, serialPolicy > +#endif +#if defined(USE_CUDA) && defined(USE_CHAI) + , std::pair< Array1D< int, NewChaiBuffer >, parallelDevicePolicy< 32 > > + , std::pair< Array1D< Tensor, NewChaiBuffer >, parallelDevicePolicy< 32 > > +#endif + >; + +TYPED_TEST_SUITE( Array1DOfArray1DOfArray1DTest, Array1DOfArray1DOfArray1DTestTypes, ); + +TYPED_TEST( Array1DOfArray1DOfArray1DTest, modifyInKernel ) +{ + this->modifyInKernel(); +} + +TYPED_TEST( Array1DOfArray1DOfArray1DTest, readInKernel ) +{ + this->readInKernel(); +} + +TYPED_TEST( Array1DOfArray1DOfArray1DTest, move ) +{ + this->move(); +} + +TYPED_TEST( Array1DOfArray1DOfArray1DTest, moveNoTouch ) +{ + this->moveNoTouch(); +} + +} // namespace testing +} // namespace LvArray + +// This is the default gtest main method. It is included for ease of debugging. +int main( int argc, char * * argv ) +{ + ::testing::InitGoogleTest( &argc, argv ); + int const result = RUN_ALL_TESTS(); + return result; +} diff --git a/unitTests/testArrayOfArrays.cpp b/unitTests/testArrayOfArrays.cpp index 4c12c0e1..f986b5b8 100644 --- a/unitTests/testArrayOfArrays.cpp +++ b/unitTests/testArrayOfArrays.cpp @@ -21,23 +21,15 @@ #include "ArrayOfArrays.hpp" #include "testUtils.hpp" #include "Array.hpp" +#include "MallocBuffer.hpp" // TPL includes #include -#ifdef USE_CHAI - #include -#endif - // System includes #include #include -#ifdef USE_OMP - #include -#endif - - namespace LvArray { namespace testing @@ -45,52 +37,21 @@ namespace testing using INDEX_TYPE = std::ptrdiff_t; -template< class T, bool CONST_SIZES=false > -using ViewType = ArrayOfArraysView< T, INDEX_TYPE const, CONST_SIZES >; - -template< class T > -void compareToReference( ViewType< T const, true > const & view, std::vector< std::vector< T > > const & ref ) -{ - ASSERT_EQ( view.size(), ref.size()); - - for( INDEX_TYPE i = 0; i < view.size(); ++i ) - { - ASSERT_EQ( view.sizeOfArray( i ), ref[i].size()); - - for( INDEX_TYPE j = 0; j < view.sizeOfArray( i ); ++j ) - { - EXPECT_EQ( view[i][j], ref[i][j] ); - EXPECT_EQ( view( i, j ), view[i][j] ); - } - - INDEX_TYPE j = 0; - for( T const & val : view.getIterableArray( i )) - { - EXPECT_EQ( val, ref[i][j] ); - ++j; - } - - EXPECT_EQ( j, view.sizeOfArray( i )); - } -} - -#define COMPARE_TO_REFERENCE( view, ref ) { SCOPED_TRACE( "" ); compareToReference( view, ref ); \ -} - -template< class T > -void printArray( ViewType< T const, true > const & view ) +// This is for debugging. +template< typename ARRAY_OF_ARRAYS > +void print( ARRAY_OF_ARRAYS const & array ) { std::cout << "{" << std::endl; - for( INDEX_TYPE i = 0; i < view.size(); ++i ) + for( INDEX_TYPE i = 0; i < array.size(); ++i ) { std::cout << "\t{"; - for( INDEX_TYPE j = 0; j < view.sizeOfArray( i ); ++j ) + for( INDEX_TYPE j = 0; j < array.sizeOfArray( i ); ++j ) { - std::cout << view[i][j] << ", "; + std::cout << array[ i ][ j ] << ", "; } - for( INDEX_TYPE j = view.sizeOfArray( i ); j < view.capacityOfArray( i ); ++j ) + for( INDEX_TYPE j = array.sizeOfArray( i ); j < array.capacityOfArray( i ); ++j ) { std::cout << "X" << ", "; } @@ -101,37 +62,83 @@ void printArray( ViewType< T const, true > const & view ) std::cout << "}" << std::endl; } -template< class T > +template< class ARRAY_OF_ARRAYS > class ArrayOfArraysTest : public ::testing::Test { public: + using T = typename ARRAY_OF_ARRAYS::value_type; + + using ViewType = std::remove_reference_t< decltype( std::declval< ARRAY_OF_ARRAYS >().toView() ) >; + using ViewTypeConstSizes = std::remove_reference_t< decltype( std::declval< ARRAY_OF_ARRAYS >().toViewConstSizes() ) >; + using ViewTypeConst = std::remove_reference_t< decltype( std::declval< ARRAY_OF_ARRAYS >().toViewConst() ) >; + + void compareToReference( ViewTypeConst const & view ) const + { + ASSERT_EQ( view.size(), m_ref.size()); + + for( INDEX_TYPE i = 0; i < view.size(); ++i ) + { + ASSERT_EQ( view.sizeOfArray( i ), m_ref[ i ].size()); + + for( INDEX_TYPE j = 0; j < view.sizeOfArray( i ); ++j ) + { + EXPECT_EQ( view[ i ][ j ], m_ref[ i ][ j ] ); + EXPECT_EQ( view( i, j ), view[ i ][ j ] ); + } + + INDEX_TYPE j = 0; + for( T const & val : view[ i ] ) + { + EXPECT_EQ( val, m_ref[ i ][ j ] ); + ++j; + } + + EXPECT_EQ( j, view.sizeOfArray( i )); + } + } + + #define COMPARE_TO_REFERENCE { SCOPED_TRACE( "" ); this->compareToReference( m_array.toViewConst() ); \ + } void appendArray( INDEX_TYPE const nArrays, INDEX_TYPE const maxAppendSize ) { - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE; - std::vector< T > arrayToAppend( maxAppendSize ); + LVARRAY_ERROR_IF_NE( nArrays % 2, 0 ); - for( INDEX_TYPE i = 0; i < nArrays; ++i ) + for( INDEX_TYPE i = 0; i < nArrays / 2; ++i ) { - INDEX_TYPE const nValues = rand( 0, maxAppendSize ); - arrayToAppend.resize( nValues ); - - for( INDEX_TYPE j = 0; j < nValues; ++j ) + // Append using a std::vector. { - arrayToAppend[j] = T( i * LARGE_NUMBER + j ); + INDEX_TYPE const nValues = rand( 0, maxAppendSize ); + + std::vector< T > toAppend; + for( INDEX_TYPE j = 0; j < nValues; ++j ) + { toAppend.emplace_back( 2 * i * LARGE_NUMBER + j ); } + + m_array.appendArray( toAppend.begin(), toAppend.end() ); + m_ref.emplace_back( toAppend.begin(), toAppend.end() ); } - m_array.appendArray( arrayToAppend.data(), arrayToAppend.size()); - m_ref.push_back( arrayToAppend ); + // Append using a std::list. + { + INDEX_TYPE const nValues = rand( 0, maxAppendSize ); + + std::list< T > toAppend; + for( INDEX_TYPE j = 0; j < nValues; ++j ) + { toAppend.emplace_back( ( 2 * i + 1 ) * LARGE_NUMBER + j ); } + + m_array.appendArray( toAppend.begin(), toAppend.end() ); + m_ref.emplace_back( toAppend.begin(), toAppend.end() ); + } } - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE; } void appendArray2( INDEX_TYPE const nArrays, INDEX_TYPE const maxAppendSize ) { - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE; std::vector< T > arrayToAppend( maxAppendSize ); @@ -144,43 +151,57 @@ class ArrayOfArraysTest : public ::testing::Test for( INDEX_TYPE j = 0; j < nValues; ++j ) { T const value = T( i * LARGE_NUMBER + j ); - arrayToAppend[j] = value; + arrayToAppend[ j ] = value; m_array( m_array.size() - 1, j ) = value; } m_ref.push_back( arrayToAppend ); } - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE; } void insertArray( INDEX_TYPE const nArrays, INDEX_TYPE const maxAppendSize ) { - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE; - std::vector< T > arrayToAppend( maxAppendSize ); + LVARRAY_ERROR_IF_NE( nArrays % 2, 0 ); for( INDEX_TYPE i = 0; i < nArrays; ++i ) { - INDEX_TYPE const nValues = rand( 0, maxAppendSize ); - arrayToAppend.resize( nValues ); - - for( INDEX_TYPE j = 0; j < nValues; ++j ) + // Insert using a std::vector { - arrayToAppend[j] = T( i * LARGE_NUMBER + j ); + INDEX_TYPE const nValues = rand( 0, maxAppendSize ); + + std::vector< T > toInsert; + for( INDEX_TYPE j = 0; j < nValues; ++j ) + { toInsert.emplace_back( 2 * i * LARGE_NUMBER + j ); } + + INDEX_TYPE const insertPos = rand( 0, m_array.size() ); + m_array.insertArray( insertPos, toInsert.begin(), toInsert.end() ); + m_ref.emplace( m_ref.begin() + insertPos, toInsert.begin(), toInsert.end() ); } - INDEX_TYPE insertPos = rand( 0, m_array.size()); - m_array.insertArray( insertPos, arrayToAppend.data(), arrayToAppend.size()); - m_ref.insert( m_ref.begin() + insertPos, arrayToAppend ); + // Insert using a std::list + { + INDEX_TYPE const nValues = rand( 0, maxAppendSize ); + + std::list< T > toInsert; + for( INDEX_TYPE j = 0; j < nValues; ++j ) + { toInsert.emplace_back( ( 2 * i + 1 ) * LARGE_NUMBER + j ); } + + INDEX_TYPE const insertPos = rand( 0, m_array.size() ); + m_array.insertArray( insertPos, toInsert.begin(), toInsert.end() ); + m_ref.emplace( m_ref.begin() + insertPos, toInsert.begin(), toInsert.end() ); + } } - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE; } void eraseArray( INDEX_TYPE const nArrays ) { - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE; for( INDEX_TYPE i = 0; i < nArrays; ++i ) { @@ -189,12 +210,12 @@ class ArrayOfArraysTest : public ::testing::Test m_ref.erase( m_ref.begin() + removePos ); } - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE; } void resize( INDEX_TYPE const newSize, INDEX_TYPE const capacityPerArray=0 ) { - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE; std::vector< INDEX_TYPE > oldSizes; std::vector< INDEX_TYPE > oldCapacities; @@ -220,13 +241,13 @@ class ArrayOfArraysTest : public ::testing::Test m_ref.resize( newSize ); - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE; } template< typename POLICY > void resizeFromCapacities( INDEX_TYPE const newSize, INDEX_TYPE const maxCapacity ) { - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE; std::vector< INDEX_TYPE > newCapacities( newSize ); @@ -246,23 +267,23 @@ class ArrayOfArraysTest : public ::testing::Test m_ref.clear(); m_ref.resize( newSize ); - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE; } void resize() { - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE; INDEX_TYPE const newSize = rand( 0, 2 * m_array.size()); m_array.resize( newSize ); m_ref.resize( newSize ); - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE; } void resizeArray( INDEX_TYPE const maxSize ) { - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE; INDEX_TYPE const nArrays = m_array.size(); for( INDEX_TYPE i = 0; i < nArrays; ++i ) @@ -271,194 +292,148 @@ class ArrayOfArraysTest : public ::testing::Test T const defaultValue = T( i ); m_array.resizeArray( i, newSize, defaultValue ); - m_ref[i].resize( newSize, defaultValue ); + m_ref[ i ].resize( newSize, defaultValue ); } - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE; } - void appendToArray( INDEX_TYPE const maxAppendSize ) + void emplaceBack( INDEX_TYPE const maxAppendSize ) { - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE; INDEX_TYPE const nArrays = m_array.size(); for( INDEX_TYPE i = 0; i < nArrays; ++i ) { - INDEX_TYPE const nValues = rand( 0, maxAppendSize ); + INDEX_TYPE const nValues = 2 * rand( 0, maxAppendSize / 2 ); INDEX_TYPE const arraySize = m_array.sizeOfArray( i ); for( INDEX_TYPE j = 0; j < nValues; ++j ) { - T const value = T( i * LARGE_NUMBER + arraySize + j ); - m_array.appendToArray( i, value ); - m_ref[i].push_back( value ); + T const value = T( i * LARGE_NUMBER + arraySize + 2 * j ); + m_array.emplaceBack( i, value ); + m_ref[ i ].emplace_back( value ); + + INDEX_TYPE const seed = i * LARGE_NUMBER + arraySize + 2 * j + 1; + m_array.emplaceBack( i, seed ); + m_ref[ i ].emplace_back( seed ); } } - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE; } - void atomicAppendToArraySerial( INDEX_TYPE const numAppends ) + void appendToArray( INDEX_TYPE const maxAppendSize ) { - INDEX_TYPE const nArrays = m_array.size(); + COMPARE_TO_REFERENCE; - for( INDEX_TYPE i = 0; i < nArrays; ++i ) - { - ASSERT_EQ( m_array.sizeOfArray( i ), 0 ); - } + INDEX_TYPE const nArrays = m_array.size(); - // Append sequential values to each array for( INDEX_TYPE i = 0; i < nArrays; ++i ) { - for( INDEX_TYPE j = 0; j < numAppends; ++j ) + // Append using a std::vector. { - T const value = T( i * LARGE_NUMBER + j ); - m_array.atomicAppendToArray( RAJA::auto_atomic{}, i, value ); - } - } + INDEX_TYPE const nValues = rand( 0, maxAppendSize / 2 ); + INDEX_TYPE const arraySize = m_array.sizeOfArray( i ); - // Now check that the values are as expected. - for( INDEX_TYPE i = 0; i < nArrays; ++i ) - { - ASSERT_EQ( m_array.sizeOfArray( i ), numAppends ); - ASSERT_LE( m_array.sizeOfArray( i ), m_array.capacityOfArray( i )); + std::vector< T > toAppend; + for( INDEX_TYPE j = 0; j < nValues; ++j ) + { toAppend.emplace_back( i * LARGE_NUMBER + arraySize + j ); } - for( INDEX_TYPE j = 0; j < numAppends; ++j ) - { - T const value = T( i * LARGE_NUMBER + j ); - EXPECT_EQ( value, m_array( i, j )) << i << ", " << j; + m_array.appendToArray( i, toAppend.begin(), toAppend.end() ); + m_ref[ i ].insert( m_ref[ i ].end(), toAppend.begin(), toAppend.end() ); } - } - } - -#ifdef USE_OPENMP - void atomicAppendToArrayOMP( INDEX_TYPE const appendsPerArrayPerThread ) - { - INDEX_TYPE const nArrays = m_array.size(); - - for( INDEX_TYPE i = 0; i < nArrays; ++i ) - { - ASSERT_EQ( m_array.sizeOfArray( i ), 0 ); - } - - INDEX_TYPE numThreads; - - #pragma omp parallel - { - #pragma omp master - numThreads = omp_get_num_threads(); - - INDEX_TYPE const threadNum = omp_get_thread_num(); - // In parallel append sequential values to each array. - for( INDEX_TYPE i = 0; i < nArrays; ++i ) + // Append using a std::list. { - for( INDEX_TYPE j = 0; j < appendsPerArrayPerThread; ++j ) - { - T const value = T( i * LARGE_NUMBER + threadNum * appendsPerArrayPerThread + j ); - m_array.atomicAppendToArray( RAJA::auto_atomic{}, i, value ); - } - } - } + INDEX_TYPE const nValues = rand( 0, maxAppendSize / 2 ); + INDEX_TYPE const arraySize = m_array.sizeOfArray( i ); - LVARRAY_LOG( "Used " << numThreads << " threads." ); + std::list< T > toAppend; + for( INDEX_TYPE j = 0; j < nValues; ++j ) + { toAppend.emplace_back( i * LARGE_NUMBER + arraySize + j ); } - // Now sort each array and check that the values are as expected. - INDEX_TYPE const appendsPerArray = numThreads * appendsPerArrayPerThread; - for( INDEX_TYPE i = 0; i < nArrays; ++i ) - { - ASSERT_EQ( m_array.sizeOfArray( i ), appendsPerArray ); - ASSERT_LE( m_array.sizeOfArray( i ), m_array.capacityOfArray( i )); - - T * const subArrayPtr = m_array[i]; - std::sort( subArrayPtr, subArrayPtr + appendsPerArray ); - - for( INDEX_TYPE j = 0; j < appendsPerArray; ++j ) - { - T const value = T( i * LARGE_NUMBER + j ); - EXPECT_EQ( value, m_array( i, j )) << i << ", " << j; + m_array.appendToArray( i, toAppend.begin(), toAppend.end() ); + m_ref[ i ].insert( m_ref[ i ].end(), toAppend.begin(), toAppend.end() ); } } + + COMPARE_TO_REFERENCE; } -#endif - void appendMultipleToArray( INDEX_TYPE const maxAppendSize ) + void emplace( INDEX_TYPE const maxInsertSize ) { - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE; - std::vector< T > valuesToAppend( maxAppendSize ); INDEX_TYPE const nArrays = m_array.size(); - for( INDEX_TYPE i = 0; i < nArrays; ++i ) { - INDEX_TYPE const nValues = rand( 0, maxAppendSize ); - valuesToAppend.resize( nValues ); INDEX_TYPE const arraySize = m_array.sizeOfArray( i ); - + INDEX_TYPE const nValues = 2 * rand( 0, maxInsertSize / 2 ); for( INDEX_TYPE j = 0; j < nValues; ++j ) { - valuesToAppend[j] = T( i * LARGE_NUMBER + arraySize + j ); - } + { + T const value = T( i * LARGE_NUMBER + arraySize + 2 * j ); + INDEX_TYPE const insertPos = rand( 0, arraySize + 2 * j ); + m_array.emplace( i, insertPos, value ); + m_ref[ i ].insert( m_ref[ i ].begin() + insertPos, value ); + } - m_array.appendToArray( i, valuesToAppend.data(), valuesToAppend.size()); - m_ref[i].insert( m_ref[i].end(), valuesToAppend.begin(), valuesToAppend.end()); + { + INDEX_TYPE const seed = i * LARGE_NUMBER + arraySize + 2 * j + 1; + INDEX_TYPE const insertPos = rand( 0, arraySize + 2 * j + 1 ); + m_array.emplace( i, insertPos, seed ); + m_ref[ i ].emplace( m_ref[ i ].begin() + insertPos, seed ); + } + } } - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE; } void insertIntoArray( INDEX_TYPE const maxInsertSize ) { - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE; + INDEX_TYPE const nArrays = m_array.size(); for( INDEX_TYPE i = 0; i < nArrays; ++i ) { - INDEX_TYPE const arraySize = m_array.sizeOfArray( i ); - INDEX_TYPE const nValues = rand( 0, maxInsertSize ); - for( INDEX_TYPE j = 0; j < nValues; ++j ) + // Insert using a std::vector { - T const value = T( i * LARGE_NUMBER + arraySize + j ); - - INDEX_TYPE const insertPos = rand( 0, arraySize + j ); - m_array.insertIntoArray( i, insertPos, value ); - m_ref[i].insert( m_ref[i].begin() + insertPos, value ); - } - } - - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); - } - - void insertMultipleIntoArray( INDEX_TYPE const maxInsertSize ) - { - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + INDEX_TYPE const nValues = rand( 0, maxInsertSize / 2 ); + INDEX_TYPE const arraySize = m_array.sizeOfArray( i ); - std::vector< T > valuesToAppend( maxInsertSize ); + std::vector< T > toInsert; + for( INDEX_TYPE j = 0; j < nValues; ++j ) + { toInsert.emplace_back( i * LARGE_NUMBER + arraySize + j ); } - INDEX_TYPE const nArrays = m_array.size(); - for( INDEX_TYPE i = 0; i < nArrays; ++i ) - { - INDEX_TYPE const nValues = rand( 0, maxInsertSize ); - valuesToAppend.resize( nValues ); + INDEX_TYPE const insertPos = rand( 0, arraySize ); + m_array.insertIntoArray( i, insertPos, toInsert.begin(), toInsert.end() ); + m_ref[ i ].insert( m_ref[ i ].begin() + insertPos, toInsert.begin(), toInsert.end() ); + } - INDEX_TYPE const arraySize = m_array.sizeOfArray( i ); - for( INDEX_TYPE j = 0; j < nValues; ++j ) + // Insert using a std::list { - valuesToAppend[j] = T( i * LARGE_NUMBER + arraySize + j ); - } + INDEX_TYPE const nValues = rand( 0, maxInsertSize / 2 ); + INDEX_TYPE const arraySize = m_array.sizeOfArray( i ); - INDEX_TYPE const insertPos = rand( 0, arraySize ); + std::list< T > toInsert; + for( INDEX_TYPE j = 0; j < nValues; ++j ) + { toInsert.emplace_back( i * LARGE_NUMBER + arraySize + j ); } - m_array.insertIntoArray( i, insertPos, valuesToAppend.data(), valuesToAppend.size()); - m_ref[i].insert( m_ref[i].begin() + insertPos, valuesToAppend.begin(), valuesToAppend.end()); + INDEX_TYPE const insertPos = rand( 0, arraySize ); + m_array.insertIntoArray( i, insertPos, toInsert.begin(), toInsert.end() ); + m_ref[ i ].insert( m_ref[ i ].begin() + insertPos, toInsert.begin(), toInsert.end() ); + } } - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE; } void eraseFromArray( INDEX_TYPE const maxRemoves ) { - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE; INDEX_TYPE const nArrays = m_array.size(); for( INDEX_TYPE i = 0; i < nArrays; ++i ) @@ -470,16 +445,16 @@ class ArrayOfArraysTest : public ::testing::Test INDEX_TYPE const removePosition = rand( 0, arraySize - j - 1 ); m_array.eraseFromArray( i, removePosition ); - m_ref[i].erase( m_ref[i].begin() + removePosition ); + m_ref[ i ].erase( m_ref[ i ].begin() + removePosition ); } } - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE; } - void removeMultipleFromArray( INDEX_TYPE const maxRemoves ) + void eraseMultipleFromArray( INDEX_TYPE const maxRemoves ) { - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE; INDEX_TYPE const nArrays = m_array.size(); for( INDEX_TYPE i = 0; i < nArrays; ++i ) @@ -491,15 +466,15 @@ class ArrayOfArraysTest : public ::testing::Test INDEX_TYPE const nToRemove = rand( 0, min( maxRemoves, arraySize - removePosition )); m_array.eraseFromArray( i, removePosition, nToRemove ); - m_ref[i].erase( m_ref[i].begin() + removePosition, m_ref[i].begin() + removePosition + nToRemove ); + m_ref[ i ].erase( m_ref[ i ].begin() + removePosition, m_ref[ i ].begin() + removePosition + nToRemove ); } - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE; } void compress() { - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE; m_array.compress(); T const * const values = m_array[0]; @@ -509,18 +484,18 @@ class ArrayOfArraysTest : public ::testing::Test { ASSERT_EQ( m_array.sizeOfArray( i ), m_array.capacityOfArray( i )); - T const * const curValues = m_array[i]; + T const * const curValues = m_array[ i ]; ASSERT_EQ( values + curOffset, curValues ); curOffset += m_array.sizeOfArray( i ); } - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE; } void fill() { - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE; T const * const values = m_array[0]; T const * const endValues = m_array[m_array.size() - 1]; @@ -535,12 +510,12 @@ class ArrayOfArraysTest : public ::testing::Test ASSERT_EQ( values, newValues ); ASSERT_EQ( endValues, newEndValues ); - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE; } void capacityOfArray( INDEX_TYPE const maxCapacity ) { - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE; for( INDEX_TYPE i = 0; i < m_array.size(); ++i ) { @@ -549,12 +524,12 @@ class ArrayOfArraysTest : public ::testing::Test if( newCapacity < capacity ) { - T const * const values = m_array[i]; + T const * const values = m_array[ i ]; m_array.setCapacityOfArray( i, newCapacity ); - T const * const newValues = m_array[i]; + T const * const newValues = m_array[ i ]; ASSERT_EQ( values, newValues ); - m_ref[i].resize( newCapacity ); + m_ref[ i ].resize( newCapacity ); } else { @@ -563,14 +538,14 @@ class ArrayOfArraysTest : public ::testing::Test } } - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE; } void deepCopy() { - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE; - ArrayOfArrays< T > copy( m_array ); + ARRAY_OF_ARRAYS copy( m_array ); ASSERT_EQ( m_array.size(), copy.size()); @@ -579,23 +554,23 @@ class ArrayOfArraysTest : public ::testing::Test INDEX_TYPE const arraySize = m_array.sizeOfArray( i ); ASSERT_EQ( arraySize, copy.sizeOfArray( i )); - T const * const values = m_array[i]; - T const * const valuesCopy = copy[i]; + T const * const values = m_array[ i ]; + T const * const valuesCopy = copy[ i ]; ASSERT_NE( values, valuesCopy ); for( INDEX_TYPE j = 0; j < arraySize; ++j ) { - ASSERT_EQ( m_array[i][j], copy[i][j] ); - copy[i][j] = T( -i * LARGE_NUMBER - j ); + ASSERT_EQ( m_array[ i ][ j ], copy[ i ][ j ] ); + copy[ i ][ j ] = T( -i * LARGE_NUMBER - j ); } } - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE; } void shallowCopy() { - ViewType< T > const copy( m_array.toView()); + ViewType const copy( m_array.toView() ); ASSERT_EQ( m_array.size(), copy.size()); @@ -603,18 +578,18 @@ class ArrayOfArraysTest : public ::testing::Test { INDEX_TYPE const arraySize = m_array.sizeOfArray( i ); ASSERT_EQ( arraySize, copy.sizeOfArray( i )); - T const * const values = m_array[i]; - T const * const valuesCopy = copy[i]; + T const * const values = m_array[ i ]; + T const * const valuesCopy = copy[ i ]; ASSERT_EQ( values, valuesCopy ); for( INDEX_TYPE j = 0; j < arraySize; ++j ) { - ASSERT_EQ( m_array[i][j], copy[i][j] ); + ASSERT_EQ( m_array[ i ][ j ], copy[ i ][ j ] ); - copy[i][j] = T( -i * LARGE_NUMBER - j ); + copy[ i ][ j ] = T( -i * LARGE_NUMBER - j ); - ASSERT_EQ( m_array[i][j], T( -i * LARGE_NUMBER - j )); - ASSERT_EQ( m_array[i][j], copy[i][j] ); + ASSERT_EQ( m_array[ i ][ j ], T( -i * LARGE_NUMBER - j )); + ASSERT_EQ( m_array[ i ][ j ], copy[ i ][ j ] ); } } } @@ -625,18 +600,18 @@ class ArrayOfArraysTest : public ::testing::Test { INDEX_TYPE const arraySize = m_array.sizeOfArray( i ); INDEX_TYPE const nToAppend = m_array.capacityOfArray( i ) - arraySize; - T const * const values = m_array[i]; + T const * const values = m_array[ i ]; T const * const endValues = m_array[m_array.size() - 1]; INDEX_TYPE const capacity = m_array.capacityOfArray( i ); for( INDEX_TYPE j = 0; j < nToAppend; ++j ) { T const valueToAppend( LARGE_NUMBER * i + j ); - m_array.appendToArray( i, valueToAppend ); - m_ref[i].push_back( valueToAppend ); + m_array.emplaceBack( i, valueToAppend ); + m_ref[ i ].emplace_back( valueToAppend ); } - T const * const newValues = m_array[i]; + T const * const newValues = m_array[ i ]; T const * const newEndValues = m_array[m_array.size() - 1]; INDEX_TYPE const endCapacity = m_array.capacityOfArray( i ); ASSERT_EQ( values, newValues ); @@ -645,91 +620,90 @@ class ArrayOfArraysTest : public ::testing::Test } INDEX_TYPE rand( INDEX_TYPE const min, INDEX_TYPE const max ) - { - return std::uniform_int_distribution< INDEX_TYPE >( min, max )( m_gen ); - } + { return std::uniform_int_distribution< INDEX_TYPE >( min, max )( m_gen ); } static constexpr INDEX_TYPE LARGE_NUMBER = 1E6; - ArrayOfArrays< T > m_array; + ARRAY_OF_ARRAYS m_array; std::vector< std::vector< T > > m_ref; std::mt19937_64 m_gen; - /// Check that the move, toView, and toViewConst methods of ArrayOfArrays< T > are detected. - static_assert( bufferManipulation::HasMemberFunction_move< ArrayOfArrays< T > >, - "ArrayOfArrays< T > has a move method." ); - static_assert( HasMemberFunction_toView< ArrayOfArrays< T > >, - "ArrayOfArrays< T > has a toView method." ); - static_assert( HasMemberFunction_toViewConst< ArrayOfArrays< T > >, - "ArrayOfArrays< T > has a toViewConst method." ); - - /// Check that the move and toViewConst methods of ArrayOfArraysView< T, INDEX_TYPE const, false > are detected. - static_assert( bufferManipulation::HasMemberFunction_move< ArrayOfArraysView< T, INDEX_TYPE const, false > >, - "ArrayOfArraysView< T, INDEX_TYPE const, false > has a move method." ); - static_assert( HasMemberFunction_toView< ArrayOfArraysView< T, INDEX_TYPE const, false > >, - "ArrayOfArraysView< T, INDEX_TYPE const, false > has a toView method." ); - static_assert( HasMemberFunction_toViewConst< ArrayOfArraysView< T, INDEX_TYPE const, false > >, - "ArrayOfArraysView< T, INDEX_TYPE const, false > has a toViewConst method." ); - - /// Check that the move and toViewConst methods of ArrayOfArraysView< T, INDEX_TYPE const, true > are detected. - static_assert( bufferManipulation::HasMemberFunction_move< ArrayOfArraysView< T, INDEX_TYPE const, true > >, - "ArrayOfArraysView< T, INDEX_TYPE const, true > has a move method." ); - static_assert( HasMemberFunction_toView< ArrayOfArraysView< T, INDEX_TYPE const, true > >, - "ArrayOfArraysView< T, INDEX_TYPE const, true > has a toView method." ); - static_assert( HasMemberFunction_toViewConst< ArrayOfArraysView< T, INDEX_TYPE const, true > >, - "ArrayOfArraysView< T, INDEX_TYPE const, true > has a toViewConst method." ); - - /// Check that the move and toViewConst methods of ArrayOfArraysView< T const, INDEX_TYPE const, true > are detected. - static_assert( bufferManipulation::HasMemberFunction_move< ArrayOfArraysView< T const, INDEX_TYPE const, true > >, - "ArrayOfArraysView< T const, INDEX_TYPE const, true > has a move method." ); - static_assert( HasMemberFunction_toView< ArrayOfArraysView< T const, INDEX_TYPE const, true > >, - "ArrayOfArraysView< T const, INDEX_TYPE const, true > has a toView method." ); - static_assert( HasMemberFunction_toViewConst< ArrayOfArraysView< T const, INDEX_TYPE const, true > >, - "ArrayOfArraysView< T const, INDEX_TYPE const, true > has a toViewConst method." ); - - /// Check that GetViewType and GetViewTypeConst are correct for ArrayOfArrays< T > - static_assert( std::is_same_v< typename GetViewType< ArrayOfArrays< T > >::type, - ArrayOfArraysView< T, INDEX_TYPE const, false > const >, - "The view type of ArrayOfArrays< T > is ArrayOfArraysView< T, INDEX_TYPE const, false > const." ); - static_assert( std::is_same_v< typename GetViewTypeConst< ArrayOfArrays< T > >::type, - ArrayOfArraysView< T const, INDEX_TYPE const, true > const >, - "The const view type of ArrayOfArrays< T > is ArrayOfArraysView< T const, INDEX_TYPE const, true > const." ); - - /// Check that GetViewType and GetViewTypeConst are correct for ArrayOfArraysView< T, INDEX_TYPE const, false > - static_assert( std::is_same_v< typename GetViewType< ArrayOfArraysView< T, INDEX_TYPE const, false > >::type, - ArrayOfArraysView< T, INDEX_TYPE const, false > const >, - "The view type of ArrayOfArraysView< T, INDEX_TYPE const, false > is ArrayOfArraysView< T, INDEX_TYPE const, false > const." ); - static_assert( std::is_same_v< typename GetViewTypeConst< ArrayOfArraysView< T, INDEX_TYPE const, false > >::type, - ArrayOfArraysView< T const, INDEX_TYPE const, true > const >, - "The const view type of ArrayOfArraysView< T, INDEX_TYPE const, false > is ArrayOfArraysView< T const, INDEX_TYPE const, true > const." ); - - /// Check that GetViewType and GetViewTypeConst are correct for ArrayOfArraysView< T, INDEX_TYPE const, true > - static_assert( std::is_same_v< typename GetViewType< ArrayOfArraysView< T, INDEX_TYPE const, true > >::type, - ArrayOfArraysView< T, INDEX_TYPE const, true > const >, - "The view type of ArrayOfArraysView< T, INDEX_TYPE const, true > is ArrayOfArraysView< T, INDEX_TYPE const, true > const." ); - static_assert( std::is_same_v< typename GetViewTypeConst< ArrayOfArraysView< T, INDEX_TYPE const, true > >::type, - ArrayOfArraysView< T const, INDEX_TYPE const, true > const >, - "The const view type of ArrayOfArraysView< T, INDEX_TYPE const, true > is ArrayOfArraysView< T const, INDEX_TYPE const, true > const." ); - - /// Check that GetViewType and GetViewTypeConst are correct for ArrayOfArraysView< T const, INDEX_TYPE const, true > - static_assert( std::is_same_v< typename GetViewType< ArrayOfArraysView< T const, INDEX_TYPE const, true > >::type, - ArrayOfArraysView< T const, INDEX_TYPE const, true > const >, - "The view type of ArrayOfArraysView< T const, INDEX_TYPE const, true > is ArrayOfArraysView< T const, INDEX_TYPE const, true > const." ); - static_assert( std::is_same_v< typename GetViewTypeConst< ArrayOfArraysView< T const, INDEX_TYPE const, true > >::type, - ArrayOfArraysView< T const, INDEX_TYPE const, true > const >, - "The const view type of ArrayOfArraysView< T const, INDEX_TYPE const, true > is ArrayOfArraysView< T const, INDEX_TYPE const, true > const." ); + /// Check that the move, toView, and toViewConst methods of ARRAY_OF_ARRAYS are detected. + static_assert( bufferManipulation::HasMemberFunction_move< ARRAY_OF_ARRAYS >, + "ARRAY_OF_ARRAYS has a move method." ); + static_assert( HasMemberFunction_toView< ARRAY_OF_ARRAYS >, + "ARRAY_OF_ARRAYS has a toView method." ); + static_assert( HasMemberFunction_toViewConst< ARRAY_OF_ARRAYS >, + "ARRAY_OF_ARRAYS has a toViewConst method." ); + + /// Check that the move and toViewConst methods of ViewType are detected. + static_assert( bufferManipulation::HasMemberFunction_move< ViewType >, + "ViewType has a move method." ); + static_assert( HasMemberFunction_toView< ViewType >, + "ViewType has a toView method." ); + static_assert( HasMemberFunction_toViewConst< ViewType >, + "ViewType has a toViewConst method." ); + + /// Check that the move and toViewConst methods of ViewTypeConstSizes are detected. + static_assert( bufferManipulation::HasMemberFunction_move< ViewTypeConstSizes >, + "ViewTypeConstSizes has a move method." ); + static_assert( HasMemberFunction_toView< ViewTypeConstSizes >, + "ViewTypeConstSizes has a toView method." ); + static_assert( HasMemberFunction_toViewConst< ViewTypeConstSizes >, + "ViewTypeConstSizes has a toViewConst method." ); + + /// Check that the move and toViewConst methods of ViewTypeConst are detected. + static_assert( bufferManipulation::HasMemberFunction_move< ViewTypeConst >, + "ViewTypeConst has a move method." ); + static_assert( HasMemberFunction_toView< ViewTypeConst >, + "ViewTypeConst has a toView method." ); + static_assert( HasMemberFunction_toViewConst< ViewTypeConst >, + "ViewTypeConst has a toViewConst method." ); + + /// Check that GetViewType and GetViewTypeConst are correct for ARRAY_OF_ARRAYS + static_assert( std::is_same_v< typename GetViewType< ARRAY_OF_ARRAYS >::type, ViewType const >, + "The view type of ARRAY_OF_ARRAYS is ViewType const." ); + static_assert( std::is_same_v< typename GetViewTypeConst< ARRAY_OF_ARRAYS >::type, ViewTypeConst const >, + "The const view type of ARRAY_OF_ARRAYS is ViewTypeConst const." ); + + /// Check that GetViewType and GetViewTypeConst are correct for ViewType + static_assert( std::is_same_v< typename GetViewType< ViewType >::type, ViewType const >, + "The view type of ViewType is ViewType const." ); + static_assert( std::is_same_v< typename GetViewTypeConst< ViewType >::type, ViewTypeConst const >, + "The const view type of ViewType is ViewTypeConst const." ); + + /// Check that GetViewType and GetViewTypeConst are correct for ViewTypeConstSizes + static_assert( std::is_same_v< typename GetViewType< ViewTypeConstSizes >::type, ViewTypeConstSizes const >, + "The view type of ViewTypeConstSizes is ViewTypeConstSizes const." ); + static_assert( std::is_same_v< typename GetViewTypeConst< ViewTypeConstSizes >::type, ViewTypeConst const >, + "The const view type of ViewTypeConstSizes is ViewTypeConst const." ); + + /// Check that GetViewType and GetViewTypeConst are correct for ViewTypeConst + static_assert( std::is_same_v< typename GetViewType< ViewTypeConst >::type, ViewTypeConst const >, + "The view type of ViewTypeConst is ViewTypeConst const." ); + static_assert( std::is_same_v< typename GetViewTypeConst< ViewTypeConst >::type, ViewTypeConst const >, + "The const view type of ViewTypeConst is ViewTypeConst const." ); }; -using TestTypes = ::testing::Types< INDEX_TYPE, Tensor, TestString >; -TYPED_TEST_SUITE( ArrayOfArraysTest, TestTypes, ); +using ArrayOfArraysTestTypes = ::testing::Types< + ArrayOfArrays< int, INDEX_TYPE, MallocBuffer > + , ArrayOfArrays< Tensor, INDEX_TYPE, MallocBuffer > + , ArrayOfArrays< TestString, INDEX_TYPE, MallocBuffer > +#if defined(USE_CHAI) + , ArrayOfArrays< int, INDEX_TYPE, NewChaiBuffer > + , ArrayOfArrays< Tensor, INDEX_TYPE, NewChaiBuffer > + , ArrayOfArrays< TestString, INDEX_TYPE, NewChaiBuffer > +#endif + >; +TYPED_TEST_SUITE( ArrayOfArraysTest, ArrayOfArraysTestTypes, ); TYPED_TEST( ArrayOfArraysTest, emptyConstruction ) { - ArrayOfArrays< TypeParam > a; + TypeParam a; ASSERT_EQ( a.size(), 0 ); ASSERT_EQ( a.capacity(), 0 ); } @@ -737,7 +711,7 @@ TYPED_TEST( ArrayOfArraysTest, emptyConstruction ) TYPED_TEST( ArrayOfArraysTest, sizedConstruction ) { - ArrayOfArrays< TypeParam > a( 10 ); + TypeParam a( 10 ); ASSERT_EQ( a.size(), 10 ); ASSERT_EQ( a.capacity(), 10 ); @@ -750,7 +724,7 @@ TYPED_TEST( ArrayOfArraysTest, sizedConstruction ) TYPED_TEST( ArrayOfArraysTest, sizedHintConstruction ) { - ArrayOfArrays< TypeParam > a( 10, 20 ); + TypeParam a( 10, 20 ); ASSERT_EQ( a.size(), 10 ); ASSERT_EQ( a.capacity(), 10 ); @@ -783,45 +757,45 @@ TYPED_TEST( ArrayOfArraysTest, insertArray ) TYPED_TEST( ArrayOfArraysTest, copyConstruction ) { this->appendArray( 100, 10 ); - ArrayOfArrays< TypeParam > a( this->m_array ); + TypeParam a( this->m_array ); ASSERT_NE( &a( 0, 0 ), &this->m_array( 0, 0 ) ); - COMPARE_TO_REFERENCE( this->m_array.toViewConst(), this->m_ref ); - COMPARE_TO_REFERENCE( a.toViewConst(), this->m_ref ); + this->compareToReference( this->m_array.toViewConst() ); + this->compareToReference( a.toViewConst() ); } TYPED_TEST( ArrayOfArraysTest, copyAssignment ) { this->appendArray( 100, 10 ); - ArrayOfArrays< TypeParam > a; + TypeParam a; ASSERT_EQ( a.size(), 0 ); a = this->m_array; ASSERT_NE( &a( 0, 0 ), &this->m_array( 0, 0 ) ); - COMPARE_TO_REFERENCE( this->m_array.toViewConst(), this->m_ref ); - COMPARE_TO_REFERENCE( a.toViewConst(), this->m_ref ); + this->compareToReference( this->m_array.toViewConst() ); + this->compareToReference( a.toViewConst() ); } TYPED_TEST( ArrayOfArraysTest, moveConstruction ) { this->appendArray( 100, 10 ); - ArrayOfArrays< TypeParam > a( std::move( this->m_array ) ); + TypeParam a( std::move( this->m_array ) ); ASSERT_EQ( this->m_array.size(), 0 ); - COMPARE_TO_REFERENCE( a.toViewConst(), this->m_ref ); + this->compareToReference( a.toViewConst() ); } TYPED_TEST( ArrayOfArraysTest, moveAssignment ) { this->appendArray( 100, 10 ); - ArrayOfArrays< TypeParam > a; + TypeParam a; ASSERT_EQ( a.size(), 0 ); a = std::move( this->m_array ); ASSERT_EQ( this->m_array.size(), 0 ); - COMPARE_TO_REFERENCE( a.toViewConst(), this->m_ref ); + this->compareToReference( a.toViewConst() ); } TYPED_TEST( ArrayOfArraysTest, eraseArray ) @@ -847,9 +821,9 @@ TYPED_TEST( ArrayOfArraysTest, resizeWithCapacity ) for( INDEX_TYPE i = 0; i < 3; ++i ) { this->resize( 100, 10 ); - this->insertIntoArray( 5 ); + this->emplace( 5 ); this->resize( 150, 10 ); - this->insertIntoArray( 5 ); + this->emplace( 5 ); } } @@ -858,11 +832,11 @@ TYPED_TEST( ArrayOfArraysTest, resizeFromCapacities ) for( INDEX_TYPE i = 0; i < 3; ++i ) { this->template resizeFromCapacities< serialPolicy >( 100, 10 ); - this->insertIntoArray( 10 ); + this->emplace( 10 ); #if defined( USE_OPENMP ) this->template resizeFromCapacities< parallelHostPolicy >( 150, 10 ); - this->insertIntoArray( 10 ); + this->emplace( 10 ); #endif } } @@ -877,64 +851,43 @@ TYPED_TEST( ArrayOfArraysTest, resizeArray ) } } -TYPED_TEST( ArrayOfArraysTest, appendToArray ) +TYPED_TEST( ArrayOfArraysTest, emplaceBack ) { this->resize( 100 ); for( INDEX_TYPE i = 0; i < 3; ++i ) { - this->appendToArray( 10 ); + this->emplaceBack( 10 ); } } -TYPED_TEST( ArrayOfArraysTest, atomicAppendToArraySerial ) -{ - INDEX_TYPE const APPENDS_PER_ARRAY = 10; - - this->resize( 20, APPENDS_PER_ARRAY ); - this->atomicAppendToArraySerial( APPENDS_PER_ARRAY ); -} - -#ifdef USE_OPENMP - -TYPED_TEST( ArrayOfArraysTest, atomicAppendToArrayOMP ) -{ - INDEX_TYPE const APPENDS_PER_THREAD = 10; - INDEX_TYPE const MAX_TOTAL_APPENDS = APPENDS_PER_THREAD * omp_get_max_threads(); - - this->resize( 20, MAX_TOTAL_APPENDS ); - this->atomicAppendToArrayOMP( APPENDS_PER_THREAD ); -} - -#endif - -TYPED_TEST( ArrayOfArraysTest, appendMultipleToArray ) +TYPED_TEST( ArrayOfArraysTest, appendToArray ) { this->resize( 100 ); for( INDEX_TYPE i = 0; i < 3; ++i ) { - this->appendMultipleToArray( 10 ); + this->appendToArray( 10 ); } } -TYPED_TEST( ArrayOfArraysTest, insertIntoArray ) +TYPED_TEST( ArrayOfArraysTest, emplace ) { this->resize( 100 ); for( INDEX_TYPE i = 0; i < 3; ++i ) { - this->insertIntoArray( 10 ); + this->emplace( 10 ); } } -TYPED_TEST( ArrayOfArraysTest, insertMultipleIntoArray ) +TYPED_TEST( ArrayOfArraysTest, insertIntoArray ) { this->resize( 100 ); for( INDEX_TYPE i = 0; i < 3; ++i ) { - this->insertMultipleIntoArray( 10 ); + this->insertIntoArray( 10 ); } } @@ -949,14 +902,14 @@ TYPED_TEST( ArrayOfArraysTest, eraseFromArray ) } } -TYPED_TEST( ArrayOfArraysTest, removeMultipleFromArray ) +TYPED_TEST( ArrayOfArraysTest, eraseMultipleFromArray ) { this->resize( 100 ); for( INDEX_TYPE i = 0; i < 3; ++i ) { this->appendToArray( 10 ); - this->removeMultipleFromArray( 10 ); + this->eraseMultipleFromArray( 10 ); } } @@ -1008,178 +961,148 @@ TYPED_TEST( ArrayOfArraysTest, shallowCopy ) this->shallowCopy(); } -#ifdef USE_CUDA +template< typename ARRAY_OF_ARRAYS_POLICY_PAIR > +class ArrayOfArraysViewTest : public ArrayOfArraysTest< typename ARRAY_OF_ARRAYS_POLICY_PAIR::first_type > +{ +public: + using ARRAY_OF_ARRAYS = typename ARRAY_OF_ARRAYS_POLICY_PAIR::first_type; + using POLICY = typename ARRAY_OF_ARRAYS_POLICY_PAIR::second_type; -template< class T > -using Array1D = Array< T, 1, RAJA::PERM_I, INDEX_TYPE >; + using T = typename ARRAY_OF_ARRAYS::value_type; -template< class T > -using Array2D = Array< T, 2, RAJA::PERM_IJ, INDEX_TYPE >; + using ParentClass = ArrayOfArraysTest< ARRAY_OF_ARRAYS >; -template< class T > -class ArrayOfArraysCudaTest : public ArrayOfArraysTest< T > -{ -public: + using ViewType = std::remove_const_t< typename ARRAY_OF_ARRAYS::ViewType >; + + template< typename T > + using Array1D = typename ArrayConverter< ARRAY_OF_ARRAYS >::template Array< T, 1, RAJA::PERM_I >; - void memoryMotion() + template< typename T > + using ArrayView1D = typename ArrayConverter< ARRAY_OF_ARRAYS >::template ArrayView< T, 1, 0 >; + + template< typename T > + using Array2D = typename ArrayConverter< ARRAY_OF_ARRAYS >::template Array< T, 2, RAJA::PERM_IJ >; + + template< typename T > + using ArrayView2D = typename ArrayConverter< ARRAY_OF_ARRAYS >::template ArrayView< T, 2, 1 >; + + + void modifyInKernel() { - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE; INDEX_TYPE const nArrays = m_array.size(); // Update the view on the device. - forall( gpu(), 0, nArrays, - [view = m_array.toView()] __device__ ( INDEX_TYPE i ) - { - INDEX_TYPE const sizeOfArray = view.sizeOfArray( i ); - for( INDEX_TYPE j = 0; j < sizeOfArray; ++j ) - { - LVARRAY_ERROR_IF( &(view[i][j]) != &(view( i, j )), "Value mismatch!" ); - view[i][j] += T( 1 ); - view( i, j ) += T( 1 ); - } - } - ); + ViewType const & view = m_array.toView(); + forall< POLICY >( nArrays, [view] LVARRAY_HOST_DEVICE ( INDEX_TYPE const i ) + { + INDEX_TYPE const sizeOfArray = view.sizeOfArray( i ); + for( INDEX_TYPE j = 0; j < sizeOfArray; ++j ) + { + PORTABLE_EXPECT_EQ( &view[ i ][ j ], &view( i, j ) ); + view[ i ][ j ] += T( view[ i ][ j ] ); + view( i, j ) += T( view( i, j ) ); + } + } ); // Update the reference. for( INDEX_TYPE i = 0; i < nArrays; ++i ) { - for( INDEX_TYPE j = 0; j < m_ref[i].size(); ++j ) + for( INDEX_TYPE j = 0; j < INDEX_TYPE( m_ref[ i ].size() ); ++j ) { - m_ref[i][j] += T( 1 ); - m_ref[i][j] += T( 1 ); + m_ref[ i ][ j ] += T( m_ref[ i ][ j ] ); + m_ref[ i ][ j ] += T( m_ref[ i ][ j ] ); } } // Move the view back to the host and compare with the reference. - forall( sequential(), 0, 1, - [view = m_array.toView(), this] ( INDEX_TYPE ) + forall< serialPolicy >( 1, [view, this] ( INDEX_TYPE ) { - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); - } - ); + SCOPED_TRACE( "" ); + this->compareToReference( view.toViewConst() ); + } ); } void memoryMotionMove() { - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE; INDEX_TYPE const nArrays = m_array.size(); // Update the view on the device. - forall( gpu(), 0, nArrays, - [view=m_array.toViewConstSizes()] __device__ ( INDEX_TYPE i ) - { - INDEX_TYPE const sizeOfArray = view.sizeOfArray( i ); - for( INDEX_TYPE j = 0; j < sizeOfArray; ++j ) - { - LVARRAY_ERROR_IF( &(view[i][j]) != &(view( i, j )), "Value mismatch!" ); - view[i][j] += T( 1 ); - view( i, j ) += T( 1 ); - } - } - ); + ViewType const & view = m_array.toView(); + forall< POLICY >( nArrays, [view] LVARRAY_HOST_DEVICE ( INDEX_TYPE const i ) + { + INDEX_TYPE const sizeOfArray = view.sizeOfArray( i ); + for( INDEX_TYPE j = 0; j < sizeOfArray; ++j ) + { + PORTABLE_EXPECT_EQ( &view[ i ][ j ], &view( i, j ) ); + view[ i ][ j ] += T( view[ i ][ j ] ); + view( i, j ) += T( view( i, j ) ); + } + } ); // Update the reference. for( INDEX_TYPE i = 0; i < nArrays; ++i ) { - for( INDEX_TYPE j = 0; j < m_ref[i].size(); ++j ) + for( INDEX_TYPE j = 0; j < INDEX_TYPE( m_ref[ i ].size() ); ++j ) { - m_ref[i][j] += T( 1 ); - m_ref[i][j] += T( 1 ); + m_ref[ i ][ j ] += T( m_ref[ i ][ j ] ); + m_ref[ i ][ j ] += T( m_ref[ i ][ j ] ); } } // Move the view back to the host and compare with the reference. - m_array.move( chai::CPU ); - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + m_array.move( MemorySpace::CPU ); + COMPARE_TO_REFERENCE; } - void appendDevice() + void emplaceBack() { - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE; INDEX_TYPE const nArrays = m_array.size(); - Array1D< Array1D< T > > valuesToAppend( nArrays ); + Array1D< Array1D< INDEX_TYPE > > seedsToAppend( nArrays ); - // Populate the valuesToAppend array and append the values to the reference. + // Populate the seedsToAppend array and append the values to the reference. for( INDEX_TYPE i = 0; i < nArrays; ++i ) { INDEX_TYPE const arraySize = m_array.sizeOfArray( i ); INDEX_TYPE maxAppends = m_array.capacityOfArray( i ) - arraySize; - INDEX_TYPE const nValues = rand( 0, maxAppends ); + INDEX_TYPE const nSeeds = rand( 0, maxAppends / 2 ); - valuesToAppend[i].resize( nValues ); + seedsToAppend[ i ].resize( nSeeds ); - for( INDEX_TYPE j = 0; j < nValues; ++j ) + for( INDEX_TYPE j = 0; j < nSeeds; ++j ) { - T const value = T( i * LARGE_NUMBER + arraySize + j ); - m_ref[i].push_back( value ); - valuesToAppend[i][j] = value; + INDEX_TYPE const seed = i * LARGE_NUMBER + arraySize + 2 * j; + m_ref[ i ].emplace_back( T( seed ) ); + m_ref[ i ].emplace_back( seed + 1 ); + seedsToAppend[ i ][ j ] = seed; } } // Append to the view on the device. - forall( gpu(), 0, nArrays, - [view=m_array.toView(), toAppend=valuesToAppend.toViewConst()] __device__ ( INDEX_TYPE i ) - { - for( INDEX_TYPE j = 0; j < toAppend[i].size(); ++j ) - { - view.appendToArray( i, toAppend[i][j] ); - } - } - ); - - // Move the view back to the host and compare with the reference. - m_array.move( chai::CPU ); - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); - } - - void atomicAppendDevice( INDEX_TYPE const numThreads, INDEX_TYPE const appendsPerArrayPerThread ) - { - INDEX_TYPE const nArrays = m_array.size(); - - for( INDEX_TYPE i = 0; i < nArrays; ++i ) - { - ASSERT_EQ( m_array.sizeOfArray( i ), 0 ); - } - - forall( gpu(), 0, numThreads, - [view=m_array.toView(), nArrays, appendsPerArrayPerThread] __device__ ( INDEX_TYPE const threadNum ) - { - for( INDEX_TYPE i = 0; i < nArrays; ++i ) - { - for( INDEX_TYPE j = 0; j < appendsPerArrayPerThread; ++j ) + ViewType const & view = m_array.toView(); + ArrayView1D< ArrayView1D< INDEX_TYPE const > const > const & seeds = seedsToAppend.toViewConst(); + forall< POLICY >( nArrays, [view, seeds] LVARRAY_HOST_DEVICE ( INDEX_TYPE const i ) { - T const value = T( i * LARGE_NUMBER + threadNum * appendsPerArrayPerThread + j ); - view.atomicAppendToArray( RAJA::auto_atomic{}, i, value ); - } - } - } - ); + for( INDEX_TYPE j = 0; j < seeds[ i ].size(); ++j ) + { + view.emplaceBack( i, T( seeds[ i ][ j ] ) ); + view.emplaceBack( i, seeds[ i ][ j ] + 1 ); + } + } ); - // Now sort each array and check that the values are as expected. - m_array.move( chai::CPU ); - INDEX_TYPE const appendsPerArray = numThreads * appendsPerArrayPerThread; - for( INDEX_TYPE i = 0; i < nArrays; ++i ) - { - ASSERT_EQ( m_array.sizeOfArray( i ), appendsPerArray ); - ASSERT_LE( m_array.sizeOfArray( i ), m_array.capacityOfArray( i )); - - T * const subArrayPtr = m_array[i]; - std::sort( subArrayPtr, subArrayPtr + appendsPerArray ); - - for( INDEX_TYPE j = 0; j < appendsPerArray; ++j ) - { - T const value = T( i * LARGE_NUMBER + j ); - EXPECT_EQ( value, m_array( i, j )) << i << ", " << j; - } - } + // Move the view back to the host and compare with the reference. + m_array.move( MemorySpace::CPU ); + COMPARE_TO_REFERENCE; } - void appendMultipleDevice() + void view_appendToArray() { - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE; INDEX_TYPE const nArrays = m_array.size(); Array1D< Array1D< T > > valuesToAppend( nArrays ); @@ -1190,35 +1113,35 @@ class ArrayOfArraysCudaTest : public ArrayOfArraysTest< T > INDEX_TYPE const arraySize = m_array.sizeOfArray( i ); INDEX_TYPE const maxAppends = m_array.capacityOfArray( i ) - arraySize; INDEX_TYPE const nValues = rand( 0, maxAppends ); - valuesToAppend[i].resize( nValues ); + valuesToAppend[ i ].resize( nValues ); for( INDEX_TYPE j = 0; j < nValues; ++j ) { T const value = T( i * LARGE_NUMBER + arraySize + j ); - m_ref[i].push_back( value ); - valuesToAppend[i][j] = value; + m_ref[ i ].push_back( value ); + valuesToAppend[ i ][ j ] = value; } } // Append to the view on the device. - forall( gpu(), 0, nArrays, - [view=m_array.toView(), toAppend=valuesToAppend.toViewConst()] __device__ ( INDEX_TYPE i ) - { - view.appendToArray( i, toAppend[i].data(), toAppend[i].size()); - } - ); + ViewType const & view = m_array.toView(); + ArrayView1D< ArrayView1D< T const > const > const & toAppend = valuesToAppend.toViewConst(); + forall< POLICY >( nArrays, [view, toAppend] LVARRAY_HOST_DEVICE ( INDEX_TYPE const i ) + { + view.appendToArray( i, toAppend[ i ].begin(), toAppend[ i ].end() ); + } ); // Move the view back to the host and compare with the reference. - m_array.move( chai::CPU ); - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + m_array.move( MemorySpace::CPU ); + COMPARE_TO_REFERENCE; } - void insertDevice() + void view_emplace() { - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE; INDEX_TYPE const nArrays = m_array.size(); - Array1D< Array1D< T > > valuesToInsert( nArrays ); + Array1D< Array1D< INDEX_TYPE > > seedsToInsert( nArrays ); Array1D< Array1D< INDEX_TYPE > > positionsToInsert( nArrays ); // Populate the valuesToInsert and positionsToInsert arrays and update the reference. @@ -1226,41 +1149,44 @@ class ArrayOfArraysCudaTest : public ArrayOfArraysTest< T > { INDEX_TYPE const arraySize = m_array.sizeOfArray( i ); INDEX_TYPE const maxInserts = m_array.capacityOfArray( i ) - arraySize; - INDEX_TYPE const nValues = rand( 0, maxInserts ); - valuesToInsert[i].resize( nValues ); - positionsToInsert[i].resize( nValues ); + INDEX_TYPE const nSeeds = rand( 0, maxInserts / 2 ); + seedsToInsert[ i ].resize( nSeeds ); + positionsToInsert[ i ].resize( nSeeds ); - for( INDEX_TYPE j = 0; j < nValues; ++j ) + for( INDEX_TYPE j = 0; j < nSeeds; ++j ) { - T const value = T( i * LARGE_NUMBER + arraySize + j ); - + INDEX_TYPE const seed = i * LARGE_NUMBER + arraySize + 2 * j; INDEX_TYPE const insertPos = rand( 0, arraySize + j ); - m_ref[i].insert( m_ref[i].begin() + insertPos, value ); - valuesToInsert[i][j] = value; - positionsToInsert[i][j] = insertPos; + + m_ref[ i ].emplace( m_ref[ i ].begin() + insertPos, T( seed ) ); + m_ref[ i ].emplace( m_ref[ i ].begin() + insertPos, seed + 1 ); + + seedsToInsert[ i ][ j ] = seed; + positionsToInsert[ i ][ j ] = insertPos; } } // Insert into the view on the device. - forall( gpu(), 0, nArrays, - [view=m_array.toView(), positions=positionsToInsert.toViewConst(), values=valuesToInsert.toViewConst()] - __device__ ( INDEX_TYPE i ) - { - for( INDEX_TYPE j = 0; j < values[i].size(); ++j ) - { - view.insertIntoArray( i, positions[i][j], values[i][j] ); - } - } - ); + ViewType const & view = m_array.toView(); + ArrayView1D< ArrayView1D< INDEX_TYPE const > const > const & positions = positionsToInsert.toViewConst(); + ArrayView1D< ArrayView1D< INDEX_TYPE const > const > const & seeds = seedsToInsert.toViewConst(); + forall< POLICY >( nArrays, [view, positions, seeds] LVARRAY_HOST_DEVICE ( INDEX_TYPE const i ) + { + for( INDEX_TYPE j = 0; j < positions[ i ].size(); ++j ) + { + view.emplace( i, positions[ i ][ j ], T( seeds[ i ][ j ] ) ); + view.emplace( i, positions[ i ][ j ], seeds[ i ][ j ] + 1 ); + } + } ); // Move the view back to the host and compare with the reference. - m_array.move( chai::CPU ); - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + m_array.move( MemorySpace::CPU ); + COMPARE_TO_REFERENCE; } - void insertMultipleDevice() + void view_insertIntoArray() { - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE; INDEX_TYPE const nArrays = m_array.size(); Array1D< Array1D< T > > valuesToInsert( nArrays ); @@ -1272,37 +1198,37 @@ class ArrayOfArraysCudaTest : public ArrayOfArraysTest< T > INDEX_TYPE const arraySize = m_array.sizeOfArray( i ); INDEX_TYPE const maxInserts = m_array.capacityOfArray( i ) - arraySize; INDEX_TYPE const nValues = rand( 0, maxInserts ); - valuesToInsert[i].resize( nValues ); + valuesToInsert[ i ].resize( nValues ); INDEX_TYPE const insertPos = rand( 0, arraySize ); - positionsToInsert[i] = insertPos; + positionsToInsert[ i ] = insertPos; for( INDEX_TYPE j = 0; j < nValues; ++j ) { T const value = T( i * LARGE_NUMBER + arraySize + j ); - valuesToInsert[i][j] = value; + valuesToInsert[ i ][ j ] = value; } - m_ref[i].insert( m_ref[i].begin() + insertPos, valuesToInsert[i].begin(), valuesToInsert[i].end()); + m_ref[ i ].insert( m_ref[ i ].begin() + insertPos, valuesToInsert[ i ].begin(), valuesToInsert[ i ].end() ); } // Insert into the view on the device. - forall( gpu(), 0, nArrays, - [view=m_array.toView(), positions=positionsToInsert.toViewConst(), values=valuesToInsert.toViewConst()] - __device__ ( INDEX_TYPE i ) - { - view.insertIntoArray( i, positions[i], values[i].data(), values[i].size()); - } - ); + ViewType const & view = m_array.toView(); + ArrayView1D< INDEX_TYPE const > const & positions = positionsToInsert.toViewConst(); + ArrayView1D< ArrayView1D< T const > const > const & values = valuesToInsert.toViewConst(); + forall< POLICY >( nArrays, [view, positions, values] LVARRAY_HOST_DEVICE ( INDEX_TYPE const i ) + { + view.insertIntoArray( i, positions[ i ], values[ i ].begin(), values[ i ].end() ); + } ); // Move the view back to the host and compare with the reference. - m_array.move( chai::CPU ); - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + m_array.move( MemorySpace::CPU ); + COMPARE_TO_REFERENCE; } - void removeDevice( INDEX_TYPE const maxRemoves ) + void view_erase( INDEX_TYPE const maxRemoves ) { - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE; INDEX_TYPE const nArrays = m_array.size(); Array1D< Array1D< INDEX_TYPE > > positionsToRemove( nArrays ); @@ -1312,41 +1238,40 @@ class ArrayOfArraysCudaTest : public ArrayOfArraysTest< T > { INDEX_TYPE const arraySize = m_array.sizeOfArray( i ); INDEX_TYPE const nToRemove = rand( 0, min( arraySize, maxRemoves )); - positionsToRemove[i].resize( nToRemove ); + positionsToRemove[ i ].resize( nToRemove ); for( INDEX_TYPE j = 0; j < nToRemove; ++j ) { INDEX_TYPE const removePosition = rand( 0, arraySize - j - 1 ); - m_ref[i].erase( m_ref[i].begin() + removePosition ); - positionsToRemove[i][j] = removePosition; + m_ref[ i ].erase( m_ref[ i ].begin() + removePosition ); + positionsToRemove[ i ][ j ] = removePosition; } } // Remove the view on the device. - forall( gpu(), 0, nArrays, - [view=m_array.toView(), positions=positionsToRemove.toViewConst()] - __device__ ( INDEX_TYPE i ) - { - for( INDEX_TYPE j = 0; j < positions[i].size(); ++j ) - { - view.eraseFromArray( i, positions[i][j] ); - } - } - ); + ViewType const & view = m_array.toView(); + ArrayView1D< ArrayView1D< INDEX_TYPE const > const > const & positions = positionsToRemove.toViewConst(); + forall< POLICY >( nArrays, [view, positions] LVARRAY_HOST_DEVICE ( INDEX_TYPE const i ) + { + for( INDEX_TYPE j = 0; j < positions[ i ].size(); ++j ) + { + view.eraseFromArray( i, positions[ i ][ j ] ); + } + } ); // Move the view back to the host and compare with the reference. - m_array.move( chai::CPU ); - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + m_array.move( MemorySpace::CPU ); + COMPARE_TO_REFERENCE; } - void removeMultipleDevice( INDEX_TYPE const maxRemoves ) + void view_eraseMultiple( INDEX_TYPE const maxRemoves ) { - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE; INDEX_TYPE const nArrays = m_array.size(); - Array2D< INDEX_TYPE > removals( nArrays, 2 ); + Array2D< INDEX_TYPE > toRemove( nArrays, 2 ); - // Populate the removals array and update the reference. + // Populate the toRemove array and update the reference. for( INDEX_TYPE i = 0; i < nArrays; ++i ) { INDEX_TYPE const arraySize = m_array.sizeOfArray( i ); @@ -1355,49 +1280,62 @@ class ArrayOfArraysCudaTest : public ArrayOfArraysTest< T > INDEX_TYPE const removePosition = rand( 0, arraySize - 1 ); INDEX_TYPE const nToRemove = rand( 0, min( maxRemoves, arraySize - removePosition )); - removals[i][0] = removePosition; - removals[i][1] = nToRemove; - m_ref[i].erase( m_ref[i].begin() + removePosition, m_ref[i].begin() + removePosition + nToRemove ); + toRemove[ i ][ 0 ] = removePosition; + toRemove[ i ][ 1 ] = nToRemove; + m_ref[ i ].erase( m_ref[ i ].begin() + removePosition, m_ref[ i ].begin() + removePosition + nToRemove ); } // Remove from the view on the device. - forall( gpu(), 0, nArrays, - [view=m_array.toView(), removals=removals.toViewConst()] - __device__ ( INDEX_TYPE i ) - { - if( view.sizeOfArray( i ) == 0 ) return; - view.eraseFromArray( i, removals[i][0], removals[i][1] ); - } - ); + ViewType const & view = m_array.toView(); + ArrayView2D< INDEX_TYPE const > removals = toRemove.toViewConst(); + forall< POLICY >( nArrays, [view, removals] LVARRAY_HOST_DEVICE ( INDEX_TYPE const i ) + { + if( view.sizeOfArray( i ) == 0 ) return; + view.eraseFromArray( i, removals[ i ][ 0 ], removals[ i ][ 1 ] ); + } ); // Move the view back to the host and compare with the reference. - m_array.move( chai::CPU ); - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + m_array.move( MemorySpace::CPU ); + COMPARE_TO_REFERENCE; } protected: - using ArrayOfArraysTest< T >::rand; - using ArrayOfArraysTest< T >::LARGE_NUMBER; - using ArrayOfArraysTest< T >::m_gen; - using ArrayOfArraysTest< T >::m_array; - using ArrayOfArraysTest< T >::m_ref; + using ParentClass::rand; + using ParentClass::LARGE_NUMBER; + using ParentClass::m_gen; + using ParentClass::m_array; + using ParentClass::m_ref; }; -using CudaTestTypes = ::testing::Types< INDEX_TYPE, Tensor >; -TYPED_TEST_SUITE( ArrayOfArraysCudaTest, CudaTestTypes ); +using ArrayOfArraysViewTestTypes = ::testing::Types< + std::pair< ArrayOfArrays< int, INDEX_TYPE, MallocBuffer >, serialPolicy > + , std::pair< ArrayOfArrays< Tensor, INDEX_TYPE, MallocBuffer >, serialPolicy > + , std::pair< ArrayOfArrays< TestString, INDEX_TYPE, MallocBuffer >, serialPolicy > +#if defined(USE_CHAI) + , std::pair< ArrayOfArrays< int, INDEX_TYPE, NewChaiBuffer >, serialPolicy > + , std::pair< ArrayOfArrays< Tensor, INDEX_TYPE, NewChaiBuffer >, serialPolicy > + , std::pair< ArrayOfArrays< TestString, INDEX_TYPE, NewChaiBuffer >, serialPolicy > +#endif + +#if defined(USE_CUDA) && defined(USE_CHAI) + , std::pair< ArrayOfArrays< int, INDEX_TYPE, NewChaiBuffer >, parallelDevicePolicy< 32 > > + , std::pair< ArrayOfArrays< Tensor, INDEX_TYPE, NewChaiBuffer >, parallelDevicePolicy< 32 > > +#endif + >; +TYPED_TEST_SUITE( ArrayOfArraysViewTest, ArrayOfArraysViewTestTypes, ); -TYPED_TEST( ArrayOfArraysCudaTest, memoryMotion ) +TYPED_TEST( ArrayOfArraysViewTest, memoryMotion ) { this->resize( 100 ); for( INDEX_TYPE i = 0; i < 3; ++i ) { this->appendToArray( 30 ); - this->memoryMotion(); + this->modifyInKernel(); } } -TYPED_TEST( ArrayOfArraysCudaTest, memoryMotionMove ) +TYPED_TEST( ArrayOfArraysViewTest, memoryMotionMove ) { this->resize( 100 ); @@ -1408,86 +1346,181 @@ TYPED_TEST( ArrayOfArraysCudaTest, memoryMotionMove ) } } -TYPED_TEST( ArrayOfArraysCudaTest, append ) +TYPED_TEST( ArrayOfArraysViewTest, emplaceBack ) { this->resize( 100 ); for( INDEX_TYPE i = 0; i < 3; ++i ) { this->appendToArray( 10 ); - this->appendDevice(); + this->emplaceBack(); } } -TYPED_TEST( ArrayOfArraysCudaTest, atomicAppend ) +TYPED_TEST( ArrayOfArraysViewTest, appendToArray ) { - INDEX_TYPE const NUM_THREADS = 10; - INDEX_TYPE const APPENDS_PER_THREAD = 10; + this->resize( 100 ); - this->resize( 100, NUM_THREADS * APPENDS_PER_THREAD ); - this->atomicAppendDevice( NUM_THREADS, APPENDS_PER_THREAD ); + for( INDEX_TYPE i = 0; i < 3; ++i ) + { + this->appendToArray( 10 ); + this->view_appendToArray(); + } } -TYPED_TEST( ArrayOfArraysCudaTest, appendMultiple ) +TYPED_TEST( ArrayOfArraysViewTest, emplace ) { this->resize( 100 ); for( INDEX_TYPE i = 0; i < 3; ++i ) { this->appendToArray( 10 ); - this->appendMultipleDevice(); + this->view_emplace(); } } -TYPED_TEST( ArrayOfArraysCudaTest, insert ) +TYPED_TEST( ArrayOfArraysViewTest, insertIntoArray ) { this->resize( 100 ); for( INDEX_TYPE i = 0; i < 3; ++i ) { this->appendToArray( 10 ); - this->insertDevice(); + this->view_insertIntoArray(); } } -TYPED_TEST( ArrayOfArraysCudaTest, insertMultiple ) +TYPED_TEST( ArrayOfArraysViewTest, erase ) { this->resize( 100 ); for( INDEX_TYPE i = 0; i < 3; ++i ) { this->appendToArray( 10 ); - this->insertMultipleDevice(); + this->view_erase( 10 ); } } -TYPED_TEST( ArrayOfArraysCudaTest, remove ) +TYPED_TEST( ArrayOfArraysViewTest, eraseMultiple ) { this->resize( 100 ); for( INDEX_TYPE i = 0; i < 3; ++i ) { this->appendToArray( 10 ); - this->removeDevice( 10 ); + this->view_eraseMultiple( 10 ); } } -TYPED_TEST( ArrayOfArraysCudaTest, removeMultiple ) + +template< typename ARRAY_OF_ARRAYS_POLICY_PAIR > +class ArrayOfArraysViewAtomicTest : public ArrayOfArraysViewTest< ARRAY_OF_ARRAYS_POLICY_PAIR > { - this->resize( 100 ); +public: + using ARRAY_OF_ARRAYS = typename ARRAY_OF_ARRAYS_POLICY_PAIR::first_type; + using POLICY = typename ARRAY_OF_ARRAYS_POLICY_PAIR::second_type; + using AtomicPolicy = typename RAJAHelper< POLICY >::AtomicPolicy; - for( INDEX_TYPE i = 0; i < 3; ++i ) + + using T = typename ARRAY_OF_ARRAYS::value_type; + + using ParentClass = ArrayOfArraysViewTest< ARRAY_OF_ARRAYS_POLICY_PAIR >; + + using ViewType = std::remove_const_t< typename ARRAY_OF_ARRAYS::ViewType >; + + + void emplaceBackAtomic( INDEX_TYPE const numThreads, INDEX_TYPE const appendsPerArrayPerThread ) { - this->appendToArray( 10 ); - this->removeMultipleDevice( 10 ); + INDEX_TYPE const nArrays = m_array.size(); + + for( INDEX_TYPE i = 0; i < nArrays; ++i ) + { + ASSERT_EQ( m_array.sizeOfArray( i ), 0 ); + } + + ViewType const & view = m_array.toView(); + forall< POLICY >( numThreads, + [view, nArrays, appendsPerArrayPerThread] LVARRAY_HOST_DEVICE ( INDEX_TYPE const threadNum ) + { + for( INDEX_TYPE i = 0; i < nArrays; ++i ) + { + for( INDEX_TYPE j = 0; j < appendsPerArrayPerThread; ++j ) + { + T const value = T( i * LARGE_NUMBER + threadNum * appendsPerArrayPerThread + j ); + view.template emplaceBackAtomic< AtomicPolicy >( i, value ); + } + } + } ); + + // Now sort each array and check that the values are as expected. + m_array.move( MemorySpace::CPU ); + INDEX_TYPE const appendsPerArray = numThreads * appendsPerArrayPerThread; + for( INDEX_TYPE i = 0; i < nArrays; ++i ) + { + ASSERT_EQ( m_array.sizeOfArray( i ), appendsPerArray ); + ASSERT_LE( m_array.sizeOfArray( i ), m_array.capacityOfArray( i )); + + T * const subArrayPtr = m_array[ i ]; + std::sort( subArrayPtr, subArrayPtr + appendsPerArray ); + + for( INDEX_TYPE j = 0; j < appendsPerArray; ++j ) + { + T const value = T( i * LARGE_NUMBER + j ); + EXPECT_EQ( value, m_array( i, j ) ) << i << ", " << j; + } + } } + +protected: + using ParentClass::rand; + using ParentClass::LARGE_NUMBER; + using ParentClass::m_gen; + using ParentClass::m_array; + using ParentClass::m_ref; +}; + +using ArrayOfArraysViewAtomicTestTypes = ::testing::Types< + std::pair< ArrayOfArrays< int, INDEX_TYPE, MallocBuffer >, serialPolicy > + , std::pair< ArrayOfArrays< Tensor, INDEX_TYPE, MallocBuffer >, serialPolicy > + , std::pair< ArrayOfArrays< TestString, INDEX_TYPE, MallocBuffer >, serialPolicy > +#if defined(USE_CHAI) + , std::pair< ArrayOfArrays< int, INDEX_TYPE, NewChaiBuffer >, serialPolicy > + , std::pair< ArrayOfArrays< Tensor, INDEX_TYPE, NewChaiBuffer >, serialPolicy > + , std::pair< ArrayOfArrays< TestString, INDEX_TYPE, NewChaiBuffer >, serialPolicy > +#endif + +#if defined(USE_OPENMP) + , std::pair< ArrayOfArrays< int, INDEX_TYPE, MallocBuffer >, parallelHostPolicy > + , std::pair< ArrayOfArrays< Tensor, INDEX_TYPE, MallocBuffer >, parallelHostPolicy > + , std::pair< ArrayOfArrays< TestString, INDEX_TYPE, MallocBuffer >, parallelHostPolicy > +#endif +#if defined(USE_OPENMP) && defined(USE_CHAI) + , std::pair< ArrayOfArrays< int, INDEX_TYPE, NewChaiBuffer >, parallelHostPolicy > + , std::pair< ArrayOfArrays< Tensor, INDEX_TYPE, NewChaiBuffer >, parallelHostPolicy > + , std::pair< ArrayOfArrays< TestString, INDEX_TYPE, NewChaiBuffer >, parallelHostPolicy > +#endif + +#if defined(USE_CUDA) && defined(USE_CHAI) + , std::pair< ArrayOfArrays< int, INDEX_TYPE, NewChaiBuffer >, parallelDevicePolicy< 32 > > + , std::pair< ArrayOfArrays< Tensor, INDEX_TYPE, NewChaiBuffer >, parallelDevicePolicy< 32 > > +#endif + >; +TYPED_TEST_SUITE( ArrayOfArraysViewAtomicTest, ArrayOfArraysViewAtomicTestTypes, ); + +TYPED_TEST( ArrayOfArraysViewAtomicTest, atomicAppend ) +{ + INDEX_TYPE const NUM_THREADS = 10; + INDEX_TYPE const APPENDS_PER_THREAD = 10; + + this->resize( 100, NUM_THREADS * APPENDS_PER_THREAD ); + this->emplaceBackAtomic( NUM_THREADS, APPENDS_PER_THREAD ); } -#endif // USE_CUDA } // namespace testing } // namespace LvArray + // This is the default gtest main method. It is included for ease of debugging. int main( int argc, char * * argv ) { diff --git a/unitTests/testArrayOfSets.cpp b/unitTests/testArrayOfSets.cpp index 8d78abb7..189d17fe 100644 --- a/unitTests/testArrayOfSets.cpp +++ b/unitTests/testArrayOfSets.cpp @@ -21,6 +21,7 @@ #include "ArrayOfArrays.hpp" #include "Array.hpp" #include "testUtils.hpp" +#include "MallocBuffer.hpp" /// TPL includes #include @@ -36,59 +37,21 @@ namespace testing using INDEX_TYPE = std::ptrdiff_t; -template< class T > -using ViewType = ArrayOfSetsView< T, INDEX_TYPE const >; - -template< class T > -using REF_TYPE = std::vector< std::set< T > >; - -template< class T > -void compareToReference( ViewType< T const > const & view, REF_TYPE< T > const & ref ) -{ - view.consistencyCheck(); - - ASSERT_EQ( view.size(), ref.size()); - - for( INDEX_TYPE i = 0; i < view.size(); ++i ) - { - ASSERT_EQ( view.sizeOfSet( i ), ref[i].size()); - - typename std::set< T >::iterator it = ref[i].begin(); - for( INDEX_TYPE j = 0; j < view.sizeOfSet( i ); ++j ) - { - EXPECT_EQ( view[i][j], *it++ ); - EXPECT_EQ( view( i, j ), view[i][j] ); - } - EXPECT_EQ( it, ref[i].end()); - - it = ref[i].begin(); - for( T const & val : view.getIterableSet( i )) - { - EXPECT_EQ( val, *it++ ); - EXPECT_TRUE( view.contains( i, val )); - } - EXPECT_EQ( it, ref[i].end()); - } -} - -// Use this macro to call compareToReference with better error messages. -#define COMPARE_TO_REFERENCE( view, ref ) { SCOPED_TRACE( "" ); compareToReference( view, ref ); \ -} - -template< class T > -void printArray( ViewType< T const > const & view ) +// This is for debugging. +template< class ARRAY_OF_SETS > +void printArray( ARRAY_OF_SETS const & array ) { std::cout << "{" << std::endl; - for( INDEX_TYPE i = 0; i < view.size(); ++i ) + for( INDEX_TYPE i = 0; i < array.size(); ++i ) { std::cout << "\t{"; - for( INDEX_TYPE j = 0; j < view.sizeOfSet( i ); ++j ) + for( INDEX_TYPE j = 0; j < array.sizeOfSet( i ); ++j ) { - std::cout << view[i][j] << ", "; + std::cout << array[ i ][ j ] << ", "; } - for( INDEX_TYPE j = view.sizeOfSet( i ); j < view.capacityOfSet( i ); ++j ) + for( INDEX_TYPE j = array.sizeOfSet( i ); j < array.capacityOfSet( i ); ++j ) { std::cout << "X" << ", "; } @@ -99,14 +62,50 @@ void printArray( ViewType< T const > const & view ) std::cout << "}" << std::endl; } -template< class T > +template< class ARRAY_OF_SETS > class ArrayOfSetsTest : public ::testing::Test { public: + using T = typename ARRAY_OF_SETS::value_type; + + using ViewType = std::remove_reference_t< decltype( std::declval< ARRAY_OF_SETS >().toView() ) >; + using ViewTypeConst = std::remove_reference_t< decltype( std::declval< ARRAY_OF_SETS >().toViewConst() ) >; + + void compareToReference( ViewTypeConst const & view ) + { + view.consistencyCheck(); + + ASSERT_EQ( view.size(), m_ref.size() ); + + for( INDEX_TYPE i = 0; i < view.size(); ++i ) + { + ASSERT_EQ( view.sizeOfSet( i ), m_ref[ i ].size()); + + typename std::set< T >::iterator it = m_ref[ i ].begin(); + for( INDEX_TYPE j = 0; j < view.sizeOfSet( i ); ++j ) + { + EXPECT_EQ( view[ i ][ j ], *it++ ); + EXPECT_EQ( view( i, j ), view[ i ][ j ] ); + } + EXPECT_EQ( it, m_ref[ i ].end()); + + it = m_ref[ i ].begin(); + for( T const & val : view[ i ] ) + { + EXPECT_EQ( val, *it++ ); + EXPECT_TRUE( view.contains( i, val ) ); + } + EXPECT_EQ( it, m_ref[ i ].end() ); + } + } + + // Use this macro to call compareToReference with better error messages. + #define COMPARE_TO_REFERENCE { SCOPED_TRACE( "" ); this->compareToReference( m_array.toViewConst() ); \ + } void appendSet( INDEX_TYPE const nSets, INDEX_TYPE const maxInserts, INDEX_TYPE const maxValue ) { - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE std::vector< T > arrayToAppend( maxInserts ); @@ -117,7 +116,7 @@ class ArrayOfSetsTest : public ::testing::Test for( INDEX_TYPE j = 0; j < nValues; ++j ) { - arrayToAppend[j] = T( rand( 0, maxValue )); + arrayToAppend[ j ] = T( rand( 0, maxValue )); } m_array.appendSet( nValues ); @@ -131,12 +130,12 @@ class ArrayOfSetsTest : public ::testing::Test m_ref.push_back( std::set< T >( arrayToAppend.begin(), arrayToAppend.end() ) ); } - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE } void insertSet( INDEX_TYPE const nSets, INDEX_TYPE const maxInserts, INDEX_TYPE const maxValue ) { - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE std::vector< T > arrayToAppend( maxInserts ); @@ -147,7 +146,7 @@ class ArrayOfSetsTest : public ::testing::Test for( INDEX_TYPE j = 0; j < nValues; ++j ) { - arrayToAppend[j] = T( rand( 0, maxValue )); + arrayToAppend[ j ] = T( rand( 0, maxValue )); } INDEX_TYPE insertPos = rand( 0, m_array.size()); @@ -163,12 +162,12 @@ class ArrayOfSetsTest : public ::testing::Test m_ref.insert( m_ref.begin() + insertPos, std::set< T >( arrayToAppend.begin(), arrayToAppend.end())); } - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE } void eraseSet( INDEX_TYPE const nSets ) { - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE for( INDEX_TYPE i = 0; i < nSets; ++i ) { @@ -177,33 +176,33 @@ class ArrayOfSetsTest : public ::testing::Test m_ref.erase( m_ref.begin() + removePos ); } - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE } void resize( INDEX_TYPE const newSize, INDEX_TYPE const capacityPerSet=0 ) { - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE m_array.resize( newSize, capacityPerSet ); m_ref.resize( newSize ); - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE } void resize() { - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE INDEX_TYPE const newSize = rand( 0, 2 * m_array.size()); m_array.resize( newSize ); m_ref.resize( newSize ); - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE } void insertIntoSet( INDEX_TYPE const maxInserts, INDEX_TYPE const maxValue ) { - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE INDEX_TYPE const nSets = m_array.size(); for( INDEX_TYPE i = 0; i < nSets; ++i ) @@ -213,16 +212,16 @@ class ArrayOfSetsTest : public ::testing::Test for( INDEX_TYPE j = 0; j < nValues; ++j ) { T const value = T( rand( 0, maxValue )); - EXPECT_EQ( m_array.insertIntoSet( i, value ), m_ref[i].insert( value ).second ); + EXPECT_EQ( m_array.insertIntoSet( i, value ), m_ref[ i ].insert( value ).second ); } } - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE } void insertMultipleIntoSet( INDEX_TYPE const maxInserts, INDEX_TYPE const maxValue ) { - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE INDEX_TYPE const nSets = m_array.size(); @@ -256,12 +255,12 @@ class ArrayOfSetsTest : public ::testing::Test } } - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE } void removeFromSet( INDEX_TYPE const maxInserts, INDEX_TYPE const maxValue ) { - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE INDEX_TYPE const nSets = m_array.size(); for( INDEX_TYPE i = 0; i < nSets; ++i ) @@ -271,16 +270,16 @@ class ArrayOfSetsTest : public ::testing::Test for( INDEX_TYPE j = 0; j < nValues; ++j ) { T const value = T( rand( 0, maxValue )); - EXPECT_EQ( m_array.removeFromSet( i, value ), m_ref[i].erase( value ) ); + EXPECT_EQ( m_array.removeFromSet( i, value ), m_ref[ i ].erase( value ) ); } } - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE } void removeMultipleFromSet( INDEX_TYPE const maxInserts, INDEX_TYPE const maxValue ) { - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE INDEX_TYPE const nSets = m_array.size(); @@ -314,12 +313,12 @@ class ArrayOfSetsTest : public ::testing::Test } } - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE } void compress() { - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE m_array.compress(); T const * const values = m_array[0]; @@ -329,13 +328,13 @@ class ArrayOfSetsTest : public ::testing::Test { EXPECT_EQ( m_array.sizeOfSet( i ), m_array.capacityOfSet( i )); - T const * const curValues = m_array[i]; + T const * const curValues = m_array[ i ]; EXPECT_EQ( values + curOffset, curValues ); curOffset += m_array.sizeOfSet( i ); } - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE } void reserveSet( INDEX_TYPE const maxIncrease ) @@ -353,7 +352,7 @@ class ArrayOfSetsTest : public ::testing::Test void fill() { - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE T const * const values = m_array[0]; T const * const endValues = m_array[m_array.size() - 1]; @@ -366,14 +365,14 @@ class ArrayOfSetsTest : public ::testing::Test EXPECT_EQ( m_array[0], values ); EXPECT_EQ( m_array[m_array.size() - 1], endValues ); - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE } void deepCopy() { - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE - ArrayOfSets< T > copy( m_array ); + ARRAY_OF_SETS copy( m_array ); EXPECT_EQ( m_array.size(), copy.size()); @@ -382,8 +381,8 @@ class ArrayOfSetsTest : public ::testing::Test INDEX_TYPE const setSize = m_array.sizeOfSet( i ); EXPECT_EQ( setSize, copy.sizeOfSet( i )); - T const * const values = m_array[i]; - T const * const valuesCopy = copy[i]; + T const * const values = m_array[ i ]; + T const * const valuesCopy = copy[ i ]; ASSERT_NE( values, valuesCopy ); for( INDEX_TYPE j = setSize -1; j >= 0; --j ) @@ -397,12 +396,12 @@ class ArrayOfSetsTest : public ::testing::Test EXPECT_EQ( m_array.sizeOfSet( i ), setSize ); } - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE } void shallowCopy() { - ViewType< T > const copy( m_array.toView()); + ViewType const copy( m_array.toView()); EXPECT_EQ( m_array.size(), copy.size()); @@ -411,8 +410,8 @@ class ArrayOfSetsTest : public ::testing::Test INDEX_TYPE const setSize = m_array.sizeOfSet( i ); EXPECT_EQ( setSize, copy.sizeOfSet( i )); - T const * const values = m_array[i]; - T const * const valuesCopy = copy[i]; + T const * const values = m_array[ i ]; + T const * const valuesCopy = copy[ i ]; EXPECT_EQ( values, valuesCopy ); for( INDEX_TYPE j = setSize -1; j >= 0; --j ) @@ -433,7 +432,7 @@ class ArrayOfSetsTest : public ::testing::Test void stealFrom( INDEX_TYPE const maxValue, INDEX_TYPE const maxInserts, sortedArrayManipulation::Description const desc ) { INDEX_TYPE const nSets = m_array.size(); - ArrayOfArrays< T > arrayToSteal( nSets ); + typename ArrayConverter< ARRAY_OF_SETS >::template ArrayOfArrays< T > arrayToSteal( nSets ); for( INDEX_TYPE i = 0; i < nSets; ++i ) { @@ -442,31 +441,31 @@ class ArrayOfSetsTest : public ::testing::Test for( INDEX_TYPE j = 0; j < nValues; ++j ) { T const value = T( rand( 0, maxValue )); - bool const insertSuccess = m_ref[i].insert( value ).second; + bool const insertSuccess = m_ref[ i ].insert( value ).second; if( sortedArrayManipulation::isUnique( desc )) { if( insertSuccess ) { - arrayToSteal.appendToArray( i, value ); + arrayToSteal.emplaceBack( i, value ); } } else { - arrayToSteal.appendToArray( i, value ); + arrayToSteal.emplaceBack( i, value ); } } if( sortedArrayManipulation::isSorted( desc )) { - T * const values = arrayToSteal[i]; + T * const values = arrayToSteal[ i ]; std::sort( values, values + arrayToSteal.sizeOfArray( i )); } } m_array.stealFrom( std::move( arrayToSteal ), desc ); - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE } protected: @@ -497,18 +496,18 @@ class ArrayOfSetsTest : public ::testing::Test INDEX_TYPE const setCapacity = m_array.capacityOfSet( i ); INDEX_TYPE nToInsert = setCapacity - setSize; - T const * const values = m_array[i]; + T const * const values = m_array[ i ]; T const * const endValues = m_array[m_array.size() - 1]; while( nToInsert > 0 ) { T const testValue = T( rand( 0, 2 * setCapacity )); bool const inserted = m_array.insertIntoSet( i, testValue ); - EXPECT_EQ( inserted, m_ref[i].insert( testValue ).second ); + EXPECT_EQ( inserted, m_ref[ i ].insert( testValue ).second ); nToInsert -= inserted; } - ASSERT_EQ( m_array[i], values ); + ASSERT_EQ( m_array[ i ], values ); ASSERT_EQ( m_array[m_array.size() - 1], endValues ); ASSERT_EQ( setCapacity, m_array.capacityOfSet( i )); } @@ -518,82 +517,81 @@ class ArrayOfSetsTest : public ::testing::Test static constexpr INDEX_TYPE LARGE_NUMBER = 1E6; - ArrayOfSets< T > m_array; + ARRAY_OF_SETS m_array; std::vector< std::set< T > > m_ref; std::mt19937_64 m_gen; - /// Check that the move, toView, and toViewConst methods of ArrayOfSets< T > are detected. - static_assert( bufferManipulation::HasMemberFunction_move< ArrayOfSets< T > >, - "ArrayOfSets< T > has a move method." ); - static_assert( HasMemberFunction_toView< ArrayOfSets< T > >, - "ArrayOfSets< T > has a toView method." ); - static_assert( HasMemberFunction_toViewConst< ArrayOfSets< T > >, - "ArrayOfSets< T > has a toViewConst method." ); - - /// Check that the move and toViewConst methods of ArrayOfSetsView< T, INDEX_TYPE const > are detected. - static_assert( bufferManipulation::HasMemberFunction_move< ArrayOfSetsView< T, INDEX_TYPE const > >, - "ArrayOfSetsView< T, INDEX_TYPE const > has a move method." ); - static_assert( HasMemberFunction_toView< ArrayOfSetsView< T, INDEX_TYPE const > >, - "ArrayOfSetsView< T, INDEX_TYPE const > has a toView method." ); - static_assert( HasMemberFunction_toViewConst< ArrayOfSetsView< T, INDEX_TYPE const > >, - "ArrayOfSetsView< T, INDEX_TYPE const > has a toViewConst method." ); - - /// Check that the move and toViewConst methods of ArrayOfSetsView< T const, INDEX_TYPE const > are detected. - static_assert( bufferManipulation::HasMemberFunction_move< ArrayOfSetsView< T const, INDEX_TYPE const > >, - "ArrayOfSetsView< T const, INDEX_TYPE const > has a move method." ); - static_assert( HasMemberFunction_toView< ArrayOfSetsView< T const, INDEX_TYPE const > >, - "ArrayOfSetsView< T const, INDEX_TYPE const > has a toView method." ); - static_assert( HasMemberFunction_toViewConst< ArrayOfSetsView< T const, INDEX_TYPE const > >, - "ArrayOfSetsView< T const, INDEX_TYPE const > has a toViewConst method." ); - - /// Check that GetViewType and GetViewTypeConst are correct for ArrayOfSets< T > - static_assert( std::is_same_v< typename GetViewType< ArrayOfSets< T > >::type, - ArrayOfSetsView< T, INDEX_TYPE const > const >, - "The view type of ArrayOfSets< T > is ArrayOfSetsView< T, INDEX_TYPE const > const." ); - static_assert( std::is_same_v< typename GetViewTypeConst< ArrayOfSets< T > >::type, - ArrayOfSetsView< T const, INDEX_TYPE const > const >, - "The const view type of ArrayOfSets< T > is ArrayOfSetsView< T const, INDEX_TYPE const > const." ); - - /// Check that GetViewType and GetViewTypeConst are correct for ArrayOfSetsView< T, INDEX_TYPE const > - static_assert( std::is_same_v< typename GetViewType< ArrayOfSetsView< T, INDEX_TYPE const > >::type, - ArrayOfSetsView< T, INDEX_TYPE const > const >, - "The view type of ArrayOfSetsView< T, INDEX_TYPE const > is ArrayOfSetsView< T, INDEX_TYPE const > const." ); - static_assert( std::is_same_v< typename GetViewTypeConst< ArrayOfSetsView< T, INDEX_TYPE const > >::type, - ArrayOfSetsView< T const, INDEX_TYPE const > const >, - "The const view type of ArrayOfSetsView< T, INDEX_TYPE const > is ArrayOfSetsView< T const, INDEX_TYPE const > const." ); - - /// Check that GetViewType and GetViewTypeConst are correct for ArrayOfSetsView< T const, INDEX_TYPE const > - static_assert( std::is_same_v< typename GetViewType< ArrayOfSetsView< T const, INDEX_TYPE const > >::type, - ArrayOfSetsView< T const, INDEX_TYPE const > const >, - "The view type of ArrayOfSetsView< T const, INDEX_TYPE const > is ArrayOfSetsView< T const, INDEX_TYPE const > const." ); - static_assert( std::is_same_v< typename GetViewTypeConst< ArrayOfSetsView< T const, INDEX_TYPE const > >::type, - ArrayOfSetsView< T const, INDEX_TYPE const > const >, - "The const view type of ArrayOfSetsView< T const, INDEX_TYPE const > is ArrayOfSetsView< T const, INDEX_TYPE const > const." ); + /// Check that the move, toView, and toViewConst methods of ARRAY_OF_SETS are detected. + static_assert( bufferManipulation::HasMemberFunction_move< ARRAY_OF_SETS >, + "ARRAY_OF_SETS has a move method." ); + static_assert( HasMemberFunction_toView< ARRAY_OF_SETS >, + "ARRAY_OF_SETS has a toView method." ); + static_assert( HasMemberFunction_toViewConst< ARRAY_OF_SETS >, + "ARRAY_OF_SETS has a toViewConst method." ); + + /// Check that the move and toViewConst methods of ViewType are detected. + static_assert( bufferManipulation::HasMemberFunction_move< ViewType >, + "ViewType has a move method." ); + static_assert( HasMemberFunction_toView< ViewType >, + "ViewType has a toView method." ); + static_assert( HasMemberFunction_toViewConst< ViewType >, + "ViewType has a toViewConst method." ); + + /// Check that the move and toViewConst methods of ViewTypeConst are detected. + static_assert( bufferManipulation::HasMemberFunction_move< ViewTypeConst >, + "ViewTypeConst has a move method." ); + static_assert( HasMemberFunction_toView< ViewTypeConst >, + "ViewTypeConst has a toView method." ); + static_assert( HasMemberFunction_toViewConst< ViewTypeConst >, + "ViewTypeConst has a toViewConst method." ); + + /// Check that GetViewType and GetViewTypeConst are correct for ARRAY_OF_SETS + static_assert( std::is_same_v< typename GetViewType< ARRAY_OF_SETS >::type, ViewType const >, + "The view type of ARRAY_OF_SETS is ViewType const." ); + static_assert( std::is_same_v< typename GetViewTypeConst< ARRAY_OF_SETS >::type, ViewTypeConst const >, + "The const view type of ARRAY_OF_SETS is ViewTypeConst const." ); + + /// Check that GetViewType and GetViewTypeConst are correct for ViewType + static_assert( std::is_same_v< typename GetViewType< ViewType >::type, ViewType const >, + "The view type of ViewType is ViewType const." ); + static_assert( std::is_same_v< typename GetViewTypeConst< ViewType >::type, ViewTypeConst const >, + "The const view type of ViewType is ViewTypeConst const." ); + + /// Check that GetViewType and GetViewTypeConst are correct for ViewTypeConst + static_assert( std::is_same_v< typename GetViewType< ViewTypeConst >::type, ViewTypeConst const >, + "The view type of ViewTypeConst is ViewTypeConst const." ); + static_assert( std::is_same_v< typename GetViewTypeConst< ViewTypeConst >::type, ViewTypeConst const >, + "The const view type of ViewTypeConst is ViewTypeConst const." ); }; -using TestTypes = ::testing::Types< - INDEX_TYPE - , Tensor - , TestString +using ArrayOfSetsTestTypes = ::testing::Types< + ArrayOfSets< int, INDEX_TYPE, MallocBuffer > + , ArrayOfSets< Tensor, INDEX_TYPE, MallocBuffer > + , ArrayOfSets< TestString, INDEX_TYPE, MallocBuffer > +#if defined(USE_CHAI) + , ArrayOfSets< int, INDEX_TYPE, NewChaiBuffer > + , ArrayOfSets< Tensor, INDEX_TYPE, NewChaiBuffer > + , ArrayOfSets< TestString, INDEX_TYPE, NewChaiBuffer > +#endif >; -TYPED_TEST_SUITE( ArrayOfSetsTest, TestTypes, ); +TYPED_TEST_SUITE( ArrayOfSetsTest, ArrayOfSetsTestTypes, ); INDEX_TYPE const DEFAULT_MAX_INSERTS = 25; INDEX_TYPE const DEFAULT_MAX_VALUE = 2 * DEFAULT_MAX_INSERTS; TYPED_TEST( ArrayOfSetsTest, emptyConstruction ) { - ArrayOfSets< TypeParam > a; + TypeParam a; ASSERT_EQ( a.size(), 0 ); ASSERT_EQ( a.capacity(), 0 ); } TYPED_TEST( ArrayOfSetsTest, sizedConstruction ) { - ArrayOfSets< TypeParam > a( 10 ); + TypeParam a( 10 ); ASSERT_EQ( a.size(), 10 ); ASSERT_EQ( a.capacity(), 10 ); @@ -606,7 +604,7 @@ TYPED_TEST( ArrayOfSetsTest, sizedConstruction ) TYPED_TEST( ArrayOfSetsTest, sizedHintConstruction ) { - ArrayOfSets< TypeParam > a( 10, 20 ); + TypeParam a( 10, 20 ); ASSERT_EQ( a.size(), 10 ); ASSERT_EQ( a.capacity(), 10 ); @@ -744,47 +742,58 @@ TYPED_TEST( ArrayOfSetsTest, stealFromUnsortedWithDuplicates ) this->stealFrom( DEFAULT_MAX_INSERTS, DEFAULT_MAX_VALUE, sortedArrayManipulation::UNSORTED_WITH_DUPLICATES ); } -// Note this is testing capabilities of the ArrayOfArrays class, however it needs to first populate +// This is testing capabilities of the ArrayOfArrays class, however it needs to first populate // the ArrayOfSets so it involves less code duplication to put it here. TYPED_TEST( ArrayOfSetsTest, ArrayOfArraysStealFrom ) { - ArrayOfArrays< TypeParam > array; + typename ArrayConverter< TypeParam >::template ArrayOfArrays< typename TypeParam::value_type > array; this->resize( 50 ); this->insertIntoSet( DEFAULT_MAX_INSERTS, DEFAULT_MAX_VALUE ); - array.stealFrom( std::move( this->m_array )); + array.stealFrom( std::move( this->m_array ) ); ASSERT_EQ( array.size(), this->m_ref.size()); for( INDEX_TYPE i = 0; i < array.size(); ++i ) { - ASSERT_EQ( array.sizeOfArray( i ), this->m_ref[i].size()); + ASSERT_EQ( array.sizeOfArray( i ), this->m_ref[ i ].size()); - typename std::set< TypeParam >::iterator it = this->m_ref[i].begin(); + auto it = this->m_ref[ i ].begin(); for( INDEX_TYPE j = 0; j < array.sizeOfArray( i ); ++j ) { - EXPECT_EQ( array[i][j], *it++ ); + EXPECT_EQ( array[ i ][ j ], *it++ ); } - EXPECT_EQ( it, this->m_ref[i].end()); + EXPECT_EQ( it, this->m_ref[ i ].end()); } } -template< class T_POLICY_PAIR > -class ArrayOfSetsViewTest : public ArrayOfSetsTest< typename T_POLICY_PAIR::first_type > +template< class ARRAY_OF_SETS_POLICY_PAIR > +class ArrayOfSetsViewTest : public ArrayOfSetsTest< typename ARRAY_OF_SETS_POLICY_PAIR::first_type > { public: - using T = typename T_POLICY_PAIR::first_type; - using POLICY = typename T_POLICY_PAIR::second_type; + using ARRAY_OF_SETS = typename ARRAY_OF_SETS_POLICY_PAIR::first_type; + using POLICY = typename ARRAY_OF_SETS_POLICY_PAIR::second_type; + using ParentClass = ArrayOfSetsTest< ARRAY_OF_SETS >; + + using typename ParentClass::T; + using typename ParentClass::ViewType; + using typename ParentClass::ViewTypeConst; + + template< typename T > + using Array1D = typename ArrayConverter< ARRAY_OF_SETS >::template Array< T, 1, RAJA::PERM_I >; + + template< typename T > + using ArrayView1D = typename ArrayConverter< ARRAY_OF_SETS >::template ArrayView< T, 1, 0 >; void memoryMotion() { - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE INDEX_TYPE const nSets = m_array.size(); // Update the view on the device. - ArrayOfSetsView< T, INDEX_TYPE const > const & view = m_array.toView(); + ViewType const & view = m_array.toView(); forall< POLICY >( nSets, [view] LVARRAY_HOST_DEVICE ( INDEX_TYPE const i ) { INDEX_TYPE const sizeOfSet = view.sizeOfSet( i ); @@ -793,7 +802,7 @@ class ArrayOfSetsViewTest : public ArrayOfSetsTest< typename T_POLICY_PAIR::firs PORTABLE_EXPECT_EQ( &view[ i ][ j ], &view( i, j ) ); } - for( T const & val : view.getIterableSet( i )) + for( T const & val : view[ i ] ) { PORTABLE_EXPECT_EQ( view.contains( i, val ), true ); } @@ -802,17 +811,17 @@ class ArrayOfSetsViewTest : public ArrayOfSetsTest< typename T_POLICY_PAIR::firs // Move the view back to the host and compare with the reference. forall< serialPolicy >( 1, [view, this] ( INDEX_TYPE ) { - COMPARE_TO_REFERENCE( view.toViewConst(), m_ref ); + this->compareToReference( view.toViewConst() ); } ); } void memoryMotionMove() { - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE INDEX_TYPE const nSets = m_array.size(); - ArrayOfSetsView< T, INDEX_TYPE const > const & view = m_array.toView(); + ViewType const & view = m_array.toView(); forall< POLICY >( nSets, [view] LVARRAY_HOST_DEVICE ( INDEX_TYPE const i ) { INDEX_TYPE const sizeOfSet = view.sizeOfSet( i ); @@ -821,25 +830,25 @@ class ArrayOfSetsViewTest : public ArrayOfSetsTest< typename T_POLICY_PAIR::firs PORTABLE_EXPECT_EQ( &view[ i ][ j ], &view( i, j ) ); } - for( T const & val : view.getIterableSet( i )) + for( T const & val : view[ i ] ) { PORTABLE_EXPECT_EQ( view.contains( i, val ), true ); } } ); // Move the view back to the host and compare with the reference. - m_array.move( chai::CPU ); - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + m_array.move( MemorySpace::CPU ); + COMPARE_TO_REFERENCE } void insertView() { - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE - Array< Array< T, 1 >, 1 > toInsert = createValues( true, false ); - ArrayView< ArrayView< T const, 1 > const, 1 > const & toInsertView = toInsert.toViewConst(); + Array1D< Array1D< T > > toInsert = createValues( true, false ); + ArrayView1D< ArrayView1D< T const > const > const & toInsertView = toInsert.toViewConst(); - ArrayOfSetsView< T, INDEX_TYPE const > const & view = m_array.toView(); + ViewType const & view = m_array.toView(); forall< POLICY >( m_array.size(), [view, toInsertView] LVARRAY_HOST_DEVICE ( INDEX_TYPE const i ) { for( INDEX_TYPE j = 0; j < toInsertView[ i ].size(); ++j ) @@ -848,35 +857,35 @@ class ArrayOfSetsViewTest : public ArrayOfSetsTest< typename T_POLICY_PAIR::firs } } ); - m_array.move( chai::CPU ); - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + m_array.move( MemorySpace::CPU ); + COMPARE_TO_REFERENCE } void insertMultipleView() { - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE - Array< Array< T, 1 >, 1 > const toInsert = createValues( true, true ); - ArrayView< ArrayView< T const, 1 > const, 1 > const & toInsertView = toInsert.toViewConst(); + Array1D< Array1D< T > > const toInsert = createValues( true, true ); + ArrayView1D< ArrayView1D< T const > const > const & toInsertView = toInsert.toViewConst(); - ArrayOfSetsView< T, INDEX_TYPE const > const & view = m_array.toView(); + ViewType const & view = m_array.toView(); forall< POLICY >( m_array.size(), [view, toInsertView] LVARRAY_HOST_DEVICE ( INDEX_TYPE const i ) { view.insertIntoSet( i, toInsertView[ i ].begin(), toInsertView[ i ].end() ); } ); - m_array.move( chai::CPU ); - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + m_array.move( MemorySpace::CPU ); + COMPARE_TO_REFERENCE } void removeView() { - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE - Array< Array< T, 1 >, 1 > const toRemove = createValues( false, false ); - ArrayView< ArrayView< T const, 1 > const, 1 > const & toRemoveView = toRemove.toViewConst(); + Array1D< Array1D< T > > const toRemove = createValues( false, false ); + ArrayView1D< ArrayView1D< T const > const > const & toRemoveView = toRemove.toViewConst(); - ArrayOfSetsView< T, INDEX_TYPE const > const & view = m_array.toView(); + ViewType const & view = m_array.toView(); forall< POLICY >( m_array.size(), [view, toRemoveView] LVARRAY_HOST_DEVICE ( INDEX_TYPE const i ) { for( INDEX_TYPE j = 0; j < toRemoveView[ i ].size(); ++j ) @@ -885,34 +894,34 @@ class ArrayOfSetsViewTest : public ArrayOfSetsTest< typename T_POLICY_PAIR::firs } } ); - m_array.move( chai::CPU ); - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + m_array.move( MemorySpace::CPU ); + COMPARE_TO_REFERENCE } void removeMultipleView() { - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE - Array< Array< T, 1 >, 1 > const toRemove = createValues( false, true ); - ArrayView< ArrayView< T const, 1 > const, 1 > const & toRemoveView = toRemove.toViewConst(); + Array1D< Array1D< T > > const toRemove = createValues( false, true ); + ArrayView1D< ArrayView1D< T const > const > const & toRemoveView = toRemove.toViewConst(); - ArrayOfSetsView< T, INDEX_TYPE const > const & view = m_array.toView(); + ViewType const & view = m_array.toView(); forall< POLICY >( m_array.size(), [view, toRemoveView] LVARRAY_HOST_DEVICE ( INDEX_TYPE const i ) { view.removeFromSet( i, toRemoveView[ i ].begin(), toRemoveView[ i ].end() ); } ); - m_array.move( chai::CPU ); - COMPARE_TO_REFERENCE( m_array.toViewConst(), m_ref ); + m_array.move( MemorySpace::CPU ); + COMPARE_TO_REFERENCE } protected: - Array< Array< T, 1 >, 1 > createValues( bool const insert, bool const sortedUnique ) + Array1D< Array1D< T > > createValues( bool const insert, bool const sortedUnique ) { INDEX_TYPE const nSets = m_array.size(); - Array< Array< T, 1 >, 1 > values( nSets ); + Array1D< Array1D< T > > values( nSets ); for( INDEX_TYPE i = 0; i < nSets; ++i ) { @@ -945,27 +954,26 @@ class ArrayOfSetsViewTest : public ArrayOfSetsTest< typename T_POLICY_PAIR::firs return values; } - using ArrayOfSetsTest< T >::rand; - using ArrayOfSetsTest< T >::LARGE_NUMBER; - using ArrayOfSetsTest< T >::m_array; - using ArrayOfSetsTest< T >::m_ref; - using ArrayOfSetsTest< T >::m_gen; + using ParentClass::rand; + using ParentClass::LARGE_NUMBER; + using ParentClass::m_array; + using ParentClass::m_ref; + using ParentClass::m_gen; }; using ArrayOfSetsViewTestTypes = ::testing::Types< - std::pair< INDEX_TYPE, serialPolicy > - , std::pair< Tensor, serialPolicy > - , std::pair< TestString, serialPolicy > - -#ifdef USE_OPENMP - , std::pair< INDEX_TYPE, parallelHostPolicy > - , std::pair< Tensor, parallelHostPolicy > - , std::pair< TestString, parallelHostPolicy > + std::pair< ArrayOfSets< int, INDEX_TYPE, MallocBuffer >, serialPolicy > + , std::pair< ArrayOfSets< Tensor, INDEX_TYPE, MallocBuffer >, serialPolicy > + , std::pair< ArrayOfSets< TestString, INDEX_TYPE, MallocBuffer >, serialPolicy > +#if defined(USE_CHAI) + , std::pair< ArrayOfSets< int, INDEX_TYPE, NewChaiBuffer >, serialPolicy > + , std::pair< ArrayOfSets< Tensor, INDEX_TYPE, NewChaiBuffer >, serialPolicy > + , std::pair< ArrayOfSets< TestString, INDEX_TYPE, NewChaiBuffer >, serialPolicy > #endif -#ifdef USE_CUDA - , std::pair< INDEX_TYPE, parallelDevicePolicy< 256 > > - , std::pair< Tensor, parallelDevicePolicy< 256 > > +#if defined(USE_CUDA) && defined(USE_CHAI) + , std::pair< ArrayOfSets< int, INDEX_TYPE, NewChaiBuffer >, parallelDevicePolicy< 32 > > + , std::pair< ArrayOfSets< Tensor, INDEX_TYPE, NewChaiBuffer >, parallelDevicePolicy< 32 > > #endif >; diff --git a/unitTests/testArraySlice.cpp b/unitTests/testArraySlice.cpp index 544fb7a9..25797779 100644 --- a/unitTests/testArraySlice.cpp +++ b/unitTests/testArraySlice.cpp @@ -18,83 +18,148 @@ // Source includes #include "Array.hpp" +#include "MallocBuffer.hpp" // TPL includes #include -using namespace LvArray; - -template< typename T, int NDIM, typename PERM, typename INDEX_TYPE, typename DIMS, camp::idx_t ... INDICES > -void resizeArray( Array< T, NDIM, PERM, INDEX_TYPE > & a, DIMS const & newdims, - camp::idx_seq< INDICES... > ) +namespace LvArray { - static_assert( sizeof...(INDICES) == NDIM, "Number of indices must be equal to number of dimensions" ); - a.resize( newdims[INDICES] ... ); -} -template< typename PERMUTATION > -class PermutedSliceTest : public ::testing::Test {}; - -using Permutations = ::testing::Types< RAJA::PERM_IJ, - RAJA::PERM_JI, - RAJA::PERM_IJK, - RAJA::PERM_JIK, - RAJA::PERM_IKJ, - RAJA::PERM_KIJ, - RAJA::PERM_KJI, - RAJA::PERM_JKI, - RAJA::PERM_IJKL, - RAJA::PERM_JIKL, - RAJA::PERM_IKJL, - RAJA::PERM_KIJL, - RAJA::PERM_JKIL, - RAJA::PERM_KJIL, - RAJA::PERM_IJLK, - RAJA::PERM_JILK, - RAJA::PERM_ILJK, - RAJA::PERM_LIJK, - RAJA::PERM_JLIK, - RAJA::PERM_LJIK, - RAJA::PERM_IKLJ, - RAJA::PERM_KILJ, - RAJA::PERM_ILKJ, - RAJA::PERM_LIKJ, - RAJA::PERM_KLIJ, - RAJA::PERM_LKIJ, - RAJA::PERM_JKLI, - RAJA::PERM_KJLI, - RAJA::PERM_JLKI, - RAJA::PERM_LJKI, - RAJA::PERM_KLJI, - RAJA::PERM_LKJI >; - -TYPED_TEST_SUITE( PermutedSliceTest, Permutations, ); - -TYPED_TEST( PermutedSliceTest, IsContiguous ) +template< typename T, typename PERMUTATION > +using ArrayT = Array< T, getDimension( PERMUTATION {} ), PERMUTATION, std::ptrdiff_t, MallocBuffer >; + +template< typename ARRAY > +class ArraySliceTest : public ::testing::Test { - using PERMUTATION = TypeParam; - constexpr int NDIM = getDimension( PERMUTATION {} ); +public: + static constexpr int NDIM = ARRAY::ndim; + using PERMUTATION = typename ARRAY::permutation; - // Create a permuted array and resize with nontrivial sizes - Array< int, NDIM, PERMUTATION, int > a; - std::array< int, NDIM > dims{}; - for( int i = 0; i < NDIM; ++i ) + void resize() { - dims[i] = 2+i; + // Create a permuted array and resize with nontrivial sizes + std::array< int, NDIM > dims{}; + for( int i = 0; i < NDIM; ++i ) + { dims[ i ] = 2 + i; } + m_array.resize( NDIM, dims.data() ); } - resizeArray( a, dims, camp::make_idx_seq_t< NDIM >{} ); - // The only way to get a contiguous (NDIM-1)-dimenstional slice is by - // chopping along the largest-stride dimension (i.e. first in permutation) - bool const contiguous = RAJA::as_array< PERMUTATION >::get()[0] == 0; + template< int _NDIM=NDIM > + std::enable_if_t< _NDIM == 2 > + isContiguous() + { checkOneSlice(); } - // There's no need to test all slices, but we might as well - for( int i = 0; i < dims[0]; ++i ) + template< int _NDIM=NDIM > + std::enable_if_t< _NDIM == 3 > + isContiguous() { - EXPECT_EQ( a[i].isContiguous(), contiguous ); + checkOneSlice(); + checkTwoSlices(); } + + template< int _NDIM=NDIM > + std::enable_if_t< _NDIM == 4 > + isContiguous() + { + checkOneSlice(); + checkTwoSlices(); + checkThreeSlices(); + } + +protected: + + void checkOneSlice() + { + // The only way to get a contiguous (NDIM-1)-dimensional slice is by + // chopping along the largest-stride dimension (i.e. first in permutation) + bool const contiguous = RAJA::as_array< PERMUTATION >::get()[ 0 ] == 0; + + // There's no need to test all slices, but we might as well + for( int i = 0; i < m_array.size( 0 ); ++i ) + { EXPECT_EQ( m_array[ i ].isContiguous(), contiguous ); } + } + + void checkTwoSlices() + { + bool const contiguous = RAJA::as_array< PERMUTATION >::get()[ 0 ] <= 1 && + RAJA::as_array< PERMUTATION >::get()[ 1 ] <= 1; + + for( int i = 0; i < m_array.size( 0 ); ++i ) + { + for( int j = 0; j < m_array.size( 1 ); ++j ) + { + EXPECT_EQ( m_array[ i ][ j ].isContiguous(), contiguous ); + } + } + } + + void checkThreeSlices() + { + bool const contiguous = RAJA::as_array< PERMUTATION >::get()[ 0 ] <= 2 && + RAJA::as_array< PERMUTATION >::get()[ 1 ] <= 2 && + RAJA::as_array< PERMUTATION >::get()[ 2 ] <= 2; + + for( int i = 0; i < m_array.size( 0 ); ++i ) + { + for( int j = 0; j < m_array.size( 1 ); ++j ) + { + for( int k = 0; k < m_array.size( 2 ); ++k ) + { + EXPECT_EQ( m_array[ i ][ j ][ k ].isContiguous(), contiguous ); + } + } + } + } + + ARRAY m_array; +}; + +using ArraySliceTestTypes = ::testing::Types< + ArrayT< int, RAJA::PERM_IJ > + , ArrayT< int, RAJA::PERM_JI > + , ArrayT< int, RAJA::PERM_IJK > + , ArrayT< int, RAJA::PERM_JIK > + , ArrayT< int, RAJA::PERM_IKJ > + , ArrayT< int, RAJA::PERM_KIJ > + , ArrayT< int, RAJA::PERM_KJI > + , ArrayT< int, RAJA::PERM_JKI > + , ArrayT< int, RAJA::PERM_IJKL > + , ArrayT< int, RAJA::PERM_JIKL > + , ArrayT< int, RAJA::PERM_IKJL > + , ArrayT< int, RAJA::PERM_KIJL > + , ArrayT< int, RAJA::PERM_JKIL > + , ArrayT< int, RAJA::PERM_KJIL > + , ArrayT< int, RAJA::PERM_IJLK > + , ArrayT< int, RAJA::PERM_JILK > + , ArrayT< int, RAJA::PERM_ILJK > + , ArrayT< int, RAJA::PERM_LIJK > + , ArrayT< int, RAJA::PERM_JLIK > + , ArrayT< int, RAJA::PERM_LJIK > + , ArrayT< int, RAJA::PERM_IKLJ > + , ArrayT< int, RAJA::PERM_KILJ > + , ArrayT< int, RAJA::PERM_ILKJ > + , ArrayT< int, RAJA::PERM_LIKJ > + , ArrayT< int, RAJA::PERM_KLIJ > + , ArrayT< int, RAJA::PERM_LKIJ > + , ArrayT< int, RAJA::PERM_JKLI > + , ArrayT< int, RAJA::PERM_KJLI > + , ArrayT< int, RAJA::PERM_JLKI > + , ArrayT< int, RAJA::PERM_LJKI > + , ArrayT< int, RAJA::PERM_KLJI > + , ArrayT< int, RAJA::PERM_LKJI > + >; + +TYPED_TEST_SUITE( ArraySliceTest, ArraySliceTestTypes, ); + +TYPED_TEST( ArraySliceTest, IsContiguous ) +{ + this->resize(); + this->checkOneSlice(); } +} // namespace LvArray + // This is the default gtest main method. It is included for ease of debugging. int main( int argc, char * * argv ) { diff --git a/unitTests/testArrayUtilities.cpp b/unitTests/testArrayUtilities.cpp index 5ef42a94..e05433b7 100644 --- a/unitTests/testArrayUtilities.cpp +++ b/unitTests/testArrayUtilities.cpp @@ -16,94 +16,93 @@ *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -/* - * Copyright (c) 2015, Lawrence Livermore National Security, LLC. - * Produced at the Lawrence Livermore National Laboratory. - * - * All rights reserved. - * - * This source code cannot be distributed without permission and - * further review from Lawrence Livermore National Laboratory. - */ +// Source includes +#include "streamIO.hpp" +#include "MallocBuffer.hpp" +// TPL includes #include + +// System includes #include -#include "streamIO.hpp" const char IGNORE_OUTPUT[] = ".*"; -using namespace LvArray; -using namespace std; +namespace LvArray +{ + +template< typename T, typename PERMUTATION > +using ArrayT = Array< T, getDimension( PERMUTATION {} ), PERMUTATION, std::ptrdiff_t, MallocBuffer >; TEST( testArrayUtilities, stringToArrayErrors ) { - string input; + std::string input; // This should work { input = " { { {0,1,2},{3,4,5} }, { {6,7,8},{9,10,11} }, { {12,13,14},{15,16,17} } , { {18,19,20},{21,22,23} } }"; - LvArray::Array< int, 3 > array; + ArrayT< int, RAJA::PERM_IJK > array; stringToArray( array, input ); } { input = " { 10 1 } "; - LvArray::Array< int, 1 > array; + ArrayT< int, RAJA::PERM_I > array; EXPECT_DEATH_IF_SUPPORTED( stringToArray( array, input ), IGNORE_OUTPUT ); } { input = " { { 1, 2 }{ 3, 4 } } "; - LvArray::Array< int, 2 > array; + ArrayT< int, RAJA::PERM_IJ > array; EXPECT_DEATH_IF_SUPPORTED( stringToArray( array, input ), IGNORE_OUTPUT ); } // This should fail the num('{')==num('}') test { input = " { { {0,1,2},{3,4,5} }, { {6,7,8},{9,10,11} }, { {12,13,14},{15,16,17} } , { {18,19,20},{21,22,23} } "; - LvArray::Array< int, 3 > array; + ArrayT< int, RAJA::PERM_IJK > array; EXPECT_DEATH_IF_SUPPORTED( stringToArray( array, input ), IGNORE_OUTPUT ); } { input = " { { {0,1,2},{3,4,5} }, { {6,7,8},{9,10,11} }, { {12,13,14},{15,16,17} , { {18,19,20},{21,22,23} } }"; - LvArray::Array< int, 3 > array; + ArrayT< int, RAJA::PERM_IKJ > array; EXPECT_DEATH_IF_SUPPORTED( stringToArray( array, input ), IGNORE_OUTPUT ); } { input = " { { {0,1,2},{3,4,5} }, { {6,7,8},{9,10,11} }, { {12,13,14,{15,16,17} } , { {18,19,20},{21,22,23} } }"; - LvArray::Array< int, 3 > array; + ArrayT< int, RAJA::PERM_JIK > array; EXPECT_DEATH_IF_SUPPORTED( stringToArray( array, input ), IGNORE_OUTPUT ); } { input = " { { {0,1,2},{3,4,5} }, { {6,7,8,{9,10,11} }, { {12,13,14},{15,16,17} } , { {18,19,20},{21,22,23} } }"; - LvArray::Array< int, 3 > array; + ArrayT< int, RAJA::PERM_JKI > array; EXPECT_DEATH_IF_SUPPORTED( stringToArray( array, input ), IGNORE_OUTPUT ); } { input = " { { 0,1,2},{3,4,5} }, { {6,7,8},{9,10,11} }, { {12,13,14},{15,16,17} } , { {18,19,20},{21,22,23} } }"; - LvArray::Array< int, 3 > array; + ArrayT< int, RAJA::PERM_KIJ > array; EXPECT_DEATH_IF_SUPPORTED( stringToArray( array, input ), IGNORE_OUTPUT ); } { input = " { {0,1,2},{3,4,5} }, { {6,7,8},{9,10,11} }, { {12,13,14},{15,16,17} } , { {18,19,20},{21,22,23} } "; - LvArray::Array< int, 3 > array; + ArrayT< int, RAJA::PERM_KJI > array; EXPECT_DEATH_IF_SUPPORTED( stringToArray( array, input ), IGNORE_OUTPUT ); } { input = " { { {,1,2},{3,4,5} }, { {6,7,8},{9,10,11} }, { {12,13,14},{15,16,17} } , { {18,19,20},{21,22,23} } }"; - LvArray::Array< int, 3 > array; + ArrayT< int, RAJA::PERM_IJK > array; EXPECT_DEATH_IF_SUPPORTED( stringToArray( array, input ), IGNORE_OUTPUT ); } { input = " { { {},{3,4,5} }, { {6,7,8},{9,10,11} }, { {12,13,14},{15,16,17} } , { {18,19,20},{21,22,23} } }"; - LvArray::Array< int, 3 > array; + ArrayT< int, RAJA::PERM_IJK > array; EXPECT_DEATH_IF_SUPPORTED( stringToArray( array, input ), IGNORE_OUTPUT ); } { input = " { { {0,1,2}}{ } }"; - LvArray::Array< int, 3 > array; + ArrayT< int, RAJA::PERM_IJK > array; EXPECT_DEATH_IF_SUPPORTED( stringToArray( array, input ), IGNORE_OUTPUT ); } @@ -112,9 +111,7 @@ TEST( testArrayUtilities, stringToArrayErrors ) TEST( testArrayUtilities, stringToArray3d ) { -// string input = " { { {0,1,2},{3,4,5} }, { {6,7,8},{9,10,11} }, { {12,13,14},{15,16,17} } , { {18,19,20},{21,22,23} } -// }"; - string input; + std::string input; input += "{ "; int numI = 4; int numJ = 5; @@ -147,7 +144,7 @@ TEST( testArrayUtilities, stringToArray3d ) } input += " }"; - LvArray::Array< int, 3 > array; + ArrayT< int, RAJA::PERM_JIK > array; stringToArray( array, input ); ASSERT_EQ( array.size( 0 ), numI ); @@ -170,7 +167,7 @@ TEST( testArrayUtilities, stringToArray3d ) TEST( testArrayUtilities, arrayToString ) { - LvArray::Array< int, 3 > array( 2, 4, 3 ); + ArrayT< int, RAJA::PERM_IKJ > array( 2, 4, 3 ); for( int i=0; i<2; ++i ) { @@ -189,3 +186,5 @@ TEST( testArrayUtilities, arrayToString ) " { { 100, 101, 102 }, { 110, 111, 112 }, { 120, 121, 122 }, { 130, 131, 132 } } }" ); } + +} // namespace LvArray diff --git a/unitTests/testArrayView.cpp b/unitTests/testArrayView.cpp deleted file mode 100644 index 794ea820..00000000 --- a/unitTests/testArrayView.cpp +++ /dev/null @@ -1,1195 +0,0 @@ -/* - *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * Copyright (c) 2018, Lawrence Livermore National Security, LLC. - * - * Produced at the Lawrence Livermore National Laboratory - * - * LLNL-CODE-746361 - * - * All rights reserved. See COPYRIGHT for details. - * - * This file is part of the GEOSX Simulation Framework. - * - * GEOSX is a free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License (as published by the - * Free Software Foundation) version 2.1 dated February 1999. - *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - */ - -// Source includes -#include "Array.hpp" -#include "SetSignalHandling.hpp" -#include "stackTrace.hpp" -#include "testUtils.hpp" - -// TPL includes -#include - -#if defined( USE_CUDA ) && defined( USE_CHAI ) - #include -#endif - -// System includes -#include -#include - -namespace LvArray -{ -namespace testing -{ - -using INDEX_TYPE = std::ptrdiff_t; - -template< typename T > -using array = Array< T, 1 >; - -template< typename T > -using arrayView = ArrayView< T, 1 > const; - -template< typename T > -using arrayView_nc = ArrayView< T, 1 >; - -template< typename T > -using arraySlice = ArraySlice< T, 1 > const; - - -template< typename T > -using array2D = Array< T, 2 >; - -template< typename T > -using arrayView2D = ArrayView< T, 2 > const; - -template< typename T > -using array3D = Array< T, 3 >; - -template< typename T > -using arrayView3D = ArrayView< T, 3 > const; - -int rand( int const low, int const high ) -{ - static std::mt19937_64 m_gen; - return std::uniform_int_distribution< int >( low, high )( m_gen ); -} - -template< int USD, typename LAYOUT > -void compareArrayToRAJAView( LvArray::ArrayView< int, 2, USD > const & v, - RAJA::View< int, LAYOUT > view ) -{ - ASSERT_EQ( v.size( 0 ), view.layout.sizes[ 0 ] ); - ASSERT_EQ( v.size( 1 ), view.layout.sizes[ 1 ] ); - - int const * const data = v.data(); - ASSERT_EQ( data, view.data ); - - for( int i = 0; i < v.size( 0 ); ++i ) - { - for( int j = 0; j < v.size( 1 ); ++j ) - { - EXPECT_EQ( &view( i, j ) - data, &v[ i ][ j ] - data ); - EXPECT_EQ( &view( i, j ) - data, &v( i, j ) - data ); - } - } -} - -template< int USD, typename LAYOUT > -void compareArrayToRAJAView( LvArray::ArrayView< int, 3, USD > const & v, - RAJA::View< int, LAYOUT > view ) -{ - ASSERT_EQ( v.size( 0 ), view.layout.sizes[ 0 ] ); - ASSERT_EQ( v.size( 1 ), view.layout.sizes[ 1 ] ); - ASSERT_EQ( v.size( 2 ), view.layout.sizes[ 2 ] ); - - int const * const data = v.data(); - ASSERT_EQ( data, view.data ); - - for( int i = 0; i < v.size( 0 ); ++i ) - { - for( int j = 0; j < v.size( 1 ); ++j ) - { - for( int k = 0; k < v.size( 2 ); ++k ) - { - EXPECT_EQ( &view( i, j, k ) - data, &v[ i ][ j ][ k ] - data ); - EXPECT_EQ( &view( i, j, k ) - data, &v( i, j, k ) - data ) << i << ", " << j << ", " << k; - } - } - } -} - -template< int USD, typename LAYOUT > -void compareArrayToRAJAView( LvArray::ArrayView< int, 4, USD > const & v, - RAJA::View< int, LAYOUT > view ) -{ - ASSERT_EQ( v.size( 0 ), view.layout.sizes[ 0 ] ); - ASSERT_EQ( v.size( 1 ), view.layout.sizes[ 1 ] ); - ASSERT_EQ( v.size( 2 ), view.layout.sizes[ 2 ] ); - ASSERT_EQ( v.size( 3 ), view.layout.sizes[ 3 ] ); - - int const * const data = v.data(); - ASSERT_EQ( data, view.data ); - - for( int i = 0; i < v.size( 0 ); ++i ) - { - for( int j = 0; j < v.size( 1 ); ++j ) - { - for( int k = 0; k < v.size( 2 ); ++k ) - { - for( int l = 0; l < v.size( 3 ); ++l ) - { - EXPECT_EQ( &view( i, j, k, l ) - data, &v[ i ][ j ][ k ][ l ] - data ); - EXPECT_EQ( &view( i, j, k, l ) - data, &v( i, j, k, l ) - data ); - EXPECT_EQ( view( i, j, k, l ), v( i, j, k, l ) ); - } - } - } - } -} - -template< typename PERMUTATION > -void testArrayPermutation() -{ - constexpr int NDIM = LvArray::getDimension( PERMUTATION {} ); - LvArray::Array< int, NDIM, PERMUTATION > a; - - std::array< INDEX_TYPE, NDIM > dimensions; - for( int i = 0; i < NDIM; ++i ) - { - dimensions[ i ] = rand( 1, 10 ); - } - - a.resize( NDIM, dimensions.data() ); - - RAJA::View< int, RAJA::Layout< NDIM > > view( a.data(), RAJA::make_permuted_layout( dimensions, RAJA::as_array< PERMUTATION >::get() ) ); - - for( int i = 0; i < NDIM; ++i ) - { - EXPECT_EQ( a.strides()[ i ], view.layout.strides[ i ] ); - } - - for( int i = 0; i < a.size(); ++i ) - { - a.data()[ i ] = i; - } - - compareArrayToRAJAView( a, view ); -} - -#ifdef USE_CUDA - - -template< typename T > -void testMemoryMotion( arrayView< T > & v ) -{ - const INDEX_TYPE N = v.size(); - - for( INDEX_TYPE i = 0; i < N; ++i ) - { - v[ i ] = T( i ); - } - - forall( gpu(), 0, N, - [=] __device__ ( INDEX_TYPE i ) - { - v[ i ] += v[ i ]; - } - ); - - forall( sequential(), 0, N, - [=]( INDEX_TYPE i ) - { - T val( i ); - val += val; - EXPECT_EQ( v[ i ], val ); - } - ); -} - - -template< typename T > -void testMemoryMotionConst( array< T > & a ) -{ - const INDEX_TYPE N = a.size(); - - for( INDEX_TYPE i = 0; i < N; ++i ) - { - a[ i ] = T( i ); - } - - arrayView< T const > & v = a.toViewConst(); - - // Capture the view on the device. - forall( gpu(), 0, N, - [=] __device__ ( INDEX_TYPE i ) - { - assert( v[i] == T( i )); - } - ); - - // Change the values that the array holds. - for( INDEX_TYPE i = 0; i < N; ++i ) - { - a[ i ] = T( 2 * i ); - } - - // Copy the array back to the host, should be a no-op since it was captured as T const - // and therefore the values should be those set above. - forall( sequential(), 0, N, - [=]( INDEX_TYPE i ) - { - EXPECT_EQ( v[ i ], T( 2 * i ) ); - } - ); -} - - -template< typename T > -void testMemoryMotionMove( array< T > & a ) -{ - const INDEX_TYPE N = a.size(); - - for( INDEX_TYPE i = 0; i < N; ++i ) - { - a[ i ] = T( i ); - } - - a.move( chai::GPU ); - arrayView< T > & v = a; - T const * const v_device_ptr = v.data(); - - forall( gpu(), 0, N, - [=] __device__ ( INDEX_TYPE i ) - { - v[ i ] += v[ i ]; - } - ); - - /* The copy construction shouldn't have changed the pointer since we moved it. */ - ASSERT_EQ( v_device_ptr, v.data()); - - a.move( chai::CPU ); - for( INDEX_TYPE i = 0; i < N; ++i ) - { - T val = T( i ); - val += val; - EXPECT_EQ( v[ i ], val ); - } -} - -template< typename T > -void testMemoryMotionMultiple( arrayView< T > & v ) -{ - const INDEX_TYPE N = v.size(); - - for( INDEX_TYPE i = 0; i < N; ++i ) - { - v[ i ] = T( i ); - } - - forall( gpu(), 0, N, - [=] __device__ ( INDEX_TYPE i ) - { - v[ i ] += T( 2 ); - } - ); - - forall( gpu(), 0, N, - [=] __device__ ( INDEX_TYPE i ) - { - v[ i ] += T( 2 ); - } - ); - - forall( sequential(), 0, N, - [=]( INDEX_TYPE i ) - { - v[ i ] += T( 2 ); - } - ); - - forall( gpu(), 0, N, - [=] __device__ ( INDEX_TYPE i ) - { - v[ i ] += T( 2 ); - } - ); - - - forall( sequential(), 0, N, - [=]( INDEX_TYPE i ) - { - T val( i ); - val += T( 2 ); - val += T( 2 ); - val += T( 2 ); - val += T( 2 ); - EXPECT_EQ( v[ i ], val ); - } - ); -} - -template< typename T > -void testMemoryMotionMultipleMove( array< T > & a ) -{ - arrayView< T > & v = a; - - const INDEX_TYPE N = v.size(); - - for( INDEX_TYPE i = 0; i < N; ++i ) - { - v[ i ] = T( i ); - } - - forall( gpu(), 0, N, - [=] __device__ ( INDEX_TYPE i ) - { - v[ i ] += T( 2 ); - } - ); - - forall( gpu(), 0, N, - [=] __device__ ( INDEX_TYPE i ) - { - v[ i ] += T( 2 ); - } - ); - - a.move( chai::CPU ); - for( INDEX_TYPE i = 0; i < N; ++i ) - { - v[ i ] += T( 2 ); - } - - forall( gpu(), 0, N, - [=] __device__ ( INDEX_TYPE i ) - { - v[ i ] += T( 2 ); - } - ); - - a.move( chai::CPU ); - for( INDEX_TYPE i = 0; i < N; ++i ) - { - T val( i ); - val += T( 2 ); - val += T( 2 ); - val += T( 2 ); - val += T( 2 ); - EXPECT_EQ( v[ i ], val ); - } -} - - -template< typename T > -void testMemoryMotionArray( array< array< T > > & a ) -{ - arrayView< arrayView< T > > & v = a.toView(); - - const INDEX_TYPE N = v.size(); - - for( INDEX_TYPE i = 0; i < N; ++i ) - { - for( INDEX_TYPE j = 0; j < N; ++j ) - { - v[ i ][ j ] = T( N * i + j ); - } - } - - forall( gpu(), 0, N, - [=] __device__ ( INDEX_TYPE i ) - { - for( INDEX_TYPE j = 0; j < N; ++j ) - { - v[ i ][ j ] += v[ i ][ j ]; - } - } - ); - - forall( sequential(), 0, N, - [=]( INDEX_TYPE i ) - { - for( INDEX_TYPE j = 0; j < N; ++j ) - { - T val( N * i + j ); - val += val; - EXPECT_EQ( v[ i ][ j ], val ); - } - } - ); -} - -template< typename T > -void testMemoryMotionArrayConst( array< array< T > > & a ) -{ - const INDEX_TYPE N = a.size(); - - // Create a shallow copy of a that we can modify later. - array< arrayView_nc< T > > a_copy; - a_copy.resize( N ); - - for( INDEX_TYPE i = 0; i < N; ++i ) - { - a_copy[ i ] = a[ i ]; - for( INDEX_TYPE j = 0; j < N; ++j ) - { - a[ i ][ j ] = T( N * i + j ); - } - } - - // Create a const view and capture it. - arrayView< arrayView< T const > > & v = a.toViewConst(); - forall( gpu(), 0, N, - [=] __device__ ( INDEX_TYPE i ) - { - for( INDEX_TYPE j = 0; j < N; ++j ) - { - assert( v[ i ][ j ] == T( N * i + j )); - } - } - ); - - // Modify a_copy. We can't use a directly since the inner arrays - // have device pointers. - for( INDEX_TYPE i = 0; i < N; ++i ) - { - for( INDEX_TYPE j = 0; j < N; ++j ) - { - a_copy[ i ][ j ] = T( 2 * ( N * i + j ) ); - } - } - - // Check that the modifications weren't overwritten. - forall( sequential(), 0, N, - [=]( INDEX_TYPE i ) - { - for( INDEX_TYPE j = 0; j < N; ++j ) - { - EXPECT_EQ( v[ i ][ j ], T( 2 * ( N * i + j ) ) ); - } - } - ); -} - - -template< typename T > -void testMemoryMotionArrayMove( array< array< T > > & a ) -{ - arrayView< arrayView< T > > & v = a.toView(); - - const INDEX_TYPE N = v.size(); - - for( INDEX_TYPE i = 0; i < N; ++i ) - { - for( INDEX_TYPE j = 0; j < N; ++j ) - { - v[ i ][ j ] = T( N * i + j ); - } - } - - forall( gpu(), 0, N, - [=] __device__ ( INDEX_TYPE i ) - { - for( INDEX_TYPE j = 0; j < N; ++j ) - { - v[ i ][ j ] += v[ i ][ j ]; - } - } - ); - - a.move( chai::CPU ); - for( INDEX_TYPE i = 0; i < N; ++i ) - { - for( INDEX_TYPE j = 0; j < N; ++j ) - { - T val( N * i + j ); - val += val; - EXPECT_EQ( v[ i ][ j ], val ); - } - } -} - - -template< typename T > -void testMemoryMotionArray2( array< array< array< T > > > & a ) -{ - arrayView< arrayView< arrayView< T > > > & v = a.toView(); - - const INDEX_TYPE N = v.size(); - - for( INDEX_TYPE i = 0; i < N; ++i ) - { - for( INDEX_TYPE j = 0; j < N; ++j ) - { - for( INDEX_TYPE k = 0; k < N; ++k ) - { - v[ i ][ j ][ k ] = T( N * N * i + N * j + k ); - } - } - } - - forall( gpu(), 0, N, - [=] __device__ ( INDEX_TYPE i ) - { - for( INDEX_TYPE j = 0; j < N; ++j ) - { - for( INDEX_TYPE k = 0; k < N; ++k ) - { - v[ i ][ j ][ k ] += v[ i ][ j ][ k ]; - } - } - } - ); - - forall( sequential(), 0, N, - [=]( INDEX_TYPE i ) - { - for( INDEX_TYPE j = 0; j < N; ++j ) - { - for( INDEX_TYPE k = 0; k < N; ++k ) - { - T val( N * N * i + N * j + k ); - val += val; - EXPECT_EQ( v[ i ][ j ][ k ], val ); - } - } - } - ); -} - -template< typename T > -void testMemoryMotionArray2Const( array< array< array< T > > > & a ) -{ - const INDEX_TYPE N = a.size(); - - for( INDEX_TYPE i = 0; i < N; ++i ) - { - for( INDEX_TYPE j = 0; j < N; ++j ) - { - for( INDEX_TYPE k = 0; k < N; ++k ) - { - a[ i ][ j ][ k ] = T( N * N * i + N * j + k ); - } - } - } - - arrayView< arrayView< arrayView< T const > const > const > const & v = a.toViewConst(); - forall( gpu(), 0, N, - [v, N] __device__ ( INDEX_TYPE i ) - { - for( INDEX_TYPE j = 0; j < N; ++j ) - { - for( INDEX_TYPE k = 0; k < N; ++k ) - { - const_cast< T & >( v[ i ][ j ][ k ] ) = T( N * N * i + N * j + k + 1 ); - } - } - } - ); - - forall( sequential(), 0, N, - [v, N]( INDEX_TYPE const i ) - { - for( INDEX_TYPE j = 0; j < N; ++j ) - { - for( INDEX_TYPE k = 0; k < N; ++k ) - { - EXPECT_EQ( v[ i ][ j ][ k ], T( N * N * i + N * j + k ) ); - } - } - } - ); -} - - -template< typename T > -void testMemoryMotionArrayMove2( array< array< array< T > > > & a ) -{ - arrayView< arrayView< arrayView< T > > > & v = a.toView(); - - const INDEX_TYPE N = v.size(); - - for( INDEX_TYPE i = 0; i < N; ++i ) - { - for( INDEX_TYPE j = 0; j < N; ++j ) - { - for( INDEX_TYPE k = 0; k < N; ++k ) - { - v[ i ][ j ][ k ] = T( N * N * i + N * j + k ); - } - } - } - - forall( gpu(), 0, N, - [=] __device__ ( INDEX_TYPE i ) - { - for( INDEX_TYPE j = 0; j < N; ++j ) - { - for( INDEX_TYPE k = 0; k < N; ++k ) - { - v[ i ][ j ][ k ] += v[ i ][ j ][ k ]; - } - } - } - ); - - a.move( chai::CPU ); - for( INDEX_TYPE i = 0; i < N; ++i ) - { - for( INDEX_TYPE j = 0; j < N; ++j ) - { - for( INDEX_TYPE k = 0; k < N; ++k ) - { - T val( N * N * i + N * j + k ); - val += val; - EXPECT_EQ( v[ i ][ j ][ k ], val ); - } - } - } -} - - -template< typename T > -void test2DAccessorsDevice( arrayView2D< T > & v ) -{ - const INDEX_TYPE I = v.size( 0 ); - const INDEX_TYPE J = v.size( 1 ); - - for( INDEX_TYPE i = 0; i < I; ++i ) - { - for( INDEX_TYPE j = 0; j < J; ++j ) - { - v[ i ][ j ] = T( J * i + j ); - } - } - - forall( gpu(), 0, I, - [=] __device__ ( INDEX_TYPE i ) - { - for( INDEX_TYPE j = 0; j < J; ++j ) - { - v( i, j ) += T( 2 ); - v[ i ][ j ] += T( 2 ); - } - } - ); - - forall( sequential(), 0, I, - [=] ( INDEX_TYPE i ) - { - for( INDEX_TYPE j = 0; j < J; ++j ) - { - T val( J * i + j ); - val += T( 2 ); - val += T( 2 ); - EXPECT_EQ( v[ i ][ j ], val ); - } - } - ); -} - - -template< typename T > -void test3DAccessorsDevice( arrayView3D< T > & v ) -{ - const INDEX_TYPE I = v.size( 0 ); - const INDEX_TYPE J = v.size( 1 ); - const INDEX_TYPE K = v.size( 2 ); - - for( INDEX_TYPE i = 0; i < I; ++i ) - { - for( INDEX_TYPE j = 0; j < J; ++j ) - { - for( INDEX_TYPE k = 0; k < K; ++k ) - { - v[ i ][ j ][ k ] = T( J * K * i + K * j + k ); - } - } - } - - forall( gpu(), 0, I, - [=] __device__ ( INDEX_TYPE i ) - { - for( INDEX_TYPE j = 0; j < J; ++j ) - { - for( INDEX_TYPE k = 0; k < K; ++k ) - { - v( i, j, k ) += T( 2 ); - v[ i ][ j ][ k ] += T( 2 ); - } - } - } - ); - - forall( sequential(), 0, I, - [=] ( INDEX_TYPE i ) - { - for( INDEX_TYPE j = 0; j < J; ++j ) - { - for( INDEX_TYPE k = 0; k < K; ++k ) - { - T val( J * K * i + K * j + k ); - val += T( 2 ); - val += T( 2 ); - EXPECT_EQ( v[ i ][ j ][ k ], val ); - } - } - } - ); -} - -template< typename T > -void testSizeOnDevice( arrayView3D< T > & v ) -{ - - forall( gpu(), 0, v.size( 0 ), - [=] __device__ ( INDEX_TYPE i ) - { - const INDEX_TYPE I = v.size( 0 ); - const INDEX_TYPE J = v.size( 1 ); - const INDEX_TYPE K = v.size( 2 ); - for( INDEX_TYPE j = 0; j < J; ++j ) - { - for( INDEX_TYPE k = 0; k < K; ++k ) - { - v( i, j, k ) = T( J * K * i + K * j + k ); - } - } - } - ); - - const INDEX_TYPE I = v.size( 0 ); - const INDEX_TYPE J = v.size( 1 ); - const INDEX_TYPE K = v.size( 2 ); - - forall( sequential(), 0, I, - [=] ( INDEX_TYPE i ) - { - for( INDEX_TYPE j = 0; j < J; ++j ) - { - for( INDEX_TYPE k = 0; k < K; ++k ) - { - T val( J * K * i + K * j + k ); - EXPECT_EQ( v[ i ][ j ][ k ], val ); - } - } - } - ); -} - - -#endif - - -TEST( ArrayView, test_upcast ) -{ - constexpr INDEX_TYPE N = 10; - - array< INDEX_TYPE > arr( N ); - - for( INDEX_TYPE a=0; a & arrView = arr; - arrayView< INDEX_TYPE const > & arrViewConst = arr; - - for( INDEX_TYPE a=0; a arrSlice1 = arrView; - arraySlice< INDEX_TYPE const > & arrSlice4 = arrView; - - for( INDEX_TYPE a=0; a arrSlice1 = arr; - arraySlice< INDEX_TYPE const > & arrSlice4 = arr; - - for( INDEX_TYPE a=0; a(); - testArrayPermutation< RAJA::PERM_JI >(); -} - -TEST( ArrayView, Permutations3D ) -{ - testArrayPermutation< RAJA::PERM_IJK >(); - testArrayPermutation< RAJA::PERM_JIK >(); - testArrayPermutation< RAJA::PERM_IKJ >(); - testArrayPermutation< RAJA::PERM_KIJ >(); - testArrayPermutation< RAJA::PERM_JKI >(); - testArrayPermutation< RAJA::PERM_KJI >(); -} - -TEST( ArrayView, Permutations4D ) -{ - testArrayPermutation< RAJA::PERM_IJKL >(); - testArrayPermutation< RAJA::PERM_JIKL >(); - testArrayPermutation< RAJA::PERM_IKJL >(); - testArrayPermutation< RAJA::PERM_KIJL >(); - testArrayPermutation< RAJA::PERM_JKIL >(); - testArrayPermutation< RAJA::PERM_KJIL >(); - testArrayPermutation< RAJA::PERM_IJLK >(); - testArrayPermutation< RAJA::PERM_JILK >(); - testArrayPermutation< RAJA::PERM_ILJK >(); - testArrayPermutation< RAJA::PERM_LIJK >(); - testArrayPermutation< RAJA::PERM_JLIK >(); - testArrayPermutation< RAJA::PERM_LJIK >(); - testArrayPermutation< RAJA::PERM_IKLJ >(); - testArrayPermutation< RAJA::PERM_KILJ >(); - testArrayPermutation< RAJA::PERM_ILKJ >(); - testArrayPermutation< RAJA::PERM_LIKJ >(); - testArrayPermutation< RAJA::PERM_KLIJ >(); - testArrayPermutation< RAJA::PERM_LKIJ >(); - testArrayPermutation< RAJA::PERM_JKLI >(); - testArrayPermutation< RAJA::PERM_KJLI >(); - testArrayPermutation< RAJA::PERM_JLKI >(); - testArrayPermutation< RAJA::PERM_LJKI >(); - testArrayPermutation< RAJA::PERM_KLJI >(); - testArrayPermutation< RAJA::PERM_LKJI >(); -} - -#ifdef USE_CUDA - -CUDA_TEST( ArrayView, memoryMotion ) -{ - constexpr INDEX_TYPE N = 10; - - { - array< INDEX_TYPE > a( N ); - testMemoryMotion( a ); - } - - { - array< Tensor > a( N ); - testMemoryMotion( a ); - } -} - -CUDA_TEST( ArrayView, memoryMotionConst ) -{ - constexpr INDEX_TYPE N = 100; - - { - array< INDEX_TYPE > a( N ); - testMemoryMotionConst( a ); - } - - { - array< Tensor > a( N ); - testMemoryMotionConst( a ); - } -} - -CUDA_TEST( ArrayView, memoryMotionMove ) -{ - constexpr INDEX_TYPE N = 100; - - { - array< INDEX_TYPE > a( N ); - testMemoryMotionMove( a ); - } - - { - array< Tensor > a( N ); - testMemoryMotionMove( a ); - } -} - -CUDA_TEST( ArrayView, memoryMotionMultiple ) -{ - constexpr INDEX_TYPE N = 100; - - { - array< INDEX_TYPE > a( N ); - testMemoryMotionMultiple( a ); - } - - { - array< Tensor > a( N ); - testMemoryMotionMultiple( a ); - } -} - -CUDA_TEST( ArrayView, memoryMotionMultipleMove ) -{ - constexpr INDEX_TYPE N = 100; - - { - array< INDEX_TYPE > a( N ); - testMemoryMotionMultipleMove( a ); - } - - { - array< Tensor > a( N ); - testMemoryMotionMultipleMove( a ); - } -} - -CUDA_TEST( ArrayView, memoryMotionArray ) -{ - constexpr INDEX_TYPE N = 10; - - { - array< array< INDEX_TYPE > > a( N ); - for( INDEX_TYPE i = 0; i < N; ++i ) - { - a[ i ].resize( N ); - } - - testMemoryMotionArray( a ); - } - - { - array< array< Tensor > > a( N ); - for( INDEX_TYPE i = 0; i < N; ++i ) - { - a[ i ].resize( N ); - } - - testMemoryMotionArray( a ); - } -} - -CUDA_TEST( ArrayView, memoryMotionEmpty ) -{ - array< INDEX_TYPE > a; - a.move( chai::GPU ); -} - -CUDA_TEST( ArrayView, memoryMotionArrayEmpty ) -{ - array< array< INDEX_TYPE > > a( 1 ); - a.move( chai::GPU ); -} - -CUDA_TEST( ArrayView, memoryMotionArrayConst ) -{ - constexpr INDEX_TYPE N = 10; - - { - array< array< INDEX_TYPE > > a( N ); - for( INDEX_TYPE i = 0; i < N; ++i ) - { - a[ i ].resize( N ); - } - - testMemoryMotionArrayConst( a ); - } - - { - array< array< Tensor > > a( N ); - for( INDEX_TYPE i = 0; i < N; ++i ) - { - a[ i ].resize( N ); - } - - testMemoryMotionArrayConst( a ); - } -} - -CUDA_TEST( ArrayView, memoryMotionArrayMove ) -{ - constexpr INDEX_TYPE N = 10; - - { - array< array< INDEX_TYPE > > a( N ); - for( INDEX_TYPE i = 0; i < N; ++i ) - { - a[ i ].resize( N ); - } - - testMemoryMotionArrayMove( a ); - } - - { - array< array< Tensor > > a( N ); - for( INDEX_TYPE i = 0; i < N; ++i ) - { - a[ i ].resize( N ); - } - - testMemoryMotionArrayMove( a ); - } -} - -CUDA_TEST( ArrayView, memoryMotionArray2 ) -{ - constexpr INDEX_TYPE N = 5; - - { - array< array< array< INDEX_TYPE > > > a( N ); - for( INDEX_TYPE i = 0; i < N; ++i ) - { - a[ i ].resize( N ); - for( INDEX_TYPE j = 0; j < N; ++j ) - { - a[ i ][ j ].resize( N ); - } - } - - testMemoryMotionArray2( a ); - } - - { - array< array< array< Tensor > > > a( N ); - for( INDEX_TYPE i = 0; i < N; ++i ) - { - a[ i ].resize( N ); - for( INDEX_TYPE j = 0; j < N; ++j ) - { - a[ i ][ j ].resize( N ); - } - } - - testMemoryMotionArray2( a ); - } -} - -CUDA_TEST( ArrayView, memoryMotionArray2Const ) -{ - constexpr INDEX_TYPE N = 5; - - { - array< array< array< INDEX_TYPE > > > a( N ); - for( INDEX_TYPE i = 0; i < N; ++i ) - { - a[ i ].resize( N ); - for( INDEX_TYPE j = 0; j < N; ++j ) - { - a[ i ][ j ].resize( N ); - } - } - - testMemoryMotionArray2Const( a ); - } - - { - array< array< array< Tensor > > > a( N ); - for( INDEX_TYPE i = 0; i < N; ++i ) - { - a[ i ].resize( N ); - for( INDEX_TYPE j = 0; j < N; ++j ) - { - a[ i ][ j ].resize( N ); - } - } - - testMemoryMotionArray2Const( a ); - } -} - -CUDA_TEST( ArrayView, memoryMotionArrayMove2 ) -{ - constexpr INDEX_TYPE N = 5; - - { - array< array< array< INDEX_TYPE > > > a( N ); - for( INDEX_TYPE i = 0; i < N; ++i ) - { - a[ i ].resize( N ); - for( INDEX_TYPE j = 0; j < N; ++j ) - { - a[ i ][ j ].resize( N ); - } - } - - testMemoryMotionArrayMove2( a ); - } - - { - array< array< array< Tensor > > > a( N ); - for( INDEX_TYPE i = 0; i < N; ++i ) - { - a[ i ].resize( N ); - for( INDEX_TYPE j = 0; j < N; ++j ) - { - a[ i ][ j ].resize( N ); - } - } - - testMemoryMotionArrayMove2( a ); - } -} - -CUDA_TEST( ArrayView, 2DAccessorsDevice ) -{ - constexpr INDEX_TYPE N = 20; - constexpr INDEX_TYPE M = 10; - - { - array2D< INDEX_TYPE > a( N, M ); - test2DAccessorsDevice( a ); - } - - { - array2D< Tensor > a( N, M ); - test2DAccessorsDevice( a ); - } -} - - -CUDA_TEST( ArrayView, 3DAccessorsDevice ) -{ - constexpr INDEX_TYPE N = 7; - constexpr INDEX_TYPE M = 8; - constexpr INDEX_TYPE P = 9; - - { - array3D< INDEX_TYPE > a( N, M, P ); - test3DAccessorsDevice( a ); - } - - { - array3D< Tensor > a( N, M, P ); - test3DAccessorsDevice( a ); - } -} - -CUDA_TEST( ArrayView, sizeOnDevice ) -{ - constexpr INDEX_TYPE N = 7; - constexpr INDEX_TYPE M = 8; - constexpr INDEX_TYPE P = 9; - - { - array3D< INDEX_TYPE > a( N, M, P ); - testSizeOnDevice( a ); - } - - { - array3D< Tensor > a( N, M, P ); - testSizeOnDevice( a ); - } -} - - -#endif - -} // namespace testing -} // namespace LvArray - -// This is the default gtest main method. It is included for ease of debugging. -int main( int argc, char * * argv ) -{ - ::testing::InitGoogleTest( &argc, argv ); - int const result = RUN_ALL_TESTS(); - return result; -} diff --git a/unitTests/testArrayView.hpp b/unitTests/testArrayView.hpp new file mode 100644 index 00000000..08426ce3 --- /dev/null +++ b/unitTests/testArrayView.hpp @@ -0,0 +1,513 @@ +/* + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Copyright (c) 2018, Lawrence Livermore National Security, LLC. + * + * Produced at the Lawrence Livermore National Laboratory + * + * LLNL-CODE-746361 + * + * All rights reserved. See COPYRIGHT for details. + * + * This file is part of the GEOSX Simulation Framework. + * + * GEOSX is a free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License (as published by the + * Free Software Foundation) version 2.1 dated February 1999. + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +// Source includes +#include "testArray.hpp" + +namespace LvArray +{ +namespace testing +{ + +template< typename ARRAY > +class ArrayViewTest : public ArrayTest< ARRAY > +{ +public: + + using T = typename ARRAY::value_type; + static constexpr int NDIM = ARRAY::ndim; + + using ViewType = std::remove_const_t< typename ARRAY::ViewType >; + using ViewTypeConst = std::remove_const_t< typename ARRAY::ViewTypeConst >; + + using SliceType = std::remove_const_t< typename ARRAY::SliceType >; + using SliceTypeConst = std::remove_const_t< typename ARRAY::SliceTypeConst >; + + using ParentClass = ArrayTest< ARRAY >; + + static void defaultConstructor() + { + { + ViewType view; + EXPECT_TRUE( view.empty() ); + + for( int i = 0; i < NDIM; ++i ) + { + EXPECT_EQ( view.size( i ), 0 ); + } + + EXPECT_EQ( view.size(), 0 ); + EXPECT_EQ( view.data(), nullptr ); + } + + { + ViewTypeConst view; + EXPECT_TRUE( view.empty() ); + + for( int i = 0; i < NDIM; ++i ) + { + EXPECT_EQ( view.size( i ), 0 ); + } + + EXPECT_EQ( view.size(), 0 ); + EXPECT_EQ( view.data(), nullptr ); + } + } + + static void copyConstructor() + { + std::unique_ptr< ARRAY > array = ParentClass::sizedConstructor(); + + { + ViewType const view = array->toView(); + ParentClass::compare( view, *array, true ); + } + + { + ViewTypeConst const constView = array->toViewConst(); + ParentClass::compare( constView, *array, true ); + } + } + + static void copyAssignmentOperator() + { + std::unique_ptr< ARRAY > array = ParentClass::sizedConstructor(); + + { + ViewType view; + view = array->toView(); + ParentClass::compare( view, *array, true ); + } + + { + ViewTypeConst constView; + constView = array->toViewConst(); + ParentClass::compare( constView, *array, true ); + } + } + + static void toView() + { + std::unique_ptr< ARRAY > array = ParentClass::sizedConstructor(); + + { + ViewType const view = array->toView(); + EXPECT_EQ( &view, &view.toView() ); + ParentClass::compare( view.toView(), *array, true ); + } + + { + ViewTypeConst const constView = array->toViewConst(); + EXPECT_EQ( &constView, &constView.toView() ); + ParentClass::compare( constView.toView(), *array, true ); + } + } + + static void toViewConst() + { + std::unique_ptr< ARRAY > array = ParentClass::sizedConstructor(); + + { + ViewType const view = array->toView(); + EXPECT_EQ( static_cast< void const * >( &view ), static_cast< void const * >( &view.toViewConst() ) ); + ParentClass::compare( view.toViewConst(), *array, true ); + } + + { + ViewTypeConst const constView = array->toViewConst(); + EXPECT_EQ( &constView, &constView.toViewConst() ); + ParentClass::compare( constView.toViewConst(), *array, true ); + } + } + + static void udcToViewConst() + { + std::unique_ptr< ARRAY > array = ParentClass::sizedConstructor(); + + { + ViewType const view = array->toView(); + ViewTypeConst const & view2 = view; + EXPECT_EQ( static_cast< void const * >( &view2 ), static_cast< void const * >( &view ) ); + ParentClass::compare( view2, *array, true ); + } + + { + ViewTypeConst const constView = array->toViewConst(); + ViewTypeConst const & view2 = constView; + EXPECT_EQ( &view2, &constView ); + ParentClass::compare( view2, *array, true ); + } + } + + static void toSlice() + { + std::unique_ptr< ARRAY > array = ParentClass::sizedConstructor(); + + { + ViewType const view = array->toView(); + SliceType const slice = view.toSlice(); + ParentClass::compare( slice, *array, true ); + } + + { + ViewTypeConst const constView = array->toViewConst(); + SliceTypeConst const constSlice = constView.toSlice(); + ParentClass::compare( constSlice, *array, true ); + } + } + + static void udcToSlice() + { + std::unique_ptr< ARRAY > array = ParentClass::sizedConstructor(); + + { + ViewType const view = array->toView(); + SliceType const slice = view; + ParentClass::compare( slice, *array, true ); + } + + { + ViewTypeConst const constView = array->toViewConst(); + SliceTypeConst const constSlice = constView; + ParentClass::compare( constSlice, *array, true ); + } + } + + static void toSliceConst() + { + std::unique_ptr< ARRAY > array = ParentClass::sizedConstructor(); + + { + ViewType const view = array->toView(); + SliceTypeConst const slice = view.toSliceConst(); + ParentClass::compare( slice, *array, true ); + } + + { + ViewTypeConst const constView = array->toViewConst(); + SliceTypeConst const constSlice = constView.toSliceConst(); + ParentClass::compare( constSlice, *array, true ); + } + } + + static void udcToSliceConst() + { + std::unique_ptr< ARRAY > array = ParentClass::sizedConstructor(); + + { + ViewType const view = array->toView(); + SliceTypeConst const slice = view; + ParentClass::compare( slice, *array, true ); + } + + { + ViewTypeConst const constView = array->toViewConst(); + SliceTypeConst const constSlice = constView; + ParentClass::compare( constSlice, *array, true ); + } + } +}; + +using ArrayViewTestTypes = ArrayTestTypes; +TYPED_TEST_SUITE( ArrayViewTest, ArrayViewTestTypes, ); + + +template< typename ARRAY_POLICY_PAIR > +class ArrayViewPolicyTest : public ArrayViewTest< typename ARRAY_POLICY_PAIR::first_type > +{ +public: + using ARRAY = typename ARRAY_POLICY_PAIR::first_type; + using POLICY = typename ARRAY_POLICY_PAIR::second_type; + + using T = typename ARRAY::value_type; + static constexpr int NDIM = ARRAY::ndim; + + using ParentClass = ArrayViewTest< ARRAY >; + + using typename ParentClass::ViewType; + using typename ParentClass::ViewTypeConst; + using typename ParentClass::SliceType; + using typename ParentClass::SliceTypeConst; + + static void modifyInKernel() + { + std::unique_ptr< ARRAY > array = ParentClass::sizedConstructor(); + ViewType const & view = array->toView(); + forall< POLICY >( array->size(), [view] LVARRAY_HOST_DEVICE ( INDEX_TYPE const i ) + { + view.data()[ i ] += view.data()[ i ]; + } ); + + forall< serialPolicy >( array->size( 0 ), [view] ( INDEX_TYPE const i ) + { + forValuesInSliceWithIndices( view[ i ], [i] ( T const & value, auto const ... indices ) + { + T expectedValue = T( ParentClass::getTestingLinearIndex( i, indices ... ) ); + expectedValue += expectedValue; + EXPECT_EQ( value, expectedValue ); + } ); + } ); + } + + static void readInKernel() + { + std::unique_ptr< ARRAY > array = ParentClass::sizedConstructor(); + ViewTypeConst const & view = array->toViewConst(); + forall< POLICY >( array->size( 0 ), [view] LVARRAY_HOST_DEVICE ( INDEX_TYPE const i ) + { + checkFillDevice( view, i ); + } ); + + // Set the data outside of a kernel. + for( INDEX_TYPE i = 0; i < array->size(); ++i ) + { array->data()[ i ] += array->data()[ i ]; } + + forall< serialPolicy >( array->size( 0 ), [view] ( INDEX_TYPE const i ) + { + forValuesInSliceWithIndices( view[ i ], [i] ( T const & value, auto const ... indices ) + { + T expectedValue = T( ParentClass::getTestingLinearIndex( i, indices ... ) ); + expectedValue += expectedValue; + EXPECT_EQ( value, expectedValue ); + } ); + } ); + } + + static void move() + { + std::unique_ptr< ARRAY > array = ParentClass::sizedConstructor(); + array->move( RAJAHelper< POLICY >::space ); + T * const dataPointer = array->data(); + forall< POLICY >( array->size(), [dataPointer] LVARRAY_HOST_DEVICE ( INDEX_TYPE const i ) + { + dataPointer[ i ] += dataPointer[ i ]; + } ); + + array->move( MemorySpace::CPU, false ); + + forValuesInSliceWithIndices( array->toSliceConst(), [] ( T const & value, auto const ... indices ) + { + T expectedValue = T( ParentClass::getTestingLinearIndex( indices ... ) ); + expectedValue += expectedValue; + EXPECT_EQ( value, expectedValue ); + } ); + } + + static void moveNoTouch() + { + std::unique_ptr< ARRAY > array = ParentClass::sizedConstructor(); + T * const hostPointer = array->data(); + array->move( RAJAHelper< POLICY >::space, false ); + T const * const devicePointer = array->data(); + + INDEX_TYPE sizes[ NDIM ]; + INDEX_TYPE strides[ NDIM ]; + for( int dim = 0; dim < NDIM; ++dim ) + { + sizes[ dim ] = array->size( dim ); + strides[ dim ] = array->strides()[ dim ]; + } + + forall< POLICY >( array->size( 0 ), [devicePointer, sizes, strides] LVARRAY_HOST_DEVICE ( INDEX_TYPE const i ) + { + SliceTypeConst slice( devicePointer, sizes, strides ); + checkFillDevice( slice, i ); + } ); + + // Set the data outside of a kernel. + for( INDEX_TYPE i = 0; i < array->size(); ++i ) + { hostPointer[ i ] += hostPointer[ i ]; } + + array->move( MemorySpace::CPU, false ); + EXPECT_EQ( array->data(), hostPointer ); + forValuesInSliceWithIndices( array->toSliceConst(), [] ( T const & value, auto const ... indices ) + { + T expectedValue = T( ParentClass::getTestingLinearIndex( indices ... ) ); + expectedValue += expectedValue; + EXPECT_EQ( value, expectedValue ); + } ); + } + + static void modifyInMultipleKernels() + { + std::unique_ptr< ARRAY > array = ParentClass::sizedConstructor(); + + ViewType const & view = array->toView(); + forall< POLICY >( array->size(), [view] LVARRAY_HOST_DEVICE ( INDEX_TYPE const i ) + { + view.data()[ i ] += view.data()[ i ]; + } ); + + forall< POLICY >( array->size(), [view] LVARRAY_HOST_DEVICE ( INDEX_TYPE const i ) + { + view.data()[ i ] += view.data()[ i ]; + } ); + + forall< serialPolicy >( array->size(), [view] LVARRAY_HOST_DEVICE ( INDEX_TYPE const i ) + { + view.data()[ i ] += view.data()[ i ]; + } ); + + forall< POLICY >( array->size(), [view] LVARRAY_HOST_DEVICE ( INDEX_TYPE const i ) + { + view.data()[ i ] += view.data()[ i ]; + } ); + + forall< serialPolicy >( array->size( 0 ), [view] ( INDEX_TYPE const i ) + { + forValuesInSliceWithIndices( view[ i ], [i] ( T const & value, auto const ... indices ) + { + T expectedValue = T( ParentClass::getTestingLinearIndex( i, indices ... ) ); + expectedValue += expectedValue; + expectedValue += expectedValue; + expectedValue += expectedValue; + expectedValue += expectedValue; + EXPECT_EQ( value, expectedValue ); + } ); + } ); + } + + static void moveMultipleTimes() + { + std::unique_ptr< ARRAY > array = ParentClass::sizedConstructor(); + + array->move( RAJAHelper< POLICY >::space ); + T * dataPointer = array->data(); + forall< POLICY >( array->size(), [dataPointer] LVARRAY_HOST_DEVICE ( INDEX_TYPE const i ) + { + dataPointer[ i ] += dataPointer[ i ]; + } ); + + forall< POLICY >( array->size(), [dataPointer] LVARRAY_HOST_DEVICE ( INDEX_TYPE const i ) + { + dataPointer[ i ] += dataPointer[ i ]; + } ); + + array->move( MemorySpace::CPU ); + dataPointer = array->data(); + forall< serialPolicy >( array->size(), [dataPointer] LVARRAY_HOST_DEVICE ( INDEX_TYPE const i ) + { + dataPointer[ i ] += dataPointer[ i ]; + } ); + + array->move( RAJAHelper< POLICY >::space ); + dataPointer = array->data(); + forall< POLICY >( array->size(), [dataPointer] LVARRAY_HOST_DEVICE ( INDEX_TYPE const i ) + { + dataPointer[ i ] += dataPointer[ i ]; + } ); + + array->move( MemorySpace::CPU, false ); + + forValuesInSliceWithIndices( array->toSliceConst(), [] ( T const & value, auto const ... indices ) + { + T expectedValue = T( ParentClass::getTestingLinearIndex( indices ... ) ); + expectedValue += expectedValue; + expectedValue += expectedValue; + expectedValue += expectedValue; + expectedValue += expectedValue; + EXPECT_EQ( value, expectedValue ); + } ); + } + + static void emptyMove() + { + ARRAY array; + array.move( RAJAHelper< POLICY >::space ); + array.move( MemorySpace::CPU ); + } + +protected: + + template< typename ARRAY > + class CheckIndices + { +public: + LVARRAY_HOST_DEVICE CheckIndices( ARRAY const slice, INDEX_TYPE const i ): + m_slice( slice ), + m_i( i ) + {} + + template< typename ... INDICES > + LVARRAY_HOST_DEVICE void operator()( T const & value, INDICES const ... indices ) + { + PORTABLE_EXPECT_EQ( value, T( ParentClass::getTestingLinearIndex( m_i, indices ... ) ) ); + PORTABLE_EXPECT_EQ( &value, &m_slice( m_i, indices ... ) ); + } + +private: + ARRAY const m_slice; + INDEX_TYPE const m_i; + }; + + static LVARRAY_HOST_DEVICE void checkFillDevice( ViewTypeConst const & view, + INDEX_TYPE const i ) + { forValuesInSliceWithIndices( view[ i ], CheckIndices< ViewTypeConst >( view, i ) ); } + + template< int DIM, int USD > + static LVARRAY_HOST_DEVICE void checkFillDevice( ArraySlice< T const, DIM, USD, INDEX_TYPE > const slice, + INDEX_TYPE const i ) + { forValuesInSliceWithIndices( slice[ i ], CheckIndices< ArraySlice< T const, DIM, USD, INDEX_TYPE > >( slice, i ) ); } +}; + +using ArrayViewPolicyTestTypes = ::testing::Types< + std::pair< Array< int, 1, RAJA::PERM_I, INDEX_TYPE, DEFAULT_BUFFER >, serialPolicy > + , std::pair< Array< int, 2, RAJA::PERM_IJ, INDEX_TYPE, DEFAULT_BUFFER >, serialPolicy > + , std::pair< Array< int, 2, RAJA::PERM_JI, INDEX_TYPE, DEFAULT_BUFFER >, serialPolicy > + , std::pair< Array< int, 3, RAJA::PERM_IJK, INDEX_TYPE, DEFAULT_BUFFER >, serialPolicy > + , std::pair< Array< int, 3, RAJA::PERM_IKJ, INDEX_TYPE, DEFAULT_BUFFER >, serialPolicy > + , std::pair< Array< int, 3, RAJA::PERM_JIK, INDEX_TYPE, DEFAULT_BUFFER >, serialPolicy > + , std::pair< Array< int, 3, RAJA::PERM_JKI, INDEX_TYPE, DEFAULT_BUFFER >, serialPolicy > + , std::pair< Array< int, 3, RAJA::PERM_KIJ, INDEX_TYPE, DEFAULT_BUFFER >, serialPolicy > + , std::pair< Array< int, 3, RAJA::PERM_KJI, INDEX_TYPE, DEFAULT_BUFFER >, serialPolicy > + , std::pair< Array< int, 4, RAJA::PERM_IJKL, INDEX_TYPE, DEFAULT_BUFFER >, serialPolicy > + , std::pair< Array< int, 4, RAJA::PERM_LKJI, INDEX_TYPE, DEFAULT_BUFFER >, serialPolicy > + , std::pair< Array< Tensor, 1, RAJA::PERM_I, INDEX_TYPE, DEFAULT_BUFFER >, serialPolicy > + , std::pair< Array< Tensor, 2, RAJA::PERM_IJ, INDEX_TYPE, DEFAULT_BUFFER >, serialPolicy > + , std::pair< Array< Tensor, 2, RAJA::PERM_JI, INDEX_TYPE, DEFAULT_BUFFER >, serialPolicy > + , std::pair< Array< Tensor, 3, RAJA::PERM_IJK, INDEX_TYPE, DEFAULT_BUFFER >, serialPolicy > + , std::pair< Array< Tensor, 3, RAJA::PERM_KJI, INDEX_TYPE, DEFAULT_BUFFER >, serialPolicy > + , std::pair< Array< Tensor, 4, RAJA::PERM_IJKL, INDEX_TYPE, DEFAULT_BUFFER >, serialPolicy > + , std::pair< Array< Tensor, 4, RAJA::PERM_LKJI, INDEX_TYPE, DEFAULT_BUFFER >, serialPolicy > + +#if defined(USE_CUDA) && defined(USE_CHAI) + , std::pair< Array< int, 1, RAJA::PERM_I, INDEX_TYPE, NewChaiBuffer >, parallelDevicePolicy< 32 > > + , std::pair< Array< int, 2, RAJA::PERM_IJ, INDEX_TYPE, NewChaiBuffer >, parallelDevicePolicy< 32 > > + , std::pair< Array< int, 2, RAJA::PERM_JI, INDEX_TYPE, NewChaiBuffer >, parallelDevicePolicy< 32 > > + , std::pair< Array< int, 3, RAJA::PERM_IJK, INDEX_TYPE, NewChaiBuffer >, parallelDevicePolicy< 32 > > + , std::pair< Array< int, 3, RAJA::PERM_IKJ, INDEX_TYPE, NewChaiBuffer >, parallelDevicePolicy< 32 > > + , std::pair< Array< int, 3, RAJA::PERM_JIK, INDEX_TYPE, NewChaiBuffer >, parallelDevicePolicy< 32 > > + , std::pair< Array< int, 3, RAJA::PERM_JKI, INDEX_TYPE, NewChaiBuffer >, parallelDevicePolicy< 32 > > + , std::pair< Array< int, 3, RAJA::PERM_KIJ, INDEX_TYPE, NewChaiBuffer >, parallelDevicePolicy< 32 > > + , std::pair< Array< int, 3, RAJA::PERM_KJI, INDEX_TYPE, NewChaiBuffer >, parallelDevicePolicy< 32 > > + , std::pair< Array< int, 4, RAJA::PERM_IJKL, INDEX_TYPE, NewChaiBuffer >, parallelDevicePolicy< 32 > > + , std::pair< Array< int, 4, RAJA::PERM_LKJI, INDEX_TYPE, NewChaiBuffer >, parallelDevicePolicy< 32 > > + , std::pair< Array< Tensor, 1, RAJA::PERM_I, INDEX_TYPE, NewChaiBuffer >, parallelDevicePolicy< 32 > > + , std::pair< Array< Tensor, 2, RAJA::PERM_IJ, INDEX_TYPE, NewChaiBuffer >, parallelDevicePolicy< 32 > > + , std::pair< Array< Tensor, 2, RAJA::PERM_JI, INDEX_TYPE, NewChaiBuffer >, parallelDevicePolicy< 32 > > + , std::pair< Array< Tensor, 3, RAJA::PERM_IJK, INDEX_TYPE, NewChaiBuffer >, parallelDevicePolicy< 32 > > + , std::pair< Array< Tensor, 3, RAJA::PERM_KJI, INDEX_TYPE, NewChaiBuffer >, parallelDevicePolicy< 32 > > + , std::pair< Array< Tensor, 4, RAJA::PERM_IJKL, INDEX_TYPE, NewChaiBuffer >, parallelDevicePolicy< 32 > > + , std::pair< Array< Tensor, 4, RAJA::PERM_LKJI, INDEX_TYPE, NewChaiBuffer >, parallelDevicePolicy< 32 > > +#endif + >; + +TYPED_TEST_SUITE( ArrayViewPolicyTest, ArrayViewPolicyTestTypes, ); + +} // namespace testing +} // namespace LvArray diff --git a/unitTests/testArrayView_copyAssignmentOperator.cpp b/unitTests/testArrayView_copyAssignmentOperator.cpp new file mode 100644 index 00000000..0f430d1a --- /dev/null +++ b/unitTests/testArrayView_copyAssignmentOperator.cpp @@ -0,0 +1,41 @@ +/* + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Copyright (c) 2018, Lawrence Livermore National Security, LLC. + * + * Produced at the Lawrence Livermore National Laboratory + * + * LLNL-CODE-746361 + * + * All rights reserved. See COPYRIGHT for details. + * + * This file is part of the GEOSX Simulation Framework. + * + * GEOSX is a free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License (as published by the + * Free Software Foundation) version 2.1 dated February 1999. + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +// Source includes +#include "testArrayView.hpp" + +namespace LvArray +{ +namespace testing +{ + +TYPED_TEST( ArrayViewTest, copyAssignmentOperator ) +{ + this->copyAssignmentOperator(); +} + +} // namespace testing +} // namespace LvArray + +// This is the default gtest main method. It is included for ease of debugging. +int main( int argc, char * * argv ) +{ + ::testing::InitGoogleTest( &argc, argv ); + int const result = RUN_ALL_TESTS(); + return result; +} diff --git a/unitTests/testArrayView_copyConstructor.cpp b/unitTests/testArrayView_copyConstructor.cpp new file mode 100644 index 00000000..c8bc5c9f --- /dev/null +++ b/unitTests/testArrayView_copyConstructor.cpp @@ -0,0 +1,41 @@ +/* + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Copyright (c) 2018, Lawrence Livermore National Security, LLC. + * + * Produced at the Lawrence Livermore National Laboratory + * + * LLNL-CODE-746361 + * + * All rights reserved. See COPYRIGHT for details. + * + * This file is part of the GEOSX Simulation Framework. + * + * GEOSX is a free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License (as published by the + * Free Software Foundation) version 2.1 dated February 1999. + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +// Source includes +#include "testArrayView.hpp" + +namespace LvArray +{ +namespace testing +{ + +TYPED_TEST( ArrayViewTest, copyConstructor ) +{ + this->copyConstructor(); +} + +} // namespace testing +} // namespace LvArray + +// This is the default gtest main method. It is included for ease of debugging. +int main( int argc, char * * argv ) +{ + ::testing::InitGoogleTest( &argc, argv ); + int const result = RUN_ALL_TESTS(); + return result; +} diff --git a/unitTests/testArrayView_defaultConstructor.cpp b/unitTests/testArrayView_defaultConstructor.cpp new file mode 100644 index 00000000..30675b62 --- /dev/null +++ b/unitTests/testArrayView_defaultConstructor.cpp @@ -0,0 +1,41 @@ +/* + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Copyright (c) 2018, Lawrence Livermore National Security, LLC. + * + * Produced at the Lawrence Livermore National Laboratory + * + * LLNL-CODE-746361 + * + * All rights reserved. See COPYRIGHT for details. + * + * This file is part of the GEOSX Simulation Framework. + * + * GEOSX is a free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License (as published by the + * Free Software Foundation) version 2.1 dated February 1999. + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +// Source includes +#include "testArrayView.hpp" + +namespace LvArray +{ +namespace testing +{ + +TYPED_TEST( ArrayViewTest, defaultConstructor ) +{ + this->defaultConstructor(); +} + +} // namespace testing +} // namespace LvArray + +// This is the default gtest main method. It is included for ease of debugging. +int main( int argc, char * * argv ) +{ + ::testing::InitGoogleTest( &argc, argv ); + int const result = RUN_ALL_TESTS(); + return result; +} diff --git a/unitTests/testArrayView_emptyMove.cpp b/unitTests/testArrayView_emptyMove.cpp new file mode 100644 index 00000000..9cc8cc2b --- /dev/null +++ b/unitTests/testArrayView_emptyMove.cpp @@ -0,0 +1,41 @@ +/* + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Copyright (c) 2018, Lawrence Livermore National Security, LLC. + * + * Produced at the Lawrence Livermore National Laboratory + * + * LLNL-CODE-746361 + * + * All rights reserved. See COPYRIGHT for details. + * + * This file is part of the GEOSX Simulation Framework. + * + * GEOSX is a free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License (as published by the + * Free Software Foundation) version 2.1 dated February 1999. + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +// Source includes +#include "testArrayView.hpp" + +namespace LvArray +{ +namespace testing +{ + +TYPED_TEST( ArrayViewPolicyTest, emptyMove ) +{ + this->emptyMove(); +} + +} // namespace testing +} // namespace LvArray + +// This is the default gtest main method. It is included for ease of debugging. +int main( int argc, char * * argv ) +{ + ::testing::InitGoogleTest( &argc, argv ); + int const result = RUN_ALL_TESTS(); + return result; +} diff --git a/unitTests/testArrayView_modifyInKernel.cpp b/unitTests/testArrayView_modifyInKernel.cpp new file mode 100644 index 00000000..0d547238 --- /dev/null +++ b/unitTests/testArrayView_modifyInKernel.cpp @@ -0,0 +1,41 @@ +/* + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Copyright (c) 2018, Lawrence Livermore National Security, LLC. + * + * Produced at the Lawrence Livermore National Laboratory + * + * LLNL-CODE-746361 + * + * All rights reserved. See COPYRIGHT for details. + * + * This file is part of the GEOSX Simulation Framework. + * + * GEOSX is a free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License (as published by the + * Free Software Foundation) version 2.1 dated February 1999. + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +// Source includes +#include "testArrayView.hpp" + +namespace LvArray +{ +namespace testing +{ + +TYPED_TEST( ArrayViewPolicyTest, modifyInKernel ) +{ + this->modifyInKernel(); +} + +} // namespace testing +} // namespace LvArray + +// This is the default gtest main method. It is included for ease of debugging. +int main( int argc, char * * argv ) +{ + ::testing::InitGoogleTest( &argc, argv ); + int const result = RUN_ALL_TESTS(); + return result; +} diff --git a/unitTests/testArrayView_modifyInMultipleKernels.cpp b/unitTests/testArrayView_modifyInMultipleKernels.cpp new file mode 100644 index 00000000..782ffcd0 --- /dev/null +++ b/unitTests/testArrayView_modifyInMultipleKernels.cpp @@ -0,0 +1,41 @@ +/* + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Copyright (c) 2018, Lawrence Livermore National Security, LLC. + * + * Produced at the Lawrence Livermore National Laboratory + * + * LLNL-CODE-746361 + * + * All rights reserved. See COPYRIGHT for details. + * + * This file is part of the GEOSX Simulation Framework. + * + * GEOSX is a free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License (as published by the + * Free Software Foundation) version 2.1 dated February 1999. + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +// Source includes +#include "testArrayView.hpp" + +namespace LvArray +{ +namespace testing +{ + +TYPED_TEST( ArrayViewPolicyTest, modifyInMultipleKernels ) +{ + this->modifyInMultipleKernels(); +} + +} // namespace testing +} // namespace LvArray + +// This is the default gtest main method. It is included for ease of debugging. +int main( int argc, char * * argv ) +{ + ::testing::InitGoogleTest( &argc, argv ); + int const result = RUN_ALL_TESTS(); + return result; +} diff --git a/unitTests/testArrayView_move.cpp b/unitTests/testArrayView_move.cpp new file mode 100644 index 00000000..4fdd27e9 --- /dev/null +++ b/unitTests/testArrayView_move.cpp @@ -0,0 +1,41 @@ +/* + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Copyright (c) 2018, Lawrence Livermore National Security, LLC. + * + * Produced at the Lawrence Livermore National Laboratory + * + * LLNL-CODE-746361 + * + * All rights reserved. See COPYRIGHT for details. + * + * This file is part of the GEOSX Simulation Framework. + * + * GEOSX is a free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License (as published by the + * Free Software Foundation) version 2.1 dated February 1999. + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +// Source includes +#include "testArrayView.hpp" + +namespace LvArray +{ +namespace testing +{ + +TYPED_TEST( ArrayViewPolicyTest, move ) +{ + this->move(); +} + +} // namespace testing +} // namespace LvArray + +// This is the default gtest main method. It is included for ease of debugging. +int main( int argc, char * * argv ) +{ + ::testing::InitGoogleTest( &argc, argv ); + int const result = RUN_ALL_TESTS(); + return result; +} diff --git a/unitTests/testArrayView_moveMultipleTimes.cpp b/unitTests/testArrayView_moveMultipleTimes.cpp new file mode 100644 index 00000000..0f58331f --- /dev/null +++ b/unitTests/testArrayView_moveMultipleTimes.cpp @@ -0,0 +1,41 @@ +/* + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Copyright (c) 2018, Lawrence Livermore National Security, LLC. + * + * Produced at the Lawrence Livermore National Laboratory + * + * LLNL-CODE-746361 + * + * All rights reserved. See COPYRIGHT for details. + * + * This file is part of the GEOSX Simulation Framework. + * + * GEOSX is a free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License (as published by the + * Free Software Foundation) version 2.1 dated February 1999. + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +// Source includes +#include "testArrayView.hpp" + +namespace LvArray +{ +namespace testing +{ + +TYPED_TEST( ArrayViewPolicyTest, moveMultipleTimes ) +{ + this->moveMultipleTimes(); +} + +} // namespace testing +} // namespace LvArray + +// This is the default gtest main method. It is included for ease of debugging. +int main( int argc, char * * argv ) +{ + ::testing::InitGoogleTest( &argc, argv ); + int const result = RUN_ALL_TESTS(); + return result; +} diff --git a/unitTests/testArrayView_moveNoTouch.cpp b/unitTests/testArrayView_moveNoTouch.cpp new file mode 100644 index 00000000..2bc5478d --- /dev/null +++ b/unitTests/testArrayView_moveNoTouch.cpp @@ -0,0 +1,41 @@ +/* + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Copyright (c) 2018, Lawrence Livermore National Security, LLC. + * + * Produced at the Lawrence Livermore National Laboratory + * + * LLNL-CODE-746361 + * + * All rights reserved. See COPYRIGHT for details. + * + * This file is part of the GEOSX Simulation Framework. + * + * GEOSX is a free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License (as published by the + * Free Software Foundation) version 2.1 dated February 1999. + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +// Source includes +#include "testArrayView.hpp" + +namespace LvArray +{ +namespace testing +{ + +TYPED_TEST( ArrayViewPolicyTest, moveNoTouch ) +{ + this->moveNoTouch(); +} + +} // namespace testing +} // namespace LvArray + +// This is the default gtest main method. It is included for ease of debugging. +int main( int argc, char * * argv ) +{ + ::testing::InitGoogleTest( &argc, argv ); + int const result = RUN_ALL_TESTS(); + return result; +} diff --git a/unitTests/testArrayView_readInKernel.cpp b/unitTests/testArrayView_readInKernel.cpp new file mode 100644 index 00000000..a2dd853b --- /dev/null +++ b/unitTests/testArrayView_readInKernel.cpp @@ -0,0 +1,40 @@ +/* + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Copyright (c) 2018, Lawrence Livermore National Security, LLC. + * + * Produced at the Lawrence Livermore National Laboratory + * + * LLNL-CODE-746361 + * + * All rights reserved. See COPYRIGHT for details. + * + * This file is part of the GEOSX Simulation Framework. + * + * GEOSX is a free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License (as published by the + * Free Software Foundation) version 2.1 dated February 1999. + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +// Source includes +#include "testArrayView.hpp" + +namespace LvArray +{ +namespace testing +{ + +TYPED_TEST( ArrayViewPolicyTest, readInKernel ) +{ + this->readInKernel(); +} +} // namespace testing +} // namespace LvArray + +// This is the default gtest main method. It is included for ease of debugging. +int main( int argc, char * * argv ) +{ + ::testing::InitGoogleTest( &argc, argv ); + int const result = RUN_ALL_TESTS(); + return result; +} diff --git a/unitTests/testArrayView_toSlice.cpp b/unitTests/testArrayView_toSlice.cpp new file mode 100644 index 00000000..7fde96c2 --- /dev/null +++ b/unitTests/testArrayView_toSlice.cpp @@ -0,0 +1,41 @@ +/* + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Copyright (c) 2018, Lawrence Livermore National Security, LLC. + * + * Produced at the Lawrence Livermore National Laboratory + * + * LLNL-CODE-746361 + * + * All rights reserved. See COPYRIGHT for details. + * + * This file is part of the GEOSX Simulation Framework. + * + * GEOSX is a free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License (as published by the + * Free Software Foundation) version 2.1 dated February 1999. + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +// Source includes +#include "testArrayView.hpp" + +namespace LvArray +{ +namespace testing +{ + +TYPED_TEST( ArrayViewTest, toSlice ) +{ + this->toSlice(); +} + +} // namespace testing +} // namespace LvArray + +// This is the default gtest main method. It is included for ease of debugging. +int main( int argc, char * * argv ) +{ + ::testing::InitGoogleTest( &argc, argv ); + int const result = RUN_ALL_TESTS(); + return result; +} diff --git a/unitTests/testArrayView_toSliceConst.cpp b/unitTests/testArrayView_toSliceConst.cpp new file mode 100644 index 00000000..5f315df6 --- /dev/null +++ b/unitTests/testArrayView_toSliceConst.cpp @@ -0,0 +1,41 @@ +/* + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Copyright (c) 2018, Lawrence Livermore National Security, LLC. + * + * Produced at the Lawrence Livermore National Laboratory + * + * LLNL-CODE-746361 + * + * All rights reserved. See COPYRIGHT for details. + * + * This file is part of the GEOSX Simulation Framework. + * + * GEOSX is a free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License (as published by the + * Free Software Foundation) version 2.1 dated February 1999. + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +// Source includes +#include "testArrayView.hpp" + +namespace LvArray +{ +namespace testing +{ + +TYPED_TEST( ArrayViewTest, toSliceConst ) +{ + this->toSliceConst(); +} + +} // namespace testing +} // namespace LvArray + +// This is the default gtest main method. It is included for ease of debugging. +int main( int argc, char * * argv ) +{ + ::testing::InitGoogleTest( &argc, argv ); + int const result = RUN_ALL_TESTS(); + return result; +} diff --git a/unitTests/testArrayView_toView.cpp b/unitTests/testArrayView_toView.cpp new file mode 100644 index 00000000..3d21259f --- /dev/null +++ b/unitTests/testArrayView_toView.cpp @@ -0,0 +1,41 @@ +/* + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Copyright (c) 2018, Lawrence Livermore National Security, LLC. + * + * Produced at the Lawrence Livermore National Laboratory + * + * LLNL-CODE-746361 + * + * All rights reserved. See COPYRIGHT for details. + * + * This file is part of the GEOSX Simulation Framework. + * + * GEOSX is a free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License (as published by the + * Free Software Foundation) version 2.1 dated February 1999. + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +// Source includes +#include "testArrayView.hpp" + +namespace LvArray +{ +namespace testing +{ + +TYPED_TEST( ArrayViewTest, toView ) +{ + this->toView(); +} + +} // namespace testing +} // namespace LvArray + +// This is the default gtest main method. It is included for ease of debugging. +int main( int argc, char * * argv ) +{ + ::testing::InitGoogleTest( &argc, argv ); + int const result = RUN_ALL_TESTS(); + return result; +} diff --git a/unitTests/testArrayView_toViewConst.cpp b/unitTests/testArrayView_toViewConst.cpp new file mode 100644 index 00000000..f4601762 --- /dev/null +++ b/unitTests/testArrayView_toViewConst.cpp @@ -0,0 +1,41 @@ +/* + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Copyright (c) 2018, Lawrence Livermore National Security, LLC. + * + * Produced at the Lawrence Livermore National Laboratory + * + * LLNL-CODE-746361 + * + * All rights reserved. See COPYRIGHT for details. + * + * This file is part of the GEOSX Simulation Framework. + * + * GEOSX is a free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License (as published by the + * Free Software Foundation) version 2.1 dated February 1999. + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +// Source includes +#include "testArrayView.hpp" + +namespace LvArray +{ +namespace testing +{ + +TYPED_TEST( ArrayViewTest, toViewConst ) +{ + this->toViewConst(); +} + +} // namespace testing +} // namespace LvArray + +// This is the default gtest main method. It is included for ease of debugging. +int main( int argc, char * * argv ) +{ + ::testing::InitGoogleTest( &argc, argv ); + int const result = RUN_ALL_TESTS(); + return result; +} diff --git a/unitTests/testArrayView_udcToSlice.cpp b/unitTests/testArrayView_udcToSlice.cpp new file mode 100644 index 00000000..d7da8632 --- /dev/null +++ b/unitTests/testArrayView_udcToSlice.cpp @@ -0,0 +1,41 @@ +/* + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Copyright (c) 2018, Lawrence Livermore National Security, LLC. + * + * Produced at the Lawrence Livermore National Laboratory + * + * LLNL-CODE-746361 + * + * All rights reserved. See COPYRIGHT for details. + * + * This file is part of the GEOSX Simulation Framework. + * + * GEOSX is a free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License (as published by the + * Free Software Foundation) version 2.1 dated February 1999. + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +// Source includes +#include "testArrayView.hpp" + +namespace LvArray +{ +namespace testing +{ + +TYPED_TEST( ArrayViewTest, udcToSlice ) +{ + this->udcToSlice(); +} + +} // namespace testing +} // namespace LvArray + +// This is the default gtest main method. It is included for ease of debugging. +int main( int argc, char * * argv ) +{ + ::testing::InitGoogleTest( &argc, argv ); + int const result = RUN_ALL_TESTS(); + return result; +} diff --git a/unitTests/testArrayView_udcToSliceConst.cpp b/unitTests/testArrayView_udcToSliceConst.cpp new file mode 100644 index 00000000..fdf2cb50 --- /dev/null +++ b/unitTests/testArrayView_udcToSliceConst.cpp @@ -0,0 +1,41 @@ +/* + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Copyright (c) 2018, Lawrence Livermore National Security, LLC. + * + * Produced at the Lawrence Livermore National Laboratory + * + * LLNL-CODE-746361 + * + * All rights reserved. See COPYRIGHT for details. + * + * This file is part of the GEOSX Simulation Framework. + * + * GEOSX is a free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License (as published by the + * Free Software Foundation) version 2.1 dated February 1999. + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +// Source includes +#include "testArrayView.hpp" + +namespace LvArray +{ +namespace testing +{ + +TYPED_TEST( ArrayViewTest, udcToSliceConst ) +{ + this->udcToSliceConst(); +} + +} // namespace testing +} // namespace LvArray + +// This is the default gtest main method. It is included for ease of debugging. +int main( int argc, char * * argv ) +{ + ::testing::InitGoogleTest( &argc, argv ); + int const result = RUN_ALL_TESTS(); + return result; +} diff --git a/unitTests/testArrayView_udcToViewConst.cpp b/unitTests/testArrayView_udcToViewConst.cpp new file mode 100644 index 00000000..867244c7 --- /dev/null +++ b/unitTests/testArrayView_udcToViewConst.cpp @@ -0,0 +1,41 @@ +/* + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Copyright (c) 2018, Lawrence Livermore National Security, LLC. + * + * Produced at the Lawrence Livermore National Laboratory + * + * LLNL-CODE-746361 + * + * All rights reserved. See COPYRIGHT for details. + * + * This file is part of the GEOSX Simulation Framework. + * + * GEOSX is a free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License (as published by the + * Free Software Foundation) version 2.1 dated February 1999. + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +// Source includes +#include "testArrayView.hpp" + +namespace LvArray +{ +namespace testing +{ + +TYPED_TEST( ArrayViewTest, udcToViewConst ) +{ + this->udcToViewConst(); +} + +} // namespace testing +} // namespace LvArray + +// This is the default gtest main method. It is included for ease of debugging. +int main( int argc, char * * argv ) +{ + ::testing::InitGoogleTest( &argc, argv ); + int const result = RUN_ALL_TESTS(); + return result; +} diff --git a/unitTests/testArray_clear.cpp b/unitTests/testArray_clear.cpp new file mode 100644 index 00000000..c56cb5c4 --- /dev/null +++ b/unitTests/testArray_clear.cpp @@ -0,0 +1,41 @@ +/* + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Copyright (c) 2019, Lawrence Livermore National Security, LLC. + * + * Produced at the Lawrence Livermore National Laboratory + * + * LLNL-CODE-746361 + * + * All rights reserved. See COPYRIGHT for details. + * + * This file is part of the GEOSX Simulation Framework. + * + * GEOSX is a free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License (as published by the + * Free Software Foundation) version 2.1 dated February 1999. + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +// Source includes +#include "testArray.hpp" + +namespace LvArray +{ +namespace testing +{ + +TYPED_TEST( ArrayTest, clear ) +{ + this->clear(); +} + +} // namespace testing +} // namespace LvArray + +// This is the default gtest main method. It is included for ease of debugging. +int main( int argc, char * * argv ) +{ + ::testing::InitGoogleTest( &argc, argv ); + int const result = RUN_ALL_TESTS(); + return result; +} diff --git a/unitTests/testArray_copyAssignmentOperator.cpp b/unitTests/testArray_copyAssignmentOperator.cpp new file mode 100644 index 00000000..d0dc5b09 --- /dev/null +++ b/unitTests/testArray_copyAssignmentOperator.cpp @@ -0,0 +1,41 @@ +/* + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Copyright (c) 2019, Lawrence Livermore National Security, LLC. + * + * Produced at the Lawrence Livermore National Laboratory + * + * LLNL-CODE-746361 + * + * All rights reserved. See COPYRIGHT for details. + * + * This file is part of the GEOSX Simulation Framework. + * + * GEOSX is a free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License (as published by the + * Free Software Foundation) version 2.1 dated February 1999. + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +// Source includes +#include "testArray.hpp" + +namespace LvArray +{ +namespace testing +{ + +TYPED_TEST( ArrayTest, copyAssignmentOperator ) +{ + this->copyAssignmentOperator(); +} + +} // namespace testing +} // namespace LvArray + +// This is the default gtest main method. It is included for ease of debugging. +int main( int argc, char * * argv ) +{ + ::testing::InitGoogleTest( &argc, argv ); + int const result = RUN_ALL_TESTS(); + return result; +} diff --git a/unitTests/testArray_copyConstructor.cpp b/unitTests/testArray_copyConstructor.cpp new file mode 100644 index 00000000..9ad38571 --- /dev/null +++ b/unitTests/testArray_copyConstructor.cpp @@ -0,0 +1,41 @@ +/* + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Copyright (c) 2019, Lawrence Livermore National Security, LLC. + * + * Produced at the Lawrence Livermore National Laboratory + * + * LLNL-CODE-746361 + * + * All rights reserved. See COPYRIGHT for details. + * + * This file is part of the GEOSX Simulation Framework. + * + * GEOSX is a free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License (as published by the + * Free Software Foundation) version 2.1 dated February 1999. + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +// Source includes +#include "testArray.hpp" + +namespace LvArray +{ +namespace testing +{ + +TYPED_TEST( ArrayTest, moveConstructor ) +{ + this->moveConstructor(); +} + +} // namespace testing +} // namespace LvArray + +// This is the default gtest main method. It is included for ease of debugging. +int main( int argc, char * * argv ) +{ + ::testing::InitGoogleTest( &argc, argv ); + int const result = RUN_ALL_TESTS(); + return result; +} diff --git a/unitTests/testArray_defaultConstructor.cpp b/unitTests/testArray_defaultConstructor.cpp new file mode 100644 index 00000000..71c483c3 --- /dev/null +++ b/unitTests/testArray_defaultConstructor.cpp @@ -0,0 +1,41 @@ +/* + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Copyright (c) 2019, Lawrence Livermore National Security, LLC. + * + * Produced at the Lawrence Livermore National Laboratory + * + * LLNL-CODE-746361 + * + * All rights reserved. See COPYRIGHT for details. + * + * This file is part of the GEOSX Simulation Framework. + * + * GEOSX is a free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License (as published by the + * Free Software Foundation) version 2.1 dated February 1999. + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +// Source includes +#include "testArray.hpp" + +namespace LvArray +{ +namespace testing +{ + +TYPED_TEST( ArrayTest, defaultConstructor ) +{ + this->defaultConstructor(); +} + +} // namespace testing +} // namespace LvArray + +// This is the default gtest main method. It is included for ease of debugging. +int main( int argc, char * * argv ) +{ + ::testing::InitGoogleTest( &argc, argv ); + int const result = RUN_ALL_TESTS(); + return result; +} diff --git a/unitTests/testArray_getSetSingleParameterResizeIndex.cpp b/unitTests/testArray_getSetSingleParameterResizeIndex.cpp new file mode 100644 index 00000000..f8e47aa3 --- /dev/null +++ b/unitTests/testArray_getSetSingleParameterResizeIndex.cpp @@ -0,0 +1,41 @@ +/* + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Copyright (c) 2019, Lawrence Livermore National Security, LLC. + * + * Produced at the Lawrence Livermore National Laboratory + * + * LLNL-CODE-746361 + * + * All rights reserved. See COPYRIGHT for details. + * + * This file is part of the GEOSX Simulation Framework. + * + * GEOSX is a free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License (as published by the + * Free Software Foundation) version 2.1 dated February 1999. + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +// Source includes +#include "testArray.hpp" + +namespace LvArray +{ +namespace testing +{ + +TYPED_TEST( ArrayTest, getSetSingleParameterResizeIndex ) +{ + this->getSetSingleParameterResizeIndex(); +} + +} // namespace testing +} // namespace LvArray + +// This is the default gtest main method. It is included for ease of debugging. +int main( int argc, char * * argv ) +{ + ::testing::InitGoogleTest( &argc, argv ); + int const result = RUN_ALL_TESTS(); + return result; +} diff --git a/unitTests/testArray_indexing.cpp b/unitTests/testArray_indexing.cpp new file mode 100644 index 00000000..514cf05c --- /dev/null +++ b/unitTests/testArray_indexing.cpp @@ -0,0 +1,41 @@ +/* + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Copyright (c) 2019, Lawrence Livermore National Security, LLC. + * + * Produced at the Lawrence Livermore National Laboratory + * + * LLNL-CODE-746361 + * + * All rights reserved. See COPYRIGHT for details. + * + * This file is part of the GEOSX Simulation Framework. + * + * GEOSX is a free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License (as published by the + * Free Software Foundation) version 2.1 dated February 1999. + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +// Source includes +#include "testArray.hpp" + +namespace LvArray +{ +namespace testing +{ + +TYPED_TEST( ArrayTest, checkIndexing ) +{ + this->checkIndexing(); +} + +} // namespace testing +} // namespace LvArray + +// This is the default gtest main method. It is included for ease of debugging. +int main( int argc, char * * argv ) +{ + ::testing::InitGoogleTest( &argc, argv ); + int const result = RUN_ALL_TESTS(); + return result; +} diff --git a/unitTests/testArray_moveAssignmentOperator.cpp b/unitTests/testArray_moveAssignmentOperator.cpp new file mode 100644 index 00000000..d15aaa98 --- /dev/null +++ b/unitTests/testArray_moveAssignmentOperator.cpp @@ -0,0 +1,41 @@ +/* + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Copyright (c) 2019, Lawrence Livermore National Security, LLC. + * + * Produced at the Lawrence Livermore National Laboratory + * + * LLNL-CODE-746361 + * + * All rights reserved. See COPYRIGHT for details. + * + * This file is part of the GEOSX Simulation Framework. + * + * GEOSX is a free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License (as published by the + * Free Software Foundation) version 2.1 dated February 1999. + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +// Source includes +#include "testArray.hpp" + +namespace LvArray +{ +namespace testing +{ + +TYPED_TEST( ArrayTest, moveAssignmentOperator ) +{ + this->moveAssignmentOperator(); +} + +} // namespace testing +} // namespace LvArray + +// This is the default gtest main method. It is included for ease of debugging. +int main( int argc, char * * argv ) +{ + ::testing::InitGoogleTest( &argc, argv ); + int const result = RUN_ALL_TESTS(); + return result; +} diff --git a/unitTests/testArray_moveConstructor.cpp b/unitTests/testArray_moveConstructor.cpp new file mode 100644 index 00000000..9ad38571 --- /dev/null +++ b/unitTests/testArray_moveConstructor.cpp @@ -0,0 +1,41 @@ +/* + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Copyright (c) 2019, Lawrence Livermore National Security, LLC. + * + * Produced at the Lawrence Livermore National Laboratory + * + * LLNL-CODE-746361 + * + * All rights reserved. See COPYRIGHT for details. + * + * This file is part of the GEOSX Simulation Framework. + * + * GEOSX is a free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License (as published by the + * Free Software Foundation) version 2.1 dated February 1999. + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +// Source includes +#include "testArray.hpp" + +namespace LvArray +{ +namespace testing +{ + +TYPED_TEST( ArrayTest, moveConstructor ) +{ + this->moveConstructor(); +} + +} // namespace testing +} // namespace LvArray + +// This is the default gtest main method. It is included for ease of debugging. +int main( int argc, char * * argv ) +{ + ::testing::InitGoogleTest( &argc, argv ); + int const result = RUN_ALL_TESTS(); + return result; +} diff --git a/unitTests/testArray_reserveAndCapacity.cpp b/unitTests/testArray_reserveAndCapacity.cpp new file mode 100644 index 00000000..8fdebddf --- /dev/null +++ b/unitTests/testArray_reserveAndCapacity.cpp @@ -0,0 +1,41 @@ +/* + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Copyright (c) 2019, Lawrence Livermore National Security, LLC. + * + * Produced at the Lawrence Livermore National Laboratory + * + * LLNL-CODE-746361 + * + * All rights reserved. See COPYRIGHT for details. + * + * This file is part of the GEOSX Simulation Framework. + * + * GEOSX is a free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License (as published by the + * Free Software Foundation) version 2.1 dated February 1999. + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +// Source includes +#include "testArray.hpp" + +namespace LvArray +{ +namespace testing +{ + +TYPED_TEST( ArrayTest, reserveAndCapacity ) +{ + this->reserveAndCapacity(); +} + +} // namespace testing +} // namespace LvArray + +// This is the default gtest main method. It is included for ease of debugging. +int main( int argc, char * * argv ) +{ + ::testing::InitGoogleTest( &argc, argv ); + int const result = RUN_ALL_TESTS(); + return result; +} diff --git a/unitTests/testArray_resize.cpp b/unitTests/testArray_resize.cpp new file mode 100644 index 00000000..c3bbe680 --- /dev/null +++ b/unitTests/testArray_resize.cpp @@ -0,0 +1,41 @@ +/* + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Copyright (c) 2019, Lawrence Livermore National Security, LLC. + * + * Produced at the Lawrence Livermore National Laboratory + * + * LLNL-CODE-746361 + * + * All rights reserved. See COPYRIGHT for details. + * + * This file is part of the GEOSX Simulation Framework. + * + * GEOSX is a free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License (as published by the + * Free Software Foundation) version 2.1 dated February 1999. + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +// Source includes +#include "testArray.hpp" + +namespace LvArray +{ +namespace testing +{ + +TYPED_TEST( ArrayTest, resize ) +{ + this->resize( false ); +} + +} // namespace testing +} // namespace LvArray + +// This is the default gtest main method. It is included for ease of debugging. +int main( int argc, char * * argv ) +{ + ::testing::InitGoogleTest( &argc, argv ); + int const result = RUN_ALL_TESTS(); + return result; +} diff --git a/unitTests/testArray_resizeDefault.cpp b/unitTests/testArray_resizeDefault.cpp new file mode 100644 index 00000000..d1e86a53 --- /dev/null +++ b/unitTests/testArray_resizeDefault.cpp @@ -0,0 +1,41 @@ +/* + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Copyright (c) 2019, Lawrence Livermore National Security, LLC. + * + * Produced at the Lawrence Livermore National Laboratory + * + * LLNL-CODE-746361 + * + * All rights reserved. See COPYRIGHT for details. + * + * This file is part of the GEOSX Simulation Framework. + * + * GEOSX is a free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License (as published by the + * Free Software Foundation) version 2.1 dated February 1999. + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +// Source includes +#include "testArray.hpp" + +namespace LvArray +{ +namespace testing +{ + +TYPED_TEST( ArrayTest, resizeDefault ) +{ + this->resize( true ); +} + +} // namespace testing +} // namespace LvArray + +// This is the default gtest main method. It is included for ease of debugging. +int main( int argc, char * * argv ) +{ + ::testing::InitGoogleTest( &argc, argv ); + int const result = RUN_ALL_TESTS(); + return result; +} diff --git a/unitTests/testArray_resizeDimension.cpp b/unitTests/testArray_resizeDimension.cpp new file mode 100644 index 00000000..41968f65 --- /dev/null +++ b/unitTests/testArray_resizeDimension.cpp @@ -0,0 +1,41 @@ +/* + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Copyright (c) 2019, Lawrence Livermore National Security, LLC. + * + * Produced at the Lawrence Livermore National Laboratory + * + * LLNL-CODE-746361 + * + * All rights reserved. See COPYRIGHT for details. + * + * This file is part of the GEOSX Simulation Framework. + * + * GEOSX is a free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License (as published by the + * Free Software Foundation) version 2.1 dated February 1999. + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +// Source includes +#include "testArray.hpp" + +namespace LvArray +{ +namespace testing +{ + +TYPED_TEST( ArrayTest, resizeDimension ) +{ + this->resizeDimension(); +} + +} // namespace testing +} // namespace LvArray + +// This is the default gtest main method. It is included for ease of debugging. +int main( int argc, char * * argv ) +{ + ::testing::InitGoogleTest( &argc, argv ); + int const result = RUN_ALL_TESTS(); + return result; +} diff --git a/unitTests/testArray_resizeFromArgs.cpp b/unitTests/testArray_resizeFromArgs.cpp new file mode 100644 index 00000000..6670391f --- /dev/null +++ b/unitTests/testArray_resizeFromArgs.cpp @@ -0,0 +1,41 @@ +/* + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Copyright (c) 2019, Lawrence Livermore National Security, LLC. + * + * Produced at the Lawrence Livermore National Laboratory + * + * LLNL-CODE-746361 + * + * All rights reserved. See COPYRIGHT for details. + * + * This file is part of the GEOSX Simulation Framework. + * + * GEOSX is a free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License (as published by the + * Free Software Foundation) version 2.1 dated February 1999. + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +// Source includes +#include "testArray.hpp" + +namespace LvArray +{ +namespace testing +{ + +TYPED_TEST( ArrayTest, resizeFromArgs ) +{ + this->resizeFromArgs(); +} + +} // namespace testing +} // namespace LvArray + +// This is the default gtest main method. It is included for ease of debugging. +int main( int argc, char * * argv ) +{ + ::testing::InitGoogleTest( &argc, argv ); + int const result = RUN_ALL_TESTS(); + return result; +} diff --git a/unitTests/testArray_resizeFromPointer.cpp b/unitTests/testArray_resizeFromPointer.cpp new file mode 100644 index 00000000..3485e70f --- /dev/null +++ b/unitTests/testArray_resizeFromPointer.cpp @@ -0,0 +1,41 @@ +/* + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Copyright (c) 2019, Lawrence Livermore National Security, LLC. + * + * Produced at the Lawrence Livermore National Laboratory + * + * LLNL-CODE-746361 + * + * All rights reserved. See COPYRIGHT for details. + * + * This file is part of the GEOSX Simulation Framework. + * + * GEOSX is a free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License (as published by the + * Free Software Foundation) version 2.1 dated February 1999. + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +// Source includes +#include "testArray.hpp" + +namespace LvArray +{ +namespace testing +{ + +TYPED_TEST( ArrayTest, resizeFromPointer ) +{ + this->resizeFromPointer(); +} + +} // namespace testing +} // namespace LvArray + +// This is the default gtest main method. It is included for ease of debugging. +int main( int argc, char * * argv ) +{ + ::testing::InitGoogleTest( &argc, argv ); + int const result = RUN_ALL_TESTS(); + return result; +} diff --git a/unitTests/testArray_resizeWithoutInitializationOrDestruction.cpp b/unitTests/testArray_resizeWithoutInitializationOrDestruction.cpp new file mode 100644 index 00000000..2472984b --- /dev/null +++ b/unitTests/testArray_resizeWithoutInitializationOrDestruction.cpp @@ -0,0 +1,41 @@ +/* + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Copyright (c) 2019, Lawrence Livermore National Security, LLC. + * + * Produced at the Lawrence Livermore National Laboratory + * + * LLNL-CODE-746361 + * + * All rights reserved. See COPYRIGHT for details. + * + * This file is part of the GEOSX Simulation Framework. + * + * GEOSX is a free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License (as published by the + * Free Software Foundation) version 2.1 dated February 1999. + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +// Source includes +#include "testArray.hpp" + +namespace LvArray +{ +namespace testing +{ + +TYPED_TEST( ArrayOfTrivialObjectsTest, resizeWithoutInitializationOrDestruction ) +{ + this->resizeWithoutInitializationOrDestruction(); +} + +} // namespace testing +} // namespace LvArray + +// This is the default gtest main method. It is included for ease of debugging. +int main( int argc, char * * argv ) +{ + ::testing::InitGoogleTest( &argc, argv ); + int const result = RUN_ALL_TESTS(); + return result; +} diff --git a/unitTests/testArray_scalarAssignmentOperator.cpp b/unitTests/testArray_scalarAssignmentOperator.cpp new file mode 100644 index 00000000..d1b90432 --- /dev/null +++ b/unitTests/testArray_scalarAssignmentOperator.cpp @@ -0,0 +1,41 @@ +/* + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Copyright (c) 2019, Lawrence Livermore National Security, LLC. + * + * Produced at the Lawrence Livermore National Laboratory + * + * LLNL-CODE-746361 + * + * All rights reserved. See COPYRIGHT for details. + * + * This file is part of the GEOSX Simulation Framework. + * + * GEOSX is a free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License (as published by the + * Free Software Foundation) version 2.1 dated February 1999. + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +// Source includes +#include "testArray.hpp" + +namespace LvArray +{ +namespace testing +{ + +TYPED_TEST( ArrayTest, scalarAssignmentOperator ) +{ + this->scalarAssignmentOperator(); +} + +} // namespace testing +} // namespace LvArray + +// This is the default gtest main method. It is included for ease of debugging. +int main( int argc, char * * argv ) +{ + ::testing::InitGoogleTest( &argc, argv ); + int const result = RUN_ALL_TESTS(); + return result; +} diff --git a/unitTests/testArray_sizedConstructor.cpp b/unitTests/testArray_sizedConstructor.cpp new file mode 100644 index 00000000..4be819a6 --- /dev/null +++ b/unitTests/testArray_sizedConstructor.cpp @@ -0,0 +1,41 @@ +/* + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Copyright (c) 2019, Lawrence Livermore National Security, LLC. + * + * Produced at the Lawrence Livermore National Laboratory + * + * LLNL-CODE-746361 + * + * All rights reserved. See COPYRIGHT for details. + * + * This file is part of the GEOSX Simulation Framework. + * + * GEOSX is a free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License (as published by the + * Free Software Foundation) version 2.1 dated February 1999. + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +// Source includes +#include "testArray.hpp" + +namespace LvArray +{ +namespace testing +{ + +TYPED_TEST( ArrayTest, sizedConstructor ) +{ + this->sizedConstructor(); +} + +} // namespace testing +} // namespace LvArray + +// This is the default gtest main method. It is included for ease of debugging. +int main( int argc, char * * argv ) +{ + ::testing::InitGoogleTest( &argc, argv ); + int const result = RUN_ALL_TESTS(); + return result; +} diff --git a/unitTests/testArray_toView.cpp b/unitTests/testArray_toView.cpp new file mode 100644 index 00000000..f98d008d --- /dev/null +++ b/unitTests/testArray_toView.cpp @@ -0,0 +1,41 @@ +/* + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Copyright (c) 2019, Lawrence Livermore National Security, LLC. + * + * Produced at the Lawrence Livermore National Laboratory + * + * LLNL-CODE-746361 + * + * All rights reserved. See COPYRIGHT for details. + * + * This file is part of the GEOSX Simulation Framework. + * + * GEOSX is a free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License (as published by the + * Free Software Foundation) version 2.1 dated February 1999. + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +// Source includes +#include "testArray.hpp" + +namespace LvArray +{ +namespace testing +{ + +TYPED_TEST( ArrayTest, toView ) +{ + this->toView(); +} + +} // namespace testing +} // namespace LvArray + +// This is the default gtest main method. It is included for ease of debugging. +int main( int argc, char * * argv ) +{ + ::testing::InitGoogleTest( &argc, argv ); + int const result = RUN_ALL_TESTS(); + return result; +} diff --git a/unitTests/testArray_toViewConst.cpp b/unitTests/testArray_toViewConst.cpp new file mode 100644 index 00000000..330ac8ca --- /dev/null +++ b/unitTests/testArray_toViewConst.cpp @@ -0,0 +1,41 @@ +/* + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Copyright (c) 2019, Lawrence Livermore National Security, LLC. + * + * Produced at the Lawrence Livermore National Laboratory + * + * LLNL-CODE-746361 + * + * All rights reserved. See COPYRIGHT for details. + * + * This file is part of the GEOSX Simulation Framework. + * + * GEOSX is a free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License (as published by the + * Free Software Foundation) version 2.1 dated February 1999. + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +// Source includes +#include "testArray.hpp" + +namespace LvArray +{ +namespace testing +{ + +TYPED_TEST( ArrayTest, toViewConst ) +{ + this->toViewConst(); +} + +} // namespace testing +} // namespace LvArray + +// This is the default gtest main method. It is included for ease of debugging. +int main( int argc, char * * argv ) +{ + ::testing::InitGoogleTest( &argc, argv ); + int const result = RUN_ALL_TESTS(); + return result; +} diff --git a/unitTests/testBuffers.cpp b/unitTests/testBuffers.cpp index 96c7c36d..38c45aaa 100644 --- a/unitTests/testBuffers.cpp +++ b/unitTests/testBuffers.cpp @@ -23,7 +23,6 @@ // Source includes #include "testUtils.hpp" #include "bufferManipulation.hpp" -#include "NewChaiBuffer.hpp" #include "StackBuffer.hpp" #include "MallocBuffer.hpp" @@ -75,12 +74,15 @@ class BufferAPITest : public ::testing::Test {}; /// The list of types to instantiate BufferAPITest with, should contain at least one instance of every buffer class. -using BufferAPITestTypes = ::testing::Types< NewChaiBuffer< int >, - NewChaiBuffer< TestString >, - StackBuffer< int, NO_REALLOC_CAPACITY >, - MallocBuffer< int >, - MallocBuffer< TestString > - >; +using BufferAPITestTypes = ::testing::Types< + StackBuffer< int, NO_REALLOC_CAPACITY > + , MallocBuffer< int > + , MallocBuffer< TestString > +#if defined(USE_CHAI) + , NewChaiBuffer< int > + , NewChaiBuffer< TestString > +#endif + >; TYPED_TEST_SUITE( BufferAPITest, BufferAPITestTypes, ); @@ -126,8 +128,8 @@ TYPED_TEST( BufferAPITest, move ) { TypeParam buffer( true ); - buffer.move( chai::CPU, 0, true ); - buffer.move( chai::CPU, true ); + buffer.move( MemorySpace::CPU, 0, true ); + buffer.move( MemorySpace::CPU, true ); bufferManipulation::free( buffer, 0 ); } @@ -139,7 +141,7 @@ TYPED_TEST( BufferAPITest, registerTouch ) { TypeParam buffer( true ); - buffer.registerTouch( chai::CPU ); + buffer.registerTouch( MemorySpace::CPU ); bufferManipulation::free( buffer, 0 ); } @@ -221,127 +223,122 @@ class BufferTestNoRealloc : public ::testing::Test } /** - * @brief Test pushBack. + * @brief Test emplaceBack. * @param nVals the number of values to append. */ - void pushBack( std::ptrdiff_t const nVals ) + void emplaceBack( std::ptrdiff_t const nVals ) { COMPARE_TO_REFERENCE( m_buffer, m_ref ); - for( std::ptrdiff_t i = 0; i < nVals; ++i ) + LVARRAY_ERROR_IF_NE( nVals % 2, 0 ); + + for( std::ptrdiff_t i = 0; i < nVals / 2; ++i ) { T const val( randInt() ); - bufferManipulation::pushBack( m_buffer, size(), val ); - m_ref.push_back( val ); - } + bufferManipulation::emplaceBack( m_buffer, size(), val ); + m_ref.emplace_back( val ); - COMPARE_TO_REFERENCE( m_buffer, m_ref ); - } - - /** - * @brief Test pushBack which takes an r-value reference. - * @param nVals the number of values to append. - */ - void pushBackMove( std::ptrdiff_t const nVals ) - { - COMPARE_TO_REFERENCE( m_buffer, m_ref ); - - for( std::ptrdiff_t i = 0; i < nVals; ++i ) - { std::ptrdiff_t const seed = randInt(); - bufferManipulation::pushBack( m_buffer, size(), T( seed ) ); - m_ref.push_back( T( seed ) ); + bufferManipulation::emplaceBack( m_buffer, size(), seed ); + m_ref.emplace_back( seed ); } COMPARE_TO_REFERENCE( m_buffer, m_ref ); } /** - * @brief Test popBack. - * @param nToPop the number of values to pop. + * @brief Test emplace. + * @param nToInsert the number of values to insert. */ - void popBack( std::ptrdiff_t const nToPop ) + void emplace( std::ptrdiff_t const nToInsert ) { COMPARE_TO_REFERENCE( m_buffer, m_ref ); - LVARRAY_ERROR_IF_GT( nToPop, size() ); + LVARRAY_ERROR_IF_NE( nToInsert % 2, 0 ); - for( std::ptrdiff_t i = 0; i < nToPop; ++i ) + for( std::ptrdiff_t i = 0; i < nToInsert / 2; ++i ) { - bufferManipulation::popBack( m_buffer, size() ); - m_ref.pop_back(); + { + T const val( randInt() ); + std::ptrdiff_t const position = randInt( size() ); + bufferManipulation::emplace( m_buffer, size(), position, val ); + m_ref.emplace( m_ref.begin() + position, val ); + } + + { + std::ptrdiff_t const seed = randInt(); + std::ptrdiff_t const position = randInt( size() ); + bufferManipulation::emplace( m_buffer, size(), position, seed ); + m_ref.emplace( m_ref.begin() + position, seed ); + } } COMPARE_TO_REFERENCE( m_buffer, m_ref ); } /** - * @brief Test insert. + * @brief Test insert which inserts multiple values. * @param nToInsert the number of values to insert. */ void insert( std::ptrdiff_t const nToInsert ) { COMPARE_TO_REFERENCE( m_buffer, m_ref ); - for( std::ptrdiff_t i = 0; i < nToInsert; ++i ) + constexpr std::ptrdiff_t MAX_VALS_PER_INSERT = 20; + + std::ptrdiff_t nInserted = 0; + while( nInserted < nToInsert ) { - T const val( randInt() ); - std::ptrdiff_t const position = randInt( size() ); - bufferManipulation::insert( m_buffer, size(), position, val ); - m_ref.insert( m_ref.begin() + position, val ); - } + // Insert from a std::vector + { + std::ptrdiff_t const nToInsertThisIter = randInt( min( MAX_VALS_PER_INSERT, nToInsert - nInserted ) ); + std::vector< T > valsToInsert( nToInsertThisIter ); - COMPARE_TO_REFERENCE( m_buffer, m_ref ); - } + for( T & val : valsToInsert ) + { val = T( randInt() ); } - /** - * @brief Test insert which takes an r-value reference. - * @param nToInsert the number of values to insert. - */ - void insertMove( std::ptrdiff_t const nToInsert ) - { - COMPARE_TO_REFERENCE( m_buffer, m_ref ); + std::ptrdiff_t const position = randInt( size() ); + bufferManipulation::insert( m_buffer, size(), position, valsToInsert.begin(), valsToInsert.end() ); + m_ref.insert( m_ref.begin() + position, valsToInsert.begin(), valsToInsert.end() ); - for( std::ptrdiff_t i = 0; i < nToInsert; ++i ) - { - std::ptrdiff_t const seed = randInt(); - std::ptrdiff_t const position = randInt( size() ); - bufferManipulation::insert( m_buffer, size(), position, T( seed ) ); - m_ref.insert( m_ref.begin() + position, T( seed ) ); + nInserted += nToInsertThisIter; + } + + // Insert from a std::list + { + std::ptrdiff_t const nToInsertThisIter = randInt( min( MAX_VALS_PER_INSERT, nToInsert - nInserted ) ); + std::list< T > valsToInsert( nToInsertThisIter ); + for( T & val : valsToInsert ) + { val = T( randInt() ); } + + std::ptrdiff_t const position = randInt( size() ); + bufferManipulation::insert( m_buffer, size(), position, valsToInsert.begin(), valsToInsert.end() ); + m_ref.insert( m_ref.begin() + position, valsToInsert.begin(), valsToInsert.end() ); + + nInserted += nToInsertThisIter; + } } + LVARRAY_ERROR_IF_NE( nInserted, nToInsert ); COMPARE_TO_REFERENCE( m_buffer, m_ref ); } /** - * @brief Test insert which inserts multiple values. - * @param nToInsert the number of values to insert. + * @brief Test popBack. + * @param nToPop the number of values to pop. */ - void insertMultiple( std::ptrdiff_t const nToInsert ) + void popBack( std::ptrdiff_t const nToPop ) { COMPARE_TO_REFERENCE( m_buffer, m_ref ); - constexpr std::ptrdiff_t MAX_VALS_PER_INSERT = 20; - std::vector< T > valsToInsert( MAX_VALS_PER_INSERT ); + LVARRAY_ERROR_IF_GT( nToPop, size() ); - std::ptrdiff_t nInserted = 0; - while( nInserted < nToInsert ) + for( std::ptrdiff_t i = 0; i < nToPop; ++i ) { - std::ptrdiff_t const nToInsertThisIter = randInt( min( MAX_VALS_PER_INSERT, nToInsert - nInserted ) ); - std::ptrdiff_t const position = randInt( size() ); - - for( std::ptrdiff_t i = 0; i < nToInsertThisIter; ++i ) - { - valsToInsert[ i ] = T( randInt() ); - } - - bufferManipulation::insert( m_buffer, size(), position, valsToInsert.data(), nToInsertThisIter ); - m_ref.insert( m_ref.begin() + position, valsToInsert.begin(), valsToInsert.begin() + nToInsertThisIter ); - - nInserted += nToInsertThisIter; + bufferManipulation::popBack( m_buffer, size() ); + m_ref.pop_back(); } - LVARRAY_ERROR_IF_NE( nInserted, nToInsert ); COMPARE_TO_REFERENCE( m_buffer, m_ref ); } @@ -399,11 +396,11 @@ TYPED_TEST( BufferTestNoRealloc, resize ) } /** - * @brief Test bufferManipulation::pushBack without reallocating. + * @brief Test bufferManipulation::emplaceBack without reallocating. */ -TYPED_TEST( BufferTestNoRealloc, pushBack ) +TYPED_TEST( BufferTestNoRealloc, emplaceBack ) { - this->pushBack( NO_REALLOC_CAPACITY ); + this->emplaceBack( NO_REALLOC_CAPACITY ); } /** @@ -411,7 +408,7 @@ TYPED_TEST( BufferTestNoRealloc, pushBack ) */ TYPED_TEST( BufferTestNoRealloc, CopyConstructor ) { - this->pushBack( 100 ); + this->emplaceBack( 100 ); TypeParam copy( this->m_buffer, 100 ); TypeParam copy2( copy ); @@ -440,7 +437,7 @@ TYPED_TEST( BufferTestNoRealloc, CopyConstructor ) */ TYPED_TEST( BufferTestNoRealloc, copyAssignmentOperator ) { - this->pushBack( 100 ); + this->emplaceBack( 100 ); TypeParam copy; copy = this->m_buffer; EXPECT_EQ( this->m_buffer.capacity(), copy.capacity() ); @@ -462,7 +459,7 @@ TYPED_TEST( BufferTestNoRealloc, copyAssignmentOperator ) */ TYPED_TEST( BufferTestNoRealloc, MoveConstructor ) { - this->pushBack( 100 ); + this->emplaceBack( 100 ); TypeParam copy( std::move( this->m_buffer ) ); COMPARE_TO_REFERENCE( copy, this->m_ref ); @@ -480,7 +477,7 @@ TYPED_TEST( BufferTestNoRealloc, MoveConstructor ) */ TYPED_TEST( BufferTestNoRealloc, moveAssignmentOperator ) { - this->pushBack( 100 ); + this->emplaceBack( 100 ); TypeParam copy; copy = std::move( this->m_buffer ); COMPARE_TO_REFERENCE( copy, this->m_ref ); @@ -494,47 +491,29 @@ TYPED_TEST( BufferTestNoRealloc, moveAssignmentOperator ) this->m_ref.clear(); } -/** - * @brief Test bufferManipulation::pushBack that takes an rvalue-reference - * without reallocating. - */ -TYPED_TEST( BufferTestNoRealloc, pushBackMove ) -{ - this->pushBackMove( NO_REALLOC_CAPACITY ); -} - /** * @brief Test bufferManipulation::popBack without reallocating. */ TYPED_TEST( BufferTestNoRealloc, popBack ) { - this->pushBack( NO_REALLOC_CAPACITY ); + this->emplaceBack( NO_REALLOC_CAPACITY ); this->popBack( NO_REALLOC_CAPACITY / 2 ); } /** - * @brief Test bufferManipulation::insert without reallocating. - */ -TYPED_TEST( BufferTestNoRealloc, insert ) -{ - this->insert( NO_REALLOC_CAPACITY ); -} - -/** - * @brief Test bufferManipulation::insert that takes an rvalue-reference - * without reallocating. + * @brief Test bufferManipulation::emplace without reallocating. */ -TYPED_TEST( BufferTestNoRealloc, insertMove ) +TYPED_TEST( BufferTestNoRealloc, emplace ) { - this->insertMove( NO_REALLOC_CAPACITY ); + this->emplace( NO_REALLOC_CAPACITY ); } /** * @brief Test bufferManipulation::insert multiple function without reallocating. */ -TYPED_TEST( BufferTestNoRealloc, insertMultiple ) +TYPED_TEST( BufferTestNoRealloc, insert ) { - this->insertMultiple( NO_REALLOC_CAPACITY ); + this->insert( NO_REALLOC_CAPACITY ); } /** @@ -542,7 +521,7 @@ TYPED_TEST( BufferTestNoRealloc, insertMultiple ) */ TYPED_TEST( BufferTestNoRealloc, erase ) { - this->pushBack( NO_REALLOC_CAPACITY ); + this->emplaceBack( NO_REALLOC_CAPACITY ); this->erase( NO_REALLOC_CAPACITY / 2 ); } @@ -551,7 +530,7 @@ TYPED_TEST( BufferTestNoRealloc, erase ) */ TYPED_TEST( BufferTestNoRealloc, copyInto ) { - this->pushBack( NO_REALLOC_CAPACITY ); + this->emplaceBack( NO_REALLOC_CAPACITY ); forEachArg( [this]( auto && copy ) @@ -560,7 +539,9 @@ TYPED_TEST( BufferTestNoRealloc, copyInto ) COMPARE_TO_REFERENCE( copy, this->m_ref ); bufferManipulation::free( copy, NO_REALLOC_CAPACITY ); }, + #if defined(USE_CHAI) NewChaiBuffer< typename TypeParam::value_type >( true ), + #endif MallocBuffer< typename TypeParam::value_type >( true ) // I would like to copInto a StackBuffer but that doesn't work with std::string. ); @@ -651,11 +632,14 @@ class BufferTestWithRealloc : public BufferTestNoRealloc< BUFFER_TYPE > /// The list of types to instantiate BufferTestWithRealloc with, /// should contain at least one instance of every dynamically reallocatable buffer class. -using BufferTestWithReallocTypes = ::testing::Types< NewChaiBuffer< int >, - NewChaiBuffer< TestString >, - MallocBuffer< int >, - MallocBuffer< TestString > - >; +using BufferTestWithReallocTypes = ::testing::Types< + MallocBuffer< int > + , MallocBuffer< TestString > +#if defined(USE_CHAI) + , NewChaiBuffer< int > + , NewChaiBuffer< TestString > +#endif + >; TYPED_TEST_SUITE( BufferTestWithRealloc, BufferTestWithReallocTypes, ); @@ -676,27 +660,27 @@ TYPED_TEST( BufferTestWithRealloc, reserve ) } /** - * @brief Test bufferManipulation::pushBack. + * @brief Test bufferManipulation::emplaceBack. */ -TYPED_TEST( BufferTestWithRealloc, pushBack ) +TYPED_TEST( BufferTestWithRealloc, emplaceBack ) { - this->pushBack( 100 ); - this->pushBack( 100 ); - this->pushBack( 100 ); + this->emplaceBack( 100 ); + this->emplaceBack( 100 ); + this->emplaceBack( 100 ); } /** - * @brief Test bufferManipulation::pushBack that takes an r-value reference. + * @brief Test bufferManipulation::emplace. */ -TYPED_TEST( BufferTestWithRealloc, pushBackMove ) +TYPED_TEST( BufferTestWithRealloc, emplace ) { - this->pushBackMove( 100 ); - this->pushBackMove( 100 ); - this->pushBackMove( 100 ); + this->emplace( 100 ); + this->emplace( 100 ); + this->emplace( 100 ); } /** - * @brief Test bufferManipulation::insert. + * @brief Test bufferManipulation::insert that inserts multiple values. */ TYPED_TEST( BufferTestWithRealloc, insert ) { @@ -705,40 +689,20 @@ TYPED_TEST( BufferTestWithRealloc, insert ) this->insert( 100 ); } -/** - * @brief Test bufferManipulation::insert that takes an r-value reference. - */ -TYPED_TEST( BufferTestWithRealloc, insertMove ) -{ - this->insertMove( 100 ); - this->insertMove( 100 ); - this->insertMove( 100 ); -} - -/** - * @brief Test bufferManipulation::insert that inserts multiple values. - */ -TYPED_TEST( BufferTestWithRealloc, insertMultiple ) -{ - this->insertMultiple( 100 ); - this->insertMultiple( 100 ); - this->insertMultiple( 100 ); -} - /** * @brief Test multiple bufferManipulation methods chained together. */ TYPED_TEST( BufferTestWithRealloc, combination ) { - this->pushBack( 100 ); - this->insert( 100 ); + this->emplaceBack( 100 ); + this->emplace( 100 ); this->erase( 100 ); - this->insertMultiple( 100 ); - this->popBack( 100 ); - this->pushBack( 100 ); this->insert( 100 ); + this->popBack( 100 ); + this->emplaceBack( 100 ); + this->emplace( 100 ); this->erase( 100 ); - this->insertMultiple( 100 ); + this->insert( 100 ); this->popBack( 100 ); } diff --git a/unitTests/testCRSMatrix.cpp b/unitTests/testCRSMatrix.cpp index 57bee1db..ade49e4d 100644 --- a/unitTests/testCRSMatrix.cpp +++ b/unitTests/testCRSMatrix.cpp @@ -22,6 +22,7 @@ #include "ArrayOfSets.hpp" #include "streamIO.hpp" #include "testUtils.hpp" +#include "MallocBuffer.hpp" // TPL includes #include @@ -40,75 +41,77 @@ namespace testing using INDEX_TYPE = std::ptrdiff_t; using COL_TYPE = int; -// A matrix is an array of rows. Where each row is a sorted collection of unique columns each paired with a value. -template< typename T > -using REF_TYPE = std::vector< std::map< COL_TYPE, T > >; +enum class AddType +{ + BINARY_SEARCH, + LINEAR_SEARCH, + HYBRID, + UNSORTED_BINARY +}; -/** - * @brief Check that the CRSMatrixView is equivalent to the reference type. - * @param [in] view the CRSMatrixView to check. - * @param [in] ref the reference to check against. - */ -template< typename T > -void compareToReference( CRSMatrixView< T const, COL_TYPE const, INDEX_TYPE const > const & view, - REF_TYPE< T > const & ref ) +template< typename CRS_MATRIX > +class CRSMatrixTest : public ::testing::Test { - INDEX_TYPE const numRows = view.numRows(); - ASSERT_EQ( numRows, ref.size()); +public: - INDEX_TYPE ref_nnz = 0; - for( INDEX_TYPE row = 0; row < numRows; ++row ) - { - INDEX_TYPE const rowNNZ = view.numNonZeros( row ); - INDEX_TYPE const refRowNNZ = ref[row].size(); - ref_nnz += refRowNNZ; + using T = typename CRS_MATRIX::value_type; - ASSERT_EQ( rowNNZ, refRowNNZ ); + using ViewType = std::remove_reference_t< decltype( std::declval< CRS_MATRIX >().toView() ) >; + using ViewTypeConstSizes = std::remove_reference_t< decltype( std::declval< CRS_MATRIX >().toViewConstSizes() ) >; + using ViewTypeConst = std::remove_reference_t< decltype( std::declval< CRS_MATRIX >().toViewConst() ) >; - if( rowNNZ == 0 ) - { - ASSERT_TRUE( view.empty( row )); - } - else + template< typename U > + using ArrayOfArraysT = typename ArrayConverter< CRS_MATRIX >::template ArrayOfArrays< U >; + + template< typename U, bool CONST_SIZES > + using ArrayOfArraysViewT = typename ArrayConverter< CRS_MATRIX >::template ArrayOfArraysView< U, CONST_SIZES >; + + void compareToReference( ViewTypeConst const & view ) const + { + INDEX_TYPE const numRows = view.numRows(); + ASSERT_EQ( numRows, m_ref.size()); + + INDEX_TYPE ref_nnz = 0; + for( INDEX_TYPE row = 0; row < numRows; ++row ) { - ASSERT_FALSE( view.empty( row )); + INDEX_TYPE const rowNNZ = view.numNonZeros( row ); + INDEX_TYPE const refRowNNZ = m_ref[ row ].size(); + ref_nnz += refRowNNZ; + + ASSERT_EQ( rowNNZ, refRowNNZ ); + + if( rowNNZ == 0 ) + { + ASSERT_TRUE( view.empty( row )); + } + else + { + ASSERT_FALSE( view.empty( row )); + } + + auto it = m_ref[ row ].begin(); + COL_TYPE const * const columns = view.getColumns( row ); + T const * const entries = view.getEntries( row ); + for( INDEX_TYPE i = 0; i < rowNNZ; ++i ) + { + EXPECT_FALSE( view.empty( row, columns[ i ] )); + EXPECT_EQ( columns[ i ], it->first ); + EXPECT_EQ( entries[ i ], it->second ); + ++it; + } } - auto it = ref[row].begin(); - COL_TYPE const * const columns = view.getColumns( row ); - T const * const entries = view.getEntries( row ); - for( INDEX_TYPE i = 0; i < rowNNZ; ++i ) + ASSERT_EQ( view.numNonZeros(), ref_nnz ); + + if( view.numNonZeros() == 0 ) { - EXPECT_FALSE( view.empty( row, columns[i] )); - EXPECT_EQ( columns[i], it->first ); - EXPECT_EQ( entries[i], it->second ); - ++it; + ASSERT_TRUE( view.empty()); } } - ASSERT_EQ( view.numNonZeros(), ref_nnz ); - - if( view.numNonZeros() == 0 ) - { - ASSERT_TRUE( view.empty()); + #define COMPARE_TO_REFERENCE { SCOPED_TRACE( "" ); this->compareToReference( this->m_matrix.toViewConst() ); \ } -} -#define COMPARE_TO_REFERENCE( view, ref ) { SCOPED_TRACE( "" ); compareToReference( view, ref ); \ -} - -enum class AddType -{ - BINARY_SEARCH, - LINEAR_SEARCH, - HYBRID, - UNSORTED_BINARY -}; - -template< typename T > -class CRSMatrixTest : public ::testing::Test -{ -public: void resize( INDEX_TYPE const nRows, INDEX_TYPE const nCols, @@ -117,7 +120,7 @@ class CRSMatrixTest : public ::testing::Test m_matrix.resize( nRows, nCols, initialRowCapacity ); m_ref.resize( nRows ); - COMPARE_TO_REFERENCE( m_matrix.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE } /** @@ -130,8 +133,8 @@ class CRSMatrixTest : public ::testing::Test INDEX_TYPE const numRows = m_matrix.numRows(); // Create an Array of the columns and values to insert into each row. - ArrayOfArrays< COL_TYPE > const columnsToInsert = createArrayOfColumns( maxInserts, oneAtATime ); - ArrayOfArrays< T > const valuesToInsert = createArrayOfValues( columnsToInsert.toViewConst() ); + ArrayOfArraysT< COL_TYPE > const columnsToInsert = createArrayOfColumns( maxInserts, oneAtATime ); + ArrayOfArraysT< T > const valuesToInsert = createArrayOfValues( columnsToInsert.toViewConst() ); // Insert the entries into the reference. insertIntoRef( columnsToInsert.toViewConst() ); @@ -141,11 +144,6 @@ class CRSMatrixTest : public ::testing::Test INDEX_TYPE const initialNNZ = m_matrix.numNonZeros( row ); INDEX_TYPE nInserted = 0; - // LVARRAY_LOG_VAR( m_matrix.getColumns( row ).toSliceConst() ); - // LVARRAY_LOG_VAR( m_matrix.getEntries( row ).toSliceConst() ); - // LVARRAY_LOG_VAR( columnsToInsert[ row ].toSliceConst() ); - // LVARRAY_LOG_VAR( valuesToInsert[ row ].toSliceConst() ); - if( oneAtATime ) { for( INDEX_TYPE i = 0; i < columnsToInsert.sizeOfArray( row ); ++i ) @@ -156,15 +154,11 @@ class CRSMatrixTest : public ::testing::Test else { nInserted = m_matrix.insertNonZeros( row, columnsToInsert[ row ], valuesToInsert[ row ], columnsToInsert.sizeOfArray( row ) ); } - // LVARRAY_LOG_VAR( m_matrix.getColumns( row ).toSliceConst() ); - // LVARRAY_LOG_VAR( m_matrix.getEntries( row ).toSliceConst() ); - // LVARRAY_LOG( "" ); - ASSERT_EQ( m_matrix.numNonZeros( row ) - initialNNZ, nInserted ); ASSERT_EQ( m_matrix.numNonZeros( row ), m_ref[ row ].size()); } - COMPARE_TO_REFERENCE( m_matrix.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE } /** @@ -251,7 +245,7 @@ class CRSMatrixTest : public ::testing::Test } } - COMPARE_TO_REFERENCE( m_matrix.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE } /** @@ -259,7 +253,7 @@ class CRSMatrixTest : public ::testing::Test */ void deepCopyTest() const { - CRSMatrix< T > copy( m_matrix ); + CRS_MATRIX copy( m_matrix ); ASSERT_EQ( m_matrix.numRows(), copy.numRows()); ASSERT_EQ( m_matrix.numColumns(), copy.numColumns()); @@ -283,10 +277,10 @@ class CRSMatrixTest : public ::testing::Test // Iterate backwards and remove entries from copy. for( INDEX_TYPE i = nnz - 1; i >= 0; --i ) { - EXPECT_EQ( cols[i], cols_cpy[i] ); - EXPECT_EQ( entries[i], entries_cpy[i] ); + EXPECT_EQ( cols[ i ], cols_cpy[ i ] ); + EXPECT_EQ( entries[ i ], entries_cpy[ i ] ); - copy.removeNonZero( row, cols_cpy[i] ); + copy.removeNonZero( row, cols_cpy[ i ] ); } EXPECT_EQ( copy.numNonZeros( row ), 0 ); @@ -296,7 +290,7 @@ class CRSMatrixTest : public ::testing::Test EXPECT_EQ( copy.numNonZeros(), 0 ); EXPECT_EQ( m_matrix.numNonZeros(), totalNNZ ); - COMPARE_TO_REFERENCE( m_matrix.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE } /** @@ -304,7 +298,7 @@ class CRSMatrixTest : public ::testing::Test */ void shallowCopyTest() const { - CRSMatrixView< T > copy( m_matrix ); + ViewType copy( m_matrix ); ASSERT_EQ( m_matrix.numRows(), copy.numRows()); ASSERT_EQ( m_matrix.numColumns(), copy.numColumns()); @@ -326,10 +320,10 @@ class CRSMatrixTest : public ::testing::Test // Iterate backwards and remove entries from copy. for( INDEX_TYPE i = nnz - 1; i >= 0; --i ) { - EXPECT_EQ( cols[i], cols_cpy[i] ); - EXPECT_EQ( entries[i], entries_cpy[i] ); + EXPECT_EQ( cols[ i ], cols_cpy[ i ] ); + EXPECT_EQ( entries[ i ], entries_cpy[ i ] ); - copy.removeNonZero( row, cols_cpy[i] ); + copy.removeNonZero( row, cols_cpy[ i ] ); } EXPECT_EQ( copy.numNonZeros( row ), 0 ); @@ -388,7 +382,7 @@ class CRSMatrixTest : public ::testing::Test } } - COMPARE_TO_REFERENCE( m_matrix.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE } void compress() @@ -418,17 +412,17 @@ class CRSMatrixTest : public ::testing::Test curOffset += m_matrix.numNonZeros( row ); } - COMPARE_TO_REFERENCE( m_matrix.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE } protected: - ArrayOfArrays< COL_TYPE > createArrayOfColumns( INDEX_TYPE const maxCols, bool const oneAtATime ) + ArrayOfArraysT< COL_TYPE > createArrayOfColumns( INDEX_TYPE const maxCols, bool const oneAtATime ) { INDEX_TYPE const numRows = m_matrix.numRows(); // Create an array of the columns. - ArrayOfArrays< COL_TYPE > columns; + ArrayOfArraysT< COL_TYPE > columns; for( INDEX_TYPE row = 0; row < numRows; ++row ) { @@ -449,7 +443,7 @@ class CRSMatrixTest : public ::testing::Test return columns; } - void insertIntoRef( ArrayOfArraysView< COL_TYPE const, INDEX_TYPE const, true > const & columnsToInsert ) + void insertIntoRef( ArrayOfArraysViewT< COL_TYPE const, true > const & columnsToInsert ) { for( INDEX_TYPE i = 0; i < columnsToInsert.size(); ++i ) { @@ -461,9 +455,9 @@ class CRSMatrixTest : public ::testing::Test } } - ArrayOfArrays< T > createArrayOfValues( ArrayOfArraysView< COL_TYPE const, INDEX_TYPE const, true > const & columns ) const + ArrayOfArraysT< T > createArrayOfValues( ArrayOfArraysViewT< COL_TYPE const, true > const & columns ) const { - ArrayOfArrays< T > values; + ArrayOfArraysT< T > values; INDEX_TYPE const numRows = m_matrix.numRows(); for( INDEX_TYPE row = 0; row < numRows; ++row ) @@ -486,83 +480,78 @@ class CRSMatrixTest : public ::testing::Test std::mt19937_64 m_gen; - CRSMatrix< T > m_matrix; - - REF_TYPE< T > m_ref; - - /// Check that the move, toView, and toViewConst methods of CRSMatrix< T > are detected. - static_assert( bufferManipulation::HasMemberFunction_move< CRSMatrix< T > >, - "CRSMatrix< T > has a move method." ); - static_assert( HasMemberFunction_toView< CRSMatrix< T > >, - "CRSMatrix< T > has a toView method." ); - static_assert( HasMemberFunction_toViewConst< CRSMatrix< T > >, - "CRSMatrix< T > has a toViewConst method." ); - - /// Check that the move and toViewConst methods of CRSMatrixView< T, COL_TYPE, INDEX_TYPE const > are detected. - static_assert( bufferManipulation::HasMemberFunction_move< CRSMatrixView< T, COL_TYPE, INDEX_TYPE const > >, - "CRSMatrixView< T, COL_TYPE, INDEX_TYPE const > has a move method." ); - static_assert( HasMemberFunction_toView< CRSMatrixView< T, COL_TYPE, INDEX_TYPE const > >, - "CRSMatrixView< T, COL_TYPE, INDEX_TYPE const > has a toView method." ); - static_assert( HasMemberFunction_toViewConst< CRSMatrixView< T, COL_TYPE, INDEX_TYPE const > >, - "CRSMatrixView< T, COL_TYPE, INDEX_TYPE const > has a toViewConst method." ); - - /// Check that the move and toViewConst methods of CRSMatrixView< T, COL_TYPE const, INDEX_TYPE const > are detected. - static_assert( bufferManipulation::HasMemberFunction_move< CRSMatrixView< T, COL_TYPE const, INDEX_TYPE const > >, - "CRSMatrixView< T, COL_TYPE const, INDEX_TYPE const > has a move method." ); - static_assert( HasMemberFunction_toView< CRSMatrixView< T, COL_TYPE const, INDEX_TYPE const > >, - "CRSMatrixView< T, COL_TYPE const, INDEX_TYPE const > has a toView method." ); - static_assert( HasMemberFunction_toViewConst< CRSMatrixView< T, COL_TYPE const, INDEX_TYPE const > >, - "CRSMatrixView< T, COL_TYPE const, INDEX_TYPE const > has a toViewConst method." ); - - /// Check that the move and toViewConst methods of CRSMatrixView< T const, COL_TYPE const, INDEX_TYPE const > are - /// detected. - static_assert( bufferManipulation::HasMemberFunction_move< CRSMatrixView< T const, COL_TYPE const, INDEX_TYPE const > >, - "CRSMatrixView< T const, COL_TYPE const, INDEX_TYPE const > has a move method." ); - static_assert( HasMemberFunction_toView< CRSMatrixView< T const, COL_TYPE const, INDEX_TYPE const > >, - "CRSMatrixView< T const, COL_TYPE const, INDEX_TYPE const > has a toView method." ); - static_assert( HasMemberFunction_toViewConst< CRSMatrixView< T const, COL_TYPE const, INDEX_TYPE const > >, - "CRSMatrixView< T const, COL_TYPE const, INDEX_TYPE const > has a toViewConst method." ); - - /// Check that GetViewType and GetViewTypeConst are correct for CRSMatrix< T > - static_assert( std::is_same_v< typename GetViewType< CRSMatrix< T > >::type, - CRSMatrixView< T, COL_TYPE, INDEX_TYPE const > const >, - "The view type of CRSMatrix< T > is CRSMatrixView< T, COL_TYPE, INDEX_TYPE const > const." ); - static_assert( std::is_same_v< typename GetViewTypeConst< CRSMatrix< T > >::type, - CRSMatrixView< T const, COL_TYPE const, INDEX_TYPE const > const >, - "The const view type of CRSMatrix< T > is CRSMatrixView< T const, COL_TYPE const, INDEX_TYPE const > const." ); - - /// Check that GetViewType and GetViewTypeConst are correct for CRSMatrixView< T, COL_TYPE, INDEX_TYPE const > - static_assert( std::is_same_v< typename GetViewType< CRSMatrixView< T, COL_TYPE, INDEX_TYPE const > >::type, - CRSMatrixView< T, COL_TYPE, INDEX_TYPE const > const >, - "The view type of CRSMatrixView< T, COL_TYPE, INDEX_TYPE const > is CRSMatrixView< T, COL_TYPE, INDEX_TYPE const > const." ); - static_assert( std::is_same_v< typename GetViewTypeConst< CRSMatrixView< T, COL_TYPE, INDEX_TYPE const > >::type, - CRSMatrixView< T const, COL_TYPE const, INDEX_TYPE const > const >, - "The const view type of CRSMatrixView< T, COL_TYPE, INDEX_TYPE const > is CRSMatrixView< T const, COL_TYPE const, INDEX_TYPE const > const." ); - - /// Check that GetViewType and GetViewTypeConst are correct for CRSMatrixView< T, COL_TYPE const, INDEX_TYPE const > - static_assert( std::is_same_v< typename GetViewType< CRSMatrixView< T, COL_TYPE const, INDEX_TYPE const > >::type, - CRSMatrixView< T, COL_TYPE const, INDEX_TYPE const > const >, - "The view type of CRSMatrixView< T, COL_TYPE const, INDEX_TYPE const > is CRSMatrixView< T, COL_TYPE const, INDEX_TYPE const > const." ); - static_assert( std::is_same_v< typename GetViewTypeConst< CRSMatrixView< T, COL_TYPE const, INDEX_TYPE const > >::type, - CRSMatrixView< T const, COL_TYPE const, INDEX_TYPE const > const >, - "The const view type of CRSMatrixView< T, COL_TYPE const, INDEX_TYPE const > is CRSMatrixView< T const, COL_TYPE const, INDEX_TYPE const > const." ); - - /// Check that GetViewType and GetViewTypeConst are correct for CRSMatrixView< T const, COL_TYPE const, INDEX_TYPE - /// const > - static_assert( std::is_same_v< typename GetViewType< CRSMatrixView< T const, COL_TYPE const, INDEX_TYPE const > >::type, - CRSMatrixView< T const, COL_TYPE const, INDEX_TYPE const > const >, - "The view type of CRSMatrixView< T const, COL_TYPE const, INDEX_TYPE const > is CRSMatrixView< T const, COL_TYPE const, INDEX_TYPE const > const." ); - static_assert( std::is_same_v< typename GetViewTypeConst< CRSMatrixView< T const, COL_TYPE const, INDEX_TYPE const > >::type, - CRSMatrixView< T const, COL_TYPE const, INDEX_TYPE const > const >, - "The const view type of CRSMatrixView< T const, COL_TYPE const, INDEX_TYPE const > is CRSMatrixView< T const, COL_TYPE const, INDEX_TYPE const > const." ); + CRS_MATRIX m_matrix; + + std::vector< std::map< COL_TYPE, T > > m_ref; + + /// Check that the move, toView, and toViewConst methods of CRS_MATRIX are detected. + static_assert( bufferManipulation::HasMemberFunction_move< CRS_MATRIX >, + "CRS_MATRIX has a move method." ); + static_assert( HasMemberFunction_toView< CRS_MATRIX >, + "CRS_MATRIX has a toView method." ); + static_assert( HasMemberFunction_toViewConst< CRS_MATRIX >, + "CRS_MATRIX has a toViewConst method." ); + + /// Check that the move and toViewConst methods of ViewType are detected. + static_assert( bufferManipulation::HasMemberFunction_move< ViewType >, + "ViewType has a move method." ); + static_assert( HasMemberFunction_toView< ViewType >, + "ViewType has a toView method." ); + static_assert( HasMemberFunction_toViewConst< ViewType >, + "ViewType has a toViewConst method." ); + + /// Check that the move and toViewConst methods of ViewTypeConstSizes are detected. + static_assert( bufferManipulation::HasMemberFunction_move< ViewTypeConstSizes >, + "ViewTypeConstSizes has a move method." ); + static_assert( HasMemberFunction_toView< ViewTypeConstSizes >, + "ViewTypeConstSizes has a toView method." ); + static_assert( HasMemberFunction_toViewConst< ViewTypeConstSizes >, + "ViewTypeConstSizes has a toViewConst method." ); + + /// Check that the move and toViewConst methods of ViewTypeConst are detected. + static_assert( bufferManipulation::HasMemberFunction_move< ViewTypeConst >, + "ViewTypeConst has a move method." ); + static_assert( HasMemberFunction_toView< ViewTypeConst >, + "ViewTypeConst has a toView method." ); + static_assert( HasMemberFunction_toViewConst< ViewTypeConst >, + "ViewTypeConst has a toViewConst method." ); + + /// Check that GetViewType and GetViewTypeConst are correct for CRS_MATRIX + static_assert( std::is_same_v< typename GetViewType< CRS_MATRIX >::type, ViewType const >, + "The view type of CRS_MATRIX is ViewType const." ); + static_assert( std::is_same_v< typename GetViewTypeConst< CRS_MATRIX >::type, ViewTypeConst const >, + "The const view type of CRS_MATRIX is ViewTypeConst const." ); + + /// Check that GetViewType and GetViewTypeConst are correct for ViewType + static_assert( std::is_same_v< typename GetViewType< ViewType >::type, ViewType const >, + "The view type of ViewType is ViewType const." ); + static_assert( std::is_same_v< typename GetViewTypeConst< ViewType >::type, ViewTypeConst const >, + "The const view type of ViewType is ViewTypeConst const." ); + + /// Check that GetViewType and GetViewTypeConst are correct for ViewTypeConstSizes + static_assert( std::is_same_v< typename GetViewType< ViewTypeConstSizes >::type, ViewTypeConstSizes const >, + "The view type of ViewTypeConstSizes is ViewTypeConstSizes const." ); + static_assert( std::is_same_v< typename GetViewTypeConst< ViewTypeConstSizes >::type, ViewTypeConst const >, + "The const view type of ViewTypeConstSizes is ViewTypeConst const." ); + + /// Check that GetViewType and GetViewTypeConst are correct for ViewTypeConst + static_assert( std::is_same_v< typename GetViewType< ViewTypeConst >::type, ViewTypeConst const >, + "The view type of ViewTypeConst is ViewTypeConst const." ); + static_assert( std::is_same_v< typename GetViewTypeConst< ViewTypeConst >::type, ViewTypeConst const >, + "The const view type of ViewTypeConst is ViewTypeConst const." ); }; -using TestTypes = ::testing::Types< - int - , Tensor - , TestString +using CRSMatrixTestTypes = ::testing::Types< + CRSMatrix< int, COL_TYPE, INDEX_TYPE, MallocBuffer > + , CRSMatrix< Tensor, COL_TYPE, INDEX_TYPE, MallocBuffer > + , CRSMatrix< TestString, COL_TYPE, INDEX_TYPE, MallocBuffer > +#if defined(USE_CHAI) + , CRSMatrix< int, COL_TYPE, INDEX_TYPE, NewChaiBuffer > + , CRSMatrix< Tensor, COL_TYPE, INDEX_TYPE, NewChaiBuffer > + , CRSMatrix< TestString, COL_TYPE, INDEX_TYPE, NewChaiBuffer > +#endif >; -TYPED_TEST_SUITE( CRSMatrixTest, TestTypes, ); +TYPED_TEST_SUITE( CRSMatrixTest, CRSMatrixTestTypes, ); const int DEFAULT_NROWS = 25; const int DEFAULT_NCOLS = 40; @@ -570,7 +559,7 @@ const int DEFAULT_MAX_INSERTS = DEFAULT_NCOLS / 2; TYPED_TEST( CRSMatrixTest, construction ) { - CRSMatrix< TypeParam > m( DEFAULT_NROWS, DEFAULT_NCOLS ); + TypeParam m( DEFAULT_NROWS, DEFAULT_NCOLS ); EXPECT_EQ( m.numRows(), DEFAULT_NROWS ); EXPECT_EQ( m.numColumns(), DEFAULT_NCOLS ); EXPECT_EQ( m.numNonZeros(), 0 ); @@ -585,14 +574,14 @@ TYPED_TEST( CRSMatrixTest, construction ) COL_TYPE const * const columns = m.getColumns( row ); EXPECT_EQ( columns, nullptr ); - TypeParam const * const entries = m.getEntries( row ); + auto const * const entries = m.getEntries( row ).dataIfContiguous(); EXPECT_EQ( entries, nullptr ); } } TYPED_TEST( CRSMatrixTest, hintConstruction ) { - CRSMatrix< TypeParam > m( DEFAULT_NROWS, DEFAULT_NCOLS, 5 ); + TypeParam m( DEFAULT_NROWS, DEFAULT_NCOLS, 5 ); EXPECT_EQ( m.numRows(), DEFAULT_NROWS ); EXPECT_EQ( m.numColumns(), DEFAULT_NCOLS ); EXPECT_EQ( m.numNonZeros(), 0 ); @@ -608,7 +597,7 @@ TYPED_TEST( CRSMatrixTest, hintConstruction ) COL_TYPE const * const columns = m.getColumns( row ); ASSERT_NE( columns, nullptr ); - TypeParam const * const entries = m.getEntries( row ); + auto const * const entries = m.getEntries( row ).dataIfContiguous(); ASSERT_NE( entries, nullptr ); } } @@ -673,16 +662,32 @@ TYPED_TEST( CRSMatrixTest, compress ) this->compress(); } -template< typename POLICY_VALUE_PAIR > -class CRSMatrixViewTest : public CRSMatrixTest< typename POLICY_VALUE_PAIR::second_type > +template< typename CRS_MATRIX_POLICY_PAIR > +class CRSMatrixViewTest : public CRSMatrixTest< typename CRS_MATRIX_POLICY_PAIR::first_type > { public: - using Policy = typename POLICY_VALUE_PAIR::first_type; - using T = typename POLICY_VALUE_PAIR::second_type; + using CRS_MATRIX = typename CRS_MATRIX_POLICY_PAIR::first_type; + using POLICY = typename CRS_MATRIX_POLICY_PAIR::second_type; + + using ParentClass = CRSMatrixTest< CRS_MATRIX >; + + using typename ParentClass::T; + using typename ParentClass::ViewType; + using typename ParentClass::ViewTypeConstSizes; + using typename ParentClass::ViewTypeConst; + + template< typename U > + using ArrayOfArraysT = typename ArrayConverter< CRS_MATRIX >::template ArrayOfArrays< U >; + + template< typename U, bool CONST_SIZES > + using ArrayOfArraysViewT = typename ArrayConverter< CRS_MATRIX >::template ArrayOfArraysView< U, CONST_SIZES >; + + using SparsityPatternViewT = typename ArrayConverter< CRS_MATRIX >::template SparsityPatternView< COL_TYPE const >; + CRSMatrixViewTest(): - CRSMatrixTest< T >(), + ParentClass(), m_view( this->m_matrix.toView() ) {}; @@ -695,7 +700,7 @@ class CRSMatrixViewTest : public CRSMatrixTest< typename POLICY_VALUE_PAIR::seco // Check that the columns and entries have been updated. INDEX_TYPE curIndex = 0; - CRSMatrixView< T, COL_TYPE, INDEX_TYPE const > const & view = m_view; + ViewType const & view = m_view; forall< serialPolicy >( m_view.numRows(), [view, &curIndex]( INDEX_TYPE row ) { @@ -710,7 +715,7 @@ class CRSMatrixViewTest : public CRSMatrixTest< typename POLICY_VALUE_PAIR::seco { memoryMotionInit(); - this->m_matrix.move( chai::CPU ); + this->m_matrix.move( MemorySpace::CPU ); INDEX_TYPE curIndex = 0; for( INDEX_TYPE row = 0; row < m_view.numRows(); ++row ) { @@ -727,21 +732,21 @@ class CRSMatrixViewTest : public CRSMatrixTest< typename POLICY_VALUE_PAIR::seco INDEX_TYPE const numCols = m_view.numColumns(); // Capture a view with const columns on device and update the entries. - CRSMatrixView< T, COL_TYPE const, INDEX_TYPE const > const & view = m_view.toViewConstSizes(); - forall< Policy >( numRows, + ViewTypeConstSizes const & view = m_view.toViewConstSizes(); + forall< POLICY >( numRows, [view, numCols] LVARRAY_HOST_DEVICE ( INDEX_TYPE row ) { COL_TYPE const * const columns = view.getColumns( row ); T * const entries = view.getEntries( row ); for( INDEX_TYPE i = 0; i < view.numNonZeros( row ); ++i ) { - LVARRAY_ERROR_IF( !arrayManipulation::isPositive( columns[i] ) || columns[i] >= numCols, "Invalid column." ); - entries[i] = T( 2 * i + 7 ); + LVARRAY_ERROR_IF( !arrayManipulation::isPositive( columns[ i ] ) || columns[ i ] >= numCols, "Invalid column." ); + entries[ i ] = T( 2 * i + 7 ); } } ); // This should copy back the entries but not the columns. - this->m_matrix.move( chai::CPU ); + this->m_matrix.move( MemorySpace::CPU ); for( INDEX_TYPE row = 0; row < numRows; ++row ) { ASSERT_EQ( m_view.numNonZeros( row ), this->m_ref[row].size()); @@ -750,9 +755,9 @@ class CRSMatrixViewTest : public CRSMatrixTest< typename POLICY_VALUE_PAIR::seco for( INDEX_TYPE i = 0; i < m_view.numNonZeros( row ); ++i ) { // So the columns should be the same as the reference. - COL_TYPE const col = m_view.getColumns( row )[i]; + COL_TYPE const col = m_view.getColumns( row )[ i ]; EXPECT_EQ( col, it->first ); - EXPECT_EQ( m_view.getEntries( row )[i], T( 2 * i + 7 )); + EXPECT_EQ( m_view.getEntries( row )[ i ], T( 2 * i + 7 )); ++it; } } @@ -768,16 +773,16 @@ class CRSMatrixViewTest : public CRSMatrixTest< typename POLICY_VALUE_PAIR::seco INDEX_TYPE const numCols = m_view.numColumns(); // Capture a view with const columns and const values on device. - CRSMatrixView< T const, COL_TYPE const, INDEX_TYPE const > const & view = m_view.toViewConst(); - forall< Policy >( numRows, + ViewTypeConst const & view = m_view.toViewConst(); + forall< POLICY >( numRows, [view, numCols] LVARRAY_HOST_DEVICE ( INDEX_TYPE row ) { COL_TYPE const * const columns = view.getColumns( row ); T const * const entries = view.getEntries( row ); for( INDEX_TYPE i = 0; i < view.numNonZeros( row ); ++i ) { - LVARRAY_ERROR_IF( !arrayManipulation::isPositive( columns[i] ) || columns[i] >= numCols, "Invalid column." ); - LVARRAY_ERROR_IF( entries[i] != T( columns[i] ), "Incorrect value." ); + LVARRAY_ERROR_IF( !arrayManipulation::isPositive( columns[ i ] ) || columns[ i ] >= numCols, "Invalid column." ); + LVARRAY_ERROR_IF( entries[ i ] != T( columns[ i ] ), "Incorrect value." ); } } ); @@ -786,10 +791,10 @@ class CRSMatrixViewTest : public CRSMatrixTest< typename POLICY_VALUE_PAIR::seco this->insert( maxInserts ); // Move the matrix back to the host, this should copy nothing. - this->m_matrix.move( chai::CPU ); + this->m_matrix.move( MemorySpace::CPU ); // And therefore the matrix should still equal the reference. - COMPARE_TO_REFERENCE( m_view.toViewConst(), this->m_ref ); + COMPARE_TO_REFERENCE } /** @@ -802,8 +807,8 @@ class CRSMatrixViewTest : public CRSMatrixTest< typename POLICY_VALUE_PAIR::seco INDEX_TYPE const numRows = this->m_matrix.numRows(); // Create an Array of the columns and values to insert into each row. - ArrayOfArrays< COL_TYPE > const columnsToInsert = this->createArrayOfColumns( maxInserts, oneAtATime ); - ArrayOfArrays< T > const valuesToInsert = this->createArrayOfValues( columnsToInsert.toViewConst() ); + ArrayOfArraysT< COL_TYPE > const columnsToInsert = this->createArrayOfColumns( maxInserts, oneAtATime ); + ArrayOfArraysT< T > const valuesToInsert = this->createArrayOfValues( columnsToInsert.toViewConst() ); // Reserve space for the inserts for( INDEX_TYPE row = 0; row < numRows; ++row ) @@ -814,12 +819,12 @@ class CRSMatrixViewTest : public CRSMatrixTest< typename POLICY_VALUE_PAIR::seco // Insert the entries into the reference. this->insertIntoRef( columnsToInsert.toViewConst() ); - CRSMatrixView< T, COL_TYPE, INDEX_TYPE const > const & view = m_view; - ArrayOfArraysView< COL_TYPE const, INDEX_TYPE const, true > const & columnsView = columnsToInsert.toViewConst(); - ArrayOfArraysView< T const, INDEX_TYPE const, true > const & valuesView = valuesToInsert.toViewConst(); + ViewType const & view = m_view; + ArrayOfArraysViewT< COL_TYPE const, true > const & columnsView = columnsToInsert.toViewConst(); + ArrayOfArraysViewT< T const, true > const & valuesView = valuesToInsert.toViewConst(); if( oneAtATime ) { - forall< Policy >( numRows, + forall< POLICY >( numRows, [view, columnsView] LVARRAY_HOST_DEVICE ( INDEX_TYPE const row ) { INDEX_TYPE const initialNNZ = view.numNonZeros( row ); @@ -836,7 +841,7 @@ class CRSMatrixViewTest : public CRSMatrixTest< typename POLICY_VALUE_PAIR::seco } else { - forall< Policy >( numRows, + forall< POLICY >( numRows, [view, columnsView, valuesView] LVARRAY_HOST_DEVICE ( INDEX_TYPE const row ) { INDEX_TYPE const initialNNZ = view.numNonZeros( row ); @@ -849,8 +854,8 @@ class CRSMatrixViewTest : public CRSMatrixTest< typename POLICY_VALUE_PAIR::seco ); } - this->m_matrix.move( chai::CPU ); - COMPARE_TO_REFERENCE( m_view.toViewConst(), this->m_ref ); + this->m_matrix.move( MemorySpace::CPU ); + COMPARE_TO_REFERENCE } /** @@ -863,7 +868,7 @@ class CRSMatrixViewTest : public CRSMatrixTest< typename POLICY_VALUE_PAIR::seco INDEX_TYPE const numRows = m_view.numRows(); // Create an Array of the columns and values to insert into each row. - ArrayOfArrays< COL_TYPE > const columnsToRemove = this->createArrayOfColumns( maxRemoves, oneAtATime ); + ArrayOfArraysT< COL_TYPE > const columnsToRemove = this->createArrayOfColumns( maxRemoves, oneAtATime ); // Insert the entries into the reference. for( INDEX_TYPE i = 0; i < columnsToRemove.size(); ++i ) @@ -875,11 +880,11 @@ class CRSMatrixViewTest : public CRSMatrixTest< typename POLICY_VALUE_PAIR::seco } } - CRSMatrixView< T, COL_TYPE, INDEX_TYPE const > const & view = m_view; - ArrayOfArraysView< COL_TYPE const, INDEX_TYPE const, true > const & columnsView = columnsToRemove.toViewConst(); + ViewType const & view = m_view; + ArrayOfArraysViewT< COL_TYPE const, true > const & columnsView = columnsToRemove.toViewConst(); if( oneAtATime ) { - forall< Policy >( numRows, + forall< POLICY >( numRows, [view, columnsView] LVARRAY_HOST_DEVICE ( INDEX_TYPE row ) { INDEX_TYPE const initialNNZ = view.numNonZeros( row ); @@ -894,7 +899,7 @@ class CRSMatrixViewTest : public CRSMatrixTest< typename POLICY_VALUE_PAIR::seco } else { - forall< Policy >( numRows, + forall< POLICY >( numRows, [view, columnsView] LVARRAY_HOST_DEVICE ( INDEX_TYPE const row ) { INDEX_TYPE const initialNNZ = view.numNonZeros( row ); @@ -903,8 +908,8 @@ class CRSMatrixViewTest : public CRSMatrixTest< typename POLICY_VALUE_PAIR::seco } ); } - this->m_matrix.move( chai::CPU ); - COMPARE_TO_REFERENCE( m_view.toViewConst(), this->m_ref ); + this->m_matrix.move( MemorySpace::CPU ); + COMPARE_TO_REFERENCE } /** @@ -921,13 +926,13 @@ class CRSMatrixViewTest : public CRSMatrixTest< typename POLICY_VALUE_PAIR::seco COL_TYPE * const columnsNC = const_cast< COL_TYPE * >(columns); for( INDEX_TYPE i = 0; i < m_view.numNonZeros( row ); ++i ) { - columnsNC[i] = COL_TYPE( 2 * i ); + columnsNC[ i ] = COL_TYPE( 2 * i ); } } // Check that each row contains the even columns and no odd columns. - CRSMatrixView< T const, COL_TYPE const, INDEX_TYPE const > const & view = m_view.toViewConst(); - forall< Policy >( numRows, + ViewTypeConst const & view = m_view.toViewConst(); + forall< POLICY >( numRows, [view] LVARRAY_HOST_DEVICE ( INDEX_TYPE const row ) { for( INDEX_TYPE i = 0; i < view.numNonZeros( row ); ++i ) @@ -945,11 +950,11 @@ class CRSMatrixViewTest : public CRSMatrixTest< typename POLICY_VALUE_PAIR::seco { INDEX_TYPE const numRows = m_view.numRows(); - SparsityPatternView< COL_TYPE const, INDEX_TYPE const > const & spView = m_view.toSparsityPatternView(); + SparsityPatternViewT const & spView = m_view.toSparsityPatternView(); // Check that each row contains the even columns and no odd columns on device. - CRSMatrixView< T const, COL_TYPE const, INDEX_TYPE const > const & view = m_view.toViewConst(); - forall< Policy >( numRows, + ViewTypeConst const & view = m_view.toViewConst(); + forall< POLICY >( numRows, [spView, view] LVARRAY_HOST_DEVICE ( INDEX_TYPE const row ) { INDEX_TYPE const nnz = view.numNonZeros( row ); @@ -983,15 +988,15 @@ class CRSMatrixViewTest : public CRSMatrixTest< typename POLICY_VALUE_PAIR::seco T * const entries = m_view.getEntries( row ); for( INDEX_TYPE i = 0; i < m_view.numNonZeros( row ); ++i ) { - columnsNC[i] = curIndex; - entries[i] = T( curIndex++ ); + columnsNC[ i ] = curIndex; + entries[ i ] = T( curIndex++ ); } } // Capture the view on device and set the entries. Here the const cast is necessary // because we don't want to test the insert/remove methods on device yet. - CRSMatrixView< T, COL_TYPE, INDEX_TYPE const > const & view = m_view; - forall< Policy >( numRows, + ViewType const & view = m_view; + forall< POLICY >( numRows, [view] LVARRAY_HOST_DEVICE ( INDEX_TYPE const row ) { COL_TYPE const * const columns = view.getColumns( row ); @@ -999,8 +1004,8 @@ class CRSMatrixViewTest : public CRSMatrixTest< typename POLICY_VALUE_PAIR::seco T * const entries = view.getEntries( row ); for( INDEX_TYPE i = 0; i < view.numNonZeros( row ); ++i ) { - columnsNC[i] += columns[i]; - entries[i] += entries[i]; + columnsNC[ i ] += columns[ i ]; + entries[ i ] += entries[ i ]; } } ); @@ -1008,38 +1013,39 @@ class CRSMatrixViewTest : public CRSMatrixTest< typename POLICY_VALUE_PAIR::seco protected: - static void memoryMotionCheckRow( CRSMatrixView< T const, COL_TYPE const, INDEX_TYPE const > const & view, + static void memoryMotionCheckRow( ViewTypeConst const & view, INDEX_TYPE const row, INDEX_TYPE & curIndex ) { for( INDEX_TYPE i = 0; i < view.numNonZeros( row ); ++i ) { - EXPECT_EQ( COL_TYPE( curIndex ) * 2, view.getColumns( row )[i] ); + EXPECT_EQ( COL_TYPE( curIndex ) * 2, view.getColumns( row )[ i ] ); T expectedEntry( curIndex ); expectedEntry += T( curIndex ); - EXPECT_EQ( expectedEntry, view.getEntries( row )[i] ); + EXPECT_EQ( expectedEntry, view.getEntries( row )[ i ] ); ++curIndex; } } - CRSMatrixView< T, COL_TYPE, INDEX_TYPE const > const & m_view; + ViewType const & m_view; }; -using ViewTestTypes = ::testing::Types< - std::pair< serialPolicy, int > - , std::pair< serialPolicy, Tensor > - , std::pair< serialPolicy, TestString > -#if defined(USE_OPENMP) - , std::pair< parallelHostPolicy, int > - , std::pair< parallelHostPolicy, Tensor > - , std::pair< parallelHostPolicy, TestString > +using CRSMatrixViewTestTypes = ::testing::Types< + std::pair< CRSMatrix< int, COL_TYPE, INDEX_TYPE, MallocBuffer >, serialPolicy > + , std::pair< CRSMatrix< Tensor, COL_TYPE, INDEX_TYPE, MallocBuffer >, serialPolicy > + , std::pair< CRSMatrix< TestString, COL_TYPE, INDEX_TYPE, MallocBuffer >, serialPolicy > +#if defined(USE_CHAI) + , std::pair< CRSMatrix< int, COL_TYPE, INDEX_TYPE, NewChaiBuffer >, serialPolicy > + , std::pair< CRSMatrix< Tensor, COL_TYPE, INDEX_TYPE, NewChaiBuffer >, serialPolicy > + , std::pair< CRSMatrix< TestString, COL_TYPE, INDEX_TYPE, NewChaiBuffer >, serialPolicy > #endif -#if defined(USE_CUDA) - , std::pair< parallelDevicePolicy< 256 >, int > - , std::pair< parallelDevicePolicy< 256 >, Tensor > + +#if defined(USE_CUDA) && defined(USE_CHAI) + , std::pair< CRSMatrix< int, COL_TYPE, INDEX_TYPE, NewChaiBuffer >, parallelDevicePolicy< 32 > > + , std::pair< CRSMatrix< Tensor, COL_TYPE, INDEX_TYPE, NewChaiBuffer >, parallelDevicePolicy< 32 > > #endif >; -TYPED_TEST_SUITE( CRSMatrixViewTest, ViewTestTypes, ); +TYPED_TEST_SUITE( CRSMatrixViewTest, CRSMatrixViewTestTypes, ); TYPED_TEST( CRSMatrixViewTest, memoryMotion ) { @@ -1125,13 +1131,26 @@ TYPED_TEST( CRSMatrixViewTest, sparsityPatternView ) this->sparsityPatternViewTest(); } -template< typename POLICY_VALUE_PAIR > -class CRSMatrixViewAtomicTest : public CRSMatrixViewTest< POLICY_VALUE_PAIR > +template< typename CRS_MATRIX_POLICY_PAIR > +class CRSMatrixViewAtomicTest : public CRSMatrixViewTest< CRS_MATRIX_POLICY_PAIR > { public: - using Policy = typename POLICY_VALUE_PAIR::first_type; - using AtomicPolicy = typename RAJAHelper< Policy >::AtomicPolicy; - using T = typename POLICY_VALUE_PAIR::second_type; + using CRS_MATRIX = typename CRS_MATRIX_POLICY_PAIR::first_type; + using POLICY = typename CRS_MATRIX_POLICY_PAIR::second_type; + using AtomicPolicy = typename RAJAHelper< POLICY >::AtomicPolicy; + + using ParentClass = CRSMatrixViewTest< CRS_MATRIX_POLICY_PAIR >; + + using typename ParentClass::T; + using typename ParentClass::ViewType; + using typename ParentClass::ViewTypeConstSizes; + using typename ParentClass::ViewTypeConst; + + template< typename U > + using ArrayOfArraysT = typename ArrayConverter< CRS_MATRIX >::template ArrayOfArrays< U >; + + template< typename U, bool CONST_SIZES > + using ArrayOfArraysViewT = typename ArrayConverter< CRS_MATRIX >::template ArrayOfArraysView< U, CONST_SIZES >; void addToRow( AddType const type, INDEX_TYPE const nThreads ) { @@ -1142,7 +1161,7 @@ class CRSMatrixViewAtomicTest : public CRSMatrixViewTest< POLICY_VALUE_PAIR > INDEX_TYPE const nColsInRow = m_view.numNonZeros( row ); // Array that holds the columns each thread will add to in the current row. - ArrayOfArrays< COL_TYPE > columns; + ArrayOfArraysT< COL_TYPE > columns; for( INDEX_TYPE threadID = 0; threadID < nThreads; ++threadID ) { INDEX_TYPE const nColsToAddTo = this->rand( nColsInRow ); @@ -1160,13 +1179,13 @@ class CRSMatrixViewAtomicTest : public CRSMatrixViewTest< POLICY_VALUE_PAIR > for( INDEX_TYPE threadID = 0; threadID < nThreads; ++threadID ) { INDEX_TYPE const numUniqueCols = - sortedArrayManipulation::makeSortedUnique( columns.getIterableArray( threadID ).begin(), columns.getIterableArray( threadID ).end() ); + sortedArrayManipulation::makeSortedUnique( columns[ threadID ].begin(), columns[ threadID ].end() ); columns.resizeArray( threadID, numUniqueCols ); } } // Array that holds the values each thread will add to in the current row. - ArrayOfArrays< T > values; + ArrayOfArraysT< T > values; for( INDEX_TYPE threadID = 0; threadID < nThreads; ++threadID ) { INDEX_TYPE const nColsToAddTo = columns.sizeOfArray( threadID ); @@ -1180,61 +1199,77 @@ class CRSMatrixViewAtomicTest : public CRSMatrixViewTest< POLICY_VALUE_PAIR > } } - CRSMatrixView< T, COL_TYPE const, INDEX_TYPE const > const & view = m_view.toViewConstSizes(); - ArrayOfArraysView< COL_TYPE const, INDEX_TYPE const, true > colView = columns.toViewConst(); - ArrayOfArraysView< T const, INDEX_TYPE const, true > valView = values.toViewConst(); + ViewTypeConstSizes const & view = m_view.toViewConstSizes(); + ArrayOfArraysViewT< COL_TYPE const, true > colView = columns.toViewConst(); + ArrayOfArraysViewT< T const, true > valView = values.toViewConst(); - if( type == AddType::LINEAR_SEARCH ) - { - forall< Policy >( nThreads, [view, colView, valView, row] LVARRAY_HOST_DEVICE ( INDEX_TYPE const threadID ) + forall< POLICY >( nThreads, [type, row, view, colView, valView] LVARRAY_HOST_DEVICE ( INDEX_TYPE const threadID ) + { + if( type == AddType::LINEAR_SEARCH ) { - view.template addToRowLinearSearch< AtomicPolicy >( row, colView[ threadID ], valView[ threadID ], colView.sizeOfArray( threadID ) ); - } ); - } - if( type == AddType::BINARY_SEARCH ) - { - forall< Policy >( nThreads, [view, colView, valView, row] LVARRAY_HOST_DEVICE ( INDEX_TYPE const threadID ) + view.template addToRowLinearSearch< AtomicPolicy >( row, + colView[ threadID ], + valView[ threadID ], + colView.sizeOfArray( threadID ) ); + } + if( type == AddType::BINARY_SEARCH ) { - view.template addToRowBinarySearch< AtomicPolicy >( row, colView[ threadID ], valView[ threadID ], colView.sizeOfArray( threadID ) ); - } ); - } - if( type == AddType::HYBRID ) - { - forall< Policy >( nThreads, [view, colView, valView, row] LVARRAY_HOST_DEVICE ( INDEX_TYPE const threadID ) + view.template addToRowBinarySearch< AtomicPolicy >( row, + colView[ threadID ], + valView[ threadID ], + colView.sizeOfArray( threadID ) ); + } + if( type == AddType::HYBRID ) { - view.template addToRow< AtomicPolicy >( row, colView[ threadID ], valView[ threadID ], colView.sizeOfArray( threadID ) ); - } ); - } - if( type == AddType::UNSORTED_BINARY ) - { - forall< Policy >( nThreads, [view, colView, valView, row] LVARRAY_HOST_DEVICE ( INDEX_TYPE const threadID ) + view.template addToRow< AtomicPolicy >( row, + colView[ threadID ], + valView[ threadID ], + colView.sizeOfArray( threadID ) ); + } + if( type == AddType::UNSORTED_BINARY ) { - view.template addToRowBinarySearchUnsorted< AtomicPolicy >( row, colView[ threadID ], valView[ threadID ], colView.sizeOfArray( threadID ) ); - } ); - } + view.template addToRowBinarySearchUnsorted< AtomicPolicy >( row, + colView[ threadID ], + valView[ threadID ], + colView.sizeOfArray( threadID ) ); + } + } ); } - this->m_matrix.move( chai::CPU ); - COMPARE_TO_REFERENCE( m_view.toViewConst(), this->m_ref ); + this->m_matrix.move( MemorySpace::CPU ); + COMPARE_TO_REFERENCE } protected: - using CRSMatrixViewTest< POLICY_VALUE_PAIR >::m_view; + using CRSMatrixViewTest< CRS_MATRIX_POLICY_PAIR >::m_view; }; -using ViewAtomicTestTypes = ::testing::Types< - std::pair< serialPolicy, int > - , std::pair< serialPolicy, Tensor > - , std::pair< serialPolicy, TestString > +using CRSMatrixViewAtomicTestTypes = ::testing::Types< + std::pair< CRSMatrix< int, COL_TYPE, INDEX_TYPE, MallocBuffer >, serialPolicy > + , std::pair< CRSMatrix< Tensor, COL_TYPE, INDEX_TYPE, MallocBuffer >, serialPolicy > + , std::pair< CRSMatrix< TestString, COL_TYPE, INDEX_TYPE, MallocBuffer >, serialPolicy > +#if defined(USE_CHAI) + , std::pair< CRSMatrix< int, COL_TYPE, INDEX_TYPE, NewChaiBuffer >, serialPolicy > + , std::pair< CRSMatrix< Tensor, COL_TYPE, INDEX_TYPE, NewChaiBuffer >, serialPolicy > + , std::pair< CRSMatrix< TestString, COL_TYPE, INDEX_TYPE, NewChaiBuffer >, serialPolicy > +#endif + #if defined(USE_OPENMP) - , std::pair< parallelHostPolicy, int > + , std::pair< CRSMatrix< int, COL_TYPE, INDEX_TYPE, MallocBuffer >, parallelHostPolicy > + , std::pair< CRSMatrix< double, COL_TYPE, INDEX_TYPE, MallocBuffer >, parallelHostPolicy > #endif -#if defined(USE_CUDA) - , std::pair< parallelDevicePolicy< 256 >, int > +#if defined(USE_OPENMP) && defined(USE_CHAI) + , std::pair< CRSMatrix< int, COL_TYPE, INDEX_TYPE, NewChaiBuffer >, parallelHostPolicy > + , std::pair< CRSMatrix< double, COL_TYPE, INDEX_TYPE, NewChaiBuffer >, parallelHostPolicy > +#endif + +#if defined(USE_CUDA) && defined(USE_CHAI) + , std::pair< CRSMatrix< int, COL_TYPE, INDEX_TYPE, NewChaiBuffer >, parallelDevicePolicy< 32 > > + , std::pair< CRSMatrix< double, COL_TYPE, INDEX_TYPE, NewChaiBuffer >, parallelDevicePolicy< 32 > > #endif >; -TYPED_TEST_SUITE( CRSMatrixViewAtomicTest, ViewAtomicTestTypes, ); +TYPED_TEST_SUITE( CRSMatrixViewAtomicTest, CRSMatrixViewAtomicTestTypes, ); TYPED_TEST( CRSMatrixViewAtomicTest, addToRowLinearSearch ) { diff --git a/unitTests/testSliceHelpers.cpp b/unitTests/testSliceHelpers.cpp index b9a1a600..f7fd1650 100644 --- a/unitTests/testSliceHelpers.cpp +++ b/unitTests/testSliceHelpers.cpp @@ -16,10 +16,11 @@ *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -/// Source includes +// Source includes #include "Array.hpp" +#include "testUtils.hpp" -/// TPL inclues +// TPL inclues #include namespace LvArray @@ -27,23 +28,28 @@ namespace LvArray namespace testing { +using INDEX_TYPE = std::ptrdiff_t; + +template< typename T, typename PERMUTATION > +using ArrayT = Array< T, getDimension( PERMUTATION {} ), PERMUTATION, INDEX_TYPE, DEFAULT_BUFFER >; + template< typename T > -void check( ArraySlice< T const, 1, 0 > const & view ) +void check( ArraySlice< T const, 1, 0, INDEX_TYPE > const & view ) { - std::ptrdiff_t offset = 0; - for( std::ptrdiff_t i = 0; i < view.size( 0 ); ++i ) + INDEX_TYPE offset = 0; + for( INDEX_TYPE i = 0; i < view.size( 0 ); ++i ) { EXPECT_EQ( view( i ), offset++ ); } } template< typename T, int USD > -void check( ArraySlice< T const, 2, USD > const & view ) +void check( ArraySlice< T const, 2, USD, INDEX_TYPE > const & view ) { - std::ptrdiff_t offset = 0; - for( std::ptrdiff_t i = 0; i < view.size( 0 ); ++i ) + INDEX_TYPE offset = 0; + for( INDEX_TYPE i = 0; i < view.size( 0 ); ++i ) { - for( std::ptrdiff_t j = 0; j < view.size( 1 ); ++j ) + for( INDEX_TYPE j = 0; j < view.size( 1 ); ++j ) { EXPECT_EQ( view( i, j ), offset++ ); } @@ -51,14 +57,14 @@ void check( ArraySlice< T const, 2, USD > const & view ) } template< typename T, int USD > -void check( ArraySlice< T const, 3, USD > const & view ) +void check( ArraySlice< T const, 3, USD, INDEX_TYPE > const & view ) { - std::ptrdiff_t offset = 0; - for( std::ptrdiff_t i = 0; i < view.size( 0 ); ++i ) + INDEX_TYPE offset = 0; + for( INDEX_TYPE i = 0; i < view.size( 0 ); ++i ) { - for( std::ptrdiff_t j = 0; j < view.size( 1 ); ++j ) + for( INDEX_TYPE j = 0; j < view.size( 1 ); ++j ) { - for( std::ptrdiff_t k = 0; k < view.size( 2 ); ++k ) + for( INDEX_TYPE k = 0; k < view.size( 2 ); ++k ) { EXPECT_EQ( view( i, j, k ), offset++ ); } @@ -67,16 +73,16 @@ void check( ArraySlice< T const, 3, USD > const & view ) } template< typename T, int USD > -void check( ArraySlice< T const, 4, USD > const & view ) +void check( ArraySlice< T const, 4, USD, INDEX_TYPE > const & view ) { - std::ptrdiff_t offset = 0; - for( std::ptrdiff_t i = 0; i < view.size( 0 ); ++i ) + INDEX_TYPE offset = 0; + for( INDEX_TYPE i = 0; i < view.size( 0 ); ++i ) { - for( std::ptrdiff_t j = 0; j < view.size( 1 ); ++j ) + for( INDEX_TYPE j = 0; j < view.size( 1 ); ++j ) { - for( std::ptrdiff_t k = 0; k < view.size( 2 ); ++k ) + for( INDEX_TYPE k = 0; k < view.size( 2 ); ++k ) { - for( std::ptrdiff_t l = 0; l < view.size( 3 ); ++l ) + for( INDEX_TYPE l = 0; l < view.size( 3 ); ++l ) { EXPECT_EQ( view( i, j, k, l ), offset++ ); } @@ -97,7 +103,7 @@ class ForValuesInSlice : public ::testing::Test check( m_array.toSliceConst() ); - std::ptrdiff_t offset = 0; + INDEX_TYPE offset = 0; forValuesInSlice( m_array.toSliceConst(), [&offset] ( auto const & val ) { EXPECT_EQ( val, offset++ ); @@ -113,7 +119,7 @@ class ForValuesInSlice : public ::testing::Test void initialize() { - std::ptrdiff_t dims[ NDIM ]; + INDEX_TYPE dims[ NDIM ]; for( int dim = 0; dim < NDIM; ++dim ) { dims[ dim ] = 10 + dim; @@ -121,7 +127,7 @@ class ForValuesInSlice : public ::testing::Test m_array.resize( NDIM, dims ); - std::ptrdiff_t offset = 0; + INDEX_TYPE offset = 0; forValuesInSlice( m_array.toSlice(), [&offset] ( auto & val ) { val = offset++; @@ -133,22 +139,22 @@ class ForValuesInSlice : public ::testing::Test using ForValuesInSliceTypes = ::testing::Types< // All 1D permutations - Array< int, 1 > + ArrayT< int, RAJA::PERM_I > // All 2D permutations - , Array< int, 2, RAJA::PERM_IJ > - , Array< int, 2, RAJA::PERM_JI > + , ArrayT< int, RAJA::PERM_IJ > + , ArrayT< int, RAJA::PERM_JI > // All 3D permutations - , Array< int, 3, RAJA::PERM_IJK > - , Array< int, 3, RAJA::PERM_IKJ > - , Array< int, 3, RAJA::PERM_JIK > - , Array< int, 3, RAJA::PERM_JKI > - , Array< int, 3, RAJA::PERM_KIJ > - , Array< int, 3, RAJA::PERM_KJI > + , ArrayT< int, RAJA::PERM_IJK > + , ArrayT< int, RAJA::PERM_IKJ > + , ArrayT< int, RAJA::PERM_JIK > + , ArrayT< int, RAJA::PERM_JKI > + , ArrayT< int, RAJA::PERM_KIJ > + , ArrayT< int, RAJA::PERM_KJI > // Some 4D permutations - , Array< int, 4, RAJA::PERM_IJKL > - , Array< int, 4, RAJA::PERM_LKJI > - , Array< int, 4, RAJA::PERM_IKLJ > - , Array< int, 4, RAJA::PERM_KLIJ > + , ArrayT< int, RAJA::PERM_IJKL > + , ArrayT< int, RAJA::PERM_LKJI > + , ArrayT< int, RAJA::PERM_IKLJ > + , ArrayT< int, RAJA::PERM_KLIJ > >; TYPED_TEST_SUITE( ForValuesInSlice, ForValuesInSliceTypes, ); @@ -171,12 +177,13 @@ TEST( ForValuesInSlice, scalar ) template< typename T, int USD_SRC > -void checkSums( ArraySlice< T const, 2, USD_SRC > const & src, ArraySlice< T const, 1, 0 > const & sums ) +void checkSums( ArraySlice< T const, 2, USD_SRC, INDEX_TYPE > const & src, + ArraySlice< T const, 1, 0, INDEX_TYPE > const & sums ) { - for( std::ptrdiff_t j = 0; j < src.size( 1 ); ++j ) + for( INDEX_TYPE j = 0; j < src.size( 1 ); ++j ) { T sum {}; - for( std::ptrdiff_t i = 0; i < src.size( 0 ); ++i ) + for( INDEX_TYPE i = 0; i < src.size( 0 ); ++i ) { sum += src( i, j ); } @@ -186,14 +193,15 @@ void checkSums( ArraySlice< T const, 2, USD_SRC > const & src, ArraySlice< T con } template< typename T, int USD_SRC, int USD_SUMS > -void checkSums( ArraySlice< T const, 3, USD_SRC > const & src, ArraySlice< T const, 2, USD_SUMS > const & sums ) +void checkSums( ArraySlice< T const, 3, USD_SRC, INDEX_TYPE > const & src, + ArraySlice< T const, 2, USD_SUMS, INDEX_TYPE > const & sums ) { - for( std::ptrdiff_t j = 0; j < src.size( 1 ); ++j ) + for( INDEX_TYPE j = 0; j < src.size( 1 ); ++j ) { - for( std::ptrdiff_t k = 0; k < src.size( 2 ); ++k ) + for( INDEX_TYPE k = 0; k < src.size( 2 ); ++k ) { T sum {}; - for( std::ptrdiff_t i = 0; i < src.size( 0 ); ++i ) + for( INDEX_TYPE i = 0; i < src.size( 0 ); ++i ) { sum += src( i, j, k ); } @@ -204,16 +212,17 @@ void checkSums( ArraySlice< T const, 3, USD_SRC > const & src, ArraySlice< T con } template< typename T, int USD_SRC, int USD_SUMS > -void checkSums( ArraySlice< T const, 4, USD_SRC > const & src, ArraySlice< T const, 3, USD_SUMS > const & sums ) +void checkSums( ArraySlice< T const, 4, USD_SRC, INDEX_TYPE > const & src, + ArraySlice< T const, 3, USD_SUMS, INDEX_TYPE > const & sums ) { - for( std::ptrdiff_t j = 0; j < src.size( 1 ); ++j ) + for( INDEX_TYPE j = 0; j < src.size( 1 ); ++j ) { - for( std::ptrdiff_t k = 0; k < src.size( 2 ); ++k ) + for( INDEX_TYPE k = 0; k < src.size( 2 ); ++k ) { - for( std::ptrdiff_t l = 0; l < src.size( 3 ); ++l ) + for( INDEX_TYPE l = 0; l < src.size( 3 ); ++l ) { T sum {}; - for( std::ptrdiff_t i = 0; i < src.size( 0 ); ++i ) + for( INDEX_TYPE i = 0; i < src.size( 0 ); ++i ) { sum += src( i, j, k, l ); } @@ -237,8 +246,8 @@ class SumOverFirstDimension : public ForValuesInSlice< typename ARRAY_PERM_PAIR: void test() { this->initialize(); - std::ptrdiff_t dims[ NDIM - 1 ]; - for( std::ptrdiff_t dim = 0; dim < NDIM - 1; ++dim ) + INDEX_TYPE dims[ NDIM - 1 ]; + for( INDEX_TYPE dim = 0; dim < NDIM - 1; ++dim ) { dims[ dim ] = this->m_array.size( dim + 1 ); } @@ -251,34 +260,34 @@ class SumOverFirstDimension : public ForValuesInSlice< typename ARRAY_PERM_PAIR: } private: - Array< T, NDIM - 1, PERM > m_sums; + ArrayT< T, PERM > m_sums; }; using SumOverFirstDimensionTypes = ::testing::Types< // All 2D permutations by all 1D permutations - std::pair< Array< int, 2, RAJA::PERM_IJ >, RAJA::PERM_I > - , std::pair< Array< int, 2, RAJA::PERM_IJ >, RAJA::PERM_I > + std::pair< ArrayT< int, RAJA::PERM_IJ >, RAJA::PERM_I > + , std::pair< ArrayT< int, RAJA::PERM_IJ >, RAJA::PERM_I > // All 3D permutations by RAJA::PERM_IJ - , std::pair< Array< int, 3, RAJA::PERM_IJK >, RAJA::PERM_IJ > - , std::pair< Array< int, 3, RAJA::PERM_IKJ >, RAJA::PERM_IJ > - , std::pair< Array< int, 3, RAJA::PERM_JIK >, RAJA::PERM_IJ > - , std::pair< Array< int, 3, RAJA::PERM_JKI >, RAJA::PERM_IJ > - , std::pair< Array< int, 3, RAJA::PERM_KIJ >, RAJA::PERM_IJ > - , std::pair< Array< int, 3, RAJA::PERM_KJI >, RAJA::PERM_IJ > + , std::pair< ArrayT< int, RAJA::PERM_IJK >, RAJA::PERM_IJ > + , std::pair< ArrayT< int, RAJA::PERM_IKJ >, RAJA::PERM_IJ > + , std::pair< ArrayT< int, RAJA::PERM_JIK >, RAJA::PERM_IJ > + , std::pair< ArrayT< int, RAJA::PERM_JKI >, RAJA::PERM_IJ > + , std::pair< ArrayT< int, RAJA::PERM_KIJ >, RAJA::PERM_IJ > + , std::pair< ArrayT< int, RAJA::PERM_KJI >, RAJA::PERM_IJ > // All 3D permutations by RAJA::PERM_JI - , std::pair< Array< int, 3, RAJA::PERM_IJK >, RAJA::PERM_JI > - , std::pair< Array< int, 3, RAJA::PERM_IKJ >, RAJA::PERM_JI > - , std::pair< Array< int, 3, RAJA::PERM_JIK >, RAJA::PERM_JI > - , std::pair< Array< int, 3, RAJA::PERM_JKI >, RAJA::PERM_JI > - , std::pair< Array< int, 3, RAJA::PERM_KIJ >, RAJA::PERM_JI > - , std::pair< Array< int, 3, RAJA::PERM_KJI >, RAJA::PERM_JI > + , std::pair< ArrayT< int, RAJA::PERM_IJK >, RAJA::PERM_JI > + , std::pair< ArrayT< int, RAJA::PERM_IKJ >, RAJA::PERM_JI > + , std::pair< ArrayT< int, RAJA::PERM_JIK >, RAJA::PERM_JI > + , std::pair< ArrayT< int, RAJA::PERM_JKI >, RAJA::PERM_JI > + , std::pair< ArrayT< int, RAJA::PERM_KIJ >, RAJA::PERM_JI > + , std::pair< ArrayT< int, RAJA::PERM_KJI >, RAJA::PERM_JI > // Some 4D permutations by some 3D permutations - , std::pair< Array< int, 4, RAJA::PERM_IJKL >, RAJA::PERM_IJK > - , std::pair< Array< int, 4, RAJA::PERM_LKJI >, RAJA::PERM_KJI > - , std::pair< Array< int, 4, RAJA::PERM_JKIL >, RAJA::PERM_JIK > - , std::pair< Array< int, 4, RAJA::PERM_KILJ >, RAJA::PERM_IKJ > - , std::pair< Array< int, 4, RAJA::PERM_LJIK >, RAJA::PERM_KIJ > - , std::pair< Array< int, 4, RAJA::PERM_ILJK >, RAJA::PERM_IJK > + , std::pair< ArrayT< int, RAJA::PERM_IJKL >, RAJA::PERM_IJK > + , std::pair< ArrayT< int, RAJA::PERM_LKJI >, RAJA::PERM_KJI > + , std::pair< ArrayT< int, RAJA::PERM_JKIL >, RAJA::PERM_JIK > + , std::pair< ArrayT< int, RAJA::PERM_KILJ >, RAJA::PERM_IKJ > + , std::pair< ArrayT< int, RAJA::PERM_LJIK >, RAJA::PERM_KIJ > + , std::pair< ArrayT< int, RAJA::PERM_ILJK >, RAJA::PERM_IJK > >; TYPED_TEST_SUITE( SumOverFirstDimension, SumOverFirstDimensionTypes, ); @@ -290,10 +299,10 @@ TYPED_TEST( SumOverFirstDimension, test ) TEST( SumOverFirstDimension, OneDimensional ) { - std::ptrdiff_t const size = 10; - Array< int, 1 > array( size ); + INDEX_TYPE const size = 10; + ArrayT< int, RAJA::PERM_I > array( size ); - for( std::ptrdiff_t i = 0; i < size; ++i ) + for( INDEX_TYPE i = 0; i < size; ++i ) { array( i ) = i + 1; } diff --git a/unitTests/testSortedArray.cpp b/unitTests/testSortedArray.cpp index 0dbd5010..50f4719e 100644 --- a/unitTests/testSortedArray.cpp +++ b/unitTests/testSortedArray.cpp @@ -19,14 +19,11 @@ // Source includes #include "SortedArray.hpp" #include "testUtils.hpp" +#include "MallocBuffer.hpp" // TPL includes #include -#if defined(USE_CHAI) && defined(USE_CUDA) - #include -#endif - // System includes #include #include @@ -39,40 +36,39 @@ namespace testing using INDEX_TYPE = std::ptrdiff_t; -/** - * @brief Check that the SortedArrayView is equivalent to the std::set. Checks equality using the - * operator[] and the raw pointer. - * @param [in] set the SortedArrayView to check. - * @param [in] ref the std::set to check against. - */ -template< class T > -void compareToReference( SortedArrayView< T const > const & set, const std::set< T > & ref ) +template< typename SORTED_ARRAY > +class SortedArrayTest : public ::testing::Test { - ASSERT_EQ( set.size(), ref.size() ); - ASSERT_EQ( set.empty(), ref.empty() ); - if( set.empty() ) - { - ASSERT_EQ( set.size(), 0 ); - return; - } +public: + + using T = typename SORTED_ARRAY::value_type; - T const * ptr = set.data(); - typename std::set< T >::const_iterator it = ref.begin(); - for( int i = 0; i < set.size(); ++i ) + /** + * @brief Check that the SortedArrayView is equivalent to the std::set. Checks equality using the + * operator[] and the raw pointer. + */ + void compareToReference() const { - ASSERT_EQ( set[ i ], *it ); - ASSERT_EQ( ptr[ i ], *it ); - ++it; - } -} + ASSERT_EQ( m_set.size(), m_ref.size() ); + ASSERT_EQ( m_set.empty(), m_ref.empty() ); + if( m_set.empty() ) + { + ASSERT_EQ( m_set.size(), 0 ); + return; + } -#define COMPARE_TO_REFERENCE( set, ref ) { SCOPED_TRACE( "" ); compareToReference( set, ref ); \ -} + T const * ptr = m_set.data(); + typename std::set< T >::const_iterator it = m_ref.begin(); + for( int i = 0; i < m_set.size(); ++i ) + { + ASSERT_EQ( m_set[ i ], *it ); + ASSERT_EQ( ptr[ i ], *it ); + ++it; + } + } -template< typename T > -class SortedArrayTest : public ::testing::Test -{ -public: + #define COMPARE_TO_REFERENCE { SCOPED_TRACE( "" ); compareToReference(); \ + } /** * @brief Test the insert method of the SortedArray. @@ -81,7 +77,7 @@ class SortedArrayTest : public ::testing::Test */ void insertTest( INDEX_TYPE const maxInserts, INDEX_TYPE const maxVal ) { - COMPARE_TO_REFERENCE( m_set.toView(), m_ref ); + COMPARE_TO_REFERENCE for( INDEX_TYPE i = 0; i < maxInserts; ++i ) { @@ -89,7 +85,7 @@ class SortedArrayTest : public ::testing::Test ASSERT_EQ( m_ref.insert( value ).second, m_set.insert( value )); } - COMPARE_TO_REFERENCE( m_set.toView(), m_ref ); + COMPARE_TO_REFERENCE } /** @@ -99,17 +95,17 @@ class SortedArrayTest : public ::testing::Test */ void insertMultipleTest( INDEX_TYPE maxInserts, INDEX_TYPE const maxVal ) { - COMPARE_TO_REFERENCE( m_set.toView(), m_ref ); + COMPARE_TO_REFERENCE // Divide maxInserts by two since we insert with both a std::vector and std::set. - maxInserts /= 2; + maxInserts /= 2; // Insert values from a std::vector { std::vector< T > values( maxInserts ); for( INDEX_TYPE i = 0; i < maxInserts; ++i ) - { values[i] = randVal( maxVal ); } + { values[ i ] = randVal( maxVal ); } m_ref.insert( values.begin(), values.end() ); @@ -117,7 +113,7 @@ class SortedArrayTest : public ::testing::Test values.resize( numUniqueValues ); m_set.insert( values.begin(), values.end() ); - COMPARE_TO_REFERENCE( m_set.toView(), m_ref ); + COMPARE_TO_REFERENCE } // Insert values from a std::set @@ -128,7 +124,7 @@ class SortedArrayTest : public ::testing::Test m_ref.insert( values.begin(), values.end() ); m_set.insert( values.begin(), values.end() ); - COMPARE_TO_REFERENCE( m_set.toView(), m_ref ); + COMPARE_TO_REFERENCE } } @@ -139,7 +135,7 @@ class SortedArrayTest : public ::testing::Test */ void removeTest( INDEX_TYPE const maxRemoves, INDEX_TYPE const maxVal ) { - COMPARE_TO_REFERENCE( m_set.toView(), m_ref ); + COMPARE_TO_REFERENCE for( INDEX_TYPE i = 0; i < maxRemoves; ++i ) { @@ -147,7 +143,7 @@ class SortedArrayTest : public ::testing::Test ASSERT_EQ( m_ref.erase( value ), m_set.remove( value ) ); } - COMPARE_TO_REFERENCE( m_set.toView(), m_ref ); + COMPARE_TO_REFERENCE } /** @@ -157,10 +153,10 @@ class SortedArrayTest : public ::testing::Test */ void removeMultipleTest( INDEX_TYPE maxRemoves, INDEX_TYPE const maxVal ) { - COMPARE_TO_REFERENCE( m_set.toView(), m_ref ); + COMPARE_TO_REFERENCE // Divide maxInserts by two since we insert with both a std::vector and std::set. - maxRemoves /= 2; + maxRemoves /= 2; // Remove values from a std::vector { @@ -177,7 +173,7 @@ class SortedArrayTest : public ::testing::Test m_set.remove( values.begin(), values.end() ); - COMPARE_TO_REFERENCE( m_set.toView(), m_ref ); + COMPARE_TO_REFERENCE } // Remove values from a std::set @@ -192,7 +188,7 @@ class SortedArrayTest : public ::testing::Test m_set.remove( values.begin(), values.end() ); - COMPARE_TO_REFERENCE( m_set.toView(), m_ref ); + COMPARE_TO_REFERENCE } } @@ -201,7 +197,7 @@ class SortedArrayTest : public ::testing::Test */ void containsTest() const { - COMPARE_TO_REFERENCE( m_set.toView(), m_ref ); + COMPARE_TO_REFERENCE auto it = m_ref.begin(); for( INDEX_TYPE i = 0; i < m_set.size(); ++i ) @@ -218,11 +214,11 @@ class SortedArrayTest : public ::testing::Test */ void deepCopyTest() const { - COMPARE_TO_REFERENCE( m_set.toView(), m_ref ); + COMPARE_TO_REFERENCE INDEX_TYPE const N = m_set.size(); - SortedArray< T > v_cpy( m_set ); + SORTED_ARRAY v_cpy( m_set ); ASSERT_EQ( N, v_cpy.size()); T const * const vals = m_set.data(); @@ -232,15 +228,15 @@ class SortedArrayTest : public ::testing::Test // Iterate backwards and erase entries from v_cpy. for( INDEX_TYPE i = N - 1; i >= 0; --i ) { - EXPECT_EQ( vals[i], vals_cpy[i] ); - v_cpy.remove( vals_cpy[i] ); + EXPECT_EQ( vals[ i ], vals_cpy[ i ] ); + v_cpy.remove( vals_cpy[ i ] ); } EXPECT_EQ( v_cpy.size(), 0 ); EXPECT_EQ( m_set.size(), N ); // check that v is still the same as m_ref. - COMPARE_TO_REFERENCE( m_set.toView(), m_ref ); + COMPARE_TO_REFERENCE } protected: @@ -248,14 +244,23 @@ class SortedArrayTest : public ::testing::Test T randVal( INDEX_TYPE const max ) { return T( std::uniform_int_distribution< INDEX_TYPE >( 0, max )( m_gen ) ); } - SortedArray< T > m_set; + SORTED_ARRAY m_set; std::set< T > m_ref; std::mt19937_64 m_gen; }; -using TestTypes = ::testing::Types< int, Tensor, TestString >; +using TestTypes = ::testing::Types< + SortedArray< int, INDEX_TYPE, MallocBuffer > + , SortedArray< Tensor, INDEX_TYPE, MallocBuffer > + , SortedArray< TestString, INDEX_TYPE, MallocBuffer > +#if defined(USE_CHAI) + , SortedArray< int, INDEX_TYPE, NewChaiBuffer > + , SortedArray< Tensor, INDEX_TYPE, NewChaiBuffer > + , SortedArray< TestString, INDEX_TYPE, NewChaiBuffer > +#endif + >; TYPED_TEST_SUITE( SortedArrayTest, TestTypes, ); INDEX_TYPE const DEFAULT_MAX_INSERTS = 200; @@ -272,7 +277,7 @@ TYPED_TEST( SortedArrayTest, insert ) TYPED_TEST( SortedArrayTest, reserve ) { this->m_set.reserve( DEFAULT_MAX_VAL + 1 ); - TypeParam const * const ptr = this->m_set.data(); + auto const * const ptr = this->m_set.data(); for( int i = 0; i < 4; ++i ) { @@ -320,13 +325,20 @@ TYPED_TEST( SortedArrayTest, deepCopy ) this->deepCopyTest(); } -#ifdef USE_CUDA -template< typename T > -class SortedArrayCudaTest : public SortedArrayTest< T > +template< typename SORTED_ARRAY_POLICY_PAIR > +class SortedArrayViewTest : public SortedArrayTest< typename SORTED_ARRAY_POLICY_PAIR::first_type > { public: + using SORTED_ARRAY = typename SORTED_ARRAY_POLICY_PAIR::first_type; + using POLICY = typename SORTED_ARRAY_POLICY_PAIR::second_type; + + using T = typename SORTED_ARRAY::value_type; + using ParentClass = SortedArrayTest< SORTED_ARRAY >; + + using ViewType = std::remove_const_t< typename SORTED_ARRAY::ViewType >; + /** * @brief Test the SortedArrayView copy constructor in regards to memory motion. * @param [in] size the number of values to insert. @@ -344,12 +356,11 @@ class SortedArrayCudaTest : public SortedArrayTest< T > ASSERT_EQ( m_set.size(), size ); // Capture a view on the device. - forall( gpu(), 0, size, - [view = m_set.toView()] __device__ ( INDEX_TYPE i ) - { - LVARRAY_ERROR_IF( view[i] != T( i ), "Values changed when moved." ); - } - ); + ViewType const & view = m_set.toView(); + forall< POLICY >( size, [view] LVARRAY_HOST_DEVICE ( INDEX_TYPE const i ) + { + LVARRAY_ERROR_IF( view[ i ] != T( i ), "Values changed when moved." ); + } ); // Change the values. m_set.clear(); @@ -361,12 +372,10 @@ class SortedArrayCudaTest : public SortedArrayTest< T > ASSERT_EQ( m_set.size(), size ); // Capture the view on host and check that the values haven't been overwritten. - forall( sequential(), 0, size, - [view = m_set.toView()]( INDEX_TYPE i ) + forall< serialPolicy >( size, [view] ( INDEX_TYPE const i ) { - EXPECT_EQ( view[i], T( i * i )); - } - ); + EXPECT_EQ( view[ i ], T( i * i )); + } ); } /** @@ -385,28 +394,26 @@ class SortedArrayCudaTest : public SortedArrayTest< T > ASSERT_EQ( m_set.size(), size ); - // Capture a view on the device. - forall( gpu(), 0, size, - [view = m_set.toView()] __device__ ( INDEX_TYPE i ) - { - LVARRAY_ERROR_IF( view[i] != T( i ), "Values changed when moved." ); - } - ); + T const * const hostPointer = m_set.data(); + m_set.move( RAJAHelper< POLICY >::space, false ); + T const * const devicePointer = m_set.data(); + forall< POLICY >( size, [devicePointer] LVARRAY_HOST_DEVICE ( INDEX_TYPE const i ) + { + LVARRAY_ERROR_IF( devicePointer[ i ] != T( i ), "Values changed when moved." ); + } ); // Change the values. - m_set.clear(); for( INDEX_TYPE i = 0; i < size; ++i ) - { - m_set.insert( T( i * i )); - } + { const_cast< T & >( hostPointer[ i ] ) = T( 2 * i ); } ASSERT_EQ( m_set.size(), size ); // Move the array back to the host and check that the values haven't been overwritten. - m_set.move( chai::CPU ); + m_set.move( MemorySpace::CPU ); + EXPECT_EQ( hostPointer, m_set.data() ); for( INDEX_TYPE i = 0; i < size; ++i ) { - EXPECT_EQ( m_set[i], T( i * i )); + EXPECT_EQ( m_set[ i ], T( 2 * i )); } } @@ -425,40 +432,52 @@ class SortedArrayCudaTest : public SortedArrayTest< T > ASSERT_EQ( m_set.size(), size ); - forall( gpu(), 0, size, - [view = m_set.toView()] __device__ ( INDEX_TYPE i ) - { - LVARRAY_ERROR_IF( !view.contains( T( 2 * i )), "view should contain even numbers." ); - LVARRAY_ERROR_IF( view.contains( T( 2 * i + 1 )), "view should not contain odd numbers." ); - } - ); + ViewType const & view = m_set.toView(); + forall< POLICY >( size, [view] LVARRAY_HOST_DEVICE ( INDEX_TYPE const i ) + { + LVARRAY_ERROR_IF( !view.contains( T( 2 * i )), "view should contain even numbers." ); + LVARRAY_ERROR_IF( view.contains( T( 2 * i + 1 )), "view should not contain odd numbers." ); + } ); } protected: - using SortedArrayTest< T >::m_set; - using SortedArrayTest< T >::m_ref; + using ParentClass::m_set; + using ParentClass::m_ref; }; -using CudaTestTypes = ::testing::Types< int, Tensor >; -TYPED_TEST_SUITE( SortedArrayCudaTest, CudaTestTypes ); +using SortedArrayViewTestTypes = ::testing::Types< + std::pair< SortedArray< int, INDEX_TYPE, MallocBuffer >, serialPolicy > + , std::pair< SortedArray< Tensor, INDEX_TYPE, MallocBuffer >, serialPolicy > + , std::pair< SortedArray< TestString, INDEX_TYPE, MallocBuffer >, serialPolicy > -TYPED_TEST( SortedArrayCudaTest, memoryMotion ) +#if defined(USE_CHAI) + , std::pair< SortedArray< int, INDEX_TYPE, NewChaiBuffer >, serialPolicy > + , std::pair< SortedArray< Tensor, INDEX_TYPE, NewChaiBuffer >, serialPolicy > + , std::pair< SortedArray< TestString, INDEX_TYPE, NewChaiBuffer >, serialPolicy > +#endif + +#if defined(USE_CUDA) && defined(USE_CHAI) + , std::pair< SortedArray< int, INDEX_TYPE, NewChaiBuffer >, parallelDevicePolicy< 32 > > + , std::pair< SortedArray< Tensor, INDEX_TYPE, NewChaiBuffer >, parallelDevicePolicy< 32 > > +#endif + >; +TYPED_TEST_SUITE( SortedArrayViewTest, SortedArrayViewTestTypes, ); + +TYPED_TEST( SortedArrayViewTest, memoryMotion ) { this->memoryMotionTest( 1000 ); } -TYPED_TEST( SortedArrayCudaTest, memoryMotionMove ) +TYPED_TEST( SortedArrayViewTest, memoryMotionMove ) { this->memoryMotionMoveTest( 1000 ); } -TYPED_TEST( SortedArrayCudaTest, containsDevice ) +TYPED_TEST( SortedArrayViewTest, containsDevice ) { this->containsDeviceTest( 1000 ); } -#endif - } // namespace testing } // namespace LvArray diff --git a/unitTests/testSortedArrayManipulation.cpp b/unitTests/testSortedArrayManipulation.cpp index 2afcd802..6ad69419 100644 --- a/unitTests/testSortedArrayManipulation.cpp +++ b/unitTests/testSortedArrayManipulation.cpp @@ -37,6 +37,14 @@ namespace LvArray namespace testing { +using INDEX_TYPE = std::ptrdiff_t; + +template< typename T > +using Array1D = Array< T, 1, RAJA::PERM_I, INDEX_TYPE, DEFAULT_BUFFER >; + +template< typename T > +using ArrayView1D = ArrayView< T, 1, 0, INDEX_TYPE, DEFAULT_BUFFER >; + template< class T_COMP_POLICY > class SingleArrayTest : public ::testing::Test { @@ -45,22 +53,22 @@ class SingleArrayTest : public ::testing::Test using COMP = std::tuple_element_t< 1, T_COMP_POLICY >; using POLICY = std::tuple_element_t< 2, T_COMP_POLICY >; - void testMakeSorted( std::ptrdiff_t const maxSize ) + void testMakeSorted( INDEX_TYPE const maxSize ) { - for( std::ptrdiff_t size = 0; size < maxSize; size = std::ptrdiff_t( size * 1.5 + 1 )) + for( INDEX_TYPE size = 0; size < maxSize; size = INDEX_TYPE( size * 1.5 + 1 )) { fill( size ); bool const isInitiallySorted = std::is_sorted( m_ref.begin(), m_ref.end(), m_comp ); std::sort( m_ref.begin(), m_ref.end(), m_comp ); - RAJA::ReduceSum< typename RAJAHelper< POLICY >::ReducePolicy, std::ptrdiff_t > resultOfFirstIsSorted( 0 ); - RAJA::ReduceSum< typename RAJAHelper< POLICY >::ReducePolicy, std::ptrdiff_t > resultOfSecondIsSorted( 0 ); - ArrayView< T, 1 > const & view = m_array; + RAJA::ReduceSum< typename RAJAHelper< POLICY >::ReducePolicy, INDEX_TYPE > resultOfFirstIsSorted( 0 ); + RAJA::ReduceSum< typename RAJAHelper< POLICY >::ReducePolicy, INDEX_TYPE > resultOfSecondIsSorted( 0 ); + ArrayView1D< T > const & view = m_array; COMP & comp = m_comp; forall< POLICY >( 1, [resultOfFirstIsSorted, resultOfSecondIsSorted, view, comp] - LVARRAY_HOST_DEVICE ( std::ptrdiff_t ) + LVARRAY_HOST_DEVICE ( INDEX_TYPE ) { resultOfFirstIsSorted += sortedArrayManipulation::isSorted( view.begin(), view.end(), comp ); sortedArrayManipulation::makeSorted( view.begin(), view.end(), comp ); @@ -70,14 +78,14 @@ class SingleArrayTest : public ::testing::Test EXPECT_EQ( resultOfFirstIsSorted.get(), isInitiallySorted ); EXPECT_TRUE( resultOfSecondIsSorted.get() ); - m_array.move( chai::CPU ); + m_array.move( MemorySpace::CPU ); checkEquality(); } } - void testRemoveDuplicates( std::ptrdiff_t const maxSize ) + void testRemoveDuplicates( INDEX_TYPE const maxSize ) { - for( std::ptrdiff_t size = 1; size < maxSize; size = std::ptrdiff_t( size * 1.5 + 1 ) ) + for( INDEX_TYPE size = 1; size < maxSize; size = INDEX_TYPE( size * 1.5 + 1 ) ) { fill( size ); @@ -91,19 +99,19 @@ class SingleArrayTest : public ::testing::Test EXPECT_TRUE( sortedArrayManipulation::isSortedUnique( m_ref.begin(), m_ref.end(), m_comp ) ); } - RAJA::ReduceSum< typename RAJAHelper< POLICY >::ReducePolicy, std::ptrdiff_t > firstIsSortedUnique( 0 ); - RAJA::ReduceSum< typename RAJAHelper< POLICY >::ReducePolicy, std::ptrdiff_t > secondIsSortedUnique( 0 ); - RAJA::ReduceSum< typename RAJAHelper< POLICY >::ReducePolicy, std::ptrdiff_t > numUniqueValues( 0 ); - ArrayView< T, 1 > const & view = m_array; + RAJA::ReduceSum< typename RAJAHelper< POLICY >::ReducePolicy, INDEX_TYPE > firstIsSortedUnique( 0 ); + RAJA::ReduceSum< typename RAJAHelper< POLICY >::ReducePolicy, INDEX_TYPE > secondIsSortedUnique( 0 ); + RAJA::ReduceSum< typename RAJAHelper< POLICY >::ReducePolicy, INDEX_TYPE > numUniqueValues( 0 ); + ArrayView1D< T > const & view = m_array; COMP & comp = m_comp; forall< POLICY >( 1, [firstIsSortedUnique, secondIsSortedUnique, numUniqueValues, view, comp] - LVARRAY_HOST_DEVICE ( std::ptrdiff_t ) + LVARRAY_HOST_DEVICE ( INDEX_TYPE ) { firstIsSortedUnique += sortedArrayManipulation::isSortedUnique( view.begin(), view.end(), comp ); sortedArrayManipulation::makeSorted( view.begin(), view.end(), comp ); - std::ptrdiff_t const numUnique = sortedArrayManipulation::makeSortedUnique( view.begin(), view.end(), comp ); + INDEX_TYPE const numUnique = sortedArrayManipulation::makeSortedUnique( view.begin(), view.end(), comp ); numUniqueValues += numUnique; secondIsSortedUnique += sortedArrayManipulation::isSortedUnique( view.begin(), view.begin() + numUnique, comp ); } ); @@ -111,7 +119,7 @@ class SingleArrayTest : public ::testing::Test EXPECT_EQ( firstIsSortedUnique.get(), isInitiallySortedUnique ); EXPECT_TRUE( secondIsSortedUnique.get() ); - m_array.move( chai::CPU ); + m_array.move( MemorySpace::CPU ); EXPECT_EQ( numUniqueValues.get(), m_ref.size() ); m_array.resize( numUniqueValues.get() ); @@ -120,9 +128,9 @@ class SingleArrayTest : public ::testing::Test } } - void testMakeSortedUnique( std::ptrdiff_t const maxSize ) + void testMakeSortedUnique( INDEX_TYPE const maxSize ) { - for( std::ptrdiff_t size = 1; size < maxSize; size = std::ptrdiff_t( size * 1.5 + 1 ) ) + for( INDEX_TYPE size = 1; size < maxSize; size = INDEX_TYPE( size * 1.5 + 1 ) ) { fill( size ); @@ -133,16 +141,16 @@ class SingleArrayTest : public ::testing::Test EXPECT_TRUE( sortedArrayManipulation::isSortedUnique( m_ref.begin(), m_ref.end(), m_comp ) ); } - RAJA::ReduceSum< typename RAJAHelper< POLICY >::ReducePolicy, std::ptrdiff_t > numUniqueValues( 0 ); - ArrayView< T, 1 > const & view = m_array; + RAJA::ReduceSum< typename RAJAHelper< POLICY >::ReducePolicy, INDEX_TYPE > numUniqueValues( 0 ); + ArrayView1D< T > const & view = m_array; COMP & comp = m_comp; - forall< POLICY >( 1, [numUniqueValues, view, comp] LVARRAY_HOST_DEVICE ( std::ptrdiff_t ) + forall< POLICY >( 1, [numUniqueValues, view, comp] LVARRAY_HOST_DEVICE ( INDEX_TYPE ) { numUniqueValues += sortedArrayManipulation::makeSortedUnique( view.begin(), view.end(), comp ); } ); - m_array.move( chai::CPU ); + m_array.move( MemorySpace::CPU ); EXPECT_EQ( numUniqueValues.get(), m_ref.size() ); m_array.resize( numUniqueValues.get() ); @@ -153,13 +161,13 @@ class SingleArrayTest : public ::testing::Test protected: - void fill( std::ptrdiff_t const size ) + void fill( INDEX_TYPE const size ) { - std::uniform_int_distribution< std::ptrdiff_t > valueDist( 0, 2 * size ); + std::uniform_int_distribution< INDEX_TYPE > valueDist( 0, 2 * size ); m_array.resize( size ); m_ref.resize( size ); - for( std::ptrdiff_t i = 0; i < size; ++i ) + for( INDEX_TYPE i = 0; i < size; ++i ) { T const val = T( valueDist( m_gen ) ); m_array[ i ] = val; @@ -169,13 +177,13 @@ class SingleArrayTest : public ::testing::Test void checkEquality() const { - for( std::ptrdiff_t i = 0; i < m_array.size(); ++i ) + for( INDEX_TYPE i = 0; i < m_array.size(); ++i ) { EXPECT_EQ( m_array[ i ], m_ref[ i ] ); } } - Array< T, 1 > m_array; + Array1D< T > m_array; std::vector< T > m_ref; COMP m_comp; std::mt19937_64 m_gen; @@ -189,7 +197,7 @@ using SingleArrayTestTypes = ::testing::Types< , std::tuple< TestString, sortedArrayManipulation::greater< TestString >, serialPolicy > , std::tuple< TestString, sortedArrayManipulation::greater< TestString >, serialPolicy > -#ifdef USE_CUDA +#if defined(USE_CUDA) && defined(USE_CHAI) , std::tuple< int, sortedArrayManipulation::less< int >, parallelDevicePolicy< 256 > > , std::tuple< int, sortedArrayManipulation::greater< int >, parallelDevicePolicy< 256 > > , std::tuple< Tensor, sortedArrayManipulation::less< Tensor >, parallelDevicePolicy< 256 > > @@ -222,39 +230,39 @@ class DualArrayTest : public ::testing::Test using COMP = std::tuple_element_t< 2, KEY_T_COMP_POLICY >; using POLICY = std::tuple_element_t< 3, KEY_T_COMP_POLICY >; - void testMakeSorted( std::ptrdiff_t maxSize ) + void testMakeSorted( INDEX_TYPE maxSize ) { - for( std::ptrdiff_t size = 0; size < maxSize; size = std::ptrdiff_t( size * 1.5 + 1 )) + for( INDEX_TYPE size = 0; size < maxSize; size = INDEX_TYPE( size * 1.5 + 1 )) { fillArrays( size ); std::sort( m_ref.begin(), m_ref.end(), PairComp< KEY, T, COMP >()); - ArrayView< KEY, 1 > const & keys = m_keys; - ArrayView< T, 1 > const & values = m_values; + ArrayView1D< KEY > const & keys = m_keys; + ArrayView1D< T > const & values = m_values; COMP & comp = m_comp; - forall< POLICY >( 1, [keys, values, comp] LVARRAY_HOST_DEVICE ( std::ptrdiff_t ) + forall< POLICY >( 1, [keys, values, comp] LVARRAY_HOST_DEVICE ( INDEX_TYPE ) { dualSort( keys.begin(), keys.end(), values.begin(), comp ); } ); - m_keys.move( chai::CPU ); - m_values.move( chai::CPU ); + m_keys.move( MemorySpace::CPU ); + m_values.move( MemorySpace::CPU ); checkEquality(); } } private: - void fillArrays( std::ptrdiff_t const size ) + void fillArrays( INDEX_TYPE const size ) { - std::uniform_int_distribution< std::ptrdiff_t > valueDist( 0, 2 * size ); + std::uniform_int_distribution< INDEX_TYPE > valueDist( 0, 2 * size ); m_keys.resize( size ); m_values.resize( size ); m_ref.resize( size ); - for( std::ptrdiff_t i = 0; i < size; ++i ) + for( INDEX_TYPE i = 0; i < size; ++i ) { - std::ptrdiff_t const seed = valueDist( m_gen ); + INDEX_TYPE const seed = valueDist( m_gen ); KEY const key = KEY( seed ); T const val = T( seed * ( seed - size ) ); m_keys[ i ] = key; @@ -265,15 +273,15 @@ class DualArrayTest : public ::testing::Test void checkEquality() { - for( std::ptrdiff_t i = 0; i < m_keys.size(); ++i ) + for( INDEX_TYPE i = 0; i < m_keys.size(); ++i ) { EXPECT_EQ( m_keys[ i ], m_ref[ i ].first ); EXPECT_EQ( m_values[ i ], m_ref[ i ].second ); } } - Array< KEY, 1 > m_keys; - Array< T, 1 > m_values; + Array1D< KEY > m_keys; + Array1D< T > m_values; std::vector< std::pair< KEY, T > > m_ref; COMP m_comp; std::mt19937_64 m_gen; @@ -289,7 +297,7 @@ using DualArrayTestTypes = ::testing::Types< , std::tuple< TestString, TestString, sortedArrayManipulation::less< TestString >, serialPolicy > , std::tuple< TestString, TestString, sortedArrayManipulation::greater< TestString >, serialPolicy > -#ifdef USE_CUDA +#if defined(USE_CUDA) && defined(USE_CHAI) , std::tuple< int, int, sortedArrayManipulation::less< int >, parallelDevicePolicy< 256 > > , std::tuple< int, int, sortedArrayManipulation::greater< int >, parallelDevicePolicy< 256 > > , std::tuple< Tensor, Tensor, sortedArrayManipulation::less< Tensor >, parallelDevicePolicy< 256 > > diff --git a/unitTests/testSparsityPattern.cpp b/unitTests/testSparsityPattern.cpp index a7cd162d..358482e4 100644 --- a/unitTests/testSparsityPattern.cpp +++ b/unitTests/testSparsityPattern.cpp @@ -21,15 +21,11 @@ #include "CRSMatrix.hpp" #include "testUtils.hpp" #include "Array.hpp" - +#include "MallocBuffer.hpp" // TPL includes #include -#if defined(USE_CHAI) && defined(USE_CUDA) - #include -#endif - // System includes #include #include @@ -42,66 +38,60 @@ namespace LvArray namespace testing { -// Alias for SparsityPatternView -template< class COL_TYPE, class INDEX_TYPE=std::ptrdiff_t > -using ViewType = SparsityPatternView< COL_TYPE, INDEX_TYPE const >; - using INDEX_TYPE = std::ptrdiff_t; -/** - * @brief Check that the SparsityPatternView is equivalent to the reference type. - * @param [in] v the SparsityPatternView to check. - * @param [in] m_ref the reference to check against. - */ -template< class COL_TYPE > -void compareToReference( ViewType< COL_TYPE const > const & v, std::vector< std::set< COL_TYPE > > const & m_ref ) +template< typename SPARSITY_PATTERN > +class SparsityPatternTest : public ::testing::Test { - INDEX_TYPE const numRows = v.numRows(); - ASSERT_EQ( numRows, INDEX_TYPE( m_ref.size())); +public: + using COL_TYPE = typename SPARSITY_PATTERN::column_type; - INDEX_TYPE ref_nnz = 0; - for( INDEX_TYPE row = 0; row < numRows; ++row ) - { - INDEX_TYPE const rowNNZ = v.numNonZeros( row ); - INDEX_TYPE const refRowNNZ = m_ref[row].size(); - ref_nnz += refRowNNZ; + using ViewType = std::remove_reference_t< decltype( std::declval< SPARSITY_PATTERN >().toView() ) >; + using ViewTypeConst = std::remove_reference_t< decltype( std::declval< SPARSITY_PATTERN >().toViewConst() ) >; - ASSERT_EQ( rowNNZ, refRowNNZ ); + void compareToReference( ViewTypeConst const & v ) + { + INDEX_TYPE const numRows = v.numRows(); + ASSERT_EQ( numRows, INDEX_TYPE( m_ref.size())); - if( rowNNZ == 0 ) - { - ASSERT_TRUE( v.empty( row )); - } - else + INDEX_TYPE ref_nnz = 0; + for( INDEX_TYPE row = 0; row < numRows; ++row ) { - ASSERT_FALSE( v.empty( row )); + INDEX_TYPE const rowNNZ = v.numNonZeros( row ); + INDEX_TYPE const refRowNNZ = m_ref[row].size(); + ref_nnz += refRowNNZ; + + ASSERT_EQ( rowNNZ, refRowNNZ ); + + if( rowNNZ == 0 ) + { + ASSERT_TRUE( v.empty( row )); + } + else + { + ASSERT_FALSE( v.empty( row )); + } + + auto it = m_ref[row].begin(); + COL_TYPE const * const columns = v.getColumns( row ); + for( INDEX_TYPE i = 0; i < v.numNonZeros( row ); ++i ) + { + EXPECT_FALSE( v.empty( row, columns[i] )); + EXPECT_EQ( columns[i], *it ); + it++; + } } - auto it = m_ref[row].begin(); - COL_TYPE const * const columns = v.getColumns( row ); - for( INDEX_TYPE i = 0; i < v.numNonZeros( row ); ++i ) + ASSERT_EQ( v.numNonZeros(), ref_nnz ); + + if( v.numNonZeros() == 0 ) { - EXPECT_FALSE( v.empty( row, columns[i] )); - EXPECT_EQ( columns[i], *it ); - it++; + ASSERT_TRUE( v.empty()); } } - ASSERT_EQ( v.numNonZeros(), ref_nnz ); - - if( v.numNonZeros() == 0 ) - { - ASSERT_TRUE( v.empty()); + #define COMPARE_TO_REFERENCE { SCOPED_TRACE( "" ); this->compareToReference( m_sp.toViewConst() ); \ } -} - -#define COMPARE_TO_REFERENCE( view, ref ) { SCOPED_TRACE( "" ); compareToReference( view, ref ); \ -} - -template< typename COL_TYPE > -class SparsityPatternTest : public ::testing::Test -{ -public: void resize( INDEX_TYPE const nRows, INDEX_TYPE const nCols, @@ -110,12 +100,12 @@ class SparsityPatternTest : public ::testing::Test m_sp.resize( nRows, nCols, initialRowCapacity ); m_ref.resize( nRows ); - COMPARE_TO_REFERENCE( m_sp.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE } void appendRow( INDEX_TYPE const nRows, INDEX_TYPE const maxInserts ) { - COMPARE_TO_REFERENCE( m_sp.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE std::vector< COL_TYPE > columnsToAppend( maxInserts ); @@ -140,7 +130,7 @@ class SparsityPatternTest : public ::testing::Test m_ref.push_back( std::set< COL_TYPE >( columnsToAppend.begin(), columnsToAppend.end() ) ); } - COMPARE_TO_REFERENCE( m_sp.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE } /** @@ -164,7 +154,7 @@ class SparsityPatternTest : public ::testing::Test } } - COMPARE_TO_REFERENCE( m_sp.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE } /** @@ -206,7 +196,7 @@ class SparsityPatternTest : public ::testing::Test } } - COMPARE_TO_REFERENCE( m_sp.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE } /** @@ -230,7 +220,7 @@ class SparsityPatternTest : public ::testing::Test } } - COMPARE_TO_REFERENCE( m_sp.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE } /** @@ -272,7 +262,7 @@ class SparsityPatternTest : public ::testing::Test } } - COMPARE_TO_REFERENCE( m_sp.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE } /** @@ -372,7 +362,7 @@ class SparsityPatternTest : public ::testing::Test } } - COMPARE_TO_REFERENCE( m_sp.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE } /** @@ -401,7 +391,7 @@ class SparsityPatternTest : public ::testing::Test curOffset += m_sp.numNonZeros( row ); } - COMPARE_TO_REFERENCE( m_sp.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE } /** @@ -409,7 +399,7 @@ class SparsityPatternTest : public ::testing::Test */ void deepCopyTest() { - SparsityPattern< COL_TYPE > copy( m_sp ); + SPARSITY_PATTERN copy( m_sp ); ASSERT_EQ( m_sp.numRows(), copy.numRows()); ASSERT_EQ( m_sp.numColumns(), copy.numColumns()); @@ -440,7 +430,7 @@ class SparsityPatternTest : public ::testing::Test EXPECT_EQ( copy.numNonZeros(), 0 ); EXPECT_EQ( m_sp.numNonZeros(), totalNNZ ); - COMPARE_TO_REFERENCE( m_sp.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE } /** @@ -448,8 +438,7 @@ class SparsityPatternTest : public ::testing::Test */ void shallowCopyTest() const { - ViewType< COL_TYPE > const & view = m_sp.toView(); - ViewType< COL_TYPE > copy( view ); + ViewType copy( m_sp.toView() ); ASSERT_EQ( m_sp.numRows(), copy.numRows()); ASSERT_EQ( m_sp.numColumns(), copy.numColumns()); @@ -509,61 +498,62 @@ class SparsityPatternTest : public ::testing::Test std::mt19937_64 m_gen; - SparsityPattern< COL_TYPE > m_sp; + SPARSITY_PATTERN m_sp; std::vector< std::set< COL_TYPE > > m_ref; - /// Check that the move, toView, and toViewConst methods of SparsityPattern< COL_TYPE > are detected. - static_assert( bufferManipulation::HasMemberFunction_move< SparsityPattern< COL_TYPE > >, - "SparsityPattern< COL_TYPE > has a move method." ); - static_assert( HasMemberFunction_toView< SparsityPattern< COL_TYPE > >, - "SparsityPattern< COL_TYPE > has a toView method." ); - static_assert( HasMemberFunction_toViewConst< SparsityPattern< COL_TYPE > >, - "SparsityPattern< COL_TYPE > has a toViewConst method." ); - - /// Check that the move and toViewConst methods of SparsityPatternView< COL_TYPE, INDEX_TYPE const > are detected. - static_assert( bufferManipulation::HasMemberFunction_move< SparsityPatternView< COL_TYPE, INDEX_TYPE const > >, - "SparsityPatternView< COL_TYPE, INDEX_TYPE const > has a move method." ); - static_assert( HasMemberFunction_toView< SparsityPatternView< COL_TYPE, INDEX_TYPE const > >, - "SparsityPatternView< COL_TYPE, INDEX_TYPE const > has a toView method." ); - static_assert( HasMemberFunction_toViewConst< SparsityPatternView< COL_TYPE, INDEX_TYPE const > >, - "SparsityPatternView< COL_TYPE, INDEX_TYPE const > has a toViewConst method." ); - - /// Check that the move and toViewConst methods of SparsityPatternView< COL_TYPE const, INDEX_TYPE const > are + /// Check that the move, toView, and toViewConst methods of SPARSITY_PATTERN are detected. + static_assert( bufferManipulation::HasMemberFunction_move< SPARSITY_PATTERN >, + "SPARSITY_PATTERN has a move method." ); + static_assert( HasMemberFunction_toView< SPARSITY_PATTERN >, + "SPARSITY_PATTERN has a toView method." ); + static_assert( HasMemberFunction_toViewConst< SPARSITY_PATTERN >, + "SPARSITY_PATTERN has a toViewConst method." ); + + /// Check that the move and toViewConst methods of ViewType are detected. + static_assert( bufferManipulation::HasMemberFunction_move< ViewType >, + "ViewType has a move method." ); + static_assert( HasMemberFunction_toView< ViewType >, + "ViewType has a toView method." ); + static_assert( HasMemberFunction_toViewConst< ViewType >, + "ViewType has a toViewConst method." ); + + /// Check that the move and toViewConst methods of ViewTypeConst are /// detected. - static_assert( bufferManipulation::HasMemberFunction_move< SparsityPatternView< COL_TYPE const, INDEX_TYPE const > >, - "SparsityPatternView< COL_TYPE const, INDEX_TYPE const > has a move method." ); - static_assert( HasMemberFunction_toView< SparsityPatternView< COL_TYPE const, INDEX_TYPE const > >, - "SparsityPatternView< COL_TYPE const, INDEX_TYPE const > has a toView method." ); - static_assert( HasMemberFunction_toViewConst< SparsityPatternView< COL_TYPE const, INDEX_TYPE const > >, - "SparsityPatternView< COL_TYPE const, INDEX_TYPE const > has a toViewConst method." ); - - // /// Check that GetViewType and GetViewTypeConst are correct for SparsityPattern< COL_TYPE > - static_assert( std::is_same_v< typename GetViewType< SparsityPattern< COL_TYPE > >::type, - SparsityPatternView< COL_TYPE, INDEX_TYPE const > const >, - "The view type of SparsityPattern< COL_TYPE > is SparsityPatternView< COL_TYPE, INDEX_TYPE const > const." ); - static_assert( std::is_same_v< typename GetViewTypeConst< SparsityPattern< COL_TYPE > >::type, - SparsityPatternView< COL_TYPE const, INDEX_TYPE const > const >, - "The const view type of SparsityPattern< COL_TYPE > is SparsityPatternView< COL_TYPE const, INDEX_TYPE const > const." ); - - /// Check that GetViewType and GetViewTypeConst are correct for SparsityPatternView< COL_TYPE, INDEX_TYPE const > - static_assert( std::is_same_v< typename GetViewType< SparsityPatternView< COL_TYPE, INDEX_TYPE const > >::type, - SparsityPatternView< COL_TYPE, INDEX_TYPE const > const >, - "The view type of SparsityPatternView< COL_TYPE, INDEX_TYPE const > is SparsityPatternView< COL_TYPE, INDEX_TYPE const > const." ); - static_assert( std::is_same_v< typename GetViewTypeConst< SparsityPatternView< COL_TYPE, INDEX_TYPE const > >::type, - SparsityPatternView< COL_TYPE const, INDEX_TYPE const > const >, - "The const view type of SparsityPatternView< COL_TYPE, INDEX_TYPE const > is SparsityPatternView< COL_TYPE const, INDEX_TYPE const > const." ); + static_assert( bufferManipulation::HasMemberFunction_move< ViewTypeConst >, + "ViewTypeConst has a move method." ); + static_assert( HasMemberFunction_toView< ViewTypeConst >, + "ViewTypeConst has a toView method." ); + static_assert( HasMemberFunction_toViewConst< ViewTypeConst >, + "ViewTypeConst has a toViewConst method." ); + + // /// Check that GetViewType and GetViewTypeConst are correct for SPARSITY_PATTERN + static_assert( std::is_same_v< typename GetViewType< SPARSITY_PATTERN >::type, ViewType const >, + "The view type of SPARSITY_PATTERN is ViewType const." ); + static_assert( std::is_same_v< typename GetViewTypeConst< SPARSITY_PATTERN >::type, ViewTypeConst const >, + "The const view type of SPARSITY_PATTERN is ViewTypeConst const." ); + + /// Check that GetViewType and GetViewTypeConst are correct for ViewType + static_assert( std::is_same_v< typename GetViewType< ViewType >::type, ViewType const >, + "The view type of ViewType is ViewType const." ); + static_assert( std::is_same_v< typename GetViewTypeConst< ViewType >::type, ViewTypeConst const >, + "The const view type of ViewType is ViewTypeConst const." ); /// Check that GetViewType and GetViewTypeConst are correct for SparsityPatternView< COL_TYPE const, INDEX_TYPE const /// > - static_assert( std::is_same_v< typename GetViewType< SparsityPatternView< COL_TYPE const, INDEX_TYPE const > >::type, - SparsityPatternView< COL_TYPE const, INDEX_TYPE const > const >, - "The view type of SparsityPatternView< COL_TYPE const, INDEX_TYPE const > is SparsityPatternView< COL_TYPE const, INDEX_TYPE const > const." ); - static_assert( std::is_same_v< typename GetViewTypeConst< SparsityPatternView< COL_TYPE const, INDEX_TYPE const > >::type, - SparsityPatternView< COL_TYPE const, INDEX_TYPE const > const >, - "The const view type of SparsityPatternView< COL_TYPE const, INDEX_TYPE const > is SparsityPatternView< COL_TYPE const, INDEX_TYPE const > const." ); + static_assert( std::is_same_v< typename GetViewType< ViewTypeConst >::type, ViewTypeConst const >, + "The view type of ViewTypeConst is ViewTypeConst const." ); + static_assert( std::is_same_v< typename GetViewTypeConst< ViewTypeConst >::type, ViewTypeConst const >, + "The const view type of ViewTypeConst is ViewTypeConst const." ); }; -using SparsityPatternTestTypes = ::testing::Types< int, unsigned int >; +using SparsityPatternTestTypes = ::testing::Types< + SparsityPattern< int, INDEX_TYPE, MallocBuffer > + , SparsityPattern< uint, INDEX_TYPE, MallocBuffer > +#if defined(USE_CHAI) + , SparsityPattern< int, INDEX_TYPE, NewChaiBuffer > + , SparsityPattern< uint, INDEX_TYPE, NewChaiBuffer > +#endif + >; TYPED_TEST_SUITE( SparsityPatternTest, SparsityPatternTestTypes, ); INDEX_TYPE const NROWS = 100; @@ -572,7 +562,7 @@ INDEX_TYPE const MAX_INSERTS = 75; TYPED_TEST( SparsityPatternTest, constructionNoHint ) { - SparsityPattern< TypeParam > sp( NROWS, NCOLS ); + TypeParam sp( NROWS, NCOLS ); EXPECT_EQ( sp.numRows(), NROWS ); EXPECT_EQ( sp.numColumns(), NCOLS ); EXPECT_EQ( sp.numNonZeros(), 0 ); @@ -583,7 +573,7 @@ TYPED_TEST( SparsityPatternTest, constructionNoHint ) EXPECT_EQ( sp.numNonZeros( row ), 0 ); EXPECT_EQ( sp.nonZeroCapacity( row ), 0 ); EXPECT_EQ( sp.empty( row ), true ); - TypeParam const * const columns = sp.getColumns( row ); + auto const * const columns = sp.getColumns( row ).dataIfContiguous(); EXPECT_EQ( columns, nullptr ); } } @@ -592,7 +582,7 @@ TYPED_TEST( SparsityPatternTest, constructionWithHint ) { constexpr int SIZE_HINT = 5; - SparsityPattern< TypeParam > sp( NROWS, NCOLS, SIZE_HINT ); + TypeParam sp( NROWS, NCOLS, SIZE_HINT ); EXPECT_EQ( sp.numRows(), NROWS ); EXPECT_EQ( sp.numColumns(), NCOLS ); EXPECT_EQ( sp.numNonZeros(), 0 ); @@ -605,7 +595,7 @@ TYPED_TEST( SparsityPatternTest, constructionWithHint ) EXPECT_EQ( sp.nonZeroCapacity( row ), SIZE_HINT ); EXPECT_EQ( sp.empty( row ), true ); - TypeParam const * const columns = sp.getColumns( row ); + auto const * const columns = sp.getColumns( row ).dataIfContiguous(); ASSERT_NE( columns, nullptr ); } } @@ -677,7 +667,7 @@ TYPED_TEST( SparsityPatternTest, capacity ) ASSERT_EQ( this->m_sp.numNonZeros( row ), 0 ); } - TypeParam const * const columns = this->m_sp.getColumns( 0 ); + auto const * const columns = this->m_sp.getColumns( 0 ).dataIfContiguous(); this->insertTest( MAX_INSERTS ); ASSERT_EQ( this->m_sp.getColumns( 0 ), columns ); } @@ -686,7 +676,7 @@ TYPED_TEST( SparsityPatternTest, rowCapacity ) { this->resize( NROWS, NCOLS, MAX_INSERTS ); - TypeParam const * const columns = this->m_sp.getColumns( 0 ); + auto const * const columns = this->m_sp.getColumns( 0 ).dataIfContiguous(); this->insertTest( MAX_INSERTS ); ASSERT_EQ( this->m_sp.getColumns( 0 ), columns ); @@ -717,12 +707,24 @@ TYPED_TEST( SparsityPatternTest, shallowCopy ) this->shallowCopyTest(); } -template< typename COL_POLICY_PAIR > -class SparsityPatternViewTest : public SparsityPatternTest< typename COL_POLICY_PAIR::first_type > +template< typename SPARSITY_PATTERN_POLICY_PAIR > +class SparsityPatternViewTest : public SparsityPatternTest< typename SPARSITY_PATTERN_POLICY_PAIR::first_type > { public: - using COL_TYPE = typename COL_POLICY_PAIR::first_type; - using POLICY = typename COL_POLICY_PAIR::second_type; + using SPARSITY_PATTERN = typename SPARSITY_PATTERN_POLICY_PAIR::first_type; + using POLICY = typename SPARSITY_PATTERN_POLICY_PAIR::second_type; + + using ParentClass = SparsityPatternTest< SPARSITY_PATTERN >; + + using typename ParentClass::COL_TYPE; + using typename ParentClass::ViewType; + using typename ParentClass::ViewTypeConst; + + template< typename T > + using Array1D = typename ArrayConverter< SPARSITY_PATTERN >::template Array< T, 1, RAJA::PERM_I >; + + template< typename T > + using ArrayView1D = typename ArrayConverter< SPARSITY_PATTERN >::template ArrayView< T, 1, 0 >; /** * @brief Test the SparsityPatternView copy constructor in regards to memory motion. @@ -746,7 +748,7 @@ class SparsityPatternViewTest : public SparsityPatternTest< typename COL_POLICY_ // Capture the view on device and set the values. Here the const cast is necessary // because we don't want to test the insert/remove methods on device yet. - SparsityPatternView< COL_TYPE, INDEX_TYPE const > const & view = m_sp.toView(); + ViewType const & view = m_sp.toView(); forall< POLICY >( numRows, [view] LVARRAY_HOST_DEVICE ( INDEX_TYPE row ) { @@ -779,7 +781,7 @@ class SparsityPatternViewTest : public SparsityPatternTest< typename COL_POLICY_ { INDEX_TYPE const numRows = m_sp.numRows(); - SparsityPatternView< COL_TYPE, INDEX_TYPE const > const & view = m_sp.toView(); + ViewType const & view = m_sp.toView(); INDEX_TYPE curIndex = 0; for( INDEX_TYPE row = 0; row < numRows; ++row ) @@ -803,7 +805,7 @@ class SparsityPatternViewTest : public SparsityPatternTest< typename COL_POLICY_ } } ); - m_sp.move( chai::CPU ); + m_sp.move( MemorySpace::CPU ); curIndex = 0; for( INDEX_TYPE row = 0; row < numRows; ++row ) { @@ -825,7 +827,7 @@ class SparsityPatternViewTest : public SparsityPatternTest< typename COL_POLICY_ INDEX_TYPE const numCols = m_sp.numColumns(); // Create a view const and capture it on device. - SparsityPatternView< COL_TYPE const, INDEX_TYPE const > const & constView = m_sp.toViewConst(); + ViewTypeConst const & constView = m_sp.toViewConst(); forall< POLICY >( numRows, [constView, numCols] LVARRAY_HOST_DEVICE ( INDEX_TYPE row ) { @@ -843,18 +845,18 @@ class SparsityPatternViewTest : public SparsityPatternTest< typename COL_POLICY_ } // Move the SparsityPattern back from device, this should be a no-op. - m_sp.move( chai::CPU ); - COMPARE_TO_REFERENCE( m_sp.toViewConst(), m_ref ); + m_sp.move( MemorySpace::CPU ); + COMPARE_TO_REFERENCE } void insertViewTest() { - COMPARE_TO_REFERENCE( m_sp.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE - Array< Array< COL_TYPE, 1 >, 1 > toInsert = createColumns( true, false ); - ArrayView< ArrayView< COL_TYPE const, 1 > const, 1 > const & toInsertView = toInsert.toViewConst(); + Array1D< Array1D< COL_TYPE > > toInsert = createColumns( true, false ); + ArrayView1D< ArrayView1D< COL_TYPE const > const > const & toInsertView = toInsert.toViewConst(); - SparsityPatternView< COL_TYPE, INDEX_TYPE const > const & view = m_sp.toView(); + ViewType const & view = m_sp.toView(); forall< POLICY >( m_sp.numRows(), [view, toInsertView] LVARRAY_HOST_DEVICE ( INDEX_TYPE const row ) { for( INDEX_TYPE j = 0; j < toInsertView[ row ].size(); ++j ) @@ -863,35 +865,35 @@ class SparsityPatternViewTest : public SparsityPatternTest< typename COL_POLICY_ } } ); - m_sp.move( chai::CPU ); - COMPARE_TO_REFERENCE( m_sp.toViewConst(), m_ref ); + m_sp.move( MemorySpace::CPU ); + COMPARE_TO_REFERENCE } void insertMultipleViewTest() { - COMPARE_TO_REFERENCE( m_sp.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE - Array< Array< COL_TYPE, 1 >, 1 > const toInsert = createColumns( true, true ); - ArrayView< ArrayView< COL_TYPE const, 1 > const, 1 > const & toInsertView = toInsert.toViewConst(); + Array1D< Array1D< COL_TYPE > > const toInsert = createColumns( true, true ); + ArrayView1D< ArrayView1D< COL_TYPE const > const > const & toInsertView = toInsert.toViewConst(); - SparsityPatternView< COL_TYPE, INDEX_TYPE const > const & view = m_sp.toView(); + ViewType const & view = m_sp.toView(); forall< POLICY >( m_sp.numRows(), [view, toInsertView] LVARRAY_HOST_DEVICE ( INDEX_TYPE const row ) { view.insertNonZeros( row, toInsertView[ row ].begin(), toInsertView[ row ].end() ); } ); - m_sp.move( chai::CPU ); - COMPARE_TO_REFERENCE( m_sp.toViewConst(), m_ref ); + m_sp.move( MemorySpace::CPU ); + COMPARE_TO_REFERENCE } void removeViewTest() { - COMPARE_TO_REFERENCE( m_sp.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE - Array< Array< COL_TYPE, 1 >, 1 > const toRemove = createColumns( false, false ); - ArrayView< ArrayView< COL_TYPE const, 1 > const, 1 > const & toRemoveView = toRemove.toViewConst(); + Array1D< Array1D< COL_TYPE > > const toRemove = createColumns( false, false ); + ArrayView1D< ArrayView1D< COL_TYPE const > const > const & toRemoveView = toRemove.toViewConst(); - SparsityPatternView< COL_TYPE, INDEX_TYPE const > const & view = m_sp.toView(); + ViewType const & view = m_sp.toView(); forall< POLICY >( m_sp.numRows(), [view, toRemoveView] LVARRAY_HOST_DEVICE ( INDEX_TYPE const row ) { for( INDEX_TYPE j = 0; j < toRemoveView[ row ].size(); ++j ) @@ -900,25 +902,25 @@ class SparsityPatternViewTest : public SparsityPatternTest< typename COL_POLICY_ } } ); - m_sp.move( chai::CPU ); - COMPARE_TO_REFERENCE( m_sp.toViewConst(), m_ref ); + m_sp.move( MemorySpace::CPU ); + COMPARE_TO_REFERENCE } void removeMultipleViewTest() { - COMPARE_TO_REFERENCE( m_sp.toViewConst(), m_ref ); + COMPARE_TO_REFERENCE - Array< Array< COL_TYPE, 1 >, 1 > const toRemove = createColumns( false, true ); - ArrayView< ArrayView< COL_TYPE const, 1 > const, 1 > const & toRemoveView = toRemove.toViewConst(); + Array1D< Array1D< COL_TYPE > > const toRemove = createColumns( false, true ); + ArrayView1D< ArrayView1D< COL_TYPE const > const > const & toRemoveView = toRemove.toViewConst(); - SparsityPatternView< COL_TYPE, INDEX_TYPE const > const & view = m_sp.toView(); + ViewType const & view = m_sp.toView(); forall< POLICY >( m_sp.numRows(), [view, toRemoveView] LVARRAY_HOST_DEVICE ( INDEX_TYPE const row ) { view.removeNonZeros( row, toRemoveView[ row ].begin(), toRemoveView[ row ].end() ); } ); - m_sp.move( chai::CPU ); - COMPARE_TO_REFERENCE( m_sp.toViewConst(), m_ref ); + m_sp.move( MemorySpace::CPU ); + COMPARE_TO_REFERENCE } /** @@ -941,7 +943,7 @@ class SparsityPatternViewTest : public SparsityPatternTest< typename COL_POLICY_ } // Check that each row contains the even columns and no odd columns on device. - SparsityPatternView< COL_TYPE const, INDEX_TYPE const > const & view = m_sp.toViewConst(); + ViewTypeConst const & view = m_sp.toViewConst(); forall< POLICY >( numRows, [view] LVARRAY_HOST_DEVICE ( INDEX_TYPE row ) { @@ -955,11 +957,11 @@ class SparsityPatternViewTest : public SparsityPatternTest< typename COL_POLICY_ protected: - Array< Array< COL_TYPE, 1 >, 1 > createColumns( bool const insert, bool const sortedUnique ) + Array1D< Array1D< COL_TYPE > > createColumns( bool const insert, bool const sortedUnique ) { INDEX_TYPE const numRows = m_sp.numRows(); - Array< Array< COL_TYPE, 1 >, 1 > columns( numRows ); + Array1D< Array1D< COL_TYPE > > columns( numRows ); for( INDEX_TYPE i = 0; i < numRows; ++i ) { @@ -992,24 +994,23 @@ class SparsityPatternViewTest : public SparsityPatternTest< typename COL_POLICY_ return columns; } - using SparsityPatternTest< COL_TYPE >::m_sp; - using SparsityPatternTest< COL_TYPE >::m_ref; - using SparsityPatternTest< COL_TYPE >::rand; - using SparsityPatternTest< COL_TYPE >::randCol; + using ParentClass::m_sp; + using ParentClass::m_ref; + using ParentClass::rand; + using ParentClass::randCol; }; using SparsityPatternViewTestTypes = ::testing::Types< - std::pair< int, serialPolicy > - , std::pair< uint, serialPolicy > - -#ifdef USE_OPENMP - , std::pair< int, parallelHostPolicy > - , std::pair< uint, parallelHostPolicy > + std::pair< SparsityPattern< int, INDEX_TYPE, MallocBuffer >, serialPolicy > + , std::pair< SparsityPattern< uint, INDEX_TYPE, MallocBuffer >, serialPolicy > +#if defined(USE_CHAI) + , std::pair< SparsityPattern< int, INDEX_TYPE, NewChaiBuffer >, serialPolicy > + , std::pair< SparsityPattern< uint, INDEX_TYPE, NewChaiBuffer >, serialPolicy > #endif -#ifdef USE_CUDA - , std::pair< int, parallelDevicePolicy< 256 > > - , std::pair< uint, parallelDevicePolicy< 256 > > +#if defined(USE_CUDA) && defined(USE_CHAI) + , std::pair< SparsityPattern< int, INDEX_TYPE, NewChaiBuffer >, parallelDevicePolicy< 32 > > + , std::pair< SparsityPattern< uint, INDEX_TYPE, NewChaiBuffer >, parallelDevicePolicy< 32 > > #endif >; @@ -1086,30 +1087,46 @@ TYPED_TEST( SparsityPatternViewTest, empty ) this->emptyViewTest(); } -template< typename T > -class CRSMatrixTest : public SparsityPatternTest< int > +// TODO Get rid of this. +template< typename > +struct CRSMatrixToSparsityPattern; + +template< typename T, + typename COL_TYPE, + typename INDEX_TYPE, + template< typename > class BUFFER_TYPE > +struct CRSMatrixToSparsityPattern< CRSMatrix< T, COL_TYPE, INDEX_TYPE, BUFFER_TYPE > > +{ + using type = SparsityPattern< COL_TYPE, INDEX_TYPE, BUFFER_TYPE >; +}; + +template< typename CRS_MATRIX > +class CRSMatrixTest : public SparsityPatternTest< typename CRSMatrixToSparsityPattern< CRS_MATRIX >::type > { public: - using COL_TYPE = int; + using ParentClass = SparsityPatternTest< typename CRSMatrixToSparsityPattern< CRS_MATRIX >::type >; + + using T = typename CRS_MATRIX::value_type; + using typename ParentClass::COL_TYPE; void stealFrom() { - CRSMatrix< T, COL_TYPE, INDEX_TYPE > matrix; + CRS_MATRIX matrix; matrix.stealFrom( std::move( this->m_sp ) ); - COMPARE_TO_REFERENCE( matrix.toSparsityPatternView(), this->m_ref ); + this->compareToReference( matrix.toSparsityPatternView() ); EXPECT_EQ( this->m_sp.numRows(), 0 ); EXPECT_EQ( this->m_sp.numColumns(), 0 ); EXPECT_EQ( this->m_sp.numNonZeros(), 0 ); INDEX_TYPE const numRows = matrix.numRows(); - ASSERT_EQ( numRows, INDEX_TYPE( m_ref.size() ) ); + ASSERT_EQ( numRows, INDEX_TYPE( this->m_ref.size() ) ); INDEX_TYPE ref_nnz = 0; for( INDEX_TYPE row = 0; row < numRows; ++row ) { INDEX_TYPE const rowNNZ = matrix.numNonZeros( row ); - INDEX_TYPE const refRowNNZ = m_ref[row].size(); + INDEX_TYPE const refRowNNZ = this->m_ref[row].size(); ref_nnz += refRowNNZ; ASSERT_EQ( rowNNZ, refRowNNZ ); @@ -1123,7 +1140,7 @@ class CRSMatrixTest : public SparsityPatternTest< int > ASSERT_FALSE( matrix.empty( row ) ); } - auto it = m_ref[ row ].begin(); + auto it = this->m_ref[ row ].begin(); COL_TYPE const * const columns = matrix.getColumns( row ); T const * const entries = matrix.getEntries( row ); for( INDEX_TYPE i = 0; i < matrix.numNonZeros( row ); ++i ) @@ -1138,9 +1155,14 @@ class CRSMatrixTest : public SparsityPatternTest< int > }; using CRSMatrixTestTypes = ::testing::Types< - int - , Tensor - , TestString + CRSMatrix< int, int, INDEX_TYPE, MallocBuffer > + , CRSMatrix< Tensor, int, INDEX_TYPE, MallocBuffer > + , CRSMatrix< TestString, int, INDEX_TYPE, MallocBuffer > +#if defined(USE_CHAI) + , CRSMatrix< int, int, INDEX_TYPE, NewChaiBuffer > + , CRSMatrix< Tensor, int, INDEX_TYPE, NewChaiBuffer > + , CRSMatrix< TestString, int, INDEX_TYPE, NewChaiBuffer > +#endif >; TYPED_TEST_SUITE( CRSMatrixTest, CRSMatrixTestTypes, ); diff --git a/unitTests/testStackArray.cpp b/unitTests/testStackArray.cpp index 642d4080..b858cdd9 100644 --- a/unitTests/testStackArray.cpp +++ b/unitTests/testStackArray.cpp @@ -32,33 +32,31 @@ namespace LvArray namespace testing { -template< typename T, int NDIM, int MAX_SIZE > -using stackArray = StackArray< T, NDIM, camp::make_idx_seq_t< NDIM >, int, MAX_SIZE >; +using INDEX_TYPE = std::ptrdiff_t; LVARRAY_HOST_DEVICE -int toLinearIndex( int const i ) +INDEX_TYPE toLinearIndex( INDEX_TYPE const i ) { return i; } LVARRAY_HOST_DEVICE -int toLinearIndex( int const i, int const j ) +INDEX_TYPE toLinearIndex( INDEX_TYPE const i, INDEX_TYPE const j ) { return i + 10 * j; } LVARRAY_HOST_DEVICE -int toLinearIndex( int const i, int const j, int const k ) +INDEX_TYPE toLinearIndex( INDEX_TYPE const i, INDEX_TYPE const j, INDEX_TYPE const k ) { return i + 10 * j + 100 * k; } -constexpr int pow( int const base, int const exponent ) +constexpr INDEX_TYPE pow( INDEX_TYPE const base, INDEX_TYPE const exponent ) { return exponent == 0 ? 1 : base * pow( base, exponent - 1 ); } -template< typename NDIM_T > +template< typename PERMUTATION > class StackArrayTest : public ::testing::Test { public: - static constexpr int NDIM = NDIM_T::value; + static constexpr int NDIM = getDimension( PERMUTATION {} ); void resize() { - init(); m_array.resize( 4 ); @@ -68,7 +66,7 @@ class StackArrayTest : public ::testing::Test EXPECT_EQ( value, toLinearIndex( indices ... ) ); } ); - int dims[ NDIM ]; + INDEX_TYPE dims[ NDIM ]; for( int i = 0; i < NDIM; ++i ) { dims[ i ] = i + 1; } @@ -89,7 +87,7 @@ class StackArrayTest : public ::testing::Test void init() { - int dims[ NDIM ]; + INDEX_TYPE dims[ NDIM ]; for( int i = 0; i < NDIM; ++i ) { dims[ i ] = 8; } @@ -105,14 +103,20 @@ class StackArrayTest : public ::testing::Test } ); } - static constexpr int CAPACITY = pow( 8, NDIM ); - stackArray< int, NDIM, CAPACITY > m_array; + static constexpr INDEX_TYPE CAPACITY = pow( 8, NDIM ); + StackArray< int, NDIM, PERMUTATION, INDEX_TYPE, CAPACITY > m_array; }; using StackArrayTestTypes = ::testing::Types< - std::integral_constant< int, 1 > - , std::integral_constant< int, 2 > - , std::integral_constant< int, 3 > + RAJA::PERM_I + , RAJA::PERM_IJ + , RAJA::PERM_JI + , RAJA::PERM_IJK + , RAJA::PERM_IKJ + , RAJA::PERM_JIK + , RAJA::PERM_JKI + , RAJA::PERM_KIJ + , RAJA::PERM_KJI >; TYPED_TEST_SUITE( StackArrayTest, StackArrayTestTypes, ); @@ -123,24 +127,27 @@ TYPED_TEST( StackArrayTest, resize ) } -template< typename NDIM_POLICY_PAIR > -class StackArrayCaptureTest : public StackArrayTest< typename NDIM_POLICY_PAIR::first_type > +template< typename PERMUTATION_POLICY_PAIR > +class StackArrayCaptureTest : public StackArrayTest< typename PERMUTATION_POLICY_PAIR::first_type > { public: - using StackArrayTest< typename NDIM_POLICY_PAIR::first_type >::NDIM; - using StackArrayTest< typename NDIM_POLICY_PAIR::first_type >::CAPACITY; - using POLICY = typename NDIM_POLICY_PAIR::second_type; + using PERMUTATION = typename PERMUTATION_POLICY_PAIR::first_type; + using POLICY = typename PERMUTATION_POLICY_PAIR::second_type; + + using ParentClass = StackArrayTest< PERMUTATION >; + using ParentClass::NDIM; + using ParentClass::CAPACITY; void captureInLambda() { this->init(); - stackArray< int, NDIM, CAPACITY > const & array = this->m_array; + StackArray< int, NDIM, PERMUTATION, INDEX_TYPE, CAPACITY > const & array = this->m_array; forall< POLICY >( 10, [array] LVARRAY_HOST_DEVICE ( int const ) { forValuesInSliceWithIndices( array.toSlice(), [] ( int & value, auto const ... indices ) { - int const index = toLinearIndex( indices ... ); + INDEX_TYPE const index = toLinearIndex( indices ... ); PORTABLE_EXPECT_EQ( value, index ); } ); } ); @@ -148,10 +155,10 @@ class StackArrayCaptureTest : public StackArrayTest< typename NDIM_POLICY_PAIR:: static void createInLambda() { - int const capacity = CAPACITY; - forall< POLICY >( 10, [capacity] LVARRAY_HOST_DEVICE ( int ) + INDEX_TYPE const capacity = CAPACITY; + forall< POLICY >( 10, [capacity] LVARRAY_HOST_DEVICE ( INDEX_TYPE ) { - stackArray< int, NDIM, CAPACITY > const array; + StackArray< int, NDIM, PERMUTATION, INDEX_TYPE, CAPACITY > const array; PORTABLE_EXPECT_EQ( array.size(), 0 ); PORTABLE_EXPECT_EQ( array.capacity(), capacity ); @@ -160,14 +167,14 @@ class StackArrayCaptureTest : public StackArrayTest< typename NDIM_POLICY_PAIR:: static void resizeInLambda() { - int dims[ NDIM ]; + INDEX_TYPE dims[ NDIM ]; for( int i = 0; i < NDIM; ++i ) { dims[ i ] = 8; } - int const capacity = CAPACITY; + INDEX_TYPE const capacity = CAPACITY; forall< POLICY >( 10, [dims, capacity] LVARRAY_HOST_DEVICE ( int ) { - stackArray< int, NDIM, CAPACITY > array; + StackArray< int, NDIM, PERMUTATION, INDEX_TYPE, CAPACITY > array; PORTABLE_EXPECT_EQ( array.size(), 0 ); PORTABLE_EXPECT_EQ( array.capacity(), capacity ); @@ -180,18 +187,17 @@ class StackArrayCaptureTest : public StackArrayTest< typename NDIM_POLICY_PAIR:: } ); } -#if defined(USE_CUDA) - /// This needs to use the parallelDevice policy because you can't next host-device lambdas. + /// This needs to use the parallelDevice policy because you can't nest host-device lambdas. static void resizeMultipleInLambda() { - int dims[ NDIM ]; + INDEX_TYPE dims[ NDIM ]; for( int i = 0; i < NDIM; ++i ) { dims[ i ] = 8; } - int const capacity = CAPACITY; - forall< parallelDevicePolicy< 32 > >( 10, [dims, capacity] LVARRAY_DEVICE ( int ) + INDEX_TYPE const capacity = CAPACITY; + forall< POLICY >( 10, [dims, capacity] LVARRAY_DEVICE ( int ) { - stackArray< int, NDIM, CAPACITY > array; + StackArray< int, NDIM, PERMUTATION, INDEX_TYPE, CAPACITY > array; PORTABLE_EXPECT_EQ( array.size(), 0 ); PORTABLE_EXPECT_EQ( array.capacity(), capacity ); @@ -202,10 +208,7 @@ class StackArrayCaptureTest : public StackArrayTest< typename NDIM_POLICY_PAIR:: PORTABLE_EXPECT_EQ( array.size(), capacity ); - forValuesInSliceWithIndices( array.toSlice(), [] LVARRAY_DEVICE ( int & value, auto const ... indices ) - { - value = toLinearIndex( indices ... ); - } ); + forValuesInSliceWithIndices( array.toSlice(), SetValue() ); array.resize( 2 ); @@ -215,67 +218,94 @@ class StackArrayCaptureTest : public StackArrayTest< typename NDIM_POLICY_PAIR:: PORTABLE_EXPECT_EQ( array.size(), array.capacity() / 4 ); - forValuesInSliceWithIndices( array.toSlice(), [] LVARRAY_DEVICE ( int & value, auto const ... indices ) - { - PORTABLE_EXPECT_EQ( value, toLinearIndex( indices ... ) ); - } ); + forValuesInSliceWithIndices( array.toSlice(), CheckValue() ); } ); } -#endif -}; -#if defined(USE_CUDA) -void sizedConstructorInLambda1D() -{ - int const SIZE = 8; - constexpr int CAPACITY = SIZE; - forall< parallelDevicePolicy< 32 > >( 10, [] LVARRAY_DEVICE ( int ) - { - stackArray< int, 1, CAPACITY > array( SIZE ); - PORTABLE_EXPECT_EQ( array.capacity(), CAPACITY ); - PORTABLE_EXPECT_EQ( array.size(), SIZE ); - PORTABLE_EXPECT_EQ( array.size( 0 ), SIZE ); - } ); -} + template< typename _PERMUTATION=PERMUTATION > + static std::enable_if_t< getDimension( _PERMUTATION {} ) == 1 > + sizedConstructorInLambda() + { + int capacity = CAPACITY; + forall< POLICY >( 10, [capacity] LVARRAY_DEVICE ( int ) + { + StackArray< int, NDIM, PERMUTATION, INDEX_TYPE, CAPACITY > array( CAPACITY ); + PORTABLE_EXPECT_EQ( array.capacity(), capacity ); + PORTABLE_EXPECT_EQ( array.size(), capacity ); + PORTABLE_EXPECT_EQ( array.size( 0 ), capacity ); + } ); + } -void sizedConstructorInLambda2D() -{ - constexpr int SIZE = 8; - constexpr int CAPACITY = SIZE * SIZE; - forall< parallelDevicePolicy< 32 > >( 10, [] LVARRAY_DEVICE ( int ) - { - stackArray< int, 2, CAPACITY > array( SIZE - 1, SIZE ); - PORTABLE_EXPECT_EQ( array.capacity(), CAPACITY ); - PORTABLE_EXPECT_EQ( array.size(), ( SIZE - 1 ) * SIZE ); - PORTABLE_EXPECT_EQ( array.size( 0 ), SIZE - 1 ); - PORTABLE_EXPECT_EQ( array.size( 1 ), SIZE ); - } ); -} + template< typename _PERMUTATION=PERMUTATION > + static std::enable_if_t< getDimension( _PERMUTATION {} ) == 2 > + sizedConstructorInLambda() + { + int capacity = CAPACITY; + int size = 8; + forall< POLICY >( 10, [capacity, size] LVARRAY_DEVICE ( int ) + { + StackArray< int, NDIM, PERMUTATION, INDEX_TYPE, CAPACITY > array( size - 1, size ); + PORTABLE_EXPECT_EQ( array.capacity(), capacity ); + PORTABLE_EXPECT_EQ( array.size(), ( size - 1 ) * size ); + PORTABLE_EXPECT_EQ( array.size( 0 ), size - 1 ); + PORTABLE_EXPECT_EQ( array.size( 1 ), size ); + } ); + } -void sizedConstructorInLambda3D() -{ - constexpr int SIZE = 8; - constexpr int CAPACITY = SIZE * SIZE * SIZE; - forall< parallelDevicePolicy< 32 > >( 10, [] LVARRAY_DEVICE ( int ) - { - stackArray< int, 3, CAPACITY > array( SIZE - 2, SIZE - 1, SIZE ); - PORTABLE_EXPECT_EQ( array.capacity(), CAPACITY ); - PORTABLE_EXPECT_EQ( array.size(), ( SIZE - 2 ) * ( SIZE - 1 ) * SIZE ); - PORTABLE_EXPECT_EQ( array.size( 0 ), SIZE - 2 ); - PORTABLE_EXPECT_EQ( array.size( 1 ), SIZE - 1 ); - PORTABLE_EXPECT_EQ( array.size( 2 ), SIZE ); - } ); -} -#endif + template< typename _PERMUTATION=PERMUTATION > + static std::enable_if_t< getDimension( _PERMUTATION {} ) == 3 > + sizedConstructorInLambda() + { + int capacity = CAPACITY; + int size = 8; + forall< POLICY >( 10, [capacity, size] LVARRAY_DEVICE ( int ) + { + StackArray< int, NDIM, PERMUTATION, INDEX_TYPE, CAPACITY > array( size - 2, size - 1, size ); + PORTABLE_EXPECT_EQ( array.capacity(), capacity ); + PORTABLE_EXPECT_EQ( array.size(), ( size - 2 ) * ( size - 1 ) * size ); + PORTABLE_EXPECT_EQ( array.size( 0 ), size - 2 ); + PORTABLE_EXPECT_EQ( array.size( 1 ), size - 1 ); + PORTABLE_EXPECT_EQ( array.size( 2 ), size ); + } ); + } + +private: + struct SetValue + { + template< typename ... INDICES > + LVARRAY_HOST_DEVICE void operator() ( int & value, INDICES const ... indices ) + { value = toLinearIndex( indices ... ); } + }; + + struct CheckValue + { + template< typename ... INDICES > + LVARRAY_HOST_DEVICE void operator() ( int & value, INDICES const ... indices ) + { PORTABLE_EXPECT_EQ( value, toLinearIndex( indices ... ) ); } + }; +}; using StackArrayCaptureTestTypes = ::testing::Types< - std::pair< std::integral_constant< int, 1 >, serialPolicy > - , std::pair< std::integral_constant< int, 2 >, serialPolicy > - , std::pair< std::integral_constant< int, 3 >, serialPolicy > + std::pair< RAJA::PERM_I, serialPolicy > + , std::pair< RAJA::PERM_IJ, serialPolicy > + , std::pair< RAJA::PERM_JI, serialPolicy > + , std::pair< RAJA::PERM_IJK, serialPolicy > + , std::pair< RAJA::PERM_IKJ, serialPolicy > + , std::pair< RAJA::PERM_JIK, serialPolicy > + , std::pair< RAJA::PERM_JKI, serialPolicy > + , std::pair< RAJA::PERM_KIJ, serialPolicy > + , std::pair< RAJA::PERM_KJI, serialPolicy > + #if defined(USE_CUDA) - , std::pair< std::integral_constant< int, 1 >, parallelDevicePolicy< 32 > > - , std::pair< std::integral_constant< int, 2 >, parallelDevicePolicy< 32 > > - , std::pair< std::integral_constant< int, 3 >, parallelDevicePolicy< 32 > > + , std::pair< RAJA::PERM_I, parallelDevicePolicy< 32 > > + , std::pair< RAJA::PERM_IJ, parallelDevicePolicy< 32 > > + , std::pair< RAJA::PERM_JI, parallelDevicePolicy< 32 > > + , std::pair< RAJA::PERM_IJK, parallelDevicePolicy< 32 > > + , std::pair< RAJA::PERM_IKJ, parallelDevicePolicy< 32 > > + , std::pair< RAJA::PERM_JIK, parallelDevicePolicy< 32 > > + , std::pair< RAJA::PERM_JKI, parallelDevicePolicy< 32 > > + , std::pair< RAJA::PERM_KIJ, parallelDevicePolicy< 32 > > + , std::pair< RAJA::PERM_KJI, parallelDevicePolicy< 32 > > #endif >; @@ -296,38 +326,16 @@ TYPED_TEST( StackArrayCaptureTest, resizeInLambda ) this->resizeInLambda(); } -#ifdef USE_CUDA -TEST( StackArrayCaptureTest, resizeMultipleInLambda1D ) +TYPED_TEST( StackArrayCaptureTest, resizeMultipleInLambda ) { - StackArrayCaptureTest< std::pair< std::integral_constant< int, 1 >, parallelDevicePolicy< 32 > > >::resizeMultipleInLambda(); + this->resizeMultipleInLambda(); } -TEST( StackArrayCaptureTest, resizeMultipleInLambda2D ) +TYPED_TEST( StackArrayCaptureTest, sizedConstructorInLambda ) { - StackArrayCaptureTest< std::pair< std::integral_constant< int, 2 >, parallelDevicePolicy< 32 > > >::resizeMultipleInLambda(); + this->sizedConstructorInLambda(); } -TEST( StackArrayCaptureTest, resizeMultipleInLambda3D ) -{ - StackArrayCaptureTest< std::pair< std::integral_constant< int, 3 >, parallelDevicePolicy< 32 > > >::resizeMultipleInLambda(); -} - -TEST( StackArrayCaptureTest, sizedConstructorInLambda1D ) -{ - sizedConstructorInLambda1D(); -} - -TEST( StackArrayCaptureTest, sizedConstructorInLambda2D ) -{ - sizedConstructorInLambda2D(); -} - -TEST( StackArrayCaptureTest, sizedConstructorInLambda3D ) -{ - sizedConstructorInLambda3D(); -} -#endif - } // namespace testing } // namespace LvArray diff --git a/unitTests/testTensorOpsCommon.hpp b/unitTests/testTensorOpsCommon.hpp index 44eb7274..d5655392 100644 --- a/unitTests/testTensorOpsCommon.hpp +++ b/unitTests/testTensorOpsCommon.hpp @@ -32,9 +32,17 @@ namespace LvArray namespace testing { +using INDEX_TYPE = std::ptrdiff_t; + +template< typename T, typename PERMUTATION > +using ArrayT = Array< T, getDimension( PERMUTATION {} ), PERMUTATION, std::ptrdiff_t, DEFAULT_BUFFER >; + +template< typename T, int NDIM, int USD > +using ArrayViewT = ArrayView< T, NDIM, USD, std::ptrdiff_t, DEFAULT_BUFFER >; + template< typename T, int NDIM, int USD, typename ... SIZES > LVARRAY_HOST_DEVICE -void fill( ArraySlice< T, NDIM, USD > const slice, std::ptrdiff_t offset ) +void fill( ArraySlice< T, NDIM, USD, INDEX_TYPE > const slice, std::ptrdiff_t offset ) { forValuesInSlice( slice, [&offset] ( T & value ) { diff --git a/unitTests/testTensorOpsFixedSize.cpp b/unitTests/testTensorOpsFixedSize.cpp index bb8d281a..3620b057 100644 --- a/unitTests/testTensorOpsFixedSize.cpp +++ b/unitTests/testTensorOpsFixedSize.cpp @@ -138,9 +138,9 @@ class FixedSizeSquareMatrixTest : public ::testing::Test void testDeterminant() { - ArrayView< T, 3, 2 > const & matrixA_IJK = m_matrixA_IJK.toView(); - ArrayView< T, 3, 1 > const & matrixA_IKJ = m_matrixA_IKJ.toView(); - ArrayView< T, 3, 0 > const & matrixA_KJI = m_matrixA_KJI.toView(); + ArrayViewT< T, 3, 2 > const & matrixA_IJK = m_matrixA_IJK.toView(); + ArrayViewT< T, 3, 1 > const & matrixA_IKJ = m_matrixA_IKJ.toView(); + ArrayViewT< T, 3, 0 > const & matrixA_KJI = m_matrixA_KJI.toView(); forall< POLICY >( 1, [matrixA_IJK, matrixA_IKJ, matrixA_KJI] LVARRAY_HOST_DEVICE ( int ) { @@ -165,13 +165,13 @@ class FixedSizeSquareMatrixTest : public ::testing::Test void testInverseTwoArgs() { - ArrayView< T, 3, 2 > const & matrixA_IJK = m_matrixA_IJK.toView(); - ArrayView< T, 3, 1 > const & matrixA_IKJ = m_matrixA_IKJ.toView(); - ArrayView< T, 3, 0 > const & matrixA_KJI = m_matrixA_KJI.toView(); + ArrayViewT< T, 3, 2 > const & matrixA_IJK = m_matrixA_IJK.toView(); + ArrayViewT< T, 3, 1 > const & matrixA_IKJ = m_matrixA_IKJ.toView(); + ArrayViewT< T, 3, 0 > const & matrixA_KJI = m_matrixA_KJI.toView(); - ArrayView< T, 3, 2 > const & matrixB_IJK = m_matrixB_IJK.toView(); - ArrayView< T, 3, 1 > const & matrixB_IKJ = m_matrixB_IKJ.toView(); - ArrayView< T, 3, 0 > const & matrixB_KJI = m_matrixB_KJI.toView(); + ArrayViewT< T, 3, 2 > const & matrixB_IJK = m_matrixB_IJK.toView(); + ArrayViewT< T, 3, 1 > const & matrixB_IKJ = m_matrixB_IKJ.toView(); + ArrayViewT< T, 3, 0 > const & matrixB_KJI = m_matrixB_KJI.toView(); std::ptrdiff_t const aSeed = m_seedMatrixA; forall< POLICY >( 1, [matrixA_IJK, matrixA_IKJ, matrixA_KJI, matrixB_IJK, matrixB_IKJ, matrixB_KJI, aSeed] LVARRAY_HOST_DEVICE ( int ) @@ -207,9 +207,9 @@ class FixedSizeSquareMatrixTest : public ::testing::Test void testInverseOneArg() { - ArrayView< T, 3, 2 > const & matrixA_IJK = m_matrixA_IJK.toView(); - ArrayView< T, 3, 1 > const & matrixA_IKJ = m_matrixA_IKJ.toView(); - ArrayView< T, 3, 0 > const & matrixA_KJI = m_matrixA_KJI.toView(); + ArrayViewT< T, 3, 2 > const & matrixA_IJK = m_matrixA_IJK.toView(); + ArrayViewT< T, 3, 1 > const & matrixA_IKJ = m_matrixA_IKJ.toView(); + ArrayViewT< T, 3, 0 > const & matrixA_KJI = m_matrixA_KJI.toView(); forall< POLICY >( 1, [matrixA_IJK, matrixA_IKJ, matrixA_KJI] LVARRAY_HOST_DEVICE ( int ) { @@ -242,15 +242,15 @@ class FixedSizeSquareMatrixTest : public ::testing::Test tensorOps::AijBj< N, N >( result, denseSymA, m_vectorB_local ); } - ArrayView< T, 2, 1 > const & vectorA_IJ = m_vectorA_IJ.toView(); - ArrayView< T, 2, 0 > const & vectorA_JI = m_vectorA_JI.toView(); + ArrayViewT< T, 2, 1 > const & vectorA_IJ = m_vectorA_IJ.toView(); + ArrayViewT< T, 2, 0 > const & vectorA_JI = m_vectorA_JI.toView(); - ArrayView< T const, 2, 1 > symMatrixA_IJ = m_symMatrixA_IJ.toViewConst(); - ArrayView< T const, 2, 0 > symMatrixA_JI = m_symMatrixA_JI.toViewConst(); + ArrayViewT< T const, 2, 1 > symMatrixA_IJ = m_symMatrixA_IJ.toViewConst(); + ArrayViewT< T const, 2, 0 > symMatrixA_JI = m_symMatrixA_JI.toViewConst(); T const ( &symMatrixA_local )[ SYM_SIZE ] = m_symMatrixA_local; - ArrayView< T const, 2, 1 > const & vectorB_IJ = m_vectorB_IJ.toViewConst(); - ArrayView< T const, 2, 0 > const & vectorB_JI = m_vectorB_JI.toViewConst(); + ArrayViewT< T const, 2, 1 > const & vectorB_IJ = m_vectorB_IJ.toViewConst(); + ArrayViewT< T const, 2, 0 > const & vectorB_JI = m_vectorB_JI.toViewConst(); T const ( &vectorB_local )[ N ] = m_vectorB_local; std::ptrdiff_t const vectorASeed = m_seedVectorA; @@ -297,15 +297,15 @@ class FixedSizeSquareMatrixTest : public ::testing::Test tensorOps::plusAijBj< N, N >( result, denseSymA, m_vectorB_local ); } - ArrayView< T, 2, 1 > const & vectorA_IJ = m_vectorA_IJ.toView(); - ArrayView< T, 2, 0 > const & vectorA_JI = m_vectorA_JI.toView(); + ArrayViewT< T, 2, 1 > const & vectorA_IJ = m_vectorA_IJ.toView(); + ArrayViewT< T, 2, 0 > const & vectorA_JI = m_vectorA_JI.toView(); - ArrayView< T const, 2, 1 > symMatrixA_IJ = m_symMatrixA_IJ.toViewConst(); - ArrayView< T const, 2, 0 > symMatrixA_JI = m_symMatrixA_JI.toViewConst(); + ArrayViewT< T const, 2, 1 > symMatrixA_IJ = m_symMatrixA_IJ.toViewConst(); + ArrayViewT< T const, 2, 0 > symMatrixA_JI = m_symMatrixA_JI.toViewConst(); T const ( &symMatrixA_local )[ SYM_SIZE ] = m_symMatrixA_local; - ArrayView< T const, 2, 1 > const & vectorB_IJ = m_vectorB_IJ.toViewConst(); - ArrayView< T const, 2, 0 > const & vectorB_JI = m_vectorB_JI.toViewConst(); + ArrayViewT< T const, 2, 1 > const & vectorB_IJ = m_vectorB_IJ.toViewConst(); + ArrayViewT< T const, 2, 0 > const & vectorB_JI = m_vectorB_JI.toViewConst(); T const ( &vectorB_local )[ N ] = m_vectorB_local; std::ptrdiff_t const vectorASeed = m_seedVectorA; @@ -351,17 +351,17 @@ class FixedSizeSquareMatrixTest : public ::testing::Test tensorOps::AikBjk< N, N, N >( result, denseSymA, m_matrixB_local ); } - ArrayView< T, 3, 2 > const & matrixA_IJK = m_matrixA_IJK.toView(); - ArrayView< T, 3, 1 > const & matrixA_IKJ = m_matrixA_IKJ.toView(); - ArrayView< T, 3, 0 > const & matrixA_KJI = m_matrixA_KJI.toView(); + ArrayViewT< T, 3, 2 > const & matrixA_IJK = m_matrixA_IJK.toView(); + ArrayViewT< T, 3, 1 > const & matrixA_IKJ = m_matrixA_IKJ.toView(); + ArrayViewT< T, 3, 0 > const & matrixA_KJI = m_matrixA_KJI.toView(); - ArrayView< T const, 2, 1 > symMatrixA_IJ = m_symMatrixA_IJ.toViewConst(); - ArrayView< T const, 2, 0 > symMatrixA_JI = m_symMatrixA_JI.toViewConst(); + ArrayViewT< T const, 2, 1 > symMatrixA_IJ = m_symMatrixA_IJ.toViewConst(); + ArrayViewT< T const, 2, 0 > symMatrixA_JI = m_symMatrixA_JI.toViewConst(); T const ( &symMatrixA_local )[ SYM_SIZE ] = m_symMatrixA_local; - ArrayView< T const, 3, 2 > const & matrixB_IJK = m_matrixB_IJK.toViewConst(); - ArrayView< T const, 3, 1 > const & matrixB_IKJ = m_matrixB_IKJ.toViewConst(); - ArrayView< T const, 3, 0 > const & matrixB_KJI = m_matrixB_KJI.toViewConst(); + ArrayViewT< T const, 3, 2 > const & matrixB_IJK = m_matrixB_IJK.toViewConst(); + ArrayViewT< T const, 3, 1 > const & matrixB_IKJ = m_matrixB_IKJ.toViewConst(); + ArrayViewT< T const, 3, 0 > const & matrixB_KJI = m_matrixB_KJI.toViewConst(); T const ( &matrixB_local )[ N ][ N ] = m_matrixB_local; std::ptrdiff_t const matrixASeed = m_seedMatrixA; @@ -417,16 +417,16 @@ class FixedSizeSquareMatrixTest : public ::testing::Test denseToSymmetric( std::integral_constant< int, N > {}, result, denseResult ); } - ArrayView< T, 2, 1 > symMatrixA_IJ = m_symMatrixA_IJ.toView(); - ArrayView< T, 2, 0 > symMatrixA_JI = m_symMatrixA_JI.toView(); + ArrayViewT< T, 2, 1 > symMatrixA_IJ = m_symMatrixA_IJ.toView(); + ArrayViewT< T, 2, 0 > symMatrixA_JI = m_symMatrixA_JI.toView(); - ArrayView< T const, 3, 2 > const & matrixA_IJK = m_matrixA_IJK.toViewConst(); - ArrayView< T const, 3, 1 > const & matrixA_IKJ = m_matrixA_IKJ.toViewConst(); - ArrayView< T const, 3, 0 > const & matrixA_KJI = m_matrixA_KJI.toViewConst(); + ArrayViewT< T const, 3, 2 > const & matrixA_IJK = m_matrixA_IJK.toViewConst(); + ArrayViewT< T const, 3, 1 > const & matrixA_IKJ = m_matrixA_IKJ.toViewConst(); + ArrayViewT< T const, 3, 0 > const & matrixA_KJI = m_matrixA_KJI.toViewConst(); T const ( &matrixA_local )[ N ][ N ] = m_matrixA_local; - ArrayView< T const, 2, 1 > symMatrixB_IJ = m_symMatrixB_IJ.toViewConst(); - ArrayView< T const, 2, 0 > symMatrixB_JI = m_symMatrixB_JI.toViewConst(); + ArrayViewT< T const, 2, 1 > symMatrixB_IJ = m_symMatrixB_IJ.toViewConst(); + ArrayViewT< T const, 2, 0 > symMatrixB_JI = m_symMatrixB_JI.toViewConst(); T const ( &symMatrixB_local )[ SYM_SIZE ] = m_symMatrixB_local; std::ptrdiff_t const matrixASeed = m_seedMatrixA; @@ -536,42 +536,44 @@ class FixedSizeSquareMatrixTest : public ::testing::Test } std::ptrdiff_t const m_seedVectorA = 0; - Array< T, 2, RAJA::PERM_IJ > m_vectorA_IJ { 1, N }; - Array< T, 2, RAJA::PERM_JI > m_vectorA_JI { 1, N }; + ArrayT< T, RAJA::PERM_IJ > m_vectorA_IJ { 1, N }; + ArrayT< T, RAJA::PERM_JI > m_vectorA_JI { 1, N }; T m_vectorA_local[ N ]; std::ptrdiff_t const m_seedVectorB = m_seedVectorA + N; - Array< T, 2, RAJA::PERM_IJ > m_vectorB_IJ { 1, N }; - Array< T, 2, RAJA::PERM_JI > m_vectorB_JI { 1, N }; + ArrayT< T, RAJA::PERM_IJ > m_vectorB_IJ { 1, N }; + ArrayT< T, RAJA::PERM_JI > m_vectorB_JI { 1, N }; T m_vectorB_local[ N ]; std::ptrdiff_t const m_seedMatrixA = m_seedVectorB + N; - Array< T, 3, RAJA::PERM_IJK > m_matrixA_IJK { 1, N, N }; - Array< T, 3, RAJA::PERM_IKJ > m_matrixA_IKJ { 1, N, N }; - Array< T, 3, RAJA::PERM_KJI > m_matrixA_KJI { 1, N, N }; + ArrayT< T, RAJA::PERM_IJK > m_matrixA_IJK { 1, N, N }; + ArrayT< T, RAJA::PERM_IKJ > m_matrixA_IKJ { 1, N, N }; + ArrayT< T, RAJA::PERM_KJI > m_matrixA_KJI { 1, N, N }; T m_matrixA_local[ N ][ N ]; std::ptrdiff_t const m_seedMatrixB = m_seedMatrixA + N * N; - Array< T, 3, RAJA::PERM_IJK > m_matrixB_IJK { 1, N, N }; - Array< T, 3, RAJA::PERM_IKJ > m_matrixB_IKJ { 1, N, N }; - Array< T, 3, RAJA::PERM_KJI > m_matrixB_KJI { 1, N, N }; + ArrayT< T, RAJA::PERM_IJK > m_matrixB_IJK { 1, N, N }; + ArrayT< T, RAJA::PERM_IKJ > m_matrixB_IKJ { 1, N, N }; + ArrayT< T, RAJA::PERM_KJI > m_matrixB_KJI { 1, N, N }; T m_matrixB_local[ N ][ N ]; std::ptrdiff_t const m_seedSymMatrixA = 0; - Array< T, 2, RAJA::PERM_IJ > m_symMatrixA_IJ { 1, SYM_SIZE }; - Array< T, 2, RAJA::PERM_JI > m_symMatrixA_JI { 1, SYM_SIZE }; + ArrayT< T, RAJA::PERM_IJ > m_symMatrixA_IJ { 1, SYM_SIZE }; + ArrayT< T, RAJA::PERM_JI > m_symMatrixA_JI { 1, SYM_SIZE }; T m_symMatrixA_local[ SYM_SIZE ]; std::ptrdiff_t const m_seedSymMatrixB = m_seedSymMatrixA + N; - Array< T, 2, RAJA::PERM_IJ > m_symMatrixB_IJ { 1, SYM_SIZE}; - Array< T, 2, RAJA::PERM_JI > m_symMatrixB_JI { 1, SYM_SIZE }; + ArrayT< T, RAJA::PERM_IJ > m_symMatrixB_IJ { 1, SYM_SIZE}; + ArrayT< T, RAJA::PERM_JI > m_symMatrixB_JI { 1, SYM_SIZE }; T m_symMatrixB_local[ SYM_SIZE ]; }; using FixedSizeSquareMatrixTestTypes = ::testing::Types< std::tuple< double, std::integral_constant< int, 2 >, serialPolicy > , std::tuple< double, std::integral_constant< int, 3 >, serialPolicy > -#if defined(USE_CUDA) + +// TODO: These tests can be run without chai and only using the c-arrays. +#if defined(USE_CUDA) && defined(USE_CHAI) , std::tuple< double, std::integral_constant< int, 2 >, parallelDevicePolicy< 32 > > , std::tuple< double, std::integral_constant< int, 3 >, parallelDevicePolicy< 32 > > #endif diff --git a/unitTests/testTensorOpsNoSize.cpp b/unitTests/testTensorOpsNoSize.cpp index e29df285..4417cd66 100644 --- a/unitTests/testTensorOpsNoSize.cpp +++ b/unitTests/testTensorOpsNoSize.cpp @@ -74,8 +74,8 @@ class NoSizeTest : public ::testing::Test void testInit2() { - ArrayView< T const, 2, 1 > const & vectorA2_IJ = m_vectorA2_IJ.toViewConst(); - ArrayView< T const, 2, 0 > const & vectorA2_JI = m_vectorA2_JI.toViewConst(); + ArrayViewT< T const, 2, 1 > const & vectorA2_IJ = m_vectorA2_IJ.toViewConst(); + ArrayViewT< T const, 2, 0 > const & vectorA2_JI = m_vectorA2_JI.toViewConst(); T const ( &vectorA2_local )[ 2 ] = m_vectorA2_local; forall< POLICY >( 1, [vectorA2_IJ, vectorA2_JI, vectorA2_local] LVARRAY_HOST_DEVICE ( int ) @@ -102,8 +102,8 @@ class NoSizeTest : public ::testing::Test void testInit3() { - ArrayView< T const, 2, 1 > const & vectorA3_IJ = m_vectorA3_IJ.toViewConst(); - ArrayView< T const, 2, 0 > const & vectorA3_JI = m_vectorA3_JI.toViewConst(); + ArrayViewT< T const, 2, 1 > const & vectorA3_IJ = m_vectorA3_IJ.toViewConst(); + ArrayViewT< T const, 2, 0 > const & vectorA3_JI = m_vectorA3_JI.toViewConst(); T const ( &vectorA3_local )[ 3 ] = m_vectorA3_local; forall< POLICY >( 1, [vectorA3_IJ, vectorA3_JI, vectorA3_local] LVARRAY_HOST_DEVICE ( int ) @@ -130,8 +130,8 @@ class NoSizeTest : public ::testing::Test void testInit6() { - ArrayView< T const, 2, 1 > const & vectorA6_IJ = m_vectorA6_IJ.toViewConst(); - ArrayView< T const, 2, 0 > const & vectorA6_JI = m_vectorA6_JI.toViewConst(); + ArrayViewT< T const, 2, 1 > const & vectorA6_IJ = m_vectorA6_IJ.toViewConst(); + ArrayViewT< T const, 2, 0 > const & vectorA6_JI = m_vectorA6_JI.toViewConst(); T const ( &vectorA6_local )[ 6 ] = m_vectorA6_local; forall< POLICY >( 1, [vectorA6_IJ, vectorA6_JI, vectorA6_local] LVARRAY_HOST_DEVICE ( int ) @@ -158,9 +158,9 @@ class NoSizeTest : public ::testing::Test void testInit2x2() { - ArrayView< T, 3, 2 > const & matrixA2_IJK = m_matrixA2_IJK.toView(); - ArrayView< T, 3, 1 > const & matrixA2_IKJ = m_matrixA2_IKJ.toView(); - ArrayView< T, 3, 0 > const & matrixA2_KJI = m_matrixA2_KJI.toView(); + ArrayViewT< T, 3, 2 > const & matrixA2_IJK = m_matrixA2_IJK.toView(); + ArrayViewT< T, 3, 1 > const & matrixA2_IKJ = m_matrixA2_IKJ.toView(); + ArrayViewT< T, 3, 0 > const & matrixA2_KJI = m_matrixA2_KJI.toView(); T const ( &matrixA2_local )[ 2 ][ 2 ] = m_matrixA2_local; forall< POLICY >( 1, [matrixA2_IJK, matrixA2_IKJ, matrixA2_KJI, matrixA2_local] LVARRAY_HOST_DEVICE ( int ) @@ -213,9 +213,9 @@ class NoSizeTest : public ::testing::Test void testInit3x3() { - ArrayView< T, 3, 2 > const & matrixA3_IJK = m_matrixA3_IJK.toView(); - ArrayView< T, 3, 1 > const & matrixA3_IKJ = m_matrixA3_IKJ.toView(); - ArrayView< T, 3, 0 > const & matrixA3_KJI = m_matrixA3_KJI.toView(); + ArrayViewT< T, 3, 2 > const & matrixA3_IJK = m_matrixA3_IJK.toView(); + ArrayViewT< T, 3, 1 > const & matrixA3_IKJ = m_matrixA3_IKJ.toView(); + ArrayViewT< T, 3, 0 > const & matrixA3_KJI = m_matrixA3_KJI.toView(); T const ( &matrixA3_local )[ 3 ][ 3 ] = m_matrixA3_local; forall< POLICY >( 1, [matrixA3_IJK, matrixA3_IKJ, matrixA3_KJI, matrixA3_local] LVARRAY_HOST_DEVICE ( int ) @@ -273,15 +273,15 @@ class NoSizeTest : public ::testing::Test result[ 1 ] = m_vectorB3_local[ 2 ] * m_vectorC3_local[ 0 ] - m_vectorB3_local[ 0 ] * m_vectorC3_local[ 2 ]; result[ 2 ] = m_vectorB3_local[ 0 ] * m_vectorC3_local[ 1 ] - m_vectorB3_local[ 1 ] * m_vectorC3_local[ 0 ]; - ArrayView< T, 2, 1 > const & vectorA3_IJ = m_vectorA3_IJ.toView(); - ArrayView< T, 2, 0 > const & vectorA3_JI = m_vectorA3_JI.toView(); + ArrayViewT< T, 2, 1 > const & vectorA3_IJ = m_vectorA3_IJ.toView(); + ArrayViewT< T, 2, 0 > const & vectorA3_JI = m_vectorA3_JI.toView(); - ArrayView< T const, 2, 1 > const & vectorB3_IJ = m_vectorB3_IJ.toViewConst(); - ArrayView< T const, 2, 0 > const & vectorB3_JI = m_vectorB3_JI.toViewConst(); + ArrayViewT< T const, 2, 1 > const & vectorB3_IJ = m_vectorB3_IJ.toViewConst(); + ArrayViewT< T const, 2, 0 > const & vectorB3_JI = m_vectorB3_JI.toViewConst(); T const ( &vectorB3_local )[ 3 ] = m_vectorB3_local; - ArrayView< T const, 2, 1 > const & vectorC3_IJ = m_vectorC3_IJ.toViewConst(); - ArrayView< T const, 2, 0 > const & vectorC3_JI = m_vectorC3_JI.toViewConst(); + ArrayViewT< T const, 2, 1 > const & vectorC3_IJ = m_vectorC3_IJ.toViewConst(); + ArrayViewT< T const, 2, 0 > const & vectorC3_JI = m_vectorC3_JI.toViewConst(); T const ( &vectorC3_local )[ 3 ] = m_vectorC3_local; std::ptrdiff_t const aSeed = m_seedVectorA3; @@ -319,47 +319,49 @@ class NoSizeTest : public ::testing::Test private: std::ptrdiff_t const m_seedVectorA2 = 0; - Array< T, 2, RAJA::PERM_IJ > m_vectorA2_IJ { 1, 2 }; - Array< T, 2, RAJA::PERM_JI > m_vectorA2_JI { 1, 2 }; + ArrayT< T, RAJA::PERM_IJ > m_vectorA2_IJ { 1, 2 }; + ArrayT< T, RAJA::PERM_JI > m_vectorA2_JI { 1, 2 }; T m_vectorA2_local[ 2 ]; std::ptrdiff_t const m_seedVectorA3 = m_seedVectorA2 + 2; - Array< T, 2, RAJA::PERM_IJ > m_vectorA3_IJ { 1, 3 }; - Array< T, 2, RAJA::PERM_JI > m_vectorA3_JI { 1, 3 }; + ArrayT< T, RAJA::PERM_IJ > m_vectorA3_IJ { 1, 3 }; + ArrayT< T, RAJA::PERM_JI > m_vectorA3_JI { 1, 3 }; T m_vectorA3_local[ 3 ]; std::ptrdiff_t const m_seedVectorB3 = m_seedVectorA3 + 3; - Array< T, 2, RAJA::PERM_IJ > m_vectorB3_IJ { 1, 3 }; - Array< T, 2, RAJA::PERM_JI > m_vectorB3_JI { 1, 3 }; + ArrayT< T, RAJA::PERM_IJ > m_vectorB3_IJ { 1, 3 }; + ArrayT< T, RAJA::PERM_JI > m_vectorB3_JI { 1, 3 }; T m_vectorB3_local[ 3 ]; std::ptrdiff_t const m_seedVectorC3 = m_seedVectorB3 + 3; - Array< T, 2, RAJA::PERM_IJ > m_vectorC3_IJ { 1, 3 }; - Array< T, 2, RAJA::PERM_JI > m_vectorC3_JI { 1, 3 }; + ArrayT< T, RAJA::PERM_IJ > m_vectorC3_IJ { 1, 3 }; + ArrayT< T, RAJA::PERM_JI > m_vectorC3_JI { 1, 3 }; T m_vectorC3_local[ 3 ]; std::ptrdiff_t const m_seedVectorA6 = m_seedVectorC3 + 3; - Array< T, 2, RAJA::PERM_IJ > m_vectorA6_IJ { 1, 6 }; - Array< T, 2, RAJA::PERM_JI > m_vectorA6_JI { 1, 6 }; + ArrayT< T, RAJA::PERM_IJ > m_vectorA6_IJ { 1, 6 }; + ArrayT< T, RAJA::PERM_JI > m_vectorA6_JI { 1, 6 }; T m_vectorA6_local[ 6 ]; std::ptrdiff_t const m_seedMatrixA2 = m_seedVectorA6 + 6; - Array< T, 3, RAJA::PERM_IJK > m_matrixA2_IJK { 1, 2, 2 }; - Array< T, 3, RAJA::PERM_IKJ > m_matrixA2_IKJ { 1, 2, 2 }; - Array< T, 3, RAJA::PERM_KJI > m_matrixA2_KJI { 1, 2, 2 }; + ArrayT< T, RAJA::PERM_IJK > m_matrixA2_IJK { 1, 2, 2 }; + ArrayT< T, RAJA::PERM_IKJ > m_matrixA2_IKJ { 1, 2, 2 }; + ArrayT< T, RAJA::PERM_KJI > m_matrixA2_KJI { 1, 2, 2 }; T m_matrixA2_local[ 2 ][ 2 ]; std::ptrdiff_t const m_seedMatrixA3 = m_seedMatrixA2 + 4; - Array< T, 3, RAJA::PERM_IJK > m_matrixA3_IJK { 1, 3, 3 }; - Array< T, 3, RAJA::PERM_IKJ > m_matrixA3_IKJ { 1, 3, 3 }; - Array< T, 3, RAJA::PERM_KJI > m_matrixA3_KJI { 1, 3, 3 }; + ArrayT< T, RAJA::PERM_IJK > m_matrixA3_IJK { 1, 3, 3 }; + ArrayT< T, RAJA::PERM_IKJ > m_matrixA3_IKJ { 1, 3, 3 }; + ArrayT< T, RAJA::PERM_KJI > m_matrixA3_KJI { 1, 3, 3 }; T m_matrixA3_local[ 3 ][ 3 ]; }; using NoSizeTestTypes = ::testing::Types< std::tuple< double, serialPolicy > , std::tuple< int, serialPolicy > -#if defined(USE_CUDA) + +// TODO: These tests can be run without chai and only using the c-arrays. +#if defined(USE_CUDA) && defined(USE_CHAI) , std::tuple< double, parallelDevicePolicy< 32 > > , std::tuple< int, parallelDevicePolicy< 32 > > #endif diff --git a/unitTests/testTensorOpsOneSize.cpp b/unitTests/testTensorOpsOneSize.cpp index 863d076b..5ee9b2f1 100644 --- a/unitTests/testTensorOpsOneSize.cpp +++ b/unitTests/testTensorOpsOneSize.cpp @@ -72,8 +72,8 @@ class OneSizeTest : public ::testing::Test for( std::ptrdiff_t i = 0; i < N; ++i ) { result[ i ] = m_vectorA_local[ i ] * scale; } - ArrayView< T, 2, 1 > const & vectorA_IJ = m_vectorA_IJ.toView(); - ArrayView< T, 2, 0 > const & vectorA_JI = m_vectorA_JI.toView(); + ArrayViewT< T, 2, 1 > const & vectorA_IJ = m_vectorA_IJ.toView(); + ArrayViewT< T, 2, 0 > const & vectorA_JI = m_vectorA_JI.toView(); std::ptrdiff_t const aSeed = m_seedVectorA; @@ -98,8 +98,8 @@ class OneSizeTest : public ::testing::Test for( std::ptrdiff_t i = 0; i < N; ++i ) { result += m_vectorA_local[ i ] * m_vectorA_local[ i ]; } - ArrayView< T const, 2, 1 > const & vectorA_IJ = m_vectorA_IJ.toViewConst(); - ArrayView< T const, 2, 0 > const & vectorA_JI = m_vectorA_JI.toViewConst(); + ArrayViewT< T const, 2, 1 > const & vectorA_IJ = m_vectorA_IJ.toViewConst(); + ArrayViewT< T const, 2, 0 > const & vectorA_JI = m_vectorA_JI.toViewConst(); T const ( &vectorA_local )[ N ] = m_vectorA_local; forall< POLICY >( 1, [result, vectorA_IJ, vectorA_JI, vectorA_local] LVARRAY_HOST_DEVICE ( int ) @@ -117,8 +117,8 @@ class OneSizeTest : public ::testing::Test { norm += m_vectorA_local[ i ] * m_vectorA_local[ i ]; } norm = sqrt( norm ); - ArrayView< T const, 2, 1 > const & vectorA_IJ = m_vectorA_IJ.toViewConst(); - ArrayView< T const, 2, 0 > const & vectorA_JI = m_vectorA_JI.toViewConst(); + ArrayViewT< T const, 2, 1 > const & vectorA_IJ = m_vectorA_IJ.toViewConst(); + ArrayViewT< T const, 2, 0 > const & vectorA_JI = m_vectorA_JI.toViewConst(); T const ( &vectorA_local )[ N ] = m_vectorA_local; forall< POLICY >( 1, [norm, vectorA_IJ, vectorA_JI, vectorA_local] LVARRAY_HOST_DEVICE ( int ) @@ -141,8 +141,8 @@ class OneSizeTest : public ::testing::Test for( std::ptrdiff_t i = 0; i < N; ++i ) { result [ i ] = m_vectorA_local[ i ] * invNorm; } - ArrayView< T, 2, 1 > const & vectorA_IJ = m_vectorA_IJ.toView(); - ArrayView< T, 2, 0 > const & vectorA_JI = m_vectorA_JI.toView(); + ArrayViewT< T, 2, 1 > const & vectorA_IJ = m_vectorA_IJ.toView(); + ArrayViewT< T, 2, 0 > const & vectorA_JI = m_vectorA_JI.toView(); std::ptrdiff_t const aSeed = m_seedVectorA; @@ -163,8 +163,8 @@ class OneSizeTest : public ::testing::Test void testFill() { - ArrayView< T, 2, 1 > const & vectorA_IJ = m_vectorA_IJ.toView(); - ArrayView< T, 2, 0 > const & vectorA_JI = m_vectorA_JI.toView(); + ArrayViewT< T, 2, 1 > const & vectorA_IJ = m_vectorA_IJ.toView(); + ArrayViewT< T, 2, 0 > const & vectorA_JI = m_vectorA_JI.toView(); forall< POLICY >( 1, [vectorA_IJ, vectorA_JI] LVARRAY_HOST_DEVICE ( int ) { @@ -193,8 +193,8 @@ class OneSizeTest : public ::testing::Test for( std::ptrdiff_t i = 0; i < N; ++i ) { maxEntry = std::max( std::abs( maxEntry ), m_vectorA_local[ i ] ); } - ArrayView< T, 2, 1 > const & vectorA_IJ = m_vectorA_IJ.toView(); - ArrayView< T, 2, 0 > const & vectorA_JI = m_vectorA_JI.toView(); + ArrayViewT< T, 2, 1 > const & vectorA_IJ = m_vectorA_IJ.toView(); + ArrayViewT< T, 2, 0 > const & vectorA_JI = m_vectorA_JI.toView(); std::ptrdiff_t const seedVectorA = m_seedVectorA; @@ -212,11 +212,11 @@ class OneSizeTest : public ::testing::Test void testCopy() { - ArrayView< T, 2, 1 > const & vectorA_IJ = m_vectorA_IJ.toView(); - ArrayView< T, 2, 0 > const & vectorA_JI = m_vectorA_JI.toView(); + ArrayViewT< T, 2, 1 > const & vectorA_IJ = m_vectorA_IJ.toView(); + ArrayViewT< T, 2, 0 > const & vectorA_JI = m_vectorA_JI.toView(); - ArrayView< T const, 2, 1 > const & vectorB_IJ = m_vectorB_IJ.toViewConst(); - ArrayView< T const, 2, 0 > const & vectorB_JI = m_vectorB_JI.toViewConst(); + ArrayViewT< T const, 2, 1 > const & vectorB_IJ = m_vectorB_IJ.toViewConst(); + ArrayViewT< T const, 2, 0 > const & vectorB_JI = m_vectorB_JI.toViewConst(); T const ( &vectorB_local )[ N ] = m_vectorB_local; std::ptrdiff_t const aSeed = m_seedVectorA; @@ -248,11 +248,11 @@ class OneSizeTest : public ::testing::Test void testScaledCopy() { T scale = T( 3.14 ); - ArrayView< T, 2, 1 > const & vectorA_IJ = m_vectorA_IJ.toView(); - ArrayView< T, 2, 0 > const & vectorA_JI = m_vectorA_JI.toView(); + ArrayViewT< T, 2, 1 > const & vectorA_IJ = m_vectorA_IJ.toView(); + ArrayViewT< T, 2, 0 > const & vectorA_JI = m_vectorA_JI.toView(); - ArrayView< T const, 2, 1 > const & vectorB_IJ = m_vectorB_IJ.toViewConst(); - ArrayView< T const, 2, 0 > const & vectorB_JI = m_vectorB_JI.toViewConst(); + ArrayViewT< T const, 2, 1 > const & vectorB_IJ = m_vectorB_IJ.toViewConst(); + ArrayViewT< T const, 2, 0 > const & vectorB_JI = m_vectorB_JI.toViewConst(); T const ( &vectorB_local )[ N ] = m_vectorB_local; std::ptrdiff_t const aSeed = m_seedVectorA; @@ -288,11 +288,11 @@ class OneSizeTest : public ::testing::Test for( std::ptrdiff_t i = 0; i < N; ++i ) { result[ i ] = m_vectorA_local[ i ] + m_vectorB_local[ i ]; } - ArrayView< T, 2, 1 > const & vectorA_IJ = m_vectorA_IJ.toView(); - ArrayView< T, 2, 0 > const & vectorA_JI = m_vectorA_JI.toView(); + ArrayViewT< T, 2, 1 > const & vectorA_IJ = m_vectorA_IJ.toView(); + ArrayViewT< T, 2, 0 > const & vectorA_JI = m_vectorA_JI.toView(); - ArrayView< T const, 2, 1 > const & vectorB_IJ = m_vectorB_IJ.toViewConst(); - ArrayView< T const, 2, 0 > const & vectorB_JI = m_vectorB_JI.toViewConst(); + ArrayViewT< T const, 2, 1 > const & vectorB_IJ = m_vectorB_IJ.toViewConst(); + ArrayViewT< T const, 2, 0 > const & vectorB_JI = m_vectorB_JI.toViewConst(); T const ( &vectorB_local )[ N ] = m_vectorB_local; std::ptrdiff_t const aSeed = m_seedVectorA; @@ -327,11 +327,11 @@ class OneSizeTest : public ::testing::Test for( std::ptrdiff_t i = 0; i < N; ++i ) { result[ i ] = m_vectorA_local[ i ] - m_vectorB_local[ i ]; } - ArrayView< T, 2, 1 > const & vectorA_IJ = m_vectorA_IJ.toView(); - ArrayView< T, 2, 0 > const & vectorA_JI = m_vectorA_JI.toView(); + ArrayViewT< T, 2, 1 > const & vectorA_IJ = m_vectorA_IJ.toView(); + ArrayViewT< T, 2, 0 > const & vectorA_JI = m_vectorA_JI.toView(); - ArrayView< T const, 2, 1 > const & vectorB_IJ = m_vectorB_IJ.toViewConst(); - ArrayView< T const, 2, 0 > const & vectorB_JI = m_vectorB_JI.toViewConst(); + ArrayViewT< T const, 2, 1 > const & vectorB_IJ = m_vectorB_IJ.toViewConst(); + ArrayViewT< T const, 2, 0 > const & vectorB_JI = m_vectorB_JI.toViewConst(); T const ( &vectorB_local )[ N ] = m_vectorB_local; std::ptrdiff_t const aSeed = m_seedVectorA; @@ -362,11 +362,11 @@ class OneSizeTest : public ::testing::Test void testScaledAdd() { - ArrayView< T, 2, 1 > const & vectorA_IJ = m_vectorA_IJ.toView(); - ArrayView< T, 2, 0 > const & vectorA_JI = m_vectorA_JI.toView(); + ArrayViewT< T, 2, 1 > const & vectorA_IJ = m_vectorA_IJ.toView(); + ArrayViewT< T, 2, 0 > const & vectorA_JI = m_vectorA_JI.toView(); - ArrayView< T const, 2, 1 > const & vectorB_IJ = m_vectorB_IJ.toViewConst(); - ArrayView< T const, 2, 0 > const & vectorB_JI = m_vectorB_JI.toViewConst(); + ArrayViewT< T const, 2, 1 > const & vectorB_IJ = m_vectorB_IJ.toViewConst(); + ArrayViewT< T const, 2, 0 > const & vectorB_JI = m_vectorB_JI.toViewConst(); T const ( &vectorB_local )[ N ] = m_vectorB_local; std::ptrdiff_t const aSeed = m_seedVectorA; @@ -406,12 +406,12 @@ class OneSizeTest : public ::testing::Test for( std::ptrdiff_t i = 0; i < N; ++i ) { expectedValue += m_vectorA_local[ i ] * m_vectorB_local[ i ]; } - ArrayView< T const, 2, 1 > const & vectorA_IJ = m_vectorA_IJ.toViewConst(); - ArrayView< T const, 2, 0 > const & vectorA_JI = m_vectorA_JI.toViewConst(); + ArrayViewT< T const, 2, 1 > const & vectorA_IJ = m_vectorA_IJ.toViewConst(); + ArrayViewT< T const, 2, 0 > const & vectorA_JI = m_vectorA_JI.toViewConst(); T const ( &vectorA_local )[ N ] = m_vectorA_local; - ArrayView< T const, 2, 1 > const & vectorB_IJ = m_vectorB_IJ.toViewConst(); - ArrayView< T const, 2, 0 > const & vectorB_JI = m_vectorB_JI.toViewConst(); + ArrayViewT< T const, 2, 1 > const & vectorB_IJ = m_vectorB_IJ.toViewConst(); + ArrayViewT< T const, 2, 0 > const & vectorB_JI = m_vectorB_JI.toViewConst(); T const ( &vectorB_local )[ N ] = m_vectorB_local; forall< POLICY >( 1, [expectedValue, vectorA_IJ, vectorA_JI, vectorB_IJ, vectorB_JI, vectorA_local, vectorB_local] LVARRAY_HOST_DEVICE ( int ) @@ -436,15 +436,15 @@ class OneSizeTest : public ::testing::Test for( std::ptrdiff_t i = 0; i < N; ++i ) { result[ i ] = m_vectorB_local[ i ] * m_vectorC_local[ i ]; } - ArrayView< T, 2, 1 > const & vectorA_IJ = m_vectorA_IJ.toView(); - ArrayView< T, 2, 0 > const & vectorA_JI = m_vectorA_JI.toView(); + ArrayViewT< T, 2, 1 > const & vectorA_IJ = m_vectorA_IJ.toView(); + ArrayViewT< T, 2, 0 > const & vectorA_JI = m_vectorA_JI.toView(); - ArrayView< T const, 2, 1 > const & vectorB_IJ = m_vectorB_IJ.toViewConst(); - ArrayView< T const, 2, 0 > const & vectorB_JI = m_vectorB_JI.toViewConst(); + ArrayViewT< T const, 2, 1 > const & vectorB_IJ = m_vectorB_IJ.toViewConst(); + ArrayViewT< T const, 2, 0 > const & vectorB_JI = m_vectorB_JI.toViewConst(); T const ( &vectorB_local )[ N ] = m_vectorB_local; - ArrayView< T const, 2, 1 > const & vectorC_IJ = m_vectorC_IJ.toViewConst(); - ArrayView< T const, 2, 0 > const & vectorC_JI = m_vectorC_JI.toViewConst(); + ArrayViewT< T const, 2, 1 > const & vectorC_IJ = m_vectorC_IJ.toViewConst(); + ArrayViewT< T const, 2, 0 > const & vectorC_JI = m_vectorC_JI.toViewConst(); T const ( &vectorC_local )[ N ] = m_vectorC_local; std::ptrdiff_t const aSeed = m_seedVectorA; @@ -488,9 +488,9 @@ class OneSizeTest : public ::testing::Test for( std::ptrdiff_t i = 0; i < N; ++i ) { result[ i ][ i ] += value; } - ArrayView< T, 3, 2 > const & matrixA_IJK = m_matrixA_IJK.toView(); - ArrayView< T, 3, 1 > const & matrixA_IKJ = m_matrixA_IKJ.toView(); - ArrayView< T, 3, 0 > const & matrixA_KJI = m_matrixA_KJI.toView(); + ArrayViewT< T, 3, 2 > const & matrixA_IJK = m_matrixA_IJK.toView(); + ArrayViewT< T, 3, 1 > const & matrixA_IKJ = m_matrixA_IKJ.toView(); + ArrayViewT< T, 3, 0 > const & matrixA_KJI = m_matrixA_KJI.toView(); std::ptrdiff_t const seedMatrixA = m_seedMatrixA; @@ -514,30 +514,30 @@ class OneSizeTest : public ::testing::Test private: std::ptrdiff_t const m_seedVectorA = 0; - Array< T, 2, RAJA::PERM_IJ > m_vectorA_IJ { 1, N }; - Array< T, 2, RAJA::PERM_JI > m_vectorA_JI { 1, N }; + ArrayT< T, RAJA::PERM_IJ > m_vectorA_IJ { 1, N }; + ArrayT< T, RAJA::PERM_JI > m_vectorA_JI { 1, N }; T m_vectorA_local[ N ]; std::ptrdiff_t const m_seedVectorB = m_seedVectorA + N; - Array< T, 2, RAJA::PERM_IJ > m_vectorB_IJ { 1, N }; - Array< T, 2, RAJA::PERM_JI > m_vectorB_JI { 1, N }; + ArrayT< T, RAJA::PERM_IJ > m_vectorB_IJ { 1, N }; + ArrayT< T, RAJA::PERM_JI > m_vectorB_JI { 1, N }; T m_vectorB_local[ N ]; std::ptrdiff_t const m_seedVectorC = m_seedVectorB + N; - Array< T, 2, RAJA::PERM_IJ > m_vectorC_IJ { 1, N }; - Array< T, 2, RAJA::PERM_JI > m_vectorC_JI { 1, N }; + ArrayT< T, RAJA::PERM_IJ > m_vectorC_IJ { 1, N }; + ArrayT< T, RAJA::PERM_JI > m_vectorC_JI { 1, N }; T m_vectorC_local[ N ]; std::ptrdiff_t const m_seedMatrixA = m_seedVectorC + N; - Array< T, 3, RAJA::PERM_IJK > m_matrixA_IJK { 1, N, N }; - Array< T, 3, RAJA::PERM_IKJ > m_matrixA_IKJ { 1, N, N }; - Array< T, 3, RAJA::PERM_KJI > m_matrixA_KJI { 1, N, N }; + ArrayT< T, RAJA::PERM_IJK > m_matrixA_IJK { 1, N, N }; + ArrayT< T, RAJA::PERM_IKJ > m_matrixA_IKJ { 1, N, N }; + ArrayT< T, RAJA::PERM_KJI > m_matrixA_KJI { 1, N, N }; T m_matrixA_local[ N ][ N ]; std::ptrdiff_t const m_seedMatrixB = m_seedMatrixA + N * N; - Array< T, 3, RAJA::PERM_IJK > m_matrixB_IJK { 1, N, N }; - Array< T, 3, RAJA::PERM_IKJ > m_matrixB_IKJ { 1, N, N }; - Array< T, 3, RAJA::PERM_KJI > m_matrixB_KJI { 1, N, N }; + ArrayT< T, RAJA::PERM_IJK > m_matrixB_IJK { 1, N, N }; + ArrayT< T, RAJA::PERM_IKJ > m_matrixB_IKJ { 1, N, N }; + ArrayT< T, RAJA::PERM_KJI > m_matrixB_KJI { 1, N, N }; T m_matrixB_local[ N ][ N ]; }; @@ -546,7 +546,9 @@ using OneSizeTestTypes = ::testing::Types< std::tuple< double, std::integral_constant< int, 2 >, serialPolicy > , std::tuple< int, std::integral_constant< int, 3 >, serialPolicy > , std::tuple< double, std::integral_constant< int, 6 >, serialPolicy > -#if defined(USE_CUDA) + +// TODO: These tests can be run without chai and only using the c-arrays. +#if defined(USE_CUDA) && defined(USE_CHAI) , std::tuple< double, std::integral_constant< int, 2 >, parallelDevicePolicy< 32 > > , std::tuple< int, std::integral_constant< int, 3 >, parallelDevicePolicy< 32 > > , std::tuple< double, std::integral_constant< int, 6 >, parallelDevicePolicy< 32 > > diff --git a/unitTests/testTensorOpsThreeSizes.hpp b/unitTests/testTensorOpsThreeSizes.hpp index 8a1e7e42..04839f1b 100644 --- a/unitTests/testTensorOpsThreeSizes.hpp +++ b/unitTests/testTensorOpsThreeSizes.hpp @@ -82,18 +82,18 @@ class ThreeSizesTest : public ::testing::Test } } - ArrayView< T, 3, 2 > const & matrixNM_IJK = m_matrixNM_IJK.toView(); - ArrayView< T, 3, 1 > const & matrixNM_IKJ = m_matrix_NM_IKJ.toView(); - ArrayView< T, 3, 0 > const & matrixNM_KJI = m_matrix_NM_KJI.toView(); + ArrayViewT< T, 3, 2 > const & matrixNM_IJK = m_matrixNM_IJK.toView(); + ArrayViewT< T, 3, 1 > const & matrixNM_IKJ = m_matrix_NM_IKJ.toView(); + ArrayViewT< T, 3, 0 > const & matrixNM_KJI = m_matrix_NM_KJI.toView(); - ArrayView< T const, 3, 2 > const & matrixML_IJK = m_matrixNL_IJK.toViewConst(); - ArrayView< T const, 3, 1 > const & matrixML_IKJ = m_matrixNL_IKJ.toViewConst(); - ArrayView< T const, 3, 0 > const & matrixML_KJI = m_matrixNL_KJI.toViewConst(); + ArrayViewT< T const, 3, 2 > const & matrixML_IJK = m_matrixNL_IJK.toViewConst(); + ArrayViewT< T const, 3, 1 > const & matrixML_IKJ = m_matrixNL_IKJ.toViewConst(); + ArrayViewT< T const, 3, 0 > const & matrixML_KJI = m_matrixNL_KJI.toViewConst(); T const ( &matrixML_local )[ N ][ L ] = m_matrixNL_local; - ArrayView< T const, 3, 2 > const & matrixLM_IJK = m_matrixLM_IJK.toViewConst(); - ArrayView< T const, 3, 1 > const & matrixLM_IKJ = m_matrixLM_IKJ.toViewConst(); - ArrayView< T const, 3, 0 > const & matrixLM_KJI = m_matrixLM_KJI.toViewConst(); + ArrayViewT< T const, 3, 2 > const & matrixLM_IJK = m_matrixLM_IJK.toViewConst(); + ArrayViewT< T const, 3, 1 > const & matrixLM_IKJ = m_matrixLM_IKJ.toViewConst(); + ArrayViewT< T const, 3, 0 > const & matrixLM_KJI = m_matrixLM_KJI.toViewConst(); T const ( &matrixLM_local )[ L ][ M ] = m_matrixLM_local; std::ptrdiff_t const matrixNMSeed = m_matrixNMSeed; @@ -154,18 +154,18 @@ class ThreeSizesTest : public ::testing::Test } } - ArrayView< T, 3, 2 > const & matrixNM_IJK = m_matrixNM_IJK.toView(); - ArrayView< T, 3, 1 > const & matrixNM_IKJ = m_matrix_NM_IKJ.toView(); - ArrayView< T, 3, 0 > const & matrixNM_KJI = m_matrix_NM_KJI.toView(); + ArrayViewT< T, 3, 2 > const & matrixNM_IJK = m_matrixNM_IJK.toView(); + ArrayViewT< T, 3, 1 > const & matrixNM_IKJ = m_matrix_NM_IKJ.toView(); + ArrayViewT< T, 3, 0 > const & matrixNM_KJI = m_matrix_NM_KJI.toView(); - ArrayView< T const, 3, 2 > const & matrixML_IJK = m_matrixNL_IJK.toViewConst(); - ArrayView< T const, 3, 1 > const & matrixML_IKJ = m_matrixNL_IKJ.toViewConst(); - ArrayView< T const, 3, 0 > const & matrixML_KJI = m_matrixNL_KJI.toViewConst(); + ArrayViewT< T const, 3, 2 > const & matrixML_IJK = m_matrixNL_IJK.toViewConst(); + ArrayViewT< T const, 3, 1 > const & matrixML_IKJ = m_matrixNL_IKJ.toViewConst(); + ArrayViewT< T const, 3, 0 > const & matrixML_KJI = m_matrixNL_KJI.toViewConst(); T const ( &matrixML_local )[ N ][ L ] = m_matrixNL_local; - ArrayView< T const, 3, 2 > const & matrixLM_IJK = m_matrixLM_IJK.toViewConst(); - ArrayView< T const, 3, 1 > const & matrixLM_IKJ = m_matrixLM_IKJ.toViewConst(); - ArrayView< T const, 3, 0 > const & matrixLM_KJI = m_matrixLM_KJI.toViewConst(); + ArrayViewT< T const, 3, 2 > const & matrixLM_IJK = m_matrixLM_IJK.toViewConst(); + ArrayViewT< T const, 3, 1 > const & matrixLM_IKJ = m_matrixLM_IKJ.toViewConst(); + ArrayViewT< T const, 3, 0 > const & matrixLM_KJI = m_matrixLM_KJI.toViewConst(); T const ( &matrixLM_local )[ L ][ M ] = m_matrixLM_local; std::ptrdiff_t const matrixNMSeed = m_matrixNMSeed; @@ -226,18 +226,18 @@ class ThreeSizesTest : public ::testing::Test } } - ArrayView< T, 3, 2 > const & matrixNM_IJK = m_matrixNM_IJK.toView(); - ArrayView< T, 3, 1 > const & matrixNM_IKJ = m_matrix_NM_IKJ.toView(); - ArrayView< T, 3, 0 > const & matrixNM_KJI = m_matrix_NM_KJI.toView(); + ArrayViewT< T, 3, 2 > const & matrixNM_IJK = m_matrixNM_IJK.toView(); + ArrayViewT< T, 3, 1 > const & matrixNM_IKJ = m_matrix_NM_IKJ.toView(); + ArrayViewT< T, 3, 0 > const & matrixNM_KJI = m_matrix_NM_KJI.toView(); - ArrayView< T const, 3, 2 > const & matrixNL_IJK = m_matrixNL_IJK.toViewConst(); - ArrayView< T const, 3, 1 > const & matrixNL_IKJ = m_matrixNL_IKJ.toViewConst(); - ArrayView< T const, 3, 0 > const & matrixNL_KJI = m_matrixNL_KJI.toViewConst(); + ArrayViewT< T const, 3, 2 > const & matrixNL_IJK = m_matrixNL_IJK.toViewConst(); + ArrayViewT< T const, 3, 1 > const & matrixNL_IKJ = m_matrixNL_IKJ.toViewConst(); + ArrayViewT< T const, 3, 0 > const & matrixNL_KJI = m_matrixNL_KJI.toViewConst(); T const ( &matrixNL_local )[ N ][ L ] = m_matrixNL_local; - ArrayView< T const, 3, 2 > const & matrixML_IJK = m_matrixML_IJK.toViewConst(); - ArrayView< T const, 3, 1 > const & matrixML_IKJ = m_matrixML_IKJ.toViewConst(); - ArrayView< T const, 3, 0 > const & matrixML_KJI = m_matrixML_KJI.toViewConst(); + ArrayViewT< T const, 3, 2 > const & matrixML_IJK = m_matrixML_IJK.toViewConst(); + ArrayViewT< T const, 3, 1 > const & matrixML_IKJ = m_matrixML_IKJ.toViewConst(); + ArrayViewT< T const, 3, 0 > const & matrixML_KJI = m_matrixML_KJI.toViewConst(); T const ( &matrixML_local )[ M ][ L ] = m_matrixML_local; std::ptrdiff_t const matrixNMSeed = m_matrixNMSeed; @@ -298,18 +298,18 @@ class ThreeSizesTest : public ::testing::Test } } - ArrayView< T, 3, 2 > const & matrixNM_IJK = m_matrixNM_IJK.toView(); - ArrayView< T, 3, 1 > const & matrixNM_IKJ = m_matrix_NM_IKJ.toView(); - ArrayView< T, 3, 0 > const & matrixNM_KJI = m_matrix_NM_KJI.toView(); + ArrayViewT< T, 3, 2 > const & matrixNM_IJK = m_matrixNM_IJK.toView(); + ArrayViewT< T, 3, 1 > const & matrixNM_IKJ = m_matrix_NM_IKJ.toView(); + ArrayViewT< T, 3, 0 > const & matrixNM_KJI = m_matrix_NM_KJI.toView(); - ArrayView< T const, 3, 2 > const & matrixNL_IJK = m_matrixNL_IJK.toViewConst(); - ArrayView< T const, 3, 1 > const & matrixNL_IKJ = m_matrixNL_IKJ.toViewConst(); - ArrayView< T const, 3, 0 > const & matrixNL_KJI = m_matrixNL_KJI.toViewConst(); + ArrayViewT< T const, 3, 2 > const & matrixNL_IJK = m_matrixNL_IJK.toViewConst(); + ArrayViewT< T const, 3, 1 > const & matrixNL_IKJ = m_matrixNL_IKJ.toViewConst(); + ArrayViewT< T const, 3, 0 > const & matrixNL_KJI = m_matrixNL_KJI.toViewConst(); T const ( &matrixNL_local )[ N ][ L ] = m_matrixNL_local; - ArrayView< T const, 3, 2 > const & matrixML_IJK = m_matrixML_IJK.toViewConst(); - ArrayView< T const, 3, 1 > const & matrixML_IKJ = m_matrixML_IKJ.toViewConst(); - ArrayView< T const, 3, 0 > const & matrixML_KJI = m_matrixML_KJI.toViewConst(); + ArrayViewT< T const, 3, 2 > const & matrixML_IJK = m_matrixML_IJK.toViewConst(); + ArrayViewT< T const, 3, 1 > const & matrixML_IKJ = m_matrixML_IKJ.toViewConst(); + ArrayViewT< T const, 3, 0 > const & matrixML_KJI = m_matrixML_KJI.toViewConst(); T const ( &matrixML_local )[ M ][ L ] = m_matrixML_local; std::ptrdiff_t const matrixNMSeed = m_matrixNMSeed; @@ -370,18 +370,18 @@ class ThreeSizesTest : public ::testing::Test } } - ArrayView< T, 3, 2 > const & matrixML_IJK = m_matrixML_IJK.toView(); - ArrayView< T, 3, 1 > const & matrixML_IKJ = m_matrixML_IKJ.toView(); - ArrayView< T, 3, 0 > const & matrixML_KJI = m_matrixML_KJI.toView(); + ArrayViewT< T, 3, 2 > const & matrixML_IJK = m_matrixML_IJK.toView(); + ArrayViewT< T, 3, 1 > const & matrixML_IKJ = m_matrixML_IKJ.toView(); + ArrayViewT< T, 3, 0 > const & matrixML_KJI = m_matrixML_KJI.toView(); - ArrayView< T const, 3, 2 > const & matrixNM_IJK = m_matrixNM_IJK.toViewConst(); - ArrayView< T const, 3, 1 > const & matrixNM_IKJ = m_matrix_NM_IKJ.toViewConst(); - ArrayView< T const, 3, 0 > const & matrixNM_KJI = m_matrix_NM_KJI.toViewConst(); + ArrayViewT< T const, 3, 2 > const & matrixNM_IJK = m_matrixNM_IJK.toViewConst(); + ArrayViewT< T const, 3, 1 > const & matrixNM_IKJ = m_matrix_NM_IKJ.toViewConst(); + ArrayViewT< T const, 3, 0 > const & matrixNM_KJI = m_matrix_NM_KJI.toViewConst(); T const ( &matrixNM_local )[ N ][ M ] = m_matrixNM_local; - ArrayView< T const, 3, 2 > const & matrixNL_IJK = m_matrixNL_IJK.toViewConst(); - ArrayView< T const, 3, 1 > const & matrixNL_IKJ = m_matrixNL_IKJ.toViewConst(); - ArrayView< T const, 3, 0 > const & matrixNL_KJI = m_matrixNL_KJI.toViewConst(); + ArrayViewT< T const, 3, 2 > const & matrixNL_IJK = m_matrixNL_IJK.toViewConst(); + ArrayViewT< T const, 3, 1 > const & matrixNL_IKJ = m_matrixNL_IKJ.toViewConst(); + ArrayViewT< T const, 3, 0 > const & matrixNL_KJI = m_matrixNL_KJI.toViewConst(); T const ( &matrixNL_local )[ N ][ L ] = m_matrixNL_local; std::ptrdiff_t const matrixMLSeed = m_matrixMLSeed; @@ -441,18 +441,18 @@ class ThreeSizesTest : public ::testing::Test } } - ArrayView< T, 3, 2 > const & matrixML_IJK = m_matrixML_IJK.toView(); - ArrayView< T, 3, 1 > const & matrixML_IKJ = m_matrixML_IKJ.toView(); - ArrayView< T, 3, 0 > const & matrixML_KJI = m_matrixML_KJI.toView(); + ArrayViewT< T, 3, 2 > const & matrixML_IJK = m_matrixML_IJK.toView(); + ArrayViewT< T, 3, 1 > const & matrixML_IKJ = m_matrixML_IKJ.toView(); + ArrayViewT< T, 3, 0 > const & matrixML_KJI = m_matrixML_KJI.toView(); - ArrayView< T const, 3, 2 > const & matrixNM_IJK = m_matrixNM_IJK.toViewConst(); - ArrayView< T const, 3, 1 > const & matrixNM_IKJ = m_matrix_NM_IKJ.toViewConst(); - ArrayView< T const, 3, 0 > const & matrixNM_KJI = m_matrix_NM_KJI.toViewConst(); + ArrayViewT< T const, 3, 2 > const & matrixNM_IJK = m_matrixNM_IJK.toViewConst(); + ArrayViewT< T const, 3, 1 > const & matrixNM_IKJ = m_matrix_NM_IKJ.toViewConst(); + ArrayViewT< T const, 3, 0 > const & matrixNM_KJI = m_matrix_NM_KJI.toViewConst(); T const ( &matrixNM_local )[ N ][ M ] = m_matrixNM_local; - ArrayView< T const, 3, 2 > const & matrixNL_IJK = m_matrixNL_IJK.toViewConst(); - ArrayView< T const, 3, 1 > const & matrixNL_IKJ = m_matrixNL_IKJ.toViewConst(); - ArrayView< T const, 3, 0 > const & matrixNL_KJI = m_matrixNL_KJI.toViewConst(); + ArrayViewT< T const, 3, 2 > const & matrixNL_IJK = m_matrixNL_IJK.toViewConst(); + ArrayViewT< T const, 3, 1 > const & matrixNL_IKJ = m_matrixNL_IKJ.toViewConst(); + ArrayViewT< T const, 3, 0 > const & matrixNL_KJI = m_matrixNL_KJI.toViewConst(); T const ( &matrixNL_local )[ N ][ L ] = m_matrixNL_local; std::ptrdiff_t const matrixMLSeed = m_matrixMLSeed; @@ -499,39 +499,65 @@ class ThreeSizesTest : public ::testing::Test private: std::ptrdiff_t const m_matrixNMSeed = 0; - Array< T, 3, RAJA::PERM_IJK > m_matrixNM_IJK { 1, N, M }; - Array< T, 3, RAJA::PERM_IKJ > m_matrix_NM_IKJ { 1, N, M }; - Array< T, 3, RAJA::PERM_KJI > m_matrix_NM_KJI { 1, N, M }; + ArrayT< T, RAJA::PERM_IJK > m_matrixNM_IJK { 1, N, M }; + ArrayT< T, RAJA::PERM_IKJ > m_matrix_NM_IKJ { 1, N, M }; + ArrayT< T, RAJA::PERM_KJI > m_matrix_NM_KJI { 1, N, M }; T m_matrixNM_local[ N ][ M ]; std::ptrdiff_t const m_matrixNLSeed = m_matrixNMSeed + N * M; - Array< T, 3, RAJA::PERM_IJK > m_matrixNL_IJK { 1, N, L }; - Array< T, 3, RAJA::PERM_IKJ > m_matrixNL_IKJ { 1, N, L }; - Array< T, 3, RAJA::PERM_KJI > m_matrixNL_KJI { 1, N, L }; + ArrayT< T, RAJA::PERM_IJK > m_matrixNL_IJK { 1, N, L }; + ArrayT< T, RAJA::PERM_IKJ > m_matrixNL_IKJ { 1, N, L }; + ArrayT< T, RAJA::PERM_KJI > m_matrixNL_KJI { 1, N, L }; T m_matrixNL_local[ N ][ L ]; std::ptrdiff_t const m_matrixLMSeed = m_matrixNMSeed + N * L; - Array< T, 3, RAJA::PERM_IJK > m_matrixLM_IJK { 1, L, M }; - Array< T, 3, RAJA::PERM_IKJ > m_matrixLM_IKJ { 1, L, M }; - Array< T, 3, RAJA::PERM_KJI > m_matrixLM_KJI { 1, L, M }; + ArrayT< T, RAJA::PERM_IJK > m_matrixLM_IJK { 1, L, M }; + ArrayT< T, RAJA::PERM_IKJ > m_matrixLM_IKJ { 1, L, M }; + ArrayT< T, RAJA::PERM_KJI > m_matrixLM_KJI { 1, L, M }; T m_matrixLM_local[ L ][ M ]; std::ptrdiff_t const m_matrixMLSeed = m_matrixLMSeed + L * M; - Array< T, 3, RAJA::PERM_IJK > m_matrixML_IJK { 1, M, L }; - Array< T, 3, RAJA::PERM_IKJ > m_matrixML_IKJ { 1, M, L }; - Array< T, 3, RAJA::PERM_KJI > m_matrixML_KJI { 1, M, L }; + ArrayT< T, RAJA::PERM_IJK > m_matrixML_IJK { 1, M, L }; + ArrayT< T, RAJA::PERM_IKJ > m_matrixML_IKJ { 1, M, L }; + ArrayT< T, RAJA::PERM_KJI > m_matrixML_KJI { 1, M, L }; T m_matrixML_local[ M ][ L ]; }; using ThreeSizesTestTypes = ::testing::Types< - std::tuple< double, std::integral_constant< int, 2 >, std::integral_constant< int, 3 >, std::integral_constant< int, 4 >, serialPolicy > - , std::tuple< int, std::integral_constant< int, 5 >, std::integral_constant< int, 4 >, std::integral_constant< int, 6 >, serialPolicy > - , std::tuple< double, std::integral_constant< int, 3 >, std::integral_constant< int, 3 >, std::integral_constant< int, 3 >, serialPolicy > -#if defined(USE_CUDA) - , std::tuple< double, std::integral_constant< int, 2 >, std::integral_constant< int, 3 >, std::integral_constant< int, 4 >, parallelDevicePolicy< 32 > > - , std::tuple< int, std::integral_constant< int, 5 >, std::integral_constant< int, 4 >, std::integral_constant< int, 6 >, parallelDevicePolicy< 32 > > - , std::tuple< double, std::integral_constant< int, 3 >, std::integral_constant< int, 3 >, std::integral_constant< int, 3 >, parallelDevicePolicy< 32 > > + std::tuple< double, + std::integral_constant< int, 2 >, + std::integral_constant< int, 3 >, + std::integral_constant< int, 4 >, + serialPolicy > + , std::tuple< int, + std::integral_constant< int, 5 >, + std::integral_constant< int, 4 >, + std::integral_constant< int, 6 >, + serialPolicy > + , std::tuple< double, + std::integral_constant< int, 3 >, + std::integral_constant< int, 3 >, + std::integral_constant< int, 3 >, + serialPolicy > + +// TODO: These tests can be run without chai and only using the c-arrays. +#if defined(USE_CUDA) && defined(USE_CHAI) + , std::tuple< double, + std::integral_constant< int, 2 >, + std::integral_constant< int, 3 >, + std::integral_constant< int, 4 >, + parallelDevicePolicy< 32 > > + , std::tuple< int, + std::integral_constant< int, 5 >, + std::integral_constant< int, 4 >, + std::integral_constant< int, 6 >, + parallelDevicePolicy< 32 > > + , std::tuple< double, + std::integral_constant< int, 3 >, + std::integral_constant< int, 3 >, + std::integral_constant< int, 3 >, + parallelDevicePolicy< 32 > > #endif >; diff --git a/unitTests/testTensorOpsTwoSizes.hpp b/unitTests/testTensorOpsTwoSizes.hpp index fc3dc877..c8d0fb89 100644 --- a/unitTests/testTensorOpsTwoSizes.hpp +++ b/unitTests/testTensorOpsTwoSizes.hpp @@ -75,9 +75,9 @@ class TwoSizesTest : public ::testing::Test } } - ArrayView< T, 3, 2 > const & matrixA_IJK = m_matrixA_IJK.toView(); - ArrayView< T, 3, 1 > const & matrixA_IKJ = m_matrixA_IKJ.toView(); - ArrayView< T, 3, 0 > const & matrixA_KJI = m_matrixA_KJI.toView(); + ArrayViewT< T, 3, 2 > const & matrixA_IJK = m_matrixA_IJK.toView(); + ArrayViewT< T, 3, 1 > const & matrixA_IKJ = m_matrixA_IKJ.toView(); + ArrayViewT< T, 3, 0 > const & matrixA_KJI = m_matrixA_KJI.toView(); std::ptrdiff_t const aSeed = m_matrixASeed; forall< POLICY >( 1, [scale, result, matrixA_IJK, matrixA_IKJ, matrixA_KJI, aSeed] LVARRAY_HOST_DEVICE ( int ) @@ -100,9 +100,9 @@ class TwoSizesTest : public ::testing::Test void testFill() { - ArrayView< T, 3, 2 > const & matrixA_IJK = m_matrixA_IJK.toView(); - ArrayView< T, 3, 1 > const & matrixA_IKJ = m_matrixA_IKJ.toView(); - ArrayView< T, 3, 0 > const & matrixA_KJI = m_matrixA_KJI.toView(); + ArrayViewT< T, 3, 2 > const & matrixA_IJK = m_matrixA_IJK.toView(); + ArrayViewT< T, 3, 1 > const & matrixA_IKJ = m_matrixA_IKJ.toView(); + ArrayViewT< T, 3, 0 > const & matrixA_KJI = m_matrixA_KJI.toView(); forall< POLICY >( 1, [matrixA_IJK, matrixA_IKJ, matrixA_KJI] LVARRAY_HOST_DEVICE ( int ) { @@ -160,16 +160,16 @@ class TwoSizesTest : public ::testing::Test } } - ArrayView< T, 3, 2 > const & matrixA_IJK = m_matrixA_IJK.toView(); - ArrayView< T, 3, 1 > const & matrixA_IKJ = m_matrixA_IKJ.toView(); - ArrayView< T, 3, 0 > const & matrixA_KJI = m_matrixA_KJI.toView(); + ArrayViewT< T, 3, 2 > const & matrixA_IJK = m_matrixA_IJK.toView(); + ArrayViewT< T, 3, 1 > const & matrixA_IKJ = m_matrixA_IKJ.toView(); + ArrayViewT< T, 3, 0 > const & matrixA_KJI = m_matrixA_KJI.toView(); - ArrayView< T const, 2, 1 > const & vectorN_IJ = m_vectorN_IJ.toViewConst(); - ArrayView< T const, 2, 0 > const & vectorN_JI = m_vectorN_JI.toViewConst(); + ArrayViewT< T const, 2, 1 > const & vectorN_IJ = m_vectorN_IJ.toViewConst(); + ArrayViewT< T const, 2, 0 > const & vectorN_JI = m_vectorN_JI.toViewConst(); T const ( &vectorN_local )[ N ] = m_vectorN_local; - ArrayView< T const, 2, 1 > const & vectorM_IJ = m_vectorM_IJ.toViewConst(); - ArrayView< T const, 2, 0 > const & vectorM_JI = m_vectorM_JI.toViewConst(); + ArrayViewT< T const, 2, 1 > const & vectorM_IJ = m_vectorM_IJ.toViewConst(); + ArrayViewT< T const, 2, 0 > const & vectorM_JI = m_vectorM_JI.toViewConst(); T const ( &vectorM_local )[ M ] = m_vectorM_local; std::ptrdiff_t const matrixSeed = m_matrixASeed; @@ -218,16 +218,16 @@ class TwoSizesTest : public ::testing::Test } } - ArrayView< T, 3, 2 > const & matrixA_IJK = m_matrixA_IJK.toView(); - ArrayView< T, 3, 1 > const & matrixA_IKJ = m_matrixA_IKJ.toView(); - ArrayView< T, 3, 0 > const & matrixA_KJI = m_matrixA_KJI.toView(); + ArrayViewT< T, 3, 2 > const & matrixA_IJK = m_matrixA_IJK.toView(); + ArrayViewT< T, 3, 1 > const & matrixA_IKJ = m_matrixA_IKJ.toView(); + ArrayViewT< T, 3, 0 > const & matrixA_KJI = m_matrixA_KJI.toView(); - ArrayView< T const, 2, 1 > const & vectorN_IJ = m_vectorN_IJ.toViewConst(); - ArrayView< T const, 2, 0 > const & vectorN_JI = m_vectorN_JI.toViewConst(); + ArrayViewT< T const, 2, 1 > const & vectorN_IJ = m_vectorN_IJ.toViewConst(); + ArrayViewT< T const, 2, 0 > const & vectorN_JI = m_vectorN_JI.toViewConst(); T const ( &vectorN_local )[ N ] = m_vectorN_local; - ArrayView< T const, 2, 1 > const & vectorM_IJ = m_vectorM_IJ.toViewConst(); - ArrayView< T const, 2, 0 > const & vectorM_JI = m_vectorM_JI.toViewConst(); + ArrayViewT< T const, 2, 1 > const & vectorM_IJ = m_vectorM_IJ.toViewConst(); + ArrayViewT< T const, 2, 0 > const & vectorM_JI = m_vectorM_JI.toViewConst(); T const ( &vectorM_local )[ M ] = m_vectorM_local; std::ptrdiff_t const matrixSeed = m_matrixASeed; @@ -279,16 +279,16 @@ class TwoSizesTest : public ::testing::Test result[ i ] = dot; } - ArrayView< T const, 3, 2 > const & matrixA_IJK = m_matrixA_IJK.toViewConst(); - ArrayView< T const, 3, 1 > const & matrixA_IKJ = m_matrixA_IKJ.toViewConst(); - ArrayView< T const, 3, 0 > const & matrixA_KJI = m_matrixA_KJI.toViewConst(); + ArrayViewT< T const, 3, 2 > const & matrixA_IJK = m_matrixA_IJK.toViewConst(); + ArrayViewT< T const, 3, 1 > const & matrixA_IKJ = m_matrixA_IKJ.toViewConst(); + ArrayViewT< T const, 3, 0 > const & matrixA_KJI = m_matrixA_KJI.toViewConst(); T const ( &matrix_local )[ N ][ M ] = m_matrixA_local; - ArrayView< T, 2, 1 > const & vectorN_IJ = m_vectorN_IJ.toView(); - ArrayView< T, 2, 0 > const & vectorN_JI = m_vectorN_JI.toView(); + ArrayViewT< T, 2, 1 > const & vectorN_IJ = m_vectorN_IJ.toView(); + ArrayViewT< T, 2, 0 > const & vectorN_JI = m_vectorN_JI.toView(); - ArrayView< T const, 2, 1 > const & vectorM_IJ = m_vectorM_IJ.toViewConst(); - ArrayView< T const, 2, 0 > const & vectorM_JI = m_vectorM_JI.toViewConst(); + ArrayViewT< T const, 2, 1 > const & vectorM_IJ = m_vectorM_IJ.toViewConst(); + ArrayViewT< T const, 2, 0 > const & vectorM_JI = m_vectorM_JI.toViewConst(); T const ( &vectorM_local )[ M ] = m_vectorM_local; std::ptrdiff_t const vectorNSeed = m_vectorNSeed; @@ -340,16 +340,16 @@ class TwoSizesTest : public ::testing::Test result[ i ] = m_vectorN_local[ i ] + dot; } - ArrayView< T const, 3, 2 > const & matrixA_IJK = m_matrixA_IJK.toViewConst(); - ArrayView< T const, 3, 1 > const & matrixA_IKJ = m_matrixA_IKJ.toViewConst(); - ArrayView< T const, 3, 0 > const & matrixA_KJI = m_matrixA_KJI.toViewConst(); + ArrayViewT< T const, 3, 2 > const & matrixA_IJK = m_matrixA_IJK.toViewConst(); + ArrayViewT< T const, 3, 1 > const & matrixA_IKJ = m_matrixA_IKJ.toViewConst(); + ArrayViewT< T const, 3, 0 > const & matrixA_KJI = m_matrixA_KJI.toViewConst(); T const ( &matrix_local )[ N ][ M ] = m_matrixA_local; - ArrayView< T, 2, 1 > const & vectorN_IJ = m_vectorN_IJ.toView(); - ArrayView< T, 2, 0 > const & vectorN_JI = m_vectorN_JI.toView(); + ArrayViewT< T, 2, 1 > const & vectorN_IJ = m_vectorN_IJ.toView(); + ArrayViewT< T, 2, 0 > const & vectorN_JI = m_vectorN_JI.toView(); - ArrayView< T const, 2, 1 > const & vectorM_IJ = m_vectorM_IJ.toViewConst(); - ArrayView< T const, 2, 0 > const & vectorM_JI = m_vectorM_JI.toViewConst(); + ArrayViewT< T const, 2, 1 > const & vectorM_IJ = m_vectorM_IJ.toViewConst(); + ArrayViewT< T const, 2, 0 > const & vectorM_JI = m_vectorM_JI.toViewConst(); T const ( &vectorM_local )[ M ] = m_vectorM_local; std::ptrdiff_t const vectorNSeed = m_vectorNSeed; @@ -401,17 +401,17 @@ class TwoSizesTest : public ::testing::Test result[ i ] = dot; } - ArrayView< T const, 3, 2 > const & matrixA_IJK = m_matrixA_IJK.toViewConst(); - ArrayView< T const, 3, 1 > const & matrixA_IKJ = m_matrixA_IKJ.toViewConst(); - ArrayView< T const, 3, 0 > const & matrixA_KJI = m_matrixA_KJI.toViewConst(); + ArrayViewT< T const, 3, 2 > const & matrixA_IJK = m_matrixA_IJK.toViewConst(); + ArrayViewT< T const, 3, 1 > const & matrixA_IKJ = m_matrixA_IKJ.toViewConst(); + ArrayViewT< T const, 3, 0 > const & matrixA_KJI = m_matrixA_KJI.toViewConst(); T const ( &matrix_local )[ N ][ M ] = m_matrixA_local; - ArrayView< T const, 2, 1 > const & vectorN_IJ = m_vectorN_IJ.toViewConst(); - ArrayView< T const, 2, 0 > const & vectorN_JI = m_vectorN_JI.toViewConst(); + ArrayViewT< T const, 2, 1 > const & vectorN_IJ = m_vectorN_IJ.toViewConst(); + ArrayViewT< T const, 2, 0 > const & vectorN_JI = m_vectorN_JI.toViewConst(); T const ( &vectorN_local )[ N ] = m_vectorN_local; - ArrayView< T, 2, 1 > const & vectorM_IJ = m_vectorM_IJ.toView(); - ArrayView< T, 2, 0 > const & vectorM_JI = m_vectorM_JI.toView(); + ArrayViewT< T, 2, 1 > const & vectorM_IJ = m_vectorM_IJ.toView(); + ArrayViewT< T, 2, 0 > const & vectorM_JI = m_vectorM_JI.toView(); std::ptrdiff_t const vectorMSeed = m_vectorMSeed; @@ -462,17 +462,17 @@ class TwoSizesTest : public ::testing::Test result[ i ] = m_vectorM_local[ i ] + dot; } - ArrayView< T const, 3, 2 > const & matrixA_IJK = m_matrixA_IJK.toViewConst(); - ArrayView< T const, 3, 1 > const & matrixA_IKJ = m_matrixA_IKJ.toViewConst(); - ArrayView< T const, 3, 0 > const & matrixA_KJI = m_matrixA_KJI.toViewConst(); + ArrayViewT< T const, 3, 2 > const & matrixA_IJK = m_matrixA_IJK.toViewConst(); + ArrayViewT< T const, 3, 1 > const & matrixA_IKJ = m_matrixA_IKJ.toViewConst(); + ArrayViewT< T const, 3, 0 > const & matrixA_KJI = m_matrixA_KJI.toViewConst(); T const ( &matrix_local )[ N ][ M ] = m_matrixA_local; - ArrayView< T const, 2, 1 > const & vectorN_IJ = m_vectorN_IJ.toViewConst(); - ArrayView< T const, 2, 0 > const & vectorN_JI = m_vectorN_JI.toViewConst(); + ArrayViewT< T const, 2, 1 > const & vectorN_IJ = m_vectorN_IJ.toViewConst(); + ArrayViewT< T const, 2, 0 > const & vectorN_JI = m_vectorN_JI.toViewConst(); T const ( &vectorN_local )[ N ] = m_vectorN_local; - ArrayView< T, 2, 1 > const & vectorM_IJ = m_vectorM_IJ.toView(); - ArrayView< T, 2, 0 > const & vectorM_JI = m_vectorM_JI.toView(); + ArrayViewT< T, 2, 1 > const & vectorM_IJ = m_vectorM_IJ.toView(); + ArrayViewT< T, 2, 0 > const & vectorM_JI = m_vectorM_JI.toView(); std::ptrdiff_t const vectorMSeed = m_vectorMSeed; @@ -512,13 +512,13 @@ class TwoSizesTest : public ::testing::Test void testCopy() { - ArrayView< T, 3, 2 > const & matrixA_IJK = m_matrixA_IJK.toView(); - ArrayView< T, 3, 1 > const & matrixA_IKJ = m_matrixA_IKJ.toView(); - ArrayView< T, 3, 0 > const & matrixA_KJI = m_matrixA_KJI.toView(); + ArrayViewT< T, 3, 2 > const & matrixA_IJK = m_matrixA_IJK.toView(); + ArrayViewT< T, 3, 1 > const & matrixA_IKJ = m_matrixA_IKJ.toView(); + ArrayViewT< T, 3, 0 > const & matrixA_KJI = m_matrixA_KJI.toView(); - ArrayView< T const, 3, 2 > const & matrixB_IJK_view = m_matrixB_IJK.toViewConst(); - ArrayView< T const, 3, 1 > const & matrixB_IKJ_view = m_matrixB_IKJ.toViewConst(); - ArrayView< T const, 3, 0 > const & matrixB_KJI_view = m_matrixB_KJI.toViewConst(); + ArrayViewT< T const, 3, 2 > const & matrixB_IJK_view = m_matrixB_IJK.toViewConst(); + ArrayViewT< T const, 3, 1 > const & matrixB_IKJ_view = m_matrixB_IKJ.toViewConst(); + ArrayViewT< T const, 3, 0 > const & matrixB_KJI_view = m_matrixB_KJI.toViewConst(); T const ( &matrixB_local )[ N ][ M ] = m_matrixB_local; std::ptrdiff_t const matrixSeed = m_matrixASeed; @@ -569,13 +569,13 @@ class TwoSizesTest : public ::testing::Test } } - ArrayView< T, 3, 2 > const & matrixA_IJK = m_matrixA_IJK.toView(); - ArrayView< T, 3, 1 > const & matrixA_IKJ = m_matrixA_IKJ.toView(); - ArrayView< T, 3, 0 > const & matrixA_KJI = m_matrixA_KJI.toView(); + ArrayViewT< T, 3, 2 > const & matrixA_IJK = m_matrixA_IJK.toView(); + ArrayViewT< T, 3, 1 > const & matrixA_IKJ = m_matrixA_IKJ.toView(); + ArrayViewT< T, 3, 0 > const & matrixA_KJI = m_matrixA_KJI.toView(); - ArrayView< T const, 3, 2 > const & matrixB_IJK_view = m_matrixB_IJK.toViewConst(); - ArrayView< T const, 3, 1 > const & matrixB_IKJ_view = m_matrixB_IKJ.toViewConst(); - ArrayView< T const, 3, 0 > const & matrixB_KJI_view = m_matrixB_KJI.toViewConst(); + ArrayViewT< T const, 3, 2 > const & matrixB_IJK_view = m_matrixB_IJK.toViewConst(); + ArrayViewT< T const, 3, 1 > const & matrixB_IKJ_view = m_matrixB_IKJ.toViewConst(); + ArrayViewT< T const, 3, 0 > const & matrixB_KJI_view = m_matrixB_KJI.toViewConst(); T const ( &matrixB_local )[ N ][ M ] = m_matrixB_local; std::ptrdiff_t const matrixSeed = m_matrixASeed; @@ -625,13 +625,13 @@ class TwoSizesTest : public ::testing::Test } } - ArrayView< T, 3, 2 > const & matrixA_IJK = m_matrixA_IJK.toView(); - ArrayView< T, 3, 1 > const & matrixA_IKJ = m_matrixA_IKJ.toView(); - ArrayView< T, 3, 0 > const & matrixA_KJI = m_matrixA_KJI.toView(); + ArrayViewT< T, 3, 2 > const & matrixA_IJK = m_matrixA_IJK.toView(); + ArrayViewT< T, 3, 1 > const & matrixA_IKJ = m_matrixA_IKJ.toView(); + ArrayViewT< T, 3, 0 > const & matrixA_KJI = m_matrixA_KJI.toView(); - ArrayView< T const, 3, 2 > const & matrixB_IJK_view = m_matrixB_IJK.toViewConst(); - ArrayView< T const, 3, 1 > const & matrixB_IKJ_view = m_matrixB_IKJ.toViewConst(); - ArrayView< T const, 3, 0 > const & matrixB_KJI_view = m_matrixB_KJI.toViewConst(); + ArrayViewT< T const, 3, 2 > const & matrixB_IJK_view = m_matrixB_IJK.toViewConst(); + ArrayViewT< T const, 3, 1 > const & matrixB_IKJ_view = m_matrixB_IKJ.toViewConst(); + ArrayViewT< T const, 3, 0 > const & matrixB_KJI_view = m_matrixB_KJI.toViewConst(); T const ( &matrixB_local )[ N ][ M ] = m_matrixB_local; std::ptrdiff_t const matrixSeed = m_matrixASeed; @@ -672,25 +672,25 @@ class TwoSizesTest : public ::testing::Test private: std::ptrdiff_t const m_matrixASeed = 0; - Array< T, 3, RAJA::PERM_IJK > m_matrixA_IJK { 1, N, M }; - Array< T, 3, RAJA::PERM_IKJ > m_matrixA_IKJ { 1, N, M }; - Array< T, 3, RAJA::PERM_KJI > m_matrixA_KJI { 1, N, M }; + ArrayT< T, RAJA::PERM_IJK > m_matrixA_IJK { 1, N, M }; + ArrayT< T, RAJA::PERM_IKJ > m_matrixA_IKJ { 1, N, M }; + ArrayT< T, RAJA::PERM_KJI > m_matrixA_KJI { 1, N, M }; T m_matrixA_local[ N ][ M ]; std::ptrdiff_t const m_matrixBSeed = m_matrixASeed + N * M; - Array< T, 3, RAJA::PERM_IJK > m_matrixB_IJK { 1, N, M }; - Array< T, 3, RAJA::PERM_IKJ > m_matrixB_IKJ { 1, N, M }; - Array< T, 3, RAJA::PERM_KJI > m_matrixB_KJI { 1, N, M }; + ArrayT< T, RAJA::PERM_IJK > m_matrixB_IJK { 1, N, M }; + ArrayT< T, RAJA::PERM_IKJ > m_matrixB_IKJ { 1, N, M }; + ArrayT< T, RAJA::PERM_KJI > m_matrixB_KJI { 1, N, M }; T m_matrixB_local[ N ][ M ]; std::ptrdiff_t const m_vectorNSeed = m_matrixBSeed + N * M; - Array< T, 2, RAJA::PERM_IJ > m_vectorN_IJ { 1, N }; - Array< T, 2, RAJA::PERM_JI > m_vectorN_JI { 1, N }; + ArrayT< T, RAJA::PERM_IJ > m_vectorN_IJ { 1, N }; + ArrayT< T, RAJA::PERM_JI > m_vectorN_JI { 1, N }; T m_vectorN_local[ N ]; std::ptrdiff_t const m_vectorMSeed = m_vectorNSeed + N; - Array< T, 2, RAJA::PERM_IJ > m_vectorM_IJ { 1, M }; - Array< T, 2, RAJA::PERM_JI > m_vectorM_JI { 1, M }; + ArrayT< T, RAJA::PERM_IJ > m_vectorM_IJ { 1, M }; + ArrayT< T, RAJA::PERM_JI > m_vectorM_JI { 1, M }; T m_vectorM_local[ M ]; }; @@ -699,7 +699,9 @@ using TwoSizesTestTypes = ::testing::Types< std::tuple< double, std::integral_constant< int, 2 >, std::integral_constant< int, 3 >, serialPolicy > , std::tuple< int, std::integral_constant< int, 5 >, std::integral_constant< int, 4 >, serialPolicy > , std::tuple< double, std::integral_constant< int, 3 >, std::integral_constant< int, 3 >, serialPolicy > -#if defined(USE_CUDA) + +// TODO: These tests can be run without chai and only using the c-arrays. +#if defined(USE_CUDA) && defined(USE_CHAI) , std::tuple< double, std::integral_constant< int, 2 >, std::integral_constant< int, 3 >, parallelDevicePolicy< 32 > > , std::tuple< int, std::integral_constant< int, 5 >, std::integral_constant< int, 4 >, parallelDevicePolicy< 32 > > , std::tuple< double, std::integral_constant< int, 3 >, std::integral_constant< int, 3 >, parallelDevicePolicy< 32 > > diff --git a/unitTests/testUtils.hpp b/unitTests/testUtils.hpp index b4fc47bf..c17b3a98 100644 --- a/unitTests/testUtils.hpp +++ b/unitTests/testUtils.hpp @@ -22,26 +22,28 @@ // Source includes #include "LvArrayConfig.hpp" #include "Array.hpp" +#include "SortedArray.hpp" +#include "ArrayOfArrays.hpp" +#include "ArrayOfSets.hpp" +#include "SparsityPattern.hpp" +#include "CRSMatrix.hpp" #include "Macros.hpp" +#if defined(USE_CHAI) +#include "NewChaiBuffer.hpp" +#else +#include "MallocBuffer.hpp" +#endif + + // TPL includes #include #include -#include // System includes #include #include -#ifdef USE_CUDA - -#define CUDA_TEST( X, Y ) \ - static void cuda_test_ ## X ## Y(); \ - TEST( X, Y ) { cuda_test_ ## X ## Y(); } \ - static void cuda_test_ ## X ## Y() - -#endif - namespace LvArray { namespace testing @@ -58,7 +60,7 @@ struct RAJAHelper< serialPolicy > { using ReducePolicy = RAJA::seq_reduce; using AtomicPolicy = RAJA::seq_atomic; - static constexpr chai::ExecutionSpace space = chai::CPU; + static constexpr MemorySpace space = MemorySpace::CPU; }; #if defined(USE_OPENMP) @@ -70,7 +72,7 @@ struct RAJAHelper< parallelHostPolicy > { using ReducePolicy = RAJA::omp_reduce; using AtomicPolicy = RAJA::builtin_atomic; - static constexpr chai::ExecutionSpace space = chai::CPU; + static constexpr MemorySpace space = MemorySpace::CPU; }; #endif @@ -85,7 +87,7 @@ struct RAJAHelper< RAJA::cuda_exec< N > > { using ReducePolicy = RAJA::cuda_reduce; using AtomicPolicy = RAJA::cuda_atomic; - static constexpr chai::ExecutionSpace space = chai::GPU; + static constexpr MemorySpace space = MemorySpace::GPU; }; #endif @@ -114,6 +116,100 @@ struct PairComp } }; +#if defined(USE_CHAI) +template< typename T > +using DEFAULT_BUFFER = NewChaiBuffer< T >; +#else +template< typename T > +using DEFAULT_BUFFER = MallocBuffer< T >; +#endif + +template< typename INDEX_TYPE, template< typename > class BUFFER_TYPE > +struct ArrayConversion +{ + template< typename T, int NDIM, typename PERMUTATION > + using Array = Array< T, NDIM, PERMUTATION, INDEX_TYPE, BUFFER_TYPE >; + + template< typename T, int NDIM, int USD > + using ArrayView = ArrayView< T, NDIM, USD, INDEX_TYPE, BUFFER_TYPE >; + + template< typename T, int NDIM, int USD > + using ArraySlice = ArraySlice< T, NDIM, USD, INDEX_TYPE >; + + template< typename T > + using SortedArray = SortedArray< T, INDEX_TYPE, BUFFER_TYPE >; + + template< typename T > + using SortedArrayView = SortedArrayView< T, INDEX_TYPE const, BUFFER_TYPE >; + + template< typename T > + using ArrayOfArrays = ArrayOfArrays< T, INDEX_TYPE, BUFFER_TYPE >; + + template< typename T, bool CONST_SIZES > + using ArrayOfArraysView = ArrayOfArraysView< T, INDEX_TYPE const, CONST_SIZES, BUFFER_TYPE >; + + template< typename T > + using ArrayOfSets = ArrayOfSets< T, INDEX_TYPE, BUFFER_TYPE >; + + template< typename T > + using ArrayOfSetsView = ArrayOfSetsView< T, INDEX_TYPE const, BUFFER_TYPE >; + + template< typename COL_TYPE > + using SparsityPattern = SparsityPattern< COL_TYPE, INDEX_TYPE, BUFFER_TYPE >; + + template< typename COL_TYPE > + using SparsityPatternView = SparsityPatternView< COL_TYPE, INDEX_TYPE const, BUFFER_TYPE >; + + template< typename T, typename COL_TYPE > + using CRSMatrix = CRSMatrix< T, COL_TYPE, INDEX_TYPE, BUFFER_TYPE >; + + template< typename T, typename COL_TYPE > + using CRSMatrixView = CRSMatrixView< T, COL_TYPE, INDEX_TYPE const, BUFFER_TYPE >; +}; + +template< typename > +struct ArrayConverter; + +template< typename T, + int NDIM, + typename PERMUTATION, + typename INDEX_TYPE, + template< typename > class BUFFER_TYPE > +struct ArrayConverter< Array< T, NDIM, PERMUTATION, INDEX_TYPE, BUFFER_TYPE > > : + public ArrayConversion< INDEX_TYPE, BUFFER_TYPE > +{}; + +template< typename T, + typename INDEX_TYPE, + template< typename > class BUFFER_TYPE > +struct ArrayConverter< ArrayOfArrays< T, INDEX_TYPE, BUFFER_TYPE > > : + public ArrayConversion< INDEX_TYPE, BUFFER_TYPE > +{}; + +template< typename T, + typename INDEX_TYPE, + template< typename > class BUFFER_TYPE > +struct ArrayConverter< ArrayOfSets< T, INDEX_TYPE, BUFFER_TYPE > > : + public ArrayConversion< INDEX_TYPE, BUFFER_TYPE > +{}; + +template< typename COL_TYPE, + typename INDEX_TYPE, + template< typename > class BUFFER_TYPE > +struct ArrayConverter< SparsityPattern< COL_TYPE, INDEX_TYPE, BUFFER_TYPE > > : + public ArrayConversion< INDEX_TYPE, BUFFER_TYPE > +{}; + +template< typename T, + typename COL_TYPE, + typename INDEX_TYPE, + template< typename > class BUFFER_TYPE > +struct ArrayConverter< CRSMatrix< T, COL_TYPE, INDEX_TYPE, BUFFER_TYPE > > : + public ArrayConversion< INDEX_TYPE, BUFFER_TYPE > +{}; + + + /** * @class TestString * @brief A wrapper around std::string that adds a constructor that takes a number