DASH  0.3.0
Region.h
1 #ifndef DASH__HALO_REGION_H
2 #define DASH__HALO_REGION_H
3 
4 #include <dash/halo/Types.h>
5 #include <dash/halo/Stencil.h>
6 #include <dash/iterator/GlobViewIter.h>
7 
8 #include <cstdlib>
9 
10 namespace dash {
11 
12 namespace halo {
13 
14 using namespace internal;
15 
39 template <dim_t NumDimensions>
40 class RegionCoords : public Dimensional<region_coord_t, NumDimensions> {
41 private:
44 
45  static constexpr auto RegionsMax = NumRegionsMax<NumDimensions>;
46 
47 public:
48  using Coords_t = std::array<uint8_t, NumDimensions>;
49  using CoordsVec_t = std::vector<Self_t>;
50  using RegIndDepVec_t = std::vector<region_index_t>;
51  using RegIndexDim_t = std::pair<region_index_t, region_index_t>;
52 
53 
54 
55 public:
62  for(dim_t i = 0; i < NumDimensions; ++i) {
63  this->_values[i] = 1;
64  }
65  }
66 
71  template <typename... Values>
72  RegionCoords(region_coord_t value, Values... values)
73  : Base_t::Dimensional(value, values...) {
74  }
75 
79  RegionCoords(region_index_t index) {
80  this->_values = Self_t::coords(index);
81  }
82 
83  static constexpr region_index_t center_index() {
84  return NumRegionsMax<NumDimensions> / 2;
85  }
86 
87  static Coords_t center_coords() {
88  Coords_t reg_coords;
89  reg_coords.fill(1);
90 
91  return reg_coords;
92  }
93 
97  constexpr region_index_t index() const { return index(this->_values); }
98 
102  static constexpr RegIndexDim_t index(dim_t dim) {
103  RegIndexDim_t index_dim = std::make_pair(0,0);
104 
105  for(dim_t d = 0; d < NumDimensions; ++d)
106  if(dim == d) {
107  index_dim.first = index_dim.first * REGION_INDEX_BASE;
108  index_dim.second = 2 + index_dim.second * REGION_INDEX_BASE;
109  }
110  else {
111  index_dim.first = 1 + index_dim.first * REGION_INDEX_BASE;
112  index_dim.second = 1 + index_dim.second * REGION_INDEX_BASE;
113  }
114 
115  return index_dim;
116  }
117 
121  static constexpr region_index_t index(dim_t dim, RegionPos pos) {
122  region_coord_t coord = (pos == RegionPos::PRE) ? 0 : 2;
123 
124  region_index_t index = 0;
125  for(dim_t d = 0; d < NumDimensions; ++d)
126  if(dim == d)
127  index = coord + index * REGION_INDEX_BASE;
128  else
129  index = 1 + index * REGION_INDEX_BASE;
130 
131  return index;
132  }
133 
137  template<typename StencilPointT>
138  static constexpr region_index_t index(const StencilPointT& stencil) {
139  region_index_t index = 0;
140  for(dim_t d = 0; d < NumDimensions; ++d) {
141  if(stencil[d] < 0) {
142  index *= REGION_INDEX_BASE;
143  continue;
144  }
145 
146  if(stencil[d] > 0) {
147  index = 2 + index * REGION_INDEX_BASE;
148  continue;
149  }
150 
151  index = 1 + index * REGION_INDEX_BASE;
152  }
153 
154  return index;
155  }
156 
162  static region_index_t index(const Coords_t& coords) {
163  region_index_t index = coords[0];
164  for(dim_t d = 1; d < NumDimensions; ++d) {
165  // in case a wrong region coordinate was set
166  if(coords[d] > 2) {
167  index = coords[d] + index * REGION_INDEX_BASE;
168  } else {
169  index = coords[d] + index * REGION_INDEX_BASE;
170  }
171  }
172 
173  return index;
174  }
175 
181  static Coords_t coords(const region_index_t index) {
182  Coords_t coords{};
183  region_index_t index_tmp =index;
184  for(auto i = (NumDimensions - 1); i >= 1; --i) {
185  auto res = std::div(static_cast<long>(index_tmp), static_cast<long>(REGION_INDEX_BASE));
186  coords[i] = res.rem;
187  index_tmp = res.quot;
188  }
189  coords[0] = index_tmp;
190 
191  return coords;
192  }
193 
197  static dim_t relevant_dim(const Coords_t& coords) {
198  dim_t dim = 1;
199  for(auto d = 1; d < NumDimensions; ++d) {
200  if(coords[d] != 1)
201  dim = d + 1;
202  }
203 
204  return dim;
205  }
206 
213  static dim_t level(const Coords_t& coords) {
214  dim_t level = 0;
215  for(auto d = 0; d < NumDimensions; ++d) {
216  if(coords[d] != 1)
217  ++level;
218  }
219  return level;
220  }
221 
231  dim_t level() { return level(this->_values); }
232 
233  static RegIndDepVec_t boundary_dependencies(region_index_t index) {
234  RegIndDepVec_t index_dep{};
235 
236  if(index >= RegionsMax) {
237  DASH_LOG_ERROR("Invalid region index: %d", index);
238 
239  return index_dep;
240  }
241 
242  auto region_coords = Self_t(index);
243  auto level = region_coords.level();
244 
245  if(level == 0) {
246  return index_dep;
247  }
248 
249  if(level == 1) {
250  index_dep.push_back(index);
251 
252  return index_dep;
253  }
254 
255  CoordsVec_t found_coords{};
256  find_dep_regions(0, region_coords, found_coords);
257 
258  for(auto& reg_coords : found_coords) {
259  index_dep.push_back(reg_coords.index());
260  }
261 
262  return index_dep;
263  }
264 
265  constexpr bool operator==(const Self_t& other) const {
266 
267  return this->_values == other._values;
268  }
269 
270  constexpr bool operator!=(const Self_t& other) const {
271  return !(*this == other);
272  }
273 
274 private:
275 
276  static void find_dep_regions(dim_t dim_change, const Self_t& current_coords, CoordsVec_t& dep_coords) {
277  dep_coords.push_back(current_coords);
278 
279  for(dim_t d = dim_change; d < NumDimensions; ++d) {
280  if(current_coords[d] != 1) {
281  auto new_coords = current_coords;
282  new_coords[d] = 1;
283  find_dep_regions(d+1, new_coords, dep_coords);
284  }
285  }
286  }
287 }; // RegionCoords
288 
293 template <dim_t NumDimensions>
294 class RegionSpec {
295 private:
297 
298 public:
300  using region_extent_t = uint16_t;
301 
302 public:
306  RegionSpec(const RegionCoords_t& coords, const region_extent_t extent)
307  : _coords(coords), _index(coords.index()), _extent(extent),
308  _rel_dim(RegionCoords_t::relevant_dim(coords.values())),
309  _level(RegionCoords_t::level(coords.values())) {}
310 
314  RegionSpec(region_index_t index, const region_extent_t extent)
315  : _coords(RegionCoords_t(index)), _index(index), _extent(extent),
316  _rel_dim(RegionCoords_t::relevant_dim(_coords.values())),
317  _level(RegionCoords_t::level(_coords.values())) {}
318 
319  RegionSpec()
320  : _coords(), _index(_coords.index()), _extent(0),
321  _rel_dim(RegionCoords_t::relevant_dim(_coords.values())),
322  _level(RegionCoords_t::level(_coords.values())) {}
323 
327  template <typename StencilT>
328  static region_index_t index(const StencilT& stencil) {
329  region_index_t index = 0;
330  if(stencil[0] == 0)
331  index = 1;
332  else if(stencil[0] > 0)
333  index = 2;
334  for(auto d(1); d < NumDimensions; ++d) {
335  if(stencil[d] < 0)
336  index *= REGION_INDEX_BASE;
337  else if(stencil[d] == 0)
338  index = 1 + index * REGION_INDEX_BASE;
339  else
340  index = 2 + index * REGION_INDEX_BASE;
341  }
342 
343  return index;
344  }
345 
349  constexpr region_index_t index() const { return _index; }
350 
354  constexpr const RegionCoords_t& coords() const { return _coords; }
355 
359  constexpr region_extent_t extent() const { return _extent; }
360 
364  constexpr region_coord_t operator[](const region_index_t index) const {
365  return _coords[index];
366  }
367 
368  constexpr bool operator==(const Self_t& other) const {
369  return _coords.index() == other._coords.index() && _extent == other._extent;
370  }
371 
372  constexpr bool operator!=(const Self_t& other) const {
373  return !(*this == other);
374  }
375 
379  dim_t relevant_dim() const { return _rel_dim; }
380 
385  dim_t level() const { return _level; }
386 
387 private:
388  RegionCoords_t _coords{};
389  region_index_t _index;
390  region_extent_t _extent = 0;
391  dim_t _rel_dim = 1;
392  dim_t _level = 0;
393 }; // RegionSpec
394 
395 template <dim_t NumDimensions>
396 std::ostream& operator<<(std::ostream& os,
397  const RegionSpec<NumDimensions>& rs) {
398  os << "dash::halo::RegionSpec<" << NumDimensions << ">(" << (uint32_t) rs[0];
399  for(auto i = 1; i < NumDimensions; ++i)
400  os << "," << (uint32_t) rs[i];
401  os << "), Extent:" << rs.extent();
402 
403  return os;
404 }
405 
410 template <typename ElementT, typename PatternT, typename GlobMemT>
411 class Region {
412 private:
414  static constexpr auto NumDimensions = PatternT::ndim();
415 
416 public:
418  using const_iterator = const iterator;
420  using GlobMem_t = GlobMemT;
421  using ViewSpec_t = typename PatternT::viewspec_type;
422  using extent_size_t = typename ViewSpec_t::size_type;
423  using pattern_size_t = typename PatternT::size_type;
424  using EnvRegInfo_t = EnvironmentRegionInfo<ViewSpec_t>;
425  using BorderPair_t = typename EnvRegInfo_t::PrePostBool_t;
426  using RegBorders_t = typename EnvRegInfo_t::RegionBorders_t;
427 
428 public:
429  Region(const RegionSpec_t& region_spec, const ViewSpec_t& view,
430  GlobMem_t& globmem, const PatternT& pattern,
431  const EnvRegInfo_t& env_reg_info)
432  : _region_spec(&region_spec), _view(view),
433  _globmem(&globmem), _pattern(&pattern),
434  _env_reg_info(&env_reg_info),
435  _beg(&globmem, *_pattern, _view, 0),
436  _end(&globmem, *_pattern, _view, _view.size()) {
437  }
438 
439  Region(const Self_t& other)
440  : _region_spec(other._region_spec),
441  _view (other._view),
442  _globmem(other._globmem),
443  _pattern(other._pattern),
444  _env_reg_info(other._env_reg_info),
445  _beg(_globmem, *_pattern, _view, 0),
446  _end(_globmem, *_pattern, _view, _view.size()) {
447  }
448 
449  Region(const Self_t&& other)
450  : _region_spec(std::move(other._region_spec)),
451  _view (std::move(other._view)),
452  _globmem(std::move(other._globmem)),
453  _pattern(std::move(other._pattern)),
454  _env_reg_info(std::move(other._env_reg_info)),
455  _beg(_globmem, *_pattern, _view, 0),
456  _end(_globmem, *_pattern, _view, _view.size()) {
457  }
458 
459  Self_t& operator=(const Self_t& other) {
460  _region_spec = other._region_spec;
461  _view = other._view;
462  _globmem = other._globmem;
463  _pattern = other._pattern;
464  _env_reg_info = other._env_reg_info;
465  _beg = iterator(_globmem, *_pattern, _view, 0);
466  _end = iterator(_globmem, *_pattern, _view, _view.size());
467 
468  return *this;
469  }
470 
471  Self_t& operator=(const Self_t&& other) {
472  _region_spec = std::move(other._region_spec);
473  _view = std::move(other._view);
474  _globmem = std::move(other._globmem);
475  _pattern = std::move(other._pattern);
476  _env_reg_info = std::move(other._env_reg_info),
477  _beg = iterator(_globmem, *_pattern, _view, 0);
478  _end = iterator(_globmem, *_pattern, _view, _view.size());
479 
480  return *this;
481  }
482 
483  const region_index_t index() const { return _region_spec->index(); }
484 
485  const RegionSpec_t& spec() const { return *_region_spec; }
486 
487  const ViewSpec_t& view() const { return _view; }
488 
489  pattern_size_t size() const { return _view.size(); }
490 
491  const RegBorders_t& border() const { return _env_reg_info->region_borders; }
492 
493  bool is_border_region() const { return _env_reg_info->border_region; }
494 
495  bool is_custom_region() const {
496  return (_env_reg_info->border_region && _env_reg_info->boundary_prop == BoundaryProp::CUSTOM) ? true : false;
497  }
498 
505  BorderPair_t border_dim(dim_t dim) const { return _env_reg_info->region_borders[dim]; }
506 
507  bool border_dim(dim_t dim, RegionPos pos) const {
508  if(pos == RegionPos::PRE) {
509  return _env_reg_info->region_borders[dim].first;
510  }
511 
512  return _env_reg_info->region_borders[dim].second;
513  }
514 
515  iterator begin() const { return _beg; }
516 
517  iterator end() const { return _end; }
518 
519 private:
520  const RegionSpec_t* _region_spec;
521  ViewSpec_t _view;
522  GlobMemT* _globmem;
523  const PatternT* _pattern;
524  const EnvRegInfo_t* _env_reg_info;
525  iterator _beg;
526  iterator _end;
527 }; // Region
528 
529 template <typename ElementT, typename PatternT, typename GlobMemT>
530 std::ostream& operator<<(std::ostream& os,
531  const Region<ElementT, PatternT, GlobMemT>& region) {
532  os << "dash::halo::Region<" << typeid(ElementT).name() << ">"
533  << "( view: " << region.view() << "; region spec: " << region.spec()
534  << "; env_reg_info: {";
535  const auto& border = region.border();
536  for(auto d = 0; d < border.size(); ++d) {
537  if(d > 0) {
538  os << ",";
539  }
540  os << "(" << border[d].first << border[d].second << ")";
541  }
542  os << "}"
543  << "; is border: " << region.is_border_region()
544  << "; is custom: " << region.is_custom_region();
545  //<< "; begin iterator: " << region.begin()
546  //<< "; end iterator: " << region.begin() << ")";
547 
548  return os;
549 }
550 
551 } // namespace halo
552 
553 } // namespace dash
554 
555 #endif // DASH__HALO_REGION_H
constexpr region_extent_t extent() const
Returns the extent.
Definition: Region.h:359
RegionCoords(region_index_t index)
Constructor takes a region index to set up the region coordinates.
Definition: Region.h:79
constexpr std::enable_if< std::is_integral< IndexType >::value, IndexType >::type index(IndexType idx)
Definition: Iterator.h:60
static region_index_t index(const Coords_t &coords)
Returns the region index for a given RegionCoords.
Definition: Region.h:162
size_t size()
Return the number of units in the global team.
constexpr auto end(RangeType &&range) -> decltype(std::forward< RangeType >(range).end())
Definition: Range.h:98
This class is a simple memory pool which holds allocates elements of size ValueType.
Definition: AllOf.h:8
dim_t level() const
returns the number of coordinates unequal the center (1) for all dimensions
Definition: Region.h:385
constexpr auto begin(RangeType &&range) -> decltype(std::forward< RangeType >(range).begin())
Definition: Range.h:89
constexpr region_index_t index() const
Definition: Region.h:97
int dim_t
Scalar type for a dimension value, with 0 indicating the first dimension.
Definition: Types.h:39
dim_t level()
returns the number of coordinates unequal to the center (1) for all dimensions
Definition: Region.h:231
dim_t relevant_dim() const
Returns the highest dimension with region values != 1.
Definition: Region.h:379
static constexpr RegIndexDim_t index(dim_t dim)
Returns a region index for a given dimension and RegionPos.
Definition: Region.h:102
RegionCoords(region_coord_t value, Values... values)
Constructor allows custom coordinate values and calculates the fitting region index.
Definition: Region.h:72
Stencil point with raletive coordinates for N dimensions e.g.
Definition: Stencil.h:19
N-Dimensional region coordinates and associated indices for all possible Halo/Boundary regions of a H...
Definition: Region.h:40
static constexpr region_index_t index(const StencilPointT &stencil)
Returns a region index for a given dimension and RegionPos.
Definition: Region.h:138
static dim_t level(const Coords_t &coords)
auto max = stencil.max(); level = 0 -> center (1,1) level = 1 -> main regions (e.g.
Definition: Region.h:213
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
RegionSpec(const RegionCoords_t &coords, const region_extent_t extent)
Constructor using RegionCoords and the extent.
Definition: Region.h:306
static dim_t relevant_dim(const Coords_t &coords)
Returns the highest dimension with region values != 1.
Definition: Region.h:197
RegionCoords()
Default Constructor.
Definition: Region.h:61
static constexpr region_index_t index(dim_t dim, RegionPos pos)
Returns a region index for a given dimension and RegionPos.
Definition: Region.h:121
static region_index_t index(const StencilT &stencil)
Returns the region index for a given StencilPoint.
Definition: Region.h:328
static Coords_t coords(const region_index_t index)
Definition: Region.h:181
Provides RegionIter and some region metadata like RegionSpec, size etc.
Definition: Region.h:411
constexpr region_coord_t operator[](const region_index_t index) const
Returns the RegionCoords for a given region index.
Definition: Region.h:364
constexpr region_index_t index() const
Returns the region index.
Definition: Region.h:349
constexpr const RegionCoords_t & coords() const
Returns the RegionCoords.
Definition: Region.h:354
constexpr DimensionalType::extent_type extent(const DimensionalType &d)
Definition: Dimensional.h:73
Region specification connecting RegionCoords with an extent.
Definition: Region.h:294
BorderPair_t border_dim(dim_t dim) const
Returns a pair of two booleans for a given dimension.
Definition: Region.h:505
RegionSpec(region_index_t index, const region_extent_t extent)
Constructor using a region index and an extent.
Definition: Region.h:314