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
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
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) {
318 template<
typename T,
typename ...P>
319 KOKKOS_FORCEINLINE_FUNCTION
320 static ordinal_type get_dimension_scalar(
const Kokkos::View<T, P...> &view) {
332 template<
class ViewType,
class ... DimArgs>
334 Kokkos::DynRankView<typename ViewType::value_type, typename DeduceLayout< ViewType >::result_layout,
typename ViewType::device_type >
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>
369#if KOKKOS_VERSION < 40099
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>
524 enum { value = supports_rank_1<T>::value };
528 template <
typename T>
532 enum { value = supports_rank_2<T>::value };
536 template <
typename T>
540 enum { value = supports_rank_3<T>::value };
544 template <
typename T>
548 enum { value = supports_rank_4<T>::value };
552 template <
typename T>
556 enum { value = supports_rank_5<T>::value };
560 template <
typename T>
564 enum { value = supports_rank_6<T>::value };
568 template <
typename T>
572 enum { value = supports_rank_7<T>::value };
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*******;
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
748 return functor.rank();
754 template<
class Functor>
755 enable_if_t<!has_rank_method<Functor>::value,
unsigned>
756 KOKKOS_INLINE_FUNCTION
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>
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
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>>
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);
Implementation of an assert that can safely be called from device code.
Contains definitions of custom data types in Intrepid2.
enable_if_t< has_rank_method< Functor >::value, unsigned > KOKKOS_INLINE_FUNCTION getFunctorRank(const Functor &functor)
constexpr int getVectorSizeForHierarchicalParallelism()
Returns a vector size to be used for the provided Scalar type in the context of hierarchically-parall...
KOKKOS_FORCEINLINE_FUNCTION constexpr std::enable_if<!(std::is_standard_layout< T >::value &&std::is_trivial< T >::value), typenameScalarTraits< T >::scalar_type >::type get_scalar_value(const T &obj)
functions returning the scalar value. for pod types, they return the input object itself....
constexpr enable_if_t< has_rank_member< Functor >::value, ordinal_type > getFixedRank()
KOKKOS_INLINE_FUNCTION constexpr std::enable_if< std::is_standard_layout< T >::value &&std::is_trivial< 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...
std::unique_ptr< Derived, DeviceDeleter< Device > > copy_virtual_class_to_device(const Derived &host_source)
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....
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 implements rank(). Used in getFunctorRank() method below; allows us to do one t...
SFINAE helper to detect whether a type supports a 1-integral-argument operator().
SFINAE helper to detect whether a type supports a 2-integral-argument operator().
SFINAE helper to detect whether a type supports a 3-integral-argument operator().
SFINAE helper to detect whether a type supports a 4-integral-argument operator().
SFINAE helper to detect whether a type supports a 5-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().
layout deduction (temporary meta-function)
Struct for deleting device instantiation.
Define layout that will allow us to wrap Sacado Scalar objects in Views without copying.
Helper to get Scalar[*+] where the number of *'s matches the given rank.
Tests whether a class has a member rank. Used in getFixedRank() method below, which in turn is used i...