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 1 commit
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
42 changes: 22 additions & 20 deletions src/ArrayOfArraysView.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,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 +43,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 +66,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 +78,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 +91,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
5 changes: 3 additions & 2 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
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
109 changes: 69 additions & 40 deletions src/Macros.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@
#include <iostream>
#include <type_traits>

#include <inttypes.h>
#include <cstdio>

#if defined(LVARRAY_USE_CUDA)
#include <cassert>
#endif
Expand Down Expand Up @@ -81,58 +84,84 @@
*/
#define LVARRAY_LOG_VAR( ... ) LVARRAY_LOG( STRINGIZE( __VA_ARGS__ ) << " = " << __VA_ARGS__ )

#if defined(__CUDA_ARCH__)
# define CUDA_INFORMATION_FMT "***** Block: [%u, %u, %u]\n***** Thread: [%u, %u, %u]\n%s"
# define CUDA_INFORMATION_PARAMS blockIdx.x, blockIdx.y, blockIdx.z, threadIdx.x, threadIdx.y, threadIdx.z, ""
# define CALL_ERROR_HANDLER() do { asm ( "trap;" ); } while ( false )
#else
# define CUDA_INFORMATION_FMT "%s"
# define CUDA_INFORMATION_PARAMS ""
# define CALL_ERROR_HANDLER() do { LvArray::system::callErrorHandler(); } while ( false )
#endif

