Intrepid2
Intrepid2_Utils.hpp
Go to the documentation of this file.
1 // @HEADER
2 // *****************************************************************************
3 // Intrepid2 Package
4 //
5 // Copyright 2007 NTESS and the Intrepid2 contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
16 #ifndef __INTREPID2_UTILS_HPP__
17 #define __INTREPID2_UTILS_HPP__
18 
19 #include "Intrepid2_ConfigDefs.hpp"
21 #include "Intrepid2_Types.hpp"
22 
23 #include "Kokkos_Core.hpp"
24 #include "Kokkos_Macros.hpp" // provides some preprocessor values used in definitions of INTREPID2_DEPRECATED, etc.
25 #include "Kokkos_Random.hpp"
26 
27 #ifdef HAVE_INTREPID2_SACADO
28 #include "Kokkos_LayoutNatural.hpp"
29 #endif
30 
31 namespace Intrepid2 {
32 
33 #if defined(__CUDA_ARCH__) || defined(__HIP_DEVICE_COMPILE__) || defined(__SYCL_DEVICE_ONLY__)
34 #define INTREPID2_COMPILE_DEVICE_CODE
35 #endif
36 
37 #if defined(KOKKOS_ENABLE_CUDA) || defined(KOKKOS_ENABLE_HIP) || defined(KOKKOS_ENABLE_SYCL)
38 #define INTREPID2_ENABLE_DEVICE
39 #endif
40 
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
45 #endif
46 
47  //
48  // test macros
49  //
50 
51 #define INTREPID2_TEST_FOR_WARNING(test, msg) \
52  if (test) { \
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); \
56  }
57 
58 #define INTREPID2_TEST_FOR_EXCEPTION(test, x, msg) \
59  if (test) { \
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); \
63  throw x(msg); \
64  }
65 
68 #ifndef INTREPID2_ENABLE_DEVICE
69 #define INTREPID2_TEST_FOR_EXCEPTION_DEVICE_SAFE(test, x, msg) \
70  if (test) { \
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"; \
74  throw x(msg); \
75  }
76 #else
77 #define INTREPID2_TEST_FOR_EXCEPTION_DEVICE_SAFE(test, x, msg) \
78  if (test) { \
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"); \
83  }
84 #endif
85 #if defined(INTREPID2_ENABLE_DEBUG) || defined(NDEBUG) || 1
86 #define INTREPID2_TEST_FOR_ABORT(test, msg) \
87  if (test) { \
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"); \
92  }
93 #else
94 #define INTREPID2_TEST_FOR_ABORT(test, msg) ((void)0)
95 #endif
96  // check the first error only
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); \
103  info = true; \
104  }
105 #else
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); \
111  info = true ; \
112  Kokkos::abort( "[Intrepid2] Abort\n"); \
113  }
114 #endif
115 
119  template<typename T>
120  struct ScalarTraits {
121  typedef typename T::scalar_type scalar_type;
122  };
123 
124  // this is built in types to support
128  template<>
129  struct ScalarTraits<float> {
130  typedef float scalar_type;
131  };
135  template<>
136  struct ScalarTraits<double> {
137  typedef double scalar_type;
138  };
142  template<>
143  struct ScalarTraits<int> {
144  typedef int scalar_type;
145  };
149  template<>
150  struct ScalarTraits<long int> {
151  typedef long int scalar_type;
152  };
156  template<>
157  struct ScalarTraits<long long> {
158  typedef long long scalar_type;
159  };
160 
161 
162 
166  template<typename ViewSpaceType, typename UserSpaceType>
167  struct ExecSpace {
168  typedef UserSpaceType ExecSpaceType;
169  };
170 
174  template<typename ViewSpaceType>
175  struct ExecSpace<ViewSpaceType,void> {
176  typedef ViewSpaceType ExecSpaceType;
177  };
178 
179 
183  template <typename ViewType>
184  struct DeduceLayout {
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,
190  default_layout,
191  input_layout >::type;
192  };
193 
194 
195  //
196  // utilities device comparible
197  //
198 
199  // this will be gone
200  template<typename IdxType, typename DimType, typename IterType>
201  KOKKOS_FORCEINLINE_FUNCTION
202  static void
203  unrollIndex(IdxType &i, IdxType &j,
204  const DimType /* dim0 */,
205  const DimType dim1,
206  const IterType iter) {
207  // left index
208  //j = iter/dim0;
209  //i = iter%dim0;
210 
211  // right index
212  i = iter/dim1;
213  j = iter%dim1;
214  }
215 
216  template<typename IdxType, typename DimType, typename IterType>
217  KOKKOS_FORCEINLINE_FUNCTION
218  static void
219  unrollIndex(IdxType &i, IdxType &j, IdxType &k,
220  const DimType dim0,
221  const DimType dim1,
222  const DimType dim2,
223  const IterType iter) {
224  IdxType tmp;
225 
226  //unrollIndex(tmp, k, dim0*dim1, dim2, iter);
227  //unrollIndex( i, j, dim0, dim1, tmp);
228 
229  unrollIndex( i, tmp, dim0, dim1*dim2, iter);
230  unrollIndex( j, k, dim1, dim2, tmp);
231  }
232 
236  template<typename T>
237  class Util {
238  public:
239  KOKKOS_FORCEINLINE_FUNCTION
240  static T min(const T a, const T b) {
241  return (a < b ? a : b);
242  }
243 
244  KOKKOS_FORCEINLINE_FUNCTION
245  static T max(const T a, const T b) {
246  return (a > b ? a : b);
247  }
248 
249  KOKKOS_FORCEINLINE_FUNCTION
250  static T abs(const T a) {
251  return (a > 0 ? a : T(-a));
252  }
253 
254  };
255 
256  template<typename T>
257  KOKKOS_FORCEINLINE_FUNCTION
258  static T min(const T &a, const T &b) {
259  return (a < b ? a : b);
260  }
261 
262  template<typename T>
263  KOKKOS_FORCEINLINE_FUNCTION
264  static T max(const T &a, const T &b) {
265  return (a > b ? a : b);
266  }
267 
268  template<typename T>
269  KOKKOS_FORCEINLINE_FUNCTION
270  static T abs(const T &a) {
271  return (a > 0 ? a : T(-a));
272  }
273 
281  template<typename T>
282  KOKKOS_FORCEINLINE_FUNCTION
283  constexpr typename
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();}
286 
287  template<typename T>
288  KOKKOS_FORCEINLINE_FUNCTION
289  constexpr typename
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;}
292 
293 
300  template<typename T, typename ...P>
301  KOKKOS_INLINE_FUNCTION
302  constexpr typename
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...> /* view */) {return 1;}
305 
306  template<typename T, typename ...P>
307  KOKKOS_INLINE_FUNCTION
308  constexpr typename
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...> /*view*/) {return 1;}
311 
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);
316  }
317 
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);
322  }
323 
332  template<class ViewType, class ... DimArgs>
333  inline
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)
336  {
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 >;
341 
342  const bool allocateFadStorage = !(std::is_standard_layout<ValueType>::value && std::is_trivial<ValueType>::value);
343  if (!allocateFadStorage)
344  {
345  return ViewTypeWithLayout(label,dims...);
346  }
347  else
348  {
349  const int derivative_dimension = get_dimension_scalar(view);
350  return ViewTypeWithLayout(label,dims...,derivative_dimension);
351  }
352  }
353 
354  using std::enable_if_t;
355 
359  template <typename T, typename = void>
360  struct has_rank_member : std::false_type{};
361 
365  template <typename T>
366  struct has_rank_member<T, decltype((void)T::rank, void())> : std::true_type {};
367 
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.");
371 #endif
372 
376  template<class Functor, ordinal_type default_value>
377  constexpr
378  enable_if_t<has_rank_member<Functor>::value, ordinal_type>
379  getFixedRank()
380  {
381  return Functor::rank;
382  }
383 
387  template<class Functor, ordinal_type default_value>
388  constexpr
389  enable_if_t<!has_rank_member<Functor>::value, ordinal_type>
390  getFixedRank()
391  {
392  return default_value;
393  }
394 
398  template <typename T>
400  {
401  typedef char one;
402  struct two { char x[2]; };
403 
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(...);
406 
407  public:
408  enum { value = sizeof(test<T>(0)) == sizeof(char) && (getFixedRank<T,1>() == 1) };
409  };
410 
414  template <typename T>
416  {
417  typedef char one;
418  struct two { char x[2]; };
419 
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(...);
422 
423  public:
424  enum { value = sizeof(test<T>(0)) == sizeof(char) && (getFixedRank<T,2>() == 2) };
425  };
426 
430  template <typename T>
432  {
433  typedef char one;
434  struct two { char x[2]; };
435 
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(...);
438 
439  public:
440  enum { value = (sizeof(test<T>(0)) == sizeof(char)) && (getFixedRank<T,3>() == 3) };
441  };
442 
446  template <typename T>
448  {
449  typedef char one;
450  struct two { char x[2]; };
451 
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(...);
454 
455  public:
456  enum { value = sizeof(test<T>(0)) == sizeof(char) && (getFixedRank<T,4>() == 4) };
457  };
458 
462  template <typename T>
464  {
465  typedef char one;
466  struct two { char x[2]; };
467 
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(...);
470 
471  public:
472  enum { value = sizeof(test<T>(0)) == sizeof(char) && (getFixedRank<T,5>() == 5) };
473  };
474 
478  template <typename T>
480  {
481  typedef char one;
482  struct two { char x[2]; };
483 
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(...);
486 
487  public:
488  enum { value = sizeof(test<T>(0)) == sizeof(char) && (getFixedRank<T,6>() == 6) };
489  };
490 
494  template <typename T>
496  {
497  typedef char one;
498  struct two { char x[2]; };
499 
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(...);
502 
503  public:
504  enum { value = sizeof(test<T>(0)) == sizeof(char) && (getFixedRank<T,7>() == 7) };
505  };
506 
510  template <typename T, int rank>
512  {
513  public:
514  enum { value = false };
515  };
516 
520  template <typename T>
521  class supports_rank<T,1>
522  {
523  public:
524  enum { value = supports_rank_1<T>::value };
525  };
526 
528  template <typename T>
529  class supports_rank<T,2>
530  {
531  public:
532  enum { value = supports_rank_2<T>::value };
533  };
534 
536  template <typename T>
537  class supports_rank<T,3>
538  {
539  public:
540  enum { value = supports_rank_3<T>::value };
541  };
542 
544  template <typename T>
545  class supports_rank<T,4>
546  {
547  public:
548  enum { value = supports_rank_4<T>::value };
549  };
550 
552  template <typename T>
553  class supports_rank<T,5>
554  {
555  public:
556  enum { value = supports_rank_5<T>::value };
557  };
558 
560  template <typename T>
561  class supports_rank<T,6>
562  {
563  public:
564  enum { value = supports_rank_6<T>::value };
565  };
566 
568  template <typename T>
569  class supports_rank<T,7>
570  {
571  public:
572  enum { value = supports_rank_7<T>::value };
573  };
574 
575 
576 
580  template<typename Scalar, int rank>
581  struct RankExpander {
582 
583  };
584 
588  template<typename Scalar>
589  struct RankExpander<Scalar,0>
590  {
591  using value_type = Scalar;
592  };
593 
597  template<typename Scalar>
598  struct RankExpander<Scalar,1>
599  {
600  using value_type = Scalar*;
601  };
602 
606  template<typename Scalar>
607  struct RankExpander<Scalar,2>
608  {
609  using value_type = Scalar**;
610  };
611 
615  template<typename Scalar>
616  struct RankExpander<Scalar,3>
617  {
618  using value_type = Scalar***;
619  };
620 
624  template<typename Scalar>
625  struct RankExpander<Scalar,4>
626  {
627  using value_type = Scalar****;
628  };
629 
633  template<typename Scalar>
634  struct RankExpander<Scalar,5>
635  {
636  using value_type = Scalar*****;
637  };
638 
642  template<typename Scalar>
643  struct RankExpander<Scalar,6>
644  {
645  using value_type = Scalar******;
646  };
647 
651  template<typename Scalar>
652  struct RankExpander<Scalar,7>
653  {
654  using value_type = Scalar*******;
655  };
656 
657  // positive checks of supports_rank for Kokkos::DynRankView:
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");
665 
666  // positive checks of supports_rank for Kokkos::View:
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");
674 
675  // negative checks of supports_rank for Kokkos::View:
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");
718 
722  template <typename T>
724  {
725  typedef char one;
726  struct two { char x[2]; };
727 
728  template <typename C> static one test( decltype( std::declval<C>().rank() ) ) ;
729  template <typename C> static two test(...);
730 
731  public:
732  enum { value = sizeof(test<T>(0)) == sizeof(char) };
733  };
734 
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.");
738 #endif
739 
743  template<class Functor>
744  enable_if_t<has_rank_method<Functor>::value, unsigned>
745  KOKKOS_INLINE_FUNCTION
746  getFunctorRank(const Functor &functor)
747  {
748  return functor.rank();
749  }
750 
754  template<class Functor>
755  enable_if_t<!has_rank_method<Functor>::value, unsigned>
756  KOKKOS_INLINE_FUNCTION
757  getFunctorRank(const Functor &functor)
758  {
759  return functor.rank;
760  }
761 
765 #ifdef HAVE_INTREPID2_SACADO
766  template <typename ValueType>
767  struct NaturalLayoutForType {
768  using layout =
769  typename std::conditional<(std::is_standard_layout<ValueType>::value && std::is_trivial<ValueType>::value),
770  Kokkos::LayoutLeft, // for POD types, use LayoutLeft
771  Kokkos::LayoutNatural<Kokkos::LayoutLeft> >::type; // For FAD types, use LayoutNatural
772  };
773 #else
774  template <typename ValueType>
776  using layout = Kokkos::LayoutLeft;
777  };
778 #endif
779 
780  // define vector sizes for hierarchical parallelism
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;
784 #else
785  const int FAD_VECTOR_SIZE = 1;
786 #endif
787 
791  template<typename Scalar>
792  constexpr int getVectorSizeForHierarchicalParallelism()
793  {
794  return (std::is_standard_layout<Scalar>::value && std::is_trivial<Scalar>::value) ? VECTOR_SIZE : FAD_VECTOR_SIZE;
795  }
796 
802  template<typename ViewType>
803  KOKKOS_INLINE_FUNCTION
804  constexpr unsigned getScalarDimensionForView(const ViewType &view)
805  {
806  return (std::is_standard_layout<typename ViewType::value_type>::value && std::is_trivial<typename ViewType::value_type>::value) ? 0 : get_dimension_scalar(view);
807  }
808 
810  template<typename Device>
811  struct DeviceDeleter {
812  template<typename T>
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);
818  }
819  };
820 
824  template<typename Device,typename Derived>
825  std::unique_ptr<Derived,DeviceDeleter<Device>>
826  copy_virtual_class_to_device(const Derived& host_source)
827  {
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);
833  }
834 } // end namespace Intrepid2
835 
836 #endif
SFINAE helper to detect whether a type supports a 5-integral-argument operator(). ...
small utility functions
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 *&#39;s matches the given rank.
scalar type traits
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)