LvArray
Macros.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2021, Lawrence Livermore National Security, LLC and LvArray contributors.
3  * All rights reserved.
4  * See the LICENSE file for details.
5  * SPDX-License-Identifier: (BSD-3-Clause)
6  */
7 
13 #pragma once
14 
15 // Source includes
16 #include "LvArrayConfig.hpp"
17 #include "system.hpp"
18 
19 // System includes
20 #include <fstream>
21 #include <sstream>
22 #include <iostream>
23 #include <type_traits>
24 
25 
26 #if defined(LVARRAY_USE_CUDA) || defined(LVARRAY_USE_HIP)
27 #define LVARRAY_USE_DEVICE
29 #endif
30 
31 #if defined(LVARRAY_USE_CUDA)
32 #define LVARRAY_DEFAULT_DEVICE_SPACE MemorySpace::cuda
33 #elif defined(LVARRAY_USE_HIP)
34 #define LVARRAY_DEFAULT_DEVICE_SPACE MemorySpace::hip
35 #endif
36 
37 #if defined(__CUDA_ARCH__) || defined(__HIP_DEVICE_COMPILE__)
38 #define LVARRAY_DEVICE_COMPILE
40 #define LVARRAY_FORCE_INLINE __forceinline__
42 #else
43 #define LVARRAY_FORCE_INLINE inline
45 #endif
46 
47 #if defined(__CUDACC__) || defined(__HIPCC__)
48 // Denotes whether to define decorator macros later in this file.
49 #define LVARRAY_DECORATE
50 #endif
51 
52 
53 //#if !defined(NDEBUG) && defined(LVARRAY_DEVICE_COMPILE)
54  #include <cassert>
55 //#endif
56 
61 #define STRINGIZE_NX( A ) #A
62 
67 #define STRINGIZE( A ) STRINGIZE_NX( A )
68 
73 #define LVARRAY_UNUSED_ARG( X )
74 
79 #define LVARRAY_UNUSED_VARIABLE( X ) ( ( void ) X )
80 
85 #define LVARRAY_DEBUG_VAR( X ) LVARRAY_UNUSED_VARIABLE( X )
86 
88 #define LOCATION __FILE__ ":" STRINGIZE( __LINE__ )
89 
94 #define TYPEOFPTR( X ) std::remove_pointer_t< decltype( X ) >
95 
100 #define TYPEOFREF( X ) std::remove_reference_t< decltype( X ) >
101 
105 #define LVARRAY_LOG( ... ) std::cout << __VA_ARGS__ << std::endl
106 
110 #define LVARRAY_LOG_VAR( ... ) LVARRAY_LOG( STRINGIZE( __VA_ARGS__ ) << " = " << __VA_ARGS__ )
111 
123 #if defined(LVARRAY_DEVICE_COMPILE)
124 // #if defined(__HIP_DEVICE_COMPILE__)
125 // // empty impl to avoid the possibility of printfs in device code
126 // // on AMD, which can cause performance degradation just by being present
127 // #define LVARRAY_ERROR_IF( EXP, MSG )
128  #if (!defined(NDEBUG)) || defined(__HIP_DEVICE_COMPILE__)
129 #define LVARRAY_ERROR_IF( EXP, MSG ) \
130  do \
131  { \
132  if( EXP ) \
133  { \
134  assert( false && "EXP = " STRINGIZE( EXP ) "MSG = " STRINGIZE( MSG ) ); \
135  } \
136  } while( false )
137  #else
138 #define LVARRAY_ERROR_IF( EXP, MSG ) \
139  do \
140  { \
141  if( EXP ) \
142  { \
143  constexpr char const * formatString = "***** ERROR\n" \
144  "***** LOCATION: " LOCATION "\n" \
145  "***** Block: [%u, %u, %u]\n" \
146  "***** Thread: [%u, %u, %u]\n" \
147  "***** Controlling expression (should be false): " STRINGIZE( EXP ) "\n" \
148  "***** MSG: " STRINGIZE( MSG ) "\n\n"; \
149  printf( formatString, blockIdx.x, blockIdx.y, blockIdx.z, threadIdx.x, threadIdx.y, threadIdx.z ); \
150  asm ( "trap;" ); \
151  } \
152  } while( false )
153  #endif
154 #else
155 #define LVARRAY_ERROR_IF( EXP, MSG ) \
156  do \
157  { \
158  if( EXP ) \
159  { \
160  std::ostringstream __oss; \
161  __oss << "***** ERROR\n"; \
162  __oss << "***** LOCATION: " LOCATION "\n"; \
163  __oss << "***** Controlling expression (should be false): " STRINGIZE( EXP ) "\n"; \
164  __oss << MSG << "\n"; \
165  __oss << LvArray::system::stackTrace( true ); \
166  std::cout << __oss.str() << std::endl; \
167  LvArray::system::callErrorHandler(); \
168  } \
169  } while( false )
170 #endif
171 
176 #define LVARRAY_ERROR( MSG ) LVARRAY_ERROR_IF( true, MSG )
177 
189 #if !defined(NDEBUG)
190 #define LVARRAY_ASSERT_MSG( EXP, MSG ) LVARRAY_ERROR_IF( !(EXP), MSG )
191 #else
192 #define LVARRAY_ASSERT_MSG( EXP, MSG ) ((void) 0)
193 #endif
194 
201 #define LVARRAY_THROW_IF( EXP, MSG, TYPE ) \
202  do \
203  { \
204  if( EXP ) \
205  { \
206  std::ostringstream __oss; \
207  __oss << "\n"; \
208  __oss << "***** LOCATION: " LOCATION "\n"; \
209  __oss << "***** Controlling expression (should be false): " STRINGIZE( EXP ) "\n"; \
210  __oss << MSG << "\n"; \
211  __oss << LvArray::system::stackTrace( true ); \
212  throw TYPE( __oss.str() ); \
213  } \
214  } while( false )
215 
220 #define LVARRAY_THROW( MSG, TYPE ) LVARRAY_THROW_IF( true, MSG, TYPE )
221 
223 #define LVARRAY_ASSERT( EXP ) LVARRAY_ASSERT_MSG( EXP, "" )
224 
230 #define LVARRAY_WARNING_IF( EXP, MSG ) \
231  do \
232  { \
233  if( EXP ) \
234  { \
235  std::ostringstream __oss; \
236  __oss << "***** WARNING\n"; \
237  __oss << "***** LOCATION: " LOCATION "\n"; \
238  __oss << "***** Controlling expression (should be false): " STRINGIZE( EXP ) "\n"; \
239  __oss << MSG; \
240  std::cout << __oss.str() << std::endl; \
241  } \
242  } while( false )
243 
248 #define LVARRAY_WARNING( MSG ) LVARRAY_WARNING_IF( true, MSG )
249 
255 #define LVARRAY_INFO_IF( EXP, MSG ) \
256  do \
257  { \
258  if( EXP ) \
259  { \
260  std::ostringstream __oss; \
261  __oss << "***** INFO\n"; \
262  __oss << "***** LOCATION: " LOCATION "\n"; \
263  __oss << "***** Controlling expression: " STRINGIZE( EXP ) "\n"; \
264  __oss << MSG; \
265  std::cout << __oss.str() << std::endl; \
266  } \
267  } while( false )
268 
273 #define LVARRAY_INFO( msg ) LVARRAY_INFO_IF( true, msg )
274 
283 #define LVARRAY_ERROR_IF_OP_MSG( lhs, OP, NOP, rhs, msg ) \
284  LVARRAY_ERROR_IF( lhs OP rhs, \
285  msg << "\n" << \
286  "Expected " << #lhs << " " << #NOP << " " << #rhs << "\n" << \
287  " " << #lhs << " = " << lhs << "\n" << \
288  " " << #rhs << " = " << rhs << "\n" )
289 
299 #define LVARRAY_THROW_IF_OP_MSG( lhs, OP, NOP, rhs, msg, TYPE ) \
300  LVARRAY_THROW_IF( lhs OP rhs, \
301  msg << "\n" << \
302  "Expected " << #lhs << " " << #NOP << " " << #rhs << "\n" << \
303  " " << #lhs << " = " << lhs << "\n" << \
304  " " << #rhs << " = " << rhs << "\n", TYPE )
305 
312 #define LVARRAY_ERROR_IF_EQ_MSG( lhs, rhs, msg ) LVARRAY_ERROR_IF_OP_MSG( lhs, ==, !=, rhs, msg )
313 
321 #define LVARRAY_THROW_IF_EQ_MSG( lhs, rhs, msg, TYPE ) LVARRAY_THROW_IF_OP_MSG( lhs, ==, !=, rhs, msg, TYPE )
322 
328 #define LVARRAY_ERROR_IF_EQ( lhs, rhs ) LVARRAY_ERROR_IF_EQ_MSG( lhs, rhs, "" )
329 
336 #define LVARRAY_THROW_IF_EQ( lhs, rhs, TYPE ) LVARRAY_THROW_IF_EQ_MSG( lhs, rhs, "", TYPE )
337 
344 #define LVARRAY_ERROR_IF_NE_MSG( lhs, rhs, msg ) LVARRAY_ERROR_IF_OP_MSG( lhs, !=, ==, rhs, msg )
345 
353 #define LVARRAY_THROW_IF_NE_MSG( lhs, rhs, msg, TYPE ) LVARRAY_THROW_IF_OP_MSG( lhs, !=, ==, rhs, msg, TYPE )
354 
360 #define LVARRAY_ERROR_IF_NE( lhs, rhs ) LVARRAY_ERROR_IF_NE_MSG( lhs, rhs, "" )
361 
368 #define LVARRAY_THROW_IF_NE( lhs, rhs, TYPE ) LVARRAY_THROW_IF_NE_MSG( lhs, rhs, "", TYPE )
369 
376 #define LVARRAY_ERROR_IF_GT_MSG( lhs, rhs, msg ) LVARRAY_ERROR_IF_OP_MSG( lhs, >, <=, rhs, msg )
377 
385 #define LVARRAY_THROW_IF_GT_MSG( lhs, rhs, msg, TYPE ) LVARRAY_THROW_IF_OP_MSG( lhs, >, <=, rhs, msg, TYPE )
386 
392 #define LVARRAY_ERROR_IF_GT( lhs, rhs ) LVARRAY_ERROR_IF_GT_MSG( lhs, rhs, "" )
393 
400 #define LVARRAY_THROW_IF_GT( lhs, rhs, TYPE ) LVARRAY_THROW_IF_GT_MSG( lhs, rhs, "", TYPE )
401 
408 #define LVARRAY_ERROR_IF_GE_MSG( lhs, rhs, msg ) LVARRAY_ERROR_IF_OP_MSG( lhs, >=, <, rhs, msg )
409 
417 #define LVARRAY_THROW_IF_GE_MSG( lhs, rhs, msg, TYPE ) LVARRAY_THROW_IF_OP_MSG( lhs, >=, <, rhs, msg, TYPE )
418 
424 #define LVARRAY_ERROR_IF_GE( lhs, rhs ) LVARRAY_ERROR_IF_GE_MSG( lhs, rhs, "" )
425 
432 #define LVARRAY_THROW_IF_GE( lhs, rhs, TYPE ) LVARRAY_THROW_IF_GE_MSG( lhs, rhs, "", TYPE )
433 
440 #define LVARRAY_ERROR_IF_LT_MSG( lhs, rhs, msg ) LVARRAY_ERROR_IF_OP_MSG( lhs, <, >=, rhs, msg )
441 
449 #define LVARRAY_THROW_IF_LT_MSG( lhs, rhs, msg, TYPE ) LVARRAY_THROW_IF_OP_MSG( lhs, <, >=, rhs, msg, TYPE )
450 
456 #define LVARRAY_ERROR_IF_LT( lhs, rhs ) LVARRAY_ERROR_IF_LT_MSG( lhs, rhs, "" )
457 
464 #define LVARRAY_THROW_IF_LT( lhs, rhs, TYPE ) LVARRAY_THROW_IF_LT_MSG( lhs, rhs, "", TYPE )
465 
472 #define LVARRAY_ERROR_IF_LE_MSG( lhs, rhs, msg ) LVARRAY_ERROR_IF_OP_MSG( lhs, <=, >, rhs, msg )
473 
481 #define LVARRAY_THROW_IF_LE_MSG( lhs, rhs, msg, TYPE ) LVARRAY_THROW_IF_OP_MSG( lhs, <=, >, rhs, msg, TYPE )
482 
488 #define LVARRAY_ERROR_IF_LE( lhs, rhs ) LVARRAY_ERROR_IF_GE_MSG( lhs, rhs, "" )
489 
496 #define LVARRAY_THROW_IF_LE( lhs, rhs, TYPE ) LVARRAY_THROW_IF_GE_MSG( lhs, rhs, "", TYPE )
497 
505 #define LVARRAY_ASSERT_OP_MSG( lhs, OP, rhs, msg ) \
506  LVARRAY_ASSERT_MSG( lhs OP rhs, \
507  msg << "\n" << \
508  " " << #lhs << " = " << lhs << "\n" << \
509  " " << #rhs << " = " << rhs << "\n" )
510 
517 #define LVARRAY_ASSERT_EQ_MSG( lhs, rhs, msg ) LVARRAY_ASSERT_OP_MSG( lhs, ==, rhs, msg )
518 
524 #define LVARRAY_ASSERT_EQ( lhs, rhs ) LVARRAY_ASSERT_EQ_MSG( lhs, rhs, "" )
525 
532 #define LVARRAY_ASSERT_NE_MSG( lhs, rhs, msg ) LVARRAY_ASSERT_OP_MSG( lhs, !=, rhs, msg )
533 
539 #define LVARRAY_ASSERT_NE( lhs, rhs ) LVARRAY_ASSERT_NE_MSG( lhs, rhs, "" )
540 
547 #define LVARRAY_ASSERT_GT_MSG( lhs, rhs, msg ) LVARRAY_ASSERT_OP_MSG( lhs, >, rhs, msg )
548 
554 #define LVARRAY_ASSERT_GT( lhs, rhs ) LVARRAY_ASSERT_GT_MSG( lhs, rhs, "" )
555 
562 #define LVARRAY_ASSERT_GE_MSG( lhs, rhs, msg ) LVARRAY_ASSERT_OP_MSG( lhs, >=, rhs, msg )
563 
569 #define LVARRAY_ASSERT_GE( lhs, rhs ) LVARRAY_ASSERT_GE_MSG( lhs, rhs, "" )
570 
571 #if defined(LVARRAY_DECORATE)
572 #define LVARRAY_HOST_DEVICE __host__ __device__
574 
575 #if defined( LVARRAY_USE_HIP )
576 #define LVARRAY_HOST_DEVICE_HIP __host__ __device__
578 #else
579 #define LVARRAY_HOST_DEVICE_HIP
581 #endif
582 
584 #define LVARRAY_DEVICE __device__
585 
593 #if defined(LVARRAY_USE_CUDA)
594 #define DISABLE_HD_WARNING _Pragma("hd_warning_disable")
595 #else
596 #define DISABLE_HD_WARNING
597 #endif
598 #else
599 #define LVARRAY_HOST_DEVICE
601 #define LVARRAY_HOST_DEVICE_HIP
603 
605 #define LVARRAY_DEVICE
606 
614 #define DISABLE_HD_WARNING
615 #endif
616 
617 
618 #if defined(__clang__)
619 #define LVARRAY_RESTRICT __restrict__
620 #define LVARRAY_RESTRICT_REF __restrict__
621 #define LVARRAY_INTEL_CONSTEXPR constexpr
622 #elif defined(__GNUC__)
623  #if defined(__INTEL_COMPILER)
624 #define LVARRAY_RESTRICT __restrict__
625 #define LVARRAY_RESTRICT_REF __restrict__
626 #define LVARRAY_INTEL_CONSTEXPR
627  #else
628 #define LVARRAY_RESTRICT __restrict__
629 #define LVARRAY_RESTRICT_REF __restrict__
630 #define LVARRAY_INTEL_CONSTEXPR constexpr
631  #endif
632 #endif
633 
634 #if !defined(LVARRAY_BOUNDS_CHECK)
635 
638 #define CONSTEXPR_WITHOUT_BOUNDS_CHECK constexpr
639 #else
640 
643 #define CONSTEXPR_WITHOUT_BOUNDS_CHECK
644 #endif
645 
646 #if defined(NDEBUG)
647 
650 #define CONSTEXPR_WITH_NDEBUG constexpr
651 #else
652 
655 #define CONSTEXPR_WITH_NDEBUG
656 #endif
657 
658 #if !defined(LVARRAY_BOUNDS_CHECK)
659 
662 #define CONSTEXPR_WITHOUT_BOUNDS_CHECK constexpr
663 #else
664 
667 #define CONSTEXPR_WITHOUT_BOUNDS_CHECK
668 #endif
669 
670 #if defined(NDEBUG)
671 
674 #define CONSTEXPR_WITH_NDEBUG constexpr
675 #else
676 
679 #define CONSTEXPR_WITH_NDEBUG
680 #endif
681 
682 // TPL includes
683 #include <RAJA/RAJA.hpp>
684 
685 template< typename >
687 {};
688 
689 using serialPolicy = RAJA::loop_exec;
690 
691 template<>
692 struct RAJAHelper< serialPolicy >
693 {
694  using ReducePolicy = RAJA::seq_reduce;
695  using AtomicPolicy = RAJA::seq_atomic;
696 };
697 
698 #if defined(RAJA_ENABLE_OPENMP)
699 
700 using parallelHostPolicy = RAJA::omp_parallel_for_exec;
701 
702 template<>
703 struct RAJAHelper< parallelHostPolicy >
704 {
705  using ReducePolicy = RAJA::omp_reduce;
706  using AtomicPolicy = RAJA::omp_atomic;
707 };
708 
709 #endif
710 
711 #if defined(LVARRAY_USE_CUDA)
712 
713 template< unsigned long THREADS_PER_BLOCK >
714 using parallelDevicePolicy = RAJA::cuda_exec< THREADS_PER_BLOCK >;
715 
716 template< unsigned long N >
717 struct RAJAHelper< RAJA::cuda_exec< N > >
718 {
719  using ReducePolicy = RAJA::cuda_reduce;
720  using AtomicPolicy = RAJA::cuda_atomic;
721 };
722 
723 #elif defined(LVARRAY_USE_HIP)
724 
725 template< unsigned long THREADS_PER_BLOCK >
726 using parallelDevicePolicy = RAJA::hip_exec< THREADS_PER_BLOCK >;
727 
728 template< unsigned long N >
729 struct RAJAHelper< RAJA::hip_exec< N > >
730 {
731  using ReducePolicy = RAJA::hip_reduce;
732  using AtomicPolicy = RAJA::hip_atomic;
733 };
734 
735 #endif
Contains functions that interact with the system or runtime environment.
Definition: Macros.hpp:686