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_View_Fad_Fwd.hpp"
29#include "Kokkos_LayoutNatural.hpp"
30#include "Kokkos_ViewFactory.hpp"
35#if defined(__CUDA_ARCH__) || defined(__HIP_DEVICE_COMPILE__) || defined(__SYCL_DEVICE_ONLY__)
36#define INTREPID2_COMPILE_DEVICE_CODE
39#if defined(KOKKOS_ENABLE_CUDA) || defined(KOKKOS_ENABLE_HIP) || defined(KOKKOS_ENABLE_SYCL)
40#define INTREPID2_ENABLE_DEVICE
43#if defined(KOKKOS_OPT_RANGE_AGGRESSIVE_VECTORIZATION) \
44 && defined(KOKKOS_ENABLE_PRAGMA_IVDEP) \
45 && !defined(INTREPID2_COMPILE_DEVICE_CODE)
46#define INTREPID2_USE_IVDEP
53#define INTREPID2_TEST_FOR_WARNING(test, msg) \
55 Kokkos::printf("[Intrepid2] Warning in file %s, line %d\n",__FILE__,__LINE__); \
56 Kokkos::printf(" Test that evaluated to true: %s\n", #test); \
57 Kokkos::printf(" %s \n", msg); \
60#define INTREPID2_TEST_FOR_EXCEPTION(test, x, msg) \
62 Kokkos::printf("[Intrepid2] Error in file %s, line %d\n",__FILE__,__LINE__); \
63 Kokkos::printf(" Test that evaluated to true: %s\n", #test); \
64 Kokkos::printf(" %s \n", msg); \
70#ifndef INTREPID2_ENABLE_DEVICE
71#define INTREPID2_TEST_FOR_EXCEPTION_DEVICE_SAFE(test, x, msg) \
73 std::cout << "[Intrepid2] Error in file " << __FILE__ << ", line " << __LINE__ << "\n"; \
74 std::cout << " Test that evaluated to true: " << #test << "\n"; \
75 std::cout << " " << msg << " \n"; \
79#define INTREPID2_TEST_FOR_EXCEPTION_DEVICE_SAFE(test, x, msg) \
81 Kokkos::printf("[Intrepid2] Error in file %s, line %d\n",__FILE__,__LINE__); \
82 Kokkos::printf(" Test that evaluated to true: %s\n", #test); \
83 Kokkos::printf(" %s \n", msg); \
84 Kokkos::abort( "[Intrepid2] Abort\n"); \
87#if defined(INTREPID2_ENABLE_DEBUG) || defined(NDEBUG) || 1
88#define INTREPID2_TEST_FOR_ABORT(test, msg) \
90 Kokkos::printf("[Intrepid2] Error in file %s, line %d\n",__FILE__,__LINE__); \
91 Kokkos::printf(" Test that evaluated to true: %s\n", #test); \
92 Kokkos::printf(" %s \n", msg); \
93 Kokkos::abort( "[Intrepid2] Abort\n"); \
96#define INTREPID2_TEST_FOR_ABORT(test, msg) ((void)0)
99#ifdef INTREPID2_TEST_FOR_DEBUG_ABORT_OVERRIDE_TO_CONTINUE
100#define INTREPID2_TEST_FOR_DEBUG_ABORT(test, info, msg) \
101 if (!(info) && (test)) { \
102 Kokkos::printf("[Intrepid2] Error in file %s, line %d\n",__FILE__,__LINE__); \
103 Kokkos::printf(" Test that evaluated to true: %s\n", #test); \
104 Kokkos::printf(" %s \n", msg); \
108#define INTREPID2_TEST_FOR_DEBUG_ABORT(test, info, msg) \
109 if (!(info) && (test)) { \
110 Kokkos::printf("[Intrepid2] Error in file %s, line %d\n",__FILE__,__LINE__); \
111 Kokkos::printf(" Test that evaluated to true: %s\n", #test); \
112 Kokkos::printf(" %s \n", msg); \
114 Kokkos::abort( "[Intrepid2] Abort\n"); \
123 typedef typename T::scalar_type scalar_type;
132 typedef float scalar_type;
139 typedef double scalar_type;
146 typedef int scalar_type;
153 typedef long int scalar_type;
160 typedef long long scalar_type;
168 template<
typename ViewSpaceType,
typename UserSpaceType>
170 typedef UserSpaceType ExecSpaceType;
176 template<
typename ViewSpaceType>
178 typedef ViewSpaceType ExecSpaceType;
185 template <
typename ViewType>
187 using input_layout =
typename ViewType::array_layout;
188 using default_layout =
typename ViewType::device_type::execution_space::array_layout;
189 using result_layout =
190 typename std::conditional<
191 std::is_same< input_layout, Kokkos::LayoutStride >::value,
193 input_layout >::type;
202 template<
typename IdxType,
typename DimType,
typename IterType>
203 KOKKOS_FORCEINLINE_FUNCTION
205 unrollIndex(IdxType &i, IdxType &j,
208 const IterType iter) {
218 template<
typename IdxType,
typename DimType,
typename IterType>
219 KOKKOS_FORCEINLINE_FUNCTION
221 unrollIndex(IdxType &i, IdxType &j, IdxType &k,
225 const IterType iter) {
231 unrollIndex( i, tmp, dim0, dim1*dim2, iter);
232 unrollIndex( j, k, dim1, dim2, tmp);
241 KOKKOS_FORCEINLINE_FUNCTION
242 static T min(
const T a,
const T b) {
243 return (a < b ? a : b);
246 KOKKOS_FORCEINLINE_FUNCTION
247 static T max(
const T a,
const T b) {
248 return (a > b ? a : b);
251 template <
typename... Args>
252 requires (std::is_same_v<T, Args> && ...)
253 KOKKOS_FORCEINLINE_FUNCTION
254 static T max(
const T a,
const T b, Args... args) {
256 T tmp_max = max(b, args...);
257 return (a > tmp_max) ? a : tmp_max;
260 KOKKOS_FORCEINLINE_FUNCTION
261 static T abs(
const T a) {
262 return (a > 0 ? a : T(-a));
268 KOKKOS_FORCEINLINE_FUNCTION
269 static T min(
const T &a,
const T &b) {
270 return (a < b ? a : b);
274 KOKKOS_FORCEINLINE_FUNCTION
275 static T max(
const T &a,
const T &b) {
276 return (a > b ? a : b);
280 KOKKOS_FORCEINLINE_FUNCTION
281 static T abs(
const T &a) {
282 return (a > 0 ? a : T(-a));
293 KOKKOS_FORCEINLINE_FUNCTION
295 std::enable_if< !(std::is_standard_layout<T>::value && std::is_trivial<T>::value),
typename ScalarTraits<T>::scalar_type >::type
299 KOKKOS_FORCEINLINE_FUNCTION
301 std::enable_if< std::is_standard_layout<T>::value && std::is_trivial<T>::value,
typename ScalarTraits<T>::scalar_type >::type
302 get_scalar_value(
const T& obj){
return obj;}
311 template<
typename T,
typename ...P>
312 KOKKOS_INLINE_FUNCTION
314 std::enable_if< std::is_standard_layout<T>::value && std::is_trivial<T>::value,
unsigned >::type
317 template<
typename T,
typename ...P>
318 KOKKOS_INLINE_FUNCTION
320 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
321 dimension_scalar(
const Kokkos::View<T, P...> ) {
return 1;}
323 template<
typename T,
typename ...P>
324 KOKKOS_FORCEINLINE_FUNCTION
325 static ordinal_type get_dimension_scalar(
const Kokkos::DynRankView<T, P...> &view) {
329 template<
typename T,
typename ...P>
330 KOKKOS_FORCEINLINE_FUNCTION
331 static ordinal_type get_dimension_scalar(
const Kokkos::View<T, P...> &view) {
337 template <
typename InputView>
340 using value =
typename InputView::non_const_value_type;
341 using layout =
typename DeduceLayout<InputView>::result_layout;
342 using device =
typename InputView::device_type;
343 using type = Kokkos::DynRankView<value, layout, device>;
347 template <
class DataType,
class... Properties>
348 KOKKOS_INLINE_FUNCTION
auto
349 as_scalar_1d_view(
const Kokkos::View<DataType, Properties...> &view) {
350 using view_t = Kokkos::View<DataType, Properties...>;
351#ifdef HAVE_INTREPID2_SACADO
352 if constexpr (Kokkos::is_view_fad<view_t>::value) {
353 return Sacado::as_scalar_view(view);
356 return Kokkos::View<
typename view_t::value_type*, Properties...>(view.data(), view.mapping().required_span_size());
359 template <
class... Args>
360 KOKKOS_INLINE_FUNCTION
auto
361 as_scalar_1d_view(
const Kokkos::DynRankView<Args...> &dyn) {
362 return as_scalar_1d_view(dyn.ConstDownCast());
371 template <
class... ViewPack>
379 template <
class OutViewType,
class CtorProp,
class... Dims>
382 const CtorProp &prop,
385 #ifdef HAVE_INTREPID2_SACADO
386 using view_factory = Kokkos::ViewFactory<ViewPack...>;
387 return view_factory::template create_view<OutViewType>(views..., prop, dims...);
390 return OutViewType(prop, dims...);
401 template <
typename OutViewType,
typename InViewType,
typename CtorProp,
typename... Dims>
404 const CtorProp &prop,
408 return cvf::template create_view<OutViewType>(view, prop, dims...);
416 template <
typename InViewType,
typename CtorProp,
typename... Dims>
417 typename DeduceDynRankView<InViewType>::type
419 const CtorProp &prop,
422 using OutViewType =
typename DeduceDynRankView<InViewType>::type;
423 return createMatchingView<OutViewType>(view, prop, dims...);
432 template <
typename OutViewType,
typename InViewType,
typename CtorProp,
typename... Dims>
433 KOKKOS_INLINE_FUNCTION
434 typename std::enable_if<
435 std::is_pointer_v<CtorProp> && !std::is_convertible_v<CtorProp, const char*>,
439 #ifdef HAVE_INTREPID2_SACADO
440 #ifdef SACADO_HAS_NEW_KOKKOS_VIEW_IMPL
441 if constexpr (Sacado::is_view_fad<InViewType>::value)
443 if constexpr (Kokkos::is_view_fad<InViewType>::value)
446 const int derivative_dimension = get_dimension_scalar(view);
447 return OutViewType(data, dims..., derivative_dimension);
450 return OutViewType(data, dims...);
453 return OutViewType(data, dims...);
462 template <
typename InViewType,
typename CtorProp,
typename ... Dims>
463 KOKKOS_INLINE_FUNCTION
464 typename std::enable_if<
465 std::is_pointer_v<CtorProp> && !std::is_convertible_v<CtorProp, const char*>,
466 typename DeduceDynRankView<InViewType>::type>::type
468 using OutViewType =
typename DeduceDynRankView<InViewType>::type;
469 return createMatchingUnmanagedView<OutViewType>(view, data, dims...);
483 template<
class ViewType,
class ... DimArgs>
485 Kokkos::DynRankView<typename ViewType::value_type, typename DeduceLayout< ViewType >::result_layout,
typename ViewType::device_type >
488 return Impl::createMatchingDynRankView(view, label, dims...);
491 using std::enable_if_t;
496 template <
typename T,
typename =
void>
502 template <
typename T>
510 template<
class Functor, ordinal_type default_value>
512 enable_if_t<has_rank_member<Functor>::value, ordinal_type>
515 return Functor::rank;
521 template<
class Functor, ordinal_type default_value>
523 enable_if_t<!has_rank_member<Functor>::value, ordinal_type>
526 return default_value;
532 template <
typename T>
536 struct two {
char x[2]; };
538 template <
typename C>
static one test(
typename std::remove_reference<
decltype( std::declval<C>().
operator()(0))>::type );
539 template <
typename C>
static two test(...);
542 enum { value =
sizeof(test<T>(0)) ==
sizeof(
char) && (getFixedRank<T,1>() == 1) };
548 template <
typename T>
552 struct two {
char x[2]; };
554 template <
typename C>
static one test(
typename std::remove_reference<
decltype( std::declval<C>().
operator()(0,0))>::type ) ;
555 template <
typename C>
static two test(...);
558 enum { value =
sizeof(test<T>(0)) ==
sizeof(
char) && (getFixedRank<T,2>() == 2) };
564 template <
typename T>
568 struct two {
char x[2]; };
570 template <
typename C>
static one test(
typename std::remove_reference<
decltype( std::declval<C>().
operator()(0,0,0))>::type ) ;
571 template <
typename C>
static two test(...);
574 enum { value = (
sizeof(test<T>(0)) ==
sizeof(
char)) && (getFixedRank<T,3>() == 3) };
580 template <
typename T>
584 struct two {
char x[2]; };
586 template <
typename C>
static one test(
typename std::remove_reference<
decltype( std::declval<C>().
operator()(0,0,0,0))>::type ) ;
587 template <
typename C>
static two test(...);
590 enum { value =
sizeof(test<T>(0)) ==
sizeof(
char) && (getFixedRank<T,4>() == 4) };
596 template <
typename T>
600 struct two {
char x[2]; };
602 template <
typename C>
static one test(
typename std::remove_reference<
decltype( std::declval<C>().
operator()(0,0,0,0,0))>::type ) ;
603 template <
typename C>
static two test(...);
606 enum { value =
sizeof(test<T>(0)) ==
sizeof(
char) && (getFixedRank<T,5>() == 5) };
612 template <
typename T>
616 struct two {
char x[2]; };
618 template <
typename C>
static one test(
typename std::remove_reference<
decltype( std::declval<C>().
operator()(0,0,0,0,0,0))>::type ) ;
619 template <
typename C>
static two test(...);
622 enum { value =
sizeof(test<T>(0)) ==
sizeof(
char) && (getFixedRank<T,6>() == 6) };
628 template <
typename T>
632 struct two {
char x[2]; };
634 template <
typename C>
static one test(
typename std::remove_reference<
decltype( std::declval<C>().
operator()(0,0,0,0,0,0,0))>::type ) ;
635 template <
typename C>
static two test(...);
638 enum { value =
sizeof(test<T>(0)) ==
sizeof(
char) && (getFixedRank<T,7>() == 7) };
644 template <
typename T,
int rank>
648 enum { value =
false };
654 template <
typename T>
662 template <
typename T>
670 template <
typename T>
678 template <
typename T>
686 template <
typename T>
694 template <
typename T>
702 template <
typename T>
714 template<
typename Scalar,
int rank>
722 template<
typename Scalar>
725 using value_type = Scalar;
731 template<
typename Scalar>
734 using value_type = Scalar*;
740 template<
typename Scalar>
743 using value_type = Scalar**;
749 template<
typename Scalar>
752 using value_type = Scalar***;
758 template<
typename Scalar>
761 using value_type = Scalar****;
767 template<
typename Scalar>
770 using value_type = Scalar*****;
776 template<
typename Scalar>
779 using value_type = Scalar******;
785 template<
typename Scalar>
788 using value_type = Scalar*******;
856 template <
typename T>
860 struct two {
char x[2]; };
862 template <
typename C>
static one test(
decltype( std::declval<C>().rank() ) ) ;
863 template <
typename C>
static two test(...);
866 enum { value =
sizeof(test<T>(0)) ==
sizeof(
char) };
869 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.");
874 template<
class Functor>
875 enable_if_t<has_rank_method<Functor>::value,
unsigned>
876 KOKKOS_INLINE_FUNCTION
879 return functor.rank();
885 template<
class Functor>
886 enable_if_t<!has_rank_method<Functor>::value,
unsigned>
887 KOKKOS_INLINE_FUNCTION
896#if defined(HAVE_INTREPID2_SACADO) && !defined(SACADO_HAS_NEW_KOKKOS_VIEW_IMPL)
897 template <
typename ValueType>
898 struct NaturalLayoutForType {
900 typename std::conditional<(std::is_standard_layout<ValueType>::value && std::is_trivial<ValueType>::value),
902 Kokkos::LayoutNatural<Kokkos::LayoutLeft> >::type;
905 template <
typename ValueType>
907 using layout = Kokkos::LayoutLeft;
912 const int VECTOR_SIZE = 1;
913#if defined(SACADO_VIEW_CUDA_HIERARCHICAL_DFAD) && defined(INTREPID2_ENABLE_DEVICE)
914 const int FAD_VECTOR_SIZE = 32;
916 const int FAD_VECTOR_SIZE = 1;
922 template<
typename Scalar>
925 return (std::is_standard_layout<Scalar>::value && std::is_trivial<Scalar>::value) ? VECTOR_SIZE : FAD_VECTOR_SIZE;
933 template<
typename ViewType>
934 KOKKOS_INLINE_FUNCTION
937 return (std::is_standard_layout<typename ViewType::value_type>::value && std::is_trivial<typename ViewType::value_type>::value) ? 0 : get_dimension_scalar(view);
941 template<
typename Device>
944 void operator()(T* ptr) {
945 Kokkos::parallel_for(Kokkos::RangePolicy<typename Device::execution_space>(0,1),
946 KOKKOS_LAMBDA (
const int i) { ptr->~T(); });
947 typename Device::execution_space().fence();
948 Kokkos::kokkos_free<typename Device::memory_space>(ptr);
955 template<
typename Device,
typename Derived>
956 std::unique_ptr<Derived,DeviceDeleter<Device>>
959 auto* p =
static_cast<Derived*
>(Kokkos::kokkos_malloc<typename Device::memory_space>(
sizeof(Derived)));
960 Kokkos::parallel_for(Kokkos::RangePolicy<typename Device::execution_space>(0,1),
961 KOKKOS_LAMBDA (
const int i) {
new (p) Derived(host_source); });
962 typename Device::execution_space().fence();
963 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)
KOKKOS_INLINE_FUNCTION std::enable_if< std::is_pointer_v< CtorProp > &&!std::is_convertible_v< CtorProp, constchar * >, OutViewType >::type createMatchingUnmanagedView(const InViewType &view, const CtorProp &data, const Dims... dims)
Creates an unmanaged view that matches the value_type of the provided view The type of the output vie...
DeduceDynRankView< InViewType >::type createMatchingDynRankView(const InViewType &view, const CtorProp &prop, const Dims... dims)
Creates and returns a view that matches the value_type of the provided view The output view type is d...
KOKKOS_INLINE_FUNCTION std::enable_if< std::is_pointer_v< CtorProp > &&!std::is_convertible_v< CtorProp, constchar * >, typenameDeduceDynRankView< InViewType >::type >::type createMatchingUnmanagedDynRankView(const InViewType &view, const CtorProp &data, const Dims... dims)
Creates an unmanaged view that matches the value_type of the provided view The output view type is de...
OutViewType createMatchingView(const InViewType &view, const CtorProp &prop, const Dims... dims)
Creates and returns a view that matches the value_type of the provided view The type of the output vi...
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. DEPRECATED,...
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().
Used to obtain the dynRankView type from an input View,.
layout deduction (temporary meta-function)
Struct for deleting device instantiation.
Factory to create a view based on the properties of input views The class is useful when the view can...
static OutViewType create_view(const ViewPack &...views, const CtorProp &prop, const Dims... dims)
Creates and returns a view that matches the value_type of the provided view When Sacado is enabled we...
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...