Skip to content
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

Add LVARRAY_ERROR_IF_PRINTF() macro to prinnt fancyer messages on errors #255

Closed
wants to merge 26 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions examples/exampleArrayOfSets.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ TEST( ArrayOfSets, assimilate )
arrayOfArrays.emplaceBack( 2, 1 );

// Assimilate arrayOfArrays into arrayOfSets.
arrayOfSets.assimilate( std::move( arrayOfArrays ),
LvArray::sortedArrayManipulation::Description::SORTED_UNIQUE );
arrayOfSets.assimilate< RAJA::loop_exec >( std::move( arrayOfArrays ),
LvArray::sortedArrayManipulation::Description::SORTED_UNIQUE );

// After being assimilated arrayOfArrays is empty.
EXPECT_EQ( arrayOfArrays.size(), 0 );
Expand All @@ -84,8 +84,8 @@ TEST( ArrayOfSets, assimilate )
arrayOfArrays.emplaceBack( 1, 4 );

// Assimilate the arrayOfArrays yet again.
arrayOfSets.assimilate( std::move( arrayOfArrays ),
LvArray::sortedArrayManipulation::Description::UNSORTED_WITH_DUPLICATES );
arrayOfSets.assimilate< RAJA::loop_exec >( std::move( arrayOfArrays ),
LvArray::sortedArrayManipulation::Description::UNSORTED_WITH_DUPLICATES );

EXPECT_EQ( arrayOfSets.size(), 2 );
EXPECT_EQ( arrayOfSets.sizeOfSet( 0 ), 2 );
Expand Down
1 change: 1 addition & 0 deletions src/ArrayOfArrays.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ class ArrayOfArrays : protected ArrayOfArraysView< T, INDEX_TYPE, false, BUFFER_
}

using ParentClass::resizeFromCapacities;
using ParentClass::resizeFromOffsets;

///@}

Expand Down
136 changes: 85 additions & 51 deletions src/ArrayOfArraysView.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand All @@ -33,8 +35,8 @@
* @note This is only active when LVARRAY_BOUNDS_CHECK is defined.
*/
#define ARRAYOFARRAYS_CHECK_BOUNDS( i ) \
LVARRAY_ERROR_IF( !arrayManipulation::isPositive( i ) || i >= this->size(), \
"Bounds Check Failed: i=" << i << " size()=" << this->size() )
LVARRAY_ERROR_IF_PRINTF( !arrayManipulation::isPositive( i ) || i >= this->size(), \
"Bounds Check Failed: i=%" PRId64 " size()=%" PRId64, (int64_t)i, (int64_t)this->size() )
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

where is PRId64 defined, and what if the index is not 64 bit?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PRId64 is in inttypes.h https://www.cplusplus.com/reference/cinttypes/,
Int are casted into int64 to be sure not to have overflow.


/**
* @brief Check that @p i is a valid array index and that @p j is a valid index into that array.
Expand All @@ -43,19 +45,21 @@
* @note This is only active when LVARRAY_BOUNDS_CHECK is defined.
*/
#define ARRAYOFARRAYS_CHECK_BOUNDS2( i, j ) \
LVARRAY_ERROR_IF( !arrayManipulation::isPositive( i ) || i >= this->size() || \
!arrayManipulation::isPositive( j ) || j >= this->m_sizes[ i ], \
"Bounds Check Failed: i=" << i << " size()=" << this->size() << \
" j=" << j << " m_sizes[ i ]=" << this->m_sizes[ i ] )
LVARRAY_ERROR_IF_PRINTF( !arrayManipulation::isPositive( i ) || i >= this->size() || \
!arrayManipulation::isPositive( j ) || j >= this->m_sizes[ i ], \
"Bounds Check Failed: i=%" PRId64 " size()=%" PRId64 \
" j=%" PRId64 " m_sizes[ i ]=%" PRId64, \
(int64_t)i, (int64_t)this->size(), (int64_t)j, (int64_t)this->m_sizes[ i ] )

/**
* @brief Check that @p i is a valid index to insert an array at.
* @param i The array index to check.
* @note This is only active when LVARRAY_BOUNDS_CHECK is defined.
*/
#define ARRAYOFARRAYS_CHECK_INSERT_BOUNDS( i ) \
LVARRAY_ERROR_IF( !arrayManipulation::isPositive( i ) || i > this->size(), \
"Insert Bounds Check Failed: i=" << i << " size()=" << this->size() )
LVARRAY_ERROR_IF_PRINTF( !arrayManipulation::isPositive( i ) || i > this->size(), \
"Insert Bounds Check Failed: i=%" PRId64 " size()=%" PRId64, \
(int64_t)i, (int64_t)this->size() )

/**
* @brief Check that @p i is a valid array index and that @p j is a valid insertion index into that array.
Expand All @@ -64,10 +68,10 @@
* @note This is only active when LVARRAY_BOUNDS_CHECK is defined.
*/
#define ARRAYOFARRAYS_CHECK_INSERT_BOUNDS2( i, j ) \
LVARRAY_ERROR_IF( !arrayManipulation::isPositive( i ) || i >= this->size() || \
!arrayManipulation::isPositive( j ) || j > this->sizeOfArray( i ), \
"Insert Bounds Check Failed: i=" << i << " size()=" << this->size() << \
" j=" << j << " sizeOfArray( i )=" << this->sizeOfArray( i ) )
LVARRAY_ERROR_IF_PRINTF( !arrayManipulation::isPositive( i ) || i >= this->size() || \
!arrayManipulation::isPositive( j ) || j > this->sizeOfArray( i ), \
"Insert Bounds Check Failed: i=%" PRId64 " size()=%" PRId64 " j=%" PRId64 " sizeOfArray( i )=%" PRId64, \
(int64_t)i, (int64_t)this->size(), (int64_t)j, (int64_t)this->sizeOfArray( i ) )

