49 #ifndef __INTREPID2_UTILS_HPP__
50 #define __INTREPID2_UTILS_HPP__
52 #include "Intrepid2_ConfigDefs.hpp"
56 #include "Kokkos_Core.hpp"
57 #include "Kokkos_Macros.hpp"
58 #include "Kokkos_Random.hpp"
60 #ifdef HAVE_INTREPID2_SACADO
61 #include "Kokkos_LayoutNatural.hpp"
66 #if defined(__CUDA_ARCH__) || defined(__HIP_DEVICE_COMPILE__) || defined(__SYCL_DEVICE_ONLY__)
67 #define INTREPID2_COMPILE_DEVICE_CODE
70 #if defined(KOKKOS_ENABLE_CUDA) || defined(KOKKOS_ENABLE_HIP) || defined(KOKKOS_ENABLE_SYCL)
71 #define INTREPID2_ENABLE_DEVICE
74 #if defined(KOKKOS_OPT_RANGE_AGGRESSIVE_VECTORIZATION) \
75 && defined(KOKKOS_ENABLE_PRAGMA_IVDEP) \
76 && !defined(INTREPID2_COMPILE_DEVICE_CODE)
77 #define INTREPID2_USE_IVDEP
84 #define INTREPID2_TEST_FOR_WARNING(test, msg) \
86 Kokkos::printf("[Intrepid2] Warning in file %s, line %d\n",__FILE__,__LINE__); \
87 Kokkos::printf(" Test that evaluated to true: %s\n", #test); \
88 Kokkos::printf(" %s \n", msg); \
91 #define INTREPID2_TEST_FOR_EXCEPTION(test, x, msg) \
93 Kokkos::printf("[Intrepid2] Error in file %s, line %d\n",__FILE__,__LINE__); \
94 Kokkos::printf(" Test that evaluated to true: %s\n", #test); \
95 Kokkos::printf(" %s \n", msg); \
101 #ifndef INTREPID2_ENABLE_DEVICE
102 #define INTREPID2_TEST_FOR_EXCEPTION_DEVICE_SAFE(test, x, msg) \
104 std::cout << "[Intrepid2] Error in file " << __FILE__ << ", line " << __LINE__ << "\n"; \
105 std::cout << " Test that evaluated to true: " << #test << "\n"; \
106 std::cout << " " << msg << " \n"; \
110 #define INTREPID2_TEST_FOR_EXCEPTION_DEVICE_SAFE(test, x, msg) \
112 Kokkos::printf("[Intrepid2] Error in file %s, line %d\n",__FILE__,__LINE__); \
113 Kokkos::printf(" Test that evaluated to true: %s\n", #test); \
114 Kokkos::printf(" %s \n", msg); \
115 Kokkos::abort( "[Intrepid2] Abort\n"); \
118 #if defined(INTREPID2_ENABLE_DEBUG) || defined(NDEBUG) || 1
119 #define INTREPID2_TEST_FOR_ABORT(test, msg) \
121 Kokkos::printf("[Intrepid2] Error in file %s, line %d\n",__FILE__,__LINE__); \
122 Kokkos::printf(" Test that evaluated to true: %s\n", #test); \
123 Kokkos::printf(" %s \n", msg); \
124 Kokkos::abort( "[Intrepid2] Abort\n"); \
127 #define INTREPID2_TEST_FOR_ABORT(test, msg) ((void)0)
130 #ifdef INTREPID2_TEST_FOR_DEBUG_ABORT_OVERRIDE_TO_CONTINUE
131 #define INTREPID2_TEST_FOR_DEBUG_ABORT(test, info, msg) \
132 if (!(info) && (test)) { \
133 Kokkos::printf("[Intrepid2] Error in file %s, line %d\n",__FILE__,__LINE__); \
134 Kokkos::printf(" Test that evaluated to true: %s\n", #test); \
135 Kokkos::printf(" %s \n", msg); \
139 #define INTREPID2_TEST_FOR_DEBUG_ABORT(test, info, msg) \
140 if (!(info) && (test)) { \
141 Kokkos::printf("[Intrepid2] Error in file %s, line %d\n",__FILE__,__LINE__); \
142 Kokkos::printf(" Test that evaluated to true: %s\n", #test); \
143 Kokkos::printf(" %s \n", msg); \
145 Kokkos::abort( "[Intrepid2] Abort\n"); \
154 typedef typename T::scalar_type scalar_type;
163 typedef float scalar_type;
170 typedef double scalar_type;
177 typedef int scalar_type;
184 typedef long int scalar_type;
191 typedef long long scalar_type;
199 template<
typename ViewSpaceType,
typename UserSpaceType>
201 typedef UserSpaceType ExecSpaceType;
207 template<
typename ViewSpaceType>
209 typedef ViewSpaceType ExecSpaceType;
216 template <
typename ViewType>
218 using input_layout =
typename ViewType::array_layout;
219 using default_layout =
typename ViewType::device_type::execution_space::array_layout;
220 using result_layout =
221 typename std::conditional<
222 std::is_same< input_layout, Kokkos::LayoutStride >::value,
224 input_layout >::type;
233 template<
typename IdxType,
typename DimType,
typename IterType>
234 KOKKOS_FORCEINLINE_FUNCTION
236 unrollIndex(IdxType &i, IdxType &j,
239 const IterType iter) {
249 template<
typename IdxType,
typename DimType,
typename IterType>
250 KOKKOS_FORCEINLINE_FUNCTION
252 unrollIndex(IdxType &i, IdxType &j, IdxType &k,
256 const IterType iter) {
262 unrollIndex( i, tmp, dim0, dim1*dim2, iter);
263 unrollIndex( j, k, dim1, dim2, tmp);
272 KOKKOS_FORCEINLINE_FUNCTION
273 static T min(
const T a,
const T b) {
274 return (a < b ? a : b);
277 KOKKOS_FORCEINLINE_FUNCTION
278 static T max(
const T a,
const T b) {
279 return (a > b ? a : b);
282 KOKKOS_FORCEINLINE_FUNCTION
283 static T abs(
const T a) {
284 return (a > 0 ? a : T(-a));
290 KOKKOS_FORCEINLINE_FUNCTION
291 static T min(
const T &a,
const T &b) {
292 return (a < b ? a : b);
296 KOKKOS_FORCEINLINE_FUNCTION
297 static T max(
const T &a,
const T &b) {
298 return (a > b ? a : b);
302 KOKKOS_FORCEINLINE_FUNCTION
303 static T abs(
const T &a) {
304 return (a > 0 ? a : T(-a));
315 KOKKOS_FORCEINLINE_FUNCTION
317 std::enable_if< !std::is_pod<T>::value,
typename ScalarTraits<T>::scalar_type >::type
318 get_scalar_value(
const T& obj) {
return obj.val();}
321 KOKKOS_FORCEINLINE_FUNCTION
323 std::enable_if< std::is_pod<T>::value,
typename ScalarTraits<T>::scalar_type >::type
324 get_scalar_value(
const T& obj){
return obj;}
333 template<
typename T,
typename ...P>
334 KOKKOS_INLINE_FUNCTION
336 std::enable_if< std::is_pod<T>::value,
unsigned >::type
337 dimension_scalar(
const Kokkos::DynRankView<T, P...> ) {
return 1;}
339 template<
typename T,
typename ...P>
340 KOKKOS_INLINE_FUNCTION
342 std::enable_if< std::is_pod<
typename Kokkos::View<T, P...>::value_type >::value,
unsigned >::type
343 dimension_scalar(
const Kokkos::View<T, P...> ) {
return 1;}
345 template<
typename T,
typename ...P>
346 KOKKOS_FORCEINLINE_FUNCTION
347 static ordinal_type get_dimension_scalar(
const Kokkos::DynRankView<T, P...> &view) {
348 return dimension_scalar(view);
351 template<
typename T,
typename ...P>
352 KOKKOS_FORCEINLINE_FUNCTION
353 static ordinal_type get_dimension_scalar(
const Kokkos::View<T, P...> &view) {
354 return dimension_scalar(view);
365 template<
class ViewType,
class ... DimArgs>
367 Kokkos::DynRankView<typename ViewType::value_type, typename DeduceLayout< ViewType >::result_layout,
typename ViewType::device_type >
368 getMatchingViewWithLabel(
const ViewType &view,
const std::string &label, DimArgs... dims)
370 using ValueType =
typename ViewType::value_type;
371 using ResultLayout =
typename DeduceLayout< ViewType >::result_layout;
372 using DeviceType =
typename ViewType::device_type;
373 using ViewTypeWithLayout = Kokkos::DynRankView<ValueType, ResultLayout, DeviceType >;
375 const bool allocateFadStorage = !std::is_pod<ValueType>::value;
376 if (!allocateFadStorage)
378 return ViewTypeWithLayout(label,dims...);
382 const int derivative_dimension = get_dimension_scalar(view);
383 return ViewTypeWithLayout(label,dims...,derivative_dimension);
387 using std::enable_if_t;
392 template <
typename T,
typename =
void>
398 template <
typename T>
401 static_assert(!
has_rank_member<Kokkos::DynRankView<double> >::value,
"DynRankView does not have a member rank, so this assert should pass -- if not, something may be wrong with has_rank_member.");
402 #if KOKKOS_VERSION < 40099
403 static_assert(
has_rank_member<Kokkos::View<double*> >::value,
"View has a member rank -- if this assert fails, something may be wrong with has_rank_member.");
409 template<
class Functor, ordinal_type default_value>
411 enable_if_t<has_rank_member<Functor>::value, ordinal_type>
414 return Functor::rank;
420 template<
class Functor, ordinal_type default_value>
422 enable_if_t<!has_rank_member<Functor>::value, ordinal_type>
425 return default_value;
431 template <
typename T>
435 struct two {
char x[2]; };
437 template <
typename C>
static one test(
typename std::remove_reference<decltype( std::declval<C>().
operator()(0))>::type );
438 template <
typename C>
static two test(...);
441 enum { value =
sizeof(test<T>(0)) ==
sizeof(char) && (getFixedRank<T,1>() == 1) };
447 template <
typename T>
451 struct two {
char x[2]; };
453 template <
typename C>
static one test(
typename std::remove_reference<decltype( std::declval<C>().
operator()(0,0))>::type ) ;
454 template <
typename C>
static two test(...);
457 enum { value =
sizeof(test<T>(0)) ==
sizeof(char) && (getFixedRank<T,2>() == 2) };
463 template <
typename T>
467 struct two {
char x[2]; };
469 template <
typename C>
static one test(
typename std::remove_reference<decltype( std::declval<C>().
operator()(0,0,0))>::type ) ;
470 template <
typename C>
static two test(...);
473 enum { value = (
sizeof(test<T>(0)) ==
sizeof(char)) && (getFixedRank<T,3>() == 3) };
479 template <
typename T>
483 struct two {
char x[2]; };
485 template <
typename C>
static one test(
typename std::remove_reference<decltype( std::declval<C>().
operator()(0,0,0,0))>::type ) ;
486 template <
typename C>
static two test(...);
489 enum { value =
sizeof(test<T>(0)) ==
sizeof(char) && (getFixedRank<T,4>() == 4) };
495 template <
typename T>
499 struct two {
char x[2]; };
501 template <
typename C>
static one test(
typename std::remove_reference<decltype( std::declval<C>().
operator()(0,0,0,0,0))>::type ) ;
502 template <
typename C>
static two test(...);
505 enum { value =
sizeof(test<T>(0)) ==
sizeof(char) && (getFixedRank<T,5>() == 5) };
511 template <
typename T>
515 struct two {
char x[2]; };
517 template <
typename C>
static one test(
typename std::remove_reference<decltype( std::declval<C>().
operator()(0,0,0,0,0,0))>::type ) ;
518 template <
typename C>
static two test(...);
521 enum { value =
sizeof(test<T>(0)) ==
sizeof(char) && (getFixedRank<T,6>() == 6) };
527 template <
typename T>
531 struct two {
char x[2]; };
533 template <
typename C>
static one test(
typename std::remove_reference<decltype( std::declval<C>().
operator()(0,0,0,0,0,0,0))>::type ) ;
534 template <
typename C>
static two test(...);
537 enum { value =
sizeof(test<T>(0)) ==
sizeof(char) && (getFixedRank<T,7>() == 7) };
543 template <
typename T,
int rank>
547 enum { value =
false };
553 template <
typename T>
561 template <
typename T>
569 template <
typename T>
577 template <
typename T>
585 template <
typename T>
593 template <
typename T>
601 template <
typename T>
613 template<
typename Scalar,
int rank>
621 template<
typename Scalar>
624 using value_type = Scalar;
630 template<
typename Scalar>
633 using value_type = Scalar*;
639 template<
typename Scalar>
642 using value_type = Scalar**;
648 template<
typename Scalar>
651 using value_type = Scalar***;
657 template<
typename Scalar>
660 using value_type = Scalar****;
666 template<
typename Scalar>
669 using value_type = Scalar*****;
675 template<
typename Scalar>
678 using value_type = Scalar******;
684 template<
typename Scalar>
687 using value_type = Scalar*******;
691 static_assert(
supports_rank<Kokkos::DynRankView<double>, 1>::value,
"rank 1 check of supports_rank for DynRankView");
692 static_assert(
supports_rank<Kokkos::DynRankView<double>, 2>::value,
"rank 2 check of supports_rank for DynRankView");
693 static_assert(
supports_rank<Kokkos::DynRankView<double>, 3>::value,
"rank 3 check of supports_rank for DynRankView");
694 static_assert(
supports_rank<Kokkos::DynRankView<double>, 4>::value,
"rank 4 check of supports_rank for DynRankView");
695 static_assert(
supports_rank<Kokkos::DynRankView<double>, 5>::value,
"rank 5 check of supports_rank for DynRankView");
696 static_assert(
supports_rank<Kokkos::DynRankView<double>, 6>::value,
"rank 6 check of supports_rank for DynRankView");
697 static_assert(
supports_rank<Kokkos::DynRankView<double>, 7>::value,
"rank 7 check of supports_rank for DynRankView");
700 static_assert(
supports_rank<Kokkos::View<double*>, 1>::value,
"rank 1 check of supports_rank");
701 static_assert(
supports_rank<Kokkos::View<double**>, 2>::value,
"rank 2 check of supports_rank");
702 static_assert(
supports_rank<Kokkos::View<double***>, 3>::value,
"rank 3 check of supports_rank");
703 static_assert(
supports_rank<Kokkos::View<double****>, 4>::value,
"rank 4 check of supports_rank");
704 static_assert(
supports_rank<Kokkos::View<double*****>, 5>::value,
"rank 5 check of supports_rank");
705 static_assert(
supports_rank<Kokkos::View<double******>, 6>::value,
"rank 6 check of supports_rank");
706 static_assert(
supports_rank<Kokkos::View<double*******>, 7>::value,
"rank 7 check of supports_rank");
709 static_assert(!
supports_rank<Kokkos::View<double*>, 2>::value,
"rank 1 check of supports_rank");
710 static_assert(!
supports_rank<Kokkos::View<double*>, 3>::value,
"rank 1 check of supports_rank");
711 static_assert(!
supports_rank<Kokkos::View<double*>, 4>::value,
"rank 1 check of supports_rank");
712 static_assert(!
supports_rank<Kokkos::View<double*>, 5>::value,
"rank 1 check of supports_rank");
713 static_assert(!
supports_rank<Kokkos::View<double*>, 6>::value,
"rank 1 check of supports_rank");
714 static_assert(!
supports_rank<Kokkos::View<double*>, 7>::value,
"rank 1 check of supports_rank");
715 static_assert(!
supports_rank<Kokkos::View<double**>, 1>::value,
"rank 2 check of supports_rank");
716 static_assert(!
supports_rank<Kokkos::View<double**>, 3>::value,
"rank 2 check of supports_rank");
717 static_assert(!
supports_rank<Kokkos::View<double**>, 4>::value,
"rank 2 check of supports_rank");
718 static_assert(!
supports_rank<Kokkos::View<double**>, 5>::value,
"rank 2 check of supports_rank");
719 static_assert(!
supports_rank<Kokkos::View<double**>, 6>::value,
"rank 2 check of supports_rank");
720 static_assert(!
supports_rank<Kokkos::View<double**>, 7>::value,
"rank 2 check of supports_rank");
721 static_assert(!
supports_rank<Kokkos::View<double***>, 1>::value,
"rank 3 check of supports_rank");
722 static_assert(!
supports_rank<Kokkos::View<double***>, 2>::value,
"rank 3 check of supports_rank");
723 static_assert(!
supports_rank<Kokkos::View<double***>, 4>::value,
"rank 3 check of supports_rank");
724 static_assert(!
supports_rank<Kokkos::View<double***>, 5>::value,
"rank 3 check of supports_rank");
725 static_assert(!
supports_rank<Kokkos::View<double***>, 6>::value,
"rank 3 check of supports_rank");
726 static_assert(!
supports_rank<Kokkos::View<double***>, 7>::value,
"rank 3 check of supports_rank");
727 static_assert(!
supports_rank<Kokkos::View<double****>, 1>::value,
"rank 4 check of supports_rank");
728 static_assert(!
supports_rank<Kokkos::View<double****>, 2>::value,
"rank 4 check of supports_rank");
729 static_assert(!
supports_rank<Kokkos::View<double****>, 3>::value,
"rank 4 check of supports_rank");
730 static_assert(!
supports_rank<Kokkos::View<double****>, 5>::value,
"rank 4 check of supports_rank");
731 static_assert(!
supports_rank<Kokkos::View<double****>, 6>::value,
"rank 4 check of supports_rank");
732 static_assert(!
supports_rank<Kokkos::View<double****>, 7>::value,
"rank 4 check of supports_rank");
733 static_assert(!
supports_rank<Kokkos::View<double*****>, 1>::value,
"rank 5 check of supports_rank");
734 static_assert(!
supports_rank<Kokkos::View<double*****>, 2>::value,
"rank 5 check of supports_rank");
735 static_assert(!
supports_rank<Kokkos::View<double*****>, 3>::value,
"rank 5 check of supports_rank");
736 static_assert(!
supports_rank<Kokkos::View<double*****>, 4>::value,
"rank 5 check of supports_rank");
737 static_assert(!
supports_rank<Kokkos::View<double*****>, 6>::value,
"rank 5 check of supports_rank");
738 static_assert(!
supports_rank<Kokkos::View<double*****>, 7>::value,
"rank 5 check of supports_rank");
739 static_assert(!
supports_rank<Kokkos::View<double******>, 1>::value,
"rank 6 check of supports_rank");
740 static_assert(!
supports_rank<Kokkos::View<double******>, 2>::value,
"rank 6 check of supports_rank");
741 static_assert(!
supports_rank<Kokkos::View<double******>, 3>::value,
"rank 6 check of supports_rank");
742 static_assert(!
supports_rank<Kokkos::View<double******>, 4>::value,
"rank 6 check of supports_rank");
743 static_assert(!
supports_rank<Kokkos::View<double******>, 5>::value,
"rank 6 check of supports_rank");
744 static_assert(!
supports_rank<Kokkos::View<double******>, 7>::value,
"rank 6 check of supports_rank");
745 static_assert(!
supports_rank<Kokkos::View<double*******>, 1>::value,
"rank 7 check of supports_rank");
746 static_assert(!
supports_rank<Kokkos::View<double*******>, 2>::value,
"rank 7 check of supports_rank");
747 static_assert(!
supports_rank<Kokkos::View<double*******>, 3>::value,
"rank 7 check of supports_rank");
748 static_assert(!
supports_rank<Kokkos::View<double*******>, 4>::value,
"rank 7 check of supports_rank");
749 static_assert(!
supports_rank<Kokkos::View<double*******>, 5>::value,
"rank 7 check of supports_rank");
750 static_assert(!
supports_rank<Kokkos::View<double*******>, 6>::value,
"rank 7 check of supports_rank");
755 template <
typename T>
759 struct two {
char x[2]; };
761 template <
typename C>
static one test( decltype( std::declval<C>().rank() ) ) ;
762 template <
typename C>
static two test(...);
765 enum { value =
sizeof(test<T>(0)) ==
sizeof(char) };
768 static_assert(
has_rank_method<Kokkos::DynRankView<double> >::value,
"DynRankView implements rank(), so this assert should pass -- if not, something may be wrong with has_rank_method.");
769 #if KOKKOS_VERSION < 40099
770 static_assert(
has_rank_member<Kokkos::View<double*> >::value,
"View has a member rank -- if this assert fails, something may be wrong with has_rank_member.");
776 template<
class Functor>
777 enable_if_t<has_rank_method<Functor>::value,
unsigned>
778 KOKKOS_INLINE_FUNCTION
779 getFunctorRank(
const Functor &functor)
781 return functor.rank();
787 template<
class Functor>
788 enable_if_t<!has_rank_method<Functor>::value,
unsigned>
789 KOKKOS_INLINE_FUNCTION
790 getFunctorRank(
const Functor &functor)
798 #ifdef HAVE_INTREPID2_SACADO
799 template <
typename ValueType>
800 struct NaturalLayoutForType {
802 typename std::conditional<std::is_pod<ValueType>::value,
804 Kokkos::LayoutNatural<Kokkos::LayoutLeft> >::type;
807 template <
typename ValueType>
809 using layout = Kokkos::LayoutLeft;
814 const int VECTOR_SIZE = 1;
815 #if defined(SACADO_VIEW_CUDA_HIERARCHICAL_DFAD) && defined(INTREPID2_ENABLE_DEVICE)
816 const int FAD_VECTOR_SIZE = 32;
818 const int FAD_VECTOR_SIZE = 1;
824 template<
typename Scalar>
825 constexpr
int getVectorSizeForHierarchicalParallelism()
827 return std::is_pod<Scalar>::value ? VECTOR_SIZE : FAD_VECTOR_SIZE;
835 template<
typename ViewType>
836 KOKKOS_INLINE_FUNCTION
837 constexpr
unsigned getScalarDimensionForView(
const ViewType &view)
839 return (std::is_pod<typename ViewType::value_type>::value) ? 0 : get_dimension_scalar(view);
SFINAE helper to detect whether a type supports a 5-integral-argument operator(). ...
SFINAE helper to detect whether a type supports a 1-integral-argument operator(). ...
SFINAE helper to detect whether a type supports a 6-integral-argument operator(). ...
SFINAE helper to detect whether a type supports a 7-integral-argument operator(). ...
SFINAE helper to detect whether a type supports a rank-integral-argument operator().
SFINAE helper to detect whether a type supports a 2-integral-argument operator(). ...
Implementation of an assert that can safely be called from device code.
Helper to get Scalar[*+] where the number of *'s matches the given rank.
SFINAE helper to detect whether a type supports a 3-integral-argument operator(). ...
Tests whether a class implements rank(). Used in getFunctorRank() method below; allows us to do one t...
Contains definitions of custom data types in Intrepid2.
Define layout that will allow us to wrap Sacado Scalar objects in Views without copying.
SFINAE helper to detect whether a type supports a 4-integral-argument operator(). ...
Tests whether a class has a member rank. Used in getFixedRank() method below, which in turn is used i...
layout deduction (temporary meta-function)