/**
* @brief Abort execution if @p EXP is true.
* @param EXP The expression to check.
* @param MSG The message to associate with the error, can be anything streamable to a std::ostream.
* @param MSG_FMT The format of the message to associate with the error, can be anything understood by printf().
* @param ... Variadic arguments to pass to printf (cannot be empty)
* @note This macro can be used in both host and device code.
* @note Tries to provide as much information about the location of the error
* as possible. On host this should result in the file and line of the error
* and a stack trace along with the provided message. On device none of this is
* guaranteed. In fact it is only guaranteed to abort the current kernel.
*/
#if defined(__CUDA_ARCH__)
#if !defined(NDEBUG)
#define LVARRAY_ERROR_IF( EXP, MSG ) \
do \
{ \
if( EXP ) \
{ \
assert( false && "EXP = " STRINGIZE( EXP ) "MSG = " STRINGIZE( MSG ) ); \
} \
#define LVARRAY_ERROR_IF_PRINTF( EXP, MSG_FMT, ... ) \
do \
{ \
if( EXP ) \
{ \
printf( "***** ERROR\n" \
"***** LOCATION: " LOCATION "\n" \
CUDA_INFORMATION_FMT \
"***** Controlling expression (should be false): " \
STRINGIZE( EXP ) "\n" \
"***** MSG: " MSG_FMT "\n\n", \
CUDA_INFORMATION_PARAMS, __VA_ARGS__ ); \
CALL_ERROR_HANDLER(); \
} \
} while( false )
#else
#define LVARRAY_ERROR_IF( EXP, MSG ) \
do \
{ \
if( EXP ) \
{ \
constexpr char const * formatString = "***** ERROR\n" \
"***** LOCATION: " LOCATION "\n" \
"***** Block: [%u, %u, %u]\n" \
"***** Thread: [%u, %u, %u]\n" \
"***** Controlling expression (should be false): " STRINGIZE( EXP ) "\n" \
"***** MSG: " STRINGIZE( MSG ) "\n\n"; \
printf( formatString, blockIdx.x, blockIdx.y, blockIdx.z, threadIdx.x, threadIdx.y, threadIdx.z ); \
asm ( "trap;" ); \
} \

/**
* @brief Abort execution if @p EXP is true.
* @param EXP The expression to check.
* @param MSG The format of the message to associate with the error, can be anything streamable to a std::ostream.
* @note This macro can be used in both host and device code.
* @note Tries to provide as much information about the location of the error
* as possible. On host this should result in the file and line of the error
* and a stack trace along with the provided message. On device none of this is
* guaranteed. In fact it is only guaranteed to abort the current kernel.
*/
#if defined(__CUDA_ARCH__)
# define LVARRAY_ERROR_IF( EXP, MSG ) \
do \
{ \
if( EXP ) \
{ \
printf("***** ERROR\n" \
"***** LOCATION: " LOCATION "\n" \
CUDA_INFORMATION_FMT \
"***** Controlling expression (should be false): " \
STRINGIZE( EXP ) "\n" \
"***** MSG: " STRINGIZE(MSG) "\n\n", \
CUDA_INFORMATION_PARAMS); \
CALL_ERROR_HANDLER(); \
} \
} while( false )
#endif
#else
#define LVARRAY_ERROR_IF( EXP, MSG ) \
do \
{ \
if( EXP ) \
{ \
std::ostringstream __oss; \
__oss << "***** ERROR\n"; \
__oss << "***** LOCATION: " LOCATION "\n"; \
__oss << "***** Controlling expression (should be false): " STRINGIZE( EXP ) "\n"; \
__oss << MSG << "\n"; \
__oss << LvArray::system::stackTrace( true ); \
std::cout << __oss.str() << std::endl; \
LvArray::system::callErrorHandler(); \
} \
# define LVARRAY_ERROR_IF( EXP, MSG ) \
do \
{ \
if( EXP ) \
{ \
std::ostringstream __oss; \
__oss << "***** ERROR\n"; \
__oss << "***** LOCATION: " LOCATION "\n"; \
__oss << "***** Controlling expression (should be false): "; \
__oss << STRINGIZE( EXP ) << "\n"; \
__oss << "***** MSG: " << MSG << "\n"; \
std::cout << __oss.str() << std::endl; \
CALL_ERROR_HANDLER(); \
} \
} while( false )
#endif

Expand Down
5 changes: 3 additions & 2 deletions src/SortedArrayView.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,9 @@
* @note This is only active when LVARRAY_BOUNDS_CHECK is defined.
*/
#define SORTEDARRAY_CHECK_BOUNDS( index ) \
LVARRAY_ERROR_IF( index < 0 || index >= size(), \
"Array Bounds Check Failed: index=" << index << " size()=" << size())
LVARRAY_ERROR_IF_PRINTF( index < 0 || index >= size(), \
"Array Bounds Check Failed: index=%" PRId64 " size()=%" PRId64, \
(int64_t)(index), (int64_t)size())

#else // LVARRAY_BOUNDS_CHECK

Expand Down
4 changes: 2 additions & 2 deletions src/SparsityPattern.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,8 @@ class SparsityPattern : protected SparsityPatternView< COL_TYPE, INDEX_TYPE, BUF
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(),
Copy link
Collaborator

Choose a reason for hiding this comment

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

This is not device code so I'm not sure it makes sense to change.

"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 );
Expand Down
9 changes: 5 additions & 4 deletions src/SparsityPatternView.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,9 @@
* @note This macro is only active with LVARRAY_BOUNDS_CHECK.
*/
#define SPARSITYPATTERN_COLUMN_CHECK( col ) \
LVARRAY_ERROR_IF( !arrayManipulation::isPositive( col ) || col >= this->numColumns(), \
"Column Check Failed: col=" << col << " numColumns=" << this->numColumns() )
LVARRAY_ERROR_IF_PRINTF( !arrayManipulation::isPositive( col ) || col >= this->numColumns(), \
"Column Check Failed: col=%" PRId64 " numColumns=%" PRId64, \
(int64_t)(col), (int64_t)this->numColumns() )

#else // LVARRAY_BOUNDS_CHECK

Expand Down Expand Up @@ -438,8 +439,8 @@ class SparsityPatternView : protected ArrayOfSetsView< COL_TYPE, INDEX_TYPE, BUF
{
LVARRAY_ERROR_IF( !arrayManipulation::isPositive( nrows ), "nrows must be positive." );
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(),
Copy link
Collaborator

Choose a reason for hiding this comment

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

Same here.

"COL_TYPE must be able to hold the range of columns: [0, %" PRId64 "].", (int64_t)(ncols - 1) );

m_numCols = ncols;
ParentClass::resizeImpl( nrows, initialRowCapacity, buffers ... );
Expand Down
10 changes: 6 additions & 4 deletions src/arrayManipulation.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,19 @@
* @note This is only active when LVARRAY_BOUNDS_CHECK is defined.
*/
#define ARRAYMANIPULATION_CHECK_BOUNDS( index ) \
LVARRAY_ERROR_IF( !isPositive( index ) || index >= size, \
"Array Bounds Check Failed: index=" << index << " size()=" << size )
LVARRAY_ERROR_IF_PRINTF( !isPositive( index ) || index >= size, \
"Array Bounds Check Failed: index=%" PRId64 " size()=%" PRId64, \
(int64_t)(index), (int64_t)size )

/**
* @brief Check that @p index is a valid insertion position in the array.
* @param index The index to check.
* @note This is only active when LVARRAY_BOUNDS_CHECK is defined.
*/
#define ARRAYMANIPULATION_CHECK_INSERT_BOUNDS( index ) \
LVARRAY_ERROR_IF( !isPositive( index ) || index > size, \
"Array Bounds Insert Check Failed: index=" << index << " size()=" << size )
LVARRAY_ERROR_IF_PRINTF( !isPositive( index ) || index > size, \
"Array Bounds Insert Check Failed: index=%" PRId64 " size()=%" PRId64, \
(int64_t)(index), (int64_t)size )

#else // LVARRAY_BOUNDS_CHECK

Expand Down