16 #ifndef __INTREPID2_UTILS_HPP__
17 #define __INTREPID2_UTILS_HPP__
19 #include "Intrepid2_ConfigDefs.hpp"
23 #include "Kokkos_Core.hpp"
24 #include "Kokkos_Macros.hpp"
25 #include "Kokkos_Random.hpp"
27 #ifdef HAVE_INTREPID2_SACADO
28 #include "Kokkos_LayoutNatural.hpp"
33 #if defined(__CUDA_ARCH__) || defined(__HIP_DEVICE_COMPILE__) || defined(__SYCL_DEVICE_ONLY__)
34 #define INTREPID2_COMPILE_DEVICE_CODE
37 #if defined(KOKKOS_ENABLE_CUDA) || defined(KOKKOS_ENABLE_HIP) || defined(KOKKOS_ENABLE_SYCL)
38 #define INTREPID2_ENABLE_DEVICE
41 #if defined(KOKKOS_OPT_RANGE_AGGRESSIVE_VECTORIZATION) \
42 && defined(KOKKOS_ENABLE_PRAGMA_IVDEP) \
43 && !defined(INTREPID2_COMPILE_DEVICE_CODE)
44 #define INTREPID2_USE_IVDEP
51 #define INTREPID2_TEST_FOR_WARNING(test, msg) \
53 Kokkos::printf("[Intrepid2] Warning in file %s, line %d\n",__FILE__,__LINE__); \
54 Kokkos::printf(" Test that evaluated to true: %s\n", #test); \
55 Kokkos::printf(" %s \n", msg); \
58 #define INTREPID2_TEST_FOR_EXCEPTION(test, x, msg) \
60 Kokkos::printf("[Intrepid2] Error in file %s, line %d\n",__FILE__,__LINE__); \
61 Kokkos::printf(" Test that evaluated to true: %s\n", #test); \
62 Kokkos::printf(" %s \n", msg); \
68 #ifndef INTREPID2_ENABLE_DEVICE
69 #define INTREPID2_TEST_FOR_EXCEPTION_DEVICE_SAFE(test, x, msg) \
71 std::cout << "[Intrepid2] Error in file " << __FILE__ << ", line " << __LINE__ << "\n"; \
72 std::cout << " Test that evaluated to true: " << #test << "\n"; \
73 std::cout << " " << msg << " \n"; \
77 #define INTREPID2_TEST_FOR_EXCEPTION_DEVICE_SAFE(test, x, msg) \
79 Kokkos::printf("[Intrepid2] Error in file %s, line %d\n",__FILE__,__LINE__); \
80 Kokkos::printf(" Test that evaluated to true: %s\n", #test); \
81 Kokkos::printf(" %s \n", msg); \
82 Kokkos::abort( "[Intrepid2] Abort\n"); \
85 #if defined(INTREPID2_ENABLE_DEBUG) || defined(NDEBUG) || 1
86 #define INTREPID2_TEST_FOR_ABORT(test, msg) \
88 Kokkos::printf("[Intrepid2] Error in file %s, line %d\n",__FILE__,__LINE__); \
89 Kokkos::printf(" Test that evaluated to true: %s\n", #test); \
90 Kokkos::printf(" %s \n", msg); \
91 Kokkos::abort( "[Intrepid2] Abort\n"); \
94 #define INTREPID2_TEST_FOR_ABORT(test, msg) ((void)0)
97 #ifdef INTREPID2_TEST_FOR_DEBUG_ABORT_OVERRIDE_TO_CONTINUE
98 #define INTREPID2_TEST_FOR_DEBUG_ABORT(test, info, msg) \
99 if (!(info) && (test)) { \
100 Kokkos::printf("[Intrepid2] Error in file %s, line %d\n",__FILE__,__LINE__); \
101 Kokkos::printf(" Test that evaluated to true: %s\n", #test); \
102 Kokkos::printf(" %s \n", msg); \
106 #define INTREPID2_TEST_FOR_DEBUG_ABORT(test, info, msg) \
107 if (!(info) && (test)) { \
108 Kokkos::printf("[Intrepid2] Error in file %s, line %d\n",__FILE__,__LINE__); \
109 Kokkos::printf(" Test that evaluated to true: %s\n", #test); \
110 Kokkos::printf(" %s \n", msg); \
112 Kokkos::abort( "[Intrepid2] Abort\n"); \
121 typedef typename T::scalar_type scalar_type;
130 typedef float scalar_type;
137 typedef double scalar_type;
144 typedef int scalar_type;
151 typedef long int scalar_type;
158 typedef long long scalar_type;
166 template<
typename ViewSpaceType,
typename UserSpaceType>
168 typedef UserSpaceType ExecSpaceType;
174 template<
typename ViewSpaceType>
176 typedef ViewSpaceType ExecSpaceType;
183 template <
typename ViewType>
185 using input_layout =
typename ViewType::array_layout;
186 using default_layout =
typename ViewType::device_type::execution_space::array_layout;
187 using result_layout =
188 typename std::conditional<
189 std::is_same< input_layout, Kokkos::LayoutStride >::value,
191 input_layout >::type;
200 template<
typename IdxType,
typename DimType,
typename IterType>
201 KOKKOS_FORCEINLINE_FUNCTION
203 unrollIndex(IdxType &i, IdxType &j,
206 const IterType iter) {
216 template<
typename IdxType,
typename DimType,
typename IterType>
217 KOKKOS_FORCEINLINE_FUNCTION
219 unrollIndex(IdxType &i, IdxType &j, IdxType &k,
223 const IterType iter) {
229 unrollIndex( i, tmp, dim0, dim1*dim2, iter);
230 unrollIndex( j, k, dim1, dim2, tmp);
239 KOKKOS_FORCEINLINE_FUNCTION
240 static T min(
const T a,
const T b) {
241 return (a < b ? a : b);
244 KOKKOS_FORCEINLINE_FUNCTION
245 static T max(
const T a,
const T b) {
246 return (a > b ? a : b);
249 KOKKOS_FORCEINLINE_FUNCTION
250 static T abs(
const T a) {
251 return (a > 0 ? a : T(-a));
257 KOKKOS_FORCEINLINE_FUNCTION
258 static T min(
const T &a,
const T &b) {
259 return (a < b ? a : b);
263 KOKKOS_FORCEINLINE_FUNCTION
264 static T max(
const T &a,
const T &b) {
265 return (a > b ? a : b);
269 KOKKOS_FORCEINLINE_FUNCTION
270 static T abs(
const T &a) {
271 return (a > 0 ? a : T(-a));
282 KOKKOS_FORCEINLINE_FUNCTION
284 std::enable_if< !(std::is_standard_layout<T>::value && std::is_trivial<T>::value),
typename ScalarTraits<T>::scalar_type >::type
285 get_scalar_value(
const T& obj) {
return obj.val();}
288 KOKKOS_FORCEINLINE_FUNCTION
290 std::enable_if< std::is_standard_layout<T>::value && std::is_trivial<T>::value,
typename ScalarTraits<T>::scalar_type >::type
291 get_scalar_value(
const T& obj){
return obj;}
300 template<
typename T,
typename ...P>
301 KOKKOS_INLINE_FUNCTION
303 std::enable_if< std::is_standard_layout<T>::value && std::is_trivial<T>::value,
unsigned >::type
304 dimension_scalar(
const Kokkos::DynRankView<T, P...> ) {
return 1;}
306 template<
typename T,
typename ...P>
307 KOKKOS_INLINE_FUNCTION
309 std::enable_if< std::is_standard_layout<
typename Kokkos::View<T, P...>::value_type>::value && std::is_trivial<
typename Kokkos::View<T, P...>::value_type>::value,
unsigned >::type
310 dimension_scalar(
const Kokkos::View<T, P...> ) {
return 1;}
312 template<
typename T,
typename ...P>
313 KOKKOS_FORCEINLINE_FUNCTION
314 static ordinal_type get_dimension_scalar(
const Kokkos::DynRankView<T, P...> &view) {
315 return dimension_scalar(view);
318 template<
typename T,
typename ...P>
319 KOKKOS_FORCEINLINE_FUNCTION
320 static ordinal_type get_dimension_scalar(
const Kokkos::View<T, P...> &view) {
321 return dimension_scalar(view);
332 template<
class ViewType,
class ... DimArgs>
334 Kokkos::DynRankView<typename ViewType::value_type, typename DeduceLayout< ViewType >::result_layout,
typename ViewType::device_type >
335 getMatchingViewWithLabel(
const ViewType &view,
const std::string &label, DimArgs... dims)
337 using ValueType =
typename ViewType::value_type;
338 using ResultLayout =
typename DeduceLayout< ViewType >::result_layout;
339 using DeviceType =
typename ViewType::device_type;
340 using ViewTypeWithLayout = Kokkos::DynRankView<ValueType, ResultLayout, DeviceType >;
342 const bool allocateFadStorage = !(std::is_standard_layout<ValueType>::value && std::is_trivial<ValueType>::value);
343 if (!allocateFadStorage)
345 return ViewTypeWithLayout(label,dims...);
349 const int derivative_dimension = get_dimension_scalar(view);
350 return ViewTypeWithLayout(label,dims...,derivative_dimension);
354 using std::enable_if_t;
359 template <
typename T,
typename =
void>
365 template <
typename T>
368 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.");
369 #if KOKKOS_VERSION < 40099
370 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.");
376 template<
class Functor, ordinal_type default_value>
378 enable_if_t<has_rank_member<Functor>::value, ordinal_type>
381 return Functor::rank;
387 template<
class Functor, ordinal_type default_value>
389 enable_if_t<!has_rank_member<Functor>::value, ordinal_type>
392 return default_value;
398 template <
typename T>
402 struct two {
char x[2]; };
404 template <
typename C>
static one test(
typename std::remove_reference<decltype( std::declval<C>().
operator()(0))>::type );
405 template <
typename C>
static two test(...);
408 enum { value =
sizeof(test<T>(0)) ==
sizeof(char) && (getFixedRank<T,1>() == 1) };
414 template <
typename T>
418 struct two {
char x[2]; };
420 template <
typename C>
static one test(
typename std::remove_reference<decltype( std::declval<C>().
operator()(0,0))>::type ) ;
421 template <
typename C>
static two test(...);
424 enum { value =
sizeof(test<T>(0)) ==
sizeof(char) && (getFixedRank<T,2>() == 2) };
430 template <
typename T>
434 struct two {
char x[2]; };
436 template <
typename C>
static one test(
typename std::remove_reference<decltype( std::declval<C>().
operator()(0,0,0))>::type ) ;
437 template <
typename C>
static two test(...);
440 enum { value = (
sizeof(test<T>(0)) ==
sizeof(char)) && (getFixedRank<T,3>() == 3) };
446 template <
typename T>
450 struct two {
char x[2]; };
452 template <
typename C>
static one test(
typename std::remove_reference<decltype( std::declval<C>().
operator()(0,0,0,0))>::type ) ;
453 template <
typename C>
static two test(...);
456 enum { value =
sizeof(test<T>(0)) ==
sizeof(char) && (getFixedRank<T,4>() == 4) };
462 template <
typename T>
466 struct two {
char x[2]; };
468 template <
typename C>
static one test(
typename std::remove_reference<decltype( std::declval<C>().
operator()(0,0,0,0,0))>::type ) ;
469 template <
typename C>
static two test(...);
472 enum { value =
sizeof(test<T>(0)) ==
sizeof(char) && (getFixedRank<T,5>() == 5) };
478 template <
typename T>
482 struct two {
char x[2]; };
484 template <
typename C>
static one test(
typename std::remove_reference<decltype( std::declval<C>().
operator()(0,0,0,0,0,0))>::type ) ;
485 template <
typename C>
static two test(...);
488 enum { value =
sizeof(test<T>(0)) ==
sizeof(char) && (getFixedRank<T,6>() == 6) };
494 template <
typename T>
498 struct two {
char x[2]; };
500 template <
typename C>
static one test(
typename std::remove_reference<decltype( std::declval<C>().
operator()(0,0,0,0,0,0,0))>::type ) ;
501 template <
typename C>
static two test(...);
504 enum { value =
sizeof(test<T>(0)) ==
sizeof(char) && (getFixedRank<T,7>() == 7) };
510 template <
typename T,
int rank>
514 enum { value =
false };
520 template <
typename T>
528 template <
typename T>
536 template <
typename T>
544 template <
typename T>
552 template <
typename T>
560 template <
typename T>
568 template <
typename T>
580 template<
typename Scalar,
int rank>
588 template<
typename Scalar>
591 using value_type = Scalar;
597 template<
typename Scalar>
600 using value_type = Scalar*;
606 template<
typename Scalar>
609 using value_type = Scalar**;
615 template<
typename Scalar>
618 using value_type = Scalar***;
624 template<
typename Scalar>
627 using value_type = Scalar****;
633 template<
typename Scalar>
636 using value_type = Scalar*****;
642 template<
typename Scalar>
645 using value_type = Scalar******;
651 template<
typename Scalar>
654 using value_type = Scalar*******;
658 static_assert(
supports_rank<Kokkos::DynRankView<double>, 1>::value,
"rank 1 check of supports_rank for DynRankView");
659 static_assert(
supports_rank<Kokkos::DynRankView<double>, 2>::value,
"rank 2 check of supports_rank for DynRankView");
660 static_assert(
supports_rank<Kokkos::DynRankView<double>, 3>::value,
"rank 3 check of supports_rank for DynRankView");
661 static_assert(
supports_rank<Kokkos::DynRankView<double>, 4>::value,
"rank 4 check of supports_rank for DynRankView");
662 static_assert(
supports_rank<Kokkos::DynRankView<double>, 5>::value,
"rank 5 check of supports_rank for DynRankView");
663 static_assert(
supports_rank<Kokkos::DynRankView<double>, 6>::value,
"rank 6 check of supports_rank for DynRankView");
664 static_assert(
supports_rank<Kokkos::DynRankView<double>, 7>::value,
"rank 7 check of supports_rank for DynRankView");
667 static_assert(
supports_rank<Kokkos::View<double*>, 1>::value,
"rank 1 check of supports_rank");
668 static_assert(
supports_rank<Kokkos::View<double**>, 2>::value,
"rank 2 check of supports_rank");
669 static_assert(
supports_rank<Kokkos::View<double***>, 3>::value,
"rank 3 check of supports_rank");
670 static_assert(
supports_rank<Kokkos::View<double****>, 4>::value,
"rank 4 check of supports_rank");
671 static_assert(
supports_rank<Kokkos::View<double*****>, 5>::value,
"rank 5 check of supports_rank");
672 static_assert(
supports_rank<Kokkos::View<double******>, 6>::value,
"rank 6 check of supports_rank");
673 static_assert(
supports_rank<Kokkos::View<double*******>, 7>::value,
"rank 7 check of supports_rank");
676 static_assert(!
supports_rank<Kokkos::View<double*>, 2>::value,
"rank 1 check of supports_rank");
677 static_assert(!
supports_rank<Kokkos::View<double*>, 3>::value,
"rank 1 check of supports_rank");
678 static_assert(!
supports_rank<Kokkos::View<double*>, 4>::value,
"rank 1 check of supports_rank");
679 static_assert(!
supports_rank<Kokkos::View<double*>, 5>::value,
"rank 1 check of supports_rank");
680 static_assert(!
supports_rank<Kokkos::View<double*>, 6>::value,
"rank 1 check of supports_rank");
681 static_assert(!
supports_rank<Kokkos::View<double*>, 7>::value,
"rank 1 check of supports_rank");
682 static_assert(!
supports_rank<Kokkos::View<double**>, 1>::value,
"rank 2 check of supports_rank");
683 static_assert(!
supports_rank<Kokkos::View<double**>, 3>::value,
"rank 2 check of supports_rank");
684 static_assert(!
supports_rank<Kokkos::View<double**>, 4>::value,
"rank 2 check of supports_rank");
685 static_assert(!
supports_rank<Kokkos::View<double**>, 5>::value,
"rank 2 check of supports_rank");
686 static_assert(!
supports_rank<Kokkos::View<double**>, 6>::value,
"rank 2 check of supports_rank");
687 static_assert(!
supports_rank<Kokkos::View<double**>, 7>::value,
"rank 2 check of supports_rank");
688 static_assert(!
supports_rank<Kokkos::View<double***>, 1>::value,
"rank 3 check of supports_rank");
689 static_assert(!
supports_rank<Kokkos::View<double***>, 2>::value,
"rank 3 check of supports_rank");
690 static_assert(!
supports_rank<Kokkos::View<double***>, 4>::value,
"rank 3 check of supports_rank");
691 static_assert(!
supports_rank<Kokkos::View<double***>, 5>::value,
"rank 3 check of supports_rank");
692 static_assert(!
supports_rank<Kokkos::View<double***>, 6>::value,
"rank 3 check of supports_rank");
693 static_assert(!
supports_rank<Kokkos::View<double***>, 7>::value,
"rank 3 check of supports_rank");
694 static_assert(!
supports_rank<Kokkos::View<double****>, 1>::value,
"rank 4 check of supports_rank");
695 static_assert(!
supports_rank<Kokkos::View<double****>, 2>::value,
"rank 4 check of supports_rank");
696 static_assert(!
supports_rank<Kokkos::View<double****>, 3>::value,
"rank 4 check of supports_rank");
697 static_assert(!
supports_rank<Kokkos::View<double****>, 5>::value,
"rank 4 check of supports_rank");
698 static_assert(!
supports_rank<Kokkos::View<double****>, 6>::value,
"rank 4 check of supports_rank");
699 static_assert(!
supports_rank<Kokkos::View<double****>, 7>::value,
"rank 4 check of supports_rank");
700 static_assert(!
supports_rank<Kokkos::View<double*****>, 1>::value,
"rank 5 check of supports_rank");
701 static_assert(!
supports_rank<Kokkos::View<double*****>, 2>::value,
"rank 5 check of supports_rank");
702 static_assert(!
supports_rank<Kokkos::View<double*****>, 3>::value,
"rank 5 check of supports_rank");
703 static_assert(!
supports_rank<Kokkos::View<double*****>, 4>::value,
"rank 5 check of supports_rank");
704 static_assert(!
supports_rank<Kokkos::View<double*****>, 6>::value,
"rank 5 check of supports_rank");
705 static_assert(!
supports_rank<Kokkos::View<double*****>, 7>::value,
"rank 5 check of supports_rank");
706 static_assert(!
supports_rank<Kokkos::View<double******>, 1>::value,
"rank 6 check of supports_rank");
707 static_assert(!
supports_rank<Kokkos::View<double******>, 2>::value,
"rank 6 check of supports_rank");
708 static_assert(!
supports_rank<Kokkos::View<double******>, 3>::value,
"rank 6 check of supports_rank");
709 static_assert(!
supports_rank<Kokkos::View<double******>, 4>::value,
"rank 6 check of supports_rank");
710 static_assert(!
supports_rank<Kokkos::View<double******>, 5>::value,
"rank 6 check of supports_rank");
711 static_assert(!
supports_rank<Kokkos::View<double******>, 7>::value,
"rank 6 check of supports_rank");
712 static_assert(!
supports_rank<Kokkos::View<double*******>, 1>::value,
"rank 7 check of supports_rank");
713 static_assert(!
supports_rank<Kokkos::View<double*******>, 2>::value,
"rank 7 check of supports_rank");
714 static_assert(!
supports_rank<Kokkos::View<double*******>, 3>::value,
"rank 7 check of supports_rank");
715 static_assert(!
supports_rank<Kokkos::View<double*******>, 4>::value,
"rank 7 check of supports_rank");
716 static_assert(!
supports_rank<Kokkos::View<double*******>, 5>::value,
"rank 7 check of supports_rank");
717 static_assert(!
supports_rank<Kokkos::View<double*******>, 6>::value,
"rank 7 check of supports_rank");
722 template <
typename T>
726 struct two {
char x[2]; };
728 template <
typename C>
static one test( decltype( std::declval<C>().rank() ) ) ;
729 template <
typename C>
static two test(...);
732 enum { value =
sizeof(test<T>(0)) ==
sizeof(char) };
735 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.");
736 #if KOKKOS_VERSION < 40099
737 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.");
743 template<
class Functor>
744 enable_if_t<has_rank_method<Functor>::value,
unsigned>
745 KOKKOS_INLINE_FUNCTION
746 getFunctorRank(
const Functor &functor)
748 return functor.rank();
754 template<
class Functor>
755 enable_if_t<!has_rank_method<Functor>::value,
unsigned>
756 KOKKOS_INLINE_FUNCTION
757 getFunctorRank(
const Functor &functor)
765 #ifdef HAVE_INTREPID2_SACADO
766 template <
typename ValueType>
767 struct NaturalLayoutForType {
769 typename std::conditional<(std::is_standard_layout<ValueType>::value && std::is_trivial<ValueType>::value),
771 Kokkos::LayoutNatural<Kokkos::LayoutLeft> >::type;
774 template <
typename ValueType>
776 using layout = Kokkos::LayoutLeft;
781 const int VECTOR_SIZE = 1;
782 #if defined(SACADO_VIEW_CUDA_HIERARCHICAL_DFAD) && defined(INTREPID2_ENABLE_DEVICE)
783 const int FAD_VECTOR_SIZE = 32;
785 const int FAD_VECTOR_SIZE = 1;
791 template<
typename Scalar>
792 constexpr
int getVectorSizeForHierarchicalParallelism()
794 return (std::is_standard_layout<Scalar>::value && std::is_trivial<Scalar>::value) ? VECTOR_SIZE : FAD_VECTOR_SIZE;
802 template<
typename ViewType>
803 KOKKOS_INLINE_FUNCTION
804 constexpr
unsigned getScalarDimensionForView(
const ViewType &view)
806 return (std::is_standard_layout<typename ViewType::value_type>::value && std::is_trivial<typename ViewType::value_type>::value) ? 0 : get_dimension_scalar(view);
810 template<
typename Device>
813 void operator()(T* ptr) {
814 Kokkos::parallel_for(Kokkos::RangePolicy<typename Device::execution_space>(0,1),
815 KOKKOS_LAMBDA (
const int i) { ptr->~T(); });
816 typename Device::execution_space().fence();
817 Kokkos::kokkos_free<typename Device::memory_space>(ptr);
824 template<
typename Device,
typename Derived>
825 std::unique_ptr<Derived,DeviceDeleter<Device>>
826 copy_virtual_class_to_device(
const Derived& host_source)
828 auto* p =
static_cast<Derived*
>(Kokkos::kokkos_malloc<typename Device::memory_space>(
sizeof(Derived)));
829 Kokkos::parallel_for(Kokkos::RangePolicy<typename Device::execution_space>(0,1),
830 KOKKOS_LAMBDA (
const int i) {
new (p) Derived(host_source); });
831 typename Device::execution_space().fence();
832 return std::unique_ptr<Derived,DeviceDeleter<Device>>(p);
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...
Struct for deleting device instantiation.
layout deduction (temporary meta-function)