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__) 67 #define INTREPID2_COMPILE_DEVICE_CODE 70 #if defined(KOKKOS_ENABLE_CUDA) || defined(KOKKOS_ENABLE_HIP) 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 printf("[Intrepid2] Warning in file %s, line %d\n",__FILE__,__LINE__); \ 87 printf(" Test that evaluated to true: %s\n", #test); \ 88 printf(" %s \n", msg); \ 91 #define INTREPID2_TEST_FOR_EXCEPTION(test, x, msg) \ 93 printf("[Intrepid2] Error in file %s, line %d\n",__FILE__,__LINE__); \ 94 printf(" Test that evaluated to true: %s\n", #test); \ 95 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 printf("[Intrepid2] Error in file %s, line %d\n",__FILE__,__LINE__); \ 113 printf(" Test that evaluated to true: %s\n", #test); \ 114 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 printf("[Intrepid2] Error in file %s, line %d\n",__FILE__,__LINE__); \ 122 printf(" Test that evaluated to true: %s\n", #test); \ 123 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 printf("[Intrepid2] Error in file %s, line %d\n",__FILE__,__LINE__); \ 134 printf(" Test that evaluated to true: %s\n", #test); \ 135 printf(" %s \n", msg); \ 139 #define INTREPID2_TEST_FOR_DEBUG_ABORT(test, info, msg) \ 140 if (!(info) && (test)) { \ 141 printf("[Intrepid2] Error in file %s, line %d\n",__FILE__,__LINE__); \ 142 printf(" Test that evaluated to true: %s\n", #test); \ 143 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
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
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) {
351 template<
typename T,
typename ...P>
352 KOKKOS_FORCEINLINE_FUNCTION
353 static ordinal_type get_dimension_scalar(
const Kokkos::View<T, P...> &view) {
365 template<
class ViewType,
class ... DimArgs>
367 Kokkos::DynRankView<typename ViewType::value_type, typename DeduceLayout< ViewType >::result_layout,
typename ViewType::device_type >
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 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.");
407 template<
class Functor, ordinal_type default_value>
409 enable_if_t<has_rank_member<Functor>::value, ordinal_type>
412 return Functor::rank;
418 template<
class Functor, ordinal_type default_value>
420 enable_if_t<!has_rank_member<Functor>::value, ordinal_type>
423 return default_value;
429 template <
typename T>
433 struct two {
char x[2]; };
435 template <
typename C>
static one test(
typename std::remove_reference<decltype( std::declval<C>().
operator()(0))>::type );
436 template <
typename C>
static two test(...);
439 enum { value =
sizeof(test<T>(0)) ==
sizeof(char) && (getFixedRank<T,1>() == 1) };
445 template <
typename T>
449 struct two {
char x[2]; };
451 template <
typename C>
static one test(
typename std::remove_reference<decltype( std::declval<C>().
operator()(0,0))>::type ) ;
452 template <
typename C>
static two test(...);
455 enum { value =
sizeof(test<T>(0)) ==
sizeof(char) && (getFixedRank<T,2>() == 2) };
461 template <
typename T>
465 struct two {
char x[2]; };
467 template <
typename C>
static one test(
typename std::remove_reference<decltype( std::declval<C>().
operator()(0,0,0))>::type ) ;
468 template <
typename C>
static two test(...);
471 enum { value = (
sizeof(test<T>(0)) ==
sizeof(char)) && (getFixedRank<T,3>() == 3) };
477 template <
typename T>
481 struct two {
char x[2]; };
483 template <
typename C>
static one test(
typename std::remove_reference<decltype( std::declval<C>().
operator()(0,0,0,0))>::type ) ;
484 template <
typename C>
static two test(...);
487 enum { value =
sizeof(test<T>(0)) ==
sizeof(char) && (getFixedRank<T,4>() == 4) };
493 template <
typename T>
497 struct two {
char x[2]; };
499 template <
typename C>
static one test(
typename std::remove_reference<decltype( std::declval<C>().
operator()(0,0,0,0,0))>::type ) ;
500 template <
typename C>
static two test(...);
503 enum { value =
sizeof(test<T>(0)) ==
sizeof(char) && (getFixedRank<T,5>() == 5) };
509 template <
typename T>
513 struct two {
char x[2]; };
515 template <
typename C>
static one test(
typename std::remove_reference<decltype( std::declval<C>().
operator()(0,0,0,0,0,0))>::type ) ;
516 template <
typename C>
static two test(...);
519 enum { value =
sizeof(test<T>(0)) ==
sizeof(char) && (getFixedRank<T,6>() == 6) };
525 template <
typename T>
529 struct two {
char x[2]; };
531 template <
typename C>
static one test(
typename std::remove_reference<decltype( std::declval<C>().
operator()(0,0,0,0,0,0,0))>::type ) ;
532 template <
typename C>
static two test(...);
535 enum { value =
sizeof(test<T>(0)) ==
sizeof(char) && (getFixedRank<T,7>() == 7) };
541 template <
typename T,
int rank>
545 enum { value =
false };
551 template <
typename T>
559 template <
typename T>
567 template <
typename T>
575 template <
typename T>
583 template <
typename T>
591 template <
typename T>
599 template <
typename T>
611 template<
typename Scalar,
int rank>
619 template<
typename Scalar>
622 using value_type = Scalar;
628 template<
typename Scalar>
631 using value_type = Scalar*;
637 template<
typename Scalar>
640 using value_type = Scalar**;
646 template<
typename Scalar>
649 using value_type = Scalar***;
655 template<
typename Scalar>
658 using value_type = Scalar****;
664 template<
typename Scalar>
667 using value_type = Scalar*****;
673 template<
typename Scalar>
676 using value_type = Scalar******;
682 template<
typename Scalar>
685 using value_type = Scalar*******;
689 static_assert(
supports_rank<Kokkos::DynRankView<double>, 1>::value,
"rank 1 check of supports_rank for DynRankView");
690 static_assert(
supports_rank<Kokkos::DynRankView<double>, 2>::value,
"rank 2 check of supports_rank for DynRankView");
691 static_assert(
supports_rank<Kokkos::DynRankView<double>, 3>::value,
"rank 3 check of supports_rank for DynRankView");
692 static_assert(
supports_rank<Kokkos::DynRankView<double>, 4>::value,
"rank 4 check of supports_rank for DynRankView");
693 static_assert(
supports_rank<Kokkos::DynRankView<double>, 5>::value,
"rank 5 check of supports_rank for DynRankView");
694 static_assert(
supports_rank<Kokkos::DynRankView<double>, 6>::value,
"rank 6 check of supports_rank for DynRankView");
695 static_assert(
supports_rank<Kokkos::DynRankView<double>, 7>::value,
"rank 7 check of supports_rank for DynRankView");
698 static_assert(
supports_rank<Kokkos::View<double*>, 1>::value,
"rank 1 check of supports_rank");
699 static_assert(
supports_rank<Kokkos::View<double**>, 2>::value,
"rank 2 check of supports_rank");
700 static_assert(
supports_rank<Kokkos::View<double***>, 3>::value,
"rank 3 check of supports_rank");
701 static_assert(
supports_rank<Kokkos::View<double****>, 4>::value,
"rank 4 check of supports_rank");
702 static_assert(
supports_rank<Kokkos::View<double*****>, 5>::value,
"rank 5 check of supports_rank");
703 static_assert(
supports_rank<Kokkos::View<double******>, 6>::value,
"rank 6 check of supports_rank");
704 static_assert(
supports_rank<Kokkos::View<double*******>, 7>::value,
"rank 7 check of supports_rank");
707 static_assert(!
supports_rank<Kokkos::View<double*>, 2>::value,
"rank 1 check of supports_rank");
708 static_assert(!
supports_rank<Kokkos::View<double*>, 3>::value,
"rank 1 check of supports_rank");
709 static_assert(!
supports_rank<Kokkos::View<double*>, 4>::value,
"rank 1 check of supports_rank");
710 static_assert(!
supports_rank<Kokkos::View<double*>, 5>::value,
"rank 1 check of supports_rank");
711 static_assert(!
supports_rank<Kokkos::View<double*>, 6>::value,
"rank 1 check of supports_rank");
712 static_assert(!
supports_rank<Kokkos::View<double*>, 7>::value,
"rank 1 check of supports_rank");
713 static_assert(!
supports_rank<Kokkos::View<double**>, 1>::value,
"rank 2 check of supports_rank");
714 static_assert(!
supports_rank<Kokkos::View<double**>, 3>::value,
"rank 2 check of supports_rank");
715 static_assert(!
supports_rank<Kokkos::View<double**>, 4>::value,
"rank 2 check of supports_rank");
716 static_assert(!
supports_rank<Kokkos::View<double**>, 5>::value,
"rank 2 check of supports_rank");
717 static_assert(!
supports_rank<Kokkos::View<double**>, 6>::value,
"rank 2 check of supports_rank");
718 static_assert(!
supports_rank<Kokkos::View<double**>, 7>::value,
"rank 2 check of supports_rank");
719 static_assert(!
supports_rank<Kokkos::View<double***>, 1>::value,
"rank 3 check of supports_rank");
720 static_assert(!
supports_rank<Kokkos::View<double***>, 2>::value,
"rank 3 check of supports_rank");
721 static_assert(!
supports_rank<Kokkos::View<double***>, 4>::value,
"rank 3 check of supports_rank");
722 static_assert(!
supports_rank<Kokkos::View<double***>, 5>::value,
"rank 3 check of supports_rank");
723 static_assert(!
supports_rank<Kokkos::View<double***>, 6>::value,
"rank 3 check of supports_rank");
724 static_assert(!
supports_rank<Kokkos::View<double***>, 7>::value,
"rank 3 check of supports_rank");
725 static_assert(!
supports_rank<Kokkos::View<double****>, 1>::value,
"rank 4 check of supports_rank");
726 static_assert(!
supports_rank<Kokkos::View<double****>, 2>::value,
"rank 4 check of supports_rank");
727 static_assert(!
supports_rank<Kokkos::View<double****>, 3>::value,
"rank 4 check of supports_rank");
728 static_assert(!
supports_rank<Kokkos::View<double****>, 5>::value,
"rank 4 check of supports_rank");
729 static_assert(!
supports_rank<Kokkos::View<double****>, 6>::value,
"rank 4 check of supports_rank");
730 static_assert(!
supports_rank<Kokkos::View<double****>, 7>::value,
"rank 4 check of supports_rank");
731 static_assert(!
supports_rank<Kokkos::View<double*****>, 1>::value,
"rank 5 check of supports_rank");
732 static_assert(!
supports_rank<Kokkos::View<double*****>, 2>::value,
"rank 5 check of supports_rank");
733 static_assert(!
supports_rank<Kokkos::View<double*****>, 3>::value,
"rank 5 check of supports_rank");
734 static_assert(!
supports_rank<Kokkos::View<double*****>, 4>::value,
"rank 5 check of supports_rank");
735 static_assert(!
supports_rank<Kokkos::View<double*****>, 6>::value,
"rank 5 check of supports_rank");
736 static_assert(!
supports_rank<Kokkos::View<double*****>, 7>::value,
"rank 5 check of supports_rank");
737 static_assert(!
supports_rank<Kokkos::View<double******>, 1>::value,
"rank 6 check of supports_rank");
738 static_assert(!
supports_rank<Kokkos::View<double******>, 2>::value,
"rank 6 check of supports_rank");
739 static_assert(!
supports_rank<Kokkos::View<double******>, 3>::value,
"rank 6 check of supports_rank");
740 static_assert(!
supports_rank<Kokkos::View<double******>, 4>::value,
"rank 6 check of supports_rank");
741 static_assert(!
supports_rank<Kokkos::View<double******>, 5>::value,
"rank 6 check of supports_rank");
742 static_assert(!
supports_rank<Kokkos::View<double******>, 7>::value,
"rank 6 check of supports_rank");
743 static_assert(!
supports_rank<Kokkos::View<double*******>, 1>::value,
"rank 7 check of supports_rank");
744 static_assert(!
supports_rank<Kokkos::View<double*******>, 2>::value,
"rank 7 check of supports_rank");
745 static_assert(!
supports_rank<Kokkos::View<double*******>, 3>::value,
"rank 7 check of supports_rank");
746 static_assert(!
supports_rank<Kokkos::View<double*******>, 4>::value,
"rank 7 check of supports_rank");
747 static_assert(!
supports_rank<Kokkos::View<double*******>, 5>::value,
"rank 7 check of supports_rank");
748 static_assert(!
supports_rank<Kokkos::View<double*******>, 6>::value,
"rank 7 check of supports_rank");
753 template <
typename T>
757 struct two {
char x[2]; };
759 template <
typename C>
static one test( decltype( std::declval<C>().rank() ) ) ;
760 template <
typename C>
static two test(...);
763 enum { value =
sizeof(test<T>(0)) ==
sizeof(char) };
766 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.");
767 static_assert(! has_rank_method<Kokkos::View<double> >::value,
"View does not implement rank() -- if this assert fails, something may be wrong with has_rank_method.");
772 template<
class Functor>
773 enable_if_t<has_rank_method<Functor>::value,
unsigned>
774 KOKKOS_INLINE_FUNCTION
777 return functor.rank();
783 template<
class Functor>
784 enable_if_t<!has_rank_method<Functor>::value,
unsigned>
785 KOKKOS_INLINE_FUNCTION
794 #ifdef HAVE_INTREPID2_SACADO 795 template <
typename ValueType>
796 struct NaturalLayoutForType {
798 typename std::conditional<std::is_pod<ValueType>::value,
800 Kokkos::LayoutNatural<Kokkos::LayoutLeft> >::type;
803 template <
typename ValueType>
805 using layout = Kokkos::LayoutLeft;
810 const int VECTOR_SIZE = 1;
811 #if defined(SACADO_VIEW_CUDA_HIERARCHICAL_DFAD) && defined(INTREPID2_ENABLE_DEVICE) 812 const int FAD_VECTOR_SIZE = 32;
814 const int FAD_VECTOR_SIZE = 1;
820 template<
typename Scalar>
823 return std::is_pod<Scalar>::value ? VECTOR_SIZE : FAD_VECTOR_SIZE;
831 template<
typename ViewType>
832 KOKKOS_INLINE_FUNCTION
835 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(). ...
constexpr int getVectorSizeForHierarchicalParallelism()
Returns a vector size to be used for the provided Scalar type in the context of hierarchically-parall...
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(). ...
KOKKOS_INLINE_FUNCTION constexpr std::enable_if< std::is_pod< T >::value, unsigned >::type dimension_scalar(const Kokkos::DynRankView< T, P... >)
specialization of functions for pod types, returning the scalar dimension (1 for pod types) of a view...
Tests whether a class implements rank(). Used in getFunctorRank() method below; allows us to do one t...
KOKKOS_INLINE_FUNCTION constexpr unsigned getScalarDimensionForView(const ViewType &view)
Returns the size of the Scalar dimension for the View. This is 0 for non-AD types. This method is useful for sizing scratch storage in hierarchically parallel kernels. Whereas get_dimension_scalar() returns 1 for POD types, this returns 0 for POD types.
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(). ...
Kokkos::DynRankView< typename ViewType::value_type, typename DeduceLayout< ViewType >::result_layout, typename ViewType::device_type > getMatchingViewWithLabel(const ViewType &view, const std::string &label, DimArgs... dims)
Creates and returns a view that matches the provided view in Kokkos Layout.
Tests whether a class has a member rank. Used in getFixedRank() method below, which in turn is used i...
constexpr enable_if_t< has_rank_member< Functor >::value, ordinal_type > getFixedRank()
KOKKOS_FORCEINLINE_FUNCTION constexpr std::enable_if< !std::is_pod< T >::value, typename ScalarTraits< T >::scalar_type >::type get_scalar_value(const T &obj)
functions returning the scalar value. for pod types, they return the input object itself...
layout deduction (temporary meta-function)
enable_if_t< has_rank_method< Functor >::value, unsigned > KOKKOS_INLINE_FUNCTION getFunctorRank(const Functor &functor)