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>
387  constexpr int getVectorSizeForHierarchicalParallelism()
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
scalar type traits
Contains definitions of custom data types in Intrepid2.
Define layout that will allow us to wrap Sacado Scalar objects in Views without copying.
layout deduction (temporary meta-function)