/**
* @brief Check that the capacity of array @p i isn't exceeded when the size is increased by @p increase.
Expand All @@ -76,10 +80,10 @@
* @note This is only active when LVARRAY_BOUNDS_CHECK is defined.
*/
#define ARRAYOFARRAYS_CAPACITY_CHECK( i, increase ) \
LVARRAY_ERROR_IF( this->sizeOfArray( i ) + increase > this->capacityOfArray( i ), \
"Capacity Check Failed: i=" << i << " increase=" << increase << \
" sizeOfArray( i )=" << this->sizeOfArray( i ) << " capacityOfArray( i )=" << \
this->capacityOfArray( i ) )
LVARRAY_ERROR_IF_PRINTF( this->sizeOfArray( i ) + increase > this->capacityOfArray( i ), \
"Capacity Check Failed: i=%" PRId64 " increase=%" PRId64 \
" sizeOfArray( i )=%" PRId64 " capacityOfArray( i )=%" PRId64, \
(int64_t)i, (int64_t)increase, (int64_t)this->sizeOfArray( i ), (int64_t)this->capacityOfArray( i ) )

/**
* @brief Check that the capacity of array @p i isn't exceeded when the size is increased by @p increase.
Expand All @@ -89,10 +93,10 @@
* @note This is only active when LVARRAY_BOUNDS_CHECK is defined.
*/
#define ARRAYOFARRAYS_ATOMIC_CAPACITY_CHECK( i, previousSize, increase ) \
LVARRAY_ERROR_IF( previousSize + increase > this->capacityOfArray( i ), \
"Capacity Check Failed: i=" << i << " increase=" << increase << \
" sizeOfArray( i )=" << previousSize << " capacityOfArray( i )=" << \
this->capacityOfArray( i ) )
LVARRAY_ERROR_IF_PRINTF( previousSize + increase > this->capacityOfArray( i ), \
"Capacity Check Failed: i=%" PRId64 " increase=%" PRId64 \
" sizeOfArray( i )=%" PRId64 " capacityOfArray( i )=%" PRId64, \
(int64_t)i, (int64_t)increase, (int64_t)previousSize, (int64_t)this->capacityOfArray( i ) )

#else // LVARRAY_BOUNDS_CHECK

Expand Down Expand Up @@ -685,6 +689,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.
Expand All @@ -699,39 +724,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,
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 ... );
}

///@}
Expand Down Expand Up @@ -1008,6 +1008,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 */
60 changes: 33 additions & 27 deletions src/ArrayOfSets.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 )
Expand All @@ -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;

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
Expand Down
7 changes: 4 additions & 3 deletions src/ArraySlice.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,9 @@ DEFINE_GDB_PY_SCRIPT( "scripts/gdb-printers.py" )
* @note This is only active when LVARRAY_BOUNDS_CHECK is defined.
*/
#define ARRAY_SLICE_CHECK_BOUNDS( index ) \
LVARRAY_ERROR_IF( index < 0 || index >= m_dims[ 0 ], \
"Array Bounds Check Failed: index=" << index << " m_dims[0]=" << m_dims[0] )
LVARRAY_ERROR_IF_PRINTF( index < 0 || index >= m_dims[ 0 ], \
"Array Bounds Check Failed: index=%" PRId64 " m_dims[0]=%" PRId64, \
((int64_t)index), ((int64_t)m_dims[0]) )

#else // LVARRAY_BOUNDS_CHECK

Expand Down Expand Up @@ -239,7 +240,7 @@ class ArraySlice
*/
template< typename ... INDICES >
LVARRAY_HOST_DEVICE inline CONSTEXPR_WITHOUT_BOUNDS_CHECK
INDEX_TYPE linearIndex( INDICES... indices ) const
std::size_t linearIndex( INDICES... indices ) const
{
static_assert( sizeof ... (INDICES) == NDIM, "number of indices does not match NDIM" );
#ifdef LVARRAY_BOUNDS_CHECK
Expand Down
2 changes: 1 addition & 1 deletion src/ArrayView.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -450,7 +450,7 @@ class ArrayView
*/
template< typename ... INDICES >
LVARRAY_HOST_DEVICE inline CONSTEXPR_WITHOUT_BOUNDS_CHECK
INDEX_TYPE linearIndex( INDICES const ... indices ) const
std::size_t linearIndex( INDICES const ... indices ) const
{
static_assert( sizeof ... (INDICES) == NDIM, "number of indices does not match NDIM" );
#ifdef LVARRAY_BOUNDS_CHECK
Expand Down
4 changes: 2 additions & 2 deletions src/CRSMatrix.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -177,8 +177,8 @@ class CRSMatrix : protected CRSMatrixView< T, COL_TYPE, INDEX_TYPE, BUFFER_TYPE
void resizeFromRowCapacities( INDEX_TYPE const nRows, INDEX_TYPE const nCols, INDEX_TYPE const * const rowCapacities )
{
LVARRAY_ERROR_IF( !arrayManipulation::isPositive( nCols ), "nCols must be positive." );
LVARRAY_ERROR_IF( nCols - 1 > std::numeric_limits< COL_TYPE >::max(),
"COL_TYPE must be able to hold the range of columns: [0, " << nCols - 1 << "]." );
LVARRAY_ERROR_IF_PRINTF( nCols - 1 > std::numeric_limits< COL_TYPE >::max(),
"COL_TYPE must be able to hold the range of columns: [0, %" PRId64 "].", (int64_t)(nCols -1) );

this->m_numCols = nCols;
ParentClass::template resizeFromCapacities< POLICY >( nRows, rowCapacities, this->m_entries );
Expand Down
Loading