1 #ifndef DASH__HALO__ITERATOR__STENCILITERATOR_H 2 #define DASH__HALO__ITERATOR__STENCILITERATOR_H 4 #include <dash/Types.h> 6 #include <dash/halo/Halo.h> 7 #include <dash/halo/HaloMemory.h> 15 using namespace internal;
17 template<
typename StencilOpT>
21 using StencilSpec_t =
typename StencilOpT::StencilSpec_t;
24 static constexpr
auto NumStencilPoints = StencilOpT::num_stencil_points();
25 static constexpr
auto MemoryArrange = StencilOpT::memory_order();
26 static constexpr
auto FastestDimension =
27 MemoryArrange == ROW_MAJOR ? NumDimensions - 1 : 0;
30 using Element_t =
typename StencilOpT::Element_t;
31 using ViewSpec_t =
typename StencilOpT::ViewSpec_t;
32 using index_t =
typename StencilOpT::index_t;
33 using uindex_t =
typename StencilOpT::uindex_t;
35 using Coords_t =
typename StencilOpT::Coords_t;
36 using stencil_index_t =
typename StencilSpec_t::stencil_index_t;
39 using RangeDim_t = std::pair<uindex_t, uindex_t>;
40 using Ranges_t = std::array<RangeDim_t, NumDimensions>;
41 using StencilOffsPtrs_t = std::array<Element_t*, NumStencilPoints>;
42 using OffsetsDim_t = std::array<uindex_t, NumDimensions>;
43 using viewspec_index_t =
typename ViewSpec_t::index_type;
50 uindex_t start_idx = 0,
const ViewSpec_t* sub_view =
nullptr)
51 : _stencil_op(&stencil_op),
52 _sub_view((sub_view !=
nullptr) ? sub_view : &(stencil_op.inner.view())),
53 _size(_sub_view->size()),
54 _local_layout(stencil_op.view_local().extents()) {
60 static constexpr decltype(
auto)
ndim() {
return NumDimensions; }
62 const ViewSpec_t& view()
const {
return _stencil_op->view_local(); }
64 const ViewSpec_t& sub_view()
const {
return *_sub_view; }
66 const Coords_t& coords()
const {
return _coords; }
68 Coords_t coords(uindex_t idx)
const {
return _local_layout.coords(idx, *_sub_view); }
70 const uindex_t&
index()
const {
return _idx; }
72 const uindex_t& offset()
const {
return _offset; }
74 Element_t& value()
const {
return *_current_lmemory_addr; }
76 Element_t& value_at(
const stencil_index_t index_stencil )
const {
return *_stencil_mem_ptr[index_stencil]; }
78 Element_t& value_at(
const StencilP_t& stencil) {
79 const auto index_stencil = _stencil_op->stencil_spec().index(stencil);
81 DASH_ASSERT_MSG(index_stencil.second,
82 "No valid region index for given stencil point found");
84 return value_at(index_stencil.first);
87 void set(uindex_t idx) {
97 init_stencil_points();
100 Element_t operator[](index_t n)
const {
101 auto index = _idx + n;
102 auto new_coords = coords(
index);
104 return _stencil_op->local_memory()[_local_layout.at(new_coords)];
107 Element_t& operator[](index_t n) {
108 return operator[](n);
111 void next_element() {
113 ++_coords[FastestDimension];
114 if(static_cast<uindex_t>(_coords[FastestDimension]) < _ranges[FastestDimension].
second) {
115 for(
auto i = 0u; i < NumStencilPoints; ++i)
116 ++_stencil_mem_ptr[i];
118 ++_current_lmemory_addr;
123 _coords[FastestDimension] = _sub_view->offset(FastestDimension);
125 if(MemoryArrange == ROW_MAJOR) {
126 for(
dim_t d = NumDimensions-1; d > 0;) {
129 if(static_cast<uindex_t>(_coords[d]) < _ranges[d].second) {
130 add = _offsets_dim[d];
133 _coords[d] = _ranges[d].first;
138 for(
dim_t d = 1; d < NumDimensions; ++d) {
140 if(static_cast<uindex_t>(_coords[d]) < _ranges[d].second) {
141 add = _offsets_dim[d];
144 _coords[d] = _ranges[d].first;
148 _current_lmemory_addr += add;
150 for(
auto i = 0u; i < NumStencilPoints; ++i) {
151 _stencil_mem_ptr[i] += add;
158 for(
dim_t d = 0; d < NumDimensions; ++d) {
159 _ranges[d] = std::make_pair(_sub_view->offset(d), _sub_view->offset(d) + _sub_view->extent(d));
164 _coords = _local_layout.coords(_idx, *_sub_view);
168 if(MemoryArrange == ROW_MAJOR) {
169 _offset = _coords[0];
170 for(
dim_t d = 1; d < NumDimensions; ++d)
171 _offset = _offset * _local_layout.extent(d) + _coords[d];
173 _offset = _coords[NumDimensions - 1];
174 for(
dim_t d = NumDimensions - 1; d > 0;) {
176 _offset = _offset * _local_layout.extent(d) + _coords[d];
180 const auto& view = _stencil_op->view_local();
181 _offsets_dim[FastestDimension] = 1;
182 if(MemoryArrange == ROW_MAJOR) {
183 if(FastestDimension > 0) {
184 _offsets_dim[FastestDimension - 1] = (view.extent(FastestDimension) - _sub_view->extent(FastestDimension)) + 1;
186 for(
dim_t d = FastestDimension - 1; d > 0;) {
188 _offsets_dim[d] = (view.extent(d+1) - _sub_view->extent(d+1)) * view.extent(d+2) + _offsets_dim[d+1];
191 if(NumDimensions > 1) {
192 _offsets_dim[FastestDimension + 1] = (view.extent(FastestDimension) - _sub_view->extent(FastestDimension)) + 1;
194 for(
dim_t d = 2; d < NumDimensions; ++d) {
195 _offsets_dim[d] = (view.extent(d-1) - _sub_view->extent(d-1)) * view.extent(d-2) + _offsets_dim[d-1];
200 void init_stencil_points() {
201 _current_lmemory_addr = _stencil_op->local_memory() + _offset;
202 for(
auto i = 0u; i < NumStencilPoints; ++i) {
203 _stencil_mem_ptr[i] = _current_lmemory_addr + _stencil_op->stencil_offsets()[i];
208 StencilOpT* _stencil_op;
209 const ViewSpec_t* _sub_view;
213 Element_t* _current_lmemory_addr;
214 StencilOffsPtrs_t _stencil_mem_ptr;
218 OffsetsDim_t _offsets_dim;
221 template <
typename StencilOpT>
222 std::ostream& operator<<(
225 os <<
"dash::halo::CoordsHelper" 226 <<
"(view: " << helper.view()
227 <<
"; sub_view: " << helper.sub_view()
228 <<
"; index: " << helper.index()
229 <<
"; offset: " << helper.offset()
231 for(
const auto& elem : helper.coords()) {
239 template<
typename StencilOpT>
244 using StencilSpec_t =
typename StencilOpT::StencilSpec_t;
245 using StencilSpecViews_t =
typename StencilOpT::StencilSpecViews_t;
248 static constexpr
auto NumStencilPoints = StencilOpT::num_stencil_points();
249 static constexpr
auto MemoryArrange = StencilOpT::memory_order();
250 static constexpr
auto FastestDimension =
251 MemoryArrange == ROW_MAJOR ? NumDimensions - 1 : 0;
254 using Element_t =
typename StencilOpT::Element_t;
255 using ViewSpec_t =
typename StencilOpT::ViewSpec_t;
256 using index_t =
typename StencilOpT::index_t;
257 using uindex_t =
typename StencilOpT::uindex_t;
259 using Coords_t =
typename StencilOpT::Coords_t;
260 using stencil_index_t =
typename StencilSpec_t::stencil_index_t;
264 using BoundaryViews_t =
typename StencilSpecViews_t::BoundaryViews_t;
265 using viewspec_index_t =
typename ViewSpec_t::index_type;
268 using ViewIndexPair_t = std::pair<const ViewSpec_t*, uindex_t>;
269 using StencilOffsPtrs_t = std::array<Element_t*, NumStencilPoints>;
270 using OffsetsDim_t = std::array<uindex_t, NumDimensions>;
276 using Ranges_t = std::array<RangeDim_t, NumDimensions>;
278 struct HaloPointProp_t {
281 region_index_t
index;
283 using HaloPoints_t = std::array<HaloPointProp_t, NumStencilPoints>;
289 : _stencil_op(&stencil_op),
290 _size(stencil_op.spec_views().boundary_size()),
292 _local_layout(stencil_op.view_local().extents()),
294 const auto& ext_max = stencil_op.stencil_spec().minmax_distances(FastestDimension);
296 _ext_dim_reduced = {
static_cast<uindex_t
>(std::abs(ext_max.first)),
297 _local_layout.extent(FastestDimension) -
static_cast<uindex_t
>(ext_max.second)};
301 static constexpr decltype(
auto)
ndim() {
return NumDimensions; }
303 const ViewSpec_t& view()
const {
return _stencil_op->view_local(); }
305 const ViewSpec_t& sub_view()
const {
return *(_current_view.first); }
307 const Coords_t& coords()
const {
return _coords; }
309 const uindex_t&
index()
const {
return _idx; }
311 const uindex_t& offset()
const {
return _offset; }
313 Element_t& value()
const {
return *_current_lmemory_addr; }
315 Element_t& value_at(
const stencil_index_t index_stencil )
const {
return *_stencil_mem_ptr[index_stencil]; }
317 Element_t& value_at(
const StencilP_t& stencil) {
318 const auto index_stencil = _stencil_op->stencil_spec().index(stencil);
320 DASH_ASSERT_MSG(index_stencil.second,
321 "No valid region index for given stencil point found");
323 return value_at(index_stencil.first);
326 void set(uindex_t idx) {
334 _current_view = get_current_view(_idx);
338 init_stencil_points();
342 Element_t operator[](index_t n)
const {
343 auto index = _idx + n;
344 auto new_coords = coords(
index);
346 return _stencil_op->local_memory()[_local_layout.at(new_coords)];
349 Element_t& operator[](index_t n) {
350 return operator[](n);
353 const region_index_t region_id()
const {
return _region_number; }
355 const uindex_t&
size()
const {
return _size; }
357 void next_element() {
359 ++_current_view.second;
360 ++_coords[FastestDimension];
362 if(static_cast<uindex_t>(_coords[FastestDimension]) < _ranges[FastestDimension].
end) {
363 if(static_cast<uindex_t>(_coords[FastestDimension]) >= _ext_dim_reduced.begin
364 && static_cast<uindex_t>(_coords[FastestDimension]) < _ext_dim_reduced.end) {
365 ++_current_lmemory_addr;
367 for(
auto i = 0u; i < NumStencilPoints; ++i) {
368 ++_stencil_mem_ptr[i];
375 if(_current_view.second == (*_current_view.first).size()) {
377 auto& bnd_views = _stencil_op->boundary.view();
381 if(_region_number >= bnd_views.size()) {
382 _region_number = bnd_views.size();
387 }
while(bnd_views[_region_number].
size() == 0);
390 _current_view = {&bnd_views[_region_number],0};
394 init_stencil_points();
400 if(static_cast<uindex_t>(_coords[FastestDimension]) >= _ranges[FastestDimension].end) {
401 _coords[FastestDimension] = _ranges[FastestDimension].begin;
402 if(MemoryArrange == ROW_MAJOR) {
403 for(
dim_t d = NumDimensions-1; d > 0;) {
406 if(static_cast<uindex_t>(_coords[d]) < _ranges[d].end) {
407 add = _offsets_dim[d];
410 _coords[d] = _ranges[d].begin;
415 if(MemoryArrange == COL_MAJOR) {
416 for(
dim_t d = 1; d < NumDimensions; ++d) {
418 if(static_cast<uindex_t>(_coords[d]) < _ranges[d].end) {
419 add = _offsets_dim[d];
422 _coords[d] = _ranges[d].begin;
429 _current_lmemory_addr += add;
431 const auto& extents = _local_layout.extents();
432 const auto& specs = _stencil_op->stencil_spec();
433 const auto& stencil_offs = _stencil_op->stencil_offsets();
434 for(
auto i = 0u; i < NumStencilPoints; ++i) {
435 if(_spoint_is_halo[i].possible) {
436 auto& stencil = specs[i];
437 auto coords = _coords;
439 if(_spoint_is_halo[i].always) {
440 for(
dim_t d = 0; d < NumDimensions; ++d)
441 coords[d] += stencil[d];
442 _stencil_mem_ptr[i] = value_halo_at(_spoint_is_halo[i].
index, coords);
446 bool is_halo =
false;
447 region_index_t
index = 0;
448 for(
dim_t d = 0; d < NumDimensions; ++d) {
449 auto stencil_off = stencil[d];
450 if(stencil_off == 0) {
451 index = 1 + index * REGION_INDEX_BASE;
454 coords[d] += stencil_off;
456 index *= REGION_INDEX_BASE;
461 if(static_cast<uindex_t>(coords[d]) < extents[d]) {
462 index = 1 + index * REGION_INDEX_BASE;
466 index = 2 + index * REGION_INDEX_BASE;
470 _stencil_mem_ptr[i] = value_halo_at(index, coords);
474 _stencil_mem_ptr[i] = _current_lmemory_addr + stencil_offs[i];
476 _stencil_mem_ptr[i] += add;
485 for(
dim_t d = 0; d < NumDimensions; ++d) {
486 auto sub_view = _current_view.first;
487 _ranges[d] = {
static_cast<uindex_t
>(sub_view->offset(d)),
488 static_cast<uindex_t>(sub_view->offset(d)) + sub_view->extent(d)};
493 _coords = _local_layout.coords(_current_view.second, *_current_view.first);
497 if(MemoryArrange == ROW_MAJOR) {
498 _offset = _coords[0];
499 for(
dim_t d = 1; d < NumDimensions; ++d)
500 _offset = _offset * _local_layout.extent(d) + _coords[d];
502 _offset = _coords[NumDimensions - 1];
503 for(
dim_t d = NumDimensions - 1; d > 0;) {
505 _offset = _offset * _local_layout.extent(d) + _coords[d];
509 auto& sub_view = *(_current_view.first);
510 _offsets_dim[FastestDimension] = 1;
511 const auto& view = _stencil_op->view_local();
512 if(MemoryArrange == ROW_MAJOR) {
513 if(FastestDimension > 0) {
514 _offsets_dim[FastestDimension - 1] = (view.extent(FastestDimension) - sub_view.extent(FastestDimension)) + 1;
516 for(
dim_t d = FastestDimension - 1; d > 0;) {
518 _offsets_dim[d] = (view.extent(d+1) - sub_view.extent(d+1)) * view.extent(d+2) + _offsets_dim[d+1];
521 if(NumDimensions > 1) {
522 _offsets_dim[FastestDimension + 1] = (view.extent(FastestDimension) - sub_view.extent(FastestDimension)) + 1;
524 for(
dim_t d = 2; d < NumDimensions; ++d) {
525 _offsets_dim[d] = (view.extent(d-1) - sub_view.extent(d-1)) * view.extent(d-2) + _offsets_dim[d-1];
530 ViewIndexPair_t get_current_view(uindex_t idx) {
532 const auto& bnd_views = _stencil_op->boundary.view();
533 for(
const auto& region : bnd_views) {
534 if(idx < region.size()) {
535 return std::make_pair(®ion, idx);
538 idx -= region.size();
541 auto& last_region = bnd_views.back();
542 return std::make_pair(&last_region, last_region.size());
545 void init_stencil_points() {
546 _current_lmemory_addr = _stencil_op->local_memory() + _offset;
547 const auto& specs = _stencil_op->stencil_spec();
548 const auto& stencil_offs = _stencil_op->stencil_offsets();
549 auto minmax = specs.minmax_distances();
550 const auto& extents = _local_layout.extents();
552 for(
auto i = 0u; i < NumStencilPoints; ++i) {
553 auto& spoint_halo =_spoint_is_halo[i];
554 spoint_halo = {
false,
true, 0};
556 auto halo_coord = _coords;
557 bool is_halo =
false;
558 for(
dim_t d = 0; d < NumDimensions; ++d) {
559 auto stencil_off = specs[i][d];
560 if(stencil_off == 0) {
561 spoint_halo.index = 1 + spoint_halo.index * REGION_INDEX_BASE;
565 halo_coord[d] += stencil_off;
566 if(halo_coord[d] < 0) {
567 spoint_halo.index *= REGION_INDEX_BASE;
568 spoint_halo.possible =
true;
571 spoint_halo.always =
false;
576 if(static_cast<uindex_t>(halo_coord[d]) < extents[d]) {
577 spoint_halo.index = 1 + spoint_halo.index * REGION_INDEX_BASE;
579 (extents[d] - static_cast<uindex_t>(_coords[d])) <= static_cast<uindex_t>(
minmax[d].
second)) {
580 spoint_halo.always =
false;
581 spoint_halo.possible =
true;
587 spoint_halo.index = 2 + spoint_halo.index * REGION_INDEX_BASE;
588 spoint_halo.possible =
true;
591 spoint_halo.always =
false;
596 _stencil_mem_ptr[i] = value_halo_at(spoint_halo.index, halo_coord);
598 _stencil_mem_ptr[i] = _current_lmemory_addr + stencil_offs[i];
602 Element_t* value_halo_at(region_index_t region_index,
603 Coords_t& halo_coords) {
604 auto& halo_memory = _stencil_op->halo_memory();
605 halo_memory.to_halo_mem_coords(region_index, halo_coords);
607 return &*(halo_memory.first_element_at(region_index)
608 + halo_memory.offset(region_index, halo_coords));
612 StencilOpT* _stencil_op;
614 region_index_t _region_number{ 0 };
618 ViewIndexPair_t _current_view;
619 Element_t* _current_lmemory_addr;
620 StencilOffsPtrs_t _stencil_mem_ptr;
621 HaloPoints_t _spoint_is_halo;
624 OffsetsDim_t _offsets_dim;
626 RangeDim_t _ext_dim_reduced;
629 template <
typename StencilOpT>
630 std::ostream& operator<<(
633 os <<
"dash::halo::CoordsHelper" 634 <<
"(view: " << helper.view()
635 <<
"; region id: " << helper.region_id()
636 <<
"; sub_view: " << helper.sub_view()
637 <<
"; index: " << helper.index()
638 <<
"; offset: " << helper.offset()
640 for(
const auto& elem : helper.coords()) {
654 template <
typename CoordsIdxManagerT>
657 using Element_t =
typename CoordsIdxManagerT::Element_t;
660 using ViewSpec_t =
typename CoordsIdxManagerT::ViewSpec_t;
666 using iterator_category = std::random_access_iterator_tag;
667 using value_type = Element_t;
668 using difference_type =
typename CoordsIdxManagerT::uindex_t;
669 using pointer = Element_t*;
670 using reference = Element_t&;
672 using index_t =
typename CoordsIdxManagerT::index_t;
673 using uindex_t =
typename CoordsIdxManagerT::uindex_t;
675 using Coords_t =
typename CoordsIdxManagerT::Coords_t;
676 using stencil_index_t =
typename CoordsIdxManagerT::stencil_index_t;
686 : _coords_mng(coords_mng) {
713 reference
operator*()
const {
return _coords_mng.value(); }
722 return _coords_mng[n];
725 reference operator[](index_t n) {
726 return _coords_mng[n];
729 uindex_t rpos()
const {
return _coords_mng.index(); }
731 uindex_t lpos()
const {
return _coords_mng.offset(); }
733 Coords_t coords()
const {
return _coords_mng.coords(); }
735 CoordsIdxManagerT& helper() {
return _coords_mng;}
741 Element_t
value_at(
const stencil_index_t index_stencil) {
742 return _coords_mng.value_at(index_stencil);
748 Element_t value_at(
const StencilP_t& stencil) {
749 return _coords_mng.value_at(stencil);
756 _coords_mng.next_element();
767 _coords_mng.next_element();
776 _coords_mng.set(_coords_mng.index()-1);
787 _coords_mng.set(_coords_mng.index()-1);
792 Self_t& operator+=(index_t n) {
793 auto index = _coords_mng.index() + n;
795 _coords_mng.set(
index);
800 Self_t& operator-=(index_t n) {
801 auto index = _coords_mng.index();
803 _coords_mng.set(
index - n);
808 Self_t operator+(index_t n)
const {
822 difference_type
operator-(
const Self_t& other)
const {
return _coords_mng.index() - other._coords_mng.index(); }
825 return compare(other, std::less<index_t>());
829 return compare(other, std::less_equal<index_t>());
833 return compare(other, std::greater<index_t>());
837 return compare(other, std::greater_equal<index_t>());
840 bool operator==(
const Self_t& other)
const {
841 return compare(other, std::equal_to<index_t>());
844 bool operator!=(
const Self_t& other)
const {
845 return compare(other, std::not_equal_to<index_t>());
853 template <
typename GlobIndexCmpFunc>
854 bool compare(
const Self_t& other,
const GlobIndexCmpFunc& gidx_cmp)
const {
856 return gidx_cmp(_coords_mng.index(), other._coords_mng.index());
860 CoordsIdxManagerT _coords_mng;
869 template <
typename ElementT,
typename PatternT,
typename GlobMemT,
typename StencilSpecT,
870 StencilViewScope Scope>
875 static constexpr
auto MemoryArrange = PatternT::memory_order();
876 static constexpr
auto FastestDimension =
877 MemoryArrange == ROW_MAJOR ? NumDimensions - 1 : 0;
880 using ViewSpec_t =
typename PatternT::viewspec_type;
881 using pattern_size_t =
typename PatternT::size_type;
887 using iterator_category = std::random_access_iterator_tag;
888 using value_type = ElementT;
889 using difference_type =
typename PatternT::index_type;
890 using pointer = ElementT*;
891 using reference = ElementT&;
894 using pattern_index_t =
typename PatternT::index_type;
898 using ElementCoords_t = std::array<pattern_index_t, NumDimensions>;
899 using signed_pattern_size_t =
typename std::make_signed<pattern_size_t>::type;
900 using StencilOffsets_t =
901 std::array<signed_pattern_size_t, NumStencilPoints>;
903 using BoundaryViews_t =
typename StencilSpecViews_t::BoundaryViews_t;
918 const StencilSpecT* stencil_spec,
919 const StencilOffsets_t* stencil_offsets,
920 const ViewSpec_t& view_local,
const ViewSpec_t& view_scope,
922 : _halomemory(halomemory), _stencil_spec(stencil_spec),
923 _stencil_offsets(stencil_offsets), _view(view_scope),
924 _local_memory(local_memory),
925 _local_layout(view_local.extents()), _idx(idx) {
926 _size = _view.size();
931 if(Scope == StencilViewScope::INNER) {
932 _ext_dim_reduced = std::make_pair(
933 _view.offset(FastestDimension),
934 _local_layout.extent(FastestDimension) - ext_max.second - 1);
937 std::make_pair(std::abs(ext_max.first),
938 _view.extent(FastestDimension) - ext_max.second - 1);
954 const StencilSpecT* stencil_spec,
955 const StencilOffsets_t* stencil_offsets,
956 const ViewSpec_t& view_local,
957 const BoundaryViews_t& boundary_views, pattern_index_t idx)
958 : _halomemory(halomemory), _stencil_spec(stencil_spec),
959 _stencil_offsets(stencil_offsets),
960 _view(view_local.extents()),
961 _boundary_views(boundary_views),
962 _local_memory(local_memory),
963 _local_layout(view_local.extents()), _idx(idx) {
965 for(
const auto& view : boundary_views)
966 _size += view.size();
974 std::make_pair(std::abs(ext_max.first),
975 _view.extent(FastestDimension) - ext_max.second - 1);
1002 reference
operator*()
const {
return *_current_lmemory_addr; }
1011 auto coords = set_coords(_idx + n);
1012 return _local_memory[_local_layout.at(coords)];
1015 pattern_index_t rpos()
const {
return _idx; }
1017 pattern_index_t lpos()
const {
return _offset; }
1019 ElementCoords_t coords()
const {
return _coords; };
1021 bool is_halo_value(
const region_index_t index_stencil) {
1022 if(Scope == StencilViewScope::INNER)
1025 auto halo_coords = _coords;
1026 const auto& stencil = (*_stencil_spec)[index_stencil];
1027 for(
auto d = 0; d < NumDimensions; ++d) {
1028 halo_coords[d] += stencil[d];
1029 if(halo_coords[d] < 0 || halo_coords[d] >= _local_layout.extent(d))
1040 ElementT
value_at(
const region_index_t index_stencil) {
1041 return *(_stencil_mem_ptr[index_stencil]);
1047 ElementT value_at(
const StencilP_t& stencil) {
1048 auto index_stencil = _stencil_spec->index(stencil);
1050 DASH_ASSERT_MSG(index_stencil.second,
1051 "No valid region index for given stencil point found");
1053 return value_at(index_stencil.first);
1094 _coords = set_coords(_idx);
1101 Self_t& operator+=(pattern_index_t n) {
1104 _coords = set_coords(_idx);
1111 Self_t& operator-=(pattern_index_t n) {
1114 _coords = set_coords(_idx);
1121 Self_t operator+(pattern_index_t n)
const {
1135 difference_type
operator-(
const Self_t& other)
const {
return _idx - other._idx; }
1138 return compare(other, std::less<pattern_index_t>());
1142 return compare(other, std::less_equal<pattern_index_t>());
1146 return compare(other, std::greater<pattern_index_t>());
1150 return compare(other, std::greater_equal<pattern_index_t>());
1153 bool operator==(
const Self_t& other)
const {
1154 return compare(other, std::equal_to<pattern_index_t>());
1157 bool operator!=(
const Self_t& other)
const {
1158 return compare(other, std::not_equal_to<pattern_index_t>());
1166 template <
typename GlobIndexCmpFunc>
1167 bool compare(
const Self_t& other,
const GlobIndexCmpFunc& gidx_cmp)
const {
1171 if(
this == &other) {
1175 return gidx_cmp(_idx, other._idx);
1181 void next_element() {
1182 const auto& coord_fastest_dim = _coords[FastestDimension];
1184 if(coord_fastest_dim >= _ext_dim_reduced.first
1185 && coord_fastest_dim < _ext_dim_reduced.second) {
1186 for(
auto it = _stencil_mem_ptr.begin(); it != _stencil_mem_ptr.end();
1190 ++_coords[FastestDimension];
1191 ++_current_lmemory_addr;
1197 if(Scope == StencilViewScope::INNER) {
1198 if(MemoryArrange == ROW_MAJOR) {
1199 for(
dim_t d = NumDimensions; d > 0;) {
1201 if(_coords[d] < _view.extent(d) + _view.offset(d) - 1) {
1205 _coords[d] = _view.offset(d);
1208 for(
dim_t d = 0; d < NumDimensions; ++d) {
1209 if(_coords[d] < _view.extent(d) + _view.offset(d) - 1) {
1213 _coords[d] = _view.offset(d);
1216 if(MemoryArrange == ROW_MAJOR) {
1217 _offset = _coords[0];
1218 for(
dim_t d = 1; d < NumDimensions; ++d)
1219 _offset = _offset * _local_layout.extent(d) + _coords[d];
1221 _offset = _coords[NumDimensions - 1];
1222 for(
dim_t d = NumDimensions - 1; d > 0;) {
1224 _offset = _offset * _local_layout.extent(d) + _coords[d];
1227 _current_lmemory_addr = _local_memory + _offset;
1228 for(
auto i = 0; i < NumStencilPoints; ++i)
1229 _stencil_mem_ptr[i] = _current_lmemory_addr + (*_stencil_offsets)[i];
1235 if(Scope == StencilViewScope::BOUNDARY) {
1236 if(_region_bound == 0) {
1237 _coords = set_coords(_idx);
1239 if(_idx < _region_bound) {
1240 const auto& region = _boundary_views[_region_number];
1242 if(MemoryArrange == ROW_MAJOR) {
1243 for(
dim_t d = NumDimensions; d > 0;) {
1245 if(_coords[d] < region.extent(d) + region.offset(d) - 1) {
1249 _coords[d] = region.offset(d);
1253 for(
dim_t d = 0; d < NumDimensions; ++d) {
1254 if(_coords[d] < region.extent(d) + region.offset(d) - 1) {
1258 _coords[d] = region.offset(d);
1265 if(_region_number >= _boundary_views.size())
1268 _region_bound += _boundary_views[_region_number].size();
1269 }
while(_idx >= _region_bound);
1270 _coords = _local_layout.coords(0, _boundary_views[_region_number]);
1275 _coords = set_coords(_idx);
1281 void set_offsets() {
1282 if(MemoryArrange == ROW_MAJOR) {
1283 _offset = _coords[0];
1284 for(
dim_t d = 1; d < NumDimensions; ++d)
1285 _offset = _offset * _local_layout.extent(d) + _coords[d];
1287 _offset = _coords[NumDimensions - 1];
1288 for(
dim_t d = NumDimensions - 1; d > 0;) {
1290 _offset = _offset * _local_layout.extent(d) + _coords[d];
1293 _current_lmemory_addr = _local_memory + _offset;
1296 if(Scope == StencilViewScope::INNER) {
1297 for(
auto i = 0; i < NumStencilPoints; ++i)
1298 _stencil_mem_ptr[i] = _current_lmemory_addr + (*_stencil_offsets)[i];
1300 using signed_extent_t =
typename std::make_signed<pattern_size_t>::type;
1301 std::array<ElementCoords_t, NumStencilPoints> halo_coords{};
1302 std::array<bool, NumStencilPoints> is_halo{};
1303 std::array<region_index_t, NumStencilPoints> indexes{};
1304 for(
auto d = 0; d < NumDimensions; ++d) {
1305 auto extent = _local_layout.extent(d);
1307 for(
auto i = 0; i < NumStencilPoints; ++i) {
1308 auto& halo_coord = halo_coords[i][d];
1309 halo_coord = _coords[d] + (*_stencil_spec)[i][d];
1310 if(halo_coord < 0) {
1311 indexes[i] *= REGION_INDEX_BASE;
1316 if(halo_coord < static_cast<signed_extent_t>(
extent)) {
1317 indexes[i] = 1 + indexes[i] * REGION_INDEX_BASE;
1321 indexes[i] = 2 + indexes[i] * REGION_INDEX_BASE;
1326 for(
auto i = 0; i < NumStencilPoints; ++i) {
1328 _stencil_mem_ptr[i] = value_halo_at(indexes[i], halo_coords[i]);
1330 _stencil_mem_ptr[i] = _current_lmemory_addr + (*_stencil_offsets)[i];
1335 ElementCoords_t set_coords(pattern_index_t idx) {
1336 if(Scope == StencilViewScope::BOUNDARY) {
1339 auto local_idx = idx;
1340 for(
const auto& region : _boundary_views) {
1341 _region_bound += region.size();
1342 if(local_idx < region.size()) {
1343 return _local_layout.coords(local_idx, region);
1346 local_idx -= region.size();
1348 DASH_ASSERT(
"idx >= size not implemented yet");
1349 return std::array<pattern_index_t, NumDimensions>{};
1351 if(_view.size() == 0)
1352 return std::array<pattern_index_t, NumDimensions>{};
1354 return _local_layout.coords(idx, _view);
1358 ElementT* value_halo_at(region_index_t region_index,
1359 ElementCoords_t& halo_coords) {
1360 _halomemory->to_halo_mem_coords(region_index, halo_coords);
1362 return &*(_halomemory->first_element_at(region_index)
1363 + _halomemory->offset(region_index, halo_coords));
1368 const StencilSpecT* _stencil_spec;
1369 const StencilOffsets_t* _stencil_offsets;
1371 BoundaryViews_t _boundary_views{};
1372 ElementT* _local_memory;
1373 std::array<ElementT*, NumStencilPoints> _stencil_mem_ptr;
1375 pattern_index_t _idx{ 0 };
1377 std::pair<pattern_index_t, pattern_index_t> _ext_dim_reduced;
1378 signed_pattern_size_t _offset;
1379 pattern_index_t _region_bound{ 0 };
1380 size_t _region_number{ 0 };
1381 ElementCoords_t _coords;
1382 ElementT* _current_lmemory_addr;
1383 pattern_index_t _size;
1391 #endif // DASH__HALO__ITERATOR__STENCILITERATOR_H
constexpr std::enable_if< std::is_integral< IndexType >::value, IndexType >::type index(IndexType idx)
size_t size()
Return the number of units in the global team.
StencilIteratorTest(CoordsIdxManagerT coords_mng)
Constructor.
constexpr auto end(RangeType &&range) -> decltype(std::forward< RangeType >(range).end())
This class is a simple memory pool which holds allocates elements of size ValueType.
Element_t operator[](index_t n) const
Subscript operator, returns global reference to element at given global index.
reference operator*() const
Dereference operator.
ElementT value_at(const region_index_t index_stencil)
Returns the value for a given stencil point index (index postion in StencilSpec)
StencilIterator(ElementT *local_memory, HaloMemory_t *halomemory, const StencilSpecT *stencil_spec, const StencilOffsets_t *stencil_offsets, const ViewSpec_t &view_local, const ViewSpec_t &view_scope, pattern_index_t idx)
Constructor.
Takes the local part of the NArray and builds halo and boundary regions.
constexpr auto begin(RangeType &&range) -> decltype(std::forward< RangeType >(range).begin())
Self_t operator++(int)
Postfix increment operator.
Self_t & operator--()
Prefix decrement operator.
int dim_t
Scalar type for a dimension value, with 0 indicating the first dimension.
DASH_CONSTEXPR auto operator-(const GlobIter< ElementType, Pattern, GlobMemType, Pointer, Reference > &lhs, const GlobIter< ElementType, Pattern, GlobMemType, Pointer, Reference > &rhs) DASH_NOEXCEPT
constexpr bool operator<=(const Pair< T1, T2 > &x, const Pair< T1, T2 > &y)
Less-than-or-equal operator implemented in terms of less-than operator.
reference operator*() const
Dereference operator.
reference operator[](pattern_index_t n) const
Subscript operator, returns global reference to element at given global index.
Stencil point with raletive coordinates for N dimensions e.g.
constexpr bool operator>=(const Pair< T1, T2 > &x, const Pair< T1, T2 > &y)
Greater-than-or-equal operator implemented in terms of less-than operator.
N-Dimensional region coordinates and associated indices for all possible Halo/Boundary regions of a H...
static constexpr stencil_size_t num_stencil_points()
StencilIterator(ElementT *local_memory, HaloMemory_t *halomemory, const StencilSpecT *stencil_spec, const StencilOffsets_t *stencil_offsets, const ViewSpec_t &view_local, const BoundaryViews_t &boundary_views, pattern_index_t idx)
Constructor.
static constexpr dim_t ndim()
The number of dimensions of the iterator's underlying pattern.
constexpr bool operator>(const Pair< T1, T2 > &x, const Pair< T1, T2 > &y)
Greater-than operator implemented in terms of less-than operator.
Self_t operator--(int)
Postfix decrement operator.
constexpr dim_t ndim(const DimensionalType &d)
Self_t operator++(int)
Postfix increment operator.
DistanceAll_t minmax_distances() const
Returns the minimal and maximal distances of all stencil points for all dimensions.
Self_t & operator++()
Prefix increment operator.
static constexpr dim_t ndim()
The number of dimensions of the iterator's underlying pattern.
Element_t value_at(const stencil_index_t index_stencil)
Returns the value for a given stencil point index (index postion in StencilSpec)
constexpr DimensionalType::extent_type extent(const DimensionalType &d)
A collection of stencil points (Stencil) e.g.
Self_t operator--(int)
Postfix decrement operator.
Self_t & operator++()
Prefix increment operator.
constexpr bool operator<(const Pair< T1, T2 > &x, const Pair< T1, T2 > &y)
A pair is smaller than another pair if the first member is smaller or the first is equal and the seco...
Self_t & operator--()
Prefix decrement operator.