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_View_Fad_Fwd.hpp"
29 #include "Kokkos_LayoutNatural.hpp"
30 #endif
31 
32 namespace Intrepid2 {
33 
34 #if defined(__CUDA_ARCH__) || defined(__HIP_DEVICE_COMPILE__) || defined(__SYCL_DEVICE_ONLY__)
35 #define INTREPID2_COMPILE_DEVICE_CODE
36 #endif
37 
38 #if defined(KOKKOS_ENABLE_CUDA) || defined(KOKKOS_ENABLE_HIP) || defined(KOKKOS_ENABLE_SYCL)
39 #define INTREPID2_ENABLE_DEVICE
40 #endif
41 
42 #if defined(KOKKOS_OPT_RANGE_AGGRESSIVE_VECTORIZATION) \
43  && defined(KOKKOS_ENABLE_PRAGMA_IVDEP) \
44  && !defined(INTREPID2_COMPILE_DEVICE_CODE)
45 #define INTREPID2_USE_IVDEP
46 #endif
47 
48  //
49  // test macros
50  //
51 
52 #define INTREPID2_TEST_FOR_WARNING(test, msg) \
53  if (test) { \
54  Kokkos::printf("[Intrepid2] Warning in file %s, line %d\n",__FILE__,__LINE__); \
55  Kokkos::printf(" Test that evaluated to true: %s\n", #test); \
56  Kokkos::printf(" %s \n", msg); \
57  }
58 
59 #define INTREPID2_TEST_FOR_EXCEPTION(test, x, msg) \
60  if (test) { \
61  Kokkos::printf("[Intrepid2] Error in file %s, line %d\n",__FILE__,__LINE__); \
62  Kokkos::printf(" Test that evaluated to true: %s\n", #test); \
63  Kokkos::printf(" %s \n", msg); \
64  throw x(msg); \
65  }
66 
69 #ifndef INTREPID2_ENABLE_DEVICE
70 #define INTREPID2_TEST_FOR_EXCEPTION_DEVICE_SAFE(test, x, msg) \
71  if (test) { \
72  std::cout << "[Intrepid2] Error in file " << __FILE__ << ", line " << __LINE__ << "\n"; \
73  std::cout << " Test that evaluated to true: " << #test << "\n"; \
74  std::cout << " " << msg << " \n"; \
75  throw x(msg); \
76  }
77 #else
78 #define INTREPID2_TEST_FOR_EXCEPTION_DEVICE_SAFE(test, x, msg) \
79  if (test) { \
80  Kokkos::printf("[Intrepid2] Error in file %s, line %d\n",__FILE__,__LINE__); \
81  Kokkos::printf(" Test that evaluated to true: %s\n", #test); \
82  Kokkos::printf(" %s \n", msg); \
83  Kokkos::abort( "[Intrepid2] Abort\n"); \
84  }
85 #endif
86 #if defined(INTREPID2_ENABLE_DEBUG) || defined(NDEBUG) || 1
87 #define INTREPID2_TEST_FOR_ABORT(test, msg) \
88  if (test) { \
89  Kokkos::printf("[Intrepid2] Error in file %s, line %d\n",__FILE__,__LINE__); \
90  Kokkos::printf(" Test that evaluated to true: %s\n", #test); \
91  Kokkos::printf(" %s \n", msg); \
92  Kokkos::abort( "[Intrepid2] Abort\n"); \
93  }
94 #else
95 #define INTREPID2_TEST_FOR_ABORT(test, msg) ((void)0)
96 #endif
97  // check the first error only
98 #ifdef INTREPID2_TEST_FOR_DEBUG_ABORT_OVERRIDE_TO_CONTINUE
99 #define INTREPID2_TEST_FOR_DEBUG_ABORT(test, info, msg) \
100  if (!(info) && (test)) { \
101  Kokkos::printf("[Intrepid2] Error in file %s, line %d\n",__FILE__,__LINE__); \
102  Kokkos::printf(" Test that evaluated to true: %s\n", #test); \
103  Kokkos::printf(" %s \n", msg); \
104  info = true; \
105  }
106 #else
107 #define INTREPID2_TEST_FOR_DEBUG_ABORT(test, info, msg) \
108  if (!(info) && (test)) { \
109  Kokkos::printf("[Intrepid2] Error in file %s, line %d\n",__FILE__,__LINE__); \
110  Kokkos::printf(" Test that evaluated to true: %s\n", #test); \
111  Kokkos::printf(" %s \n", msg); \
112  info = true ; \
113  Kokkos::abort( "[Intrepid2] Abort\n"); \
114  }
115 #endif
116 
120  template<typename T>
121  struct ScalarTraits {
122  typedef typename T::scalar_type scalar_type;
123  };
124 
125  // this is built in types to support
129  template<>
130  struct ScalarTraits<float> {
131  typedef float scalar_type;
132  };
136  template<>
137  struct ScalarTraits<double> {
138  typedef double scalar_type;
139  };
143  template<>
144  struct ScalarTraits<int> {
145  typedef int scalar_type;
146  };
150  template<>
151  struct ScalarTraits<long int> {
152  typedef long int scalar_type;
153  };
157  template<>
158  struct ScalarTraits<long long> {
159  typedef long long scalar_type;
160  };
161 
162 
163 
167  template<typename ViewSpaceType, typename UserSpaceType>
168  struct ExecSpace {
169  typedef UserSpaceType ExecSpaceType;
170  };
171 
175  template<typename ViewSpaceType>
176  struct ExecSpace<ViewSpaceType,void> {
177  typedef ViewSpaceType ExecSpaceType;
178  };
179 
180 
184  template <typename ViewType>
185  struct DeduceLayout {
186  using input_layout = typename ViewType::array_layout;
187  using default_layout = typename ViewType::device_type::execution_space::array_layout;
188  using result_layout =
189  typename std::conditional<
190  std::is_same< input_layout, Kokkos::LayoutStride >::value,
191  default_layout,
192  input_layout >::type;
193  };
194 
195 
196  //
197  // utilities device comparible
198  //
199 
200  // this will be gone
201  template<typename IdxType, typename DimType, typename IterType>
202  KOKKOS_FORCEINLINE_FUNCTION
203  static void
204  unrollIndex(IdxType &i, IdxType &j,
205  const DimType /* dim0 */,
206  const DimType dim1,
207  const IterType iter) {
208  // left index
209  //j = iter/dim0;
210  //i = iter%dim0;
211 
212  // right index
213  i = iter/dim1;
214  j = iter%dim1;
215  }
216 
217  template<typename IdxType, typename DimType, typename IterType>
218  KOKKOS_FORCEINLINE_FUNCTION
219  static void
220  unrollIndex(IdxType &i, IdxType &j, IdxType &k,
221  const DimType dim0,
222  const DimType dim1,
223  const DimType dim2,
224  const IterType iter) {
225  IdxType tmp;
226 
227  //unrollIndex(tmp, k, dim0*dim1, dim2, iter);
228  //unrollIndex( i, j, dim0, dim1, tmp);
229 
230  unrollIndex( i, tmp, dim0, dim1*dim2, iter);
231  unrollIndex( j, k, dim1, dim2, tmp);
232  }
233 
237  template<typename T>
238  class Util {
239  public:
240  KOKKOS_FORCEINLINE_FUNCTION
241  static T min(const T a, const T b) {
242  return (a < b ? a : b);
243  }
244 
245  KOKKOS_FORCEINLINE_FUNCTION
246  static T max(const T a, const T b) {
247  return (a > b ? a : b);
248  }
249 
250  KOKKOS_FORCEINLINE_FUNCTION
251  static T abs(const T a) {
252  return (a > 0 ? a : T(-a));
253  }
254 
255  };
256 
257  template<typename T>
258  KOKKOS_FORCEINLINE_FUNCTION
259  static T min(const T &a, const T &b) {
260  return (a < b ? a : b);
261  }
262 
263  template<typename T>
264  KOKKOS_FORCEINLINE_FUNCTION
265  static T max(const T &a, const T &b) {
266  return (a > b ? a : b);
267  }
268 
269  template<typename T>
270  KOKKOS_FORCEINLINE_FUNCTION
271  static T abs(const T &a) {
272  return (a > 0 ? a : T(-a));
273  }
274 
282  template<typename T>
283  KOKKOS_FORCEINLINE_FUNCTION
284  constexpr typename
285  std::enable_if< !(std::is_standard_layout<T>::value && std::is_trivial<T>::value), typename ScalarTraits<T>::scalar_type >::type
286  get_scalar_value(const T& obj) {return obj.val();}
287 
288  template<typename T>
289  KOKKOS_FORCEINLINE_FUNCTION
290  constexpr typename
291  std::enable_if< std::is_standard_layout<T>::value && std::is_trivial<T>::value, typename ScalarTraits<T>::scalar_type >::type
292  get_scalar_value(const T& obj){return obj;}
293 
294 
301  template<typename T, typename ...P>
302  KOKKOS_INLINE_FUNCTION
303  constexpr typename
304  std::enable_if< std::is_standard_layout<T>::value && std::is_trivial<T>::value, unsigned >::type
305  dimension_scalar(const Kokkos::DynRankView<T, P...> /* view */) {return 1;}
306 
307  template<typename T, typename ...P>
308  KOKKOS_INLINE_FUNCTION
309  constexpr typename
310  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
311  dimension_scalar(const Kokkos::View<T, P...> /*view*/) {return 1;}
312 
313  template<typename T, typename ...P>
314  KOKKOS_FORCEINLINE_FUNCTION
315  static ordinal_type get_dimension_scalar(const Kokkos::DynRankView<T, P...> &view) {
316  return dimension_scalar(view);
317  }
318 
319  template<typename T, typename ...P>
320  KOKKOS_FORCEINLINE_FUNCTION
321  static ordinal_type get_dimension_scalar(const Kokkos::View<T, P...> &view) {
322  return dimension_scalar(view);
323  }
324 
333  template<class ViewType, class ... DimArgs>
334  inline
335  Kokkos::DynRankView<typename ViewType::value_type, typename DeduceLayout< ViewType >::result_layout, typename ViewType::device_type >
336  getMatchingViewWithLabel(const ViewType &view, const std::string &label, DimArgs... dims)
337  {
338  using ValueType = typename ViewType::value_type;
339  using ResultLayout = typename DeduceLayout< ViewType >::result_layout;
340  using DeviceType = typename ViewType::device_type;
341  using ViewTypeWithLayout = Kokkos::DynRankView<ValueType, ResultLayout, DeviceType >;
342 
343  const bool allocateFadStorage = !(std::is_standard_layout<ValueType>::value && std::is_trivial<ValueType>::value);
344  if (!allocateFadStorage)
345  {
346  return ViewTypeWithLayout(label,dims...);
347  }
348  else
349  {
350  const int derivative_dimension = get_dimension_scalar(view);
351  return ViewTypeWithLayout(label,dims...,derivative_dimension);
352  }
353  }
354 
355  using std::enable_if_t;
356 
360  template <typename T, typename = void>
361  struct has_rank_member : std::false_type{};
362 
366  template <typename T>
367  struct has_rank_member<T, decltype((void)T::rank, void())> : std::true_type {};
368 
369  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.");
370 #if KOKKOS_VERSION < 40099
371  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.");
372 #endif
373 
377  template<class Functor, ordinal_type default_value>
378  constexpr
379  enable_if_t<has_rank_member<Functor>::value, ordinal_type>
380  getFixedRank()
381  {
382  return Functor::rank;
383  }
384 
388  template<class Functor, ordinal_type default_value>
389  constexpr
390  enable_if_t<!has_rank_member<Functor>::value, ordinal_type>
391  getFixedRank()
392  {
393  return default_value;
394  }
395 
399  template <typename T>
401  {
402  typedef char one;
403  struct two { char x[2]; };
404 
405  template <typename C> static one test( typename std::remove_reference<decltype( std::declval<C>().operator()(0))>::type );
406  template <typename C> static two test(...);
407 
408  public:
409  enum { value = sizeof(test<T>(0)) == sizeof(char) && (getFixedRank<T,1>() == 1) };
410  };
411 
415  template <typename T>
417  {
418  typedef char one;
419  struct two { char x[2]; };
420 
421  template <typename C> static one test( typename std::remove_reference<decltype( std::declval<C>().operator()(0,0))>::type ) ;
422  template <typename C> static two test(...);
423 
424  public:
425  enum { value = sizeof(test<T>(0)) == sizeof(char) && (getFixedRank<T,2>() == 2) };
426  };
427 
431  template <typename T>
433  {
434  typedef char one;
435  struct two { char x[2]; };
436 
437  template <typename C> static one test( typename std::remove_reference<decltype( std::declval<C>().operator()(0,0,0))>::type ) ;
438  template <typename C> static two test(...);
439 
440  public:
441  enum { value = (sizeof(test<T>(0)) == sizeof(char)) && (getFixedRank<T,3>() == 3) };
442  };
443 
447  template <typename T>
449  {
450  typedef char one;
451  struct two { char x[2]; };
452 
453  template <typename C> static one test( typename std::remove_reference<decltype( std::declval<C>().operator()(0,0,0,0))>::type ) ;
454  template <typename C> static two test(...);
455 
456  public:
457  enum { value = sizeof(test<T>(0)) == sizeof(char) && (getFixedRank<T,4>() == 4) };
458  };
459 
463  template <typename T>
465  {
466  typedef char one;
467  struct two { char x[2]; };
468 
469  template <typename C> static one test( typename std::remove_reference<decltype( std::declval<C>().operator()(0,0,0,0,0))>::type ) ;
470  template <typename C> static two test(...);
471 
472  public:
473  enum { value = sizeof(test<T>(0)) == sizeof(char) && (getFixedRank<T,5>() == 5) };
474  };
475 
479  template <typename T>
481  {
482  typedef char one;
483  struct two { char x[2]; };
484 
485  template <typename C> static one test( typename std::remove_reference<decltype( std::declval<C>().operator()(0,0,0,0,0,0))>::type ) ;
486  template <typename C> static two test(...);
487 
488  public:
489  enum { value = sizeof(test<T>(0)) == sizeof(char) && (getFixedRank<T,6>() == 6) };
490  };
491 
495  template <typename T>
497  {
498  typedef char one;
499  struct two { char x[2]; };
500 
501  template <typename C> static one test( typename std::remove_reference<decltype( std::declval<C>().operator()(0,0,0,0,0,0,0))>::type ) ;
502  template <typename C> static two test(...);
503 
504  public:
505  enum { value = sizeof(test<T>(0)) == sizeof(char) && (getFixedRank<T,7>() == 7) };
506  };
507 
511  template <typename T, int rank>
513  {
514  public:
515  enum { value = false };
516  };
517 
521  template <typename T>
522  class supports_rank<T,1>
523  {
524  public:
525  enum { value = supports_rank_1<T>::value };
526  };
527 
529  template <typename T>
530  class supports_rank<T,2>
531  {
532  public:
533  enum { value = supports_rank_2<T>::value };
534  };
535 
537  template <typename T>
538  class supports_rank<T,3>
539  {
540  public:
541  enum { value = supports_rank_3<T>::value };
542  };
543 
545  template <typename T>
546  class supports_rank<T,4>
547  {
548  public:
549  enum { value = supports_rank_4<T>::value };
550  };
551 
553  template <typename T>
554  class supports_rank<T,5>
555  {
556  public:
557  enum { value = supports_rank_5<T>::value };
558  };
559 
561  template <typename T>
562  class supports_rank<T,6>
563  {
564  public:
565  enum { value = supports_rank_6<T>::value };
566  };
567 
569  template <typename T>
570  class supports_rank<T,7>
571  {
572  public:
573  enum { value = supports_rank_7<T>::value };
574  };
575 
576 
577 
581  template<typename Scalar, int rank>
582  struct RankExpander {
583 
584  };
585 
589  template<typename Scalar>
590  struct RankExpander<Scalar,0>
591  {
592  using value_type = Scalar;
593  };
594 
598  template<typename Scalar>
599  struct RankExpander<Scalar,1>
600  {
601  using value_type = Scalar*;
602  };
603 
607  template<typename Scalar>
608  struct RankExpander<Scalar,2>
609  {
610  using value_type = Scalar**;
611  };
612 
616  template<typename Scalar>
617  struct RankExpander<Scalar,3>
618  {
619  using value_type = Scalar***;
620  };
621 
625  template<typename Scalar>
626  struct RankExpander<Scalar,4>
627  {
628  using value_type = Scalar****;
629  };
630 
634  template<typename Scalar>
635  struct RankExpander<Scalar,5>
636  {
637  using value_type = Scalar*****;
638  };
639 
643  template<typename Scalar>
644  struct RankExpander<Scalar,6>
645  {
646  using value_type = Scalar******;
647  };
648 
652  template<typename Scalar>
653  struct RankExpander<Scalar,7>
654  {
655  using value_type = Scalar*******;
656  };
657 
658  // positive checks of supports_rank for Kokkos::DynRankView:
659  static_assert(supports_rank<Kokkos::DynRankView<double>, 1>::value, "rank 1 check of supports_rank for DynRankView");
660  static_assert(supports_rank<Kokkos::DynRankView<double>, 2>::value, "rank 2 check of supports_rank for DynRankView");
661  static_assert(supports_rank<Kokkos::DynRankView<double>, 3>::value, "rank 3 check of supports_rank for DynRankView");
662  static_assert(supports_rank<Kokkos::DynRankView<double>, 4>::value, "rank 4 check of supports_rank for DynRankView");
663  static_assert(supports_rank<Kokkos::DynRankView<double>, 5>::value, "rank 5 check of supports_rank for DynRankView");
664  static_assert(supports_rank<Kokkos::DynRankView<double>, 6>::value, "rank 6 check of supports_rank for DynRankView");
665  static_assert(supports_rank<Kokkos::DynRankView<double>, 7>::value, "rank 7 check of supports_rank for DynRankView");
666 
667  // positive checks of supports_rank for Kokkos::View:
668  static_assert(supports_rank<Kokkos::View<double*>, 1>::value, "rank 1 check of supports_rank");
669  static_assert(supports_rank<Kokkos::View<double**>, 2>::value, "rank 2 check of supports_rank");
670  static_assert(supports_rank<Kokkos::View<double***>, 3>::value, "rank 3 check of supports_rank");
671  static_assert(supports_rank<Kokkos::View<double****>, 4>::value, "rank 4 check of supports_rank");
672  static_assert(supports_rank<Kokkos::View<double*****>, 5>::value, "rank 5 check of supports_rank");
673  static_assert(supports_rank<Kokkos::View<double******>, 6>::value, "rank 6 check of supports_rank");
674  static_assert(supports_rank<Kokkos::View<double*******>, 7>::value, "rank 7 check of supports_rank");
675 
676  // negative checks of supports_rank for Kokkos::View:
677  static_assert(!supports_rank<Kokkos::View<double*>, 2>::value, "rank 1 check of supports_rank");
678  static_assert(!supports_rank<Kokkos::View<double*>, 3>::value, "rank 1 check of supports_rank");
679  static_assert(!supports_rank<Kokkos::View<double*>, 4>::value, "rank 1 check of supports_rank");
680  static_assert(!supports_rank<Kokkos::View<double*>, 5>::value, "rank 1 check of supports_rank");
681  static_assert(!supports_rank<Kokkos::View<double*>, 6>::value, "rank 1 check of supports_rank");
682  static_assert(!supports_rank<Kokkos::View<double*>, 7>::value, "rank 1 check of supports_rank");
683  static_assert(!supports_rank<Kokkos::View<double**>, 1>::value, "rank 2 check of supports_rank");
684  static_assert(!supports_rank<Kokkos::View<double**>, 3>::value, "rank 2 check of supports_rank");
685  static_assert(!supports_rank<Kokkos::View<double**>, 4>::value, "rank 2 check of supports_rank");
686  static_assert(!supports_rank<Kokkos::View<double**>, 5>::value, "rank 2 check of supports_rank");
687  static_assert(!supports_rank<Kokkos::View<double**>, 6>::value, "rank 2 check of supports_rank");
688  static_assert(!supports_rank<Kokkos::View<double**>, 7>::value, "rank 2 check of supports_rank");
689  static_assert(!supports_rank<Kokkos::View<double***>, 1>::value, "rank 3 check of supports_rank");
690  static_assert(!supports_rank<Kokkos::View<double***>, 2>::value, "rank 3 check of supports_rank");
691  static_assert(!supports_rank<Kokkos::View<double***>, 4>::value, "rank 3 check of supports_rank");
692  static_assert(!supports_rank<Kokkos::View<double***>, 5>::value, "rank 3 check of supports_rank");
693  static_assert(!supports_rank<Kokkos::View<double***>, 6>::value, "rank 3 check of supports_rank");
694  static_assert(!supports_rank<Kokkos::View<double***>, 7>::value, "rank 3 check of supports_rank");
695  static_assert(!supports_rank<Kokkos::View<double****>, 1>::value, "rank 4 check of supports_rank");
696  static_assert(!supports_rank<Kokkos::View<double****>, 2>::value, "rank 4 check of supports_rank");
697  static_assert(!supports_rank<Kokkos::View<double****>, 3>::value, "rank 4 check of supports_rank");
698  static_assert(!supports_rank<Kokkos::View<double****>, 5>::value, "rank 4 check of supports_rank");
699  static_assert(!supports_rank<Kokkos::View<double****>, 6>::value, "rank 4 check of supports_rank");
700  static_assert(!supports_rank<Kokkos::View<double****>, 7>::value, "rank 4 check of supports_rank");
701  static_assert(!supports_rank<Kokkos::View<double*****>, 1>::value, "rank 5 check of supports_rank");
702  static_assert(!supports_rank<Kokkos::View<double*****>, 2>::value, "rank 5 check of supports_rank");
703  static_assert(!supports_rank<Kokkos::View<double*****>, 3>::value, "rank 5 check of supports_rank");
704  static_assert(!supports_rank<Kokkos::View<double*****>, 4>::value, "rank 5 check of supports_rank");
705  static_assert(!supports_rank<Kokkos::View<double*****>, 6>::value, "rank 5 check of supports_rank");
706  static_assert(!supports_rank<Kokkos::View<double*****>, 7>::value, "rank 5 check of supports_rank");
707  static_assert(!supports_rank<Kokkos::View<double******>, 1>::value, "rank 6 check of supports_rank");
708  static_assert(!supports_rank<Kokkos::View<double******>, 2>::value, "rank 6 check of supports_rank");
709  static_assert(!supports_rank<Kokkos::View<double******>, 3>::value, "rank 6 check of supports_rank");
710  static_assert(!supports_rank<Kokkos::View<double******>, 4>::value, "rank 6 check of supports_rank");
711  static_assert(!supports_rank<Kokkos::View<double******>, 5>::value, "rank 6 check of supports_rank");
712  static_assert(!supports_rank<Kokkos::View<double******>, 7>::value, "rank 6 check of supports_rank");
713  static_assert(!supports_rank<Kokkos::View<double*******>, 1>::value, "rank 7 check of supports_rank");
714  static_assert(!supports_rank<Kokkos::View<double*******>, 2>::value, "rank 7 check of supports_rank");
715  static_assert(!supports_rank<Kokkos::View<double*******>, 3>::value, "rank 7 check of supports_rank");
716  static_assert(!supports_rank<Kokkos::View<double*******>, 4>::value, "rank 7 check of supports_rank");
717  static_assert(!supports_rank<Kokkos::View<double*******>, 5>::value, "rank 7 check of supports_rank");
718  static_assert(!supports_rank<Kokkos::View<double*******>, 6>::value, "rank 7 check of supports_rank");
719 
723  template <typename T>
725  {
726  typedef char one;
727  struct two { char x[2]; };
728 
729  template <typename C> static one test( decltype( std::declval<C>().rank() ) ) ;
730  template <typename C> static two test(...);
731 
732  public:
733  enum { value = sizeof(test<T>(0)) == sizeof(char) };
734  };
735 
736  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.");
737 #if KOKKOS_VERSION < 40099
738  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.");
739 #endif
740 
744  template<class Functor>
745  enable_if_t<has_rank_method<Functor>::value, unsigned>
746  KOKKOS_INLINE_FUNCTION
747  getFunctorRank(const Functor &functor)
748  {
749  return functor.rank();
750  }
751 
755  template<class Functor>
756  enable_if_t<!has_rank_method<Functor>::value, unsigned>
757  KOKKOS_INLINE_FUNCTION
758  getFunctorRank(const Functor &functor)
759  {
760  return functor.rank;
761  }
762 
766 #if defined(HAVE_INTREPID2_SACADO) && !defined(SACADO_HAS_NEW_KOKKOS_VIEW_IMPL)
767  template <typename ValueType>
768  struct NaturalLayoutForType {
769  using layout =
770  typename std::conditional<(std::is_standard_layout<ValueType>::value && std::is_trivial<ValueType>::value),
771  Kokkos::LayoutLeft, // for POD types, use LayoutLeft
772  Kokkos::LayoutNatural<Kokkos::LayoutLeft> >::type; // For FAD types, use LayoutNatural
773  };
774 #else
775  template <typename ValueType>
777  using layout = Kokkos::LayoutLeft;
778  };
779 #endif
780 
781  // define vector sizes for hierarchical parallelism
782  const int VECTOR_SIZE = 1;
783 #if defined(SACADO_VIEW_CUDA_HIERARCHICAL_DFAD) && defined(INTREPID2_ENABLE_DEVICE)
784  const int FAD_VECTOR_SIZE = 32;
785 #else
786  const int FAD_VECTOR_SIZE = 1;
787 #endif
788 
792  template<typename Scalar>
793  constexpr int getVectorSizeForHierarchicalParallelism()
794  {
795  return (std::is_standard_layout<Scalar>::value && std::is_trivial<Scalar>::value) ? VECTOR_SIZE : FAD_VECTOR_SIZE;
796  }
797 
803  template<typename ViewType>
804  KOKKOS_INLINE_FUNCTION
805  constexpr unsigned getScalarDimensionForView(const ViewType &view)
806  {
807  return (std::is_standard_layout<typename ViewType::value_type>::value && std::is_trivial<typename ViewType::value_type>::value) ? 0 : get_dimension_scalar(view);
808  }
809 
811  template<typename Device>
812  struct DeviceDeleter {
813  template<typename T>
814  void operator()(T* ptr) {
815  Kokkos::parallel_for(Kokkos::RangePolicy<typename Device::execution_space>(0,1),
816  KOKKOS_LAMBDA (const int i) { ptr->~T(); });
817  typename Device::execution_space().fence();
818  Kokkos::kokkos_free<typename Device::memory_space>(ptr);
819  }
820  };
821 
825  template<typename Device,typename Derived>
826  std::unique_ptr<Derived,DeviceDeleter<Device>>
827  copy_virtual_class_to_device(const Derived& host_source)
828  {
829  auto* p = static_cast<Derived*>(Kokkos::kokkos_malloc<typename Device::memory_space>(sizeof(Derived)));
830  Kokkos::parallel_for(Kokkos::RangePolicy<typename Device::execution_space>(0,1),
831  KOKKOS_LAMBDA (const int i) {new (p) Derived(host_source); });
832  typename Device::execution_space().fence();
833  return std::unique_ptr<Derived,DeviceDeleter<Device>>(p);
834  }
835 } // end namespace Intrepid2
836 
837 #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)