Intrepid2
Intrepid2_Utils.hpp
Go to the documentation of this file.
1 // @HEADER
2 // ************************************************************************
3 //
4 // Intrepid2 Package
5 // Copyright (2007) Sandia Corporation
6 //
7 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8 // license for use of this work by or on behalf of the U.S. Government.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Kyungjoo Kim (kyukim@sandia.gov), or
38 // Mauro Perego (mperego@sandia.gov)
39 //
40 // ************************************************************************
41 // @HEADER
42 
49 #ifndef __INTREPID2_UTILS_HPP__
50 #define __INTREPID2_UTILS_HPP__
51 
52 #include "Intrepid2_ConfigDefs.hpp"
53 #include "Intrepid2_Types.hpp"
54 
55 #include "Kokkos_Core.hpp"
56 #include "Kokkos_Macros.hpp" // provides some preprocessor values used in definitions of INTREPID2_DEPRECATED, etc.
57 
58 #ifdef HAVE_INTREPID2_SACADO
59 #include "Kokkos_LayoutNatural.hpp"
60 #endif
61 
62 namespace Intrepid2 {
63 
64 #if defined(KOKKOS_OPT_RANGE_AGGRESSIVE_VECTORIZATION) && defined(KOKKOS_ENABLE_PRAGMA_IVDEP) && !defined(__CUDA_ARCH__)
65 #define INTREPID2_USE_IVDEP
66 #endif
67 
68  //
69  // test macros
70  //
71 
72 #define INTREPID2_TEST_FOR_WARNING(test, msg) \
73  if (test) { \
74  printf("[Intrepid2] Warning in file %s, line %d\n",__FILE__,__LINE__); \
75  printf(" Test that evaluated to true: %s\n", #test); \
76  printf(" %s \n", msg); \
77  }
78 
79 #define INTREPID2_TEST_FOR_EXCEPTION(test, x, msg) \
80  if (test) { \
81  printf("[Intrepid2] Error in file %s, line %d\n",__FILE__,__LINE__); \
82  printf(" Test that evaluated to true: %s\n", #test); \
83  printf(" %s \n", msg); \
84  throw x(msg); \
85  }
86 
87 #ifndef KOKKOS_ENABLE_CUDA
88 #define INTREPID2_TEST_FOR_EXCEPTION_DEVICE_SAFE(test, x, msg) \
89  if (test) { \
90  printf("[Intrepid2] Error in file %s, line %d\n",__FILE__,__LINE__); \
91  printf(" Test that evaluated to true: %s\n", #test); \
92  printf(" %s \n", msg); \
93  throw x(msg); \
94  }
95 #else
96  #define INTREPID2_TEST_FOR_EXCEPTION_DEVICE_SAFE(test, x, msg) device_assert(!test);
97 #endif
98 
99 #define INTREPID2_TEST_FOR_ABORT(test, msg) \
100  if (test) { \
101  printf("[Intrepid2] Error in file %s, line %d\n",__FILE__,__LINE__); \
102  printf(" Test that evaluated to true: %s\n", #test); \
103  printf(" %s \n", msg); \
104  Kokkos::abort( "[Intrepid2] Abort\n"); \
105  }
106 
107  // check the first error only
108 #ifdef INTREPID2_TEST_FOR_DEBUG_ABORT_OVERRIDE_TO_CONTINUE
109 #define INTREPID2_TEST_FOR_DEBUG_ABORT(test, info, msg) \
110  if (!(info) && (test)) { \
111  printf("[Intrepid2] Error in file %s, line %d\n",__FILE__,__LINE__); \
112  printf(" Test that evaluated to true: %s\n", #test); \
113  printf(" %s \n", msg); \
114  info = true; \
115  }
116 #else
117 #define INTREPID2_TEST_FOR_DEBUG_ABORT(test, info, msg) \
118  if (!(info) && (test)) { \
119  printf("[Intrepid2] Error in file %s, line %d\n",__FILE__,__LINE__); \
120  printf(" Test that evaluated to true: %s\n", #test); \
121  printf(" %s \n", msg); \
122  info = true ; \
123  Kokkos::abort( "[Intrepid2] Abort\n"); \
124  }
125 #endif
126 
130  template<typename T>
131  struct ScalarTraits {
132  typedef typename T::scalar_type scalar_type;
133  };
134 
135  // this is built in types to support
139  template<>
140  struct ScalarTraits<float> {
141  typedef float scalar_type;
142  };
146  template<>
147  struct ScalarTraits<double> {
148  typedef double scalar_type;
149  };
153  template<>
154  struct ScalarTraits<int> {
155  typedef int scalar_type;
156  };
160  template<>
161  struct ScalarTraits<long int> {
162  typedef long int scalar_type;
163  };
167  template<>
168  struct ScalarTraits<long long> {
169  typedef long long scalar_type;
170  };
171 
172 
173 
177  template<typename ViewSpaceType, typename UserSpaceType>
178  struct ExecSpace {
179  typedef UserSpaceType ExecSpaceType;
180  };
181 
185  template<typename ViewSpaceType>
186  struct ExecSpace<ViewSpaceType,void> {
187  typedef ViewSpaceType ExecSpaceType;
188  };
189 
190 
194  template <typename ViewType>
195  struct DeduceLayout {
196  using input_layout = typename ViewType::array_layout;
197  using default_layout = typename ViewType::device_type::execution_space::array_layout;
198  using result_layout =
199  typename std::conditional<
200  std::is_same< input_layout, Kokkos::LayoutStride >::value,
201  default_layout,
202  input_layout >::type;
203  };
204 
205 
206  //
207  // utilities device comparible
208  //
209 
210  // this will be gone
211  template<typename IdxType, typename DimType, typename IterType>
212  KOKKOS_FORCEINLINE_FUNCTION
213  static void
214  unrollIndex(IdxType &i, IdxType &j,
215  const DimType /* dim0 */,
216  const DimType dim1,
217  const IterType iter) {
218  // left index
219  //j = iter/dim0;
220  //i = iter%dim0;
221 
222  // right index
223  i = iter/dim1;
224  j = iter%dim1;
225  }
226 
227  template<typename IdxType, typename DimType, typename IterType>
228  KOKKOS_FORCEINLINE_FUNCTION
229  static void
230  unrollIndex(IdxType &i, IdxType &j, IdxType &k,
231  const DimType dim0,
232  const DimType dim1,
233  const DimType dim2,
234  const IterType iter) {
235  IdxType tmp;
236 
237  //unrollIndex(tmp, k, dim0*dim1, dim2, iter);
238  //unrollIndex( i, j, dim0, dim1, tmp);
239 
240  unrollIndex( i, tmp, dim0, dim1*dim2, iter);
241  unrollIndex( j, k, dim1, dim2, tmp);
242  }
243 
247  template<typename T>
248  class Util {
249  public:
250  KOKKOS_FORCEINLINE_FUNCTION
251  static T min(const T a, const T b) {
252  return (a < b ? a : b);
253  }
254 
255  KOKKOS_FORCEINLINE_FUNCTION
256  static T max(const T a, const T b) {
257  return (a > b ? a : b);
258  }
259 
260  KOKKOS_FORCEINLINE_FUNCTION
261  static T abs(const T a) {
262  return (a > 0 ? a : T(-a));
263  }
264 
265  };
266 
267  template<typename T>
268  KOKKOS_FORCEINLINE_FUNCTION
269  static T min(const T &a, const T &b) {
270  return (a < b ? a : b);
271  }
272 
273  template<typename T>
274  KOKKOS_FORCEINLINE_FUNCTION
275  static T max(const T &a, const T &b) {
276  return (a > b ? a : b);
277  }
278 
279  template<typename T>
280  KOKKOS_FORCEINLINE_FUNCTION
281  static T abs(const T &a) {
282  return (a > 0 ? a : T(-a));
283  }
284 
292  template<typename T>
293  KOKKOS_FORCEINLINE_FUNCTION
294  constexpr typename
295  std::enable_if< !std::is_pod<T>::value, typename ScalarTraits<T>::scalar_type >::type
296  get_scalar_value(const T& obj) {return obj.val();}
297 
298  template<typename T>
299  KOKKOS_FORCEINLINE_FUNCTION
300  constexpr typename
301  std::enable_if< std::is_pod<T>::value, typename ScalarTraits<T>::scalar_type >::type
302  get_scalar_value(const T& obj){return obj;}
303 
304 
311  template<typename T, typename ...P>
312  KOKKOS_INLINE_FUNCTION
313  constexpr typename
314  std::enable_if< std::is_pod<T>::value, unsigned >::type
315  dimension_scalar(const Kokkos::DynRankView<T, P...> /* view */) {return 1;}
316 
317  template<typename T, typename ...P>
318  KOKKOS_INLINE_FUNCTION
319  constexpr typename
320  std::enable_if< std::is_pod<T>::value, unsigned >::type
321  dimension_scalar(const Kokkos::View<T, P...> view) {return 1;}
322 
323  template<typename T>
324  KOKKOS_FORCEINLINE_FUNCTION
325  static ordinal_type get_dimension_scalar(const T view) {
326  return dimension_scalar(view);
327  }
328 
337  template<class ViewType, class ... DimArgs>
338  inline ViewType getMatchingViewWithLabel(ViewType &view, const std::string &label, DimArgs... dims)
339  {
340  using ValueType = typename ViewType::value_type;
341  using ResultLayout = typename DeduceLayout< ViewType >::result_layout;
342  using DeviceType = typename ViewType::device_type;
343  using ViewTypeWithLayout = Kokkos::DynRankView<ValueType, ResultLayout, DeviceType >;
344 
345  const bool allocateFadStorage = !std::is_pod<ValueType>::value;
346  if (!allocateFadStorage)
347  {
348  return ViewTypeWithLayout(label,dims...);
349  }
350  else
351  {
352  const int derivative_dimension = get_dimension_scalar(view);
353  return ViewTypeWithLayout(label,dims...,derivative_dimension);
354  }
355  }
356 
360 #ifdef HAVE_INTREPID2_SACADO
361  template <typename ValueType>
362  struct NaturalLayoutForType {
363  using layout =
364  typename std::conditional<std::is_pod<ValueType>::value,
365  Kokkos::LayoutLeft, // for POD types, use LayoutLeft
366  Kokkos::LayoutNatural<Kokkos::LayoutLeft> >::type; // For FAD types, use LayoutNatural
367  };
368 #else
369  template <typename ValueType>
371  using layout = Kokkos::LayoutLeft;
372  };
373 #endif
374 
375  // define vector sizes for hierarchical parallelism
376  const int VECTOR_SIZE = 1;
377 #if defined(SACADO_VIEW_CUDA_HIERARCHICAL_DFAD) && defined(KOKKOS_ENABLE_CUDA)
378  const int FAD_VECTOR_SIZE = 32;
379 #else
380  const int FAD_VECTOR_SIZE = 1;
381 #endif
382 
386  template<typename Scalar>
388  {
389  return std::is_pod<Scalar>::value ? VECTOR_SIZE : FAD_VECTOR_SIZE;
390  }
391 
397  template<typename ViewType>
398  KOKKOS_INLINE_FUNCTION
399  constexpr unsigned getScalarDimensionForView(const ViewType &view)
400  {
401  return (std::is_pod<typename ViewType::value_type>::value) ? 0 : get_dimension_scalar(view);
402  }
403 } // end namespace Intrepid2
404 
405 #endif
small utility functions
constexpr int getVectorSizeForHierarchicalParallelism()
Returns a vector size to be used for the provided Scalar type in the context of hierarchically-parall...
ViewType getMatchingViewWithLabel(ViewType &view, const std::string &label, DimArgs... dims)
Creates and returns a view that matches the provided view in Kokkos Layout.
scalar type traits
KOKKOS_INLINE_FUNCTION constexpr std::enable_if< std::is_pod< 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...
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. This method is useful for sizing scratch storage in hierarchically parallel kernels. Whereas get_dimension_scalar() returns 1 for POD types, this returns 0 for POD types.
Contains definitions of custom data types in Intrepid2.
Define layout that will allow us to wrap Sacado Scalar objects in Views without copying.
KOKKOS_FORCEINLINE_FUNCTION constexpr std::enable_if< !std::is_pod< T >::value, typename ScalarTraits< T >::scalar_type >::type get_scalar_value(const T &obj)
functions returning the scalar value. for pod types, they return the input object itself...
layout deduction (temporary meta-function)