omega_h
Reliable mesh adaptation
Omega_h_few.hpp
1 #ifndef OMEGA_H_FEW_HPP
2 #define OMEGA_H_FEW_HPP
3 
4 #include <initializer_list>
5 #include <new>
6 #include <type_traits>
7 
8 #include <Omega_h_defines.hpp>
9 #include <Omega_h_scalar.hpp>
10 
11 namespace Omega_h {
12 
13 #ifdef OMEGA_H_USE_KOKKOS
14 
15 template <typename T, Int n>
16 class Few {
17  T array_[n];
18 
19  public:
20  using value_type = T;
21  OMEGA_H_INLINE T* data() { return array_; }
22  OMEGA_H_INLINE T const* data() const { return array_; }
23  OMEGA_H_INLINE constexpr Int size() const { return n; }
24 #ifdef OMEGA_H_CHECK_BOUNDS
25 #define OMEGA_H_FEW_AT \
26  OMEGA_H_CHECK(0 <= i); \
27  OMEGA_H_CHECK(i < size()); \
28  return array_[i]
29 #else
30 #define OMEGA_H_FEW_AT return array_[i]
31 #endif
32  OMEGA_H_INLINE T& operator[](Int i) { OMEGA_H_FEW_AT; }
33  OMEGA_H_INLINE T const& operator[](Int i) const { OMEGA_H_FEW_AT; }
34  OMEGA_H_INLINE T& operator()(Int i) { OMEGA_H_FEW_AT; }
35  OMEGA_H_INLINE T const& operator()(Int i) const { OMEGA_H_FEW_AT; }
36 #undef OMEGA_H_FEW_AT
37  OMEGA_H_INLINE
38  Few(std::initializer_list<T> l) {
39  Int i = 0;
40  for (auto it = l.begin(); it != l.end(); ++it) {
41  new (array_ + (i++)) T(*it);
42  }
43  }
44  OMEGA_H_INLINE Few() {}
45  OMEGA_H_INLINE ~Few() {}
46  OMEGA_H_INLINE void operator=(Few<T, n> const& rhs) {
47  for (Int i = 0; i < n; ++i) array_[i] = rhs[i];
48  }
49  OMEGA_H_INLINE Few(Few<T, n> const& rhs) {
50  for (Int i = 0; i < n; ++i) new (array_ + i) T(rhs[i]);
51  }
52  OMEGA_H_INLINE const T* begin() const OMEGA_H_NOEXCEPT { return array_; }
53  OMEGA_H_INLINE const T* end() const OMEGA_H_NOEXCEPT { return array_ + size(); }
54  OMEGA_H_INLINE T* begin() OMEGA_H_NOEXCEPT { return array_; }
55  OMEGA_H_INLINE T* end() OMEGA_H_NOEXCEPT { return array_ + size(); }
56 };
57 
58 #else
59 
60 template <typename T, Int n>
61 class Few {
62  T array_[n];
63 
64  public:
65  using value_type = T;
66  OMEGA_H_INLINE T* data() OMEGA_H_NOEXCEPT { return array_; }
67  OMEGA_H_INLINE T const* data() const OMEGA_H_NOEXCEPT { return array_; }
68  OMEGA_H_INLINE constexpr Int size() const { return n; }
69 #ifdef OMEGA_H_CHECK_BOUNDS
70 #define OMEGA_H_FEW_AT \
71  OMEGA_H_CHECK(0 <= i); \
72  OMEGA_H_CHECK(i < size()); \
73  return array_[i]
74 #else
75 #define OMEGA_H_FEW_AT return array_[i]
76 #endif
77  OMEGA_H_INLINE T& operator[](Int i) OMEGA_H_NOEXCEPT { OMEGA_H_FEW_AT; }
78  OMEGA_H_INLINE T const& operator[](Int i) const OMEGA_H_NOEXCEPT {
79  OMEGA_H_FEW_AT;
80  }
81  OMEGA_H_INLINE T& operator()(Int i) OMEGA_H_NOEXCEPT { OMEGA_H_FEW_AT; }
82  OMEGA_H_INLINE T const& operator()(Int i) const OMEGA_H_NOEXCEPT {
83  OMEGA_H_FEW_AT;
84  }
85 #undef OMEGA_H_FEW_AT
86  OMEGA_H_INLINE
87  Few(std::initializer_list<T> l) {
88  Int i = 0;
89  for (auto it = l.begin(); it != l.end(); ++it) {
90  new (array_ + (i++)) T(*it);
91  }
92  }
93  inline Few() = default;
94  inline ~Few() = default;
95  inline Few(Few<T, n> const& rhs) = default;
96  inline Few(Few<T, n>&& rhs) = default;
97  inline Few& operator=(Few const& rhs) = default;
98  inline Few& operator=(Few&& rhs) = default;
99  OMEGA_H_INLINE const T* begin() const OMEGA_H_NOEXCEPT { return array_; }
100  OMEGA_H_INLINE const T* end() const OMEGA_H_NOEXCEPT { return array_ + size(); }
101  OMEGA_H_INLINE T* begin() OMEGA_H_NOEXCEPT { return array_; }
102  OMEGA_H_INLINE T* end() OMEGA_H_NOEXCEPT { return array_ + size(); }
103 };
104 
105 #endif
106 
107 template <Int capacity, typename T>
108 OMEGA_H_INLINE void add_unique(
109  Few<T, capacity>& stack, Int& n, T e) OMEGA_H_NOEXCEPT {
110  for (Int i = 0; i < n; ++i)
111  if (stack[i] == e) return;
112  stack[n++] = e;
113 }
114 
115 template <Int n, typename T>
116 OMEGA_H_INLINE T average(Few<T, n> x) OMEGA_H_NOEXCEPT {
117  auto avg = x[0];
118  for (Int i = 1; i < n; ++i) avg = avg + x[i];
119  return avg / n;
120 }
121 
122 template <Int n, typename T, typename Op>
123 OMEGA_H_INLINE T reduce(Few<T, n> x, Op op) OMEGA_H_NOEXCEPT {
124  auto out = x[0];
125  decltype(op) tmp_op; // workaround icpx
126  for (Int i = 1; i < n; ++i) out = tmp_op(out, x[i]);
127  return out;
128 }
129 
130 #if !(defined(KOKKOS_ENABLE_CUDA) && defined(__clang__))
131 template <Int n, typename T>
132 OMEGA_H_INLINE decltype(std::declval<T>() * std::declval<T>()) inner_product(
133  Few<T, n> a, Few<T, n> b) OMEGA_H_NOEXCEPT {
134  auto out = a[0] * b[0];
135  for (Int i = 1; i < n; ++i) out = out + (a[i] * b[i]);
136  return out;
137 }
138 #else
139 template <Int n, typename T>
140 OMEGA_H_INLINE decltype(T() * T()) inner_product(
141  Few<T, n> a, Few<T, n> b) OMEGA_H_NOEXCEPT {
142  auto out = a[0] * b[0];
143  for (Int i = 1; i < n; ++i) out = out + (a[i] * b[i]);
144  return out;
145 }
146 #endif
147 
148 } // namespace Omega_h
149 
150 #endif
Definition: Omega_h_few.hpp:61
Definition: amr_mpi_test.cpp:6