DASH  0.3.0
Stencil.h
1 #ifndef DASH__HALO_STENCIL_H
2 #define DASH__HALO_STENCIL_H
3 
4 #include <dash/halo/Types.h>
5 
6 #include <dash/Dimensional.h>
7 
8 namespace dash {
9 
10 namespace halo {
11 
12 using namespace internal;
13 
18 template <dim_t NumDimensions, typename CoeffT = double>
19 class StencilPoint : public Dimensional<spoint_value_t, NumDimensions> {
20 public:
21  using coefficient_t = CoeffT;
22 
23 private:
25 
26 public:
27  // TODO constexpr
34  for(dim_t d = 0; d < NumDimensions; ++d) {
35  this->_values[d] = 0;
36  }
37  }
38 
45  template <typename... Values>
46  constexpr StencilPoint(
47  typename std::enable_if<sizeof...(Values) == NumDimensions - 1,
48  spoint_value_t>::type value,
49  Values... values)
50  : Base_t::Dimensional(value, (spoint_value_t) values...) {}
51 
57  template <typename... Values>
58  constexpr StencilPoint(
59  typename std::enable_if<sizeof...(Values) == NumDimensions - 1,
60  CoeffT>::type coefficient,
61  spoint_value_t value, Values... values)
62  : Base_t::Dimensional(value, (spoint_value_t) values...),
63  _coefficient(coefficient) {}
64 
65  // TODO as constexpr
69  int max() const {
70  int max = 0;
71  for(dim_t d = 0; d < NumDimensions; ++d)
72  max = std::max(max, (int) std::abs(this->_values[d]));
73  return max;
74  }
75 
79  template <typename ElementCoordsT>
80  ElementCoordsT stencil_coords(ElementCoordsT& coords) const {
82  }
83 
87  template <typename ElementCoordsT>
88  static ElementCoordsT stencil_coords(
89  ElementCoordsT coords,
90  const StencilPoint<NumDimensions, CoeffT>& stencilp) {
91  for(dim_t d = 0; d < NumDimensions; ++d) {
92  coords[d] += stencilp[d];
93  }
94 
95  return coords;
96  }
97 
103  template <typename ElementCoordsT, typename ViewSpecT>
104  std::pair<ElementCoordsT, bool> stencil_coords_check(
105  ElementCoordsT coords, const ViewSpecT& view) const {
106  bool halo = false;
107  for(dim_t d = 0; d < NumDimensions; ++d) {
108  coords[d] += this->_values[d];
109  if(coords[d] < view.offset(d) || coords[d] >= view.offset(d) + view.extent(d))
110  halo = true;
111  }
112 
113  return std::make_pair(coords, halo);
114  }
115 
124  template <typename ElementCoordsT, typename ViewSpecT>
125  std::pair<ElementCoordsT, bool> stencil_coords_check_abort(
126  ElementCoordsT coords, const ViewSpecT& view) const {
127  for(dim_t d = 0; d < NumDimensions; ++d) {
128  coords[d] += this->_values[d];
129  if(coords[d] < view.offset(d) || coords[d] >= view.offset(d) + view.extent(d))
130  return std::make_pair(coords, true);
131  }
132 
133  return std::make_pair(coords, false);
134  }
135 
139  CoeffT coefficient() const { return _coefficient; }
140 
141 private:
142  CoeffT _coefficient = 1.0;
143 }; // StencilPoint
144 
145 template <dim_t NumDimensions, typename CoeffT>
146 std::ostream& operator<<(
147  std::ostream& os, const StencilPoint<NumDimensions, CoeffT>& stencil_point) {
148  os << "dash::halo::StencilPoint<" << NumDimensions << ">"
149  << "(coefficient = " << stencil_point.coefficient() << " - points: ";
150  for(auto d = 0; d < NumDimensions; ++d) {
151  if(d > 0) {
152  os << ",";
153  }
154  os << stencil_point[d];
155  }
156  os << ")";
157 
158  return os;
159 }
160 
166 template <typename StencilPointT, std::size_t NumStencilPoints>
167 class StencilSpec {
168 private:
170  static constexpr auto NumDimensions = StencilPointT::ndim();
171 
172 public:
173  using stencil_size_t = std::size_t;
174  using stencil_index_t = std::size_t;
175  using StencilArray_t = std::array<StencilPointT, NumStencilPoints>;
176  using StencilPoint_t = StencilPointT;
177  using DistanceDim_t = std::pair<spoint_value_t, spoint_value_t>;
178  using DistanceAll_t = std::array<DistanceDim_t, NumDimensions>;
179  using DistanceTotal_t = std::array<spoint_distance_t, NumDimensions>;
180 
181 public:
187  constexpr StencilSpec(const StencilArray_t& specs) : _specs(specs) {}
188 
195  template <typename... Values>
196  constexpr StencilSpec(const StencilPointT& value, const Values&... values)
197  : _specs{ { value, (StencilPointT) values... } } {
198  static_assert(sizeof...(values) == NumStencilPoints - 1,
199  "Invalid number of stencil point arguments");
200  }
201 
202  // TODO constexpr
206  StencilSpec(const Self_t& other) { _specs = other._specs; }
207 
211  constexpr const StencilArray_t& specs() const { return _specs; }
212 
216  static constexpr stencil_size_t num_stencil_points() {
217  return NumStencilPoints;
218  }
219 
228  const std::pair<stencil_index_t, bool> index(StencilPointT stencil) const {
229  for(auto i = 0; i < _specs.size(); ++i) {
230  if(_specs[i] == stencil)
231  return std::make_pair(i, true);
232  }
233 
234  return std::make_pair(0, false);
235  }
236 
242  DistanceTotal_t total_distances() const {
243  DistanceTotal_t total_dist{};
244  auto minmax = minmax_distances();
245  for(auto d = 0; d < NumDimensions; ++d) {
246  total_dist[d] = (-1) * minmax.first() + minmax.second;
247  }
248 
249  return total_dist;
250  }
251 
257  spoint_distance_t total_distances(dim_t dim) const {
258  auto minmax = minmax_distances();
259 
260  return (-1) * minmax.first() + minmax.second;
261  }
262 
267  DistanceAll_t minmax_distances() const {
268  DistanceAll_t max_dist{};
269  for(const auto& stencil_point : _specs) {
270  for(auto d = 0; d < NumDimensions; ++d) {
271  if(stencil_point[d] < max_dist[d].first) {
272  max_dist[d].first = stencil_point[d];
273  continue;
274  }
275  if(stencil_point[d] > max_dist[d].second)
276  max_dist[d].second = stencil_point[d];
277  }
278  }
279 
280  return max_dist;
281  }
282 
287  DistanceDim_t minmax_distances(dim_t dim) const {
288  DistanceDim_t max_dist{};
289  for(const auto& stencil_point : _specs) {
290  if(stencil_point[dim] < max_dist.first) {
291  max_dist.first = stencil_point[dim];
292  continue;
293  }
294  if(stencil_point[dim] > max_dist.second)
295  max_dist.second = stencil_point[dim];
296  }
297 
298  return max_dist;
299  }
303  constexpr const StencilPointT& operator[](stencil_index_t index) const {
304  return _specs[index];
305  }
306 
307 private:
308  StencilArray_t _specs{};
309 }; // StencilSpec
310 
311 template <typename StencilPointT, std::size_t NumStencilPoints>
312 std::ostream& operator<<(
313  std::ostream& os, const StencilSpec<StencilPointT, NumStencilPoints>& specs) {
314  os << "dash::halo::StencilSpec<" << NumStencilPoints << ">"
315  << "(";
316  for(auto i = 0; i < NumStencilPoints; ++i) {
317  if(i > 0) {
318  os << ",";
319  }
320  os << specs[i];
321  }
322  os << ")";
323 
324  return os;
325 }
326 
327 template <typename StencilPointT>
329 private:
330  using stencil_dist_t = spoint_value_t;
331  using StencilPerm_t = std::vector<StencilPointT>;
332 
333  static constexpr auto NumDimensions = StencilPointT::ndim();
334 
335 public:
336 
337  static constexpr decltype(auto) full_stencil_spec(stencil_dist_t dist) {
339 
340  using StencilArray_t = typename StencilSpec_t::StencilArray_t;
341 
342  StencilPerm_t stencil_perms;
343  StencilArray_t points;
344  StencilPointT start_stencil;
345  for(dim_t d = 0; d < NumDimensions; ++d) {
346  start_stencil[d] = std::abs(dist);
347  }
348  permutate_stencil_points(0, start_stencil, stencil_perms, dist);
349 
350  size_t count = 0;
351  for(const auto& elem : stencil_perms) {
352  bool center = true;
353  for(dim_t d = 0; d < NumDimensions; ++d) {
354  if(elem[d] != 0 ) {
355  center = false;
356  break;
357  }
358  }
359  if(!center) {
360  points[count] = elem;
361  ++count;
362  }
363  }
364 
365  return StencilSpec_t(points);
366  }
367 
368 private:
369  static void permutate_stencil_points(dim_t dim_change, const StencilPointT& current_stencil, StencilPerm_t& perm_stencil, stencil_dist_t dist) {
370  perm_stencil.push_back(current_stencil);
371 
372  for(dim_t d = dim_change; d < NumDimensions; ++d) {
373  if(current_stencil[d] != 0) {
374  auto new_stencil = current_stencil;
375  new_stencil[d] = 0;
376  permutate_stencil_points(d+1, new_stencil, perm_stencil, dist);
377  new_stencil[d] = -dist;
378  permutate_stencil_points(d+1, new_stencil, perm_stencil, dist);
379  }
380  }
381  }
382 
383 };
384 
385 } // namespace halo
386 
387 } // namespace dash
388 
389 #endif // DASH__HALO_STENCIL_H
spoint_distance_t total_distances(dim_t dim) const
Returns the total distances of all stencil points for all dimensions.
Definition: Stencil.h:257
Returns second operand.
Definition: Operation.h:218
constexpr std::enable_if< std::is_integral< IndexType >::value, IndexType >::type index(IndexType idx)
Definition: Iterator.h:60
StencilSpec(const Self_t &other)
Copy Constructor.
Definition: Stencil.h:206
This class is a simple memory pool which holds allocates elements of size ValueType.
Definition: AllOf.h:8
int dim_t
Scalar type for a dimension value, with 0 indicating the first dimension.
Definition: Types.h:39
constexpr const StencilArray_t & specs() const
Definition: Stencil.h:211
Returns second operand.
Definition: Operation.h:201
StencilPoint()
Default Contructor.
Definition: Stencil.h:33
Reduce operands to their maximum value.
Definition: Operation.h:144
DistanceDim_t minmax_distances(dim_t dim) const
Returns the minimal and maximal distances of all stencil points for the given dimension.
Definition: Stencil.h:287
Stencil point with raletive coordinates for N dimensions e.g.
Definition: Stencil.h:19
static ElementCoordsT stencil_coords(ElementCoordsT coords, const StencilPoint< NumDimensions, CoeffT > &stencilp)
Returns coordinates adjusted by a given stencil point.
Definition: Stencil.h:88
static constexpr stencil_size_t num_stencil_points()
Definition: Stencil.h:216
constexpr const StencilPointT & operator[](stencil_index_t index) const
Definition: Stencil.h:303
ElementCoordsT stencil_coords(ElementCoordsT &coords) const
Returns coordinates adjusted by stencil point.
Definition: Stencil.h:80
CoeffT coefficient() const
Returns the coefficient for this stencil point.
Definition: Stencil.h:139
int max() const
Returns maximum distance to center over all dimensions.
Definition: Stencil.h:69
Base class for dimensional attributes, stores an n-dimensional value with identical type all dimensio...
Definition: Dimensional.h:101
constexpr dim_t ndim(const DimensionalType &d)
Definition: Dimensional.h:56
DistanceAll_t minmax_distances() const
Returns the minimal and maximal distances of all stencil points for all dimensions.
Definition: Stencil.h:267
const std::pair< stencil_index_t, bool > index(StencilPointT stencil) const
Returns the stencil point index for a given StencilPoint.
Definition: Stencil.h:228
constexpr StencilSpec(const StencilPointT &value, const Values &... values)
Constructor.
Definition: Stencil.h:196
std::pair< ElementCoordsT, bool > stencil_coords_check_abort(ElementCoordsT coords, const ViewSpecT &view) const
Returns coordinates adjusted by a stencil point and a boolean to indicate a if the adjusted coordinat...
Definition: Stencil.h:125
A collection of stencil points (Stencil) e.g.
Definition: Stencil.h:167
std::pair< ElementCoordsT, bool > stencil_coords_check(ElementCoordsT coords, const ViewSpecT &view) const
Returns coordinates adjusted by a stencil point and a boolean to indicate a if the adjusted coordinat...
Definition: Stencil.h:104
Definition: main.cpp:123
constexpr StencilPoint(typename std::enable_if< sizeof...(Values)==NumDimensions - 1, CoeffT >::type coefficient, spoint_value_t value, Values... values)
Constructor.
Definition: Stencil.h:58
constexpr StencilPoint(typename std::enable_if< sizeof...(Values)==NumDimensions - 1, spoint_value_t >::type value, Values... values)
Constructor.
Definition: Stencil.h:46
constexpr StencilSpec(const StencilArray_t &specs)
Constructor.
Definition: Stencil.h:187
DistanceTotal_t total_distances() const
Returns the total distances of all stencil points for all dimensions.
Definition: Stencil.h:242