DASH  0.3.0
BlockPattern.h
1 #ifndef DASH__BLOCK_PATTERN_H_
2 #define DASH__BLOCK_PATTERN_H_
3 
4 #include <dash/Types.h>
5 #include <dash/Distribution.h>
6 #include <dash/Exception.h>
7 #include <dash/Dimensional.h>
8 #include <dash/Cartesian.h>
9 #include <dash/Team.h>
10 
11 #include <dash/pattern/PatternProperties.h>
12 #include <dash/pattern/internal/PatternArguments.h>
13 
14 #include <dash/internal/Math.h>
15 #include <dash/internal/Logging.h>
16 
17 #include <functional>
18 #include <array>
19 #include <type_traits>
20 #include <utility>
21 
22 namespace dash {
23 
37 template<
38  dim_t NumDimensions,
39  MemArrange Arrangement = ROW_MAJOR,
40  typename IndexType = dash::default_index_t
41 >
43 {
44 public:
45  static constexpr const char * PatternName = "BlockPattern";
46 
47 public:
50  // Block extents are constant for every dimension.
52  // Identical number of elements in every block.
54  // Size of blocks may differ.
59  // Number of blocks assigned to a unit may differ.
64  // Local indices iterate over block boundaries.
66  // Local element order corresponds to canonical linearization
67  // within entire local memory.
70 
71 private:
73  typedef typename std::make_unsigned<IndexType>::type
74  SizeType;
77  self_t;
89  TeamSpec_t;
91  SizeSpec_t;
93  ViewSpec_t;
94  typedef internal::PatternArguments<NumDimensions, IndexType>
95  PatternArguments_t;
96 
97 public:
98  typedef IndexType index_type;
99  typedef SizeType size_type;
100  typedef ViewSpec_t viewspec_type;
101  typedef struct {
102  team_unit_t unit;
103  IndexType index{};
104  } local_index_t;
105  typedef struct {
106  team_unit_t unit;
107  std::array<index_type, NumDimensions> coords;
108  } local_coords_t;
109 
110 private:
114  DistributionSpec_t _distspec;
116  dash::Team * _team = nullptr;
118  TeamSpec_t _teamspec;
120  SizeType _nunits = 0;
123  MemoryLayout_t _memory_layout;
125  BlockSizeSpec_t _blocksize_spec;
127  BlockSpec_t _blockspec;
131  LocalMemoryLayout_t _local_memory_layout;
133  BlockSpec_t _local_blockspec;
135  SizeType _local_capacity;
137  IndexType _lbegin;
139  IndexType _lend;
140 
141 public:
179  template<typename ... Args>
184  SizeType arg,
188  Args && ... args)
189  : BlockPattern(PatternArguments_t(arg, args...))
190  {
191  DASH_LOG_TRACE("BlockPattern()", "Constructor with argument list");
192  initialize_local_range();
193  DASH_LOG_TRACE("BlockPattern()", "BlockPattern initialized");
194  }
195 
226  const SizeSpec_t &sizespec,
229  DistributionSpec_t dist,
231  const TeamSpec_t &teamspec,
234  : _distspec(std::move(dist))
235  , _team(&team)
236  , _teamspec(teamspec, _distspec, *_team)
237  , _nunits(_teamspec.size())
238  , _memory_layout(sizespec.extents())
239  , _blocksize_spec(
240  initialize_blocksizespec(sizespec, _distspec, _teamspec))
241  , _blockspec(initialize_blockspec(sizespec, _distspec, _blocksize_spec))
242  , _local_memory_layout(initialize_local_extents(_team->myid()))
243  , _local_blockspec(
244  initialize_local_blockspec(_blocksize_spec, _local_memory_layout))
245  , _local_capacity(initialize_local_capacity())
246  {
247  DASH_LOG_TRACE("BlockPattern()", "(sizespec, dist, teamspec, team)");
248  initialize_local_range();
249  DASH_LOG_TRACE("BlockPattern()", "BlockPattern initialized");
250  }
251 
288  const SizeSpec_t &sizespec,
292  DistributionSpec_t dist = DistributionSpec_t(),
295  : _distspec(std::move(dist))
296  , _team(&team)
297  , _teamspec(_distspec, *_team)
298  , _nunits(_teamspec.size())
299  , _memory_layout(sizespec.extents())
300  , _blocksize_spec(
301  initialize_blocksizespec(sizespec, _distspec, _teamspec))
302  , _blockspec(initialize_blockspec(sizespec, _distspec, _blocksize_spec))
303  , _local_memory_layout(initialize_local_extents(_team->myid()))
304  , _local_blockspec(
305  initialize_local_blockspec(_blocksize_spec, _local_memory_layout))
306  , _local_capacity(initialize_local_capacity())
307  {
308  DASH_LOG_TRACE("BlockPattern()", "(sizespec, dist, team)");
309  initialize_local_range();
310  DASH_LOG_TRACE("BlockPattern()", "BlockPattern initialized");
311  }
312 
316  BlockPattern(const self_t & other)
317  : _distspec(other._distspec),
318  _team(other._team),
319  _teamspec(other._teamspec),
320  _nunits(other._nunits),
321  _memory_layout(other._memory_layout),
322  _blocksize_spec(other._blocksize_spec),
323  _blockspec(other._blockspec),
324  _local_memory_layout(other._local_memory_layout),
325  _local_blockspec(other._local_blockspec),
326  _local_capacity(other._local_capacity),
327  _lbegin(other._lbegin),
328  _lend(other._lend)
329  {
330  // No need to copy _arguments as it is just used to
331  // initialize other members.
332  DASH_LOG_TRACE("BlockPattern(other)", "BlockPattern copied");
333  }
334 
341  BlockPattern(self_t & other)
342  : BlockPattern(static_cast<const self_t &>(other))
343  { }
344 
350  const self_t & other) const
351  {
352  if (this == &other) {
353  return true;
354  }
355  // no need to compare all members as most are derived from
356  // constructor arguments.
357  return(
358  _distspec == other._distspec &&
359  _teamspec == other._teamspec &&
360  _memory_layout == other._memory_layout &&
361  _blockspec == other._blockspec &&
362  _blocksize_spec == other._blocksize_spec &&
363  _nunits == other._nunits
364  );
365  }
366 
372  const self_t & other) const
373  {
374  return !(*this == other);
375  }
376 
381  {
382  DASH_LOG_TRACE("BlockPattern.=(other)");
383  if (this != &other) {
384  _distspec = other._distspec;
385  _team = other._team;
386  _teamspec = other._teamspec;
387  _memory_layout = other._memory_layout;
388  _local_memory_layout = other._local_memory_layout;
389  _blocksize_spec = other._blocksize_spec;
390  _blockspec = other._blockspec;
391  _local_blockspec = other._local_blockspec;
392  _local_capacity = other._local_capacity;
393  _nunits = other._nunits;
394  _lbegin = other._lbegin;
395  _lend = other._lend;
396  DASH_LOG_TRACE("BlockPattern.=(other)", "BlockPattern assigned");
397  }
398  return *this;
399  }
400 
406  IndexType lbegin() const
407  {
408  return _lbegin;
409  }
410 
416  IndexType lend() const
417  {
418  return _lend;
419  }
420 
424 
432  const std::array<IndexType, NumDimensions> & coords,
434  const ViewSpec_t & viewspec) const
435  {
436  // Apply viewspec offsets to coordinates:
437  std::array<IndexType, NumDimensions> vs_coords;
438  for (auto d = 0; d < NumDimensions; ++d) {
439  vs_coords[d] = coords[d] + viewspec.offset(0);
440  }
441  return unit_at(vs_coords);
442  }
443 
450  const std::array<IndexType, NumDimensions> & coords) const
451  {
452  std::array<IndexType, NumDimensions> unit_coords{};
453  // Coord to block coord to unit coord:
454  for (auto d = 0; d < NumDimensions; ++d) {
455  unit_coords[d] = (coords[d] / _blocksize_spec.extent(d))
456  % _teamspec.extent(d);
457  }
458  // Unit coord to unit id:
459  team_unit_t unit_id(_teamspec.at(unit_coords));
460  DASH_LOG_TRACE("BlockPattern.unit_at",
461  "coords", coords,
462  "> unit id", unit_id);
463  return unit_id;
464  }
465 
473  IndexType global_pos,
475  const ViewSpec_t & viewspec) const
476  {
477  auto global_coords = _memory_layout.coords(global_pos);
478  return unit_at(global_coords, viewspec);
479  }
480 
492  IndexType global_pos) const
493  {
494  auto global_coords = _memory_layout.coords(global_pos);
495  return unit_at(global_coords);
496  }
497 
501 
511  IndexType extent(dim_t dim) const
512  {
513  if (dim >= NumDimensions || dim < 0) {
514  DASH_THROW(
516  "Wrong dimension for Pattern::local_extent. "
517  << "Expected dimension between 0 and " << NumDimensions-1 << ", "
518  << "got " << dim);
519  }
520  return _memory_layout.extent(dim);
521  }
522 
534  IndexType local_extent(dim_t dim) const
535  {
536  if (dim >= NumDimensions || dim < 0) {
537  DASH_THROW(
539  "Wrong dimension for Pattern::local_extent. "
540  << "Expected dimension between 0 and " << NumDimensions-1 << ", "
541  << "got " << dim);
542  }
543  return _local_memory_layout.extent(dim);
544  }
545 
557  constexpr std::array<SizeType, NumDimensions> local_extents() const noexcept
558  {
559  return _local_memory_layout.extents();
560  }
561 
573  constexpr std::array<SizeType, NumDimensions> local_extents(
574  team_unit_t unit) const noexcept
575  {
576  return ( unit == _team->myid()
577  ? _local_memory_layout.extents()
578  : initialize_local_extents(unit)
579  );
580  }
581 
585 
592  IndexType local_at(
594  const std::array<IndexType, NumDimensions> & local_coords,
596  const ViewSpec_t & viewspec) const
597  {
598  auto coords = local_coords;
599  for (auto d = 0; d < NumDimensions; ++d) {
600  coords[d] += viewspec.offset(d);
601  }
602  return _local_memory_layout.at(coords);
603  }
604 
610  constexpr IndexType local_at(
612  const std::array<IndexType, NumDimensions> & local_coords) const
613  {
614  return _local_memory_layout.at(local_coords);
615  }
616 
625  local_coords_t local(
626  const std::array<IndexType, NumDimensions> & global_coords) const
627  {
628  local_coords_t l_coords;
629  l_coords.coords = local_coords(global_coords);
630  l_coords.unit = unit_at(global_coords);
631  return l_coords;
632  }
633 
641  local_index_t local(
642  IndexType g_index) const
643  {
644  DASH_LOG_TRACE_VAR("BlockPattern.local()", g_index);
645  // TODO: Implement dedicated method for this, conversion to/from
646  // global coordinates is expensive.
647  auto l_coords = coords(g_index);
648  return local_index(l_coords);
649  }
650 
657  std::array<IndexType, NumDimensions> local_coords(
658  const std::array<IndexType, NumDimensions> & global_coords) const
659  {
660  std::array<IndexType, NumDimensions> local_coords{};
661  for (auto d = 0; d < NumDimensions; ++d) {
662  auto block_size_d = _blocksize_spec.extent(d);
663  auto b_offset_d = global_coords[d] % block_size_d;
664  auto g_block_offset_d = global_coords[d] / block_size_d;
665  auto l_block_offset_d = g_block_offset_d / _teamspec.extent(d);
666  local_coords[d] = b_offset_d +
667  (l_block_offset_d * block_size_d);
668  }
669  return local_coords;
670  }
671 
677  local_index_t local_index(
678  const std::array<IndexType, NumDimensions> & global_coords) const
679  {
680  DASH_LOG_TRACE_VAR("BlockPattern.local_index()", global_coords);
681  auto unit = unit_at(global_coords);
682  DASH_LOG_TRACE_VAR("BlockPattern.local_index", unit);
683  // Global coords to local coords:
684  std::array<IndexType, NumDimensions> l_coords =
685  local_coords(global_coords);
686  DASH_LOG_TRACE_VAR("BlockPattern.local_index", l_coords);
687  if (unit == _team->myid()) {
688  // Coords are local to this unit, use pre-generated local memory
689  // layout
690  return local_index_t { unit, _local_memory_layout.at(l_coords) };
691  } else {
692  // Cannot use _local_memory_layout as it is only defined for the
693  // active unit but does not specify local memory of other units.
694  // Generate local memory layout for unit assigned to coords:
695  auto l_mem_layout =
696  LocalMemoryLayout_t(initialize_local_extents(unit));
697  return local_index_t { unit, l_mem_layout.at(l_coords) };
698  }
699  }
700 
704 
710  std::array<IndexType, NumDimensions> global(
711  team_unit_t unit,
712  const std::array<IndexType, NumDimensions> & local_coords) const
713  {
714  DASH_LOG_DEBUG_VAR("BlockPattern.global()", local_coords);
715  if (_teamspec.size() < 2) {
716  return local_coords;
717  }
718  // Coordinates of the unit within the team spec:
719  std::array<IndexType, NumDimensions> unit_ts_coord =
720  _teamspec.coords(unit);
721  // Index of the element:
722  std::array<IndexType, NumDimensions> glob_index{};
723  for (auto d = 0; d < NumDimensions; ++d) {
724  const Distribution & dist = _distspec[d];
725  auto num_units_d = _teamspec.extent(d);
726  auto blocksize_d = _blocksize_spec.extent(d);
727  auto local_index_d = local_coords[d];
728  // TOOD: Use % (blocksize_d - underfill_d)
729  auto elem_block_offset_d = local_index_d % blocksize_d;
730  // Global coords of the element's block within all blocks:
731  auto block_index_d = dist.local_index_to_block_coord(
732  unit_ts_coord[d], // unit ts offset in d
733  local_index_d,
734  num_units_d
735  );
736  glob_index[d] = (block_index_d * blocksize_d) + elem_block_offset_d;
737  }
738  DASH_LOG_DEBUG_VAR("BlockPattern.global >", glob_index);
739  return glob_index;
740  }
741 
747  std::array<IndexType, NumDimensions> global(
748  const std::array<IndexType, NumDimensions> & local_coords) const
749  {
750  return global(_team->myid(), local_coords);
751  }
752 
761  IndexType global(
762  IndexType local_index) const
763  {
764  std::array<IndexType, NumDimensions> local_coords =
765  _local_memory_layout.coords(local_index);
766  DASH_LOG_TRACE_VAR("BlockPattern.local_to_global_idx()", local_coords);
767  std::array<IndexType, NumDimensions> global_coords =
768  global(_team->myid(), local_coords);
769  DASH_LOG_TRACE_VAR("BlockPattern.local_to_global_idx >", global_coords);
770  return _memory_layout.at(global_coords);
771  }
772 
781  IndexType global_index(
782  team_unit_t unit,
783  const std::array<IndexType, NumDimensions> & local_coords) const
784  {
785  std::array<IndexType, NumDimensions> global_coords =
786  global(unit, local_coords);
787  DASH_LOG_TRACE_VAR("BlockPattern.local_to_global_idx", global_coords);
788  return _memory_layout.at(global_coords);
789  }
790 
800  IndexType global_at(
801  const std::array<IndexType, NumDimensions> & view_coords,
802  const ViewSpec_t & viewspec) const
803  {
804  DASH_LOG_TRACE("BlockPattern.global_at()",
805  "view coords:",view_coords,
806  "view:", viewspec);
807  // Global coordinates of the element referenced in the view:
808  std::array<IndexType, NumDimensions> global_coords{};
809  for (auto d = 0; d < NumDimensions; ++d) {
810  global_coords[d] = view_coords[d] + viewspec.offset(d);
811  }
812  DASH_LOG_TRACE("BlockPattern.global_at",
813  "global coords:", global_coords);
814  // Offset in iteration order is identical to offset in canonical order:
815  auto offset = _memory_layout.at(global_coords);
816  DASH_LOG_TRACE_VAR("BlockPattern.global_at >", offset);
817  return offset;
818  }
819 
832  IndexType global_at(
833  const std::array<IndexType, NumDimensions> & global_coords) const
834  {
835  DASH_LOG_TRACE("BlockPattern.global_at()",
836  "gcoords:", global_coords);
837  // Offset in iteration order is identical to offset in canonical order:
838  auto offset = _memory_layout.at(global_coords);
839  DASH_LOG_TRACE_VAR("BlockPattern.global_at >", offset);
840  return offset;
841  }
842 
846 
855  IndexType at(
856  const std::array<IndexType, NumDimensions> & global_coords) const
857  {
858  auto unit = unit_at(global_coords);
859  // Global coords to local coords:
860  std::array<IndexType, NumDimensions> l_coords =
861  local_coords(global_coords);
862  DASH_LOG_TRACE_VAR("BlockPattern.at", l_coords);
863  if (unit == _team->myid()) {
864  // Coords are local to this unit, use pre-generated local memory
865  // layout
866  return _local_memory_layout.at(l_coords);
867  } else {
868  // Cannot use _local_memory_layout as it is only defined for the
869  // active unit but does not specify local memory of other units.
870  // Generate local memory layout for unit assigned to coords:
871  auto l_mem_layout =
872  LocalMemoryLayout_t(initialize_local_extents(unit));
873  return l_mem_layout.at(l_coords);
874  }
875  }
876 
884  IndexType at(
885  const std::array<IndexType, NumDimensions> & global_coords,
886  const ViewSpec_t & viewspec) const
887  {
888  auto coords = global_coords;
889  for (auto d = 0; d < NumDimensions; ++d) {
890  coords[d] += viewspec.offset(d);
891  }
892  DASH_LOG_TRACE_VAR("BlockPattern.at()", coords);
893  DASH_LOG_TRACE_VAR("BlockPattern.at()", viewspec);
894  return at(coords);
895  }
896 
904  template<typename ... Values>
905  IndexType at(IndexType value, Values ... values) const
906  {
907  static_assert(
908  sizeof...(values) == NumDimensions-1,
909  "Wrong parameter number");
910  std::array<IndexType, NumDimensions> inputindex = {
911  value, (IndexType)values...
912  };
913  return at(inputindex);
914  }
915 
919 
928  dim_t dim,
930  IndexType dim_offset,
932  team_unit_t unit,
934  const ViewSpec_t & viewspec) const
935  {
936  DASH_LOG_TRACE_VAR("BlockPattern.has_local_elements()", dim);
937  DASH_LOG_TRACE_VAR("BlockPattern.has_local_elements()", dim_offset);
938  DASH_LOG_TRACE_VAR("BlockPattern.has_local_elements()", unit);
939  // Apply viewspec offset in dimension to given position
940  dim_offset += viewspec.offset(dim);
941  // Offset to block offset
942  IndexType block_coord_d = dim_offset / _blocksize_spec.extent(dim);
943  DASH_LOG_TRACE_VAR("BlockPattern.has_local_elements", block_coord_d);
944  // Coordinate of unit in team spec in given dimension
945  IndexType teamspec_coord_d = block_coord_d % _teamspec.extent(dim);
946  DASH_LOG_TRACE_VAR("BlockPattern.has_local_elements()",
947  teamspec_coord_d);
948  // Check if unit id lies in cartesian sub-space of team spec
949  return _teamspec.includes_index(
950  teamspec_coord_d,
951  dim,
952  dim_offset);
953  }
954 
960  bool is_local(
961  IndexType index,
962  team_unit_t unit) const
963  {
964  auto glob_coords = coords(index);
965  auto coords_unit = unit_at(glob_coords);
966  DASH_LOG_TRACE_VAR("BlockPattern.is_local >", (coords_unit == unit));
967  return coords_unit == unit;
968  }
969 
976  constexpr bool is_local(
977  IndexType index) const noexcept
978  {
979  return is_local(index, team().myid());
980  }
981 
985 
989  constexpr const BlockSpec_t & blockspec() const noexcept
990  {
991  return _blockspec;
992  }
993 
997  constexpr const BlockSpec_t & local_blockspec() const noexcept
998  {
999  return _local_blockspec;
1000  }
1001 
1007  index_type block_at(
1009  const std::array<index_type, NumDimensions> & g_coords) const
1010  {
1011  std::array<index_type, NumDimensions> block_coords{};
1012  // Coord to block coord to unit coord:
1013  for (auto d = 0; d < NumDimensions; ++d) {
1014  block_coords[d] = g_coords[d] / _blocksize_spec.extent(d);
1015  }
1016  // Block coord to block index:
1017  auto block_idx = _blockspec.at(block_coords);
1018  DASH_LOG_TRACE("BlockPattern.block_at",
1019  "coords", g_coords,
1020  "> block index", block_idx);
1021  return block_idx;
1022  }
1023 
1029  local_index_t local_block_at(
1031  const std::array<index_type, NumDimensions> & g_coords) const
1032  {
1033  local_index_t l_pos;
1034 
1035  std::array<IndexType, NumDimensions> l_block_coords{};
1036  std::array<IndexType, NumDimensions> unit_ts_coords{};
1037  for (dim_t d = 0; d < NumDimensions; ++d) {
1038  auto nunits_d = _teamspec.extent(d);
1039  auto blocksize_d = _blocksize_spec.extent(d);
1040  auto block_coord_d = g_coords[d] / blocksize_d;
1041  l_block_coords[d] = block_coord_d / nunits_d;
1042  unit_ts_coords[d] = block_coord_d % nunits_d;
1043  }
1044  l_pos.unit = _teamspec.at(unit_ts_coords);
1045  l_pos.index = _local_blockspec.at(l_block_coords);
1046 
1047  DASH_LOG_TRACE("BlockPattern.local_block_at >",
1048  "coords", g_coords,
1049  "unit:", l_pos.unit,
1050  "local block index:", l_pos.index);
1051  return l_pos;
1052  }
1053 
1058  ViewSpec_t block(
1059  index_type global_block_index) const
1060  {
1061  // block index -> block coords -> offset
1062  auto block_coords = _blockspec.coords(global_block_index);
1063  std::array<index_type, NumDimensions> offsets{};
1064  std::array<size_type, NumDimensions> extents{};
1065 
1066  for (auto d = 0; d < NumDimensions; ++d) {
1067  auto num_blocks_d = _blockspec.extent(d);
1068  extents[d] = _blocksize_spec.extent(d);
1069  if(block_coords[d] == (num_blocks_d - 1)){
1070  extents[d] -= underfilled_blocksize(d);
1071  }
1072  offsets[d] = block_coords[d] * _blocksize_spec.extent(d);
1073  }
1074  return ViewSpec_t(offsets, extents);
1075  }
1076 
1081  ViewSpec_t local_block(
1082  index_type local_block_index) const
1083  {
1084  // Initialize viewspec result with block extents:
1085  std::array<SizeType, NumDimensions> block_vs_extents =
1086  _blocksize_spec.extents();
1087  std::array<IndexType, NumDimensions> block_vs_offsets {{ }};
1088  // Local block index to local block coords:
1089  auto l_block_coords = _local_blockspec.coords(local_block_index);
1090  auto l_elem_coords = l_block_coords;
1091  // TODO: This is convenient but less efficient:
1092  // Translate local coordinates of first element in local block to global
1093  // coordinates:
1094  for (auto d = 0; d < NumDimensions; ++d) {
1095  auto num_blocks_d =_local_blockspec.extent(d);
1096  if(l_block_coords[d] == (num_blocks_d - 1)){
1097  size_type remaining = local_extent(d) % block_vs_extents[d];
1098  block_vs_extents[d] = (remaining == 0)
1099  ? block_vs_extents[d]
1100  : remaining;
1101  // to calculate offset, extent of fully filled blocks are needed
1102  l_elem_coords[d] *= _blocksize_spec.extent(d);
1103  } else {
1104  l_elem_coords[d] *= block_vs_extents[d];
1105  }
1106  }
1107  // Global coordinates of first element in block:
1108  auto g_elem_coords = global(l_elem_coords);
1109  for (auto d = 0; d < NumDimensions; ++d) {
1110  block_vs_offsets[d] = g_elem_coords[d];
1111  }
1112 #ifdef __TODO__
1113  // Coordinates of the unit within the team spec:
1114  std::array<IndexType, NumDimensions> unit_ts_coord =
1115  _teamspec.coords(unit);
1116  for (auto d = 0; d < NumDimensions; ++d) {
1117  const Distribution & dist = _distspec[d];
1118  auto blocksize_d = block_vs_extents[d];
1119  auto num_units_d = _teamspec.extent(d);
1120  auto num_blocks_d = _blockspec.extent(d);
1121  // Local to global block coords:
1122  auto g_block_coord_d = (l_block_coords[d] + _myid) *
1123  _teamspec.extent(d);
1124  block_vs_offsets[d] = g_block_coord_d * blocksize_d;
1125  }
1126 #endif
1127  ViewSpec_t block_vs(block_vs_offsets, block_vs_extents);
1128  return block_vs;
1129  }
1130 
1135  ViewSpec_t local_block_local(
1136  index_type local_block_index) const
1137  {
1138  // Local block index to local block coords:
1139  auto l_block_coords = _local_blockspec.coords(local_block_index);
1140  std::array<index_type, NumDimensions> offsets;
1141  std::array<size_type, NumDimensions> extents = _blocksize_spec.extents();
1142  // last block in at least one dimension
1143  for(dim_t d=0; d<NumDimensions; ++d){
1144  if(l_block_coords[d] == (_local_blockspec.extent(d)-1)){
1145  size_type remaining = local_extent(d) % extents[d];
1146  extents[d] = (remaining == 0) ? extents[d] : remaining;
1147  // to calculate offset, extent of fully filled blocks are needed
1148  offsets[d] = l_block_coords[d] * _blocksize_spec.extent(d);
1149  } else {
1150  offsets[d] = l_block_coords[d] * extents[d];
1151  }
1152  }
1153  return ViewSpec_t(offsets, extents);
1154  }
1155 
1163  constexpr SizeType blocksize(
1165  dim_t dimension) const noexcept
1166  {
1167  return _blocksize_spec.extent(dimension);
1168  }
1169 
1178  constexpr SizeType max_blocksize() const noexcept
1179  {
1180  return _blocksize_spec.size();
1181  }
1182 
1189  constexpr SizeType local_capacity() const noexcept
1190  {
1191  return _local_capacity;
1192  }
1193 
1204  constexpr SizeType local_size(
1205  team_unit_t unit = UNDEFINED_TEAM_UNIT_ID) const noexcept
1206  {
1207  return (unit == UNDEFINED_TEAM_UNIT_ID)
1208  ? _local_memory_layout.size()
1209  : initialize_local_extents(unit).size();
1210  }
1211 
1217  constexpr IndexType num_units() const noexcept
1218  {
1219  return _nunits;
1220  }
1221 
1227  constexpr IndexType capacity() const noexcept
1228  {
1229  return _memory_layout.size();
1230  }
1231 
1237  constexpr IndexType size() const noexcept
1238  {
1239  return _memory_layout.size();
1240  }
1241 
1246  constexpr dash::Team & team() const noexcept
1247  {
1248  return *_team;
1249  }
1250 
1254  constexpr const DistributionSpec_t & distspec() const noexcept
1255  {
1256  return _distspec;
1257  }
1258 
1264  constexpr SizeSpec_t sizespec() const noexcept
1265  {
1266  return SizeSpec_t(_memory_layout.extents());
1267  }
1268 
1274  constexpr const std::array<SizeType, NumDimensions> &
1275  extents() const noexcept
1276  {
1277  return _memory_layout.extents();
1278  }
1279 
1286  constexpr const TeamSpec_t & teamspec() const noexcept
1287  {
1288  return _teamspec;
1289  }
1290 
1297  constexpr std::array<IndexType, NumDimensions> coords(
1298  IndexType index) const noexcept
1299  {
1300  return _memory_layout.coords(index);
1301  }
1302 
1309  constexpr std::array<IndexType, NumDimensions> coords(
1311  IndexType index,
1313  const ViewSpec_t & viewspec) const noexcept
1314  {
1315  return _memory_layout.coords(index, viewspec);
1316  }
1317 
1321  constexpr static MemArrange memory_order() noexcept
1322  {
1323  return Arrangement;
1324  }
1325 
1329  constexpr static dim_t ndim() noexcept
1330  {
1331  return NumDimensions;
1332  }
1333 
1340  dim_t dimension) const
1341  {
1342  // Underflow blocksize = regular blocksize - overflow blocksize:
1343  auto ovf_blocksize = _memory_layout.extent(dimension) %
1344  blocksize(dimension);
1345  if (ovf_blocksize == 0) {
1346  return 0;
1347  } else {
1348  auto reg_blocksize = blocksize(dimension);
1349  return reg_blocksize - ovf_blocksize;
1350  }
1351  }
1352 
1353 private:
1354 
1355  BlockPattern(const PatternArguments_t & arguments)
1356  : _distspec(arguments.distspec()),
1357  _team(&arguments.team()),
1358  _teamspec(arguments.teamspec()),
1359  _nunits(_teamspec.size()),
1360  _memory_layout(arguments.sizespec().extents()),
1361  _blocksize_spec(initialize_blocksizespec(
1362  arguments.sizespec(),
1363  _distspec,
1364  _teamspec)),
1365  _blockspec(initialize_blockspec(
1366  arguments.sizespec(),
1367  _distspec,
1368  _blocksize_spec)),
1369  _local_memory_layout(
1370  initialize_local_extents(_team->myid())),
1371  _local_blockspec(initialize_local_blockspec(
1372  _blocksize_spec,
1373  _local_memory_layout)),
1374  _local_capacity(initialize_local_capacity())
1375  {}
1376 
1381  BlockSizeSpec_t initialize_blocksizespec(
1382  const SizeSpec_t & sizespec,
1383  const DistributionSpec_t & distspec,
1384  const TeamSpec_t & teamspec) const
1385  {
1386  DASH_LOG_TRACE_VAR("BlockPattern.init_blocksizespec", teamspec.size());
1387  if (teamspec.size() == 0) {
1388  return BlockSizeSpec_t();
1389  }
1390  // Extents of a single block:
1391  std::array<SizeType, NumDimensions> s_blocks{};
1392  for (auto d = 0; d < NumDimensions; ++d) {
1393  const Distribution & dist = distspec[d];
1394  SizeType max_blocksize_d = dist.max_blocksize_in_range(
1395  sizespec.extent(d), // size of range (extent)
1396  teamspec.extent(d)); // number of blocks (units)
1397  s_blocks[d] = max_blocksize_d;
1398  }
1399  return BlockSizeSpec_t(s_blocks);
1400  }
1401 
1406  BlockSpec_t initialize_blockspec(
1407  const SizeSpec_t & sizespec,
1408  const DistributionSpec_t & distspec,
1409  const BlockSizeSpec_t & blocksizespec) const
1410  {
1411  if (blocksizespec.size() == 0) {
1412  return BlockSpec_t();
1413  }
1414  // Number of blocks in all dimensions:
1415  std::array<SizeType, NumDimensions> n_blocks{};
1416  for (auto d = 0; d < NumDimensions; ++d) {
1417  DASH_LOG_TRACE_VAR("BlockPattern.init_blockspec", distspec[d].type);
1418  SizeType max_blocksize_d = blocksizespec.extent(d);
1419  SizeType max_blocks_d = dash::math::div_ceil(
1420  sizespec.extent(d),
1421  max_blocksize_d);
1422  n_blocks[d] = max_blocks_d;
1423  }
1424  DASH_LOG_TRACE_VAR("BlockPattern.init_blockspec", n_blocks);
1425  return BlockSpec_t(n_blocks);
1426  }
1427 
1431  BlockSpec_t initialize_local_blockspec(
1432  const BlockSizeSpec_t & blocksizespec,
1433  const LocalMemoryLayout_t & local_mem_layout) const
1434  {
1435  auto num_l_blocks = local_mem_layout.extents();
1436  for (auto d = 0; d < NumDimensions; ++d) {
1437  auto blocksize_d = blocksizespec.extent(d);
1438  if (blocksize_d > 0) {
1439  num_l_blocks[d] = dash::math::div_ceil(
1440  num_l_blocks[d],
1441  blocksizespec.extent(d));
1442  } else {
1443  num_l_blocks[d] = 0;
1444  }
1445  }
1446  DASH_LOG_TRACE_VAR("BlockPattern.init_local_blockspec", num_l_blocks);
1447  return BlockSpec_t(num_l_blocks);
1448  }
1449 
1457  SizeType initialize_local_capacity() const
1458  {
1459  SizeType l_capacity = 1;
1460  if (_teamspec.size() == 0) {
1461  return 0;
1462  }
1463  for (auto d = 0; d < NumDimensions; ++d) {
1464  auto num_units_d = _teamspec.extent(d);
1465  // Maximum number of occurrences of a single unit in given
1466  // dimension:
1467  auto num_blocks_d = dash::math::div_ceil(
1468  _memory_layout.extent(d),
1469  _blocksize_spec.extent(d));
1470  auto max_l_blocks_d = dash::math::div_ceil(
1471  num_blocks_d,
1472  num_units_d);
1473  DASH_LOG_TRACE_VAR("BlockPattern.init_lcapacity.d", d);
1474  DASH_LOG_TRACE_VAR("BlockPattern.init_lcapacity.d", num_units_d);
1475  DASH_LOG_TRACE_VAR("BlockPattern.init_lcapacity.d", max_l_blocks_d);
1476  l_capacity *= max_l_blocks_d;
1477  }
1478  l_capacity *= _blocksize_spec.size();;
1479  DASH_LOG_DEBUG_VAR("BlockPattern.init_lcapacity >", l_capacity);
1480  return l_capacity;
1481  }
1482 
1487  void initialize_local_range()
1488  {
1489  auto l_size = _local_memory_layout.size();
1490  DASH_LOG_DEBUG_VAR("BlockPattern.init_local_range()", l_size);
1491  if (l_size == 0) {
1492  _lbegin = 0;
1493  _lend = 0;
1494  } else {
1495  // First local index transformed to global index
1496  _lbegin = global(0);
1497  // Index past last local index transformed to global index
1498  _lend = global(l_size - 1) + 1;
1499  }
1500  DASH_LOG_DEBUG_VAR("BlockPattern.init_local_range >", _lbegin);
1501  DASH_LOG_DEBUG_VAR("BlockPattern.init_local_range >", _lend);
1502  }
1503 
1507  std::array<SizeType, NumDimensions> initialize_local_extents(
1508  team_unit_t unit) const
1509  {
1510  DASH_LOG_DEBUG_VAR("BlockPattern.init_local_extents()", unit);
1511  DASH_LOG_DEBUG_VAR("BlockPattern.init_local_extents()", _nunits);
1512  if (_nunits == 0) {
1513  return ::std::array<SizeType, NumDimensions> {{ }};
1514  }
1515  // Coordinates of local unit id in team spec:
1516  auto unit_ts_coords = _teamspec.coords(unit);
1517  DASH_LOG_TRACE_VAR("BlockPattern.init_local_extents", unit_ts_coords);
1518  ::std::array<SizeType, NumDimensions> l_extents{};
1519  for (auto d = 0; d < NumDimensions; ++d) {
1520  auto num_elem_d = _memory_layout.extent(d);
1521  // Number of units in dimension:
1522  auto num_units_d = _teamspec.extent(d);
1523  // Number of blocks in dimension:
1524  auto num_blocks_d = _blockspec.extent(d);
1525  // Maximum extent of single block in dimension:
1526  auto blocksize_d = _blocksize_spec.extent(d);
1527  // Minimum number of blocks local to every unit in dimension:
1528  auto min_local_blocks_d = num_blocks_d / num_units_d;
1529  // Coordinate of this unit id in teamspec in dimension:
1530  auto unit_ts_coord = unit_ts_coords[d];
1531  DASH_LOG_TRACE_VAR("BlockPattern.init_local_extents.d", d);
1532  DASH_LOG_TRACE_VAR("BlockPattern.init_local_extents.d", unit_ts_coord);
1533  DASH_LOG_TRACE_VAR("BlockPattern.init_local_extents.d", num_elem_d);
1534  DASH_LOG_TRACE_VAR("BlockPattern.init_local_extents.d", num_units_d);
1535  DASH_LOG_TRACE_VAR("BlockPattern.init_local_extents.d", num_blocks_d);
1536  DASH_LOG_TRACE_VAR("BlockPattern.init_local_extents.d", blocksize_d);
1537  DASH_LOG_TRACE_VAR("BlockPattern.init_local_extents.d",
1538  min_local_blocks_d);
1539  // Possibly there are more blocks than units in dimension and no
1540  // block left for this unit. Local extent in d then becomes 0.
1541  l_extents[d] = min_local_blocks_d * blocksize_d;
1542  if (num_blocks_d == 1 && num_units_d == 1) {
1543  // One block assigned to one unit, use full extent in dimension:
1544  l_extents[d] = num_elem_d;
1545  } else {
1546  // Number of additional blocks for this unit, if any:
1547  auto num_add_blocks =
1548  static_cast<IndexType>(num_blocks_d % num_units_d);
1549  // Unit id assigned to the last block in dimension:
1550  team_unit_t last_block_unit_d((num_blocks_d % num_units_d == 0)
1551  ? num_units_d - 1
1552  : (num_blocks_d % num_units_d) - 1);
1553  DASH_LOG_TRACE_VAR("BlockPattern.init_local_extents.d",
1554  last_block_unit_d);
1555  DASH_LOG_TRACE_VAR("BlockPattern.init_local_extents.d", num_add_blocks);
1556  if (unit_ts_coord < num_add_blocks) {
1557  // Unit is assigned to an additional block:
1558  l_extents[d] += blocksize_d;
1559  DASH_LOG_TRACE_VAR("BlockPattern.init_local_extents.d", l_extents[d]);
1560  }
1561  if (unit_ts_coord == last_block_unit_d) {
1562  // If the last block in the dimension is underfilled and
1563  // assigned to the local unit, subtract the missing extent:
1564  SizeType undfill_blocksize_d = underfilled_blocksize(d);
1565  DASH_LOG_TRACE_VAR("BlockPattern.init_local_extents",
1566  undfill_blocksize_d);
1567  l_extents[d] -= undfill_blocksize_d;
1568  }
1569  }
1570  DASH_LOG_TRACE_VAR("BlockPattern.init_local_extents.d", l_extents[d]);
1571  }
1572  DASH_LOG_DEBUG_VAR("BlockPattern.init_local_extents >", l_extents);
1573  return l_extents;
1574  }
1575 };
1576 
1577 } // namespace dash
1578 
1579 #include <dash/pattern/BlockPattern1D.h>
1580 
1581 #endif // DASH__BLOCK_PATTERN_H_
bool operator==(const self_t &other) const
Equality comparison operator.
Definition: BlockPattern.h:348
constexpr team_unit_t UNDEFINED_TEAM_UNIT_ID
Invalid local unit ID.
Definition: Types.h:341
All blocks have identical size.
IndexType global(IndexType local_index) const
Resolve an element&#39;s linear global index from the calling unit&#39;s local index of that element...
Definition: BlockPattern.h:761
bool includes_index(IndexType index, dim_t dimension, IndexType dim_offset) const
Whether the given index lies in the cartesian sub-space specified by a dimension and offset in the di...
Definition: TeamSpec.h:385
constexpr std::array< SizeType, NumDimensions > local_extents() const noexcept
The actual number of elements in this pattern that are local to the active unit, by dimension...
Definition: BlockPattern.h:557
global_unit_t myid()
Shortcut to query the global unit ID of the calling unit.
constexpr IndexType capacity() const noexcept
The maximum number of elements arranged in this pattern.
local_index_t local_block_at(const std::array< index_type, NumDimensions > &g_coords) const
Unit and local block index at given global coordinates.
constexpr std::enable_if< std::is_integral< IndexType >::value, IndexType >::type index(IndexType idx)
Definition: Iterator.h:60
Defines how a list of global indices is mapped to single units within a Team.
Definition: BlockPattern.h:42
constexpr SizeType blocksize(dim_t dimension) const noexcept
Maximum number of elements in a single block in the given dimension.
constexpr const DistributionSpec_t & distspec() const noexcept
Distribution specification of this pattern.
This class is a simple memory pool which holds allocates elements of size ValueType.
Definition: AllOf.h:8
Local element order corresponds to a logical linearization within single blocks (if blocked) or withi...
BlockPattern(SizeType arg, Args &&... args)
Constructor, initializes a pattern from an argument list consisting of the pattern size (extent...
Definition: BlockPattern.h:180
Specifies cartesian extents in a specific number of dimensions.
Definition: Cartesian.h:197
IndexType at(IndexType value, Values ... values) const
Global coordinates to local index.
Definition: BlockPattern.h:905
Specifies view parameters for implementing submat, rows and cols.
Definition: Dimensional.h:430
IndexType global_at(const std::array< IndexType, NumDimensions > &view_coords, const ViewSpec_t &viewspec) const
Global coordinates and viewspec to global position in the pattern&#39;s iteration order.
Definition: BlockPattern.h:800
int dim_t
Scalar type for a dimension value, with 0 indicating the first dimension.
Definition: Types.h:39
std::array< IndexType, NumDimensions > global(const std::array< IndexType, NumDimensions > &local_coords) const
Converts local coordinates of active unit to global coordinates.
Definition: BlockPattern.h:747
constexpr SizeType max_blocksize() const noexcept
Maximum number of elements in a single block in all dimensions.
bool operator!=(const self_t &other) const
Inquality comparison operator.
Definition: BlockPattern.h:370
constexpr const TeamSpec_t & teamspec() const noexcept
Cartesian arrangement of the Team containing the units to which this pattern&#39;s elements are mapped...
pattern_mapping_properties< pattern_mapping_tag::unbalanced > mapping_properties
Satisfiable properties in pattern property category Mapping:
Definition: BlockPattern.h:61
All local indices are mapped to a single logical index domain and thus not indexed blockwise...
constexpr const BlockSpec_t & blockspec() const noexcept
block
Definition: BlockPattern.h:989
std::array< IndexType, NumDimensions > local_coords(const std::array< IndexType, NumDimensions > &global_coords) const
Converts global coordinates to their associated unit&#39;s respective local coordinates.
Definition: BlockPattern.h:657
constexpr SizeType local_capacity() const noexcept
Maximum number of elements assigned to a single unit in total, equivalent to the local capacity of ev...
constexpr IndexType local_at(const std::array< IndexType, NumDimensions > &local_coords) const
Convert given local coordinates to linear local offset (index).
Definition: BlockPattern.h:610
pattern_partitioning_properties< pattern_partitioning_tag::rectangular, pattern_partitioning_tag::balanced, pattern_partitioning_tag::unbalanced > partitioning_properties
Satisfiable properties in pattern property category Partitioning:
Definition: BlockPattern.h:56
local_index_t local_index(const std::array< IndexType, NumDimensions > &global_coords) const
Resolves the unit and the local index from global coordinates.
Definition: BlockPattern.h:677
The number of blocks assigned to units may differ.
IndexType global_index(team_unit_t unit, const std::array< IndexType, NumDimensions > &local_coords) const
Resolve an element&#39;s linear global index from a given unit&#39;s local coordinates of that element...
Definition: BlockPattern.h:781
pattern_layout_properties< pattern_layout_tag::canonical, pattern_layout_tag::linear > layout_properties
Satisfiable properties in pattern property category Layout:
Definition: BlockPattern.h:69
Block extents are constant for every dimension.
SizeType underfilled_blocksize(dim_t dimension) const
Number of elements missing in the overflow block of given dimension compared to the regular blocksize...
std::array< IndexType, NumDimensions > global(team_unit_t unit, const std::array< IndexType, NumDimensions > &local_coords) const
global
Definition: BlockPattern.h:710
local_coords_t local(const std::array< IndexType, NumDimensions > &global_coords) const
Converts global coordinates to their associated unit and its respective local coordinates.
Definition: BlockPattern.h:625
team_unit_t unit_at(IndexType global_pos) const
Convert given global linear index to its assigned unit id.
Definition: BlockPattern.h:490
constexpr SizeType local_size(team_unit_t unit=UNDEFINED_TEAM_UNIT_ID) const noexcept
The actual number of elements in this pattern that are local to the calling unit in total...
bool is_local(IndexType index, team_unit_t unit) const
Whether the given global index is local to the specified unit.
Definition: BlockPattern.h:960
internal::default_signed_index default_index_t
Signed integer type used as default for index values.
Definition: Types.h:59
A Team instance specifies a subset of all available units.
Definition: Team.h:41
static constexpr dim_t ndim() noexcept
Number of dimensions of the cartesian space partitioned by the pattern.
ViewSpec_t local_block(index_type local_block_index) const
View spec (offset and extents) of block at local linear block index in global cartesian element space...
constexpr const extents_type & extents() const noexcept
Extents of the cartesian space, by dimension.
Definition: Cartesian.h:402
constexpr bool is_local(IndexType index) const noexcept
Whether the given global index is local to the unit that created this pattern instance.
Definition: BlockPattern.h:976
team_unit_t unit_at(const std::array< IndexType, NumDimensions > &coords, const ViewSpec_t &viewspec) const
unit_at
Definition: BlockPattern.h:430
constexpr SizeSpec_t sizespec() const noexcept
Size specification of the index space mapped by this pattern.
std::array< IndexType, NumDimensions > coords(IndexType index) const
Convert given linear offset (index) to cartesian coordinates.
Definition: Cartesian.h:497
SizeType extent(dim_t dim) const
The extent of the cartesian space in the given dimension.
Definition: Cartesian.h:412
IndexType local_index_to_block_coord(IndexType unit_teamspec_coord, IndexType local_index, SizeType num_units_in_dim) const
Resolve the block coordinate for a given local index in the distribution&#39;s dimension.
Definition: Distribution.h:63
Defines a cartesian, totally-ordered index space by mapping linear indices to cartesian coordinates d...
Definition: Cartesian.h:239
constexpr std::array< IndexType, NumDimensions > coords(IndexType index, const ViewSpec_t &viewspec) const noexcept
Convert given global linear offset (index) and viewspec to global cartesian coordinates.
constexpr IndexType at(IndexType arg, Args... args) const
Convert the given coordinates to their respective linear index.
Definition: Cartesian.h:429
Specifies how a Pattern distributes elements to units in a specific dimension.
Definition: Distribution.h:24
ViewSpec_t block(index_type global_block_index) const
View spec (offset and extents) of block at global linear block index in cartesian element space...
BlockPattern & operator=(const BlockPattern &other)
Assignment operator.
Definition: BlockPattern.h:380
constexpr IndexType num_units() const noexcept
The number of units to which this pattern&#39;s elements are mapped.
BlockPattern(const SizeSpec_t &sizespec, DistributionSpec_t dist=DistributionSpec_t(), Team &team=dash::Team::All())
Constructor, initializes a pattern from explicit instances of SizeSpec, DistributionSpec and a Team...
Definition: BlockPattern.h:286
bool has_local_elements(dim_t dim, IndexType dim_offset, team_unit_t unit, const ViewSpec_t &viewspec) const
is_local
Definition: BlockPattern.h:926
BlockPattern(const SizeSpec_t &sizespec, DistributionSpec_t dist, const TeamSpec_t &teamspec, dash::Team &team=dash::Team::All())
Constructor, initializes a pattern from explicit instances of SizeSpec, DistributionSpec, TeamSpec and a Team.
Definition: BlockPattern.h:224
constexpr const BlockSpec_t & local_blockspec() const noexcept
Cartesian arrangement of local pattern blocks.
Definition: BlockPattern.h:997
IndexType lbegin() const
Resolves the global index of the first local element in the pattern.
Definition: BlockPattern.h:406
struct dash::unit_id< dash::local_unit, dart_team_unit_t > team_unit_t
Unit ID to use for team-local IDs.
Definition: Types.h:319
constexpr std::array< SizeType, NumDimensions > local_extents(team_unit_t unit) const noexcept
The actual number of elements in this pattern that are local to the given unit, by dimension...
Definition: BlockPattern.h:573
IndexType local_extent(dim_t dim) const
The actual number of elements in this pattern that are local to the calling unit in the given dimensi...
Definition: BlockPattern.h:534
IndexType max_blocksize_in_range(IndexType range, SizeType num_units) const
The maximum size of a single block within an extent for a given total number of units.
Definition: Distribution.h:114
SizeType extent(dim_t dim) const
The extent of the cartesian space in the given dimension.
Definition: Cartesian.h:181
IndexType global_at(const std::array< IndexType, NumDimensions > &global_coords) const
Global coordinates to global position in the pattern&#39;s iteration order.
Definition: BlockPattern.h:832
IndexType local_at(const std::array< IndexType, NumDimensions > &local_coords, const ViewSpec_t &viewspec) const
local
Definition: BlockPattern.h:592
local_index_t local(IndexType g_index) const
Converts global index to its associated unit and respective local index.
Definition: BlockPattern.h:641
IndexType lend() const
Resolves the global index past the last local element in the pattern.
Definition: BlockPattern.h:416
constexpr IndexType size() const noexcept
The number of elements arranged in this pattern.
constexpr SizeType size() const noexcept
The number of discrete elements within the space spanned by the coordinate.
Definition: Cartesian.h:395
static Team & All()
The invariant Team instance containing all available units.
Definition: Team.h:213
see https://en.cppreference.com/w/cpp/feature_test for recommended feature tests
Definition: cstddef.h:8
IndexType at(const std::array< IndexType, NumDimensions > &global_coords) const
at
Definition: BlockPattern.h:855
team_unit_t unit_at(const std::array< IndexType, NumDimensions > &coords) const
Convert given coordinate in pattern to its assigned unit id.
Definition: BlockPattern.h:449
IndexType at(const std::array< IndexType, NumDimensions > &global_coords, const ViewSpec_t &viewspec) const
Global coordinates and viewspec to local index.
Definition: BlockPattern.h:884
index_type block_at(const std::array< index_type, NumDimensions > &g_coords) const
Index of block at given global coordinates.
constexpr const std::array< SizeType, NumDimensions > & extents() const noexcept
Size specification of the index space mapped by this pattern.
constexpr std::array< IndexType, NumDimensions > coords(IndexType index) const noexcept
Convert given global linear offset (index) to global cartesian coordinates.
IndexType extent(dim_t dim) const
extent
Definition: BlockPattern.h:511
constexpr dash::Team & team() const noexcept
The Team containing the units to which this pattern&#39;s elements are mapped.
BlockPattern(const self_t &other)
Copy constructor.
Definition: BlockPattern.h:316
BlockPattern(self_t &other)
Copy constructor using non-const lvalue reference parameter.
Definition: BlockPattern.h:341
DistributionSpec describes distribution patterns of all dimensions,.
Definition: Dimensional.h:222
Generic type of mapping properties of a model satisfying the Pattern concept.
team_unit_t unit_at(IndexType global_pos, const ViewSpec_t &viewspec) const
Convert given global linear index to its assigned unit id.
Definition: BlockPattern.h:471
ViewSpec_t local_block_local(index_type local_block_index) const
View spec (offset and extents) of block at local linear block index in local cartesian element space...
static constexpr MemArrange memory_order() noexcept
Memory order followed by the pattern.