23 #include <RAJA/RAJA.hpp> 28 #ifdef LVARRAY_BOUNDS_CHECK 35 #define ARRAYOFARRAYS_CHECK_BOUNDS( i ) \ 36 LVARRAY_ERROR_IF( !arrayManipulation::isPositive( i ) || i >= this->size(), \ 37 "Bounds Check Failed: i=" << i << " size()=" << this->size() ) 45 #define ARRAYOFARRAYS_CHECK_BOUNDS2( i, j ) \ 46 LVARRAY_ERROR_IF( !arrayManipulation::isPositive( i ) || i >= this->size() || \ 47 !arrayManipulation::isPositive( j ) || j >= this->m_sizes[ i ], \ 48 "Bounds Check Failed: i=" << i << " size()=" << this->size() << \ 49 " j=" << j << " m_sizes[ i ]=" << this->m_sizes[ i ] ) 56 #define ARRAYOFARRAYS_CHECK_INSERT_BOUNDS( i ) \ 57 LVARRAY_ERROR_IF( !arrayManipulation::isPositive( i ) || i > this->size(), \ 58 "Insert Bounds Check Failed: i=" << i << " size()=" << this->size() ) 66 #define ARRAYOFARRAYS_CHECK_INSERT_BOUNDS2( i, j ) \ 67 LVARRAY_ERROR_IF( !arrayManipulation::isPositive( i ) || i >= this->size() || \ 68 !arrayManipulation::isPositive( j ) || j > this->sizeOfArray( i ), \ 69 "Insert Bounds Check Failed: i=" << i << " size()=" << this->size() << \ 70 " j=" << j << " sizeOfArray( i )=" << this->sizeOfArray( i ) ) 78 #define ARRAYOFARRAYS_CAPACITY_CHECK( i, increase ) \ 79 LVARRAY_ERROR_IF( this->sizeOfArray( i ) + increase > this->capacityOfArray( i ), \ 80 "Capacity Check Failed: i=" << i << " increase=" << increase << \ 81 " sizeOfArray( i )=" << this->sizeOfArray( i ) << " capacityOfArray( i )=" << \ 82 this->capacityOfArray( i ) ) 91 #define ARRAYOFARRAYS_ATOMIC_CAPACITY_CHECK( i, previousSize, increase ) \ 92 LVARRAY_ERROR_IF( previousSize + increase > this->capacityOfArray( i ), \ 93 "Capacity Check Failed: i=" << i << " increase=" << increase << \ 94 " sizeOfArray( i )=" << previousSize << " capacityOfArray( i )=" << \ 95 this->capacityOfArray( i ) ) 97 #else // LVARRAY_BOUNDS_CHECK 104 #define ARRAYOFARRAYS_CHECK_BOUNDS( i ) 112 #define ARRAYOFARRAYS_CHECK_BOUNDS2( i, j ) 119 #define ARRAYOFARRAYS_CHECK_INSERT_BOUNDS( i ) 127 #define ARRAYOFARRAYS_CHECK_INSERT_BOUNDS2( i, j ) 135 #define ARRAYOFARRAYS_CAPACITY_CHECK( i, increase ) 144 #define ARRAYOFARRAYS_ATOMIC_CAPACITY_CHECK( i, previousSize, increase ) 146 #endif // LVARRAY_BOUNDS_CHECK 164 template<
typename T,
167 template<
typename >
class BUFFER_TYPE >
175 using SIZE_TYPE = std::conditional_t< CONST_SIZES, INDEX_TYPE const, INDEX_TYPE_NC >;
178 static_assert( !std::is_const< T >::value || (std::is_const< INDEX_TYPE >::value && CONST_SIZES),
179 "When T is const INDEX_TYPE must also be const and CONST_SIZES must be true" );
180 static_assert( std::is_integral< INDEX_TYPE >::value,
"INDEX_TYPE must be integral." );
221 { src.m_numArrays = 0; }
232 BUFFER_TYPE< INDEX_TYPE >
const & offsets,
233 BUFFER_TYPE< SIZE_TYPE >
const & sizes,
234 BUFFER_TYPE< T >
const & values ):
259 m_sizes = std::move( src.m_sizes );
260 m_values = std::move( src.m_values );
387 T &
operator()( INDEX_TYPE
const i, INDEX_TYPE
const j )
const 408 template<
typename ... ARGS >
429 template<
typename POLICY,
typename ... ARGS >
436 INDEX_TYPE
const previousSize = RAJA::atomicInc< POLICY >( &
m_sizes[ i ] );
451 template<
typename ITER >
453 void appendToArray( INDEX_TYPE
const i, ITER
const first, ITER
const last )
const 472 template<
typename ... ARGS >
474 void emplace( INDEX_TYPE
const i, INDEX_TYPE
const j, ARGS && ... args )
const 494 template<
typename ITER >
499 ITER
const last )
const 517 void eraseFromArray( INDEX_TYPE
const i, INDEX_TYPE
const j, INDEX_TYPE
const n=1 )
const 540 m_sizes.registerTouch( space );
555 #if defined(LVARRAY_USE_CUDA) 556 if( space == MemorySpace::GPU ) touch =
false;
569 template<
typename U >
570 using PairOfBuffers = std::pair< BUFFER_TYPE< U > &, BUFFER_TYPE< U >
const & >;
593 void resize( INDEX_TYPE
const newSize, INDEX_TYPE
const defaultArrayCapacity=0 )
594 {
return resizeImpl( newSize, defaultArrayCapacity ); }
613 template<
class ... BUFFERS >
614 void reserveValues( INDEX_TYPE
const newValueCapacity, BUFFERS & ... buffers )
630 template<
class ... BUFFERS >
637 INDEX_TYPE
const nextOffset =
m_offsets[ i + 1 ];
639 INDEX_TYPE
const sizeOfNextArray =
sizeOfArray( i + 1 );
643 [sizeOfNextArray, nextOffset, shiftAmount] (
auto & buffer )
665 template<
typename POLICY,
typename ... BUFFERS >
667 INDEX_TYPE
const *
const capacities,
668 BUFFERS & ... buffers )
672 #ifdef LVARRAY_BOUNDS_CHECK 673 for( INDEX_TYPE i = 0; i < numSubArrays; ++i )
682 std::fill_n(
m_sizes.data(), numSubArrays, 0 );
689 if( numSubArrays > 0 )
692 RAJA::inclusive_scan< POLICY >(
const_cast< INDEX_TYPE *
>( capacities ),
693 const_cast< INDEX_TYPE * >( capacities + numSubArrays ),
717 { *
this = std::move( src ); }
725 template<
typename ... BUFFERS >
726 void resizeImpl( INDEX_TYPE
const newSize, INDEX_TYPE
const defaultArrayCapacity, BUFFERS & ... buffers )
734 destroyValues( newSize,
m_numArrays, buffers ... );
746 if( defaultArrayCapacity > 0 )
748 for( INDEX_TYPE i = 1; i < newSize + 1 -
m_numArrays; ++i )
750 m_offsets[ m_numArrays + i ] = originalOffset + i * defaultArrayCapacity;
753 INDEX_TYPE
const totalSize =
m_offsets[ newSize ];
772 template<
class ... BUFFERS >
773 void free( BUFFERS & ... buffers )
796 template<
class ... PAIRS_OF_BUFFERS >
798 INDEX_TYPE
const srcMaxOffset,
799 BUFFER_TYPE< INDEX_TYPE >
const & srcOffsets,
800 BUFFER_TYPE< INDEX_TYPE >
const & srcSizes,
801 BUFFER_TYPE< T >
const & srcValues,
802 PAIRS_OF_BUFFERS && ... pairs )
821 auto & dstBuffer = pair.first;
822 auto const & srcBuffer = pair.second;
826 INDEX_TYPE
const offset =
m_offsets[ i ];
829 &srcBuffer[ offset ] + arraySize,
830 &dstBuffer[ offset ] );
843 template<
class ... BUFFERS >
850 INDEX_TYPE
const capacityIncrease = newCapacity - arrayCapacity;
851 if( capacityIncrease == 0 )
return;
853 if( capacityIncrease > 0 )
857 [
this, i, maxOffset, capacityIncrease](
auto & buffer )
863 for( INDEX_TYPE array =
m_numArrays - 1; array > i; --array )
865 INDEX_TYPE
const curArraySize =
sizeOfArray( array );
866 INDEX_TYPE
const curArrayOffset =
m_offsets[ array ];
875 INDEX_TYPE
const arrayOffset =
m_offsets[ i ];
876 INDEX_TYPE
const capacityDecrease = -capacityIncrease;
879 INDEX_TYPE
const newArraySize =
math::min( prevArraySize, newCapacity );
883 [
this, i, capacityDecrease, arrayOffset, newArraySize, prevArraySize] (
auto & buffer )
889 for( INDEX_TYPE array = i + 1; array <
m_numArrays; ++array )
891 INDEX_TYPE
const curArraySize =
sizeOfArray( array );
892 INDEX_TYPE
const curArrayOffset =
m_offsets[array];
901 for( INDEX_TYPE array = i + 1; array <
m_numArrays + 1; ++array )
909 m_offsets.registerTouch( MemorySpace::CPU );
917 template<
typename U >
920 m_offsets.template setName< U >( name +
"/m_offsets" );
921 m_sizes.template setName< U >( name +
"/m_sizes" );
922 m_values.template setName< U >( name +
"/m_values" );
953 template<
class ... BUFFERS >
954 void destroyValues( INDEX_TYPE
const begin, INDEX_TYPE
const end, BUFFERS & ... buffers )
962 std::is_trivially_destructible< typename BUFFERS::value_type > ... >::value )
963 {
move( MemorySpace::CPU,
true ); }
967 if( !std::is_trivially_destructible< std::remove_reference_t< decltype( buffer[ 0 ] ) > >::value )
969 buffer.move( MemorySpace::CPU,
true );
970 for( INDEX_TYPE i = begin; i < end; ++i )
972 INDEX_TYPE
const offset = m_offsets[ i ];
#define ARRAYOFARRAYS_ATOMIC_CAPACITY_CHECK(i, previousSize, increase)
Check that the capacity of array i isn't exceeded when the size is increased by increase.
#define LVARRAY_ASSERT(EXP)
Assert EXP is true with no message.
constexpr std::iterator_traits< ITER >::difference_type iterDistance(ITER first, ITER const last, std::input_iterator_tag)
constexpr T & operator()(INDEX_TYPE const i, INDEX_TYPE const j) const
void reserve(BUFFER &buf, std::ptrdiff_t const size, std::ptrdiff_t const newCapacity)
Reserve space in the buffer for at least the given capacity.
void emplace(INDEX_TYPE const i, INDEX_TYPE const j, ARGS &&... args) const
Insert a value into an array.
#define ARRAYOFARRAYS_CHECK_BOUNDS(i)
Check that i is a valid array index.
INDEX_TYPE size_type
The integer type used for indexing, here for stl compatability.
#define LVARRAY_ERROR_IF_LT(lhs, rhs)
Raise a hard error if one value compares less than the other.
void reserve(INDEX_TYPE const newCapacity)
Reserve space for the given number of arrays.
void emplaceBack(INDEX_TYPE const i, ARGS &&... args) const
Append a value to an array.
This class serves to provide a sliced multidimensional interface to the family of LvArray classes...
INDEX_TYPE IndexType
The integer type used for indexing.
BUFFER_TYPE< INDEX_TYPE > m_offsets
void uninitializedShiftUp(T *const LVARRAY_RESTRICT ptr, std::ptrdiff_t const size, std::ptrdiff_t const amount)
Shift values up into uninitialized memory.
ArrayOfArraysView()=default
A constructor to create an uninitialized ArrayOfArraysView.
constexpr INDEX_TYPE_NC size() const
void dynamicReserve(BUFFER &buf, std::ptrdiff_t const size, std::ptrdiff_t const newCapacity)
If the buffer's capacity is greater than newCapacity this is a no-op. Otherwise the buffer's capacity...
BUFFER_TYPE< T > m_values
void move(MemorySpace const space, bool touch=true) const
Move this ArrayOfArrays to the given memory space.
Contains templates useful for type manipulation.
ArrayOfArraysView & operator=(ArrayOfArraysView &&src)
Move assignment operator..
void copyInto(DST_BUFFER &dst, std::ptrdiff_t const dstSize, SRC_BUFFER const &src, std::ptrdiff_t const srcSize)
Copy values from the source buffer into the destination buffer.
constexpr INDEX_TYPE_NC capacityOfArray(INDEX_TYPE const i) const
BUFFER_TYPE< SIZE_TYPE > m_sizes
Holds the size of each array.
#define ARRAYOFARRAYS_CHECK_BOUNDS2(i, j)
Check that i is a valid array index and that j is a valid index into that array.
globalIndex const value_type
An alias for the type contained in the inner arrays, here for stl compatability.
void compress(BUFFERS &... buffers)
Compress the arrays so that the values of each array are contiguous with no extra capacity in between...
#define CONSTEXPR_WITHOUT_BOUNDS_CHECK
Expands to constexpr when array bound checking is disabled.
constexpr std::enable_if< std::is_signed< INDEX_TYPE >::value, bool >::type isPositive(INDEX_TYPE const i)
void destroy(T *const LVARRAY_RESTRICT ptr, std::ptrdiff_t const size)
Destory the values in the array.
void uninitializedCopy(ITER first, ITER const &last, T *LVARRAY_RESTRICT dst)
Copy construct values from the source to the destination.
ArrayOfArraysView & operator=(ArrayOfArraysView const &)=default
Default copy assignment operator.
void resize(INDEX_TYPE const newSize, INDEX_TYPE const defaultArrayCapacity=0)
Set the number of arrays.
Contains the implementation of LvArray::ArraySlice.
constexpr ArrayOfArraysView< T, INDEX_TYPE const, CONST_SIZES, BUFFER_TYPE > toView() const
void setName(std::string const &name)
Set the name to be displayed whenever the underlying Buffer's user call back is called.
constexpr ArraySlice< T, 1, 0, INDEX_TYPE_NC > operator[](INDEX_TYPE const i) const
This class provides a view into an array of arrays like object.
void emplaceBackAtomic(INDEX_TYPE const i, ARGS &&... args) const
Append a value to an array in a thread safe manner.
#define ARRAYOFARRAYS_CAPACITY_CHECK(i, increase)
Check that the capacity of array i isn't exceeded when the size is increased by increase.
constexpr ArrayOfArraysView(INDEX_TYPE const numArrays, BUFFER_TYPE< INDEX_TYPE > const &offsets, BUFFER_TYPE< SIZE_TYPE > const &sizes, BUFFER_TYPE< T > const &values)
Construct a new ArrayOfArraysView from the given buffers.
Contains functions for manipulating buffers.
void insertIntoArray(INDEX_TYPE const i, INDEX_TYPE const j, ITER const first, ITER const last) const
Insert values into an array.
Contains some portable math functions.
void resizeImpl(INDEX_TYPE const newSize, INDEX_TYPE const defaultArrayCapacity, BUFFERS &... buffers)
Set the number of arrays.
void emplace(T *const LVARRAY_RESTRICT ptr, std::ptrdiff_t const size, std::ptrdiff_t const index, ARGS &&... args)
Insert into the array constructing the new value in place.
constexpr INDEX_TYPE_NC sizeOfArray(INDEX_TYPE const i) const
void appendToArray(INDEX_TYPE const i, ITER const first, ITER const last) const
Append values to an array.
#define ARRAYOFARRAYS_CHECK_INSERT_BOUNDS(i)
Check that i is a valid index to insert an array at.
CONSTEXPR_WITH_NDEBUG INDEX_TYPE_NC capacity() const
Contains functions for manipulating a contiguous array of values.
constexpr ArrayOfArraysView< T, INDEX_TYPE const, true, BUFFER_TYPE > toViewConstSizes() const
MemorySpace
An enum containing the available memory spaces.
constexpr ArrayOfArraysView(ArrayOfArraysView &&src)
Default move constructor.
std::ptrdiff_t append(T *const LVARRAY_RESTRICT ptr, std::ptrdiff_t const size, ITER first, ITER const last)
Append the given values to the array.
void eraseFromArray(INDEX_TYPE const i, INDEX_TYPE const j, INDEX_TYPE const n=1) const
Erase values from an array.
void resizeFromCapacities(INDEX_TYPE const numSubArrays, INDEX_TYPE const *const capacities, BUFFERS &... buffers)
Clears the array and creates a new array with the given number of sub-arrays.
void setEqualTo(INDEX_TYPE const srcNumArrays, INDEX_TYPE const srcMaxOffset, BUFFER_TYPE< INDEX_TYPE > const &srcOffsets, BUFFER_TYPE< INDEX_TYPE > const &srcSizes, BUFFER_TYPE< T > const &srcValues, PAIRS_OF_BUFFERS &&... pairs)
Set this ArrayOfArraysView equal to the provided arrays.
INDEX_TYPE_NC m_numArrays
The number of arrays contained.
ArrayOfArraysView(bool)
Protected constructor to be used by parent classes.
void free(BUFFERS &... buffers)
Destroy all the objects held by this array and free all associated memory.
std::remove_const_t< INDEX_TYPE > INDEX_TYPE_NC
Since INDEX_TYPE should always be const we need an alias for the non const version.
void uninitializedShiftDown(T *const LVARRAY_RESTRICT ptr, std::ptrdiff_t const size, std::ptrdiff_t const amount)
Shift values down into uninitialized memory.
void setCapacityOfArray(INDEX_TYPE const i, INDEX_TYPE const newCapacity, BUFFERS &... buffers)
Set the capacity of the given array.
#define ARRAYOFARRAYS_CHECK_INSERT_BOUNDS2(i, j)
Check that i is a valid array index and that j is a valid insertion index into that array...
void assimilate(ArrayOfArraysView< T, INDEX_TYPE, CONST_SIZES, BUFFER_TYPE > &&src)
Steal the resources of src, clearing it in the process.
void erase(T *const LVARRAY_RESTRICT ptr, std::ptrdiff_t const size, std::ptrdiff_t const index, std::ptrdiff_t const n=1)
Shift the values in the array at or above the given position down by the given amount overwriting the...
void emplaceBack(T *const LVARRAY_RESTRICT ptr, std::ptrdiff_t const size, ARGS &&... args)
Append the to the array constructing the new value in place.
std::string string
String type.
std::conditional_t< CONST_SIZES, INDEX_TYPE const, INDEX_TYPE_NC > SIZE_TYPE
The type contained by the m_sizes buffer.
std::pair< BUFFER_TYPE< U > &, BUFFER_TYPE< U > const & > PairOfBuffers
Alias for a std::pair of buffers.
camp::concepts::metalib::all_of_t< TYPES ... > all_of_t
A struct that contains a static constexpr bool value that is true if all of TYPES::value are true...
constexpr std::enable_if_t< std::is_arithmetic< T >::value, T > min(T const a, T const b)
void reserveValues(INDEX_TYPE const newValueCapacity, BUFFERS &... buffers)
Reserve space for the given number of values.
void insert(T *const LVARRAY_RESTRICT ptr, std::ptrdiff_t const size, std::ptrdiff_t const index, ITERATOR first, std::ptrdiff_t const n)
Insert the given values into the array at the given position.
#define CONSTEXPR_WITH_NDEBUG
Expands to constexpr in release builds (when NDEBUG is defined).
constexpr INDEX_TYPE_NC valueCapacity() const
void registerTouch(MemorySpace const space) const
Touch the memory in space.
constexpr ArrayOfArraysView< T const, INDEX_TYPE const, true, BUFFER_TYPE > toViewConst() const
constexpr void forEachArg(F &&f)
The recursive base case where no argument is provided.
void resize(BUFFER &buf, std::ptrdiff_t const size, std::ptrdiff_t const newSize, ARGS &&... args)
Resize the buffer to the given size.
#define LVARRAY_HOST_DEVICE
Mark a function for both host and device usage.
globalIndex const ValueType
An alias for the type contained in the inner arrays.