From d9755cc8c9f478da5a2d74034a531e17fdceea86 Mon Sep 17 00:00:00 2001 From: Sergey Klevtsov Date: Fri, 19 May 2023 03:11:29 -0700 Subject: [PATCH] WIP on new layouts --- ...rkArray1DR2TensorMultiplicationKernels.cpp | 16 +- ...aysNodeToElementMapConstructionKernels.cpp | 8 +- benchmarks/benchmarkHelpers.hpp | 8 +- examples/exampleArray.cpp | 21 +- src/Array.hpp | 329 +++++----- src/ArrayOfArraysView.hpp | 4 +- src/ArraySlice.hpp | 237 ++++--- src/ArrayView.hpp | 448 ++++++------- src/CRSMatrixView.hpp | 7 +- src/Constant.hpp | 285 +++++++++ src/Layout.hpp | 493 +++++++++++++++ src/Macros.hpp | 6 + src/SortedArrayView.hpp | 6 +- src/input.hpp | 23 +- src/memcpy.hpp | 91 +-- src/output.hpp | 12 +- src/python/PyArray.cpp | 39 -- src/python/PyArray.hpp | 22 - src/sliceHelpers.hpp | 40 +- src/tupleManipulation.hpp | 594 ++++++++++++++++++ src/typeManipulation.hpp | 28 + unitTests/CMakeLists.txt | 4 +- unitTests/testArray.hpp | 109 ++-- unitTests/testArray1DOfArray1D.cpp | 6 +- unitTests/testArray1DOfArray1DOfArray1D.cpp | 6 +- unitTests/testArrayOfArrays.cpp | 4 +- unitTests/testArrayOfSets.cpp | 2 +- unitTests/testArrayView.hpp | 25 +- unitTests/testArrayView_typeConversion.cpp | 12 +- ...Array_getSetSingleParameterResizeIndex.cpp | 30 - unitTests/testConstant.cpp | 97 +++ unitTests/testInvalidOperations.cpp | 4 +- unitTests/testLayout.cpp | 126 ++++ unitTests/testSliceHelpers.cpp | 239 ++++--- unitTests/testSortedArrayManipulation.cpp | 2 +- unitTests/testSparsityPattern.cpp | 2 +- unitTests/testTensorOpsCommon.hpp | 8 +- unitTests/testTensorOpsEigen.cpp | 22 +- unitTests/testTensorOpsFixedSize.cpp | 94 +-- unitTests/testTensorOpsInverse.hpp | 52 +- unitTests/testTensorOpsNoSize.cpp | 36 +- unitTests/testTensorOpsOneSize.cpp | 114 ++-- unitTests/testTensorOpsThreeSizes.hpp | 108 ++-- unitTests/testTensorOpsTwoSizes.hpp | 180 +++--- unitTests/testTensorOpsTwoSizes1.cpp | 180 +++--- unitTests/testTupleManipulation.cpp | 86 +++ unitTests/testTypeManipulation.cpp | 86 +-- 47 files changed, 2998 insertions(+), 1353 deletions(-) create mode 100644 src/Constant.hpp create mode 100644 src/Layout.hpp create mode 100644 src/tupleManipulation.hpp delete mode 100644 unitTests/testArray_getSetSingleParameterResizeIndex.cpp create mode 100644 unitTests/testConstant.cpp create mode 100644 unitTests/testLayout.cpp create mode 100644 unitTests/testTupleManipulation.cpp diff --git a/benchmarks/benchmarkArray1DR2TensorMultiplicationKernels.cpp b/benchmarks/benchmarkArray1DR2TensorMultiplicationKernels.cpp index 9b0afe0f..b4970e29 100644 --- a/benchmarks/benchmarkArray1DR2TensorMultiplicationKernels.cpp +++ b/benchmarks/benchmarkArray1DR2TensorMultiplicationKernels.cpp @@ -52,18 +52,18 @@ namespace benchmarking RAJA_OUTER_LOOP( N, INNER_LOOP( a_ijl, b_ilk, c_ijk ) ) -template< typename VALUE_TYPE_CONST, int USD > +template< typename VALUE_TYPE_CONST, typename LAYOUT, std::enable_if_t< LAYOUT::NDIM == 2 >* = nullptr > inline LVARRAY_HOST_DEVICE constexpr -void R2TensorMultiplyFortran( 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 ) +void R2TensorMultiplyFortran( LvArray::ArraySlice2< VALUE_TYPE_CONST, LAYOUT > const a, + LvArray::ArraySlice2< VALUE_TYPE_CONST, LAYOUT > const b, + LvArray::ArraySlice2< VALUE_TYPE, LAYOUT > const c ) { INNER_LOOP( a( j, l ), b( l, k ), c( j, k ) ) } -template< typename VALUE_TYPE_CONST, int USD > +template< typename VALUE_TYPE_CONST, typename LAYOUT, std::enable_if_t< LAYOUT::NDIM == 2 >* = nullptr > RAJA_INLINE LVARRAY_HOST_DEVICE constexpr -void R2TensorMultiplySubscript( 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 ) +void R2TensorMultiplySubscript( LvArray::ArraySlice2< VALUE_TYPE_CONST, LAYOUT > const a, + LvArray::ArraySlice2< VALUE_TYPE_CONST, LAYOUT > const b, + LvArray::ArraySlice2< VALUE_TYPE, LAYOUT > const c ) { INNER_LOOP( a[ j ][ l ], b[ l ][ k ], c[ j ][ k ] ) } diff --git a/benchmarks/benchmarkArrayOfArraysNodeToElementMapConstructionKernels.cpp b/benchmarks/benchmarkArrayOfArraysNodeToElementMapConstructionKernels.cpp index 051cee25..072780b2 100644 --- a/benchmarks/benchmarkArrayOfArraysNodeToElementMapConstructionKernels.cpp +++ b/benchmarks/benchmarkArrayOfArraysNodeToElementMapConstructionKernels.cpp @@ -15,7 +15,7 @@ namespace benchmarking // Sphinx start after vector void NaiveNodeToElemMapConstruction:: - vector( ArrayView< INDEX_TYPE const, 2, 1, INDEX_TYPE, DEFAULT_BUFFER > const & elementToNodeMap, + vector( ArrayView< INDEX_TYPE const, 2, RAJA::PERM_IJ, INDEX_TYPE, DEFAULT_BUFFER > const & elementToNodeMap, std::vector< std::vector< INDEX_TYPE > > & nodeToElementMap, INDEX_TYPE const numNodes ) { @@ -33,7 +33,7 @@ void NaiveNodeToElemMapConstruction:: // Sphinx start after naive void NaiveNodeToElemMapConstruction:: - naive( ArrayView< INDEX_TYPE const, 2, 1, INDEX_TYPE, DEFAULT_BUFFER > const & elementToNodeMap, + naive( ArrayView< INDEX_TYPE const, 2, RAJA::PERM_IJ, INDEX_TYPE, DEFAULT_BUFFER > const & elementToNodeMap, ArrayOfArrays< INDEX_TYPE, INDEX_TYPE, DEFAULT_BUFFER > & nodeToElementMap, INDEX_TYPE const numNodes ) { @@ -52,7 +52,7 @@ void NaiveNodeToElemMapConstruction:: // Sphinx start after overAllocation template< typename POLICY > void NodeToElemMapConstruction< POLICY >:: -overAllocation( ArrayView< INDEX_TYPE const, 2, 1, INDEX_TYPE, DEFAULT_BUFFER > const & elementToNodeMap, +overAllocation( ArrayView< INDEX_TYPE const, 2, RAJA::PERM_IJ, INDEX_TYPE, DEFAULT_BUFFER > const & elementToNodeMap, ArrayOfArrays< INDEX_TYPE, INDEX_TYPE, DEFAULT_BUFFER > & nodeToElementMap, INDEX_TYPE const numNodes, INDEX_TYPE const maxNodeElements ) @@ -83,7 +83,7 @@ overAllocation( ArrayView< INDEX_TYPE const, 2, 1, INDEX_TYPE, DEFAULT_BUFFER > // Sphinx start after resizeFromCapacities template< typename POLICY > void NodeToElemMapConstruction< POLICY >:: -resizeFromCapacities( ArrayView< INDEX_TYPE const, 2, 1, INDEX_TYPE, DEFAULT_BUFFER > const & elementToNodeMap, +resizeFromCapacities( ArrayView< INDEX_TYPE const, 2, RAJA::PERM_IJ, INDEX_TYPE, DEFAULT_BUFFER > const & elementToNodeMap, ArrayOfArrays< INDEX_TYPE, INDEX_TYPE, DEFAULT_BUFFER > & nodeToElementMap, INDEX_TYPE const numNodes ) { diff --git a/benchmarks/benchmarkHelpers.hpp b/benchmarks/benchmarkHelpers.hpp index 25074b5c..0a8217da 100644 --- a/benchmarks/benchmarkHelpers.hpp +++ b/benchmarks/benchmarkHelpers.hpp @@ -71,7 +71,7 @@ using ArrayT = LvArray::Array< T, typeManipulation::getDimension< PERMUTATION >, template< typename T, typename PERMUTATION > using ArrayViewT = LvArray::ArrayView< T, typeManipulation::getDimension< PERMUTATION >, -typeManipulation::getStrideOneDimension( PERMUTATION {} ), +PERMUTATION, INDEX_TYPE, DEFAULT_BUFFER >; @@ -145,8 +145,8 @@ inline std::uint_fast64_t getSeed() } -template< typename T, int NDIM, int USD > -void initialize( ArraySlice< T, NDIM, USD, INDEX_TYPE > const slice, int & iter ) +template< typename T, typename LAYOUT > +void initialize( ArraySlice2< T, LAYOUT > const slice, int & iter ) { ++iter; std::mt19937_64 gen( iter * getSeed() ); @@ -171,7 +171,7 @@ RajaView< T, PERMUTATION > makeRajaView( ArrayT< T, PERMUTATION > const & array for( int i = 0; i < NDIM; ++i ) { - sizes[ i ] = array.dims()[ i ]; + sizes[ i ] = array.size( i ); } constexpr std::array< camp::idx_t, NDIM > const permutation = RAJA::as_array< PERMUTATION >::get(); diff --git a/examples/exampleArray.cpp b/examples/exampleArray.cpp index 2a22aeee..677c7597 100644 --- a/examples/exampleArray.cpp +++ b/examples/exampleArray.cpp @@ -106,9 +106,9 @@ TEST( Array, permutations ) LvArray::MallocBuffer > array( 3, 4, 5 ); // Index 0 has the largest stride while index 2 has unit stride. - EXPECT_EQ( array.strides()[ 0 ], array.size( 2 ) * array.size( 1 ) ); - EXPECT_EQ( array.strides()[ 1 ], array.size( 2 ) ); - EXPECT_EQ( array.strides()[ 2 ], 1 ); + EXPECT_EQ( array.stride< 0 >(), array.size( 2 ) * array.size( 1 ) ); + EXPECT_EQ( array.stride< 1 >(), array.size( 2 ) ); + EXPECT_EQ( array.stride< 2 >(), 1 ); int const * const pointer = array.data(); for( std::ptrdiff_t i = 0; i < array.size( 0 ); ++i ) @@ -134,9 +134,9 @@ TEST( Array, permutations ) LvArray::MallocBuffer > array( 3, 4, 5 ); // Index 0 has the unit stride while index 2 has the largest stride. - EXPECT_EQ( array.strides()[ 0 ], 1 ); - EXPECT_EQ( array.strides()[ 1 ], array.size( 0 ) ); - EXPECT_EQ( array.strides()[ 2 ], array.size( 0 ) * array.size( 1 ) ); + EXPECT_EQ( array.stride< 0 >(), 1 ); + EXPECT_EQ( array.stride< 1 >(), array.size( 0 ) ); + EXPECT_EQ( array.stride< 2 >(), array.size( 0 ) * array.size( 1 ) ); int const * const pointer = array.data(); for( std::ptrdiff_t i = 0; i < array.size( 0 ); ++i ) @@ -223,8 +223,7 @@ TEST( Array, resizeSingleDimension ) } // Shrink the second dimension from 6 to 3; - array.setSingleParameterResizeIndex( 1 ); - array.resize( 3 ); + array.resizeDimension< 1 >( 3 ); for( std::ptrdiff_t i = 0; i < array.size( 0 ); ++i ) { for( std::ptrdiff_t j = 0; j < array.size( 1 ); ++j ) @@ -254,7 +253,7 @@ TEST( Array, arrayView ) // Create a view. LvArray::ArrayView< int, 2, - 0, + camp::idx_seq< 1, 0 >, std::ptrdiff_t, LvArray::MallocBuffer > const view = array; EXPECT_EQ( view.data(), array.data() ); @@ -262,7 +261,7 @@ TEST( Array, arrayView ) // Create a view with const values. LvArray::ArrayView< int const, 2, - 0, + camp::idx_seq< 1, 0 >, std::ptrdiff_t, LvArray::MallocBuffer > const viewConst = array.toViewConst(); EXPECT_EQ( viewConst.data(), array.data() ); @@ -270,7 +269,7 @@ TEST( Array, arrayView ) // Copy a view. LvArray::ArrayView< int, 2, - 0, + camp::idx_seq< 1, 0 >, std::ptrdiff_t, LvArray::MallocBuffer > const viewCopy = view; EXPECT_EQ( viewCopy.data(), array.data() ); diff --git a/src/Array.hpp b/src/Array.hpp index 503d4750..225cb55e 100644 --- a/src/Array.hpp +++ b/src/Array.hpp @@ -48,35 +48,35 @@ namespace LvArray * one template argument that describes the type of the data being stored (T). */ template< typename T, - int NDIM, + typename EXTENT, typename PERMUTATION, - typename INDEX_TYPE, template< typename > class BUFFER_TYPE > -class Array : public ArrayView< T, - NDIM, - typeManipulation::getStrideOneDimension( PERMUTATION {} ), - INDEX_TYPE, - BUFFER_TYPE > +class Array2 : public ArrayView2< T, Layout< EXTENT, CompactStride< LayoutDefault, EXTENT, PERMUTATION > >, BUFFER_TYPE > { public: - // Check that the template arguments are valid. - static_assert( NDIM >= 0, "The dimension of the Array must be positive." ); - static_assert( typeManipulation::isValidPermutation( PERMUTATION {} ), "The permutation must be valid." ); - static_assert( typeManipulation::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 permutation of the array. + /// Alias for the permutation. using Permutation = PERMUTATION; /// Alias for the parent class. - using ParentClass = ArrayView< T, NDIM, typeManipulation::getStrideOneDimension( Permutation {} ), INDEX_TYPE, BUFFER_TYPE >; + using ParentClass = ArrayView2< T, Layout< EXTENT, CompactStride< LayoutDefault, EXTENT, PERMUTATION > >, BUFFER_TYPE >; - using ParentClass::USD; + using typename ParentClass::LayoutType; + using typename ParentClass::ExtentType; + using typename ParentClass::StrideType; + using typename ParentClass::IndexType; using typename ParentClass::NestedViewType; using typename ParentClass::NestedViewTypeConst; + using ParentClass::NDIM; + using ParentClass::USD; + + /// Index of dimension for single-parameter resize. TODO: consider making this a template parameter? + static constexpr int SingleResizeDim = 0; + + /// Whether array can be resized/cleared + static constexpr bool IsResizable = !is_constant_v< camp::tuple_element_t< SingleResizeDim, ExtentType > >; + /** * @name Constructors, destructor and assignment operators. */ @@ -86,11 +86,9 @@ class Array : public ArrayView< T, * @brief default constructor */ LVARRAY_HOST_DEVICE - inline Array(): + Array2(): ParentClass( true ) { - this->m_strides = indexing::calculateStrides< PERMUTATION >( this->m_dims ); - #if !defined(LVARRAY_DEVICE_COMPILE) setName( "" ); #endif @@ -107,8 +105,8 @@ class Array : public ArrayView< T, typename=std::enable_if_t< sizeof ... ( DIMS ) == NDIM && typeManipulation::all_of_t< std::is_integral< DIMS > ... >::value > > LVARRAY_HOST_DEVICE - inline explicit Array( DIMS const ... dims ): - Array() + inline explicit Array2( DIMS const ... dims ): + Array2() { resize( dims ... ); } /** @@ -116,11 +114,9 @@ class Array : public ArrayView< T, * @param buffer The buffer to construct the Array from. * @note The Array is empty and @p buffer is expected to be empty as well. */ - Array( BUFFER_TYPE< T > && buffer ): + Array2( BUFFER_TYPE< T > && buffer ): ParentClass( std::move( buffer ) ) { - this->m_strides = indexing::calculateStrides< PERMUTATION >( this->m_dims ); - #if !defined(LVARRAY_DEVICE_COMPILE) setName( "" ); #endif @@ -135,8 +131,8 @@ class Array : public ArrayView< T, * @note Performs a deep copy of source */ LVARRAY_HOST_DEVICE - Array( Array const & source ): - Array() + Array2( Array2 const & source ): + Array2() { *this = source; } /** @@ -147,21 +143,19 @@ class Array : public ArrayView< T, * implementation of BUFFER_TYPE. */ LVARRAY_HOST_DEVICE - Array( Array && source ): + Array2( Array2 && source ): ParentClass( std::move( source ) ) { - for( int i = 0; i < NDIM; ++i ) - { - source.m_dims[ i ] = 0; - source.m_strides[ i ] = 0; - } + // This resets to 0 all non-constant extents/strides + source.m_layout.extent() = ExtentType{}; + source.m_layout.stride() = StrideType{}; } /** * @brief Destructor, free's the data. */ LVARRAY_HOST_DEVICE - ~Array() + ~Array2() { bufferManipulation::free( this->m_dataBuffer, this->size() ); } /** @@ -170,17 +164,10 @@ class Array : public ArrayView< T, * @return *this. */ LVARRAY_HOST_DEVICE - Array & operator=( Array const & rhs ) + Array2 & operator=( Array2 const & rhs ) { bufferManipulation::copyInto( this->m_dataBuffer, this->size(), rhs.m_dataBuffer, rhs.size() ); - - for( int i = 0; i < NDIM; ++i ) - { - this->m_dims[ i ] = rhs.m_dims[ i ]; - this->m_strides[ i ] = rhs.m_strides[ i ]; - } - - setSingleParameterResizeIndex( rhs.getSingleParameterResizeIndex() ); + this->m_layout = rhs.m_layout; return *this; } @@ -190,19 +177,10 @@ class Array : public ArrayView< T, * @return *this. */ LVARRAY_HOST_DEVICE - Array & operator=( typename ParentClass::ViewTypeConst const & rhs ) + Array2 & operator=( typename ParentClass::ViewTypeConst const & rhs ) { bufferManipulation::copyInto( this->m_dataBuffer, this->size(), rhs.dataBuffer(), rhs.size() ); - - INDEX_TYPE const * const dims = rhs.dims(); - INDEX_TYPE const * const strides = rhs.strides(); - for( int i = 0; i < NDIM; ++i ) - { - this->m_dims[ i ] = dims[ i ]; - this->m_strides[ i ] = strides[ i ]; - } - - setSingleParameterResizeIndex( rhs.getSingleParameterResizeIndex() ); + this->m_layout = rhs.m_layout; return *this; } @@ -212,17 +190,14 @@ class Array : public ArrayView< T, * @return *this. */ LVARRAY_HOST_DEVICE - Array & operator=( Array && rhs ) + Array2 & operator=( Array2 && rhs ) { bufferManipulation::free( this->m_dataBuffer, this->size() ); - ParentClass::operator=( std::move( rhs ) ); - for( int i = 0; i < NDIM; ++i ) - { - rhs.m_dims[ i ] = 0; - rhs.m_strides[ i ] = 0; - } + // Reset all dynamic extents/strides to 0 + rhs.m_layout.extent() = ExtentType{}; + rhs.m_layout.stride() = StrideType{}; return *this; } @@ -244,7 +219,7 @@ class Array : public ArrayView< T, * This overload prevents that from happening. */ inline LVARRAY_HOST_DEVICE constexpr - ArrayView< T, NDIM, USD, INDEX_TYPE, BUFFER_TYPE > toView() const && = delete; + ArrayView2< T, LayoutType, BUFFER_TYPE > toView() const && = delete; using ParentClass::toViewConst; @@ -256,7 +231,7 @@ class Array : public ArrayView< T, * This overload prevents that from happening. */ inline LVARRAY_HOST_DEVICE constexpr - ArrayView< T const, NDIM, USD, INDEX_TYPE, BUFFER_TYPE > toViewConst() const && = delete; + ArrayView2< T const, LayoutType, BUFFER_TYPE > toViewConst() const && = delete; using ParentClass::toNestedView; @@ -287,7 +262,7 @@ class Array : public ArrayView< T, * @return A new ArrayView where @c T is @c const. */ inline LVARRAY_HOST_DEVICE constexpr - operator ArrayView< T const, NDIM, USD, INDEX_TYPE, BUFFER_TYPE >() const & noexcept + operator ArrayView2< T const, LayoutType, BUFFER_TYPE >() const & noexcept { return toViewConst(); } /** @@ -297,10 +272,10 @@ class Array : public ArrayView< T, * contain the buffer of the current @c Array that is about to be destroyed. * This overload prevents that from happening. */ - template< typename _T=T > + template< typename T_=T > inline LVARRAY_HOST_DEVICE constexpr - operator std::enable_if_t< !std::is_const< _T >::value, - ArrayView< T const, NDIM, USD, INDEX_TYPE, BUFFER_TYPE > >() const && noexcept = delete; + operator std::enable_if_t< !std::is_const< T_ >::value, + ArrayView2< T const, LayoutType, BUFFER_TYPE > >() const && noexcept = delete; ///@} @@ -309,6 +284,8 @@ class Array : public ArrayView< T, */ ///@{ +public: + /** * @brief Resize the dimensions of the Array to match the given dimensions. * @param numDims must equal NDIMS. @@ -320,47 +297,65 @@ class Array : public ArrayView< T, void resize( int const numDims, DIMS_TYPE const * const dims ) { LVARRAY_ERROR_IF_NE( numDims, NDIM ); - - INDEX_TYPE const oldSize = this->size(); - for( int i = 0; i < NDIM; ++i ) + IndexType const oldSize = this->size(); + tupleManipulation::forEach( this->m_layout.extent(), [dims, i = 0]( auto & e ) mutable { - this->m_dims[ i ] = LvArray::integerConversion< INDEX_TYPE >( dims[ i ] ); - LVARRAY_ERROR_IF_LT( this->m_dims[ i ], 0 ); - } - - this->m_strides = indexing::calculateStrides< PERMUTATION >( this->m_dims ); - + if constexpr( is_constant_v< decltype( e ) > ) + { + // For static extents, only check that assigned value is the same + LVARRAY_ERROR_IF_NE_MSG( dims[ i ], e, "Static array extent cannot be changed" ); + } + else + { + LVARRAY_ERROR_IF_LT( dims[ i ], 0 ); + e = dims[ i ]; + } + ++i; + } ); + calculateStrides(); bufferManipulation::resize( this->m_dataBuffer, oldSize, this->size() ); } /** * @brief function to resize the array. * @tparam DIMS Variadic list of integral types. - * @param newDims The new dimensions, must be of length NDIM. + * @param newExtent The new extent * @note This does not preserve the values in the Array unless NDIM == 1. * @return void. */ template< typename ... DIMS > LVARRAY_HOST_DEVICE - std::enable_if_t< sizeof ... ( DIMS ) == NDIM && typeManipulation::all_of_t< std::is_integral< DIMS > ... >::value > - resize( DIMS const ... newDims ) + void + resize( Extent< DIMS ... > const & newExtent ) { static_assert( sizeof ... ( DIMS ) == NDIM, "The number of arguments provided does not equal NDIM!" ); - INDEX_TYPE const oldSize = this->size(); - - int curDim = 0; - typeManipulation::forEachArg( [&]( auto const newDim ) + tupleManipulation::forEach( newExtent, []( auto const newDim ) { - this->m_dims[ curDim ] = LvArray::integerConversion< INDEX_TYPE >( newDim ); - LVARRAY_ERROR_IF_LT( this->m_dims[ curDim ], 0 ); - ++curDim; - }, newDims ... ); + LVARRAY_ERROR_IF_LT( newDim, 0 ); + } ); - this->m_strides = indexing::calculateStrides< PERMUTATION >( this->m_dims ); + IndexType const oldSize = this->size(); + this->m_layout.extent() = newExtent; + calculateStrides(); bufferManipulation::resize( this->m_dataBuffer, oldSize, this->size() ); } + /** + * @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 NDIM == 1. + * @return void. + */ + template< typename ... DIMS > + LVARRAY_HOST_DEVICE + std::enable_if_t< sizeof ... ( DIMS ) == NDIM && typeManipulation::all_of< is_integral_v< DIMS > ... >::value > + resize( DIMS const ... newDims ) + { + resize( makeExtent( newDims... ) ); + } + /** * @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. @@ -388,20 +383,16 @@ class Array : public ArrayView< T, void resizeWithoutInitializationOrDestruction( MemorySpace const space, 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." ); + static_assert( std::is_trivially_destructible< T >::value, "This function is only safe if T is trivially destructible." ); - INDEX_TYPE const oldSize = this->size(); - - int i = 0; typeManipulation::forEachArg( [&]( auto const newDim ) { - this->m_dims[ i ] = LvArray::integerConversion< INDEX_TYPE >( newDim ); - LVARRAY_ERROR_IF_LT( this->m_dims[ i ], 0 ); - ++i; + LVARRAY_ERROR_IF_LT( newDim, 0 ); }, newDims ... ); - this->m_strides = indexing::calculateStrides< PERMUTATION >( this->m_dims ); + IndexType const oldSize = this->size(); + this->m_layout.extent() = makeExtent( newDims... ); + calculateStrides(); bufferManipulation::reserve( this->m_dataBuffer, oldSize, space, this->size() ); } @@ -414,7 +405,7 @@ class Array : public ArrayView< T, * dimensions INDICES[ 0 ]. * @note This does not preserve the values in the Array unless NDIM == 1. */ - template< INDEX_TYPE... INDICES, typename ... DIMS > + template< int ... INDICES, typename ... DIMS > LVARRAY_HOST_DEVICE void resizeDimension( DIMS const ... newDims ) { @@ -423,16 +414,15 @@ class Array : public ArrayView< T, "The number of indices must match the number of dimensions." ); static_assert( typeManipulation::all_of< ( 0 <= INDICES ) ... >::value, "INDICES must all be positive." ); static_assert( typeManipulation::all_of< ( INDICES < NDIM ) ... >::value, "INDICES must all be less than NDIM." ); - - INDEX_TYPE const oldSize = this->size(); - - typeManipulation::forEachArg( [&]( auto const & pair ) + + typeManipulation::forEachArg( [&]( auto const & newDim ) { - this->m_dims[ camp::get< 0 >( pair ) ] = LvArray::integerConversion< INDEX_TYPE >( camp::get< 1 >( pair ) ); - LVARRAY_ERROR_IF_LT( this->m_dims[ camp::get< 0 >( pair ) ], 0 ); - }, camp::make_tuple( INDICES, newDims )... ); + LVARRAY_ERROR_IF_LT( newDim, 0 ); + }, newDims... ); - this->m_strides = indexing::calculateStrides< PERMUTATION >( this->m_dims ); + IndexType const oldSize = this->size(); + tupleManipulation::selectRefs( this->m_layout.extent(), camp::idx_seq< INDICES... >{} ) = makeTuple( newDims... ); + calculateStrides(); bufferManipulation::resize( this->m_dataBuffer, oldSize, this->size() ); } @@ -441,10 +431,10 @@ class Array : public ArrayView< T, * @brief Resize the default dimension of the Array. * @param newdim the new size of the default dimension. * @note This preserves the values in the Array. - * @note The default dimension is given by m_singleParameterResizeIndex. + * @note The default dimension is 0. */ LVARRAY_HOST_DEVICE - void resize( INDEX_TYPE const newdim ) + void resize( IndexType const newdim ) { resizeDefaultDimension( newdim ); } /** @@ -452,36 +442,23 @@ class Array : public ArrayView< T, * @param newdim the new size of the default dimension. * @param defaultValue the value to initialize the new values with. * @note This preserves the values in the Array. - * @note The default dimension is given by m_singleParameterResizeIndex. + * @note The default dimension is 0. */ LVARRAY_HOST_DEVICE - void resizeDefault( INDEX_TYPE const newdim, T const & defaultValue ) + void resizeDefault( IndexType const newdim, T const & defaultValue ) { resizeDefaultDimension( newdim, defaultValue ); } /** * @brief Sets the size of the Array to zero and destroys all the values. - * @details Sets the size of m_singleParameterResizeIndex to 0 but leaves the + * @details Sets the size of 0th dimension to 0 but leaves the * size of the other dimensions untouched. Equivalent to resize( 0 ). */ void clear() { + static_assert( IsResizable, "Array must have a dynamic leftmost extent to be resized." ); bufferManipulation::resize( this->m_dataBuffer, this->size(), 0 ); - - this->m_dims[ this->getSingleParameterResizeIndex() ] = 0; - - this->m_strides = indexing::calculateStrides< PERMUTATION >( this->m_dims ); - } - - /** - * @brief Set the default resize dimension. - * @param index The new default dimension. - */ - LVARRAY_HOST_DEVICE - inline void setSingleParameterResizeIndex( int const index ) - { - LVARRAY_ERROR_IF_LT( index, 0 ); - LVARRAY_ERROR_IF_GE( index, NDIM ); - this->m_singleParameterResizeIndex = index; + camp::get< SingleResizeDim >( this->m_layout.extent() ) = 0; + calculateStrides(); } ///@} @@ -496,7 +473,7 @@ class Array : public ArrayView< T, * @param newCapacity the number of values to reserve space for. After this call * capacity() >= newCapacity. */ - void reserve( INDEX_TYPE const newCapacity ) + void reserve( IndexType const newCapacity ) { bufferManipulation::reserve( this->m_dataBuffer, this->size(), MemorySpace::host, newCapacity ); } ///@} @@ -518,8 +495,9 @@ class Array : public ArrayView< T, std::enable_if_t< _NDIM == 1 > emplace_back( ARGS && ... args ) { + static_assert( IsResizable, "Array must have a dynamic leftmost extent to be resized." ); bufferManipulation::emplaceBack( this->m_dataBuffer, this->size(), std::forward< ARGS >( args ) ... ); - ++this->m_dims[ 0 ]; + ++camp::get< SingleResizeDim >( this->m_layout.extent() ); } /** @@ -532,10 +510,11 @@ class Array : public ArrayView< T, */ template< typename ... ARGS, int _NDIM=NDIM > std::enable_if_t< _NDIM == 1 > - emplace( INDEX_TYPE const pos, ARGS && ... args ) + emplace( IndexType const pos, ARGS && ... args ) { + static_assert( IsResizable, "Array must have a dynamic leftmost extent to be resized." ); bufferManipulation::emplace( this->m_dataBuffer, this->size(), pos, std::forward< ARGS >( args ) ... ); - ++this->m_dims[ 0 ]; + ++camp::get< SingleResizeDim >( this->m_layout.extent() ); } /** @@ -549,8 +528,11 @@ class Array : public ArrayView< T, */ template< typename ITER, int _NDIM=NDIM > std::enable_if_t< _NDIM == 1 > - insert( INDEX_TYPE const pos, ITER const first, ITER const last ) - { this->m_dims[ 0 ] += bufferManipulation::insert( this->m_dataBuffer, this->size(), pos, first, last ); } + insert( IndexType const pos, ITER const first, ITER const last ) + { + static_assert( IsResizable, "Array must have a dynamic leftmost extent to be resized." ); + camp::get< SingleResizeDim >( this->m_layout.extent() ) += bufferManipulation::insert( this->m_dataBuffer, this->size(), pos, first, last ); + } /** * @brief Remove the last value in the array. @@ -561,8 +543,9 @@ class Array : public ArrayView< T, std::enable_if_t< _NDIM == 1 > pop_back() { + static_assert( IsResizable, "Array must have a dynamic leftmost extent to be resized." ); bufferManipulation::popBack( this->m_dataBuffer, this->size() ); - --this->m_dims[ 0 ]; + --camp::get< SingleResizeDim >( this->m_layout.extent() ); } /** @@ -573,10 +556,11 @@ class Array : public ArrayView< T, */ template< int _NDIM=NDIM > std::enable_if_t< _NDIM == 1 > - erase( INDEX_TYPE const pos ) + erase( IndexType const pos ) { + static_assert( IsResizable, "Array must have a dynamic leftmost extent to be resized." ); bufferManipulation::erase( this->m_dataBuffer, this->size(), pos ); - --this->m_dims[ 0 ]; + --camp::get< SingleResizeDim >( this->m_layout.extent() ); } ///@} @@ -602,43 +586,50 @@ class Array : public ArrayView< T, private: + LVARRAY_HOST_DEVICE + void calculateStrides() + { + this->m_layout.stride() = makeCompactStride( LayoutDefault{}, this->layout().extent(), Permutation{} ); + } + /** * @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. * @note This preserves the values in the Array. - * @note The default dimension is given by m_singleParameterResizeIndex. + * @note The default dimension is 0. */ DISABLE_HD_WARNING template< typename ... ARGS > LVARRAY_HOST_DEVICE - void resizeDefaultDimension( INDEX_TYPE const newDimLength, ARGS && ... args ) + void resizeDefaultDimension( IndexType const newDimLength, ARGS && ... args ) { + static_assert( IsResizable, "Array must have a dynamic leftmost extent to be resized." ); LVARRAY_ERROR_IF_LT( newDimLength, 0 ); - // If m_singleParameterResizeIndex is the first dimension in memory than a simple 1D resizing is sufficient. The + // If SingleResizeDim 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 || typeManipulation::asArray( PERMUTATION {} )[ 0 ] == this->m_singleParameterResizeIndex ) + if( NDIM == 1 || typeManipulation::asArray( PERMUTATION {} )[ 0 ] == SingleResizeDim ) { - INDEX_TYPE const oldSize = this->size(); - this->m_dims[ this->m_singleParameterResizeIndex ] = newDimLength; - this->m_strides = indexing::calculateStrides< PERMUTATION >( this->m_dims ); + IndexType const oldSize = this->size(); + camp::get< SingleResizeDim >( this->m_layout.extent() ) = newDimLength; + calculateStrides(); bufferManipulation::resize( this->m_dataBuffer, oldSize, this->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 = this->m_dims[ this->m_singleParameterResizeIndex ]; - INDEX_TYPE const curDimStride = this->m_strides[ this->m_singleParameterResizeIndex ]; - INDEX_TYPE const curSize = this->size(); + IndexType const curDimLength = camp::get< SingleResizeDim >( this->m_layout.extent() ); + IndexType const curDimStride = camp::get< SingleResizeDim >( this->m_layout.stride() ); + IndexType const curSize = this->size(); // Set the size of the dimension, recalculate the strides and get the new total size. - this->m_dims[ this->m_singleParameterResizeIndex ] = newDimLength; - this->m_strides = indexing::calculateStrides< PERMUTATION >( this->m_dims ); + camp::get< SingleResizeDim >( this->m_layout.extent() ) = newDimLength; + calculateStrides(); - INDEX_TYPE const newSize = this->size(); + IndexType const newSize = this->size(); // If we aren't changing the total size then we can return early. if( newSize == curSize ) return; @@ -652,22 +643,22 @@ class Array : public ArrayView< T, // The resizing consists of iterations where each iteration consists of the addition of a // contiguous segment of new values. - INDEX_TYPE const valuesToAddPerIteration = curDimStride * ( newDimLength - curDimLength ); - INDEX_TYPE const valuesToShiftPerIteration = curDimStride * curDimLength; - INDEX_TYPE const numIterations = ( newSize - curSize ) / valuesToAddPerIteration; + IndexType const valuesToAddPerIteration = curDimStride * ( newDimLength - curDimLength ); + IndexType const valuesToShiftPerIteration = curDimStride * curDimLength; + IndexType const numIterations = ( newSize - curSize ) / valuesToAddPerIteration; // Iterate backwards over the iterations. - for( INDEX_TYPE i = numIterations - 1; i >= 0; --i ) + for( IndexType i = numIterations - 1; i >= 0; --i ) { // First shift the values up to make remove for the values of subsequent iterations. // This step is a no-op on the last iteration (i=0). - INDEX_TYPE const valuesLeftToInsert = valuesToAddPerIteration * i; + IndexType const valuesLeftToInsert = valuesToAddPerIteration * i; T * const startOfShift = ptr + valuesToShiftPerIteration * i; - arrayManipulation::shiftUp( startOfShift, valuesToShiftPerIteration, INDEX_TYPE( 0 ), valuesLeftToInsert ); + arrayManipulation::shiftUp( startOfShift, valuesToShiftPerIteration, IndexType( 0 ), valuesLeftToInsert ); // Initialize the new values. T * const startOfNewValues = startOfShift + valuesToShiftPerIteration + valuesLeftToInsert; - for( INDEX_TYPE j = 0; j < valuesToAddPerIteration; ++j ) + for( IndexType j = 0; j < valuesToAddPerIteration; ++j ) { new ( startOfNewValues + j ) T( args ... ); } @@ -679,14 +670,14 @@ class Array : public ArrayView< T, // The resizing consists of iterations where each iteration consists of the removal of a // contiguous segment of new values. - INDEX_TYPE const valuesToRemovePerIteration = curDimStride * ( curDimLength - newDimLength ); - INDEX_TYPE const valuesToShiftPerIteration = curDimStride * newDimLength; - INDEX_TYPE const numIterations = ( curSize - newSize ) / valuesToRemovePerIteration; + IndexType const valuesToRemovePerIteration = curDimStride * ( curDimLength - newDimLength ); + IndexType const valuesToShiftPerIteration = curDimStride * newDimLength; + IndexType const numIterations = ( curSize - newSize ) / valuesToRemovePerIteration; // Iterate over the iterations, skipping the first. - for( INDEX_TYPE i = 1; i < numIterations; ++i ) + for( IndexType i = 1; i < numIterations; ++i ) { - INDEX_TYPE const amountToShift = valuesToRemovePerIteration * i; + IndexType const amountToShift = valuesToRemovePerIteration * i; T * const startOfShift = ptr + valuesToShiftPerIteration * i; arrayManipulation::shiftDown( startOfShift, valuesToShiftPerIteration + amountToShift, @@ -695,8 +686,8 @@ class Array : public ArrayView< T, // After the iterations are complete all the values to remove have been moved to the end of the array. // We destroy them here. - INDEX_TYPE const totalValuesToRemove = valuesToRemovePerIteration * numIterations; - for( INDEX_TYPE i = 0; i < totalValuesToRemove; ++i ) + IndexType const totalValuesToRemove = valuesToRemovePerIteration * numIterations; + for( IndexType i = 0; i < totalValuesToRemove; ++i ) { ptr[ newSize + i ].~T(); } @@ -704,6 +695,13 @@ class Array : public ArrayView< T, } }; +template< typename T, + int NDIM, + typename PERMUTATION, + typename INDEX_TYPE, + template< typename > class BUFFER_TYPE > +using Array = Array2< T, DynamicExtent< NDIM, INDEX_TYPE >, PERMUTATION, BUFFER_TYPE >; + /** * @brief True if the template type is an Array. */ @@ -719,11 +717,10 @@ constexpr bool isArray = false; * @brief Specialization of isArray for the Array class. */ template< typename T, - int NDIM, + typename EXTENT, typename PERMUTATION, - typename INDEX_TYPE, template< typename > class BUFFER_TYPE > -constexpr bool isArray< Array< T, NDIM, PERMUTATION, INDEX_TYPE, BUFFER_TYPE > > = true; +constexpr bool isArray< Array2< T, EXTENT, PERMUTATION, BUFFER_TYPE > > = true; namespace internal { diff --git a/src/ArrayOfArraysView.hpp b/src/ArrayOfArraysView.hpp index e92c5843..48042da2 100644 --- a/src/ArrayOfArraysView.hpp +++ b/src/ArrayOfArraysView.hpp @@ -406,10 +406,10 @@ class ArrayOfArraysView * @param i the array to access. */ LVARRAY_HOST_DEVICE CONSTEXPR_WITHOUT_BOUNDS_CHECK inline - ArraySlice< T, 1, 0, INDEX_TYPE_NC > operator[]( INDEX_TYPE const i ) const + ArraySlice2< T, DynamicLayout1D< INDEX_TYPE > > operator[]( INDEX_TYPE const i ) const { ARRAYOFARRAYS_CHECK_BOUNDS( i ); - return ArraySlice< T, 1, 0, INDEX_TYPE_NC >( m_values.data() + m_offsets[ i ], &m_sizes[ i ], nullptr ); + return ArraySlice2< T, DynamicLayout1D< INDEX_TYPE > >( m_values.data() + m_offsets[ i ], makeLayout( makeExtent( m_sizes[ i ] ) ) ); } /** diff --git a/src/ArraySlice.hpp b/src/ArraySlice.hpp index 374979e3..9ec544be 100644 --- a/src/ArraySlice.hpp +++ b/src/ArraySlice.hpp @@ -36,8 +36,10 @@ DEFINE_GDB_PY_SCRIPT( "scripts/gdb-printers.py" ) // Source includes #include "LvArrayConfig.hpp" +#include "Layout.hpp" #include "indexing.hpp" #include "Macros.hpp" +#include "sortedArrayManipulation.hpp" // System includes #ifndef NDEBUG @@ -85,24 +87,33 @@ 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_TPARAM, int USD_TPARAM, typename INDEX_TYPE > -class ArraySlice +template< typename T, typename LAYOUT > +class ArraySlice2 { public: - static_assert( USD_TPARAM < NDIM_TPARAM, "USD must be less than NDIM." ); + static_assert( is_layout_v< LAYOUT >, "LAYOUT template parameter must be a Layout instantiation" ); - /// The type of the value in the ArraySlice. - using ValueType = T; + /// The type of layout. + using LayoutType = LAYOUT; + + /// The type of extent. + using Extent = typename LayoutType::ExtentType; + + /// The type of stride. + using Stride = typename LayoutType::StrideType; /// The number of dimensions. - static constexpr int NDIM = NDIM_TPARAM; + static constexpr int NDIM = LayoutType::NDIM; - /// The unit stride dimension. - static constexpr int USD = USD_TPARAM; + /// The unit-stride dimension index. + static constexpr int USD = LayoutType::USD; + + /// The type of the value in the ArraySlice. + using ValueType = T; /// The integer type used for indexing. - using IndexType = INDEX_TYPE; + using IndexType = typename LayoutType::IndexType; /** * @name Constructors, destructor and assignment operators. @@ -110,7 +121,7 @@ class ArraySlice ///@{ /// deleted default constructor - ArraySlice() = delete; + ArraySlice2() = delete; /** * @brief Construct a new ArraySlice. @@ -118,13 +129,11 @@ class ArraySlice * @param inputDimensions pointer to the beginning of the dimensions for this slice. * @param inputStrides pointer to the beginning of the strides for this slice */ - LVARRAY_HOST_DEVICE inline explicit CONSTEXPR_WITHOUT_BOUNDS_CHECK - ArraySlice( T * const LVARRAY_RESTRICT inputData, - INDEX_TYPE const * const LVARRAY_RESTRICT inputDimensions, - INDEX_TYPE const * const LVARRAY_RESTRICT inputStrides ) noexcept: + LVARRAY_HOST_DEVICE explicit CONSTEXPR_WITHOUT_BOUNDS_CHECK + ArraySlice2( T * const LVARRAY_RESTRICT inputData, + LayoutType const & layout ) noexcept: m_data( inputData ), - m_dims( inputDimensions ), - m_strides( inputStrides ) + m_layout( layout ) { #if defined(LVARRAY_USE_TOTALVIEW_OUTPUT) && !defined(LVARRAY_DEVICE_COMPILE) && defined(LVARRAY_BOUNDS_CHECK) ArraySlice::TV_ttf_display_type( nullptr ); @@ -141,18 +150,18 @@ class ArraySlice /** * @return Return a new immutable slice. */ - LVARRAY_HOST_DEVICE inline constexpr - ArraySlice< T const, NDIM, USD, INDEX_TYPE > + LVARRAY_HOST_DEVICE constexpr + ArraySlice2< T const, LayoutType > toSliceConst() const noexcept - { return ArraySlice< T const, NDIM, USD, INDEX_TYPE >( m_data, m_dims, m_strides ); } + { return ArraySlice2< T const, LayoutType >( m_data, m_layout ); } /** * @return Return a new immutable slice. */ template< typename U=T > - LVARRAY_HOST_DEVICE inline constexpr + LVARRAY_HOST_DEVICE constexpr operator std::enable_if_t< !std::is_const< U >::value, - ArraySlice< T const, NDIM, USD, INDEX_TYPE > > + ArraySlice2< T const, LayoutType > > () const noexcept { return toSliceConst(); } @@ -163,73 +172,104 @@ class ArraySlice */ ///@{ + LVARRAY_HOST_DEVICE constexpr + auto const & + layout() const noexcept + { + return m_layout; + } + /** * @return Return the total size of the slice. */ - LVARRAY_HOST_DEVICE inline constexpr - INDEX_TYPE size() const noexcept + LVARRAY_HOST_DEVICE constexpr + auto + size() const noexcept { - #if defined( __ibmxl__ ) - // Note: This used to be done with a recursive template but XL-release would produce incorrect results. - // Specifically in exampleArray it would return an "old" size even after being updated, strange. - INDEX_TYPE val = m_dims[ 0 ]; - for( int i = 1; i < NDIM; ++i ) - { val *= m_dims[ i ]; } - - return val; - #else - return indexing::multiplyAll< NDIM >( m_dims ); - #endif + return m_layout.size(); } /** * @return Return the length of the given dimension. * @param dim the dimension to get the length of. */ - LVARRAY_HOST_DEVICE inline CONSTEXPR_WITHOUT_BOUNDS_CHECK - INDEX_TYPE size( int const dim ) const noexcept + LVARRAY_HOST_DEVICE CONSTEXPR_WITHOUT_BOUNDS_CHECK + auto + size( int const dim ) const noexcept { #ifdef LVARRAY_BOUNDS_CHECK LVARRAY_ERROR_IF_GE( dim, NDIM ); #endif - return m_dims[ dim ]; + return tupleManipulation::getValue( m_layout.extent(), dim ); + } + + /** + * @return Return the length of the given dimension. + * @param N the dimension to get the length of. + */ + template< int N > + LVARRAY_HOST_DEVICE constexpr + IndexType size() const noexcept + { + static_assert( N < NDIM, "Dimension index must be less than number of dimensions." ); + return camp::get< N >( m_layout.extent() ); } /** * @return Return the stride of the given dimension. * @param dim the dimension to get the stride of. */ - LVARRAY_HOST_DEVICE inline CONSTEXPR_WITHOUT_BOUNDS_CHECK - INDEX_TYPE stride( int const dim ) const noexcept + LVARRAY_HOST_DEVICE CONSTEXPR_WITHOUT_BOUNDS_CHECK + IndexType stride( int const dim ) const noexcept { #ifdef LVARRAY_BOUNDS_CHECK LVARRAY_ERROR_IF_GE( dim, NDIM ); #endif - return m_strides[ dim ]; + return tupleManipulation::getValue( m_layout.stride(), dim ); + } + + /** + * @return Return the stride of the given dimension. + * @param N the dimension to get the stride of. + */ + template< int N > + LVARRAY_HOST_DEVICE constexpr + auto stride() const noexcept + { + static_assert( N < NDIM, "Dimension index must be less than number of dimensions." ); + return camp::get< N >( m_layout.stride() ); } /** * @brief Check if the slice is contiguous in memory * @return @p true if represented slice is contiguous in memory */ - LVARRAY_HOST_DEVICE inline constexpr + LVARRAY_HOST_DEVICE constexpr bool isContiguous() const { + // Deal with obvious cases if( USD < 0 ) return false; if( NDIM == 1 && USD == 0 ) return true; - bool rval = true; + // Slice is contiguous when strides are an ex-scan of extents. + // Since they might be permuted, we need to sort them first. + // Can't sort tuples directly, so decay to arrays. + // XXX: Is there an easier/faster way? + + auto sortedExtents = tupleManipulation::toArray( m_layout.extent() ); + auto sortedStrides = tupleManipulation::toArray( m_layout.stride() ); + sortedArrayManipulation::dualSort( sortedStrides.data, sortedStrides.data + NDIM, sortedExtents.data ); + + IndexType stride = 1; for( int i = 0; i < NDIM; ++i ) { - if( i == USD ) continue; - INDEX_TYPE prod = 1; - for( int j = 0; j < NDIM; ++j ) + if ( stride != sortedStrides[i] ) { - if( j != i ) prod *= m_dims[j]; + return false; } - rval &= (m_strides[i] <= prod); + stride *= sortedExtents[i]; } - return rval; + return true; } /** @@ -238,14 +278,11 @@ class ArraySlice * @param indices The indices of the value to get the linear index of. */ template< typename ... INDICES > - LVARRAY_HOST_DEVICE inline CONSTEXPR_WITHOUT_BOUNDS_CHECK - INDEX_TYPE linearIndex( INDICES... indices ) const + LVARRAY_HOST_DEVICE CONSTEXPR_WITHOUT_BOUNDS_CHECK + IndexType linearIndex( INDICES... indices ) const { static_assert( sizeof ... (INDICES) == NDIM, "number of indices does not match NDIM" ); -#ifdef LVARRAY_BOUNDS_CHECK - indexing::checkIndices( m_dims, indices ... ); -#endif - return indexing::getLinearIndex< USD >( m_strides, indices ... ); + return m_layout( indices... ); } ///@} @@ -260,52 +297,47 @@ class ArraySlice * @note This method is only active when NDIM == 1 and USD == 0. */ template< int NDIM_=NDIM, int USD_=USD > - LVARRAY_HOST_DEVICE constexpr inline + LVARRAY_HOST_DEVICE constexpr operator std::enable_if_t< NDIM_ == 1 && USD_ == 0, T * const LVARRAY_RESTRICT > () const noexcept { return m_data; } - /** - * @return Return a lower dimensionsal slice of this ArrayView. - * @param index The index of the slice to create. - * @note This method is only active when NDIM > 1. - */ - template< int U=NDIM > - LVARRAY_HOST_DEVICE inline CONSTEXPR_WITHOUT_BOUNDS_CHECK - std::enable_if_t< (U > 1), ArraySlice< T, NDIM - 1, USD - 1, INDEX_TYPE > > - operator[]( INDEX_TYPE const index ) const noexcept - { - ARRAY_SLICE_CHECK_BOUNDS( index ); - return ArraySlice< T, NDIM-1, USD-1, INDEX_TYPE >( m_data + indexing::ConditionalMultiply< USD == 0 >::multiply( index, m_strides[ 0 ] ), - m_dims + 1, - m_strides + 1 ); - } - /** * @return Return a reference to the value at the given index. * @param index The index of the value to access. * @note This method is only active when NDIM == 1. */ - template< int U=NDIM > - LVARRAY_HOST_DEVICE inline CONSTEXPR_WITHOUT_BOUNDS_CHECK - std::enable_if_t< U == 1, T & > - operator[]( INDEX_TYPE const index ) const noexcept + LVARRAY_HOST_DEVICE CONSTEXPR_WITHOUT_BOUNDS_CHECK + decltype(auto) + operator[]( IndexType const index ) const noexcept { - ARRAY_SLICE_CHECK_BOUNDS( index ); - return m_data[ indexing::ConditionalMultiply< USD == 0 >::multiply( index, m_strides[ 0 ] ) ]; + return operator()( index ); } /** * @tparam INDICES A variadic pack of integral types. - * @return Return a reference to the value at the given multidimensional index. + * @return Return a reference to the value at the given multidimensional index or a lower-dimensional slice. * @param indices The indices of the value to access. + * + * If the number of indices matches the number of slice dimensions, and none of the indices are a slicer (_{}) + * a value reference is returned. Otherwise the set of indices is applied to the left-most dimensions, and + * a slice representing the remaining dimension is returned. */ template< typename ... INDICES > - LVARRAY_HOST_DEVICE inline constexpr - T & operator()( INDICES... indices ) const + LVARRAY_HOST_DEVICE CONSTEXPR_WITHOUT_BOUNDS_CHECK + decltype(auto) + operator()( INDICES... indices ) const { - static_assert( sizeof ... (INDICES) == NDIM, "number of indices does not match NDIM" ); - return m_data[ linearIndex( indices ... ) ]; + auto const sliceLayout = m_layout.slice( indices... ); + auto const sliceOffset = m_layout( indices... ); + if constexpr ( decltype( sliceLayout )::NDIM == 0 ) + { + return m_data[ sliceOffset ]; + } + else + { + return ArraySlice2< T, std::remove_cv_t< decltype( sliceLayout ) > >( m_data + sliceOffset, sliceLayout ); + } } /** @@ -314,7 +346,7 @@ class ArraySlice * @pre The slice must be contiguous. */ template< int USD_ = USD > - LVARRAY_HOST_DEVICE inline + LVARRAY_HOST_DEVICE T * dataIfContiguous() const { // Note: need both compile-time and runtime checks as USD >= 0 does not guarantee contiguous data. @@ -327,7 +359,7 @@ class ArraySlice * @return Return a pointer to the values. * @pre The slice must be contiguous. */ - LVARRAY_HOST_DEVICE inline constexpr + LVARRAY_HOST_DEVICE constexpr T * begin() const { return dataIfContiguous(); } @@ -335,7 +367,7 @@ class ArraySlice * @return Return a pointer to the end values. * @pre The slice must be contiguous. */ - LVARRAY_HOST_DEVICE inline constexpr + LVARRAY_HOST_DEVICE constexpr T * end() const { return dataIfContiguous() + size(); } @@ -347,7 +379,7 @@ class ArraySlice * @param av A pointer to the array that is being displayed. * @return 0 if everything went OK */ - static int TV_ttf_display_type( ArraySlice const * av ) + static int TV_ttf_display_type( ArraySlice2 const * av ) { if( av!=nullptr ) { @@ -367,12 +399,37 @@ class ArraySlice /// pointer to beginning of data for this array, or sub-array. T * const LVARRAY_RESTRICT m_data; - /// pointer to array of length NDIM that contains the lengths of each array dimension - INDEX_TYPE const * const LVARRAY_RESTRICT m_dims; + /// layout describing the mapping from coordinates to memory offsets + LayoutType m_layout; - /// pointer to array of length NDIM that contains the strides of each array dimension - INDEX_TYPE const * const LVARRAY_RESTRICT m_strides; +}; +template< int NDIM, int USD, typename INDEX_TYPE > +struct ArraySliceDefaultStrideHelper +{ + using FullDynamicStride = decltype( tupleManipulation::repeat< NDIM >( INDEX_TYPE{} ) ); + using StrideWithUSD = decltype( tupleManipulation::replace< (USD < 0) ? 0 : USD >( FullDynamicStride{}, Constant< INDEX_TYPE, 1 >{} ) ); + using type = std::conditional_t< ( USD < 0 ), FullDynamicStride, StrideWithUSD >; }; +template< int NDIM, int USD, typename INDEX_TYPE > +using ArraySliceDefaultStride = typename ArraySliceDefaultStrideHelper< NDIM, USD, INDEX_TYPE >::type; + +/** + * @class ArraySlice + * @brief This class serves to provide a sliced multidimensional interface to the family of LvArray classes. + * @tparam T type of data that is contained by the array + * @tparam NDIM The number of dimensions in array (e.g. NDIM=1->vector, NDIM=2->Matrix, etc. ). + * @tparam USD The dimension with a unit stride, in an Array with a standard layout + * this is the last dimension. + * @tparam INDEX_TYPE The integer to use for indexing the components of the array. + * @brief This class serves as a sliced interface to an array. This is a lightweight class that contains + * only pointers, and provides an operator[] to create a lower dimensionsal slice and an operator() + * to access values given a multidimensional index. + * 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, typename INDEX_TYPE > +using ArraySlice = ArraySlice2< T, Layout< DynamicExtent< NDIM, INDEX_TYPE >, ArraySliceDefaultStride< NDIM, USD, INDEX_TYPE > > >; + } // namespace LvArray diff --git a/src/ArrayView.hpp b/src/ArrayView.hpp index aabd48bf..86b2d7a0 100644 --- a/src/ArrayView.hpp +++ b/src/ArrayView.hpp @@ -14,6 +14,7 @@ // Source includes #include "ArraySlice.hpp" +#include "Layout.hpp" #include "Macros.hpp" #include "indexing.hpp" #include "limits.hpp" @@ -34,10 +35,7 @@ namespace LvArray * @class ArrayView * @brief This class serves to provide a "view" of a multidimensional array. * @tparam T type of data that is contained by the array - * @tparam NDIM_TPARAM number of dimensions in array (e.g. NDIM=1->vector, NDIM=2->Matrix, etc. ). - * @tparam USD the dimension with a unit stride, in an Array with a standard layout - * this is the last dimension. - * @tparam INDEX_TYPE the integer to use for indexing. + * @tparam LAYOUT type of layout function that defines the mapping from logical coordinates to memory offsets * @tparam BUFFER_TYPE A class that defines how to actually allocate memory for the Array. Must take * one template argument that describes the type of the data being stored (T). * @@ -61,53 +59,60 @@ namespace LvArray * are only present in Array. */ template< typename T, - int NDIM_TPARAM, - int USD_TPARAM, - typename INDEX_TYPE, + typename LAYOUT, template< typename > class BUFFER_TYPE > -class ArrayView +class ArrayView2 { public: - static_assert( NDIM_TPARAM > 0, "Number of dimensions must be greater than zero." ); - static_assert( USD_TPARAM >= 0, "USD must be positive." ); - static_assert( USD_TPARAM < NDIM_TPARAM, "USD must be less than NDIM." ); + static_assert( is_layout_v< LAYOUT >, "LAYOUT template parameter must be a Layout instantiation" ); - /// The type of the values in the ArrayView. - using ValueType = T; + /// The type of layout. + using LayoutType = LAYOUT; + + /// The type of extent. + using ExtentType = typename LayoutType::ExtentType; + + /// The type of stride. + using StrideType = typename LayoutType::StrideType; /// The number of dimensions. - static constexpr int NDIM = NDIM_TPARAM; + static constexpr int NDIM = LayoutType::NDIM; + + /// The unit-stride dimension index. + static constexpr int USD = LayoutType::USD; + + static_assert( NDIM > 0, "Number of dimensions must be greater than zero." ); - /// The unit stride dimension. - static constexpr int USD = USD_TPARAM; + /// The type of the values in the ArrayView. + using ValueType = T; /// The integer type used for indexing. - using IndexType = INDEX_TYPE; + using IndexType = typename LayoutType::IndexType; - /// The type when the data type is const. - using ViewTypeConst = ArrayView< std::remove_const_t< T > const, NDIM, USD, INDEX_TYPE, BUFFER_TYPE >; + /// The view type + using ViewType = ArrayView2; + /// The type when the data type is const. + using ViewTypeConst = ArrayView2< std::remove_const_t< T > const, LAYOUT, BUFFER_TYPE >; /// The type when all inner array classes are converted to const views. - using NestedViewType = ArrayView< std::remove_reference_t< typeManipulation::NestedViewType< T > >, - NDIM, USD, INDEX_TYPE, BUFFER_TYPE >; + using NestedViewType = ArrayView2< std::remove_reference_t< typeManipulation::NestedViewType< T > >, LAYOUT, BUFFER_TYPE >; /// The type when all inner array classes are converted to const views and the inner most view's values are also const. - using NestedViewTypeConst = ArrayView< std::remove_reference_t< typeManipulation::NestedViewTypeConst< T > >, - NDIM, USD, INDEX_TYPE, BUFFER_TYPE >; + using NestedViewTypeConst = ArrayView2< std::remove_reference_t< typeManipulation::NestedViewTypeConst< T > >, LAYOUT, BUFFER_TYPE >; /// The type of the ArrayView when converted to an ArraySlice. - using SliceType = ArraySlice< T, NDIM, USD, INDEX_TYPE > const; + using SliceType = ArraySlice2< T, LayoutType > const; /// The type of the ArrayView when converted to an immutable ArraySlice. - using SliceTypeConst = ArraySlice< T const, NDIM, USD, INDEX_TYPE > const; + using SliceTypeConst = ArraySlice2< T const, LayoutType > const; /// The type of the values in the ArrayView, here for stl compatability. using value_type = T; /// The integer type used for indexing, here for stl compatability. - using size_type = INDEX_TYPE; + using size_type = IndexType; /** * @name Constructors, destructor and assignment operators. @@ -118,7 +123,7 @@ class ArrayView * @brief A constructor to create an uninitialized ArrayView. * @note An uninitialized ArrayView should not be used until it is assigned to. */ - ArrayView() = default; + ArrayView2() = default; /** * @brief Copy Constructor. @@ -127,12 +132,10 @@ class ArrayView * ChaiBuffer this can move the underlying buffer to a new memory space if the execution context is set. */ DISABLE_HD_WARNING - inline LVARRAY_HOST_DEVICE constexpr - ArrayView( ArrayView const & source ) noexcept: - m_dims{ source.m_dims }, - m_strides{ source.m_strides }, - m_dataBuffer{ source.m_dataBuffer, source.size() }, - m_singleParameterResizeIndex( source.m_singleParameterResizeIndex ) + LVARRAY_HOST_DEVICE constexpr + ArrayView2( ArrayView2 const & source ) noexcept: + m_layout( source.m_layout ), + m_dataBuffer{ source.m_dataBuffer, source.size() } {} /** @@ -150,24 +153,19 @@ class ArrayView * assert( y( 3, 4 )[ 0 ] == x( 3, 8 ) ); * @endcode */ - template< typename U, typename=std::enable_if_t< !std::is_same< T, U >::value > > - inline LVARRAY_HOST_DEVICE constexpr - explicit ArrayView( ArrayView< U, NDIM, USD, INDEX_TYPE, BUFFER_TYPE > const & source ): - m_dims{ source.dimsArray() }, - m_strides{ source.stridesArray() }, - m_dataBuffer{ source.dataBuffer() }, - m_singleParameterResizeIndex( source.getSingleParameterResizeIndex() ) - { - m_dims[ USD ] = typeManipulation::convertSize< T, U >( m_dims[ USD ] ); + template< typename U, typename=std::enable_if_t< !std::is_same< T, U >::value && ( sizeof( T ) % sizeof( U ) == 0 ) > > + LVARRAY_HOST_DEVICE constexpr + explicit ArrayView2( ArrayView2< U, decltype( LayoutType{}.template downcast< sizeof( T ) / ( sizeof( U ) ) >() ), BUFFER_TYPE > const & source ): + m_layout( source.layout().template upcast< sizeof( T ) / ( sizeof( U ) ) >() ), + m_dataBuffer{ source.dataBuffer() } + {} - for( int i = 0; i < NDIM; ++i ) - { - if( i != USD ) - { - m_strides[ i ] = typeManipulation::convertSize< T, U >( m_strides[ i ] ); - } - } - } + template< typename U, typename=std::enable_if_t< ( sizeof( U ) > sizeof( T ) ) && ( sizeof( U ) % sizeof( T ) == 0 ) > > + LVARRAY_HOST_DEVICE constexpr + explicit ArrayView2( ArrayView2< U, decltype( LayoutType{}.template upcast< sizeof( U ) / ( sizeof( T ) ) >() ), BUFFER_TYPE > const & source ): + m_layout( source.layout().template downcast< sizeof( U ) / ( sizeof( T ) ) >() ), + m_dataBuffer{ source.dataBuffer() } + {} /** * @brief Move constructor, creates a shallow copy and invalidates the source. @@ -185,28 +183,22 @@ class ArrayView * ArrayView< int, 1, 0, std::ptrdiff_t, MallocBuffer > anotherView = std::move( view ); * @endcode */ - ArrayView( ArrayView && source ) = default; + ArrayView2( ArrayView2 && source ) = default; /** * @brief Construct a new ArrayView from existing components. - * @param dims The array of dimensions. - * @param strides The array of strides. - * @param singleParameterResizeIndex The single parameter resize index. + * @param layout The array view layout. * @param buffer The buffer to copy construct. */ - inline LVARRAY_HOST_DEVICE constexpr explicit - ArrayView( typeManipulation::CArray< INDEX_TYPE, NDIM > const & dims, - typeManipulation::CArray< INDEX_TYPE, NDIM > const & strides, - int const singleParameterResizeIndex, - BUFFER_TYPE< T > const & buffer ): - m_dims( dims ), - m_strides( strides ), - m_dataBuffer( buffer ), - m_singleParameterResizeIndex( singleParameterResizeIndex ) + LVARRAY_HOST_DEVICE constexpr explicit + ArrayView2( LayoutType const & layout, + BUFFER_TYPE< T > const & buffer ): + m_layout( layout ), + m_dataBuffer( buffer ) {} /// The default destructor. - ~ArrayView() = default; + ~ArrayView2() = default; /** * @brief Move assignment operator, creates a shallow copy and invalidates the source. @@ -227,37 +219,20 @@ class ArrayView * anotherView = std::move( view ); * @endcode */ - inline LVARRAY_HOST_DEVICE LVARRAY_INTEL_CONSTEXPR - ArrayView & operator=( ArrayView && rhs ) - { - 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 ]; - } - - return *this; - } + LVARRAY_HOST_DEVICE LVARRAY_INTEL_CONSTEXPR + ArrayView2 & operator=( ArrayView2 && rhs ) noexcept = default; /** * @brief Copy assignment operator, creates a shallow copy. * @param rhs object to copy. * @return *this */ - inline LVARRAY_INTEL_CONSTEXPR - ArrayView & operator=( ArrayView const & rhs ) noexcept + LVARRAY_INTEL_CONSTEXPR + //ArrayView2 & operator=( ArrayView2 const & rhs ) noexcept = default; + ArrayView2 & operator=( ArrayView2 const & rhs ) noexcept { m_dataBuffer = 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 ]; - } - - return *this; + m_layout = rhs.m_layout; } ///@} @@ -270,43 +245,40 @@ class ArrayView /** * @return Return a new ArrayView. */ - inline LVARRAY_HOST_DEVICE constexpr - ArrayView toView() const & - { return ArrayView( m_dims, m_strides, m_singleParameterResizeIndex, m_dataBuffer ); } + LVARRAY_HOST_DEVICE constexpr + ArrayView2 toView() const & + { return ArrayView2( layout(), dataBuffer() ); } /** * @return Return a new ArrayView where @c T is @c const. */ - inline LVARRAY_HOST_DEVICE constexpr + LVARRAY_HOST_DEVICE constexpr ViewTypeConst toViewConst() const & { - return ViewTypeConst( m_dims, - m_strides, - m_singleParameterResizeIndex, - m_dataBuffer ); + return ViewTypeConst( layout(), dataBuffer() ); } /** * @brief @return Return *this after converting any nested arrays to const views. */ - inline LVARRAY_HOST_DEVICE constexpr + LVARRAY_HOST_DEVICE constexpr NestedViewType toNestedView() const & { return reinterpret_cast< NestedViewType const & >( *this ); } /** * @brief @return Return *this after converting any nested arrays to const views to const values. */ - inline LVARRAY_HOST_DEVICE constexpr + LVARRAY_HOST_DEVICE constexpr NestedViewTypeConst toNestedViewConst() const & { return reinterpret_cast< NestedViewTypeConst const & >( *this ); } /** * @return Return an ArraySlice representing this ArrayView. */ - inline LVARRAY_HOST_DEVICE constexpr - ArraySlice< T, NDIM, USD, INDEX_TYPE > + LVARRAY_HOST_DEVICE constexpr + ArraySlice2< T, LayoutType > toSlice() const & noexcept - { return ArraySlice< T, NDIM, USD, INDEX_TYPE >( data(), m_dims.data, m_strides.data ); } + { return ArraySlice2< T, LayoutType >( data(), layout() ); } /** * @brief Overload for rvalues that is deleted. @@ -315,17 +287,17 @@ class ArrayView * contain pointers to the dims and strides of the current @c ArrayView that is * about to be destroyed. This overload prevents that from happening. */ - inline LVARRAY_HOST_DEVICE constexpr - ArraySlice< T, NDIM, USD, INDEX_TYPE > + LVARRAY_HOST_DEVICE constexpr + ArraySlice2< T, LayoutType > toSlice() const && noexcept = delete; /** * @return Return an immutable ArraySlice representing this ArrayView. */ - inline LVARRAY_HOST_DEVICE constexpr - ArraySlice< T const, NDIM, USD, INDEX_TYPE > + LVARRAY_HOST_DEVICE constexpr + ArraySlice2< T const, LayoutType > toSliceConst() const & noexcept - { return ArraySlice< T const, NDIM, USD, INDEX_TYPE >( data(), m_dims.data, m_strides.data ); } + { return ArraySlice2< T const, LayoutType >( data(), layout() ); } /** * @brief Overload for rvalues that is deleted. @@ -334,8 +306,8 @@ class ArrayView * contain pointers to the dims and strides of the current @c ArrayView that is * about to be destroyed. This overload prevents that from happening. */ - inline LVARRAY_HOST_DEVICE constexpr - ArraySlice< T const, NDIM, USD, INDEX_TYPE > + LVARRAY_HOST_DEVICE constexpr + ArraySlice2< T const, LayoutType > toSliceConst() const && noexcept = delete; /** @@ -343,16 +315,16 @@ class ArrayView * @return A new ArrayView where @c T is @c const. */ template< typename _T=T > - inline LVARRAY_HOST_DEVICE constexpr + LVARRAY_HOST_DEVICE constexpr operator std::enable_if_t< !std::is_const< _T >::value, - ArrayView< T const, NDIM, USD, INDEX_TYPE, BUFFER_TYPE > >() const noexcept + ArrayView2< T const, LayoutType, BUFFER_TYPE > >() const noexcept { return toViewConst(); } /** * @return Return an ArraySlice representing this ArrayView. */ - inline LVARRAY_HOST_DEVICE constexpr - operator ArraySlice< T, NDIM, USD, INDEX_TYPE >() const & noexcept + LVARRAY_HOST_DEVICE constexpr + operator ArraySlice2< T, LayoutType >() const & noexcept { return toSlice(); } /** @@ -362,16 +334,16 @@ class ArrayView * contain pointers to the dims and strides of the current @c ArrayView that is * about to be destroyed. This overload prevents that from happening. */ - inline LVARRAY_HOST_DEVICE constexpr - operator ArraySlice< T, NDIM, USD, INDEX_TYPE >() const && noexcept = delete; + LVARRAY_HOST_DEVICE constexpr + operator ArraySlice2< T, LayoutType >() const && noexcept = delete; /** * @return Return an immutable ArraySlice representing this ArrayView. */ template< typename _T=T > - inline LVARRAY_HOST_DEVICE constexpr + LVARRAY_HOST_DEVICE constexpr operator std::enable_if_t< !std::is_const< _T >::value, - ArraySlice< T const, NDIM, USD, INDEX_TYPE > const >() const & noexcept + ArraySlice2< T const, LayoutType > const >() const & noexcept { return toSliceConst(); } /** @@ -382,9 +354,9 @@ class ArrayView * about to be destroyed. This overload prevents that from happening. */ template< typename _T=T > - inline LVARRAY_HOST_DEVICE constexpr + LVARRAY_HOST_DEVICE constexpr operator std::enable_if_t< !std::is_const< _T >::value, - ArraySlice< T const, NDIM, USD, INDEX_TYPE > const >() const && noexcept = delete; + ArraySlice2< T const, LayoutType > const >() const && noexcept = delete; ///@} @@ -393,109 +365,105 @@ class ArrayView */ ///@{ + /** + * @return A reference to the view's layout. + */ + LVARRAY_HOST_DEVICE constexpr + LayoutType const & layout() const noexcept + { return m_layout; } + /** * @return Return the allocated size. */ - LVARRAY_HOST_DEVICE inline constexpr - INDEX_TYPE size() const noexcept + LVARRAY_HOST_DEVICE constexpr + IndexType size() const noexcept { - #if defined( __ibmxl__ ) - // Note: This used to be done with a recursive template but XL-release would produce incorrect results. - // Specifically in exampleArray it would return an "old" size even after being updated, strange. - INDEX_TYPE val = m_dims[ 0 ]; - for( int i = 1; i < NDIM; ++i ) - { val *= m_dims[ i ]; } - - return val; - #else - return indexing::multiplyAll< NDIM >( m_dims.data ); - #endif + return layout().size(); } /** * @return Return the length of the given dimension. * @param dim The dimension to get the length of. */ - LVARRAY_HOST_DEVICE inline CONSTEXPR_WITHOUT_BOUNDS_CHECK - INDEX_TYPE size( int const dim ) const noexcept + LVARRAY_HOST_DEVICE CONSTEXPR_WITHOUT_BOUNDS_CHECK + IndexType size( int const dim ) const noexcept { #ifdef LVARRAY_BOUNDS_CHECK LVARRAY_ASSERT_GE( dim, 0 ); LVARRAY_ASSERT_GT( NDIM, dim ); #endif - return m_dims[ dim ]; + return tupleManipulation::getValue( layout().extent(), dim ); } /** - * @return Return true if the array is empty. - */ - LVARRAY_HOST_DEVICE inline constexpr - bool empty() const - { return size() == 0; } - - /** - * @return Return the maximum number of values the Array can hold without reallocation. + * @return Return the length of the given dimension. + * @param N the dimension to get the length of. */ + template< int N > LVARRAY_HOST_DEVICE constexpr - INDEX_TYPE capacity() const - { return LvArray::integerConversion< INDEX_TYPE >( m_dataBuffer.capacity() ); } - - /** - * @return Return the default resize dimension. - */ - LVARRAY_HOST_DEVICE inline constexpr - int getSingleParameterResizeIndex() const - { return m_singleParameterResizeIndex; } + auto size() const noexcept + { + static_assert( N < NDIM, "Dimension index must be less than number of dimensions." ); + return camp::get< N >( m_layout.extent() ); + } /** - * @tparam INDICES A variadic pack of integral types. - * @return Return the linear index from a multidimensional index. - * @param indices The indices of the value to get the linear index of. + * @return Return the stride of the given dimension. + * @param dim the dimension to get the stride of. */ - template< typename ... INDICES > - LVARRAY_HOST_DEVICE inline CONSTEXPR_WITHOUT_BOUNDS_CHECK - INDEX_TYPE linearIndex( INDICES const ... indices ) const + LVARRAY_HOST_DEVICE CONSTEXPR_WITHOUT_BOUNDS_CHECK + IndexType stride( int const dim ) const noexcept { - static_assert( sizeof ... (INDICES) == NDIM, "number of indices does not match NDIM" ); #ifdef LVARRAY_BOUNDS_CHECK - indexing::checkIndices( m_dims.data, indices ... ); + LVARRAY_ERROR_IF_GE( dim, NDIM ); #endif - return indexing::getLinearIndex< USD >( m_strides.data, indices ... ); + return tupleManipulation::getValue( m_layout.stride(), dim ); } /** - * @return A pointer to the array containing the size of each dimension. + * @return Return the stride of the given dimension. + * @param N the dimension to get the stride of. */ - LVARRAY_HOST_DEVICE inline constexpr - INDEX_TYPE const * dims() const noexcept - { return m_dims.data; } + template< int N > + LVARRAY_HOST_DEVICE constexpr + auto stride() const noexcept + { + static_assert( N < NDIM, "Dimension index must be less than number of dimensions." ); + return camp::get< N >( m_layout.stride() ); + } /** - * @return The CArray containing the size of each dimension. + * @return Return true if the array is empty. */ - LVARRAY_HOST_DEVICE inline constexpr - typeManipulation::CArray< INDEX_TYPE, NDIM > const & dimsArray() const - { return m_dims; } + LVARRAY_HOST_DEVICE constexpr + bool empty() const + { return size() == 0; } /** - * @return A pointer to the array containing the stride of each dimension. + * @return Return the maximum number of values the Array can hold without reallocation. */ - LVARRAY_HOST_DEVICE inline constexpr - INDEX_TYPE const * strides() const noexcept - { return m_strides.data; } + LVARRAY_HOST_DEVICE constexpr + IndexType capacity() const + { return LvArray::integerConversion< IndexType >( m_dataBuffer.capacity() ); } /** - * @return The CArray containing the stride of each dimension. + * @tparam INDICES A variadic pack of integral types. + * @return Return the linear index from a multidimensional index. + * @param indices The indices of the value to get the linear index of. */ - LVARRAY_HOST_DEVICE inline constexpr - typeManipulation::CArray< INDEX_TYPE, NDIM > const & stridesArray() const - { return m_strides; } + template< typename ... INDICES > + LVARRAY_HOST_DEVICE CONSTEXPR_WITHOUT_BOUNDS_CHECK + IndexType linearIndex( INDICES const ... indices ) const + { + static_assert( sizeof ... (INDICES) == NDIM, "number of indices does not match NDIM" ); + return layout()( indices... ); + } /** * @return A reference to the underlying buffer. * @note Use with caution. */ - LVARRAY_HOST_DEVICE inline constexpr + LVARRAY_HOST_DEVICE constexpr BUFFER_TYPE< T > const & dataBuffer() const { return m_dataBuffer; } @@ -507,47 +475,24 @@ class ArrayView ///@{ /** - * @return Return a lower dimensional slice of this ArrayView. - * @param index The index of the slice to create. - * @note This method is only active when NDIM > 1. + * @return Return a value reference or a lower dimensional slice of this ArrayView. + * @param index The index along the left-most dimension */ - template< int _NDIM=NDIM > - LVARRAY_HOST_DEVICE inline CONSTEXPR_WITHOUT_BOUNDS_CHECK - std::enable_if_t< (_NDIM > 1), ArraySlice< T, NDIM - 1, USD - 1, INDEX_TYPE > > - operator[]( INDEX_TYPE const index ) const & noexcept + LVARRAY_HOST_DEVICE CONSTEXPR_WITHOUT_BOUNDS_CHECK + decltype(auto) + operator[]( IndexType const index ) const & noexcept { - ARRAY_SLICE_CHECK_BOUNDS( index ); - return ArraySlice< T, NDIM-1, USD-1, INDEX_TYPE >( data() + indexing::ConditionalMultiply< USD == 0 >::multiply( index, m_strides[ 0 ] ), - m_dims.data + 1, - m_strides.data + 1 ); + return operator()( index ); } /** - * @brief Overload for rvalues that is deleted. - * @param index Not used. - * @return A null ArraySlice. - * @brief The multidimensional operator[] cannot be called on a rvalue since the @c ArraySlice - * would contain pointers to the object that is about to be destroyed. This overload - * prevents that from happening. - */ - template< int _NDIM=NDIM > - LVARRAY_HOST_DEVICE inline CONSTEXPR_WITHOUT_BOUNDS_CHECK - std::enable_if_t< (_NDIM > 1), ArraySlice< T, NDIM - 1, USD - 1, INDEX_TYPE > > - operator[]( INDEX_TYPE const index ) const && noexcept = delete; - - /** - * @return Return a reference to the value at the given index. - * @param index The index of the value to access. - * @note This method is only active when NDIM == 1. + * @return Return a value reference or a lower dimensional slice of this ArrayView. + * @param index The index along the left-most dimension + * @note Deleted rvalue overload */ - template< int _NDIM=NDIM > - LVARRAY_HOST_DEVICE inline CONSTEXPR_WITHOUT_BOUNDS_CHECK - std::enable_if_t< _NDIM == 1, T & > - operator[]( INDEX_TYPE const index ) const & noexcept - { - ARRAY_SLICE_CHECK_BOUNDS( index ); - return data()[ indexing::ConditionalMultiply< USD == 0 >::multiply( index, m_strides[ 0 ] ) ]; - } + LVARRAY_HOST_DEVICE CONSTEXPR_WITHOUT_BOUNDS_CHECK + decltype(auto) + operator[]( IndexType const index ) && = delete; /** * @tparam INDICES A variadic pack of integral types. @@ -555,31 +500,40 @@ class ArrayView * @param indices The indices of the value to access. */ template< typename ... INDICES > - LVARRAY_HOST_DEVICE inline constexpr - T & operator()( INDICES... indices ) const + LVARRAY_HOST_DEVICE constexpr + decltype(auto) + operator()( INDICES... indices ) const { - static_assert( sizeof ... (INDICES) == NDIM, "number of indices does not match NDIM" ); - return data()[ linearIndex( indices ... ) ]; + auto const sliceLayout = layout().slice( indices... ); + auto const sliceOffset = layout()( indices... ); + if constexpr ( decltype( sliceLayout )::NDIM == 0 ) + { + return data()[ sliceOffset ]; + } + else + { + return ArraySlice2< T, std::remove_cv_t< decltype( sliceLayout ) > >( data() + sliceOffset, sliceLayout ); + } } /** * @return Return a pointer to the values. */ - LVARRAY_HOST_DEVICE inline constexpr + LVARRAY_HOST_DEVICE constexpr T * data() const { return m_dataBuffer.data(); } /** * @return Return an iterator to the begining of the data. */ - LVARRAY_HOST_DEVICE inline constexpr + LVARRAY_HOST_DEVICE constexpr T * begin() const { return data(); } /** * @return Return an iterator to the end of the data. */ - LVARRAY_HOST_DEVICE inline constexpr + LVARRAY_HOST_DEVICE constexpr T * end() const { return data() + size(); } @@ -613,8 +567,8 @@ class ArrayView void setValues( T const & value ) const { auto const view = toView(); - RAJA::forall< POLICY >( RAJA::TypedRangeSegment< INDEX_TYPE >( 0, size() ), - [value, view] LVARRAY_HOST_DEVICE ( INDEX_TYPE const i ) + RAJA::forall< POLICY >( RAJA::TypedRangeSegment< IndexType >( 0, size() ), + [value, view] LVARRAY_HOST_DEVICE ( IndexType const i ) { view.data()[ i ] = value; } ); @@ -626,7 +580,7 @@ class ArrayView * If the buffer is allocated using Umpire then the Umpire ResouceManager is used, otherwise std::memset is used. * @note The memset occurs in the last space the array was used in and the view is moved and touched in that space. */ - inline void zero() const + void zero() const { #if !defined( LVARRAY_USE_UMPIRE ) LVARRAY_ERROR_IF_NE_MSG( getPreviousSpace(), MemorySpace::host, "Without Umpire only host memory is supported." ); @@ -645,17 +599,11 @@ class ArrayView * @param rhs The source array view, must have the same dimensions and strides as *this. */ template< typename POLICY > - void setValues( ArrayView< T const, NDIM, USD, INDEX_TYPE, BUFFER_TYPE > const & rhs ) const + void setValues( ArrayView2< T const, LayoutType, BUFFER_TYPE > const & rhs ) const { - for( int dim = 0; dim < NDIM; ++dim ) - { - LVARRAY_ERROR_IF_NE( size( dim ), rhs.size( dim ) ); - LVARRAY_ERROR_IF_NE_MSG( strides()[ dim ], rhs.strides()[ dim ], - "This method only works with Arrays with the same data layout." ); - } - + LVARRAY_ERROR_IF_NE_MSG( layout(), rhs.layout(), "This method only works with Arrays with the same data layout." ); auto const view = toView(); - RAJA::forall< POLICY >( RAJA::TypedRangeSegment< INDEX_TYPE >( 0, size() ), [view, rhs] LVARRAY_HOST_DEVICE ( INDEX_TYPE const i ) + RAJA::forall< POLICY >( RAJA::TypedRangeSegment< IndexType >( 0, size() ), [view, rhs] LVARRAY_HOST_DEVICE ( IndexType const i ) { view.data()[ i ] = rhs.data()[ i ]; } ); @@ -710,7 +658,6 @@ class ArrayView TV_ttf_add_row( "m_dims", totalview::format< INDEX_TYPE, int >( 1, &ndim ).c_str(), (av->m_dims) ); TV_ttf_add_row( "m_strides", totalview::format< INDEX_TYPE, int >( 1, &ndim ).c_str(), (av->m_strides) ); TV_ttf_add_row( "m_dataBuffer", LvArray::system::demangle< BUFFER_TYPE< T > >().c_str(), &(av->m_dataBuffer) ); - TV_ttf_add_row( "m_singleParameterResizeIndex", "int", &(av->m_singleParameterResizeIndex) ); } return 0; } @@ -723,10 +670,8 @@ class ArrayView * @note The unused boolean parameter is to distinguish this from the default constructor. */ DISABLE_HD_WARNING - LVARRAY_HOST_DEVICE inline explicit CONSTEXPR_WITHOUT_BOUNDS_CHECK - ArrayView( bool ) noexcept: - m_dims{ 0 }, - m_strides{ 0 }, + LVARRAY_HOST_DEVICE explicit CONSTEXPR_WITHOUT_BOUNDS_CHECK + ArrayView2( bool ) noexcept: m_dataBuffer( true ) { #if defined(LVARRAY_USE_TOTALVIEW_OUTPUT) && !defined(__CUDA_ARCH__) && defined(LVARRAY_BOUNDS_CHECK) @@ -740,28 +685,25 @@ class ArrayView * @param buffer The buffer use. */ DISABLE_HD_WARNING - inline LVARRAY_HOST_DEVICE constexpr - ArrayView( BUFFER_TYPE< T > && buffer ) noexcept: - m_dims{ 0 }, - m_strides{ 0 }, - m_dataBuffer{ std::move( buffer ) }, - m_singleParameterResizeIndex{ 0 } + LVARRAY_HOST_DEVICE constexpr + ArrayView2( BUFFER_TYPE< T > && buffer ) noexcept: + m_dataBuffer{ std::move( buffer ) } {} - /// the dimensions of the array. - typeManipulation::CArray< INDEX_TYPE, NDIM > m_dims = { 0 }; - - /// the strides of the array. - typeManipulation::CArray< INDEX_TYPE, NDIM > m_strides = { 0 }; + /// layout describing the mapping from coordinates to memory offsets + LayoutType m_layout; /// this data member contains the actual data for the array. BUFFER_TYPE< T > m_dataBuffer; - - /// this data member specifies the dimension that will be resized as a result of a call to the - /// single dimension resize method. - int m_singleParameterResizeIndex = 0; }; +template< typename T, + int NDIM, + typename PERMUTATION, + typename INDEX_TYPE, + template< typename > class BUFFER_TYPE > +using ArrayView = ArrayView2< T, Layout< DynamicExtent< NDIM, INDEX_TYPE >, CompactStride< LayoutRight, DynamicExtent< NDIM, INDEX_TYPE >, PERMUTATION > >, BUFFER_TYPE >; + /** * @brief True if the template type is a ArrayView. */ @@ -777,10 +719,8 @@ constexpr bool isArrayView = false; * @brief Specialization of isArrayView for the ArrayView class. */ template< typename T, - int NDIM, - int USD, - typename INDEX_TYPE, + typename LAYOUT, template< typename > class BUFFER_TYPE > -constexpr bool isArrayView< ArrayView< T, NDIM, USD, INDEX_TYPE, BUFFER_TYPE > > = true; +constexpr bool isArrayView< ArrayView2< T, LAYOUT, BUFFER_TYPE > > = true; } // namespace LvArray diff --git a/src/CRSMatrixView.hpp b/src/CRSMatrixView.hpp index 2a240103..e08993e2 100644 --- a/src/CRSMatrixView.hpp +++ b/src/CRSMatrixView.hpp @@ -241,12 +241,11 @@ class CRSMatrixView : protected SparsityPatternView< COL_TYPE, INDEX_TYPE, BUFFE * @param row The row to access. */ LVARRAY_HOST_DEVICE inline - ArraySlice< T, 1, 0, INDEX_TYPE_NC > getEntries( INDEX_TYPE const row ) const + ArraySlice2< T, DynamicLayout1D< INDEX_TYPE > > getEntries( INDEX_TYPE const row ) const { ARRAYOFARRAYS_CHECK_BOUNDS( row ); - return ArraySlice< T, 1, 0, INDEX_TYPE_NC >( m_entries.data() + this->m_offsets[ row ], - &this->m_sizes[ row ], - nullptr ); + return ArraySlice2< T, DynamicLayout1D< INDEX_TYPE > >( m_entries.data() + this->m_offsets[ row ], + makeLayout( makeExtent( this->m_sizes[ row ] ) ) ); } /** diff --git a/src/Constant.hpp b/src/Constant.hpp new file mode 100644 index 00000000..ac3bc8f7 --- /dev/null +++ b/src/Constant.hpp @@ -0,0 +1,285 @@ +/* + * Copyright (c) 2021, Lawrence Livermore National Security, LLC and LvArray contributors. + * All rights reserved. + * See the LICENSE file for details. + * SPDX-License-Identifier: (BSD-3-Clause) + */ + +/** + * @file Constant.hpp + * @brief Contains the implementation of Constant. + */ + +#pragma once + +#include "Macros.hpp" + +#include + +namespace LvArray +{ + +/** + * @brief A simple compile-time number with arithmetic operations that preserve compile-timeness when possible. + * @tparam T type of value + * @tparam v the value + * @note this cannot be declared as an alias, as we don't want to define arithmetic operations for all integral constants + */ +template< typename T, T v = T{} > +struct Constant +{ + static constexpr T value = v; + using value_type = T; + using type = Constant< T, v >; + LVARRAY_HOST_DEVICE constexpr operator value_type() const noexcept { return value; } + LVARRAY_HOST_DEVICE constexpr value_type operator()() const noexcept { return value; } + + template< typename U, U u > + Constant & operator=( Constant< U, u > const & ) + { + static_assert( u == v, "Unable to change a compile-time constant value" ); + } +}; + +/** + * @brief Detection trait for Constant. + * @tparam T the type to test + */ +template< typename T > +struct is_constant : Constant< bool, false > {}; + +/** + * @brief Detection trait specialization for Constant. + * @tparam T type of value + * @tparam v the value in constant + */ +template< typename T, T v > +struct is_constant< Constant< T, v > > : Constant< bool, true > {}; + +/** + * @brief Variable version of the detection trait for Constant. + * @tparam T the type to test + */ +template< typename T > +inline constexpr bool is_constant_v = is_constant< T >::value; + +/** + * @brief Trait for detecting integral types, which considers all Constant specializations to be integral. + * @tparam T type to test + */ +template< typename T > +inline constexpr bool is_integral_v = std::is_integral_v< T > || is_constant_v< T >; + +/** + * @brief Detection trait for Constant holding a particular value. + * @tparam val the value to test against + * @tparam T the type to test + */ +template< auto val, typename T > +struct is_constant_value : Constant< bool, false > {}; + +/** + * @brief Detection trait specialization for Constant holding a particular value. + * @tparam val the value to test against + * @tparam T type of value + * @tparam v the value in constant + */ +template< auto val, typename T, T v > +struct is_constant_value< val, Constant< T, v > > : Constant< bool, ( v == val ) ? true : false > {}; + +/** + * @brief Variable version of the detection trait for Constant holding a particular value. + * @tparam val the value to test against + * @tparam T the type to test + */ +template< auto val, typename T > +inline constexpr bool is_constant_value_v = is_constant_value< val, std::decay_t< T > >::value; + +template< typename T > +struct value_type +{ + using type = T; +}; + +template< typename T, T v > +struct value_type< Constant< T, v > > +{ + using type = T; +}; + +template< typename T > +using value_type_t = typename value_type< T >::type; + +// Useful special compile-time constants +using _0 = Constant< int, 0 >; ///< Alias for compile-time 0 type +using _1 = Constant< int, 1 >; ///< Alias for compile-time 1 type +using _2 = Constant< int, 2 >; ///< Alias for compile-time 2 type +using _3 = Constant< int, 3 >; ///< Alias for compile-time 3 type +using _4 = Constant< int, 4 >; ///< Alias for compile-time 4 type +using _5 = Constant< int, 5 >; ///< Alias for compile-time 5 type +using _6 = Constant< int, 6 >; ///< Alias for compile-time 6 type +using _7 = Constant< int, 7 >; ///< Alias for compile-time 7 type +using _8 = Constant< int, 8 >; ///< Alias for compile-time 8 type +using _9 = Constant< int, 9 >; ///< Alias for compile-time 9 type +using _10 = Constant< int, 10 >; ///< Alias for compile-time 10 type +using _11 = Constant< int, 11 >; ///< Alias for compile-time 11 type +using _12 = Constant< int, 12 >; ///< Alias for compile-time 12 type +using _t = Constant< bool, true >; ///< Alias for compile-time true +using _f = Constant< bool, false >; ///< Alias for compile-time false + +template< typename T, T v > +std::ostream & operator<<( std::ostream & os, Constant< T, v > ) +{ + os << '_' << v; + return os; +} + +namespace literals +{ + +namespace internal +{ + +// Parser adapted from: +// https://stackoverflow.com/questions/13869193/compile-time-type-conversion-check-constexpr-and-user-defined-literals/13869688#13869688 +template< typename T, T S, char ... Chars > +struct IntegralLiteralParser; + +template< typename T, T S, char C, char... Cs > +struct IntegralLiteralParser< T, S, C, Cs... > +{ + static_assert( '0' <= C && C <= '9', "Invalid constant literal" ); + static constexpr T value = IntegralLiteralParser< T, S * 10 + ( C - '0' ), Cs... >::value; +}; + +template< typename T, T S > +struct IntegralLiteralParser< T, S > +{ + static constexpr int value = S; +}; + +} // namespace internal + +template< char... Chars > +auto +operator""_Ci() +{ + return Constant< int, internal::IntegralLiteralParser< int, 0, Chars... >::value >{}; +} + +template< char... Chars > +auto +operator""_Cl() +{ + return Constant< long, internal::IntegralLiteralParser< long, 0l, Chars... >::value >{}; +} + +template< char... Chars > +auto +operator""_Cll() +{ + return Constant< long long, internal::IntegralLiteralParser< long long, 0ll, Chars... >::value >{}; +} + +template< char... Chars > +auto +operator""_Cui() +{ + return Constant< unsigned int, internal::IntegralLiteralParser< unsigned int, 0u, Chars... >::value >{}; +} + +template< char... Chars > +auto +operator""_Cul() +{ + return Constant< unsigned long, internal::IntegralLiteralParser< unsigned long, 0ul, Chars... >::value >{}; +} + +template< char... Chars > +auto +operator""_Cull() +{ + return Constant< unsigned long long, internal::IntegralLiteralParser< unsigned long long, 0ull, Chars... >::value >{}; +} + +} // namespace literals + +#define LVARRAY_CONSTANT_BINARY_OP( OP ) \ +template< typename T, T v, typename U, U s > \ +LVARRAY_HOST_DEVICE constexpr \ +Constant< decltype( v OP s ), ( v OP s ) > \ +operator OP( Constant< T, v > const &, \ + Constant< U, s > const & ) \ +{ \ + return {}; \ +} \ + +LVARRAY_CONSTANT_BINARY_OP( + ) +LVARRAY_CONSTANT_BINARY_OP( - ) +LVARRAY_CONSTANT_BINARY_OP( * ) +LVARRAY_CONSTANT_BINARY_OP( / ) +LVARRAY_CONSTANT_BINARY_OP( % ) +LVARRAY_CONSTANT_BINARY_OP( == ) +LVARRAY_CONSTANT_BINARY_OP( != ) +LVARRAY_CONSTANT_BINARY_OP( > ) +LVARRAY_CONSTANT_BINARY_OP( >= ) +LVARRAY_CONSTANT_BINARY_OP( < ) +LVARRAY_CONSTANT_BINARY_OP( <= ) +LVARRAY_CONSTANT_BINARY_OP( && ) +LVARRAY_CONSTANT_BINARY_OP( || ) + +#undef LVARRAY_CONSTANT_BINARY_OP + +// Shortcuts to preserve static type where we can + +template< typename T, typename U > +LVARRAY_HOST_DEVICE constexpr +Constant< decltype( T{} * U{} ) > +operator*( Constant< T, T{} > const &, U const & ) +{ + return {}; +} + +template< typename T, typename U > +LVARRAY_HOST_DEVICE constexpr +Constant< decltype( U{} * T{} ) > +operator*( U const &, Constant< T, T{} > const & ) +{ + return {}; +} + +template< typename T, typename U > +LVARRAY_HOST_DEVICE constexpr +Constant< decltype( T{} / U{} ) > +operator/( Constant< T, T{} > const &, U const & ) +{ + return {}; +} + +template< typename T, typename U > +LVARRAY_HOST_DEVICE constexpr +Constant< decltype( U{} / T{} ) > +operator/( U const &, Constant< T, T{} > const & ) +{ + static_assert( sizeof( U ) == 0, "Division by zero!"); + return {}; +} + +template< typename T, typename U > +LVARRAY_HOST_DEVICE constexpr +Constant< decltype( T{} % U{} ) > +operator%( Constant< T, T{} > const &, U const & ) +{ + return {}; +} + +template< typename T, typename U > +LVARRAY_HOST_DEVICE constexpr +Constant< decltype( U{} % T{} ) > +operator%( U const &, Constant< T, T{} > const & ) +{ + static_assert( sizeof( U ) == 0, "Division by zero!"); + return {}; +} + +} // namespace LvArray diff --git a/src/Layout.hpp b/src/Layout.hpp new file mode 100644 index 00000000..412129da --- /dev/null +++ b/src/Layout.hpp @@ -0,0 +1,493 @@ +/* + * Copyright (c) 2021, Lawrence Livermore National Security, LLC and LvArray contributors. + * All rights reserved. + * See the LICENSE file for details. + * SPDX-License-Identifier: (BSD-3-Clause) + */ + +/** + * @file Layout.hpp + * @brief Contains the implementation of Layout. + */ + +#pragma once + +#include "Macros.hpp" +#include "Constant.hpp" +#include "tupleManipulation.hpp" +#include "typeManipulation.hpp" + +#include "RAJA/util/types.hpp" +#include "RAJA/util/Permutations.hpp" + +#include + +namespace LvArray +{ + +/** + * @brief Type used to represent multidimensional array extents + */ +template< typename ... Ts > +using Extent = camp::tuple< Ts... >; + +/** + * @brief Make function for extent + * @tparam Ts argument type list + * @param args variadic arguments + * @return the constructed extent object + */ +template< typename ... Ts > +LVARRAY_HOST_DEVICE +constexpr auto makeExtent( Ts && ... args ) +{ + return makeTuple( static_cast( args )... ); +} + +/** + * @brief Type used to represent multidimensional array strides + */ +template< typename ... Ts > +using Stride = camp::tuple< Ts... >; + +/** + * @brief Make function for stride + * @tparam Ts argument type list + * @param args variadic arguments + * @return the constructed stride object + */ +template< typename ... Ts > +LVARRAY_HOST_DEVICE +constexpr auto makeStride( Ts && ... args ) +{ + return makeTuple( static_cast( args )... ); +} + +/** + * @brief Type used to represent multidimensional array coordinate + */ +template< typename ... Ts > +using Coord = camp::tuple< Ts... >; + +/** + * @brief Make function for coordinate + * @tparam Ts argument type list + * @param args variadic arguments + * @return the constructed coordinate object + */ +template< typename ... Ts > +LVARRAY_HOST_DEVICE +constexpr auto makeCoord( Ts && ... args ) +{ + return makeTuple( static_cast( args )... ); +} + +/** + * @brief Compute the product of all tuple elements. + * @tparam T type of tuple + * @param t the tuple + * @return the product + */ +template< typename T > +LVARRAY_HOST_DEVICE constexpr +auto +product( T && t ) +{ + return tupleManipulation::apply( LVARRAY_FWD( t ), []( auto && ... vs ){ return ( _1{} * ... * vs ); } ); +} + +/** + * @brief Compute the inner product of two tuples + * @tparam T1 type of first tuple + * @tparam T2 type of second tuple + * @param t1 the first tuple + * @param t2 the second tuple + * @return the inner product + */ +template< typename T1, typename T2 > +LVARRAY_HOST_DEVICE constexpr +auto +innerProduct( T1 && t1, T2 && t2 ) +{ + return tupleManipulation::transformApply2( LVARRAY_FWD( t1 ), LVARRAY_FWD( t2 ), + []( auto && v1, auto && v2 ){ return v1 * v2; }, + []( auto && ... vs ){ return ( _0{} + ... + vs ); } ); +} + +/// Special type to indicate slicing a layout dimension. +struct Slicer : _0 {}; + +/// Convenience alias +using _ = Slicer; + +template< typename T > +struct is_slicer : Constant< bool, false > {}; + +template<> +struct is_slicer< Slicer > : Constant< bool, true > {}; + +template< typename T > +inline constexpr bool is_slicer_v = is_slicer< camp::decay< T > >::value; + +template< typename T > +struct has_slicer : Constant< bool, false > {}; + +template< template< typename... > class T, typename ... Ts > +struct has_slicer< T< Ts... > > : Constant< bool, typeManipulation::any_of_t< is_slicer< Ts >... >::value > {}; + +template< typename T > +inline constexpr bool has_slicer_v = has_slicer< camp::decay< T > >::value; + +template< typename T, typename U > +LVARRAY_HOST_DEVICE constexpr +auto +sliceTuple( T && t, U && mask ) +{ + return tupleManipulation::filter( LVARRAY_FWD( t ), LVARRAY_FWD( mask ), []( auto && e, auto && m ) + { + if constexpr( is_slicer_v< decltype( m ) > ) return makeTuple( LVARRAY_FWD( e ) ); + else return makeTuple(); + } ); +} + +/** + * @brief Shortcut to define an all-dynamic extent type (default for arrays) + */ +template< int NDIM, typename INDEX > +using DynamicExtent = decltype( tupleManipulation::repeat< NDIM >( INDEX{} ) ); + +struct LayoutLeft{}; +struct LayoutRight{}; + +namespace internal +{ + +template< typename EXTENT > +LVARRAY_HOST_DEVICE constexpr +auto +foldExtent( LayoutLeft, EXTENT const & extent ) +{ + auto scanner = []( auto curr, auto e ) + { + return makeTuple( tupleManipulation::append( camp::get< 0 >( curr ), camp::get< 1 >( curr ) ), camp::get< 1 >( curr ) * e ); + }; + auto init = Constant< value_type_t< camp::tuple_element_t< 0, EXTENT > >, 1 >{}; + return tupleManipulation::foldLeft( extent, makeTuple( makeStride(), init ), scanner ); +} + +template< typename EXTENT > +LVARRAY_HOST_DEVICE constexpr +auto +foldExtent( LayoutRight, EXTENT const & extent ) +{ + auto scanner = []( auto e, auto curr ) + { + return makeTuple( tupleManipulation::prepend( camp::get< 0 >( curr ), camp::get< 1 >( curr ) ), camp::get< 1 >( curr ) * e ); + }; + auto init = Constant< value_type_t< camp::tuple_element_t< camp::tsize_v< EXTENT > - 1, EXTENT > >, 1 >{}; + return tupleManipulation::foldRight( extent, makeTuple( makeStride(), init ), scanner ); +} + +} + +/** + * @brief Computes a compact stride given an extent and permutation + * @tparam EXTENT type of extent + * @tparam PERM type of permutation sequence + * @param extent the extent + * @param perm the permutation + * @return the computed stride object + * + * Packed stride is defined assuming a compact right layout: + * rightmost dimension is assigned stride _1, each next stride in + * right-to-left order is a product of previous stride and extent. + */ +template< typename LAYOUT_TAG, typename EXTENT, typename PERMUTATION > +LVARRAY_HOST_DEVICE +auto +makeCompactStride( LAYOUT_TAG tag, EXTENT const & extent, PERMUTATION perm = camp::idx_seq_from_t< EXTENT >{} ) +{ + static_assert( typeManipulation::getDimension< PERMUTATION > == camp::tsize_v< EXTENT >, "Permutation size must match the extent." ); + static_assert( typeManipulation::isValidPermutation( PERMUTATION{} ), "The permutation must be valid." ); + auto folded = internal::foldExtent( tag, tupleManipulation::select( extent, perm ) ); + return tupleManipulation::select( camp::get< 0 >( folded ), RAJA::invert_permutation< PERMUTATION >{} ); +} + +template< typename LAYOUT_TAG, typename EXTENT, typename PERM = camp::idx_seq_from_t< EXTENT > > +using CompactStride = decltype( makeCompactStride( LAYOUT_TAG{}, EXTENT{}, PERM{} ) ); + +template< typename EXTENT, typename STRIDE > +struct Layout; + +template< typename EXTENT, typename STRIDE > +LVARRAY_HOST_DEVICE +auto +makeLayout( EXTENT && extent, STRIDE && stride ) +{ + return Layout< camp::decay< EXTENT >, camp::decay< STRIDE > >( LVARRAY_FWD( extent ), LVARRAY_FWD( stride ) ); +} + +/** + * @brief Layout defines a mapping from a multidimensional coordinate to an offset in memory + * @tparam EXTENT type of extent + * @tparam STRIDE type of stride + */ +template< typename EXTENT, typename STRIDE = CompactStride< LayoutRight, EXTENT > > +struct Layout : private camp::tuple< EXTENT, STRIDE > // EBO for static layouts +{ +public: + + using ExtentType = EXTENT; + using StrideType = STRIDE; + using Base = camp::tuple< ExtentType, StrideType >; + + // Convenience type to denote indices + using IndexType = tupleManipulation::common_type_t< ExtentType >; + + static_assert( camp::tsize_v< ExtentType > == camp::tsize_v< StrideType >, "Extent and Stride must have matching number of dims" ); + + /// Number of dimensons (rank) of the layout + static constexpr int NDIM = camp::tsize_v< ExtentType >; + + struct USDHelper + { + static constexpr int value = tupleManipulation::find( StrideType{}, []( auto s ){ return is_constant_value< 1, decltype( s ) >{}; } ); + }; + + /// Unit-stride dimension index. + static constexpr int USD = ( USDHelper::value < NDIM ) ? USDHelper::value : -1; + + LVARRAY_HOST_DEVICE constexpr + explicit Layout( ExtentType const & extent = ExtentType{}, StrideType const & stride = StrideType{} ) noexcept : Base( extent, stride ) {} + + LVARRAY_HOST_DEVICE constexpr + ExtentType const & + extent() const { return camp::get< 0 >( static_cast< Base const & >( *this ) ); } + + LVARRAY_HOST_DEVICE constexpr + ExtentType & + extent() { return camp::get< 0 >( static_cast< Base & >( *this ) ); } + + LVARRAY_HOST_DEVICE constexpr + StrideType const & + stride() const { return camp::get< 1 >( static_cast< Base const & >( *this ) ); } + + LVARRAY_HOST_DEVICE constexpr + StrideType & + stride() { return camp::get< 1 >( static_cast< Base & >( *this ) ); } + + struct CoordCheck + { + template< typename C, typename E > + auto operator()( C const & c, E const & e ) + { + if constexpr( is_slicer_v< C > ) return true; + else return c < e; + } + }; + + /** + * @brief Compute an offset at given coordinates. + * @tparam Ts types of coordinates + * @param coord the coordinates as a tuple + * @return the offset that can be added to a base array pointer + * @note The caller is responsible for determining whether the resulting object should be + * an array slice or a specific value reference, which can also be considered to be + * a rank-0 slice. To obtain a layout for the slice, one may call slice() method. + */ + template< typename ... Ts > + LVARRAY_HOST_DEVICE CONSTEXPR_WITHOUT_BOUNDS_CHECK + auto + operator()( Coord< Ts... > const & coord ) const noexcept + { + // We allow specifying only leading coordinates and right-pad to NDIM with _{} + static_assert( sizeof...( Ts ) <= NDIM, "The number of coordinates must not exceed the number of dimensions." ); + auto coordFull = tupleManipulation::append< NDIM - sizeof...( Ts ) >( coord, _{} ); +#ifdef LVARRAY_BOUNDS_CHECK + LVARRAY_ERROR_IF( !tupleManipulation::allOf2( coordFull, extent(), CoordCheck{} ), "Invalid coordinates." ); +#endif + return innerProduct( stride(), coordFull ); + } + + template< typename ... Ts, std::enable_if_t< typeManipulation::all_of< ( is_integral_v< Ts > || is_slicer_v< Ts > )... >::value > * = nullptr > + LVARRAY_HOST_DEVICE CONSTEXPR_WITHOUT_BOUNDS_CHECK + auto + operator()( Ts ... coords ) const noexcept + { + return operator()( makeCoord( coords... ) ); + } + + template< typename ... Ts > + LVARRAY_HOST_DEVICE CONSTEXPR_WITHOUT_BOUNDS_CHECK + auto + slice( Coord< Ts... > const & coord ) const noexcept + { + static_assert( sizeof...( Ts ) <= NDIM, "The number of coordinates must not exceed the number of dimensions." ); + auto coordFull = tupleManipulation::append< NDIM - sizeof...( Ts ) >( coord, _{} ); +#ifdef LVARRAY_BOUNDS_CHECK + LVARRAY_ERROR_IF( !tupleManipulation::allOf2( coordFull, extent(), CoordCheck{} ), "Invalid coordinates." ); +#endif + return makeLayout( sliceTuple( extent(), coordFull ), sliceTuple( stride(), coordFull ) ); + } + + template< typename ... Ts, std::enable_if_t< typeManipulation::all_of< ( is_integral_v< Ts > || is_slicer_v< Ts > )... >::value > * = nullptr > + LVARRAY_HOST_DEVICE CONSTEXPR_WITHOUT_BOUNDS_CHECK + auto + slice( Ts ... coords ) const noexcept + { + return slice( makeCoord( coords... ) ); + } + + LVARRAY_HOST_DEVICE constexpr + auto + size() const noexcept + { + return product( extent() ); + } + + template< int N, typename E = EXTENT, std::enable_if_t< camp::tsize_v< E > != 1 > * = nullptr > + LVARRAY_HOST_DEVICE constexpr + auto + downcast() const noexcept + { + auto [newExtent, newStride ] = tupleManipulation::unzip2( tupleManipulation::transform2( extent(), stride(), []( auto e, auto s ) + { + if constexpr( is_constant_value_v< 1, decltype( s ) > ) + { + return makeTuple( e * Constant< int, N >{}, s ); + } + else + { + return makeTuple( e, s * Constant< int, N >{} ); + } + } ) ); + return makeLayout( newExtent, newStride ); + } + + // specialize for 1D layouts to work around a camp bug + template< int N, typename E = EXTENT, std::enable_if_t< camp::tsize_v< E > == 1 > * = nullptr > + LVARRAY_HOST_DEVICE constexpr + auto + downcast() const noexcept + { + if constexpr( is_constant_value_v< 1, decltype( camp::get< 0 >( stride() ) ) > ) + { + return makeLayout( makeExtent( camp::get< 0 >( extent() ) * Constant< int, N >{} ), stride() ); + } + else + { + return makeLayout( extent(), makeStride( camp::get< 0 >( stride() ) * Constant< int, N >{} ) ); + } + } + + template< int N, typename E = EXTENT, std::enable_if_t< camp::tsize_v< E > != 1 > * = nullptr > + LVARRAY_HOST_DEVICE constexpr + auto + upcast() const noexcept + { + auto [newExtent, newStride] = tupleManipulation::unzip2( tupleManipulation::transform2( extent(), stride(), []( auto e, auto s ) + { + if constexpr( is_constant_value_v< 1, decltype( s ) > ) + { + return makeTuple( e / Constant< int, N >{}, s ); + } + else + { + return makeTuple( e, s / Constant< int, N >{} ); + } + } ) ); + return makeLayout( newExtent, newStride ); + } + + // specialize for 1D layouts to work around a camp bug + template< int N, typename E = EXTENT, std::enable_if_t< camp::tsize_v< E > == 1 > * = nullptr > + LVARRAY_HOST_DEVICE constexpr + auto + upcast() const noexcept + { + if constexpr( is_constant_value_v< 1, decltype( camp::get< 0 >( stride() ) ) > ) + { + return makeLayout( makeExtent( camp::get< 0 >( extent() ) / Constant< int, N >{} ), stride() ); + } + else + { + return makeLayout( extent(), makeStride( camp::get< 0 >( stride() ) / Constant< int, N >{} ) ); + } + } + + template< typename RExtent, typename RStride > + LVARRAY_HOST_DEVICE constexpr + friend bool operator==( Layout const & lhs, Layout< RExtent, RStride > const & rhs ) + { + return tupleManipulation::allOf2( lhs.extent(), rhs.extent(), tupleManipulation::cmp_eq{} ) + && tupleManipulation::allOf2( lhs.stride(), rhs.stride(), tupleManipulation::cmp_eq{} ); + } + + template< typename RExtent, typename RStride > + LVARRAY_HOST_DEVICE constexpr + friend bool operator!=( Layout const & lhs, Layout< RExtent, RStride > const & rhs ) + { + return !( lhs == rhs ); + } + + friend std::ostream & operator<<( std::ostream & os, Layout const & layout ) + { + // Unqualified lookup via ADL does not work for camp::tuple because its + // operator<< is defined outside its namespace. This trips up compilers. + //return os << layout.extent() << ':' << layout.stride(); + ::operator<<(os, layout.extent()); + os << ':'; + ::operator<<(os, layout.stride()); + return os; + } +}; + +/** + * @brief Detection trait for Layout. + * @tparam T the type to test + */ +template< typename T > +struct is_layout : Constant< bool, false > {}; + +/** + * @brief Specialization of detection trait for Layout. + * @tparam EXTENT extent type + * @tparam STRIDE stride type + */ +template< typename EXTENT, typename STRIDE > +struct is_layout< Layout< EXTENT, STRIDE > > : Constant< bool, true > {}; + +/** + * @brief Variable version of detection trait for Layout. + * @tparam T the type to test + */ +template< typename T > +inline constexpr bool is_layout_v = is_layout< camp::decay< T > >::value; + +// Useful default types + +/// LvArray defaults to right layouts (last index is contiguous by default) +using LayoutDefault = LayoutRight; + +/// Default dynamic layout type +template< int NDIM, typename INDEX_TYPE > +using DynamicLayout = Layout< DynamicExtent< NDIM, INDEX_TYPE >, CompactStride< LayoutDefault, DynamicExtent< NDIM, INDEX_TYPE > > >; + +/// Default 1D dynamic layout type +template< typename INDEX_TYPE > +using DynamicLayout1D = DynamicLayout< 1, INDEX_TYPE >; + +/// Default static layout type +template< typename T, T ... DIMS > +using StaticLayout = Layout< Extent< Constant< T, DIMS >... >, CompactStride< LayoutDefault, Extent< Constant< T, DIMS >... > > >; + +template< typename EXTENT > +LVARRAY_HOST_DEVICE +auto +makeLayout( EXTENT && extent ) +{ + auto stride = makeCompactStride( LayoutDefault{}, extent, camp::idx_seq_from_t< EXTENT >{} ); + return makeLayout( LVARRAY_FWD( extent ), LVARRAY_FWD( stride ) ); +} + +} // namespace LvArray diff --git a/src/Macros.hpp b/src/Macros.hpp index 6e213e88..1fe5d484 100644 --- a/src/Macros.hpp +++ b/src/Macros.hpp @@ -68,6 +68,12 @@ //#pragma message "LVARRAY_DEVICE_COMPILE: " STRINGIZE(LVARRAY_DEVICE_COMPILE) +/** + * @brief Perfect forwarding macro. + * @param X the variable to forward + */ +#define LVARRAY_FWD( X ) static_cast< decltype( X ) && >( X ) + /** * @brief Mark @p X as an unused argument, used to silence compiler warnings. * @param X the unused argument. diff --git a/src/SortedArrayView.hpp b/src/SortedArrayView.hpp index 8559a3fc..5f1f6ae6 100644 --- a/src/SortedArrayView.hpp +++ b/src/SortedArrayView.hpp @@ -154,8 +154,8 @@ class SortedArrayView * @return Return an ArraySlice representing this SortedArrayView. */ LVARRAY_HOST_DEVICE constexpr inline - ArraySlice< T const, 1, 0, INDEX_TYPE > toSlice() const & - { return ArraySlice< T const, 1, 0, INDEX_TYPE >( data(), &m_size, nullptr ); } + ArraySlice2< T const, DynamicLayout1D< INDEX_TYPE > > toSlice() const & + { return ArraySlice2< T const, DynamicLayout1D< INDEX_TYPE > >( data(), makeLayout( makeExtent( m_size ) ) ); } /** * @brief Overload for rvalues that is deleted. @@ -165,7 +165,7 @@ class SortedArrayView * about to be destroyed. This overload prevents that from happening. */ LVARRAY_HOST_DEVICE constexpr inline - ArraySlice< T const, 1, 0, INDEX_TYPE > toSlice() const && = delete; + ArraySlice2< T const, DynamicLayout1D< INDEX_TYPE > > toSlice() const && = delete; ///@} diff --git a/src/input.hpp b/src/input.hpp index 12cc033a..daeb0fb7 100644 --- a/src/input.hpp +++ b/src/input.hpp @@ -55,7 +55,6 @@ struct StringToArrayHelper * @param arrayValue A reference to the array value to read in * @param inputStream the stream to read a value from */ - template< int NDIM > static void Read( T & arrayValue, INDEX_TYPE const *, std::istringstream & inputStream ) @@ -74,9 +73,9 @@ struct StringToArrayHelper * @param dims The dimensions of the array. * @param inputStream The stream to read from. */ - template< int NDIM, int USD > + template< typename LAYOUT > static void - Read( ArraySlice< T, NDIM, USD, INDEX_TYPE > const arraySlice, + Read( ArraySlice2< T, LAYOUT > const arraySlice, INDEX_TYPE const * const dims, std::istringstream & inputStream ) { @@ -87,7 +86,7 @@ struct StringToArrayHelper for( int i=0; i<(*dims); ++i ) { skipDelimiters( inputStream ); - Read< NDIM-1 >( arraySlice[i], dims+1, inputStream ); + Read( arraySlice[i], dims+1, inputStream ); } skipDelimiters( inputStream ); @@ -117,13 +116,15 @@ struct StringToArrayHelper * All spaces are stripped prior to processing, please don't use tabs for anything. */ template< typename T, - int NDIM, + typename EXTENT, typename PERMUTATION, - typename INDEX_TYPE, - template< typename > class BUFFER_TYPE > -static void stringToArray( Array< T, NDIM, PERMUTATION, INDEX_TYPE, BUFFER_TYPE > & array, + template< typename > class BUFFER_TYPE > +static void stringToArray( Array2< T, EXTENT, PERMUTATION, BUFFER_TYPE > & array, std::string valueString ) { + using IndexType = typename Array2< T, EXTENT, PERMUTATION, BUFFER_TYPE >::IndexType; + constexpr int NDIM = Array2< T, EXTENT, PERMUTATION, BUFFER_TYPE >::NDIM; + // 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 @@ -216,10 +217,10 @@ static void stringToArray( Array< T, NDIM, PERMUTATION, INDEX_TYPE, BUFFER_TYPE int dimLevel = -1; // dims is the dimensions that get set the first diving down. - INDEX_TYPE dims[NDIM] = {0}; + IndexType dims[NDIM] = {0}; // currentDims is used to track the dimensions for subsequent dives down the dimensions. - INDEX_TYPE currentDims[NDIM] = {0}; + IndexType currentDims[NDIM] = {0}; // flag to see if the dims value has been set for a given dimension bool dimSet[NDIM] = {false}; @@ -304,7 +305,7 @@ static void stringToArray( Array< T, NDIM, PERMUTATION, INDEX_TYPE, BUFFER_TYPE } std::istringstream strstream( valueString ); // this recursively reads the values from the stringstream - internal::StringToArrayHelper< T, INDEX_TYPE >::Read( array.toSlice(), array.dims(), strstream ); + internal::StringToArrayHelper< T, IndexType >::Read( array.toSlice(), dims, strstream ); } } // namespace input diff --git a/src/memcpy.hpp b/src/memcpy.hpp index 0ef94ea1..e88875c3 100644 --- a/src/memcpy.hpp +++ b/src/memcpy.hpp @@ -25,42 +25,25 @@ namespace LvArray namespace internal { -/** - * @brief Specialization for when all the indices have been consumed. - * @return @p curSlice. - * @tparam N_LEFT The number of indices left to consume, this is a specialization for @c N_LEFT == 0. - * @tparam T The type of values in the slice. - * @tparam NDIM The number of dimensions in the slice. - * @tparam USD The unit stride dimension of the slice. - * @tparam INDEX_TYPE The index type of the slice. - * @param curSlice The slice to return. - */ -template< int N_LEFT, typename T, int NDIM, int USD, typename INDEX_TYPE > -std::enable_if_t< N_LEFT == 0, ArraySlice< T, NDIM, USD, INDEX_TYPE > > -slice( ArraySlice< T, NDIM, USD, INDEX_TYPE > const curSlice, INDEX_TYPE const * ) -{ return curSlice; } - /** * @brief Slice @p curSlice until all of @p remainingIndices have been consumed. - * @tparam N_LEFT The number of indices left to consume. * @tparam T The type of values in the slice. - * @tparam NDIM The number of dimensions in the slice. - * @tparam USD The unit stride dimension of the slice. - * @tparam INDEX_TYPE The index type of the slice. + * @tparam LAYOUT The layout of the slice + * @tparam Is a pack of indices to access @p indices * @param curSlice The ArraySlice to further slice. - * @param remainingIndices The indices used to slice @p curSlice. + * @param indices The indices used to slice @p curSlice. * @return @code curSlice[ remainingIndices[ 0 ] ][ remainingIndices[ 1 ] ][ ... ] @endcode. */ -template< int N_LEFT, typename T, int NDIM, int USD, typename INDEX_TYPE > -std::enable_if_t< N_LEFT != 0, ArraySlice< T, NDIM - N_LEFT, USD - N_LEFT, INDEX_TYPE > > -slice( ArraySlice< T, NDIM, USD, INDEX_TYPE > const curSlice, INDEX_TYPE const * const remainingIndices ) -{ return slice< N_LEFT - 1 >( curSlice[ remainingIndices[ 0 ] ], remainingIndices + 1 ); } +template< typename T, typename LAYOUT, camp::idx_t ... Is > +auto +slice( ArraySlice2< T, LAYOUT > const curSlice, typename LAYOUT::IndexType const * const indices, camp::idx_seq< Is... > ) +{ return curSlice( indices[Is]... ); } } // namespace internal /** * @brief Use memcpy to copy @p src in to @p dst. - * @tparam T The type contined by @p dst and @p src. + * @tparam T The type contained by @p dst and @p src. * @tparam NDIM The number of dimensions in @p dst and @p src. * @tparam DST_USD The unit stride dimension of @p dst and @p src. * @tparam DST_INDEX_TYPE The index type of @p dst. @@ -70,13 +53,13 @@ slice( ArraySlice< T, NDIM, USD, INDEX_TYPE > const curSlice, INDEX_TYPE const * * @details If both @p src and @p dst were allocated with Umpire then the Umpire ResouceManager is used to perform * the copy, otherwise std::memcpy is used. */ -template< typename T, int NDIM, int USD, typename DST_INDEX_TYPE, typename SRC_INDEX_TYPE > -void memcpy( ArraySlice< T, NDIM, USD, DST_INDEX_TYPE > const dst, - ArraySlice< T const, NDIM, USD, SRC_INDEX_TYPE > const src ) +template< typename T, typename LAYOUT > +void memcpy( ArraySlice2< T, LAYOUT > const dst, + ArraySlice2< T const, LAYOUT > const src ) { LVARRAY_ERROR_IF_NE( dst.size(), src.size() ); - for( int i = 0; i < NDIM; ++i ) + for( int i = 0; i < LAYOUT::NDIM; ++i ) { LVARRAY_ERROR_IF_NE( dst.stride( i ), src.stride( i ) ); } @@ -104,14 +87,14 @@ void memcpy( ArraySlice< T, NDIM, USD, DST_INDEX_TYPE > const dst, * resources, in fact it does not even support synchronous copying with host resources. As such if a @p resource * wraps a resource of type @c camp::resouces::Host the method that doesn't take a resource is used. */ -template< typename T, int NDIM, int USD, typename DST_INDEX_TYPE, typename SRC_INDEX_TYPE > +template< typename T, typename LAYOUT > camp::resources::Event memcpy( camp::resources::Resource & resource, - ArraySlice< T, NDIM, USD, DST_INDEX_TYPE > const dst, - ArraySlice< T const, NDIM, USD, SRC_INDEX_TYPE > const src ) + ArraySlice2< T, LAYOUT > const dst, + ArraySlice2< T const, LAYOUT > const src ) { LVARRAY_ERROR_IF_NE( dst.size(), src.size() ); - for( int i = 0; i < NDIM; ++i ) + for( int i = 0; i < LAYOUT::NDIM; ++i ) { LVARRAY_ERROR_IF_NE( dst.stride( i ), src.stride( i ) ); } @@ -149,13 +132,13 @@ camp::resources::Event memcpy( camp::resources::Resource & resource, * memcpy< 1, 0 >( x, { 5 }, y, {} ); * @endcode */ -template< std::size_t N_DST_INDICES, std::size_t N_SRC_INDICES, typename T, int DST_NDIM, int DST_USD, - typename DST_INDEX_TYPE, template< typename > class DST_BUFFER, int SRC_NDIM, int SRC_USD, - typename SRC_INDEX_TYPE, template< typename > class SRC_BUFFER > -void memcpy( ArrayView< T, DST_NDIM, DST_USD, DST_INDEX_TYPE, DST_BUFFER > const & dst, - std::array< DST_INDEX_TYPE, N_DST_INDICES > const & dstIndices, - ArrayView< T const, SRC_NDIM, SRC_USD, SRC_INDEX_TYPE, SRC_BUFFER > const & src, - std::array< SRC_INDEX_TYPE, N_SRC_INDICES > const & srcIndices ) +template< std::size_t N_DST_INDICES, std::size_t N_SRC_INDICES, typename T, + typename DST_LAYOUT, template< typename > class DST_BUFFER, + typename SRC_LAYOUT, template< typename > class SRC_BUFFER > +void memcpy( ArrayView2< T, DST_LAYOUT, DST_BUFFER > const & dst, + std::array< typename DST_LAYOUT::IndexType, N_DST_INDICES > const & dstIndices, + ArrayView2< T const, SRC_LAYOUT, SRC_BUFFER > const & src, + std::array< typename SRC_LAYOUT::IndexType, N_SRC_INDICES > const & srcIndices ) { #if !defined( LVARRAY_USE_UMPIRE ) LVARRAY_ERROR_IF_NE_MSG( dst.getPreviousSpace(), MemorySpace::host, "Without Umpire only host memory is supported." ); @@ -165,11 +148,8 @@ void memcpy( ArrayView< T, DST_NDIM, DST_USD, DST_INDEX_TYPE, DST_BUFFER > const dst.move( dst.getPreviousSpace(), true ); src.move( src.getPreviousSpace(), false ); - ArraySlice< T, DST_NDIM - N_DST_INDICES, DST_USD - N_DST_INDICES, DST_INDEX_TYPE > const dstSlice = - internal::slice< N_DST_INDICES >( dst.toSlice(), dstIndices.data() ); - - ArraySlice< T const, SRC_NDIM - N_SRC_INDICES, SRC_USD - N_SRC_INDICES, SRC_INDEX_TYPE > const srcSlice = - internal::slice< N_SRC_INDICES >( src.toSlice(), srcIndices.data() ); + auto const dstSlice = internal::slice( dst.toSlice(), dstIndices.data(), camp::make_idx_seq_t< N_DST_INDICES >{} ); + auto const srcSlice = internal::slice( src.toSlice(), srcIndices.data(), camp::make_idx_seq_t< N_SRC_INDICES >{} ); memcpy( dstSlice, srcSlice ); } @@ -196,23 +176,20 @@ void memcpy( ArrayView< T, DST_NDIM, DST_USD, DST_INDEX_TYPE, DST_BUFFER > const * @details The copy occurs from the current space of @p src to the current space of @p dst. * Each array is moved to their current space. */ -template< std::size_t N_DST_INDICES, std::size_t N_SRC_INDICES, typename T, int DST_NDIM, int DST_USD, - typename DST_INDEX_TYPE, template< typename > class DST_BUFFER, int SRC_NDIM, int SRC_USD, - typename SRC_INDEX_TYPE, template< typename > class SRC_BUFFER > +template< std::size_t N_DST_INDICES, std::size_t N_SRC_INDICES, typename T, + typename DST_LAYOUT, template< typename > class DST_BUFFER, + typename SRC_LAYOUT, template< typename > class SRC_BUFFER > camp::resources::Event memcpy( camp::resources::Resource & resource, - ArrayView< T, DST_NDIM, DST_USD, DST_INDEX_TYPE, DST_BUFFER > const & dst, - std::array< DST_INDEX_TYPE, N_DST_INDICES > const & dstIndices, - ArrayView< T const, SRC_NDIM, SRC_USD, SRC_INDEX_TYPE, SRC_BUFFER > const & src, - std::array< SRC_INDEX_TYPE, N_SRC_INDICES > const & srcIndices ) + ArrayView2< T, DST_LAYOUT, DST_BUFFER > const & dst, + std::array< typename DST_LAYOUT::IndexType, N_DST_INDICES > const & dstIndices, + ArrayView2< T const, SRC_LAYOUT, SRC_BUFFER > const & src, + std::array< typename SRC_LAYOUT::IndexType, N_SRC_INDICES > const & srcIndices ) { dst.move( dst.getPreviousSpace(), true ); src.move( src.getPreviousSpace(), false ); - ArraySlice< T, DST_NDIM - N_DST_INDICES, DST_USD - N_DST_INDICES, DST_INDEX_TYPE > const dstSlice = - internal::slice< N_DST_INDICES >( dst.toSlice(), dstIndices.data() ); - - ArraySlice< T const, SRC_NDIM - N_SRC_INDICES, SRC_USD - N_SRC_INDICES, SRC_INDEX_TYPE > const srcSlice = - internal::slice< N_SRC_INDICES >( src.toSlice(), srcIndices.data() ); + auto const dstSlice = internal::slice( dst.toSlice(), dstIndices.data(), camp::make_idx_seq_t< N_DST_INDICES >{} ); + auto const srcSlice = internal::slice( src.toSlice(), srcIndices.data(), camp::make_idx_seq_t< N_SRC_INDICES >{} ); return memcpy( resource, dstSlice, srcSlice ); } diff --git a/src/output.hpp b/src/output.hpp index a0b28826..236d4315 100644 --- a/src/output.hpp +++ b/src/output.hpp @@ -45,9 +45,9 @@ namespace LvArray * @return @p stream . */ // Sphinx start after Array stream IO -template< typename T, int NDIM, int USD, typename INDEX_TYPE > +template< typename T, typename LAYOUT > std::ostream & operator<<( std::ostream & stream, - ::LvArray::ArraySlice< T, NDIM, USD, INDEX_TYPE > const slice ) + ::LvArray::ArraySlice2< T, LAYOUT > const slice ) { stream << "{ "; @@ -56,7 +56,7 @@ std::ostream & operator<<( std::ostream & stream, stream << slice[ 0 ]; } - for( INDEX_TYPE i = 1; i < slice.size( 0 ); ++i ) + for( typename LvArray::ArraySlice2< T, LAYOUT >::IndexType i = 1; i < slice.size( 0 ); ++i ) { stream << ", " << slice[ i ]; } @@ -79,12 +79,10 @@ std::ostream & operator<<( std::ostream & stream, * @return @p stream . */ template< typename T, - int NDIM, - int USD, - typename INDEX_TYPE, + typename LAYOUT, template< typename > class BUFFER_TYPE > std::ostream & operator<<( std::ostream & stream, - ::LvArray::ArrayView< T, NDIM, USD, INDEX_TYPE, BUFFER_TYPE > const & view ) + ::LvArray::ArrayView2< T, LAYOUT, BUFFER_TYPE > const & view ) { return stream << view.toSliceConst(); } /** diff --git a/src/python/PyArray.cpp b/src/python/PyArray.cpp index 8e36b51e..d47784a3 100644 --- a/src/python/PyArray.cpp +++ b/src/python/PyArray.cpp @@ -90,43 +90,6 @@ static PyObject * PyArray_repr( PyObject * const obj ) return PyUnicode_FromString( repr.c_str() ); } -static constexpr char const * PyArray_getSingleParameterResizeIndexDocString = - "get_single_parameter_resize_index(self)\n" - "--\n\n" - "Return the default resize dimension.\n"; -static PyObject * PyArray_getSingleParameterResizeIndex( PyArray * const self, PyObject * const args ) -{ - LVARRAY_UNUSED_VARIABLE( args ); - VERIFY_NON_NULL_SELF( self ); - VERIFY_INITIALIZED( self ); - - return PyLong_FromLongLong( self->array->getSingleParameterResizeIndex() ); -} - -static constexpr char const * PyArray_setSingleParameterResizeIndexDocString = - "set_single_parameter_resize_index(self, dim)\n" - "--\n\n" - "Set the default resize dimension."; -static PyObject * PyArray_setSingleParameterResizeIndex( PyArray * const self, PyObject * const args ) -{ - VERIFY_NON_NULL_SELF( self ); - VERIFY_INITIALIZED( self ); - VERIFY_RESIZEABLE( self ); - - int dim; - if( !PyArg_ParseTuple( args, "i", &dim ) ) - { - return nullptr; - } - - PYTHON_ERROR_IF( dim < 0 || dim >= self->array->ndim(), PyExc_ValueError, - "argument out of bounds", nullptr ); - - self->array->setSingleParameterResizeIndex( dim ); - - Py_RETURN_NONE; -} - static constexpr char const * PyArray_resizeDocString = "resize(self, size)\n" "--\n\n" @@ -247,8 +210,6 @@ static PyMemberDef PyArray_members[] = { }; static PyMethodDef PyArray_methods[] = { - { "get_single_parameter_resize_index", (PyCFunction) PyArray_getSingleParameterResizeIndex, METH_NOARGS, PyArray_getSingleParameterResizeIndexDocString }, - { "set_single_parameter_resize_index", (PyCFunction) PyArray_setSingleParameterResizeIndex, METH_VARARGS, PyArray_setSingleParameterResizeIndexDocString }, { "resize", (PyCFunction) PyArray_resize, METH_VARARGS, PyArray_resizeDocString }, { "resize_all", (PyCFunction) PyArray_resizeAll, METH_VARARGS, PyArray_resizeAllDocString }, { "to_numpy", (PyCFunction) PyArray_toNumPy, METH_VARARGS, PyArray_toNumPyDocString }, diff --git a/src/python/PyArray.hpp b/src/python/PyArray.hpp index a64a0f93..2abef303 100644 --- a/src/python/PyArray.hpp +++ b/src/python/PyArray.hpp @@ -83,20 +83,6 @@ class PyArrayWrapperBase */ virtual int ndim() const = 0; - /** - * @brief Return the single parameter resize index of the Array. - * @return the single parameter resize index of the array. - * @note This wraps Array::getSingleParameterResizeIndex(). - */ - virtual int getSingleParameterResizeIndex() const = 0; - - /** - * @brief Set the single parameter resize index of the Array. - * @param dim The dimension to make the single parameter resize index. - * @note This wraps Array::setSingleParameterResizeIndex( int ). - */ - virtual void setSingleParameterResizeIndex( int const dim ) const = 0; - /** * @brief Resize the default dimension of the Array. * @param newSize The new size of the default dimension. @@ -172,14 +158,6 @@ class PyArrayWrapper final : public PyArrayWrapperBase virtual int ndim() const final override { return NDIM; } - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - virtual int getSingleParameterResizeIndex() const final override - { return m_array.getSingleParameterResizeIndex(); } - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - virtual void setSingleParameterResizeIndex( int const dim ) const final override - { m_array.setSingleParameterResizeIndex( dim ); } - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// virtual void resize( long long const newSize ) final override { m_array.resize( integerConversion< INDEX_TYPE >( newSize ) ); } diff --git a/src/sliceHelpers.hpp b/src/sliceHelpers.hpp index 38dec145..e3ab4f0e 100644 --- a/src/sliceHelpers.hpp +++ b/src/sliceHelpers.hpp @@ -35,19 +35,18 @@ void forValuesInSlice( T & value, LAMBDA && f ) * @tparam T The type of values stored in @p slice. * @tparam NDIM the dimension of @p slice. * @tparam USD the unit stride dimension of @p slice. - * @tparam INDEX_TYPE the integer used to index into @p slice. * @tparam LAMBDA the type of the function @p f to apply. * @brief Iterate over the values in the slice in lexicographic order. * @param slice the slice to iterate over. * @param f the function to apply to each value. */ DISABLE_HD_WARNING -template< typename T, int NDIM, int USD, typename INDEX_TYPE, typename LAMBDA > +template< typename T, typename LAYOUT, typename LAMBDA > LVARRAY_HOST_DEVICE -void forValuesInSlice( ArraySlice< T, NDIM, USD, INDEX_TYPE > const slice, LAMBDA && f ) +void forValuesInSlice( ArraySlice2< T, LAYOUT > const slice, LAMBDA && f ) { - INDEX_TYPE const bounds = slice.size( 0 ); - for( INDEX_TYPE i = 0; i < bounds; ++i ) + auto const bounds = slice.template size< 0 >(); + for( typename LAYOUT::IndexType i = 0; i < bounds; ++i ) { forValuesInSlice( slice[ i ], f ); } @@ -82,14 +81,14 @@ void forValuesInSliceWithIndices( T & value, LAMBDA && f, INDICES const ... indi * @param indices The previous sliced off indices. */ DISABLE_HD_WARNING -template< typename T, int NDIM, int USD, typename INDEX_TYPE, typename LAMBDA, typename ... INDICES > +template< typename T, typename LAYOUT, typename LAMBDA, typename ... INDICES > LVARRAY_HOST_DEVICE -void forValuesInSliceWithIndices( ArraySlice< T, NDIM, USD, INDEX_TYPE > const slice, +void forValuesInSliceWithIndices( ArraySlice2< T, LAYOUT > const slice, LAMBDA && f, INDICES const ... indices ) { - INDEX_TYPE const bounds = slice.size( 0 ); - for( INDEX_TYPE i = 0; i < bounds; ++i ) + auto const bounds = slice.template size< 0 >(); + for( typename LAYOUT::IndexType i = 0; i < bounds; ++i ) { forValuesInSliceWithIndices( slice[ i ], f, indices ..., i ); } @@ -104,12 +103,12 @@ void forValuesInSliceWithIndices( ArraySlice< T, NDIM, USD, INDEX_TYPE > const s * @param src The array slice to sum over. * @param dst The value to add the sum to. */ -template< typename T, int USD_SRC, typename INDEX_TYPE > -void sumOverFirstDimension( ArraySlice< T const, 1, USD_SRC, INDEX_TYPE > const src, +template< typename T, typename LAYOUT > +void sumOverFirstDimension( ArraySlice2< T const, LAYOUT > const src, T & dst ) { - INDEX_TYPE const bounds = src.size( 0 ); - for( INDEX_TYPE i = 0; i < bounds; ++i ) + auto const bounds = src.template size< 0 >(); + for( typename LAYOUT::IndexType i = 0; i < bounds; ++i ) { dst += src( i ); } @@ -125,18 +124,19 @@ void sumOverFirstDimension( ArraySlice< T const, 1, USD_SRC, INDEX_TYPE > const * @param src The slice to sum over. * @param dst The slice to add to. */ -template< typename T, int NDIM, int USD_SRC, int USD_DST, typename INDEX_TYPE > -void sumOverFirstDimension( ArraySlice< T const, NDIM, USD_SRC, INDEX_TYPE > const src, - ArraySlice< T, NDIM - 1, USD_DST, INDEX_TYPE > const dst ) +template< typename T, typename LAYOUT_SRC, typename LAYOUT_DST > +void sumOverFirstDimension( ArraySlice2< T const, LAYOUT_SRC > const src, + ArraySlice2< T, LAYOUT_DST > const dst ) { + static_assert(LAYOUT_DST::NDIM == LAYOUT_SRC::NDIM - 1, "Destination slice must have dimension one less than source"); #ifdef ARRAY_SLICE_CHECK_BOUNDS - for( int i = 1; i < NDIM; ++i ) + tupleManipulation::forEach2( tupleManipulation::drop_front< 1 >( src.layout().extent() ), dst.layout().extent(), []( auto src_size, auto dst_size ) { - LVARRAY_ERROR_IF_NE( src.size( i ), dst.size( i - 1 ) ); - } + LVARRAY_ERROR_IF_NE( src_size, dst_size ); + } ); #endif - forValuesInSliceWithIndices( src, [dst] ( T const & value, INDEX_TYPE const, auto const ... indices ) + forValuesInSliceWithIndices( src, [dst] ( T const & value, auto, auto const ... indices ) { dst( indices ... ) += value; } ); diff --git a/src/tupleManipulation.hpp b/src/tupleManipulation.hpp new file mode 100644 index 00000000..66252c55 --- /dev/null +++ b/src/tupleManipulation.hpp @@ -0,0 +1,594 @@ +/* + * Copyright (c) 2021, Lawrence Livermore National Security, LLC and LvArray contributors. + * All rights reserved. + * See the LICENSE file for details. + * SPDX-License-Identifier: (BSD-3-Clause) + */ + +/** + * @file Layout.hpp + * @brief Contains the implementation of Layout. + */ + +#pragma once + +#include "Macros.hpp" +#include "typeManipulation.hpp" + +#include "camp/tuple.hpp" + +namespace camp +{ + +template< typename T, int N > +struct seq_inc {}; + +template< typename T, T ... Is, int N > +struct seq_inc< int_seq< T, Is... >, N > +{ + using type = int_seq< T, Is + N ... >; +}; + +template< typename T, int N > +using seq_inc_t = typename seq_inc< T, N >::type; + +template< typename T, T Lower, T Upper > +using make_range = seq_inc_t< make_int_seq_t< T, Upper - Lower >, Lower >; + +template< idx_t Lower, idx_t Upper > +using make_idx_range = make_range< idx_t, Lower, Upper >; + +namespace detail +{ + +template< typename Seq > +struct reverse_seq {}; + +template< typename T, T ... Is > +struct reverse_seq< int_seq< T, Is... > > +{ + using type = int_seq< T, sizeof...(Is) - Is - 1 ... >; +}; + +} // namespace detail + +template< typename Seq > +using reverse_seq_t = typename detail::reverse_seq< Seq >::type; + +template< typename T, T N > +using make_int_rseq_t = reverse_seq_t< make_int_seq_t< T, N > >; + +template< idx_t N > +using make_idx_rseq_t = make_int_rseq_t< idx_t, N >; + +template< typename T > +using idx_rseq_from_t = reverse_seq_t< idx_seq_from_t< T > >; + +template< typename T > +inline constexpr idx_t tsize_v = tuple_size< decay< T > >::value; + +} + +namespace LvArray +{ + +/** + * @brief Make function for tuple + * @tparam Ts argument type list + * @param args variadic arguments + * @return the constructed tuple + */ +template< typename ... Ts > +LVARRAY_HOST_DEVICE constexpr +auto +makeTuple( Ts && ... args ) +{ + return camp::make_tuple( LVARRAY_FWD( args )... ); +} + +namespace tupleManipulation +{ + +template< typename T > +struct common_type; + +template< typename T, typename ... Ts > +struct common_type< camp::tuple< T, Ts... > > +{ + using type = std::common_type_t< value_type_t< T >, value_type_t< Ts >... >; +}; + +template<> +struct common_type< camp::tuple<> > +{ + using type = int; +}; + +template< typename T > +using common_type_t = typename common_type< camp::decay< T > >::type; + +namespace internal +{ + +template< typename T, typename U, camp::idx_t ... Is, camp::idx_t ... Js, camp::idx_t ... Ks > +LVARRAY_HOST_DEVICE constexpr +auto +construct( T const & t, U const & v, camp::idx_seq< Is... >, camp::idx_seq< Js... >, camp::idx_seq< Ks... > ) +{ + return makeTuple( camp::get< Is >( t )..., (void(Js), v)..., camp::get< Ks >( t )... ); +} + +} // namespace internal + +template< int N, typename U > +LVARRAY_HOST_DEVICE constexpr +auto +repeat( U const & v ) +{ + return internal::construct( camp::tuple<>{}, v, camp::idx_seq<>{}, camp::make_idx_seq_t< N >{}, camp::idx_seq<>{} ); +} + +template< typename T, camp::idx_t ... Is > +LVARRAY_HOST_DEVICE constexpr +auto +select( T const & t, camp::idx_seq< Is... > ) +{ + return makeTuple( camp::get< Is >( t ) ... ); +} + +template< typename T, camp::idx_t ... Is > +LVARRAY_HOST_DEVICE constexpr +auto +selectRefs( T const & t, camp::idx_seq< Is... > ) +{ + return camp::tuple< camp::tuple_element_t< Is, T > const & ... >( camp::get< Is >( t ) ... ); +} + +template< typename T, camp::idx_t ... Is > +LVARRAY_HOST_DEVICE constexpr +auto +selectRefs( T & t, camp::idx_seq< Is... > ) +{ + return camp::tuple< camp::tuple_element_t< Is, T > & ... >( camp::get< Is >( t ) ... ); +} + +template< int N = 1, typename T, typename U > +LVARRAY_HOST_DEVICE constexpr +auto +prepend( T const & t, U const & v ) +{ + return internal::construct( t, v, camp::idx_seq<>{}, camp::make_idx_seq_t< N >{}, camp::idx_seq_from_t< T >{} ); +} + +template< int N = 1, typename T, typename U > +LVARRAY_HOST_DEVICE constexpr +auto +append( T const & t, U const & v ) +{ + return internal::construct( t, v, camp::idx_seq_from_t< T >{}, camp::make_idx_seq_t< N >{}, camp::idx_seq<>{} ); +} + +template< int I, int N = 1, typename T, typename U > +LVARRAY_HOST_DEVICE constexpr +auto +replace( T const & t, U const & v ) +{ + return internal::construct( t, v, camp::make_idx_seq_t< I >{}, camp::make_idx_seq_t< N >{}, camp::make_idx_range< I + N, camp::tsize_v< T > >{} ); +} + +template< int I, int N = 1, typename T, typename U > +LVARRAY_HOST_DEVICE constexpr +auto +insert( T const & t, U const & v ) +{ + return internal::construct( t, v, camp::make_idx_seq_t< I >{}, camp::make_idx_seq_t< N >{}, camp::make_idx_range< I, camp::tsize_v< T > >{} ); +} + +template< int I, int N = 1, typename T > +LVARRAY_HOST_DEVICE constexpr +auto +remove( T const & t ) +{ + return internal::construct( t, 0, camp::make_idx_seq_t< I >{}, camp::idx_seq<>{}, camp::make_idx_range< I + N, camp::tsize_v< T > >{} ); +} + +template< int I, int J, typename T > +LVARRAY_HOST_DEVICE constexpr +auto +take( T const & t ) +{ + return select( t, camp::make_idx_range< I, J >{} ); +} + +template< int N, typename T > +LVARRAY_HOST_DEVICE constexpr +auto +drop_front( T const & t ) +{ + return select( t, camp::make_idx_range< N, camp::tsize_v< T > >{} ); +} + +template< int N, typename T > +LVARRAY_HOST_DEVICE constexpr +auto +drop_back( T const & t ) +{ + return select( t, camp::make_idx_range< 0, camp::tsize_v< T > - N >{} ); +} + +namespace internal +{ + +// Implementation of general zip() and unzip() are left as an exercise to the reader. + +template< typename T, camp::idx_t ... Is > +LVARRAY_HOST_DEVICE constexpr +auto +zip2( T && t, camp::idx_seq< Is... > ) +{ + return makeTuple( makeTuple( camp::get< Is >( camp::get< 0 >( LVARRAY_FWD( t ) ) ), camp::get< Is >( camp::get< 1 >( LVARRAY_FWD( t ) ) ) )... ); +} + +template< typename T, camp::idx_t ... Is > +LVARRAY_HOST_DEVICE constexpr +auto +unzip2( T && t, camp::idx_seq< Is... > ) +{ + return makeTuple( makeTuple( camp::get< 0 >( camp::get< Is >( LVARRAY_FWD( t ) ) )... ), + makeTuple( camp::get< 1 >( camp::get< Is >( LVARRAY_FWD( t ) ) )... ) ); +} + +} // namespace internal + +template< typename T > +LVARRAY_HOST_DEVICE constexpr +auto +zip2( T && t ) +{ + return internal::zip2( LVARRAY_FWD( t ), camp::idx_seq_from_t< camp::tuple_element_t< 0, T > >{} ); +} + +template< typename T1, typename T2 > +LVARRAY_HOST_DEVICE constexpr +auto +zip2( T1 && t1, T2 && t2 ) +{ + static_assert( camp::tsize_v< T1 > == camp::tsize_v< T2 >, "Tuples must have equal sizes." ); + return zip2( makeTuple( LVARRAY_FWD( t1 ), LVARRAY_FWD( t2 ) ) ); +} + +template< typename T > +LVARRAY_HOST_DEVICE constexpr +auto +unzip2( T && t ) +{ + return internal::unzip2( LVARRAY_FWD( t ), camp::idx_seq_from_t< T >{} ); +} + +namespace internal +{ + +template< typename T, typename F, typename G, camp::idx_t ... Is > +LVARRAY_HOST_DEVICE constexpr +auto +transformApply( T && t, F && f, G && g, camp::idx_seq< Is... > ) +{ + return LVARRAY_FWD( g )( f( camp::get< Is >( LVARRAY_FWD( t ) ) )... ); +} + +template< typename T1, typename T2, typename F, typename G, camp::idx_t ... Is > +LVARRAY_HOST_DEVICE constexpr +auto +transformApply2( T1 && t1, T2 && t2, F && f, G && g, camp::idx_seq< Is... > ) +{ + return LVARRAY_FWD( g )( f( camp::get< Is >( LVARRAY_FWD( t1 ) ), camp::get< Is >( LVARRAY_FWD( t2 ) ) )... ); +} + +} // namespace internal + +template< typename T, typename F, typename G, typename SEQ = camp::idx_seq_from_t< T > > +LVARRAY_HOST_DEVICE constexpr +auto +transformApply( T && t, F && f, G && g, SEQ s = {} ) +{ + return internal::transformApply( LVARRAY_FWD( t ), LVARRAY_FWD( f ), LVARRAY_FWD( g ), s ); +} + +template< typename T1, typename T2, typename F, typename G, typename SEQ = camp::idx_seq_from_t< T1 > > +LVARRAY_HOST_DEVICE constexpr +auto +transformApply2( T1 && t1, T2 && t2, F && f, G && g, SEQ s = {} ) +{ + static_assert( camp::tsize_v< T1 > == camp::tsize_v< T2 >, "Tuples must have equal number of elements" ); + return internal::transformApply2( LVARRAY_FWD( t1 ), LVARRAY_FWD( t2 ), LVARRAY_FWD( f ), LVARRAY_FWD( g ), s ); +} + +template< typename T, typename F, typename SEQ = camp::idx_seq_from_t< T > > +LVARRAY_HOST_DEVICE constexpr +auto +transform( T && t, F && f, SEQ s = {} ) +{ + return transformApply( LVARRAY_FWD( t ), LVARRAY_FWD( f ), []( auto && ... vs ) { return makeTuple( LVARRAY_FWD( vs )... ); }, s ); +} + +template< typename T1, typename T2, typename F, typename SEQ = camp::idx_seq_from_t< T1 > > +LVARRAY_HOST_DEVICE constexpr +auto +transform2( T1 && t, T2 && t2, F && f, SEQ s = {} ) +{ + return transformApply2( LVARRAY_FWD( t ), LVARRAY_FWD( t2 ), LVARRAY_FWD( f ), []( auto && ... vs ) { return makeTuple( LVARRAY_FWD( vs )... ); }, s ); +} + +template< typename T, typename G, typename SEQ = camp::idx_seq_from_t< T > > +LVARRAY_HOST_DEVICE constexpr +auto +apply( T && t, G && g, SEQ s = {} ) +{ + return transformApply( LVARRAY_FWD( t ), []( auto && v ) -> decltype(auto) { return LVARRAY_FWD( v ); }, LVARRAY_FWD( g ), s ); +} + +template< typename T, typename F, typename SEQ = camp::idx_seq_from_t< T > > +LVARRAY_HOST_DEVICE constexpr +void +forEach( T && t, F && f, SEQ s = {} ) +{ + tupleManipulation::apply( LVARRAY_FWD( t ), [&f]( auto && ... vs ){ ( f( LVARRAY_FWD( vs ) ), ... ); }, s ); +} + +template< typename T1, typename T2, typename F, typename SEQ = camp::idx_seq_from_t< T1 > > +LVARRAY_HOST_DEVICE constexpr +void +forEach2( T1 && t1, T2 && t2, F && f, SEQ s = {} ) +{ + tupleManipulation::transform2( LVARRAY_FWD( t1 ), LVARRAY_FWD( t2 ), [&f]( auto && v1, auto && v2 ) { f( LVARRAY_FWD( v1 ), LVARRAY_FWD( v2 ) ); return _t{}; }, s ); +} + +namespace internal +{ + +template< typename T, typename U, typename F > +LVARRAY_HOST_DEVICE constexpr +decltype(auto) +fold( T &&, U && init, F &&, camp::idx_seq<> ) +{ + return LVARRAY_FWD( init ); +} + +template< typename T, typename U, typename F, camp::idx_t I, camp::idx_t ... Is > +LVARRAY_HOST_DEVICE constexpr +auto +fold( T && t, U && init, F && f, camp::idx_seq< I, Is... > ) +{ + return fold( t, f( LVARRAY_FWD( init ), camp::get< I >( LVARRAY_FWD( t ) ) ), f, camp::idx_seq< Is... >{} ); +} + +} // namespace internal + +template< typename T, typename U, typename F > +LVARRAY_HOST_DEVICE constexpr +auto +foldLeft( T && t, U && init, F && f ) +{ + return internal::fold( LVARRAY_FWD( t ), LVARRAY_FWD( init ), LVARRAY_FWD( f ), camp::idx_seq_from_t< T >{} ); +} + +template< typename T, typename U, typename F > +LVARRAY_HOST_DEVICE constexpr +auto +foldRight( T && t, U && init, F && f ) +{ + return internal::fold( LVARRAY_FWD( t ), LVARRAY_FWD( init ), [&f]( auto && x, auto && y ){ return f( LVARRAY_FWD( y ), LVARRAY_FWD( x ) ); }, camp::idx_rseq_from_t< T >{} ); +} + +template< typename T, typename F > +LVARRAY_HOST_DEVICE constexpr +auto +allOf( T && t, F && f ) +{ + return transformApply( LVARRAY_FWD( t ), LVARRAY_FWD( f ), []( auto && ... vs ){ return ( _t{} && ... && vs ); } ); +} + +template< typename T1, typename T2, typename F, typename SEQ = camp::idx_seq_from_t< T1 > > +LVARRAY_HOST_DEVICE constexpr +auto +allOf2( T1 && t1, T2 && t2, F && f, SEQ s = {} ) +{ + return transformApply2( LVARRAY_FWD( t1 ), LVARRAY_FWD( t2 ), LVARRAY_FWD( f ), []( auto && ... vs ){ return ( _t{} && ... && vs ); }, s ); +} + +template< typename T, typename F > +LVARRAY_HOST_DEVICE constexpr +auto +anyOf( T && t, F && f ) +{ + return transformApply( LVARRAY_FWD( t ), LVARRAY_FWD( f ), []( auto && ... vs ){ return ( _f{} || ... || vs ); } ); +} + +template< typename T1, typename T2, typename F, typename SEQ = camp::idx_seq_from_t< T1 > > +LVARRAY_HOST_DEVICE constexpr +auto +anyOf2( T1 && t1, T2 && t2, F && f, SEQ s = {} ) +{ + return transformApply2( LVARRAY_FWD( t1 ), LVARRAY_FWD( t2 ), LVARRAY_FWD( f ), []( auto && ... vs ){ return ( _f{} || ... || vs ); }, s ); +} + +namespace internal +{ + +template< typename T, camp::idx_t... TI, typename U, camp::idx_t... UI > +LVARRAY_HOST_DEVICE constexpr +auto +concat( T && t, camp::idx_seq< TI... >, U && u, camp::idx_seq< UI... > ) +{ + return makeTuple( camp::get< TI >( LVARRAY_FWD( t ) )..., camp::get< UI >( LVARRAY_FWD( u ) )... ); +} + +} + +template< typename T, typename ... Ts > +LVARRAY_HOST_DEVICE constexpr +auto +concat( T && t, Ts && ... ts ) +{ + if constexpr( sizeof...( Ts ) == 0 ) + { + return LVARRAY_FWD( t ); + } + else + { + // This doesn't compile under nvcc 12.1: + // return camp::tuple_cat_pair( LVARRAY_FWD( t ), concat( LVARRAY_FWD( ts )... ) ); + auto u = concat( LVARRAY_FWD( ts )... ); + return internal::concat( LVARRAY_FWD( t ), camp::idx_seq_from_t< T >{}, LVARRAY_FWD( u ), camp::idx_seq_from_t< decltype( u ) >{} ); + } +} + +template< typename T, typename P > +LVARRAY_HOST_DEVICE constexpr +auto +filter( T && t, P && p ) +{ + return transformApply( LVARRAY_FWD( t ), LVARRAY_FWD( p ), []( auto && ... vs ){ return concat( LVARRAY_FWD( vs )... ); } ); +} + +template< typename T1, typename T2, typename P > +LVARRAY_HOST_DEVICE constexpr +auto +filter( T1 && t1, T2 && t2, P && p ) +{ + return transformApply2( LVARRAY_FWD( t1 ), LVARRAY_FWD( t2 ), LVARRAY_FWD( p ), []( auto && ... vs ){ return concat( LVARRAY_FWD( vs )... ); } ); +} + +namespace internal +{ + +template< camp::idx_t I, typename T, typename P > +LVARRAY_HOST_DEVICE constexpr +camp::idx_t +find( T const & t, P && p ) +{ + if constexpr( I == camp::tsize_v< T > ) + { + return I; + } + else + { + if constexpr( decltype( p( camp::get< I >( t ) ) )::value ) + { + return I; + } + else + { + return find< I + 1 >( t, p ); + } + } +} + +} + +template< typename T, typename P > +LVARRAY_HOST_DEVICE constexpr +camp::idx_t +find( T && t, P && p ) +{ + if constexpr( camp::tsize_v< T > == 0 ) + { + return 1; + } + else + { + return internal::find< 0 >( LVARRAY_FWD( t ), LVARRAY_FWD( p ) ); + } +} + +template< typename T > +LVARRAY_HOST_DEVICE constexpr +auto +getValue( T const & t, int const idx ) +{ + // TODO: reconsider Array/Slice interface and remove this garbage function if no longer needed + static_assert( camp::tsize_v< T > > 0, "Tuple must not be empty." ); + common_type_t< T > ret = camp::get< 0 >( t ); + tupleManipulation::forEach( t, [idx, curr=0, &ret]( auto const & e ) mutable { if( idx == curr++ ) ret = e; } ); + return ret; +} + +namespace internal +{ + +template< typename T, camp::idx_t ... Is > +LVARRAY_HOST_DEVICE constexpr +typeManipulation::CArray< common_type_t< T >, camp::tsize_v< T > > +toArray( T && t, camp::idx_seq< Is... > ) +{ + return { camp::get< Is >( LVARRAY_FWD( t ) )... }; +} + +template< typename T, int N, camp::idx_t ... Is > +LVARRAY_HOST_DEVICE constexpr +auto +fromArray( typeManipulation::CArray< T, N > const & arr, camp::idx_seq< Is... > ) +{ + return makeTuple( arr[Is]... ); +} + +} // namespace internal + +template< typename T > +LVARRAY_HOST_DEVICE constexpr +auto +toArray( T && t ) +{ + return internal::toArray( LVARRAY_FWD( t ), camp::idx_seq_from_t< T >{} ); +} + +template< typename T, int N > +LVARRAY_HOST_DEVICE constexpr +auto +fromArray( typeManipulation::CArray< T, N > const & arr ) +{ + return internal::fromArray( arr, camp::make_idx_seq_t< N >{} ); +} + +#define LVARRAY_MAKE_CMP_STRUCT( NAME, OP ) \ +struct NAME \ +{ \ + template< typename T, typename U > \ + LVARRAY_HOST_DEVICE constexpr \ + auto operator()( T const & lhs, U const & rhs ) \ + { \ + return lhs OP rhs; \ + } \ +} + +LVARRAY_MAKE_CMP_STRUCT( cmp_lt, < ); +LVARRAY_MAKE_CMP_STRUCT( cmp_le, <= ); +LVARRAY_MAKE_CMP_STRUCT( cmp_gt, > ); +LVARRAY_MAKE_CMP_STRUCT( cmp_ge, >= ); +LVARRAY_MAKE_CMP_STRUCT( cmp_eq, == ); +LVARRAY_MAKE_CMP_STRUCT( cmp_ne, != ); + +#undef LVARRAY_MAKE_CMP_STRUCT + +#define LVARRAY_MAKE_BOP_STRUCT( NAME, OP ) \ +struct NAME \ +{ \ + template< typename T, typename U > \ + LVARRAY_HOST_DEVICE constexpr \ + auto operator()( T const & lhs, U const & rhs ) \ + { \ + return lhs OP rhs; \ + } \ +} + +LVARRAY_MAKE_BOP_STRUCT( op_plus, + ); +LVARRAY_MAKE_BOP_STRUCT( op_minus, - ); +LVARRAY_MAKE_BOP_STRUCT( op_mult, * ); +LVARRAY_MAKE_BOP_STRUCT( op_div, / ); +LVARRAY_MAKE_BOP_STRUCT( op_rem, % ); + +#undef LVARRAY_MAKE_BOP_STRUCT + +} // namespace tupleManipulation + +} // namespace LvArray diff --git a/src/typeManipulation.hpp b/src/typeManipulation.hpp index 33ca95c6..14bef7b2 100644 --- a/src/typeManipulation.hpp +++ b/src/typeManipulation.hpp @@ -118,6 +118,18 @@ namespace LvArray namespace typeManipulation { +template< typename T > +void printType() +{ + static_assert( sizeof( T ) == 0, "Printing type" ); +} + +template< typename T > +void printType( T ) +{ + static_assert( sizeof( T ) == 0, "Printing type" ); +} + /** * @tparam F The type of the function to call. * @brief The recursive base case where no argument is provided. @@ -163,6 +175,22 @@ using all_of = camp::concepts::metalib::all_of< BOOLS ... >; template< typename ... TYPES > using all_of_t = camp::concepts::metalib::all_of_t< TYPES ... >; +/** + * @brief A struct that contains a static constexpr bool value that is true if any of BOOLS are true. + * @tparam BOOLS A variadic pack of bool. + * @note Not a static constexpr bool so it can be used on device. + */ +template< bool ... BOOLS > +using any_of = camp::concepts::metalib::any_of< BOOLS ... >; + +/** + * @brief A struct that contains a static constexpr bool value that is true if any of TYPES::value are true. + * @tparam TYPES A variadic pack of types all of which define a static constexpr bool value. + * @note Not a static constexpr bool so it can be used on device. + */ +template< typename ... TYPES > +using any_of_t = camp::concepts::metalib::any_of_t< TYPES ... >; + /** * @tparam TEMPLATE The template to check if @p TYPE is an instantiation of. * @tparam TYPE The type to check. diff --git a/unitTests/CMakeLists.txt b/unitTests/CMakeLists.txt index 4d91681e..fe417411 100644 --- a/unitTests/CMakeLists.txt +++ b/unitTests/CMakeLists.txt @@ -40,7 +40,6 @@ set( testSources testArray_copyAssignmentOperator.cpp testArray_copyConstructor.cpp testArray_defaultConstructor.cpp - testArray_getSetSingleParameterResizeIndex.cpp testArray_indexing.cpp testArray_moveAssignmentOperator.cpp testArray_moveConstructor.cpp @@ -55,10 +54,12 @@ set( testSources testArray_toView.cpp testArray_toViewConst.cpp testBuffers.cpp + testConstant.cpp testCRSMatrix.cpp testIndexing.cpp testInput.cpp testIntegerConversion.cpp + testLayout.cpp testMath.cpp testMemcpy.cpp testSliceHelpers.cpp @@ -73,6 +74,7 @@ set( testSources testTensorOpsSymDeterminant.cpp testTensorOpsSymInverseOneArg.cpp testTensorOpsSymInverseTwoArgs.cpp + testTupleManipulation.cpp testTypeManipulation.cpp testStackTrace.cpp testInvalidOperations.cpp diff --git a/unitTests/testArray.hpp b/unitTests/testArray.hpp index 093d236d..1489abd3 100644 --- a/unitTests/testArray.hpp +++ b/unitTests/testArray.hpp @@ -43,7 +43,6 @@ class ArrayTest : public ::testing::Test { ARRAY array; EXPECT_TRUE( array.empty() ); - EXPECT_EQ( array.getSingleParameterResizeIndex(), 0 ); for( int i = 0; i < NDIM; ++i ) { @@ -65,7 +64,6 @@ class ArrayTest : public ::testing::Test [] ( 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 ) @@ -157,17 +155,6 @@ class ArrayTest : public ::testing::Test compare( copy, movedCopy ); } - 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(); @@ -298,47 +285,43 @@ class ArrayTest : public ::testing::Test // 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 ); + constexpr int dim = ARRAY::SingleResizeDim; - std::array< INDEX_TYPE, NDIM > oldSizes; - for( int d = 0; d < NDIM; ++d ) - { oldSizes[ d ] = randomInteger( 1, maxDimSize / 2 ); } + 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; + std::array< INDEX_TYPE, NDIM > newSizes = oldSizes; - array.resize( NDIM, oldSizes.data() ); + array.resize( NDIM, oldSizes.data() ); - fill( array ); + 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; + // 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 ); - } + // 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 ); } } } @@ -349,7 +332,7 @@ class ArrayTest : public ::testing::Test INDEX_TYPE const initialSize = array->size(); EXPECT_EQ( array->capacity(), initialSize ); - INDEX_TYPE const defaultDimSize = array->size( array->getSingleParameterResizeIndex() ); + INDEX_TYPE const defaultDimSize = array->size( 0 ); array->reserve( 2 * initialSize ); T const * const pointerAfterReserve = array->data(); @@ -394,7 +377,7 @@ class ArrayTest : public ::testing::Test EXPECT_EQ( array->data(), oldPointer ); for( int dim = 0; dim < NDIM; ++dim ) { - if( dim == array->getSingleParameterResizeIndex() ) + if( dim == 0 ) { EXPECT_EQ( array->size( dim ), 0 ); } @@ -404,7 +387,7 @@ class ArrayTest : public ::testing::Test } } - array->resize( oldSizes[ array->getSingleParameterResizeIndex() ] ); + array->resize( oldSizes[ 0 ] ); EXPECT_EQ( array->size(), oldSize ); EXPECT_EQ( array->capacity(), oldCapacity ); @@ -418,6 +401,20 @@ class ArrayTest : public ::testing::Test fill( *array ); } + template< typename IDX > + struct LayoutChecker + { + IDX const * data; + int dim = 0; + + template< typename T > + LVARRAY_HOST_DEVICE + void operator()( T && v ) + { + EXPECT_EQ( v, data[ dim++ ] ); + } + }; + static void checkIndexing() { ARRAY array; @@ -436,11 +433,11 @@ class ArrayTest : public ::testing::Test EXPECT_EQ( array.data(), getRAJAViewData( view ) ); RAJA::Layout< NDIM > const & layout = getRAJAViewLayout( view ); - for( int dim = 0; dim < NDIM; ++dim ) - { - EXPECT_EQ( array.size( dim ), layout.sizes[ dim ] ); - EXPECT_EQ( array.strides()[ dim ], layout.strides[ dim ] ); - } + // The following should work but produces host-device errors with nvcc-12.1: + // tupleManipulation::forEach( array.layout().extent(), [layout, dim] LVARRAY_HOST_DEVICE ( auto e ) mutable { EXPECT_EQ( e, layout.sizes[ dim++ ] ); } ); + // tupleManipulation::forEach( array.layout().stride(), [layout, dim] LVARRAY_HOST_DEVICE ( auto e ) mutable { EXPECT_EQ( e, layout.strides[ dim++ ] ); } ); + tupleManipulation::forEach( array.layout().extent(), LayoutChecker< typename RAJA::Layout< NDIM >::IndexLinear >{ layout.sizes } ); + tupleManipulation::forEach( array.layout().stride(), LayoutChecker< typename RAJA::Layout< NDIM >::IndexLinear >{ layout.strides } ); compareToRAJAView( array, view ); } diff --git a/unitTests/testArray1DOfArray1D.cpp b/unitTests/testArray1DOfArray1D.cpp index 7ff271cb..4ff091d0 100644 --- a/unitTests/testArray1DOfArray1D.cpp +++ b/unitTests/testArray1DOfArray1D.cpp @@ -34,11 +34,11 @@ template< typename U, typename T > struct ToArray1D {}; -template< typename U, typename T, int NDIM, typename PERM, typename INDEX_TYPE, template< typename > class BUFFER_TYPE > -struct ToArray1D< U, Array< T, NDIM, PERM, INDEX_TYPE, BUFFER_TYPE > > +template< typename U, typename T, typename EXTENT, typename PERM, template< typename > class BUFFER_TYPE > +struct ToArray1D< U, Array2< T, EXTENT, PERM, BUFFER_TYPE > > { using array = Array< U, 1, RAJA::PERM_I, INDEX_TYPE, BUFFER_TYPE >; - using view = ArrayView< U, 1, 0, INDEX_TYPE, BUFFER_TYPE >; + using view = ArrayView< U, 1, RAJA::PERM_I, INDEX_TYPE, BUFFER_TYPE >; }; template< typename ARRAY1D_POLICY_PAIR > diff --git a/unitTests/testArray1DOfArray1DOfArray1D.cpp b/unitTests/testArray1DOfArray1DOfArray1D.cpp index 5038d778..58a0b12a 100644 --- a/unitTests/testArray1DOfArray1DOfArray1D.cpp +++ b/unitTests/testArray1DOfArray1DOfArray1D.cpp @@ -34,11 +34,11 @@ template< typename U, typename T > struct ToArray1D {}; -template< typename U, typename T, int NDIM, typename PERM, typename INDEX_TYPE, template< typename > class BUFFER_TYPE > -struct ToArray1D< U, Array< T, NDIM, PERM, INDEX_TYPE, BUFFER_TYPE > > +template< typename U, typename T, typename EXTENT, typename PERM, template< typename > class BUFFER_TYPE > +struct ToArray1D< U, Array2< T, EXTENT, PERM, BUFFER_TYPE > > { using array = Array< U, 1, RAJA::PERM_I, INDEX_TYPE, BUFFER_TYPE >; - using view = ArrayView< U, 1, 0, INDEX_TYPE, BUFFER_TYPE >; + using view = ArrayView< U, 1, RAJA::PERM_I, INDEX_TYPE, BUFFER_TYPE >; }; template< typename ARRAY1D_POLICY_PAIR > diff --git a/unitTests/testArrayOfArrays.cpp b/unitTests/testArrayOfArrays.cpp index aa20086b..950e6077 100644 --- a/unitTests/testArrayOfArrays.cpp +++ b/unitTests/testArrayOfArrays.cpp @@ -921,10 +921,10 @@ template< typename U, typename T, typename INDEX_TYPE, template< typename > clas struct ToArray< U, ArrayOfArrays< T, INDEX_TYPE, BUFFER_TYPE > > { using OneD = Array< U, 1, RAJA::PERM_I, INDEX_TYPE, BUFFER_TYPE >; - using OneDView = ArrayView< U, 1, 0, INDEX_TYPE, BUFFER_TYPE >; + using OneDView = typename OneD::ViewType; using TwoD = Array< U, 2, RAJA::PERM_IJ, INDEX_TYPE, BUFFER_TYPE >; - using TwoDView = ArrayView< U, 2, 1, INDEX_TYPE, BUFFER_TYPE >; + using TwoDView = typename TwoD::ViewType; }; diff --git a/unitTests/testArrayOfSets.cpp b/unitTests/testArrayOfSets.cpp index ac71a76b..a5966bb5 100644 --- a/unitTests/testArrayOfSets.cpp +++ b/unitTests/testArrayOfSets.cpp @@ -32,7 +32,7 @@ template< typename U, typename T, typename INDEX_TYPE, template< typename > clas struct ToArray< U, ArrayOfSets< T, INDEX_TYPE, BUFFER_TYPE > > { using OneD = Array< U, 1, RAJA::PERM_I, INDEX_TYPE, BUFFER_TYPE >; - using OneDView = ArrayView< U, 1, 0, INDEX_TYPE, BUFFER_TYPE >; + using OneDView = typename OneD::ViewType; using AoA = ArrayOfArrays< U, INDEX_TYPE, BUFFER_TYPE >; }; diff --git a/unitTests/testArrayView.hpp b/unitTests/testArrayView.hpp index 961723b8..98d4cfc7 100644 --- a/unitTests/testArrayView.hpp +++ b/unitTests/testArrayView.hpp @@ -299,18 +299,11 @@ class ArrayViewPolicyTest : public ArrayViewTest< typename ARRAY_POLICY_PAIR::fi T * const hostPointer = array->data(); array->move( RAJAHelper< POLICY >::space, false ); T const * const devicePointer = array->data(); + auto layout = array->layout(); - 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 ) + forall< POLICY >( array->size( 0 ), [devicePointer, layout] LVARRAY_HOST_DEVICE ( INDEX_TYPE const i ) { - SliceTypeConst slice( devicePointer, sizes, strides ); + SliceTypeConst slice( devicePointer, layout ); checkFillDevice( slice, i ); } ); @@ -481,7 +474,7 @@ class ArrayViewPolicyTest : public ArrayViewTest< typename ARRAY_POLICY_PAIR::fi ARRAY array; std::unique_ptr< ARRAY > arrayToCopy = ParentClass::sizedConstructor(); - array.resize( NDIM, arrayToCopy->dims() ); + array.resize( arrayToCopy->layout().extent() ); T const * const initialPtr = array.data(); ViewTypeConst const viewToCopy = arrayToCopy->toViewConst(); @@ -507,7 +500,7 @@ class ArrayViewPolicyTest : public ArrayViewTest< typename ARRAY_POLICY_PAIR::fi template< typename ARRAY > class CheckIndices { -public: + public: LVARRAY_HOST_DEVICE CheckIndices( ARRAY const slice, INDEX_TYPE const i ): m_slice( slice ), m_i( i ) @@ -520,7 +513,7 @@ class ArrayViewPolicyTest : public ArrayViewTest< typename ARRAY_POLICY_PAIR::fi PORTABLE_EXPECT_EQ( &value, &m_slice( m_i, indices ... ) ); } -private: + private: ARRAY const m_slice; INDEX_TYPE const m_i; }; @@ -529,10 +522,10 @@ class ArrayViewPolicyTest : public ArrayViewTest< typename ARRAY_POLICY_PAIR::fi 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, + //template< int DIM, int USD > + static LVARRAY_HOST_DEVICE void checkFillDevice( SliceTypeConst const slice, INDEX_TYPE const i ) - { forValuesInSliceWithIndices( slice[ i ], CheckIndices< ArraySlice< T const, DIM, USD, INDEX_TYPE > >( slice, i ) ); } + { forValuesInSliceWithIndices( slice[ i ], CheckIndices< SliceTypeConst >( slice, i ) ); } }; using ArrayViewPolicyTestTypes = ::testing::Types< diff --git a/unitTests/testArrayView_typeConversion.cpp b/unitTests/testArrayView_typeConversion.cpp index 9223c8ba..beae98a1 100644 --- a/unitTests/testArrayView_typeConversion.cpp +++ b/unitTests/testArrayView_typeConversion.cpp @@ -22,19 +22,19 @@ void testTypeConversion() { { Array< int, 1, RAJA::PERM_I, int, BUFFER_TYPE > array( 20 ); - ArrayView< int[ 4 ], 1, 0, int, BUFFER_TYPE > const view4( array ); + ArrayView< int[ 4 ], 1, RAJA::PERM_I, int, BUFFER_TYPE > const view4( array ); EXPECT_EQ( view4.size(), array.size() / 4 ); EXPECT_EQ( reinterpret_cast< int * >( view4.data() ), array.data() ); - ArrayView< int[ 2 ], 1, 0, int, BUFFER_TYPE > const view2( view4 ); + ArrayView< int[ 2 ], 1, RAJA::PERM_I, int, BUFFER_TYPE > const view2( view4 ); EXPECT_EQ( view2.size(), array.size() / 2 ); EXPECT_EQ( reinterpret_cast< int * >( view2.data() ), array.data() ); } { Array< int, 2, RAJA::PERM_IJ, int, BUFFER_TYPE > array( 10, 20 ); - ArrayView< int[ 4 ], 2, 1, int, BUFFER_TYPE > const view4( array ); + ArrayView< int[ 4 ], 2, RAJA::PERM_IJ, int, BUFFER_TYPE > const view4( array ); EXPECT_EQ( view4.size(), array.size() / 4 ); EXPECT_EQ( view4.size( 0 ), array.size( 0 ) ); EXPECT_EQ( view4.size( 1 ), array.size( 1 ) / 4 ); @@ -50,7 +50,7 @@ void testTypeConversion() } } - ArrayView< int[ 2 ], 2, 1, int, BUFFER_TYPE > view2( view4 ); + ArrayView< int[ 2 ], 2, RAJA::PERM_IJ, int, BUFFER_TYPE > view2( view4 ); EXPECT_EQ( view2.size(), array.size() / 2 ); EXPECT_EQ( view2.size( 0 ), array.size( 0 ) ); EXPECT_EQ( view2.size( 1 ), array.size( 1 ) / 2 ); @@ -69,7 +69,7 @@ void testTypeConversion() { Array< int, 3, RAJA::PERM_KJI, int, BUFFER_TYPE > array( 8, 10, 11 ); - ArrayView< int[ 4 ], 3, 0, int, BUFFER_TYPE > const view4( array ); + ArrayView< int[ 4 ], 3, RAJA::PERM_KJI, int, BUFFER_TYPE > const view4( array ); EXPECT_EQ( view4.size(), array.size() / 4 ); EXPECT_EQ( view4.size( 0 ), array.size( 0 ) / 4 ); EXPECT_EQ( view4.size( 1 ), array.size( 1 ) ); @@ -89,7 +89,7 @@ void testTypeConversion() } } - ArrayView< int[ 2 ], 3, 0, int, BUFFER_TYPE > const view2( view4 ); + ArrayView< int[ 2 ], 3, RAJA::PERM_KJI, int, BUFFER_TYPE > const view2( view4 ); EXPECT_EQ( view2.size(), array.size() / 2 ); EXPECT_EQ( view2.size( 0 ), array.size( 0 ) / 2 ); EXPECT_EQ( view2.size( 1 ), array.size( 1 ) ); diff --git a/unitTests/testArray_getSetSingleParameterResizeIndex.cpp b/unitTests/testArray_getSetSingleParameterResizeIndex.cpp deleted file mode 100644 index ad5e857e..00000000 --- a/unitTests/testArray_getSetSingleParameterResizeIndex.cpp +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2021, Lawrence Livermore National Security, LLC and LvArray contributors. - * All rights reserved. - * See the LICENSE file for details. - * SPDX-License-Identifier: (BSD-3-Clause) - */ - -// 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/testConstant.cpp b/unitTests/testConstant.cpp new file mode 100644 index 00000000..8b2e32ad --- /dev/null +++ b/unitTests/testConstant.cpp @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2021, Lawrence Livermore National Security, LLC and LvArray contributors. + * All rights reserved. + * See the LICENSE file for details. + * SPDX-License-Identifier: (BSD-3-Clause) + */ + +// Source includes +#include "Constant.hpp" + +// TPL includes +#include + +namespace LvArray +{ + +static_assert( !is_constant_v< int > ); +static_assert( is_constant_v< _0 > ); +static_assert( is_constant_v< _1 > ); +static_assert( is_constant_v< _t > ); +static_assert( is_constant_v< _f > ); + +static_assert( is_constant_value_v< 0, _0 > ); +static_assert( is_constant_value_v< 1, _1 > ); +static_assert( is_constant_value_v< 345, Constant< int, 345 > > ); +static_assert( is_constant_value_v< true, _t > ); +static_assert( is_constant_value_v< false, _f > ); + +static_assert( std::is_same_v< decltype( _0{} + _0{} ), _0 > ); +static_assert( std::is_same_v< decltype( _0{} + _1{} ), _1 > ); +static_assert( std::is_same_v< decltype( _1{} + _0{} ), _1 > ); +static_assert( std::is_same_v< decltype( _1{} + _1{} ), _2 > ); +static_assert( std::is_same_v< decltype( _2{} + _1{} ), _3 > ); +static_assert( std::is_same_v< decltype( _1{} + _1{} + _1{} ), _3 > ); + +static_assert( std::is_same_v< decltype( _0{} + 0 ), int > ); +static_assert( std::is_same_v< decltype( 0 + _0{} ), int > ); +static_assert( std::is_same_v< decltype( _1{} + 0 ), int > ); +static_assert( std::is_same_v< decltype( 0 + _1{} ), int > ); + +static_assert( std::is_same_v< decltype( _0{} - _0{} ), _0 > ); +static_assert( std::is_same_v< decltype( _1{} - _0{} ), _1 > ); +static_assert( std::is_same_v< decltype( _0{} - _1{} ), Constant< int, -1 > > ); +static_assert( std::is_same_v< decltype( _1{} - _1{} ), _0 > ); + +static_assert( std::is_same_v< decltype( _0{} * _0{} ), _0 > ); +static_assert( std::is_same_v< decltype( _0{} * _1{} ), _0 > ); +static_assert( std::is_same_v< decltype( _1{} * _0{} ), _0 > ); +static_assert( std::is_same_v< decltype( _1{} * _1{} ), _1 > ); +static_assert( std::is_same_v< decltype( _0{} * 1 ), _0 > ); +static_assert( std::is_same_v< decltype( 1 * _0{} ), _0 > ); + +static_assert( std::is_same_v< decltype( _0{} / _1{} ), _0 > ); +static_assert( std::is_same_v< decltype( _1{} / _1{} ), _1 > ); +static_assert( std::is_same_v< decltype( _2{} / _1{} ), _2 > ); +static_assert( std::is_same_v< decltype( _2{} / _3{} ), _0 > ); +static_assert( std::is_same_v< decltype( _4{} / _3{} ), _1 > ); + +static_assert( std::is_same_v< decltype( _0{} % _1{} ), _0 > ); +static_assert( std::is_same_v< decltype( _1{} % _1{} ), _0 > ); +static_assert( std::is_same_v< decltype( _2{} % _1{} ), _0 > ); +static_assert( std::is_same_v< decltype( _2{} % _3{} ), _2 > ); +static_assert( std::is_same_v< decltype( _4{} % _3{} ), _1 > ); +static_assert( std::is_same_v< decltype( _4{} % _2{} ), _0 > ); + +static_assert( std::is_same_v< decltype( _0{} == _0{} ), _t > ); +static_assert( std::is_same_v< decltype( _0{} != _0{} ), _f > ); +static_assert( std::is_same_v< decltype( _0{} == _1{} ), _f > ); +static_assert( std::is_same_v< decltype( _0{} != _1{} ), _t > ); +static_assert( std::is_same_v< decltype( _0{} < _1{} ), _t > ); +static_assert( std::is_same_v< decltype( _0{} <= _1{} ), _t > ); +static_assert( std::is_same_v< decltype( _1{} <= _1{} ), _t > ); +static_assert( std::is_same_v< decltype( _1{} < _0{} ), _f > ); +static_assert( std::is_same_v< decltype( _1{} <= _0{} ), _f > ); +static_assert( std::is_same_v< decltype( _1{} > _0{} ), _t > ); +static_assert( std::is_same_v< decltype( _1{} >= _0{} ), _t > ); +static_assert( std::is_same_v< decltype( _0{} > _0{} ), _f > ); +static_assert( std::is_same_v< decltype( _0{} >= _1{} ), _f > ); + +using namespace literals; + +static_assert( std::is_same_v< decltype( 0_Ci ), Constant< int, 0 > > ); +static_assert( std::is_same_v< decltype( 1_Ci ), Constant< int, 1 > > ); +static_assert( std::is_same_v< decltype( 345_Ci ), Constant< int, 345 > > ); + +static_assert( std::is_same_v< decltype( 0_Cull ), Constant< unsigned long long, 0 > > ); +static_assert( std::is_same_v< decltype( 1_Cull ), Constant< unsigned long long, 1 > > ); +static_assert( std::is_same_v< decltype( 345_Cull ), Constant< unsigned long long, 345 > > ); + +} // namespace LvArray + +int main( int argc, char * * argv ) +{ + ::testing::InitGoogleTest( &argc, argv ); + int const result = RUN_ALL_TESTS(); + return result; +} diff --git a/unitTests/testInvalidOperations.cpp b/unitTests/testInvalidOperations.cpp index b421fffa..a1b24c8b 100644 --- a/unitTests/testInvalidOperations.cpp +++ b/unitTests/testInvalidOperations.cpp @@ -44,7 +44,7 @@ template< typename T > using ArrayT2D = Array< T, 2, RAJA::PERM_IJ, std::ptrdiff_t, MallocBuffer >; template< typename T > -using ArrayViewT = ArrayView< T, 1, 0, std::ptrdiff_t, MallocBuffer >; +using ArrayViewT = ArrayView< T, 1, RAJA::PERM_I, std::ptrdiff_t, MallocBuffer >; template< typename T > using ArraySliceT = ArraySlice< T, 1, 0, std::ptrdiff_t >; @@ -70,7 +70,7 @@ static_assert( !std::is_convertible< ArrayViewT< int > &&, ArraySliceT< int > >: "The conversion from an ArrayView< T > rvalue to an ArraySlice< T > is not allowed." ); static_assert( !std::is_convertible< ArrayViewT< int > &&, ArraySliceT< int const > >::value, "The conversion from an ArrayView< T > rvalue to an ArraySlice< T const > is not allowed." ); -static_assert( !HasRvalueSubscriptOperator< ArrayView< int, 2, 1, std::ptrdiff_t, MallocBuffer > >, +static_assert( !HasRvalueSubscriptOperator< ArrayView< int, 2, RAJA::PERM_IJ, std::ptrdiff_t, MallocBuffer > >, "The subscript operator on a multidimensional ArrayView rvalue is not allowed." ); // SortedArrayView diff --git a/unitTests/testLayout.cpp b/unitTests/testLayout.cpp new file mode 100644 index 00000000..fde1efd7 --- /dev/null +++ b/unitTests/testLayout.cpp @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2021, Lawrence Livermore National Security, LLC and LvArray contributors. + * All rights reserved. + * See the LICENSE file for details. + * SPDX-License-Identifier: (BSD-3-Clause) + */ + +// Source includes +#include "Layout.hpp" + +// TPL includes +#include + +namespace LvArray +{ + +static_assert( std::is_same_v< _1, decltype( product( makeTuple() ) ) > ); +static_assert( std::is_same_v< _0, decltype( product( makeTuple( _0{} ) ) ) > ); +static_assert( std::is_same_v< _0, decltype( product( makeTuple( _0{}, _2{} ) ) ) > ); +static_assert( std::is_same_v< _2, decltype( product( makeTuple( _1{}, _2{} ) ) ) > ); +static_assert( std::is_same_v< _6, decltype( product( makeTuple( _1{}, _2{}, _3{} ) ) ) > ); +static_assert( std::is_same_v< int, decltype( product( makeTuple( _1{}, 2, _3{} ) ) ) > ); + +static_assert( std::is_same_v< _0, decltype( innerProduct( makeTuple(), makeTuple() ) ) > ); +static_assert( std::is_same_v< _0, decltype( innerProduct( makeTuple( _0{} ), makeTuple( _1{} ) ) ) > ); +static_assert( std::is_same_v< _0, decltype( innerProduct( makeTuple( _1{} ), makeTuple( _0{} ) ) ) > ); +static_assert( std::is_same_v< _1, decltype( innerProduct( makeTuple( _1{} ), makeTuple( _1{} ) ) ) > ); +static_assert( std::is_same_v< _4, decltype( innerProduct( makeTuple( _2{} ), makeTuple( _2{} ) ) ) > ); +static_assert( std::is_same_v< _1, decltype( innerProduct( makeTuple( _1{}, _0{} ), makeTuple( _1{}, _1{} ) ) ) > ); +static_assert( std::is_same_v< _1, decltype( innerProduct( makeTuple( _1{}, _1{} ), makeTuple( _0{}, _1{} ) ) ) > ); +static_assert( std::is_same_v< _1, decltype( innerProduct( makeTuple( _1{}, _1{} ), makeTuple( _0{}, _1{} ) ) ) > ); +static_assert( std::is_same_v< _2, decltype( innerProduct( makeTuple( _1{}, _1{} ), makeTuple( _1{}, _1{} ) ) ) > ); +static_assert( std::is_same_v< _4, decltype( innerProduct( makeTuple( _2{}, _1{} ), makeTuple( _1{}, _2{} ) ) ) > ); +static_assert( std::is_same_v< _6, decltype( innerProduct( makeTuple( _2{}, _3{}, _1{} ), makeTuple( _2{}, _0{}, _2{} ) ) ) > ); +static_assert( std::is_same_v< int, decltype( innerProduct( makeTuple( _2{}, 1 ), makeTuple( _1{}, _2{} ) ) ) > ); +static_assert( std::is_same_v< int, decltype( innerProduct( makeTuple( _2{}, _1{} ), makeTuple( _1{}, 2 ) ) ) > ); +static_assert( std::is_same_v< int, decltype( innerProduct( makeTuple( 1, 1 ), makeTuple( 1, 2 ) ) ) > ); + +static_assert( std::is_same_v< DynamicExtent< 0, int >, Extent<> > ); +static_assert( std::is_same_v< DynamicExtent< 1, int >, Extent< int > > ); +static_assert( std::is_same_v< DynamicExtent< 2, int >, Extent< int, int > > ); +static_assert( std::is_same_v< DynamicExtent< 3, int >, Extent< int, int, int > > ); + +static_assert( std::is_same_v< Stride< _1 >, CompactStride< LayoutLeft, Extent< _0 > > > ); +static_assert( std::is_same_v< Stride< _1 >, CompactStride< LayoutLeft, Extent< _1 > > > ); +static_assert( std::is_same_v< Stride< _1, _2 >, CompactStride< LayoutLeft, Extent< _2, _3 > > > ); +static_assert( std::is_same_v< Stride< _1, _2 >, CompactStride< LayoutLeft, Extent< _2, _3 >, camp::idx_seq< 0, 1 > > > ); +static_assert( std::is_same_v< Stride< _3, _1 >, CompactStride< LayoutLeft, Extent< _2, _3 >, camp::idx_seq< 1, 0 > > > ); +static_assert( std::is_same_v< Stride< _1, _2, _2 >, CompactStride< LayoutLeft, Extent< _2, _1, _3 >, camp::idx_seq< 0, 1, 2 > > > ); +static_assert( std::is_same_v< Stride< _3, _6, _1 >, CompactStride< LayoutLeft, Extent< _2, _1, _3 >, camp::idx_seq< 2, 0, 1 > > > ); +static_assert( std::is_same_v< Stride< _3, _3, _1 >, CompactStride< LayoutLeft, Extent< _2, _1, _3 >, camp::idx_seq< 2, 1, 0 > > > ); +static_assert( std::is_same_v< Stride< _3, _1, _1 >, CompactStride< LayoutLeft, Extent< _2, _1, _3 >, camp::idx_seq< 1, 2, 0 > > > ); + +static_assert( std::is_same_v< Stride< _1 >, CompactStride< LayoutRight, Extent< _0 > > > ); +static_assert( std::is_same_v< Stride< _1 >, CompactStride< LayoutRight, Extent< _1 > > > ); +static_assert( std::is_same_v< Stride< _3, _1 >, CompactStride< LayoutRight, Extent< _2, _3 > > > ); +static_assert( std::is_same_v< Stride< _3, _1 >, CompactStride< LayoutRight, Extent< _2, _3 >, camp::idx_seq< 0, 1 > > > ); +static_assert( std::is_same_v< Stride< _1, _2 >, CompactStride< LayoutRight, Extent< _2, _3 >, camp::idx_seq< 1, 0 > > > ); +static_assert( std::is_same_v< Stride< _3, _3, _1 >, CompactStride< LayoutRight, Extent< _2, _1, _3 >, camp::idx_seq< 0, 1, 2 > > > ); +static_assert( std::is_same_v< Stride< _1, _1, _2 >, CompactStride< LayoutRight, Extent< _2, _1, _3 >, camp::idx_seq< 2, 0, 1 > > > ); +static_assert( std::is_same_v< Stride< _1, _2, _2 >, CompactStride< LayoutRight, Extent< _2, _1, _3 >, camp::idx_seq< 2, 1, 0 > > > ); +static_assert( std::is_same_v< Stride< _1, _6, _2 >, CompactStride< LayoutRight, Extent< _2, _1, _3 >, camp::idx_seq< 1, 2, 0 > > > ); + +static_assert( std::is_same_v< Layout< Extent< _4 >, Stride< _1 > >, decltype( makeLayout( makeExtent( _4{} ) ) ) > ); +static_assert( std::is_same_v< Layout< Extent< _4, _2 >, Stride< _2, _1 > >, decltype( makeLayout( makeExtent( _4{}, _2{} ) ) ) > ); +static_assert( std::is_same_v< Layout< Extent< _4, _0 >, Stride< _0, _1 > >, decltype( makeLayout( makeExtent( _4{}, _0{} ) ) ) > ); +static_assert( std::is_same_v< Layout< Extent< _1, _2, _3 >, Stride< _6, _3, _1 > >, decltype( makeLayout( makeExtent( _1{}, _2{}, _3{} ) ) ) > ); +static_assert( std::is_same_v< Layout< Extent< _4, int >, Stride< int, _1 > >, decltype( makeLayout( makeExtent( _4{}, 4 ) ) ) > ); +static_assert( std::is_same_v< Layout< Extent< int, _4 >, Stride< _4, _1 > >, decltype( makeLayout( makeExtent( 4, _4{} ) ) ) > ); + +using TestLayout = Layout< Extent< _1, _2, _3 > >; +static_assert( std::is_same_v< Layout< Extent< _1, _2, _3 >, Stride< _6, _3, _1 > >, TestLayout > ); + +static_assert( std::is_same_v< _0, decltype( TestLayout{}( _0{}, _0{}, _0{} ) ) > ); +static_assert( std::is_same_v< _1, decltype( TestLayout{}( _0{}, _0{}, _1{} ) ) > ); +static_assert( std::is_same_v< _3, decltype( TestLayout{}( _0{}, _1{}, _0{} ) ) > ); +static_assert( std::is_same_v< _6, decltype( TestLayout{}( _1{}, _0{}, _0{} ) ) > ); +static_assert( std::is_same_v< _5, decltype( TestLayout{}( _0{}, _1{}, _2{} ) ) > ); +static_assert( std::is_same_v< _3, decltype( TestLayout{}( _0{}, _1{}, _{} ) ) > ); +static_assert( std::is_same_v< _6, decltype( TestLayout{}( _1{}, _{}, _{} ) ) > ); +static_assert( std::is_same_v< _6, decltype( TestLayout{}( _{}, _2{}, _{} ) ) > ); +static_assert( std::is_same_v< _3, decltype( TestLayout{}( _{}, _{}, _3{} ) ) > ); +static_assert( std::is_same_v< _0, decltype( TestLayout{}( _{}, _{}, _{} ) ) > ); +static_assert( std::is_same_v< _6, decltype( TestLayout{}( _1{} ) ) > ); +static_assert( std::is_same_v< _9, decltype( TestLayout{}( _1{}, _1{} ) ) > ); + +static_assert( std::is_same_v< Layout< Extent<>, Stride<> >, decltype( TestLayout{}.slice( _1{}, _1{}, _2{} ) ) > ); +static_assert( std::is_same_v< Layout< Extent< _3 >, Stride< _1 > >, decltype( TestLayout{}.slice( _1{}, _1{}, _{} ) ) > ); +static_assert( std::is_same_v< Layout< Extent< _2 >, Stride< _3 > >, decltype( TestLayout{}.slice( _1{}, _{}, _1{} ) ) > ); +static_assert( std::is_same_v< Layout< Extent< _1 >, Stride< _6 > >, decltype( TestLayout{}.slice( _{}, _1{}, _1{} ) ) > ); +static_assert( std::is_same_v< Layout< Extent< _1, _2 >, Stride< _6, _3 > >, decltype( TestLayout{}.slice( _{}, _{}, _1{} ) ) > ); +static_assert( std::is_same_v< Layout< Extent< _1, _3 >, Stride< _6, _1 > >, decltype( TestLayout{}.slice( _{}, _1{}, _{} ) ) > ); +static_assert( std::is_same_v< Layout< Extent< _2, _3 >, Stride< _3, _1 > >, decltype( TestLayout{}.slice( _1{}, _{}, _{} ) ) > ); +static_assert( std::is_same_v< TestLayout, decltype( TestLayout{}.slice( _{}, _{}, _{} ) ) > ); +static_assert( std::is_same_v< Layout< Extent< _2, _3 >, Stride< _3, _1 > >, decltype( TestLayout{}.slice( _1{} ) ) > ); +static_assert( std::is_same_v< Layout< Extent< _3 >, Stride< _1 > >, decltype( TestLayout{}.slice( _1{}, _1{} ) ) > ); + +static_assert( std::is_same_v< Layout< Extent< _8 >, Stride< _1 > >, decltype( Layout< Extent< _2 >, Stride< _1 > >{}.downcast< 4 >() ) > ); +static_assert( std::is_same_v< Layout< Extent< _3, _8 >, Stride< _8, _1 > >, decltype( Layout< Extent< _3, _2 >, Stride< _2, _1 > >{}.downcast< 4 >() ) > ); +static_assert( std::is_same_v< TestLayout, decltype( TestLayout{}.downcast< 1 >() ) > ); +static_assert( std::is_same_v< Layout< Extent< _1, _2, _6 >, Stride< _12, _6, _1 > >, decltype( TestLayout{}.downcast< 2 >() ) > ); +static_assert( std::is_same_v< Layout< Extent< _1, _2, _9 >, Stride< Constant< int, 18 >, _9, _1 > >, decltype( TestLayout{}.downcast< 3 >() ) > ); + +static_assert( 0 == Layout< Extent<>, Stride<> >::NDIM ); +static_assert( 1 == Layout< Extent< _2 >, Stride< _1 > >::NDIM ); +static_assert( 2 == Layout< Extent< _2, _3 >, Stride< _1, _2 > >::NDIM ); +static_assert( 2 == Layout< Extent< int, int >, Stride< int, _1 > >::NDIM ); + +static_assert( -1 == Layout< Extent<>, Stride<> >::USD ); +static_assert( 0 == Layout< Extent< _2 >, Stride< _1 > >::USD ); +static_assert( 0 == Layout< Extent< _2, _3 >, Stride< _1, _2 > >::USD ); +static_assert( 0 == Layout< Extent< int, int >, Stride< _1, int > >::USD ); +static_assert( 1 == Layout< Extent< int, int >, Stride< int, _1 > >::USD ); +static_assert( -1 == Layout< Extent< int, int >, Stride< int, int > >::USD ); +static_assert( 1 == Layout< Extent< int, int, int >, Stride< int, _1, int > >::USD ); + +static_assert( std::is_assignable_v< TestLayout, TestLayout > ); + +} // namespace LvArray + +int main( int argc, char * * argv ) +{ + ::testing::InitGoogleTest( &argc, argv ); + int const result = RUN_ALL_TESTS(); + return result; +} diff --git a/unitTests/testSliceHelpers.cpp b/unitTests/testSliceHelpers.cpp index 33ff5d81..79529924 100644 --- a/unitTests/testSliceHelpers.cpp +++ b/unitTests/testSliceHelpers.cpp @@ -22,62 +22,89 @@ using INDEX_TYPE = std::ptrdiff_t; template< typename T, typename PERMUTATION > using ArrayT = Array< T, typeManipulation::getDimension< PERMUTATION >, PERMUTATION, INDEX_TYPE, DEFAULT_BUFFER >; -template< typename T > -void check( ArraySlice< T const, 1, 0, INDEX_TYPE > const slice ) +//template< typename T > +//void check( ArraySlice< T const, 1, 0, INDEX_TYPE > const slice ) +//{ +// INDEX_TYPE offset = 0; +// for( INDEX_TYPE i = 0; i < slice.size( 0 ); ++i ) +// { +// EXPECT_EQ( slice( i ), offset++ ); +// } +//} +// +//template< typename T, int USD > +//void check( ArraySlice< T const, 2, USD, INDEX_TYPE > const slice ) +//{ +// INDEX_TYPE offset = 0; +// for( INDEX_TYPE i = 0; i < slice.size( 0 ); ++i ) +// { +// for( INDEX_TYPE j = 0; j < slice.size( 1 ); ++j ) +// { +// EXPECT_EQ( slice( i, j ), offset++ ); +// } +// } +//} +// +//template< typename T, int USD > +//void check( ArraySlice< T const, 3, USD, INDEX_TYPE > const slice ) +//{ +// INDEX_TYPE offset = 0; +// for( INDEX_TYPE i = 0; i < slice.size( 0 ); ++i ) +// { +// for( INDEX_TYPE j = 0; j < slice.size( 1 ); ++j ) +// { +// for( INDEX_TYPE k = 0; k < slice.size( 2 ); ++k ) +// { +// EXPECT_EQ( slice( i, j, k ), offset++ ); +// } +// } +// } +//} +// +//template< typename T, int USD > +//void check( ArraySlice< T const, 4, USD, INDEX_TYPE > const slice ) +//{ +// INDEX_TYPE offset = 0; +// for( INDEX_TYPE i = 0; i < slice.size( 0 ); ++i ) +// { +// for( INDEX_TYPE j = 0; j < slice.size( 1 ); ++j ) +// { +// for( INDEX_TYPE k = 0; k < slice.size( 2 ); ++k ) +// { +// for( INDEX_TYPE l = 0; l < slice.size( 3 ); ++l ) +// { +// EXPECT_EQ( slice( i, j, k, l ), offset++ ); +// } +// } +// } +// } +//} + +namespace internal { - INDEX_TYPE offset = 0; - for( INDEX_TYPE i = 0; i < slice.size( 0 ); ++i ) - { - EXPECT_EQ( slice( i ), offset++ ); - } -} -template< typename T, int USD > -void check( ArraySlice< T const, 2, USD, INDEX_TYPE > const slice ) +template< typename T > +void check( T value, T & offset ) { - INDEX_TYPE offset = 0; - for( INDEX_TYPE i = 0; i < slice.size( 0 ); ++i ) - { - for( INDEX_TYPE j = 0; j < slice.size( 1 ); ++j ) - { - EXPECT_EQ( slice( i, j ), offset++ ); - } - } + EXPECT_EQ( value, offset++ ); } -template< typename T, int USD > -void check( ArraySlice< T const, 3, USD, INDEX_TYPE > const slice ) +template< typename T, typename LAYOUT > +void check( ArraySlice2< T const, LAYOUT > const slice, T & offset ) { - INDEX_TYPE offset = 0; - for( INDEX_TYPE i = 0; i < slice.size( 0 ); ++i ) + for( typename LAYOUT::IndexType i = 0; i < slice.template size< 0 >(); ++i ) { - for( INDEX_TYPE j = 0; j < slice.size( 1 ); ++j ) - { - for( INDEX_TYPE k = 0; k < slice.size( 2 ); ++k ) - { - EXPECT_EQ( slice( i, j, k ), offset++ ); - } - } + check( slice( i ), offset ); } } -template< typename T, int USD > -void check( ArraySlice< T const, 4, USD, INDEX_TYPE > const slice ) +} // namespace internal + +template< typename T, typename LAYOUT > +void check( ArraySlice2< T const, LAYOUT > const slice ) { - INDEX_TYPE offset = 0; - for( INDEX_TYPE i = 0; i < slice.size( 0 ); ++i ) - { - for( INDEX_TYPE j = 0; j < slice.size( 1 ); ++j ) - { - for( INDEX_TYPE k = 0; k < slice.size( 2 ); ++k ) - { - for( INDEX_TYPE l = 0; l < slice.size( 3 ); ++l ) - { - EXPECT_EQ( slice( i, j, k, l ), offset++ ); - } - } - } - } + T offset = 0; + internal::check( slice, offset ); } template< typename ARRAY > @@ -165,61 +192,95 @@ TEST( ForValuesInSlice, scalar ) } -template< typename T, int USD_SRC > -void checkSums( ArraySlice< T const, 2, USD_SRC, INDEX_TYPE > const src, - ArraySlice< T const, 1, 0, INDEX_TYPE > const sums ) +//template< typename T, int USD_SRC > +//void checkSums( ArraySlice< T const, 2, USD_SRC, INDEX_TYPE > const src, +// ArraySlice< T const, 1, 0, INDEX_TYPE > const sums ) +//{ +// for( INDEX_TYPE j = 0; j < src.size( 1 ); ++j ) +// { +// T sum {}; +// for( INDEX_TYPE i = 0; i < src.size( 0 ); ++i ) +// { +// sum += src( i, j ); +// } +// +// EXPECT_EQ( sum, sums( j ) ); +// } +//} +// +//template< typename T, int USD_SRC, int USD_SUMS > +//void checkSums( ArraySlice< T const, 3, USD_SRC, INDEX_TYPE > const src, +// ArraySlice< T const, 2, USD_SUMS, INDEX_TYPE > const sums ) +//{ +// for( INDEX_TYPE j = 0; j < src.size( 1 ); ++j ) +// { +// for( INDEX_TYPE k = 0; k < src.size( 2 ); ++k ) +// { +// T sum {}; +// for( INDEX_TYPE i = 0; i < src.size( 0 ); ++i ) +// { +// sum += src( i, j, k ); +// } +// +// EXPECT_EQ( sum, sums( j, k ) ); +// } +// } +//} +// +//template< typename T, int USD_SRC, int USD_SUMS > +//void checkSums( ArraySlice< T const, 4, USD_SRC, INDEX_TYPE > const src, +// ArraySlice< T const, 3, USD_SUMS, INDEX_TYPE > const sums ) +//{ +// for( INDEX_TYPE j = 0; j < src.size( 1 ); ++j ) +// { +// for( INDEX_TYPE k = 0; k < src.size( 2 ); ++k ) +// { +// for( INDEX_TYPE l = 0; l < src.size( 3 ); ++l ) +// { +// T sum {}; +// for( INDEX_TYPE i = 0; i < src.size( 0 ); ++i ) +// { +// sum += src( i, j, k, l ); +// } +// +// EXPECT_EQ( sum, sums( j, k, l ) ); +// } +// } +// } +//} + +namespace internal { - for( INDEX_TYPE j = 0; j < src.size( 1 ); ++j ) - { - T sum {}; - for( INDEX_TYPE i = 0; i < src.size( 0 ); ++i ) - { - sum += src( i, j ); - } - EXPECT_EQ( sum, sums( j ) ); +template< typename T, typename LAYOUT, std::enable_if_t< LAYOUT::NDIM == 1 >* = nullptr > +void checkSums( ArraySlice2< T const, LAYOUT > const src, T const & sums ) +{ + T sum {}; + for( INDEX_TYPE i = 0; i < src.template size< 0 >(); ++i ) + { + sum += src( i ); } + EXPECT_EQ( sum, sums ); } -template< typename T, int USD_SRC, int USD_SUMS > -void checkSums( ArraySlice< T const, 3, USD_SRC, INDEX_TYPE > const src, - ArraySlice< T const, 2, USD_SUMS, INDEX_TYPE > const sums ) +template< typename T, typename LAYOUT, typename LAYOUT_SUMS, std::enable_if_t< LAYOUT::NDIM != 1 >* = nullptr > +void checkSums( ArraySlice2< T const, LAYOUT > const src, + ArraySlice2< T const, LAYOUT_SUMS > const sums ) { - for( INDEX_TYPE j = 0; j < src.size( 1 ); ++j ) + for( INDEX_TYPE i = 0; i < src.template size< 1 >(); ++i ) { - for( INDEX_TYPE k = 0; k < src.size( 2 ); ++k ) - { - T sum {}; - for( INDEX_TYPE i = 0; i < src.size( 0 ); ++i ) - { - sum += src( i, j, k ); - } - - EXPECT_EQ( sum, sums( j, k ) ); - } + internal::checkSums( src( _{}, i ), sums( i ) ); } } -template< typename T, int USD_SRC, int USD_SUMS > -void checkSums( ArraySlice< T const, 4, USD_SRC, INDEX_TYPE > const src, - ArraySlice< T const, 3, USD_SUMS, INDEX_TYPE > const sums ) +} + +template< typename T, typename LAYOUT, typename LAYOUT_SUMS > +void checkSums( ArraySlice2< T const, LAYOUT > const src, + ArraySlice2< T const, LAYOUT_SUMS > const sums ) { - for( INDEX_TYPE j = 0; j < src.size( 1 ); ++j ) - { - for( INDEX_TYPE k = 0; k < src.size( 2 ); ++k ) - { - for( INDEX_TYPE l = 0; l < src.size( 3 ); ++l ) - { - T sum {}; - for( INDEX_TYPE i = 0; i < src.size( 0 ); ++i ) - { - sum += src( i, j, k, l ); - } - - EXPECT_EQ( sum, sums( j, k, l ) ); - } - } - } + static_assert( LAYOUT_SUMS::NDIM == LAYOUT::NDIM - 1, "Invalid number of dimensions" ); + internal::checkSums( src, sums ); } template< typename ARRAY_PERM_PAIR > diff --git a/unitTests/testSortedArrayManipulation.cpp b/unitTests/testSortedArrayManipulation.cpp index ae376cb4..63ed5db8 100644 --- a/unitTests/testSortedArrayManipulation.cpp +++ b/unitTests/testSortedArrayManipulation.cpp @@ -32,7 +32,7 @@ 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 >; +using ArrayView1D = ArrayView< T, 1, RAJA::PERM_I, INDEX_TYPE, DEFAULT_BUFFER >; template< class T_COMP_POLICY > class SingleArrayTest : public ::testing::Test diff --git a/unitTests/testSparsityPattern.cpp b/unitTests/testSparsityPattern.cpp index fee7a995..7e4b7982 100644 --- a/unitTests/testSparsityPattern.cpp +++ b/unitTests/testSparsityPattern.cpp @@ -35,7 +35,7 @@ template< typename U, typename T, typename INDEX_TYPE, template< typename > clas struct ToArray1D< U, SparsityPattern< T, INDEX_TYPE, BUFFER_TYPE > > { using array = Array< U, 1, RAJA::PERM_I, INDEX_TYPE, BUFFER_TYPE >; - using view = ArrayView< U, 1, 0, INDEX_TYPE, BUFFER_TYPE >; + using view = ArrayView< U, 1, RAJA::PERM_I, INDEX_TYPE, BUFFER_TYPE >; }; template< typename SPARSITY_PATTERN > diff --git a/unitTests/testTensorOpsCommon.hpp b/unitTests/testTensorOpsCommon.hpp index 39921996..f25822a6 100644 --- a/unitTests/testTensorOpsCommon.hpp +++ b/unitTests/testTensorOpsCommon.hpp @@ -29,13 +29,13 @@ using INDEX_TYPE = std::ptrdiff_t; template< typename T, typename PERMUTATION > using ArrayT = Array< T, typeManipulation::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, typename PERMUTATION > +using ArrayViewT = ArrayView< T, NDIM, PERMUTATION, std::ptrdiff_t, DEFAULT_BUFFER >; -template< typename T, int NDIM, int USD, typename ... SIZES > +template< typename T, typename LAYOUT, typename ... SIZES > LVARRAY_HOST_DEVICE -void fill( ArraySlice< T, NDIM, USD, INDEX_TYPE > const slice, std::ptrdiff_t offset ) +void fill( ArraySlice2< T, LAYOUT > const slice, std::ptrdiff_t offset ) { forValuesInSlice( slice, [&offset] ( T & value ) { diff --git a/unitTests/testTensorOpsEigen.cpp b/unitTests/testTensorOpsEigen.cpp index 2c556ec7..ba430566 100644 --- a/unitTests/testTensorOpsEigen.cpp +++ b/unitTests/testTensorOpsEigen.cpp @@ -80,9 +80,9 @@ class TestEigendecomposition : public ::testing::Test { FLOAT const tol = tolerance(); - ArrayViewT< T const, 2, 1 > const matrices = m_matrices.toViewConst(); - ArrayViewT< FLOAT, 2, 1 > const eigenvalues = m_eigenvalues.toView(); - ArrayViewT< FLOAT, 3, 2 > const eigenvectors = m_eigenvectors.toView(); + ArrayViewT< T const, 2, RAJA::PERM_IJ > const matrices = m_matrices.toViewConst(); + ArrayViewT< FLOAT, 2, RAJA::PERM_IJ > const eigenvalues = m_eigenvalues.toView(); + ArrayViewT< FLOAT, 3, RAJA::PERM_IJK > const eigenvectors = m_eigenvectors.toView(); forall< POLICY >( matrices.size( 0 ), [=] LVARRAY_HOST_DEVICE ( std::ptrdiff_t const i ) { FLOAT eigenvaluesOnly[ M ]; @@ -100,10 +100,10 @@ class TestEigendecomposition : public ::testing::Test FLOAT const tol = ( iteration == 0 ) ? tolerance() : reducedTolerance(); std::vector< double > relativeDiffs; - ArrayViewT< T const, 2, 1 > const matrices = m_matrices.toViewConst(); - ArrayViewT< FLOAT const, 2, 1 > const eigenvalues = m_eigenvalues.toViewConst(); - ArrayViewT< FLOAT, 2, 1 > const expectedEigenvalues = m_expectedEigenvalues.toView(); - ArrayViewT< FLOAT const, 3, 2 > const eigenvectors = m_eigenvectors.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_IJ > const matrices = m_matrices.toViewConst(); + ArrayViewT< FLOAT const, 2, RAJA::PERM_IJ > const eigenvalues = m_eigenvalues.toViewConst(); + ArrayViewT< FLOAT, 2, RAJA::PERM_IJ > const expectedEigenvalues = m_expectedEigenvalues.toView(); + ArrayViewT< FLOAT const, 3, RAJA::PERM_IJK > const eigenvectors = m_eigenvectors.toViewConst(); forall< serialPolicy >( matrices.size( 0 ), [=, &relativeDiffs] ( std::ptrdiff_t const i ) { if( iteration > 0 ) @@ -170,10 +170,10 @@ class TestEigendecomposition : public ::testing::Test // This is done by A = Q \lambda Q^T where Q is the matrix whose columns are the eigenvectors. void duplicateEigenvalues() { - ArrayViewT< T, 2, 1 > const matrices = m_matrices.toView(); - ArrayViewT< FLOAT, 2, 1 > const eigenvalues = m_eigenvalues.toView(); - ArrayViewT< FLOAT, 2, 1 > const expectedEigenvalues = m_expectedEigenvalues.toView(); - ArrayViewT< FLOAT, 3, 2 > const eigenvectors = m_eigenvectors.toView(); + ArrayViewT< T, 2, RAJA::PERM_IJ > const matrices = m_matrices.toView(); + ArrayViewT< FLOAT, 2, RAJA::PERM_IJ > const eigenvalues = m_eigenvalues.toView(); + ArrayViewT< FLOAT, 2, RAJA::PERM_IJ > const expectedEigenvalues = m_expectedEigenvalues.toView(); + ArrayViewT< FLOAT, 3, RAJA::PERM_IJK > const eigenvectors = m_eigenvectors.toView(); forall< serialPolicy >( matrices.size( 0 ), [=] ( std::ptrdiff_t const i ) { // Since we're constructing the matrix we know the eigenvalues beforehand. diff --git a/unitTests/testTensorOpsFixedSize.cpp b/unitTests/testTensorOpsFixedSize.cpp index 21392a17..8031b7fd 100644 --- a/unitTests/testTensorOpsFixedSize.cpp +++ b/unitTests/testTensorOpsFixedSize.cpp @@ -127,15 +127,15 @@ class FixedSizeSquareMatrixTest : public ::testing::Test tensorOps::Ri_eq_AijBj< N, N >( result, denseSymA, m_vectorB_local ); } - ArrayViewT< T, 2, 1 > const vectorA_IJ = m_vectorA_IJ.toView(); - ArrayViewT< T, 2, 0 > const vectorA_JI = m_vectorA_JI.toView(); + ArrayViewT< T, 2, RAJA::PERM_IJ > const vectorA_IJ = m_vectorA_IJ.toView(); + ArrayViewT< T, 2, RAJA::PERM_JI > const vectorA_JI = m_vectorA_JI.toView(); - ArrayViewT< T const, 2, 1 > const symMatrixA_IJ = m_symMatrixA_IJ.toViewConst(); - ArrayViewT< T const, 2, 0 > const symMatrixA_JI = m_symMatrixA_JI.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_IJ > const symMatrixA_IJ = m_symMatrixA_IJ.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_JI > const symMatrixA_JI = m_symMatrixA_JI.toViewConst(); T const ( &symMatrixA_local )[ SYM_SIZE ] = m_symMatrixA_local; - ArrayViewT< T const, 2, 1 > const vectorB_IJ = m_vectorB_IJ.toViewConst(); - ArrayViewT< T const, 2, 0 > const vectorB_JI = m_vectorB_JI.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_IJ > const vectorB_IJ = m_vectorB_IJ.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_JI > const vectorB_JI = m_vectorB_JI.toViewConst(); T const ( &vectorB_local )[ N ] = m_vectorB_local; std::ptrdiff_t const vectorASeed = m_seedVectorA; @@ -182,15 +182,15 @@ class FixedSizeSquareMatrixTest : public ::testing::Test tensorOps::Ri_add_AijBj< N, N >( result, denseSymA, m_vectorB_local ); } - ArrayViewT< T, 2, 1 > const vectorA_IJ = m_vectorA_IJ.toView(); - ArrayViewT< T, 2, 0 > const vectorA_JI = m_vectorA_JI.toView(); + ArrayViewT< T, 2, RAJA::PERM_IJ > const vectorA_IJ = m_vectorA_IJ.toView(); + ArrayViewT< T, 2, RAJA::PERM_JI > const vectorA_JI = m_vectorA_JI.toView(); - ArrayViewT< T const, 2, 1 > const symMatrixA_IJ = m_symMatrixA_IJ.toViewConst(); - ArrayViewT< T const, 2, 0 > const symMatrixA_JI = m_symMatrixA_JI.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_IJ > const symMatrixA_IJ = m_symMatrixA_IJ.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_JI > const symMatrixA_JI = m_symMatrixA_JI.toViewConst(); T const ( &symMatrixA_local )[ SYM_SIZE ] = m_symMatrixA_local; - ArrayViewT< T const, 2, 1 > const vectorB_IJ = m_vectorB_IJ.toViewConst(); - ArrayViewT< T const, 2, 0 > const vectorB_JI = m_vectorB_JI.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_IJ > const vectorB_IJ = m_vectorB_IJ.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_JI > const vectorB_JI = m_vectorB_JI.toViewConst(); T const ( &vectorB_local )[ N ] = m_vectorB_local; std::ptrdiff_t const vectorASeed = m_seedVectorA; @@ -236,17 +236,17 @@ class FixedSizeSquareMatrixTest : public ::testing::Test tensorOps::Rij_eq_AikBjk< N, N, N >( result, denseSymA, m_matrixB_local ); } - 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(); + ArrayViewT< T, 3, RAJA::PERM_IJK > const matrixA_IJK = m_matrixA_IJK.toView(); + ArrayViewT< T, 3, RAJA::PERM_IKJ > const matrixA_IKJ = m_matrixA_IKJ.toView(); + ArrayViewT< T, 3, RAJA::PERM_KJI > const matrixA_KJI = m_matrixA_KJI.toView(); - ArrayViewT< T const, 2, 1 > const symMatrixA_IJ = m_symMatrixA_IJ.toViewConst(); - ArrayViewT< T const, 2, 0 > const symMatrixA_JI = m_symMatrixA_JI.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_IJ > const symMatrixA_IJ = m_symMatrixA_IJ.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_JI > const symMatrixA_JI = m_symMatrixA_JI.toViewConst(); T const ( &symMatrixA_local )[ SYM_SIZE ] = m_symMatrixA_local; - 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(); + ArrayViewT< T const, 3, RAJA::PERM_IJK > const matrixB_IJK = m_matrixB_IJK.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_IKJ > const matrixB_IKJ = m_matrixB_IKJ.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_KJI > const matrixB_KJI = m_matrixB_KJI.toViewConst(); T const ( &matrixB_local )[ N ][ N ] = m_matrixB_local; std::ptrdiff_t const matrixASeed = m_seedMatrixA; @@ -302,16 +302,16 @@ class FixedSizeSquareMatrixTest : public ::testing::Test tensorOps::denseToSymmetric< N >( result, denseResult ); } - ArrayViewT< T, 2, 1 > const symMatrixA_IJ = m_symMatrixA_IJ.toView(); - ArrayViewT< T, 2, 0 > const symMatrixA_JI = m_symMatrixA_JI.toView(); + ArrayViewT< T, 2, RAJA::PERM_IJ > const symMatrixA_IJ = m_symMatrixA_IJ.toView(); + ArrayViewT< T, 2, RAJA::PERM_JI > const symMatrixA_JI = m_symMatrixA_JI.toView(); - 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(); + ArrayViewT< T const, 3, RAJA::PERM_IJK > const matrixA_IJK = m_matrixA_IJK.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_IKJ > const matrixA_IKJ = m_matrixA_IKJ.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_KJI > const matrixA_KJI = m_matrixA_KJI.toViewConst(); T const ( &matrixA_local )[ N ][ N ] = m_matrixA_local; - ArrayViewT< T const, 2, 1 > const symMatrixB_IJ = m_symMatrixB_IJ.toViewConst(); - ArrayViewT< T const, 2, 0 > const symMatrixB_JI = m_symMatrixB_JI.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_IJ > const symMatrixB_IJ = m_symMatrixB_IJ.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_JI > const symMatrixB_JI = m_symMatrixB_JI.toViewConst(); T const ( &symMatrixB_local )[ SYM_SIZE ] = m_symMatrixB_local; std::ptrdiff_t const matrixASeed = m_seedMatrixA; @@ -365,11 +365,11 @@ class FixedSizeSquareMatrixTest : public ::testing::Test T symResult[ SYM_SIZE ]; tensorOps::denseToSymmetric< N >( symResult, result ); - ArrayViewT< T, 2, 1 > const symMatrixA_IJ = m_symMatrixA_IJ.toView(); - ArrayViewT< T, 2, 0 > const symMatrixA_JI = m_symMatrixA_JI.toView(); + ArrayViewT< T, 2, RAJA::PERM_IJ > const symMatrixA_IJ = m_symMatrixA_IJ.toView(); + ArrayViewT< T, 2, RAJA::PERM_JI > const symMatrixA_JI = m_symMatrixA_JI.toView(); - ArrayViewT< T const, 2, 1 > const vectorA_IJ = m_vectorA_IJ.toViewConst(); - ArrayViewT< T const, 2, 0 > const vectorA_JI = m_vectorA_JI.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_IJ > const vectorA_IJ = m_vectorA_IJ.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_JI > const vectorA_JI = m_vectorA_JI.toViewConst(); T const ( &vectorA_local )[ N ] = m_vectorA_local; std::ptrdiff_t const matrixSeed = m_seedSymMatrixA; @@ -412,15 +412,15 @@ class FixedSizeSquareMatrixTest : public ::testing::Test T symResult[ SYM_SIZE ]; tensorOps::denseToSymmetric< N >( symResult, result ); - ArrayViewT< T, 2, 1 > const symMatrixA_IJ = m_symMatrixA_IJ.toView(); - ArrayViewT< T, 2, 0 > const symMatrixA_JI = m_symMatrixA_JI.toView(); + ArrayViewT< T, 2, RAJA::PERM_IJ > const symMatrixA_IJ = m_symMatrixA_IJ.toView(); + ArrayViewT< T, 2, RAJA::PERM_JI > const symMatrixA_JI = m_symMatrixA_JI.toView(); - ArrayViewT< T const, 2, 1 > const vectorA_IJ = m_vectorA_IJ.toViewConst(); - ArrayViewT< T const, 2, 0 > const vectorA_JI = m_vectorA_JI.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_IJ > const vectorA_IJ = m_vectorA_IJ.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_JI > const vectorA_JI = m_vectorA_JI.toViewConst(); T const ( &vectorA_local )[ N ] = m_vectorA_local; - ArrayViewT< T const, 2, 1 > const vectorB_IJ = m_vectorB_IJ.toViewConst(); - ArrayViewT< T const, 2, 0 > const vectorB_JI = m_vectorB_JI.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_IJ > const vectorB_IJ = m_vectorB_IJ.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_JI > const vectorB_JI = m_vectorB_JI.toViewConst(); T const ( &vectorB_local )[ N ] = m_vectorB_local; std::ptrdiff_t const matrixSeed = m_seedSymMatrixA; @@ -460,13 +460,13 @@ class FixedSizeSquareMatrixTest : public ::testing::Test void symmetricToDense() { - ArrayViewT< T const, 2, 1 > const symMatrixA_IJ = m_symMatrixA_IJ.toViewConst(); - ArrayViewT< T const, 2, 0 > const symMatrixA_JI = m_symMatrixA_JI.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_IJ > const symMatrixA_IJ = m_symMatrixA_IJ.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_JI > const symMatrixA_JI = m_symMatrixA_JI.toViewConst(); T const ( &symMatrixA_local )[ SYM_SIZE ] = m_symMatrixA_local; - 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(); + ArrayViewT< T, 3, RAJA::PERM_IJK > const matrixA_IJK = m_matrixA_IJK.toView(); + ArrayViewT< T, 3, RAJA::PERM_IKJ > const matrixA_IKJ = m_matrixA_IKJ.toView(); + ArrayViewT< T, 3, RAJA::PERM_KJI > const matrixA_KJI = m_matrixA_KJI.toView(); std::ptrdiff_t const matrixASeed = m_seedMatrixA; @@ -496,12 +496,12 @@ class FixedSizeSquareMatrixTest : public ::testing::Test void denseToSymmetric() { - ArrayViewT< T, 2, 1 > const symMatrixA_IJ = m_symMatrixA_IJ.toView(); - ArrayViewT< T, 2, 0 > const symMatrixA_JI = m_symMatrixA_JI.toView(); + ArrayViewT< T, 2, RAJA::PERM_IJ > const symMatrixA_IJ = m_symMatrixA_IJ.toView(); + ArrayViewT< T, 2, RAJA::PERM_JI > const symMatrixA_JI = m_symMatrixA_JI.toView(); - 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(); + ArrayViewT< T const, 3, RAJA::PERM_IJK > const matrixA_IJK = m_matrixA_IJK.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_IKJ > const matrixA_IKJ = m_matrixA_IKJ.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_KJI > const matrixA_KJI = m_matrixA_KJI.toViewConst(); T const ( &matrixA_local )[ N ][ N ] = m_matrixA_local; std::ptrdiff_t const symMatrixASeed = m_seedSymMatrixA; diff --git a/unitTests/testTensorOpsInverse.hpp b/unitTests/testTensorOpsInverse.hpp index 9edfa950..27e565d2 100644 --- a/unitTests/testTensorOpsInverse.hpp +++ b/unitTests/testTensorOpsInverse.hpp @@ -34,9 +34,9 @@ class InverseTest : public ::testing::Test void determinant() { - ArrayViewT< T, 3, 2 > const srcMatrix_IJK = m_srcMatrix_IJK.toView(); - ArrayViewT< T, 3, 1 > const srcMatrix_IKJ = m_srcMatrix_IKJ.toView(); - ArrayViewT< T, 3, 0 > const srcMatrix_KJI = m_srcMatrix_KJI.toView(); + ArrayViewT< T, 3, RAJA::PERM_IJK > const srcMatrix_IJK = m_srcMatrix_IJK.toView(); + ArrayViewT< T, 3, RAJA::PERM_IKJ > const srcMatrix_IKJ = m_srcMatrix_IKJ.toView(); + ArrayViewT< T, 3, RAJA::PERM_KJI > const srcMatrix_KJI = m_srcMatrix_KJI.toView(); ArrayT< T, RAJA::PERM_IJK > arrayOfMatrices( numMatrices, M, M ); @@ -44,7 +44,7 @@ class InverseTest : public ::testing::Test for( T & value : arrayOfMatrices ) { value = randomValue( scale, m_gen ); } - ArrayViewT< T const, 3, 2 > const matrices = arrayOfMatrices.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_IJK > const matrices = arrayOfMatrices.toViewConst(); forall< POLICY >( matrices.size( 0 ), [=] LVARRAY_HOST_DEVICE ( INDEX_TYPE const i ) { @@ -64,8 +64,8 @@ class InverseTest : public ::testing::Test void symDeterminant() { - ArrayViewT< T, 2, 1 > const srcSymMatrix_IJ = m_srcSymMatrix_IJ.toView(); - ArrayViewT< T, 2, 0 > const srcSymMatrix_JI = m_srcSymMatrix_JI.toView(); + ArrayViewT< T, 2, RAJA::PERM_IJ > const srcSymMatrix_IJ = m_srcSymMatrix_IJ.toView(); + ArrayViewT< T, 2, RAJA::PERM_JI > const srcSymMatrix_JI = m_srcSymMatrix_JI.toView(); ArrayT< T, RAJA::PERM_IJ > arrayOfMatrices( numMatrices, SYM_SIZE ); @@ -73,7 +73,7 @@ class InverseTest : public ::testing::Test for( T & value : arrayOfMatrices ) { value = randomValue( scale, m_gen ); } - ArrayViewT< T const, 2, 1 > const matrices = arrayOfMatrices.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_IJ > const matrices = arrayOfMatrices.toViewConst(); forall< POLICY >( matrices.size( 0 ), [=] LVARRAY_HOST_DEVICE ( INDEX_TYPE const i ) { @@ -92,13 +92,13 @@ class InverseTest : public ::testing::Test void inverseTwoArgs() { - ArrayViewT< T, 3, 2 > const srcMatrix_IJK = m_srcMatrix_IJK.toView(); - ArrayViewT< T, 3, 1 > const srcMatrix_IKJ = m_srcMatrix_IKJ.toView(); - ArrayViewT< T, 3, 0 > const srcMatrix_KJI = m_srcMatrix_KJI.toView(); + ArrayViewT< T, 3, RAJA::PERM_IJK > const srcMatrix_IJK = m_srcMatrix_IJK.toView(); + ArrayViewT< T, 3, RAJA::PERM_IKJ > const srcMatrix_IKJ = m_srcMatrix_IKJ.toView(); + ArrayViewT< T, 3, RAJA::PERM_KJI > const srcMatrix_KJI = m_srcMatrix_KJI.toView(); - ArrayViewT< FLOAT, 3, 2 > const dstMatrix_IJK = m_dstMatrix_IJK.toView(); - ArrayViewT< FLOAT, 3, 1 > const dstMatrix_IKJ = m_dstMatrix_IKJ.toView(); - ArrayViewT< FLOAT, 3, 0 > const dstMatrix_KJI = m_dstMatrix_KJI.toView(); + ArrayViewT< FLOAT, 3, RAJA::PERM_IJK > const dstMatrix_IJK = m_dstMatrix_IJK.toView(); + ArrayViewT< FLOAT, 3, RAJA::PERM_IKJ > const dstMatrix_IKJ = m_dstMatrix_IKJ.toView(); + ArrayViewT< FLOAT, 3, RAJA::PERM_KJI > const dstMatrix_KJI = m_dstMatrix_KJI.toView(); ArrayT< T, RAJA::PERM_IJK > arrayOfMatrices( numMatrices, M, M ); @@ -106,7 +106,7 @@ class InverseTest : public ::testing::Test for( T & value : arrayOfMatrices ) { value = randomValue( scale, m_gen ); } - ArrayViewT< T const, 3, 2 > const matrices = arrayOfMatrices.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_IJK > const matrices = arrayOfMatrices.toViewConst(); forall< POLICY >( matrices.size( 0 ), [=] LVARRAY_HOST_DEVICE ( INDEX_TYPE const i ) { @@ -137,9 +137,9 @@ class InverseTest : public ::testing::Test void inverseOneArg() { - ArrayViewT< T, 3, 2 > const srcMatrix_IJK = m_srcMatrix_IJK.toView(); - ArrayViewT< T, 3, 1 > const srcMatrix_IKJ = m_srcMatrix_IKJ.toView(); - ArrayViewT< T, 3, 0 > const srcMatrix_KJI = m_srcMatrix_KJI.toView(); + ArrayViewT< T, 3, RAJA::PERM_IJK > const srcMatrix_IJK = m_srcMatrix_IJK.toView(); + ArrayViewT< T, 3, RAJA::PERM_IKJ > const srcMatrix_IKJ = m_srcMatrix_IKJ.toView(); + ArrayViewT< T, 3, RAJA::PERM_KJI > const srcMatrix_KJI = m_srcMatrix_KJI.toView(); ArrayT< T, RAJA::PERM_IJK > arrayOfMatrices( numMatrices, M, M ); @@ -147,7 +147,7 @@ class InverseTest : public ::testing::Test for( T & value : arrayOfMatrices ) { value = randomValue( scale, m_gen ); } - ArrayViewT< T const, 3, 2 > const matrices = arrayOfMatrices.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_IJK > const matrices = arrayOfMatrices.toViewConst(); forall< POLICY >( matrices.size( 0 ), [=] LVARRAY_HOST_DEVICE ( INDEX_TYPE const i ) { @@ -172,11 +172,11 @@ class InverseTest : public ::testing::Test void symInverseTwoArgs() { - ArrayViewT< T, 2, 1 > const srcSymMatrix_IJ = m_srcSymMatrix_IJ.toView(); - ArrayViewT< T, 2, 0 > const srcSymMatrix_JI = m_srcSymMatrix_JI.toView(); + ArrayViewT< T, 2, RAJA::PERM_IJ > const srcSymMatrix_IJ = m_srcSymMatrix_IJ.toView(); + ArrayViewT< T, 2, RAJA::PERM_JI > const srcSymMatrix_JI = m_srcSymMatrix_JI.toView(); - ArrayViewT< FLOAT, 2, 1 > const dstSymMatrix_IJ = m_dstSymMatrix_IJ.toView(); - ArrayViewT< FLOAT, 2, 0 > const dstSymMatrix_JI = m_dstSymMatrix_JI.toView(); + ArrayViewT< FLOAT, 2, RAJA::PERM_IJ > const dstSymMatrix_IJ = m_dstSymMatrix_IJ.toView(); + ArrayViewT< FLOAT, 2, RAJA::PERM_JI > const dstSymMatrix_JI = m_dstSymMatrix_JI.toView(); ArrayT< T, RAJA::PERM_IJ > arrayOfMatrices( numMatrices, SYM_SIZE ); @@ -184,7 +184,7 @@ class InverseTest : public ::testing::Test for( T & value : arrayOfMatrices ) { value = randomValue( scale, m_gen ); } - ArrayViewT< T const, 2, 1 > const matrices = arrayOfMatrices.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_IJ > const matrices = arrayOfMatrices.toViewConst(); forall< POLICY >( matrices.size( 0 ), [=] LVARRAY_HOST_DEVICE ( INDEX_TYPE const i ) { @@ -213,8 +213,8 @@ class InverseTest : public ::testing::Test void symInverseOneArg() { - ArrayViewT< T, 2, 1 > const srcSymMatrix_IJ = m_srcSymMatrix_IJ.toView(); - ArrayViewT< T, 2, 0 > const srcSymMatrix_JI = m_srcSymMatrix_JI.toView(); + ArrayViewT< T, 2, RAJA::PERM_IJ > const srcSymMatrix_IJ = m_srcSymMatrix_IJ.toView(); + ArrayViewT< T, 2, RAJA::PERM_JI > const srcSymMatrix_JI = m_srcSymMatrix_JI.toView(); ArrayT< T, RAJA::PERM_IJ > arrayOfMatrices( numMatrices, SYM_SIZE ); @@ -222,7 +222,7 @@ class InverseTest : public ::testing::Test for( T & value : arrayOfMatrices ) { value = randomValue( scale, m_gen ); } - ArrayViewT< T const, 2, 1 > const matrices = arrayOfMatrices.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_IJ > const matrices = arrayOfMatrices.toViewConst(); forall< POLICY >( matrices.size( 0 ), [=] LVARRAY_HOST_DEVICE ( INDEX_TYPE const i ) { diff --git a/unitTests/testTensorOpsNoSize.cpp b/unitTests/testTensorOpsNoSize.cpp index 8c1112d4..1742e810 100644 --- a/unitTests/testTensorOpsNoSize.cpp +++ b/unitTests/testTensorOpsNoSize.cpp @@ -63,8 +63,8 @@ class NoSizeTest : public ::testing::Test void testInit2() { - ArrayViewT< T const, 2, 1 > const vectorA2_IJ = m_vectorA2_IJ.toViewConst(); - ArrayViewT< T const, 2, 0 > const vectorA2_JI = m_vectorA2_JI.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_IJ > const vectorA2_IJ = m_vectorA2_IJ.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_JI > 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 ) @@ -91,8 +91,8 @@ class NoSizeTest : public ::testing::Test void testInit3() { - ArrayViewT< T const, 2, 1 > const vectorA3_IJ = m_vectorA3_IJ.toViewConst(); - ArrayViewT< T const, 2, 0 > const vectorA3_JI = m_vectorA3_JI.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_IJ > const vectorA3_IJ = m_vectorA3_IJ.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_JI > 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 ) @@ -119,8 +119,8 @@ class NoSizeTest : public ::testing::Test void testInit6() { - ArrayViewT< T const, 2, 1 > const vectorA6_IJ = m_vectorA6_IJ.toViewConst(); - ArrayViewT< T const, 2, 0 > const vectorA6_JI = m_vectorA6_JI.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_IJ > const vectorA6_IJ = m_vectorA6_IJ.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_JI > 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 ) @@ -147,9 +147,9 @@ class NoSizeTest : public ::testing::Test void testInit2x2() { - 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(); + ArrayViewT< T, 3, RAJA::PERM_IJK > const matrixA2_IJK = m_matrixA2_IJK.toView(); + ArrayViewT< T, 3, RAJA::PERM_IKJ > const matrixA2_IKJ = m_matrixA2_IKJ.toView(); + ArrayViewT< T, 3, RAJA::PERM_KJI > 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 ) @@ -202,9 +202,9 @@ class NoSizeTest : public ::testing::Test void testInit3x3() { - 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(); + ArrayViewT< T, 3, RAJA::PERM_IJK > const matrixA3_IJK = m_matrixA3_IJK.toView(); + ArrayViewT< T, 3, RAJA::PERM_IKJ > const matrixA3_IKJ = m_matrixA3_IKJ.toView(); + ArrayViewT< T, 3, RAJA::PERM_KJI > 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 ) @@ -262,15 +262,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 ]; - ArrayViewT< T, 2, 1 > const vectorA3_IJ = m_vectorA3_IJ.toView(); - ArrayViewT< T, 2, 0 > const vectorA3_JI = m_vectorA3_JI.toView(); + ArrayViewT< T, 2, RAJA::PERM_IJ > const vectorA3_IJ = m_vectorA3_IJ.toView(); + ArrayViewT< T, 2, RAJA::PERM_JI > const vectorA3_JI = m_vectorA3_JI.toView(); - ArrayViewT< T const, 2, 1 > const vectorB3_IJ = m_vectorB3_IJ.toViewConst(); - ArrayViewT< T const, 2, 0 > const vectorB3_JI = m_vectorB3_JI.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_IJ > const vectorB3_IJ = m_vectorB3_IJ.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_JI > const vectorB3_JI = m_vectorB3_JI.toViewConst(); T const ( &vectorB3_local )[ 3 ] = m_vectorB3_local; - ArrayViewT< T const, 2, 1 > const vectorC3_IJ = m_vectorC3_IJ.toViewConst(); - ArrayViewT< T const, 2, 0 > const vectorC3_JI = m_vectorC3_JI.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_IJ > const vectorC3_IJ = m_vectorC3_IJ.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_JI > const vectorC3_JI = m_vectorC3_JI.toViewConst(); T const ( &vectorC3_local )[ 3 ] = m_vectorC3_local; std::ptrdiff_t const aSeed = m_seedVectorA3; diff --git a/unitTests/testTensorOpsOneSize.cpp b/unitTests/testTensorOpsOneSize.cpp index 78946638..7009c6be 100644 --- a/unitTests/testTensorOpsOneSize.cpp +++ b/unitTests/testTensorOpsOneSize.cpp @@ -67,8 +67,8 @@ class OneSizeTest : public ::testing::Test for( std::ptrdiff_t i = 0; i < N; ++i ) { result[ i ] = m_vectorA_local[ i ] * scale; } - ArrayViewT< T, 2, 1 > const vectorA_IJ = m_vectorA_IJ.toView(); - ArrayViewT< T, 2, 0 > const vectorA_JI = m_vectorA_JI.toView(); + ArrayViewT< T, 2, RAJA::PERM_IJ > const vectorA_IJ = m_vectorA_IJ.toView(); + ArrayViewT< T, 2, RAJA::PERM_JI > const vectorA_JI = m_vectorA_JI.toView(); std::ptrdiff_t const aSeed = m_seedVectorA; @@ -93,8 +93,8 @@ class OneSizeTest : public ::testing::Test for( std::ptrdiff_t i = 0; i < N; ++i ) { result += m_vectorA_local[ i ] * m_vectorA_local[ i ]; } - ArrayViewT< T const, 2, 1 > const vectorA_IJ = m_vectorA_IJ.toViewConst(); - ArrayViewT< T const, 2, 0 > const vectorA_JI = m_vectorA_JI.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_IJ > const vectorA_IJ = m_vectorA_IJ.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_JI > 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 ) @@ -112,8 +112,8 @@ class OneSizeTest : public ::testing::Test { norm += m_vectorA_local[ i ] * m_vectorA_local[ i ]; } norm = sqrt( norm ); - ArrayViewT< T const, 2, 1 > const vectorA_IJ = m_vectorA_IJ.toViewConst(); - ArrayViewT< T const, 2, 0 > const vectorA_JI = m_vectorA_JI.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_IJ > const vectorA_IJ = m_vectorA_IJ.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_JI > 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 ) @@ -139,8 +139,8 @@ class OneSizeTest : public ::testing::Test for( std::ptrdiff_t i = 0; i < N; ++i ) { result [ i ] = m_vectorA_local[ i ] * invNorm; } - ArrayViewT< T, 2, 1 > const vectorA_IJ = m_vectorA_IJ.toView(); - ArrayViewT< T, 2, 0 > const vectorA_JI = m_vectorA_JI.toView(); + ArrayViewT< T, 2, RAJA::PERM_IJ > const vectorA_IJ = m_vectorA_IJ.toView(); + ArrayViewT< T, 2, RAJA::PERM_JI > const vectorA_JI = m_vectorA_JI.toView(); std::ptrdiff_t const aSeed = m_seedVectorA; @@ -165,8 +165,8 @@ class OneSizeTest : public ::testing::Test void testFill() { - ArrayViewT< T, 2, 1 > const vectorA_IJ = m_vectorA_IJ.toView(); - ArrayViewT< T, 2, 0 > const vectorA_JI = m_vectorA_JI.toView(); + ArrayViewT< T, 2, RAJA::PERM_IJ > const vectorA_IJ = m_vectorA_IJ.toView(); + ArrayViewT< T, 2, RAJA::PERM_JI > const vectorA_JI = m_vectorA_JI.toView(); forall< POLICY >( 1, [vectorA_IJ, vectorA_JI] LVARRAY_HOST_DEVICE ( int ) { @@ -195,8 +195,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 ] ); } - ArrayViewT< T, 2, 1 > const vectorA_IJ = m_vectorA_IJ.toView(); - ArrayViewT< T, 2, 0 > const vectorA_JI = m_vectorA_JI.toView(); + ArrayViewT< T, 2, RAJA::PERM_IJ > const vectorA_IJ = m_vectorA_IJ.toView(); + ArrayViewT< T, 2, RAJA::PERM_JI > const vectorA_JI = m_vectorA_JI.toView(); std::ptrdiff_t const seedVectorA = m_seedVectorA; @@ -214,11 +214,11 @@ class OneSizeTest : public ::testing::Test void testCopy() { - ArrayViewT< T, 2, 1 > const vectorA_IJ = m_vectorA_IJ.toView(); - ArrayViewT< T, 2, 0 > const vectorA_JI = m_vectorA_JI.toView(); + ArrayViewT< T, 2, RAJA::PERM_IJ > const vectorA_IJ = m_vectorA_IJ.toView(); + ArrayViewT< T, 2, RAJA::PERM_JI > const vectorA_JI = m_vectorA_JI.toView(); - ArrayViewT< T const, 2, 1 > const vectorB_IJ = m_vectorB_IJ.toViewConst(); - ArrayViewT< T const, 2, 0 > const vectorB_JI = m_vectorB_JI.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_IJ > const vectorB_IJ = m_vectorB_IJ.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_JI > const vectorB_JI = m_vectorB_JI.toViewConst(); T const ( &vectorB_local )[ N ] = m_vectorB_local; std::ptrdiff_t const aSeed = m_seedVectorA; @@ -250,11 +250,11 @@ class OneSizeTest : public ::testing::Test void testScaledCopy() { T scale = T( 3.14 ); - ArrayViewT< T, 2, 1 > const vectorA_IJ = m_vectorA_IJ.toView(); - ArrayViewT< T, 2, 0 > const vectorA_JI = m_vectorA_JI.toView(); + ArrayViewT< T, 2, RAJA::PERM_IJ > const vectorA_IJ = m_vectorA_IJ.toView(); + ArrayViewT< T, 2, RAJA::PERM_JI > const vectorA_JI = m_vectorA_JI.toView(); - ArrayViewT< T const, 2, 1 > const vectorB_IJ = m_vectorB_IJ.toViewConst(); - ArrayViewT< T const, 2, 0 > const vectorB_JI = m_vectorB_JI.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_IJ > const vectorB_IJ = m_vectorB_IJ.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_JI > const vectorB_JI = m_vectorB_JI.toViewConst(); T const ( &vectorB_local )[ N ] = m_vectorB_local; std::ptrdiff_t const aSeed = m_seedVectorA; @@ -290,11 +290,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 ]; } - ArrayViewT< T, 2, 1 > const vectorA_IJ = m_vectorA_IJ.toView(); - ArrayViewT< T, 2, 0 > const vectorA_JI = m_vectorA_JI.toView(); + ArrayViewT< T, 2, RAJA::PERM_IJ > const vectorA_IJ = m_vectorA_IJ.toView(); + ArrayViewT< T, 2, RAJA::PERM_JI > const vectorA_JI = m_vectorA_JI.toView(); - ArrayViewT< T const, 2, 1 > const vectorB_IJ = m_vectorB_IJ.toViewConst(); - ArrayViewT< T const, 2, 0 > const vectorB_JI = m_vectorB_JI.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_IJ > const vectorB_IJ = m_vectorB_IJ.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_JI > const vectorB_JI = m_vectorB_JI.toViewConst(); T const ( &vectorB_local )[ N ] = m_vectorB_local; std::ptrdiff_t const aSeed = m_seedVectorA; @@ -330,8 +330,8 @@ class OneSizeTest : public ::testing::Test for( std::ptrdiff_t i = 0; i < N; ++i ) { result[ i ] = m_vectorA_local[ i ] + scalar; } - ArrayViewT< T, 2, 1 > const vectorA_IJ = m_vectorA_IJ.toView(); - ArrayViewT< T, 2, 0 > const vectorA_JI = m_vectorA_JI.toView(); + ArrayViewT< T, 2, RAJA::PERM_IJ > const vectorA_IJ = m_vectorA_IJ.toView(); + ArrayViewT< T, 2, RAJA::PERM_JI > const vectorA_JI = m_vectorA_JI.toView(); std::ptrdiff_t const aSeed = m_seedVectorA; @@ -356,11 +356,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 ]; } - ArrayViewT< T, 2, 1 > const vectorA_IJ = m_vectorA_IJ.toView(); - ArrayViewT< T, 2, 0 > const vectorA_JI = m_vectorA_JI.toView(); + ArrayViewT< T, 2, RAJA::PERM_IJ > const vectorA_IJ = m_vectorA_IJ.toView(); + ArrayViewT< T, 2, RAJA::PERM_JI > const vectorA_JI = m_vectorA_JI.toView(); - ArrayViewT< T const, 2, 1 > const vectorB_IJ = m_vectorB_IJ.toViewConst(); - ArrayViewT< T const, 2, 0 > const vectorB_JI = m_vectorB_JI.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_IJ > const vectorB_IJ = m_vectorB_IJ.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_JI > const vectorB_JI = m_vectorB_JI.toViewConst(); T const ( &vectorB_local )[ N ] = m_vectorB_local; std::ptrdiff_t const aSeed = m_seedVectorA; @@ -391,11 +391,11 @@ class OneSizeTest : public ::testing::Test void testScaledAdd() { - ArrayViewT< T, 2, 1 > const vectorA_IJ = m_vectorA_IJ.toView(); - ArrayViewT< T, 2, 0 > const vectorA_JI = m_vectorA_JI.toView(); + ArrayViewT< T, 2, RAJA::PERM_IJ > const vectorA_IJ = m_vectorA_IJ.toView(); + ArrayViewT< T, 2, RAJA::PERM_JI > const vectorA_JI = m_vectorA_JI.toView(); - ArrayViewT< T const, 2, 1 > const vectorB_IJ = m_vectorB_IJ.toViewConst(); - ArrayViewT< T const, 2, 0 > const vectorB_JI = m_vectorB_JI.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_IJ > const vectorB_IJ = m_vectorB_IJ.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_JI > const vectorB_JI = m_vectorB_JI.toViewConst(); T const ( &vectorB_local )[ N ] = m_vectorB_local; std::ptrdiff_t const aSeed = m_seedVectorA; @@ -436,12 +436,12 @@ class OneSizeTest : public ::testing::Test for( std::ptrdiff_t i = 0; i < N; ++i ) { expectedValue += m_vectorA_local[ i ] * m_vectorB_local[ i ]; } - ArrayViewT< T const, 2, 1 > const vectorA_IJ = m_vectorA_IJ.toViewConst(); - ArrayViewT< T const, 2, 0 > const vectorA_JI = m_vectorA_JI.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_IJ > const vectorA_IJ = m_vectorA_IJ.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_JI > const vectorA_JI = m_vectorA_JI.toViewConst(); T const ( &vectorA_local )[ N ] = m_vectorA_local; - ArrayViewT< T const, 2, 1 > const vectorB_IJ = m_vectorB_IJ.toViewConst(); - ArrayViewT< T const, 2, 0 > const vectorB_JI = m_vectorB_JI.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_IJ > const vectorB_IJ = m_vectorB_IJ.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_JI > 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 ) @@ -466,15 +466,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 ]; } - ArrayViewT< T, 2, 1 > const vectorA_IJ = m_vectorA_IJ.toView(); - ArrayViewT< T, 2, 0 > const vectorA_JI = m_vectorA_JI.toView(); + ArrayViewT< T, 2, RAJA::PERM_IJ > const vectorA_IJ = m_vectorA_IJ.toView(); + ArrayViewT< T, 2, RAJA::PERM_JI > const vectorA_JI = m_vectorA_JI.toView(); - ArrayViewT< T const, 2, 1 > const vectorB_IJ = m_vectorB_IJ.toViewConst(); - ArrayViewT< T const, 2, 0 > const vectorB_JI = m_vectorB_JI.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_IJ > const vectorB_IJ = m_vectorB_IJ.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_JI > const vectorB_JI = m_vectorB_JI.toViewConst(); T const ( &vectorB_local )[ N ] = m_vectorB_local; - ArrayViewT< T const, 2, 1 > const vectorC_IJ = m_vectorC_IJ.toViewConst(); - ArrayViewT< T const, 2, 0 > const vectorC_JI = m_vectorC_JI.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_IJ > const vectorC_IJ = m_vectorC_IJ.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_JI > const vectorC_JI = m_vectorC_JI.toViewConst(); T const ( &vectorC_local )[ N ] = m_vectorC_local; std::ptrdiff_t const aSeed = m_seedVectorA; @@ -518,9 +518,9 @@ class OneSizeTest : public ::testing::Test for( std::ptrdiff_t i = 0; i < N; ++i ) { result[ i ][ i ] += value; } - 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(); + ArrayViewT< T, 3, RAJA::PERM_IJK > const matrixA_IJK = m_matrixA_IJK.toView(); + ArrayViewT< T, 3, RAJA::PERM_IKJ > const matrixA_IKJ = m_matrixA_IKJ.toView(); + ArrayViewT< T, 3, RAJA::PERM_KJI > const matrixA_KJI = m_matrixA_KJI.toView(); std::ptrdiff_t const seedMatrixA = m_seedMatrixA; @@ -551,9 +551,9 @@ class OneSizeTest : public ::testing::Test { result[ i ][ j ] = m_matrixA_local[ j ][ i ]; } } - 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(); + ArrayViewT< T, 3, RAJA::PERM_IJK > const matrixA_IJK = m_matrixA_IJK.toView(); + ArrayViewT< T, 3, RAJA::PERM_IKJ > const matrixA_IKJ = m_matrixA_IKJ.toView(); + ArrayViewT< T, 3, RAJA::PERM_KJI > const matrixA_KJI = m_matrixA_KJI.toView(); std::ptrdiff_t const seedMatrixA = m_seedMatrixA; @@ -581,9 +581,9 @@ class OneSizeTest : public ::testing::Test for( std::ptrdiff_t i = 0; i < N; ++i ) { result += m_matrixA_local[ i ][ i ]; } - 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(); + ArrayViewT< T, 3, RAJA::PERM_IJK > const matrixA_IJK = m_matrixA_IJK.toView(); + ArrayViewT< T, 3, RAJA::PERM_IKJ > const matrixA_IKJ = m_matrixA_IKJ.toView(); + ArrayViewT< T, 3, RAJA::PERM_KJI > const matrixA_KJI = m_matrixA_KJI.toView(); std::ptrdiff_t const seedMatrixA = m_seedMatrixA; @@ -610,8 +610,8 @@ class OneSizeTest : public ::testing::Test for( std::ptrdiff_t i = 0; i < N; ++i ) { result[ i ] += value; } - ArrayViewT< T, 2, 1 > const symMatrix_IJ = m_symMatrix_IJ.toView(); - ArrayViewT< T, 2, 0 > const symMatrix_JI = m_symMatrix_JI.toView(); + ArrayViewT< T, 2, RAJA::PERM_IJ > const symMatrix_IJ = m_symMatrix_IJ.toView(); + ArrayViewT< T, 2, RAJA::PERM_JI > const symMatrix_JI = m_symMatrix_JI.toView(); std::ptrdiff_t const seedSymMatrix = m_seedSymMatrix; @@ -636,8 +636,8 @@ class OneSizeTest : public ::testing::Test for( std::ptrdiff_t i = 0; i < N; ++i ) { result += m_symMatrix_local[ i ]; } - ArrayViewT< T, 2, 1 > const symMatrix_IJ = m_symMatrix_IJ.toView(); - ArrayViewT< T, 2, 0 > const symMatrix_JI = m_symMatrix_JI.toView(); + ArrayViewT< T, 2, RAJA::PERM_IJ > const symMatrix_IJ = m_symMatrix_IJ.toView(); + ArrayViewT< T, 2, RAJA::PERM_JI > const symMatrix_JI = m_symMatrix_JI.toView(); std::ptrdiff_t const seedSymMatrix = m_seedSymMatrix; diff --git a/unitTests/testTensorOpsThreeSizes.hpp b/unitTests/testTensorOpsThreeSizes.hpp index b4546a9b..560d6922 100644 --- a/unitTests/testTensorOpsThreeSizes.hpp +++ b/unitTests/testTensorOpsThreeSizes.hpp @@ -71,18 +71,18 @@ class ThreeSizesTest : public ::testing::Test } } - 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(); + ArrayViewT< T, 3, RAJA::PERM_IJK > const matrixNM_IJK = m_matrixNM_IJK.toView(); + ArrayViewT< T, 3, RAJA::PERM_IKJ > const matrixNM_IKJ = m_matrix_NM_IKJ.toView(); + ArrayViewT< T, 3, RAJA::PERM_KJI > const matrixNM_KJI = m_matrix_NM_KJI.toView(); - 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(); + ArrayViewT< T const, 3, RAJA::PERM_IJK > const matrixML_IJK = m_matrixNL_IJK.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_IKJ > const matrixML_IKJ = m_matrixNL_IKJ.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_KJI > const matrixML_KJI = m_matrixNL_KJI.toViewConst(); T const ( &matrixML_local )[ N ][ L ] = m_matrixNL_local; - 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(); + ArrayViewT< T const, 3, RAJA::PERM_IJK > const matrixLM_IJK = m_matrixLM_IJK.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_IKJ > const matrixLM_IKJ = m_matrixLM_IKJ.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_KJI > const matrixLM_KJI = m_matrixLM_KJI.toViewConst(); T const ( &matrixLM_local )[ L ][ M ] = m_matrixLM_local; std::ptrdiff_t const matrixNMSeed = m_matrixNMSeed; @@ -143,18 +143,18 @@ class ThreeSizesTest : public ::testing::Test } } - 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(); + ArrayViewT< T, 3, RAJA::PERM_IJK > const matrixNM_IJK = m_matrixNM_IJK.toView(); + ArrayViewT< T, 3, RAJA::PERM_IKJ > const matrixNM_IKJ = m_matrix_NM_IKJ.toView(); + ArrayViewT< T, 3, RAJA::PERM_KJI > const matrixNM_KJI = m_matrix_NM_KJI.toView(); - 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(); + ArrayViewT< T const, 3, RAJA::PERM_IJK > const matrixML_IJK = m_matrixNL_IJK.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_IKJ > const matrixML_IKJ = m_matrixNL_IKJ.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_KJI > const matrixML_KJI = m_matrixNL_KJI.toViewConst(); T const ( &matrixML_local )[ N ][ L ] = m_matrixNL_local; - 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(); + ArrayViewT< T const, 3, RAJA::PERM_IJK > const matrixLM_IJK = m_matrixLM_IJK.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_IKJ > const matrixLM_IKJ = m_matrixLM_IKJ.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_KJI > const matrixLM_KJI = m_matrixLM_KJI.toViewConst(); T const ( &matrixLM_local )[ L ][ M ] = m_matrixLM_local; std::ptrdiff_t const matrixNMSeed = m_matrixNMSeed; @@ -215,18 +215,18 @@ class ThreeSizesTest : public ::testing::Test } } - 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(); + ArrayViewT< T, 3, RAJA::PERM_IJK > const matrixNM_IJK = m_matrixNM_IJK.toView(); + ArrayViewT< T, 3, RAJA::PERM_IKJ > const matrixNM_IKJ = m_matrix_NM_IKJ.toView(); + ArrayViewT< T, 3, RAJA::PERM_KJI > const matrixNM_KJI = m_matrix_NM_KJI.toView(); - 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(); + ArrayViewT< T const, 3, RAJA::PERM_IJK > const matrixNL_IJK = m_matrixNL_IJK.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_IKJ > const matrixNL_IKJ = m_matrixNL_IKJ.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_KJI > const matrixNL_KJI = m_matrixNL_KJI.toViewConst(); T const ( &matrixNL_local )[ N ][ L ] = m_matrixNL_local; - 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(); + ArrayViewT< T const, 3, RAJA::PERM_IJK > const matrixML_IJK = m_matrixML_IJK.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_IKJ > const matrixML_IKJ = m_matrixML_IKJ.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_KJI > const matrixML_KJI = m_matrixML_KJI.toViewConst(); T const ( &matrixML_local )[ M ][ L ] = m_matrixML_local; std::ptrdiff_t const matrixNMSeed = m_matrixNMSeed; @@ -287,18 +287,18 @@ class ThreeSizesTest : public ::testing::Test } } - 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(); + ArrayViewT< T, 3, RAJA::PERM_IJK > const matrixNM_IJK = m_matrixNM_IJK.toView(); + ArrayViewT< T, 3, RAJA::PERM_IKJ > const matrixNM_IKJ = m_matrix_NM_IKJ.toView(); + ArrayViewT< T, 3, RAJA::PERM_KJI > const matrixNM_KJI = m_matrix_NM_KJI.toView(); - 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(); + ArrayViewT< T const, 3, RAJA::PERM_IJK > const matrixNL_IJK = m_matrixNL_IJK.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_IKJ > const matrixNL_IKJ = m_matrixNL_IKJ.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_KJI > const matrixNL_KJI = m_matrixNL_KJI.toViewConst(); T const ( &matrixNL_local )[ N ][ L ] = m_matrixNL_local; - 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(); + ArrayViewT< T const, 3, RAJA::PERM_IJK > const matrixML_IJK = m_matrixML_IJK.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_IKJ > const matrixML_IKJ = m_matrixML_IKJ.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_KJI > const matrixML_KJI = m_matrixML_KJI.toViewConst(); T const ( &matrixML_local )[ M ][ L ] = m_matrixML_local; std::ptrdiff_t const matrixNMSeed = m_matrixNMSeed; @@ -359,18 +359,18 @@ class ThreeSizesTest : public ::testing::Test } } - 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(); + ArrayViewT< T, 3, RAJA::PERM_IJK > const matrixML_IJK = m_matrixML_IJK.toView(); + ArrayViewT< T, 3, RAJA::PERM_IKJ > const matrixML_IKJ = m_matrixML_IKJ.toView(); + ArrayViewT< T, 3, RAJA::PERM_KJI > const matrixML_KJI = m_matrixML_KJI.toView(); - 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(); + ArrayViewT< T const, 3, RAJA::PERM_IJK > const matrixNM_IJK = m_matrixNM_IJK.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_IKJ > const matrixNM_IKJ = m_matrix_NM_IKJ.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_KJI > const matrixNM_KJI = m_matrix_NM_KJI.toViewConst(); T const ( &matrixNM_local )[ N ][ M ] = m_matrixNM_local; - 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(); + ArrayViewT< T const, 3, RAJA::PERM_IJK > const matrixNL_IJK = m_matrixNL_IJK.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_IKJ > const matrixNL_IKJ = m_matrixNL_IKJ.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_KJI > const matrixNL_KJI = m_matrixNL_KJI.toViewConst(); T const ( &matrixNL_local )[ N ][ L ] = m_matrixNL_local; std::ptrdiff_t const matrixMLSeed = m_matrixMLSeed; @@ -430,18 +430,18 @@ class ThreeSizesTest : public ::testing::Test } } - 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(); + ArrayViewT< T, 3, RAJA::PERM_IJK > const matrixML_IJK = m_matrixML_IJK.toView(); + ArrayViewT< T, 3, RAJA::PERM_IKJ > const matrixML_IKJ = m_matrixML_IKJ.toView(); + ArrayViewT< T, 3, RAJA::PERM_KJI > const matrixML_KJI = m_matrixML_KJI.toView(); - 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(); + ArrayViewT< T const, 3, RAJA::PERM_IJK > const matrixNM_IJK = m_matrixNM_IJK.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_IKJ > const matrixNM_IKJ = m_matrix_NM_IKJ.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_KJI > const matrixNM_KJI = m_matrix_NM_KJI.toViewConst(); T const ( &matrixNM_local )[ N ][ M ] = m_matrixNM_local; - 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(); + ArrayViewT< T const, 3, RAJA::PERM_IJK > const matrixNL_IJK = m_matrixNL_IJK.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_IKJ > const matrixNL_IKJ = m_matrixNL_IKJ.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_KJI > const matrixNL_KJI = m_matrixNL_KJI.toViewConst(); T const ( &matrixNL_local )[ N ][ L ] = m_matrixNL_local; std::ptrdiff_t const matrixMLSeed = m_matrixMLSeed; diff --git a/unitTests/testTensorOpsTwoSizes.hpp b/unitTests/testTensorOpsTwoSizes.hpp index 5492b2b5..13c5c3f3 100644 --- a/unitTests/testTensorOpsTwoSizes.hpp +++ b/unitTests/testTensorOpsTwoSizes.hpp @@ -74,9 +74,9 @@ class TwoSizesTest : public ::testing::Test } } - 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(); + ArrayViewT< T, 3, RAJA::PERM_IJK > const matrixA_IJK = m_matrixA_IJK.toView(); + ArrayViewT< T, 3, RAJA::PERM_IKJ > const matrixA_IKJ = m_matrixA_IKJ.toView(); + ArrayViewT< T, 3, RAJA::PERM_KJI > 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 ) @@ -99,9 +99,9 @@ class TwoSizesTest : public ::testing::Test void testFill() { - 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(); + ArrayViewT< T, 3, RAJA::PERM_IJK > const matrixA_IJK = m_matrixA_IJK.toView(); + ArrayViewT< T, 3, RAJA::PERM_IKJ > const matrixA_IKJ = m_matrixA_IKJ.toView(); + ArrayViewT< T, 3, RAJA::PERM_KJI > const matrixA_KJI = m_matrixA_KJI.toView(); forall< POLICY >( 1, [matrixA_IJK, matrixA_IKJ, matrixA_KJI] LVARRAY_HOST_DEVICE ( int ) { @@ -159,16 +159,16 @@ class TwoSizesTest : public ::testing::Test } } - 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(); + ArrayViewT< T, 3, RAJA::PERM_IJK > const matrixA_IJK = m_matrixA_IJK.toView(); + ArrayViewT< T, 3, RAJA::PERM_IKJ > const matrixA_IKJ = m_matrixA_IKJ.toView(); + ArrayViewT< T, 3, RAJA::PERM_KJI > const matrixA_KJI = m_matrixA_KJI.toView(); - ArrayViewT< T const, 2, 1 > const vectorN_IJ = m_vectorN_IJ.toViewConst(); - ArrayViewT< T const, 2, 0 > const vectorN_JI = m_vectorN_JI.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_IJ > const vectorN_IJ = m_vectorN_IJ.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_JI > const vectorN_JI = m_vectorN_JI.toViewConst(); T const ( &vectorN_local )[ N ] = m_vectorN_local; - ArrayViewT< T const, 2, 1 > const vectorM_IJ = m_vectorM_IJ.toViewConst(); - ArrayViewT< T const, 2, 0 > const vectorM_JI = m_vectorM_JI.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_IJ > const vectorM_IJ = m_vectorM_IJ.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_JI > const vectorM_JI = m_vectorM_JI.toViewConst(); T const ( &vectorM_local )[ M ] = m_vectorM_local; std::ptrdiff_t const matrixSeed = m_matrixASeed; @@ -217,16 +217,16 @@ class TwoSizesTest : public ::testing::Test } } - 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(); + ArrayViewT< T, 3, RAJA::PERM_IJK > const matrixA_IJK = m_matrixA_IJK.toView(); + ArrayViewT< T, 3, RAJA::PERM_IKJ > const matrixA_IKJ = m_matrixA_IKJ.toView(); + ArrayViewT< T, 3, RAJA::PERM_KJI > const matrixA_KJI = m_matrixA_KJI.toView(); - ArrayViewT< T const, 2, 1 > const vectorN_IJ = m_vectorN_IJ.toViewConst(); - ArrayViewT< T const, 2, 0 > const vectorN_JI = m_vectorN_JI.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_IJ > const vectorN_IJ = m_vectorN_IJ.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_JI > const vectorN_JI = m_vectorN_JI.toViewConst(); T const ( &vectorN_local )[ N ] = m_vectorN_local; - ArrayViewT< T const, 2, 1 > const vectorM_IJ = m_vectorM_IJ.toViewConst(); - ArrayViewT< T const, 2, 0 > const vectorM_JI = m_vectorM_JI.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_IJ > const vectorM_IJ = m_vectorM_IJ.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_JI > const vectorM_JI = m_vectorM_JI.toViewConst(); T const ( &vectorM_local )[ M ] = m_vectorM_local; std::ptrdiff_t const matrixSeed = m_matrixASeed; @@ -278,16 +278,16 @@ class TwoSizesTest : public ::testing::Test result[ i ] = dot; } - 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(); + ArrayViewT< T const, 3, RAJA::PERM_IJK > const matrixA_IJK = m_matrixA_IJK.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_IKJ > const matrixA_IKJ = m_matrixA_IKJ.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_KJI > const matrixA_KJI = m_matrixA_KJI.toViewConst(); T const ( &matrix_local )[ N ][ M ] = m_matrixA_local; - ArrayViewT< T, 2, 1 > const vectorN_IJ = m_vectorN_IJ.toView(); - ArrayViewT< T, 2, 0 > const vectorN_JI = m_vectorN_JI.toView(); + ArrayViewT< T, 2, RAJA::PERM_IJ > const vectorN_IJ = m_vectorN_IJ.toView(); + ArrayViewT< T, 2, RAJA::PERM_JI > const vectorN_JI = m_vectorN_JI.toView(); - ArrayViewT< T const, 2, 1 > const vectorM_IJ = m_vectorM_IJ.toViewConst(); - ArrayViewT< T const, 2, 0 > const vectorM_JI = m_vectorM_JI.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_IJ > const vectorM_IJ = m_vectorM_IJ.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_JI > const vectorM_JI = m_vectorM_JI.toViewConst(); T const ( &vectorM_local )[ M ] = m_vectorM_local; std::ptrdiff_t const vectorNSeed = m_vectorNSeed; @@ -339,16 +339,16 @@ class TwoSizesTest : public ::testing::Test result[ i ] = m_vectorN_local[ i ] + dot; } - 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(); + ArrayViewT< T const, 3, RAJA::PERM_IJK > const matrixA_IJK = m_matrixA_IJK.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_IKJ > const matrixA_IKJ = m_matrixA_IKJ.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_KJI > const matrixA_KJI = m_matrixA_KJI.toViewConst(); T const ( &matrix_local )[ N ][ M ] = m_matrixA_local; - ArrayViewT< T, 2, 1 > const vectorN_IJ = m_vectorN_IJ.toView(); - ArrayViewT< T, 2, 0 > const vectorN_JI = m_vectorN_JI.toView(); + ArrayViewT< T, 2, RAJA::PERM_IJ > const vectorN_IJ = m_vectorN_IJ.toView(); + ArrayViewT< T, 2, RAJA::PERM_JI > const vectorN_JI = m_vectorN_JI.toView(); - ArrayViewT< T const, 2, 1 > const vectorM_IJ = m_vectorM_IJ.toViewConst(); - ArrayViewT< T const, 2, 0 > const vectorM_JI = m_vectorM_JI.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_IJ > const vectorM_IJ = m_vectorM_IJ.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_JI > const vectorM_JI = m_vectorM_JI.toViewConst(); T const ( &vectorM_local )[ M ] = m_vectorM_local; std::ptrdiff_t const vectorNSeed = m_vectorNSeed; @@ -400,17 +400,17 @@ class TwoSizesTest : public ::testing::Test result[ i ] = dot; } - 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(); + ArrayViewT< T const, 3, RAJA::PERM_IJK > const matrixA_IJK = m_matrixA_IJK.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_IKJ > const matrixA_IKJ = m_matrixA_IKJ.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_KJI > const matrixA_KJI = m_matrixA_KJI.toViewConst(); T const ( &matrix_local )[ N ][ M ] = m_matrixA_local; - ArrayViewT< T const, 2, 1 > const vectorN_IJ = m_vectorN_IJ.toViewConst(); - ArrayViewT< T const, 2, 0 > const vectorN_JI = m_vectorN_JI.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_IJ > const vectorN_IJ = m_vectorN_IJ.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_JI > const vectorN_JI = m_vectorN_JI.toViewConst(); T const ( &vectorN_local )[ N ] = m_vectorN_local; - ArrayViewT< T, 2, 1 > const vectorM_IJ = m_vectorM_IJ.toView(); - ArrayViewT< T, 2, 0 > const vectorM_JI = m_vectorM_JI.toView(); + ArrayViewT< T, 2, RAJA::PERM_IJ > const vectorM_IJ = m_vectorM_IJ.toView(); + ArrayViewT< T, 2, RAJA::PERM_JI > const vectorM_JI = m_vectorM_JI.toView(); std::ptrdiff_t const vectorMSeed = m_vectorMSeed; @@ -461,17 +461,17 @@ class TwoSizesTest : public ::testing::Test result[ i ] = m_vectorM_local[ i ] + dot; } - 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(); + ArrayViewT< T const, 3, RAJA::PERM_IJK > const matrixA_IJK = m_matrixA_IJK.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_IKJ > const matrixA_IKJ = m_matrixA_IKJ.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_KJI > const matrixA_KJI = m_matrixA_KJI.toViewConst(); T const ( &matrix_local )[ N ][ M ] = m_matrixA_local; - ArrayViewT< T const, 2, 1 > const vectorN_IJ = m_vectorN_IJ.toViewConst(); - ArrayViewT< T const, 2, 0 > const vectorN_JI = m_vectorN_JI.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_IJ > const vectorN_IJ = m_vectorN_IJ.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_JI > const vectorN_JI = m_vectorN_JI.toViewConst(); T const ( &vectorN_local )[ N ] = m_vectorN_local; - ArrayViewT< T, 2, 1 > const vectorM_IJ = m_vectorM_IJ.toView(); - ArrayViewT< T, 2, 0 > const vectorM_JI = m_vectorM_JI.toView(); + ArrayViewT< T, 2, RAJA::PERM_IJ > const vectorM_IJ = m_vectorM_IJ.toView(); + ArrayViewT< T, 2, RAJA::PERM_JI > const vectorM_JI = m_vectorM_JI.toView(); std::ptrdiff_t const vectorMSeed = m_vectorMSeed; @@ -511,13 +511,13 @@ class TwoSizesTest : public ::testing::Test void testCopy() { - 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(); + ArrayViewT< T, 3, RAJA::PERM_IJK > const matrixA_IJK = m_matrixA_IJK.toView(); + ArrayViewT< T, 3, RAJA::PERM_IKJ > const matrixA_IKJ = m_matrixA_IKJ.toView(); + ArrayViewT< T, 3, RAJA::PERM_KJI > const matrixA_KJI = m_matrixA_KJI.toView(); - 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(); + ArrayViewT< T const, 3, RAJA::PERM_IJK > const matrixB_IJK_view = m_matrixB_IJK.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_IKJ > const matrixB_IKJ_view = m_matrixB_IKJ.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_KJI > const matrixB_KJI_view = m_matrixB_KJI.toViewConst(); T const ( &matrixB_local )[ N ][ M ] = m_matrixB_local; std::ptrdiff_t const matrixSeed = m_matrixASeed; @@ -568,13 +568,13 @@ class TwoSizesTest : public ::testing::Test } } - 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(); + ArrayViewT< T, 3, RAJA::PERM_IJK > const matrixA_IJK = m_matrixA_IJK.toView(); + ArrayViewT< T, 3, RAJA::PERM_IKJ > const matrixA_IKJ = m_matrixA_IKJ.toView(); + ArrayViewT< T, 3, RAJA::PERM_KJI > const matrixA_KJI = m_matrixA_KJI.toView(); - 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(); + ArrayViewT< T const, 3, RAJA::PERM_IJK > const matrixB_IJK_view = m_matrixB_IJK.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_IKJ > const matrixB_IKJ_view = m_matrixB_IKJ.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_KJI > const matrixB_KJI_view = m_matrixB_KJI.toViewConst(); T const ( &matrixB_local )[ N ][ M ] = m_matrixB_local; std::ptrdiff_t const matrixSeed = m_matrixASeed; @@ -624,13 +624,13 @@ class TwoSizesTest : public ::testing::Test } } - 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(); + ArrayViewT< T, 3, RAJA::PERM_IJK > const matrixA_IJK = m_matrixA_IJK.toView(); + ArrayViewT< T, 3, RAJA::PERM_IKJ > const matrixA_IKJ = m_matrixA_IKJ.toView(); + ArrayViewT< T, 3, RAJA::PERM_KJI > const matrixA_KJI = m_matrixA_KJI.toView(); - 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(); + ArrayViewT< T const, 3, RAJA::PERM_IJK > const matrixB_IJK_view = m_matrixB_IJK.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_IKJ > const matrixB_IKJ_view = m_matrixB_IKJ.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_KJI > const matrixB_KJI_view = m_matrixB_KJI.toViewConst(); T const ( &matrixB_local )[ N ][ M ] = m_matrixB_local; std::ptrdiff_t const matrixSeed = m_matrixASeed; @@ -671,13 +671,13 @@ class TwoSizesTest : public ::testing::Test void testScaledAdd() { - 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(); + ArrayViewT< T, 3, RAJA::PERM_IJK > const matrixA_IJK = m_matrixA_IJK.toView(); + ArrayViewT< T, 3, RAJA::PERM_IKJ > const matrixA_IKJ = m_matrixA_IKJ.toView(); + ArrayViewT< T, 3, RAJA::PERM_KJI > const matrixA_KJI = m_matrixA_KJI.toView(); - ArrayViewT< T const, 3, 2 > const matrixB_IJK_view = m_matrixB_IJK.toView(); - ArrayViewT< T const, 3, 1 > const matrixB_IKJ_view = m_matrixB_IKJ.toView(); - ArrayViewT< T const, 3, 0 > const matrixB_KJI_view = m_matrixB_KJI.toView(); + ArrayViewT< T const, 3, RAJA::PERM_IJK > const matrixB_IJK_view = m_matrixB_IJK.toView(); + ArrayViewT< T const, 3, RAJA::PERM_IKJ > const matrixB_IKJ_view = m_matrixB_IKJ.toView(); + ArrayViewT< T const, 3, RAJA::PERM_KJI > const matrixB_KJI_view = m_matrixB_KJI.toView(); T const ( &matrixB_local )[ N ][ M ] = m_matrixB_local; @@ -744,14 +744,14 @@ class TwoSizesTest : public ::testing::Test } } - ArrayViewT< T const, 3, 2 > const matrixMN_IJK = m_matrixMN_IJK.toViewConst(); - ArrayViewT< T const, 3, 1 > const matrixMN_IKJ = m_matrixMN_IKJ.toViewConst(); - ArrayViewT< T const, 3, 0 > const matrixMN_KJI = m_matrixMN_KJI.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_IJK > const matrixMN_IJK = m_matrixMN_IJK.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_IKJ > const matrixMN_IKJ = m_matrixMN_IKJ.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_KJI > const matrixMN_KJI = m_matrixMN_KJI.toViewConst(); T const ( &matrixMN_local )[ M ][ N ] = m_matrixMN_local; - ArrayViewT< T, 3, 2 > const matrixNN_IJK = m_matrixNN_IJK.toView(); - ArrayViewT< T, 3, 1 > const matrixNN_IKJ = m_matrixNN_IKJ.toView(); - ArrayViewT< T, 3, 0 > const matrixNN_KJI = m_matrixNN_KJI.toView(); + ArrayViewT< T, 3, RAJA::PERM_IJK > const matrixNN_IJK = m_matrixNN_IJK.toView(); + ArrayViewT< T, 3, RAJA::PERM_IKJ > const matrixNN_IKJ = m_matrixNN_IKJ.toView(); + ArrayViewT< T, 3, RAJA::PERM_KJI > const matrixNN_KJI = m_matrixNN_KJI.toView(); std::ptrdiff_t const matrixNNSeed = m_matrixNNSeed; @@ -798,14 +798,14 @@ class TwoSizesTest : public ::testing::Test } } - 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(); + ArrayViewT< T const, 3, RAJA::PERM_IJK > const matrixA_IJK = m_matrixA_IJK.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_IKJ > const matrixA_IKJ = m_matrixA_IKJ.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_KJI > const matrixA_KJI = m_matrixA_KJI.toViewConst(); T const ( &matrixA_local )[ N ][ M ] = m_matrixA_local; - ArrayViewT< T, 3, 2 > const matrixNN_IJK = m_matrixNN_IJK.toView(); - ArrayViewT< T, 3, 1 > const matrixNN_IKJ = m_matrixNN_IKJ.toView(); - ArrayViewT< T, 3, 0 > const matrixNN_KJI = m_matrixNN_KJI.toView(); + ArrayViewT< T, 3, RAJA::PERM_IJK > const matrixNN_IJK = m_matrixNN_IJK.toView(); + ArrayViewT< T, 3, RAJA::PERM_IKJ > const matrixNN_IKJ = m_matrixNN_IKJ.toView(); + ArrayViewT< T, 3, RAJA::PERM_KJI > const matrixNN_KJI = m_matrixNN_KJI.toView(); std::ptrdiff_t const matrixNNSeed = m_matrixNNSeed; @@ -838,13 +838,13 @@ class TwoSizesTest : public ::testing::Test void testTranspose() { - 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(); + ArrayViewT< T, 3, RAJA::PERM_IJK > const matrixA_IJK = m_matrixA_IJK.toView(); + ArrayViewT< T, 3, RAJA::PERM_IKJ > const matrixA_IKJ = m_matrixA_IKJ.toView(); + ArrayViewT< T, 3, RAJA::PERM_KJI > const matrixA_KJI = m_matrixA_KJI.toView(); - ArrayViewT< T const, 3, 2 > const matrixMN_IJK_view = m_matrixMN_IJK.toViewConst(); - ArrayViewT< T const, 3, 1 > const matrixMN_IKJ_view = m_matrixMN_IKJ.toViewConst(); - ArrayViewT< T const, 3, 0 > const matrixMN_KJI_view = m_matrixMN_KJI.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_IJK > const matrixMN_IJK_view = m_matrixMN_IJK.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_IKJ > const matrixMN_IKJ_view = m_matrixMN_IKJ.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_KJI > const matrixMN_KJI_view = m_matrixMN_KJI.toViewConst(); T const ( &matrixMN_local )[ M ][ N ] = m_matrixMN_local; std::ptrdiff_t const matrixSeed = m_matrixASeed; diff --git a/unitTests/testTensorOpsTwoSizes1.cpp b/unitTests/testTensorOpsTwoSizes1.cpp index 96ac793c..99f423e1 100644 --- a/unitTests/testTensorOpsTwoSizes1.cpp +++ b/unitTests/testTensorOpsTwoSizes1.cpp @@ -75,9 +75,9 @@ class TwoSizesTest : public ::testing::Test } } - 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(); + ArrayViewT< T, 3, RAJA::PERM_IJK > const matrixA_IJK = m_matrixA_IJK.toView(); + ArrayViewT< T, 3, RAJA::PERM_IKJ > const matrixA_IKJ = m_matrixA_IKJ.toView(); + ArrayViewT< T, 3, RAJA::PERM_KJI > 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() { - 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(); + ArrayViewT< T, 3, RAJA::PERM_IJK > const matrixA_IJK = m_matrixA_IJK.toView(); + ArrayViewT< T, 3, RAJA::PERM_IKJ > const matrixA_IKJ = m_matrixA_IKJ.toView(); + ArrayViewT< T, 3, RAJA::PERM_KJI > 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 } } - 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(); + ArrayViewT< T, 3, RAJA::PERM_IJK > const matrixA_IJK = m_matrixA_IJK.toView(); + ArrayViewT< T, 3, RAJA::PERM_IKJ > const matrixA_IKJ = m_matrixA_IKJ.toView(); + ArrayViewT< T, 3, RAJA::PERM_KJI > const matrixA_KJI = m_matrixA_KJI.toView(); - ArrayViewT< T const, 2, 1 > const vectorN_IJ = m_vectorN_IJ.toViewConst(); - ArrayViewT< T const, 2, 0 > const vectorN_JI = m_vectorN_JI.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_IJ > const vectorN_IJ = m_vectorN_IJ.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_JI > const vectorN_JI = m_vectorN_JI.toViewConst(); T const ( &vectorN_local )[ N ] = m_vectorN_local; - ArrayViewT< T const, 2, 1 > const vectorM_IJ = m_vectorM_IJ.toViewConst(); - ArrayViewT< T const, 2, 0 > const vectorM_JI = m_vectorM_JI.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_IJ > const vectorM_IJ = m_vectorM_IJ.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_JI > 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 } } - 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(); + ArrayViewT< T, 3, RAJA::PERM_IJK > const matrixA_IJK = m_matrixA_IJK.toView(); + ArrayViewT< T, 3, RAJA::PERM_IKJ > const matrixA_IKJ = m_matrixA_IKJ.toView(); + ArrayViewT< T, 3, RAJA::PERM_KJI > const matrixA_KJI = m_matrixA_KJI.toView(); - ArrayViewT< T const, 2, 1 > const vectorN_IJ = m_vectorN_IJ.toViewConst(); - ArrayViewT< T const, 2, 0 > const vectorN_JI = m_vectorN_JI.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_IJ > const vectorN_IJ = m_vectorN_IJ.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_JI > const vectorN_JI = m_vectorN_JI.toViewConst(); T const ( &vectorN_local )[ N ] = m_vectorN_local; - ArrayViewT< T const, 2, 1 > const vectorM_IJ = m_vectorM_IJ.toViewConst(); - ArrayViewT< T const, 2, 0 > const vectorM_JI = m_vectorM_JI.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_IJ > const vectorM_IJ = m_vectorM_IJ.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_JI > 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; } - 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(); + ArrayViewT< T const, 3, RAJA::PERM_IJK > const matrixA_IJK = m_matrixA_IJK.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_IKJ > const matrixA_IKJ = m_matrixA_IKJ.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_KJI > const matrixA_KJI = m_matrixA_KJI.toViewConst(); T const ( &matrix_local )[ N ][ M ] = m_matrixA_local; - ArrayViewT< T, 2, 1 > const vectorN_IJ = m_vectorN_IJ.toView(); - ArrayViewT< T, 2, 0 > const vectorN_JI = m_vectorN_JI.toView(); + ArrayViewT< T, 2, RAJA::PERM_IJ > const vectorN_IJ = m_vectorN_IJ.toView(); + ArrayViewT< T, 2, RAJA::PERM_JI > const vectorN_JI = m_vectorN_JI.toView(); - ArrayViewT< T const, 2, 1 > const vectorM_IJ = m_vectorM_IJ.toViewConst(); - ArrayViewT< T const, 2, 0 > const vectorM_JI = m_vectorM_JI.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_IJ > const vectorM_IJ = m_vectorM_IJ.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_JI > 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; } - 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(); + ArrayViewT< T const, 3, RAJA::PERM_IJK > const matrixA_IJK = m_matrixA_IJK.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_IKJ > const matrixA_IKJ = m_matrixA_IKJ.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_KJI > const matrixA_KJI = m_matrixA_KJI.toViewConst(); T const ( &matrix_local )[ N ][ M ] = m_matrixA_local; - ArrayViewT< T, 2, 1 > const vectorN_IJ = m_vectorN_IJ.toView(); - ArrayViewT< T, 2, 0 > const vectorN_JI = m_vectorN_JI.toView(); + ArrayViewT< T, 2, RAJA::PERM_IJ > const vectorN_IJ = m_vectorN_IJ.toView(); + ArrayViewT< T, 2, RAJA::PERM_JI > const vectorN_JI = m_vectorN_JI.toView(); - ArrayViewT< T const, 2, 1 > const vectorM_IJ = m_vectorM_IJ.toViewConst(); - ArrayViewT< T const, 2, 0 > const vectorM_JI = m_vectorM_JI.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_IJ > const vectorM_IJ = m_vectorM_IJ.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_JI > 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; } - 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(); + ArrayViewT< T const, 3, RAJA::PERM_IJK > const matrixA_IJK = m_matrixA_IJK.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_IKJ > const matrixA_IKJ = m_matrixA_IKJ.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_KJI > const matrixA_KJI = m_matrixA_KJI.toViewConst(); T const ( &matrix_local )[ N ][ M ] = m_matrixA_local; - ArrayViewT< T const, 2, 1 > const vectorN_IJ = m_vectorN_IJ.toViewConst(); - ArrayViewT< T const, 2, 0 > const vectorN_JI = m_vectorN_JI.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_IJ > const vectorN_IJ = m_vectorN_IJ.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_JI > const vectorN_JI = m_vectorN_JI.toViewConst(); T const ( &vectorN_local )[ N ] = m_vectorN_local; - ArrayViewT< T, 2, 1 > const vectorM_IJ = m_vectorM_IJ.toView(); - ArrayViewT< T, 2, 0 > const vectorM_JI = m_vectorM_JI.toView(); + ArrayViewT< T, 2, RAJA::PERM_IJ > const vectorM_IJ = m_vectorM_IJ.toView(); + ArrayViewT< T, 2, RAJA::PERM_JI > 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; } - 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(); + ArrayViewT< T const, 3, RAJA::PERM_IJK > const matrixA_IJK = m_matrixA_IJK.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_IKJ > const matrixA_IKJ = m_matrixA_IKJ.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_KJI > const matrixA_KJI = m_matrixA_KJI.toViewConst(); T const ( &matrix_local )[ N ][ M ] = m_matrixA_local; - ArrayViewT< T const, 2, 1 > const vectorN_IJ = m_vectorN_IJ.toViewConst(); - ArrayViewT< T const, 2, 0 > const vectorN_JI = m_vectorN_JI.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_IJ > const vectorN_IJ = m_vectorN_IJ.toViewConst(); + ArrayViewT< T const, 2, RAJA::PERM_JI > const vectorN_JI = m_vectorN_JI.toViewConst(); T const ( &vectorN_local )[ N ] = m_vectorN_local; - ArrayViewT< T, 2, 1 > const vectorM_IJ = m_vectorM_IJ.toView(); - ArrayViewT< T, 2, 0 > const vectorM_JI = m_vectorM_JI.toView(); + ArrayViewT< T, 2, RAJA::PERM_IJ > const vectorM_IJ = m_vectorM_IJ.toView(); + ArrayViewT< T, 2, RAJA::PERM_JI > 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() { - 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(); + ArrayViewT< T, 3, RAJA::PERM_IJK > const matrixA_IJK = m_matrixA_IJK.toView(); + ArrayViewT< T, 3, RAJA::PERM_IKJ > const matrixA_IKJ = m_matrixA_IKJ.toView(); + ArrayViewT< T, 3, RAJA::PERM_KJI > const matrixA_KJI = m_matrixA_KJI.toView(); - 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(); + ArrayViewT< T const, 3, RAJA::PERM_IJK > const matrixB_IJK_view = m_matrixB_IJK.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_IKJ > const matrixB_IKJ_view = m_matrixB_IKJ.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_KJI > 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 } } - 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(); + ArrayViewT< T, 3, RAJA::PERM_IJK > const matrixA_IJK = m_matrixA_IJK.toView(); + ArrayViewT< T, 3, RAJA::PERM_IKJ > const matrixA_IKJ = m_matrixA_IKJ.toView(); + ArrayViewT< T, 3, RAJA::PERM_KJI > const matrixA_KJI = m_matrixA_KJI.toView(); - 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(); + ArrayViewT< T const, 3, RAJA::PERM_IJK > const matrixB_IJK_view = m_matrixB_IJK.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_IKJ > const matrixB_IKJ_view = m_matrixB_IKJ.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_KJI > 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 } } - 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(); + ArrayViewT< T, 3, RAJA::PERM_IJK > const matrixA_IJK = m_matrixA_IJK.toView(); + ArrayViewT< T, 3, RAJA::PERM_IKJ > const matrixA_IKJ = m_matrixA_IKJ.toView(); + ArrayViewT< T, 3, RAJA::PERM_KJI > const matrixA_KJI = m_matrixA_KJI.toView(); - 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(); + ArrayViewT< T const, 3, RAJA::PERM_IJK > const matrixB_IJK_view = m_matrixB_IJK.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_IKJ > const matrixB_IKJ_view = m_matrixB_IKJ.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_KJI > 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,13 +672,13 @@ class TwoSizesTest : public ::testing::Test void testScaledAdd() { - 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(); + ArrayViewT< T, 3, RAJA::PERM_IJK > const matrixA_IJK = m_matrixA_IJK.toView(); + ArrayViewT< T, 3, RAJA::PERM_IKJ > const matrixA_IKJ = m_matrixA_IKJ.toView(); + ArrayViewT< T, 3, RAJA::PERM_KJI > const matrixA_KJI = m_matrixA_KJI.toView(); - ArrayViewT< T const, 3, 2 > const matrixB_IJK_view = m_matrixB_IJK.toView(); - ArrayViewT< T const, 3, 1 > const matrixB_IKJ_view = m_matrixB_IKJ.toView(); - ArrayViewT< T const, 3, 0 > const matrixB_KJI_view = m_matrixB_KJI.toView(); + ArrayViewT< T const, 3, RAJA::PERM_IJK > const matrixB_IJK_view = m_matrixB_IJK.toView(); + ArrayViewT< T const, 3, RAJA::PERM_IKJ > const matrixB_IKJ_view = m_matrixB_IKJ.toView(); + ArrayViewT< T const, 3, RAJA::PERM_KJI > const matrixB_KJI_view = m_matrixB_KJI.toView(); T const ( &matrixB_local )[ N ][ M ] = m_matrixB_local; @@ -745,14 +745,14 @@ class TwoSizesTest : public ::testing::Test } } - ArrayViewT< T const, 3, 2 > const matrixMN_IJK = m_matrixMN_IJK.toViewConst(); - ArrayViewT< T const, 3, 1 > const matrixMN_IKJ = m_matrixMN_IKJ.toViewConst(); - ArrayViewT< T const, 3, 0 > const matrixMN_KJI = m_matrixMN_KJI.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_IJK > const matrixMN_IJK = m_matrixMN_IJK.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_IKJ > const matrixMN_IKJ = m_matrixMN_IKJ.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_KJI > const matrixMN_KJI = m_matrixMN_KJI.toViewConst(); T const ( &matrixMN_local )[ M ][ N ] = m_matrixMN_local; - ArrayViewT< T, 3, 2 > const matrixNN_IJK = m_matrixNN_IJK.toView(); - ArrayViewT< T, 3, 1 > const matrixNN_IKJ = m_matrixNN_IKJ.toView(); - ArrayViewT< T, 3, 0 > const matrixNN_KJI = m_matrixNN_KJI.toView(); + ArrayViewT< T, 3, RAJA::PERM_IJK > const matrixNN_IJK = m_matrixNN_IJK.toView(); + ArrayViewT< T, 3, RAJA::PERM_IKJ > const matrixNN_IKJ = m_matrixNN_IKJ.toView(); + ArrayViewT< T, 3, RAJA::PERM_KJI > const matrixNN_KJI = m_matrixNN_KJI.toView(); std::ptrdiff_t const matrixNNSeed = m_matrixNNSeed; @@ -799,14 +799,14 @@ class TwoSizesTest : public ::testing::Test } } - 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(); + ArrayViewT< T const, 3, RAJA::PERM_IJK > const matrixA_IJK = m_matrixA_IJK.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_IKJ > const matrixA_IKJ = m_matrixA_IKJ.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_KJI > const matrixA_KJI = m_matrixA_KJI.toViewConst(); T const ( &matrixA_local )[ N ][ M ] = m_matrixA_local; - ArrayViewT< T, 3, 2 > const matrixNN_IJK = m_matrixNN_IJK.toView(); - ArrayViewT< T, 3, 1 > const matrixNN_IKJ = m_matrixNN_IKJ.toView(); - ArrayViewT< T, 3, 0 > const matrixNN_KJI = m_matrixNN_KJI.toView(); + ArrayViewT< T, 3, RAJA::PERM_IJK > const matrixNN_IJK = m_matrixNN_IJK.toView(); + ArrayViewT< T, 3, RAJA::PERM_IKJ > const matrixNN_IKJ = m_matrixNN_IKJ.toView(); + ArrayViewT< T, 3, RAJA::PERM_KJI > const matrixNN_KJI = m_matrixNN_KJI.toView(); std::ptrdiff_t const matrixNNSeed = m_matrixNNSeed; @@ -839,13 +839,13 @@ class TwoSizesTest : public ::testing::Test void testTranspose() { - 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(); + ArrayViewT< T, 3, RAJA::PERM_IJK > const matrixA_IJK = m_matrixA_IJK.toView(); + ArrayViewT< T, 3, RAJA::PERM_IKJ > const matrixA_IKJ = m_matrixA_IKJ.toView(); + ArrayViewT< T, 3, RAJA::PERM_KJI > const matrixA_KJI = m_matrixA_KJI.toView(); - ArrayViewT< T const, 3, 2 > const matrixMN_IJK_view = m_matrixMN_IJK.toViewConst(); - ArrayViewT< T const, 3, 1 > const matrixMN_IKJ_view = m_matrixMN_IKJ.toViewConst(); - ArrayViewT< T const, 3, 0 > const matrixMN_KJI_view = m_matrixMN_KJI.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_IJK > const matrixMN_IJK_view = m_matrixMN_IJK.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_IKJ > const matrixMN_IKJ_view = m_matrixMN_IKJ.toViewConst(); + ArrayViewT< T const, 3, RAJA::PERM_KJI > const matrixMN_KJI_view = m_matrixMN_KJI.toViewConst(); T const ( &matrixMN_local )[ M ][ N ] = m_matrixMN_local; std::ptrdiff_t const matrixSeed = m_matrixASeed; diff --git a/unitTests/testTupleManipulation.cpp b/unitTests/testTupleManipulation.cpp new file mode 100644 index 00000000..fa7839a4 --- /dev/null +++ b/unitTests/testTupleManipulation.cpp @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2021, Lawrence Livermore National Security, LLC and LvArray contributors. + * All rights reserved. + * See the LICENSE file for details. + * SPDX-License-Identifier: (BSD-3-Clause) + */ + +// Source includes +#include "Constant.hpp" +#include "tupleManipulation.hpp" + +// TPL includes +#include + +namespace LvArray +{ + +namespace tupleManipulation +{ + +static_assert( std::is_same_v< camp::tuple<>, decltype( repeat< 0 >( _1{} ) ) > ); +static_assert( std::is_same_v< camp::tuple< _1 >, decltype( repeat< 1 >( _1{} ) ) > ); +static_assert( std::is_same_v< camp::tuple< _1, _1 >, decltype( repeat< 2 >( _1{} ) ) > ); + +static_assert( std::is_same_v< camp::tuple< _0 >, decltype( replace< 0 >( makeTuple( _1{} ), _0{} ) ) > ); +static_assert( std::is_same_v< camp::tuple< _0, _2 >, decltype( replace< 0 >( makeTuple( _1{}, _2{} ), _0{} ) ) > ); +static_assert( std::is_same_v< camp::tuple< _1, _0 >, decltype( replace< 1 >( makeTuple( _1{}, _2{} ), _0{} ) ) > ); +static_assert( std::is_same_v< camp::tuple< int, _2 >, decltype( replace< 0 >( makeTuple( _1{}, _2{} ), 0 ) ) > ); +static_assert( std::is_same_v< camp::tuple< _1, int >, decltype( replace< 1 >( makeTuple( _1{}, _2{} ), 0 ) ) > ); + +static_assert( std::is_same_v< camp::tuple< _1 >, decltype( append( makeTuple(), _1{} ) ) > ); +static_assert( std::is_same_v< camp::tuple< _1, _1, _1 >, decltype( append<3>( makeTuple(), _1{} ) ) > ); +static_assert( std::is_same_v< camp::tuple< _1, _2, _3 >, decltype( append( makeTuple( _1{}, _2{} ), _3{} ) ) > ); + +static_assert( std::is_same_v< camp::tuple< _1 >, decltype( prepend( makeTuple(), _1{} ) ) > ); +static_assert( std::is_same_v< camp::tuple< _1, _1, _1 >, decltype( prepend<3>( makeTuple(), _1{} ) ) > ); +static_assert( std::is_same_v< camp::tuple< _3, _1, _2 >, decltype( prepend( makeTuple( _1{}, _2{} ), _3{} ) ) > ); + +static_assert( std::is_same_v< camp::tuple< _1, _1 >, decltype( insert<0,2>( makeTuple(), _1{} ) ) > ); +static_assert( std::is_same_v< camp::tuple< _0, _1, _1, _0 >, decltype( insert<1,2>( makeTuple( _0{}, _0{} ), _1{} ) ) > ); + +static_assert( std::is_same_v< camp::tuple<>, decltype( remove<0,2>( makeTuple( _1{}, _1{} ) ) ) > ); +static_assert( std::is_same_v< camp::tuple< _0, _0 >, decltype( remove<1,2>( makeTuple( _0{}, _1{}, _1{}, _0{} ) ) ) > ); + +static_assert( std::is_same_v< camp::tuple<>, decltype( select( makeTuple( _1{}, _2{}, _3{} ), camp::idx_seq<>{} ) ) > ); +static_assert( std::is_same_v< camp::tuple< _1, _3 >, decltype( select( makeTuple( _1{}, _2{}, _3{} ), camp::idx_seq<0,2>{} ) ) > ); + +static_assert( std::is_same_v< camp::tuple<>, decltype( take<1,1>( makeTuple( _1{}, _2{}, _3{} ) ) ) > ); +static_assert( std::is_same_v< camp::tuple< _2, _3 >, decltype( take<1,3>( makeTuple( _1{}, _2{}, _3{} ) ) ) > ); + +static_assert( std::is_same_v< camp::tuple<>, decltype( zip2( makeTuple(), makeTuple() ) ) > ); +static_assert( std::is_same_v< camp::tuple< camp::tuple<>, camp::tuple<> >, decltype( unzip2( makeTuple() ) ) > ); +// camp::tuple's converting constructor is too eager, so it's impossible to construct a tuple> from a temporary. +// Re-enable the following tests after the fix in https://github.com/LLNL/camp/pull/132 makes its way to LvArray. +//static_assert( std::is_same_v< camp::tuple< camp::tuple< _1, _2 > >, decltype( zip2( makeTuple( _1{} ), makeTuple( _2{} ) ) ) > ); +//static_assert( std::is_same_v< camp::tuple< camp::tuple< _1 >, camp::tuple< _2 > >, decltype( unzip2( make_tuple( makeTuple( _1{}, _2{} ) ) ) ) > ); +static_assert( std::is_same_v< camp::tuple< camp::tuple< _1, _2 >, camp::tuple< _3, _4 > >, decltype( zip2( makeTuple( _1{}, _3{} ), makeTuple( _2{}, _4{} ) ) ) > ); +static_assert( std::is_same_v< camp::tuple< camp::tuple< _1, _3 >, camp::tuple< _2, _4 > >, decltype( unzip2( makeTuple( makeTuple( _1{}, _2{} ), makeTuple( _3{}, _4{} ) ) ) ) > ); + +static_assert( std::is_same_v< _1, decltype( foldLeft( makeTuple(), _1{}, op_plus{} ) ) > ); +static_assert( std::is_same_v< _6, decltype( foldLeft( makeTuple( _1{}, _2{}, _3{} ), _1{}, op_mult{} ) ) > ); +static_assert( std::is_same_v< _0, decltype( foldLeft( makeTuple( _1{}, _2{}, _3{} ), _6{}, op_minus{} ) ) > ); + +static_assert( std::is_same_v< _1, decltype( foldRight( makeTuple(), _1{}, op_plus{} ) ) > ); +static_assert( std::is_same_v< _6, decltype( foldRight( makeTuple( _1{}, _2{}, _3{} ), _1{}, op_mult{} ) ) > ); +static_assert( std::is_same_v< _0, decltype( foldRight( makeTuple( _1{}, _2{}, _3{} ), _2{}, op_minus{} ) ) > ); + +static_assert( std::is_same_v< _t, decltype( allOf2( makeTuple( _1{}, _2{} ), makeTuple( _2{}, _3{} ), cmp_lt{} ) ) > ); +static_assert( std::is_same_v< _t, decltype( allOf2( makeTuple( _1{}, _2{} ), makeTuple( _2{}, _3{} ), cmp_le{} ) ) > ); +static_assert( std::is_same_v< _f, decltype( allOf2( makeTuple( _1{}, _2{} ), makeTuple( _2{}, _3{} ), cmp_gt{} ) ) > ); +static_assert( std::is_same_v< _f, decltype( allOf2( makeTuple( _1{}, _2{} ), makeTuple( _2{}, _3{} ), cmp_ge{} ) ) > ); +static_assert( std::is_same_v< _t, decltype( allOf2( makeTuple( _1{}, _2{} ), makeTuple( _1{}, _2{} ), cmp_eq{} ) ) > ); +static_assert( std::is_same_v< _f, decltype( allOf2( makeTuple( _1{}, _2{} ), makeTuple( _1{}, _3{} ), cmp_eq{} ) ) > ); +static_assert( std::is_same_v< _f, decltype( anyOf2( makeTuple( _1{}, _2{} ), makeTuple( _1{}, _2{} ), cmp_ne{} ) ) > ); +static_assert( std::is_same_v< _t, decltype( anyOf2( makeTuple( _1{}, _2{} ), makeTuple( _1{}, _3{} ), cmp_ne{} ) ) > ); + +} // namespace tupleManipulation + +} // namespace LvArray + +int main( int argc, char * * argv ) +{ + ::testing::InitGoogleTest( &argc, argv ); + int const result = RUN_ALL_TESTS(); + return result; +} diff --git a/unitTests/testTypeManipulation.cpp b/unitTests/testTypeManipulation.cpp index 494fb038..a9d59f11 100644 --- a/unitTests/testTypeManipulation.cpp +++ b/unitTests/testTypeManipulation.cpp @@ -155,8 +155,8 @@ TEST( typeManipulation, is_instantiation_of ) template< typename T, int NDIM, typename PERM > using ArrayT = Array< T, NDIM, PERM, 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, typename PERMUTATION > +using ArrayViewT = ArrayView< T, NDIM, PERMUTATION, std::ptrdiff_t, DEFAULT_BUFFER >; template< typename T > using SortedArrayT = SortedArray< T, std::ptrdiff_t, DEFAULT_BUFFER >; @@ -218,9 +218,9 @@ using ObjectsThatHaveTheMethods = ::testing::Types< ArrayT< int, 3, RAJA::PERM_IJK > , ArrayT< std::string, 4, RAJA::PERM_IKLJ > , ArrayT< ArrayT< int, 1, RAJA::PERM_I >, 1, RAJA::PERM_I > - , ArrayViewT< double, 2, 1 > - , ArrayViewT< float const, 4, 2 > - , ArrayViewT< ArrayViewT< std::string, 2, 0 > const, 3, 1 > + , ArrayViewT< double, 2, RAJA::PERM_IJ > + , ArrayViewT< float const, 4, RAJA::PERM_IJLK > + , ArrayViewT< ArrayViewT< std::string, 2, RAJA::PERM_JI > const, 3, RAJA::PERM_IKJ > , SortedArrayT< int > , SortedArrayT< std::string > , SortedArrayViewT< int > @@ -307,53 +307,53 @@ struct GetViewTypes : public ::testing::Test using GetViewTypesTypes = ::testing::Types< std::tuple< ArrayT< int, 3, RAJA::PERM_IJK >, - ArrayViewT< int, 3, 2 >, - ArrayViewT< int, 3, 2 >, - ArrayViewT< int const, 3, 2 >, - ArrayViewT< int, 3, 2 > const, - ArrayViewT< int const, 3, 2 > const + ArrayViewT< int, 3, RAJA::PERM_IJK >, + ArrayViewT< int, 3, RAJA::PERM_IJK >, + ArrayViewT< int const, 3, RAJA::PERM_IJK >, + ArrayViewT< int, 3, RAJA::PERM_IJK > const, + ArrayViewT< int const, 3, RAJA::PERM_IJK > const > , std::tuple< ArrayT< std::string, 4, RAJA::PERM_IKLJ > const, - ArrayViewT< std::string, 4, 1 >, - ArrayViewT< std::string, 4, 1 >, - ArrayViewT< std::string const, 4, 1 >, - ArrayViewT< std::string, 4, 1 > const, - ArrayViewT< std::string const, 4, 1 > const + ArrayViewT< std::string, 4, RAJA::PERM_IKLJ >, + ArrayViewT< std::string, 4, RAJA::PERM_IKLJ >, + ArrayViewT< std::string const, 4, RAJA::PERM_IKLJ >, + ArrayViewT< std::string, 4, RAJA::PERM_IKLJ > const, + ArrayViewT< std::string const, 4, RAJA::PERM_IKLJ > const > , std::tuple< ArrayT< ArrayT< int, 1, RAJA::PERM_I >, 1, RAJA::PERM_I >, - ArrayViewT< ArrayT< int, 1, RAJA::PERM_I >, 1, 0 >, - ArrayViewT< ArrayT< int, 1, RAJA::PERM_I >, 1, 0 >, - ArrayViewT< ArrayT< int, 1, RAJA::PERM_I > const, 1, 0 >, - ArrayViewT< ArrayViewT< int, 1, 0 > const, 1, 0 > const, - ArrayViewT< ArrayViewT< int const, 1, 0 > const, 1, 0 > const + ArrayViewT< ArrayT< int, 1, RAJA::PERM_I >, 1, RAJA::PERM_I >, + ArrayViewT< ArrayT< int, 1, RAJA::PERM_I >, 1, RAJA::PERM_I >, + ArrayViewT< ArrayT< int, 1, RAJA::PERM_I > const, 1, RAJA::PERM_I >, + ArrayViewT< ArrayViewT< int, 1, RAJA::PERM_I > const, 1, RAJA::PERM_I > const, + ArrayViewT< ArrayViewT< int const, 1, RAJA::PERM_I > const, 1, RAJA::PERM_I > const > , std::tuple< ArrayT< ArrayT< ArrayT< int, 2, RAJA::PERM_JI >, 1, RAJA::PERM_I >, 1, RAJA::PERM_I >, - ArrayViewT< ArrayT< ArrayT< int, 2, RAJA::PERM_JI >, 1, RAJA::PERM_I >, 1, 0 >, - ArrayViewT< ArrayT< ArrayT< int, 2, RAJA::PERM_JI >, 1, RAJA::PERM_I >, 1, 0 >, - ArrayViewT< ArrayT< ArrayT< int, 2, RAJA::PERM_JI >, 1, RAJA::PERM_I > const, 1, 0 >, - ArrayViewT< ArrayViewT< ArrayViewT< int, 2, 0 > const, 1, 0 > const, 1, 0 > const, - ArrayViewT< ArrayViewT< ArrayViewT< int const, 2, 0 > const, 1, 0 > const, 1, 0 > const + ArrayViewT< ArrayT< ArrayT< int, 2, RAJA::PERM_JI >, 1, RAJA::PERM_I >, 1, RAJA::PERM_I >, + ArrayViewT< ArrayT< ArrayT< int, 2, RAJA::PERM_JI >, 1, RAJA::PERM_I >, 1, RAJA::PERM_I >, + ArrayViewT< ArrayT< ArrayT< int, 2, RAJA::PERM_JI >, 1, RAJA::PERM_I > const, 1, RAJA::PERM_I >, + ArrayViewT< ArrayViewT< ArrayViewT< int, 2, RAJA::PERM_JI > const, 1, RAJA::PERM_I > const, 1, RAJA::PERM_I > const, + ArrayViewT< ArrayViewT< ArrayViewT< int const, 2, RAJA::PERM_JI > const, 1, RAJA::PERM_I > const, 1, RAJA::PERM_I > const > - , std::tuple< ArrayViewT< double, 2, 1 >, - ArrayViewT< double, 2, 1 >, - ArrayViewT< double, 2, 1 >, - ArrayViewT< double const, 2, 1 >, - ArrayViewT< double, 2, 1 > const, - ArrayViewT< double const, 2, 1 > const + , std::tuple< ArrayViewT< double, 2, RAJA::PERM_IJ >, + ArrayViewT< double, 2, RAJA::PERM_IJ >, + ArrayViewT< double, 2, RAJA::PERM_IJ >, + ArrayViewT< double const, 2, RAJA::PERM_IJ >, + ArrayViewT< double, 2, RAJA::PERM_IJ > const, + ArrayViewT< double const, 2, RAJA::PERM_IJ > const > - , std::tuple< ArrayViewT< char const, 4, 2 > const, - ArrayViewT< char const, 4, 2 >, - ArrayViewT< char const, 4, 2 >, - ArrayViewT< char const, 4, 2 >, - ArrayViewT< char const, 4, 2 > const, - ArrayViewT< char const, 4, 2 > const + , std::tuple< ArrayViewT< char const, 4, RAJA::PERM_IKLJ > const, + ArrayViewT< char const, 4, RAJA::PERM_IKLJ >, + ArrayViewT< char const, 4, RAJA::PERM_IKLJ >, + ArrayViewT< char const, 4, RAJA::PERM_IKLJ >, + ArrayViewT< char const, 4, RAJA::PERM_IKLJ > const, + ArrayViewT< char const, 4, RAJA::PERM_IKLJ > const > - , std::tuple< ArrayViewT< ArrayViewT< std::string, 2, 0 > const, 3, 1 >, - ArrayViewT< ArrayViewT< std::string, 2, 0 > const, 3, 1 >, - ArrayViewT< ArrayViewT< std::string, 2, 0 > const, 3, 1 >, - ArrayViewT< ArrayViewT< std::string, 2, 0 > const, 3, 1 >, - ArrayViewT< ArrayViewT< std::string, 2, 0 > const, 3, 1 > const, - ArrayViewT< ArrayViewT< std::string const, 2, 0 > const, 3, 1 > const + , std::tuple< ArrayViewT< ArrayViewT< std::string, 2, RAJA::PERM_JI > const, 3, RAJA::PERM_IKJ >, + ArrayViewT< ArrayViewT< std::string, 2, RAJA::PERM_JI > const, 3, RAJA::PERM_IKJ >, + ArrayViewT< ArrayViewT< std::string, 2, RAJA::PERM_JI > const, 3, RAJA::PERM_IKJ >, + ArrayViewT< ArrayViewT< std::string, 2, RAJA::PERM_JI > const, 3, RAJA::PERM_IKJ >, + ArrayViewT< ArrayViewT< std::string, 2, RAJA::PERM_JI > const, 3, RAJA::PERM_IKJ > const, + ArrayViewT< ArrayViewT< std::string const, 2, RAJA::PERM_JI > const, 3, RAJA::PERM_IKJ > const > , std::tuple< SortedArrayT< float >, SortedArrayViewT< float const >,