-
Notifications
You must be signed in to change notification settings - Fork 10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Enhancements for ArrayOf[Arrays|Sets] construction/assimilation #256
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,9 +15,11 @@ | |
// Source includes | ||
#include "bufferManipulation.hpp" | ||
#include "arrayManipulation.hpp" | ||
#include "sortedArrayManipulation.hpp" | ||
#include "ArraySlice.hpp" | ||
#include "typeManipulation.hpp" | ||
#include "math.hpp" | ||
#include "umpireInterface.hpp" | ||
|
||
// TPL includes | ||
#include <RAJA/RAJA.hpp> | ||
|
@@ -685,6 +687,27 @@ class ArrayOfArraysView | |
m_offsets[ m_numArrays ] = m_offsets[ m_numArrays - 1 ] + sizeOfArray( m_numArrays - 1 ); | ||
} | ||
|
||
/** | ||
* @brief Clears the array and creates a new array with the given number of sub-arrays. | ||
* @param numSubArrays The new number of arrays. | ||
* @param offsets A pointer to an array of length @p numSubArrays+1 containing the offset | ||
* of each new sub array. Offsets are precomputed by the caller. | ||
* @param buffers A variadic pack of buffers to treat similarly to m_values. | ||
*/ | ||
template< typename ... BUFFERS > | ||
void resizeFromOffsets( INDEX_TYPE const numSubArrays, | ||
INDEX_TYPE const * const offsets, | ||
BUFFERS & ... buffers ) | ||
{ | ||
auto const fillOffsets = [&]() | ||
{ | ||
arrayManipulation::uninitializedCopy( offsets, | ||
offsets + numSubArrays + 1, | ||
m_offsets.data() ); | ||
}; | ||
resizeFromOffsetsImpl( numSubArrays, fillOffsets, buffers ... ); | ||
} | ||
|
||
/** | ||
* @tparam POLICY The RAJA policy used to convert @p capacities into the offsets array. | ||
* Should NOT be a device policy. | ||
|
@@ -699,39 +722,14 @@ class ArrayOfArraysView | |
INDEX_TYPE const * const capacities, | ||
BUFFERS & ... buffers ) | ||
{ | ||
LVARRAY_ASSERT( arrayManipulation::isPositive( numSubArrays ) ); | ||
|
||
#ifdef LVARRAY_BOUNDS_CHECK | ||
for( INDEX_TYPE i = 0; i < numSubArrays; ++i ) | ||
auto const fillOffsets = [&]() | ||
{ | ||
LVARRAY_ERROR_IF_LT( capacities[ i ], 0 ); | ||
} | ||
#endif | ||
|
||
destroyValues( 0, m_numArrays, buffers ... ); | ||
|
||
bufferManipulation::reserve( m_sizes, m_numArrays, MemorySpace::host, numSubArrays ); | ||
std::fill_n( m_sizes.data(), numSubArrays, 0 ); | ||
|
||
INDEX_TYPE const offsetsSize = ( m_numArrays == 0 ) ? 0 : m_numArrays + 1; | ||
bufferManipulation::reserve( m_offsets, offsetsSize, MemorySpace::host, numSubArrays + 1 ); | ||
|
||
m_offsets[ 0 ] = 0; | ||
// RAJA::inclusive_scan fails on empty input range | ||
if( numSubArrays > 0 ) | ||
{ | ||
// const_cast needed until for RAJA bug. | ||
RAJA::inclusive_scan< POLICY >( const_cast< INDEX_TYPE * >( capacities ), | ||
const_cast< INDEX_TYPE * >( capacities + numSubArrays ), | ||
m_offsets[ 0 ] = 0; | ||
RAJA::inclusive_scan< POLICY >( capacities, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This function should probably call There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So I couldn't just call it, because the result of the scan is written straight into |
||
capacities + numSubArrays, | ||
m_offsets.data() + 1 ); | ||
} | ||
|
||
m_numArrays = numSubArrays; | ||
INDEX_TYPE const maxOffset = m_offsets[ m_numArrays ]; | ||
typeManipulation::forEachArg( [ maxOffset] ( auto & buffer ) | ||
{ | ||
bufferManipulation::reserve( buffer, 0, MemorySpace::host, maxOffset ); | ||
}, m_values, buffers ... ); | ||
}; | ||
resizeFromOffsetsImpl( numSubArrays, fillOffsets, buffers ... ); | ||
} | ||
|
||
///@} | ||
|
@@ -1008,6 +1006,40 @@ class ArrayOfArraysView | |
} | ||
}, m_values, buffers ... ); | ||
} | ||
|
||
/** | ||
* @brief Clears the array and creates a new array with the given number of sub-arrays. | ||
* @param numSubArrays The new number of arrays. | ||
* @param fillOffsets A function that will be called to populate sub-array offsets. | ||
* @param buffers A variadic pack of buffers to treat similarly to m_values. | ||
* @note This is to be called by other resizeFrom functions. | ||
*/ | ||
template< typename FUNC, typename ... BUFFERS > | ||
void resizeFromOffsetsImpl( INDEX_TYPE const numSubArrays, | ||
FUNC && fillOffsets, | ||
BUFFERS & ... buffers ) | ||
{ | ||
LVARRAY_ASSERT( arrayManipulation::isPositive( numSubArrays ) ); | ||
|
||
destroyValues( 0, m_numArrays, buffers ... ); | ||
|
||
bufferManipulation::reserve( m_sizes, m_numArrays, MemorySpace::host, numSubArrays ); | ||
umpireInterface::memset( m_sizes.data(), 0, m_sizes.capacity() * sizeof( INDEX_TYPE ) ); | ||
|
||
INDEX_TYPE const offsetsSize = ( m_numArrays == 0 ) ? 0 : m_numArrays + 1; | ||
bufferManipulation::reserve( m_offsets, offsetsSize, MemorySpace::host, numSubArrays + 1 ); | ||
|
||
fillOffsets(); | ||
LVARRAY_ASSERT_EQ( m_offsets[0], 0 ); | ||
LVARRAY_ASSERT( sortedArrayManipulation::isSorted( m_offsets.data(), m_offsets.data() + numSubArrays + 1 ) ); | ||
|
||
m_numArrays = numSubArrays; | ||
INDEX_TYPE const maxOffset = m_offsets[ m_numArrays ]; | ||
typeManipulation::forEachArg( [ maxOffset ] ( auto & buffer ) | ||
{ | ||
bufferManipulation::reserve( buffer, 0, MemorySpace::host, maxOffset ); | ||
}, m_values, buffers ... ); | ||
} | ||
}; | ||
|
||
} /* namespace LvArray */ |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -121,10 +121,11 @@ class ArrayOfSets : protected ArrayOfSetsView< T, INDEX_TYPE, BUFFER_TYPE > | |
|
||
/** | ||
* @brief Steal the resources from an ArrayOfArrays and convert it to an ArrayOfSets. | ||
* @tparam POLICY a RAJA execution policy to use when sorting/removing duplicates in sub-arrays. | ||
* @param src the ArrayOfArrays to convert. | ||
* @param desc describes the type of data in the source. | ||
* TODO: Add a RAJA policy template parameter. | ||
*/ | ||
template< typename POLICY > | ||
inline | ||
void assimilate( ArrayOfArrays< T, INDEX_TYPE, BUFFER_TYPE > && src, | ||
sortedArrayManipulation::Description const desc ) | ||
|
@@ -133,38 +134,43 @@ class ArrayOfSets : protected ArrayOfSetsView< T, INDEX_TYPE, BUFFER_TYPE > | |
ParentClass::assimilate( reinterpret_cast< ParentClass && >( src ) ); | ||
|
||
INDEX_TYPE const numSets = size(); | ||
ArrayOfArraysView< T, INDEX_TYPE const, true, BUFFER_TYPE > const view = | ||
ArrayOfArraysView< T, INDEX_TYPE const, true, BUFFER_TYPE >( numSets, | ||
this->m_offsets, | ||
this->m_sizes, | ||
this->m_values ); | ||
BUFFER_TYPE< INDEX_TYPE > const sizes = this->m_sizes; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There seems to be no way to manually "resize" a single sub-array through There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This looks good to me. |
||
|
||
if( desc == sortedArrayManipulation::UNSORTED_NO_DUPLICATES ) | ||
{ | ||
for( INDEX_TYPE i = 0; i < numSets; ++i ) | ||
{ | ||
T * const setValues = getSetValues( i ); | ||
INDEX_TYPE const numValues = sizeOfSet( i ); | ||
std::sort( setValues, setValues + numValues ); | ||
} | ||
RAJA::forall< POLICY >( RAJA::TypedRangeSegment< INDEX_TYPE >( 0, numSets ), | ||
[view] LVARRAY_HOST_DEVICE ( INDEX_TYPE const i ) | ||
{ | ||
ArraySlice< T, 1, 0, INDEX_TYPE > const setValues = view[i]; | ||
sortedArrayManipulation::makeSorted( setValues.begin(), setValues.end() ); | ||
} ); | ||
} | ||
if( desc == sortedArrayManipulation::SORTED_WITH_DUPLICATES ) | ||
else if( desc == sortedArrayManipulation::SORTED_WITH_DUPLICATES ) | ||
{ | ||
for( INDEX_TYPE i = 0; i < numSets; ++i ) | ||
{ | ||
T * const setValues = getSetValues( i ); | ||
INDEX_TYPE const numValues = sizeOfSet( i ); | ||
|
||
INDEX_TYPE const numUniqueValues = sortedArrayManipulation::removeDuplicates( setValues, setValues + numValues ); | ||
arrayManipulation::resize( setValues, numValues, numUniqueValues ); | ||
this->m_sizes[ i ] = numUniqueValues; | ||
} | ||
RAJA::forall< POLICY >( RAJA::TypedRangeSegment< INDEX_TYPE >( 0, numSets ), | ||
[view, sizes] LVARRAY_HOST_DEVICE ( INDEX_TYPE const i ) | ||
{ | ||
ArraySlice< T, 1, 0, INDEX_TYPE > const setValues = view[i]; | ||
INDEX_TYPE const numUniqueValues = sortedArrayManipulation::removeDuplicates( setValues.begin(), setValues.end() ); | ||
arrayManipulation::resize< T >( setValues, setValues.size(), numUniqueValues ); | ||
sizes[ i ] = numUniqueValues; | ||
} ); | ||
} | ||
if( desc == sortedArrayManipulation::UNSORTED_WITH_DUPLICATES ) | ||
else if( desc == sortedArrayManipulation::UNSORTED_WITH_DUPLICATES ) | ||
{ | ||
for( INDEX_TYPE i = 0; i < numSets; ++i ) | ||
{ | ||
T * const setValues = getSetValues( i ); | ||
INDEX_TYPE const numValues = sizeOfSet( i ); | ||
|
||
INDEX_TYPE const numUniqueValues = sortedArrayManipulation::makeSortedUnique( setValues, setValues + numValues ); | ||
arrayManipulation::resize( setValues, numValues, numUniqueValues ); | ||
this->m_sizes[ i ] = numUniqueValues; | ||
} | ||
RAJA::forall< POLICY >( RAJA::TypedRangeSegment< INDEX_TYPE >( 0, numSets ), | ||
[view, sizes] LVARRAY_HOST_DEVICE ( INDEX_TYPE const i ) | ||
{ | ||
ArraySlice< T, 1, 0, INDEX_TYPE > const setValues = view[ i ]; | ||
INDEX_TYPE const numUniqueValues = sortedArrayManipulation::makeSortedUnique( setValues.begin(), setValues.end() ); | ||
arrayManipulation::resize< T >( setValues, setValues.size(), numUniqueValues ); | ||
sizes[ i ] = numUniqueValues; | ||
} ); | ||
} | ||
|
||
#ifdef ARRAY_BOUNDS_CHECK | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Casts seem no longer needed with current version of RAJA we're using