DASH  0.3.0
TilePattern.h
1 #ifndef DASH__TILE_PATTERN_H_
2 #define DASH__TILE_PATTERN_H_
3 
4 #include <functional>
5 #include <cstring>
6 #include <array>
7 #include <type_traits>
8 #include <iostream>
9 #include <sstream>
10 #include <utility>
11 
12 #include <dash/Types.h>
13 #include <dash/Distribution.h>
14 #include <dash/Exception.h>
15 #include <dash/Dimensional.h>
16 #include <dash/Cartesian.h>
17 #include <dash/Team.h>
18 
19 #include <dash/pattern/PatternProperties.h>
20 #include <dash/pattern/internal/PatternArguments.h>
21 
22 #include <dash/internal/Math.h>
23 #include <dash/internal/Logging.h>
24 
25 namespace dash {
26 
43 template<
44  dim_t NumDimensions,
45  MemArrange Arrangement = ROW_MAJOR,
46  typename IndexType = dash::default_index_t>
48 {
49 public:
50  static constexpr char const * PatternName = "TilePattern";
51 
52 public:
55  // Block extents are constant for every dimension.
57  // Identical number of elements in every block.
62  // Same number of blocks assigned to every unit.
64  // Number of blocks assigned to a unit may differ.
69  // Elements are contiguous in local memory within single
70  // block.
72  // Local element order corresponds to a logical
73  // linearization within single blocks.
76 
77 private:
79  typedef typename std::make_unsigned<IndexType>::type
80  SizeType;
83  self_t;
95  TeamSpec_t;
97  SizeSpec_t;
99  ViewSpec_t;
100  typedef internal::PatternArguments<NumDimensions, IndexType>
101  PatternArguments_t;
102 
103 public:
104  typedef IndexType index_type;
105  typedef SizeType size_type;
106  typedef ViewSpec_t viewspec_type;
107  typedef struct {
108  team_unit_t unit;
109  IndexType index{};
110  } local_index_t;
111  typedef struct {
112  team_unit_t unit;
113  std::array<index_type, NumDimensions> coords{};
114  } local_coords_t;
115 
116 private:
120  DistributionSpec_t _distspec;
122  dash::Team * _team = nullptr;
124  team_unit_t _myid;
126  TeamSpec_t _teamspec;
129  MemoryLayout_t _memory_layout;
131  SizeType _nunits = dash::Team::All().size();
133  BlockSizeSpec_t _blocksize_spec;
135  BlockSpec_t _blockspec;
137  BlockSpec_t _local_blockspec;
141  LocalMemoryLayout_t _local_memory_layout;
143  SizeType _local_capacity;
145  IndexType _lbegin;
147  IndexType _lend;
148 
149 public:
184  template<typename ... Args>
189  SizeType arg,
193  Args && ... args)
194  : TilePattern(PatternArguments_t(arg, args...))
195  {
196  DASH_LOG_TRACE("TilePattern()", "Constructor with Argument list");
197  initialize_local_range();
198  }
199 
235  const SizeSpec_t &sizespec,
238  DistributionSpec_t dist,
240  const TeamSpec_t &teamspec,
243  : _distspec(std::move(dist))
244  , _team(&team)
245  , _myid(_team->myid())
246  , _teamspec(teamspec, _distspec, *_team)
247  , _memory_layout(sizespec.extents())
248  , _nunits(_teamspec.size())
249  , _blocksize_spec(
250  initialize_blocksizespec(sizespec, _distspec, _teamspec))
251  , _blockspec(initialize_blockspec(sizespec, _blocksize_spec, _teamspec))
252  , _local_blockspec(
253  initialize_local_blockspec(_blockspec, _blocksize_spec, _teamspec))
254  , _local_memory_layout(initialize_local_extents(_myid))
255  , _local_capacity(initialize_local_capacity(_local_memory_layout))
256  {
257  DASH_LOG_TRACE("TilePattern()", "(sizespec, dist, teamspec, team)");
258  initialize_local_range();
259  }
260 
296  const SizeSpec_t &sizespec,
300  DistributionSpec_t dist = DistributionSpec_t(),
303  : _distspec(std::move(dist))
304  , _team(&team)
305  , _myid(_team->myid())
306  , _teamspec(_distspec, *_team)
307  , _memory_layout(sizespec.extents())
308  , _nunits(_teamspec.size())
309  , _blocksize_spec(
310  initialize_blocksizespec(sizespec, _distspec, _teamspec))
311  , _blockspec(initialize_blockspec(sizespec, _blocksize_spec, _teamspec))
312  , _local_blockspec(
313  initialize_local_blockspec(_blockspec, _blocksize_spec, _teamspec))
314  , _local_memory_layout(initialize_local_extents(_myid))
315  , _local_capacity(initialize_local_capacity(_local_memory_layout))
316  {
317  DASH_LOG_TRACE("TilePattern()", "(sizespec, dist, team)");
318  initialize_local_range();
319  }
320 
324  TilePattern(const self_t & other) = default;
325 
332  TilePattern(self_t & other)
333  : TilePattern(static_cast<const self_t &>(other))
334  { }
335 
339  TilePattern & operator=(const self_t & other) = default;
340 
344  bool operator==(const self_t & other) const
345  {
346  if (this == &other) {
347  return true;
348  }
349  // no need to compare all members as most are derived from
350  // constructor arguments.
351  return(
352  _distspec == other._distspec &&
353  _teamspec == other._teamspec &&
354  _memory_layout == other._memory_layout &&
355  _blockspec == other._blockspec &&
356  _blocksize_spec == other._blocksize_spec &&
357  _nunits == other._nunits
358  );
359  }
360 
364  constexpr bool operator!=(
366  const self_t & other) const
367  {
368  return !(*this == other);
369  }
370 
376  constexpr IndexType lbegin() const {
377  return _lbegin;
378  }
379 
385  constexpr IndexType lend() const {
386  return _lend;
387  }
388 
392 
400  const std::array<IndexType, NumDimensions> & coords,
402  const ViewSpec_t & viewspec) const
403  {
404  DASH_LOG_TRACE("TilePattern.unit_at()",
405  "coords:", coords,
406  "viewspec:", viewspec);
407  std::array<IndexType, NumDimensions> unit_ts_coords{};
408  std::array<IndexType, NumDimensions> block_coords{};
409  // Unit id from diagonals in cartesian index space,
410  // e.g (x + y + z) % nunits
411  for (auto d = 0; d < NumDimensions; ++d) {
412  auto vs_coord = coords[d] + viewspec.offset(d);
413  // Global block coordinate:
414  block_coords[d] = vs_coord / _blocksize_spec.extent(d);
415  unit_ts_coords[d] = block_coords[d] % _teamspec.extent(d);
416  }
417  team_unit_t unit_id(_teamspec.at(unit_ts_coords));
418  DASH_LOG_TRACE_VAR("TilePattern.unit_at", block_coords);
419  DASH_LOG_TRACE_VAR("TilePattern.unit_at", unit_ts_coords);
420  DASH_LOG_TRACE_VAR("TilePattern.unit_at >", unit_id);
421  return unit_id;
422  }
423 
430  const std::array<IndexType, NumDimensions> & coords) const
431  {
432  DASH_LOG_TRACE("TilePattern.unit_at()",
433  "coords:", coords);
434  std::array<IndexType, NumDimensions> unit_ts_coords{};
435  std::array<IndexType, NumDimensions> block_coords{};
436  // Unit id from diagonals in cartesian index space,
437  // e.g (x + y + z) % nunits
438  for (auto d = 0; d < NumDimensions; ++d) {
439  // Global block coordinate:
440  block_coords[d] = coords[d] / _blocksize_spec.extent(d);
441  unit_ts_coords[d] = block_coords[d] % _teamspec.extent(d);
442  }
443  team_unit_t unit_id(_teamspec.at(unit_ts_coords));
444  DASH_LOG_TRACE_VAR("TilePattern.unit_at", block_coords);
445  DASH_LOG_TRACE_VAR("TilePattern.unit_at", unit_ts_coords);
446  DASH_LOG_TRACE_VAR("TilePattern.unit_at >", unit_id);
447  return unit_id;
448  }
449 
457  IndexType global_pos,
459  const ViewSpec_t & viewspec) const
460  {
461  auto global_coords = _memory_layout.coords(global_pos);
462  return unit_at(global_coords, viewspec);
463  }
464 
472  IndexType global_pos) const
473  {
474  auto global_coords = _memory_layout.coords(global_pos);
475  return unit_at(global_coords);
476  }
477 
481 
491  SizeType extent(dim_t dim) const {
492  if (dim >= NumDimensions || dim < 0) {
493  DASH_THROW(
495  "Wrong dimension for TilePattern::local_extent. "
496  << "Expected dimension between 0 and " << NumDimensions-1 << ", "
497  << "got " << dim);
498  }
499  return _memory_layout.extent(dim);
500  }
501 
513  SizeType local_extent(dim_t dim) const
514  {
515  if (dim >= NumDimensions || dim < 0) {
516  DASH_THROW(
518  "Wrong dimension for TilePattern::local_extent. "
519  << "Expected dimension between 0 and " << NumDimensions-1 << ", "
520  << "got " << dim);
521  }
522  return _local_memory_layout.extent(dim);
523  }
524 
536  constexpr std::array<SizeType, NumDimensions> local_extents(
537  team_unit_t unit = UNDEFINED_TEAM_UNIT_ID) const
538  {
539  return ( ( unit == UNDEFINED_TEAM_UNIT_ID ||
540  unit == _myid )
541  ? _local_memory_layout.extents()
542  : initialize_local_extents(unit) );
543  }
544 
548 
555  IndexType local_at(
557  const std::array<IndexType, NumDimensions> & local_coords,
559  const ViewSpec_t & viewspec) const
560  {
561  DASH_LOG_TRACE("TilePattern.local_at()",
562  "local_coords:", local_coords,
563  "view:", viewspec,
564  "local blocks:", _local_blockspec.extents());
565  // Phase coordinates of element:
566  std::array<IndexType, NumDimensions> phase_coords{};
567  // Coordinates of the local block containing the element:
568  std::array<IndexType, NumDimensions> block_coords_l{};
569  for (auto d = 0; d < NumDimensions; ++d) {
570  auto vs_offset_d = viewspec.offset(d);
571  auto vs_coord_d = local_coords[d] + vs_offset_d;
572  auto block_size_d = _blocksize_spec.extent(d);
573  phase_coords[d] = vs_coord_d % block_size_d;
574  block_coords_l[d] = vs_coord_d / block_size_d;
575  }
576  DASH_LOG_TRACE("TilePattern.local_at",
577  "local_coords:", local_coords);
578  DASH_LOG_TRACE("TilePattern.local_at",
579  "view:", viewspec);
580  DASH_LOG_TRACE("TilePattern.local_at",
581  "local blocks:", _local_blockspec.extents());
582  DASH_LOG_TRACE("TilePattern.local_at",
583  "local block coords:", block_coords_l);
584  DASH_LOG_TRACE("TilePattern.local_at",
585  "phase coords:", phase_coords);
586  // Number of blocks preceeding the coordinates' block:
587  auto block_offset_l = _local_blockspec.at(block_coords_l);
588  DASH_LOG_TRACE("TilePattern.local_at",
589  "local block offset:", block_offset_l);
590  auto local_index =
591  block_offset_l * _blocksize_spec.size() + // preceeding blocks
592  _blocksize_spec.at(phase_coords); // element phase
593  DASH_LOG_TRACE_VAR("TilePattern.local_at >", local_index);
594  return local_index;
595  }
596 
602  IndexType local_at(
604  const std::array<IndexType, NumDimensions> & local_coords) const
605  {
606  DASH_LOG_TRACE("TilePattern.local_at()",
607  "local coords:", local_coords,
608  "local blocks:", _local_blockspec.extents());
609  // Phase coordinates of element:
610  std::array<IndexType, NumDimensions> phase_coords{};
611  // Coordinates of the local block containing the element:
612  std::array<IndexType, NumDimensions> block_coords_l{};
613  for (auto d = 0; d < NumDimensions; ++d) {
614  auto gcoord_d = local_coords[d];
615  auto block_size_d = _blocksize_spec.extent(d);
616  phase_coords[d] = gcoord_d % block_size_d;
617  block_coords_l[d] = gcoord_d / block_size_d;
618  }
619  DASH_LOG_TRACE("TilePattern.local_at",
620  "local_coords:", local_coords,
621  "local blocks:", _local_blockspec.extents(),
622  "local block coords:", block_coords_l,
623  "block size:", _blocksize_spec.extents(),
624  "phase coords:", phase_coords);
625  // Number of blocks preceeding the coordinates' block:
626  auto block_offset_l = _local_blockspec.at(block_coords_l);
627  auto local_index =
628  block_offset_l * _blocksize_spec.size() + // preceeding blocks
629  _blocksize_spec.at(phase_coords); // element phase
630  DASH_LOG_TRACE_VAR("TilePattern.local_at >", local_index);
631  return local_index;
632  }
633 
641  const std::array<IndexType, NumDimensions> & global_coords) const
642  {
643  local_coords_t l_coords;
644  std::array<IndexType, NumDimensions> local_coords{};
645  std::array<IndexType, NumDimensions> unit_ts_coords{};
646  for (dim_t d = 0; d < NumDimensions; ++d) {
647  auto nunits_d = _teamspec.extent(d);
648  auto blocksize_d = _blocksize_spec.extent(d);
649  auto block_coord_d = global_coords[d] / blocksize_d;
650  auto phase_d = global_coords[d] % blocksize_d;
651  auto l_block_coord_d = block_coord_d / nunits_d;
652  unit_ts_coords[d] = block_coord_d % nunits_d;
653  local_coords[d] = (l_block_coord_d * blocksize_d) + phase_d;
654  }
655  l_coords.unit = _teamspec.at(unit_ts_coords);
656  l_coords.coords = local_coords;
657  return l_coords;
658  }
659 
668  constexpr local_index_t local(
669  IndexType g_index) const
670  {
671  // TODO: Implement dedicated method for this, conversion to/from
672  // global coordinates is expensive.
673  return local_index(coords(g_index));
674  }
675 
682  std::array<IndexType, NumDimensions> local_coords(
683  const std::array<IndexType, NumDimensions> & global_coords) const
684  {
685  std::array<IndexType, NumDimensions> local_coords{};
686  for (dim_t d = 0; d < NumDimensions; ++d) {
687  auto nunits_d = _teamspec.extent(d);
688  auto blocksize_d = _blocksize_spec.extent(d);
689  auto block_coord_d = global_coords[d] / blocksize_d;
690  auto phase_d = global_coords[d] % blocksize_d;
691  auto l_block_coord_d = block_coord_d / nunits_d;
692  local_coords[d] = (l_block_coord_d * blocksize_d) + phase_d;
693  }
694  return local_coords;
695  }
696 
703  const std::array<IndexType, NumDimensions> & global_coords) const
704  {
705  DASH_LOG_TRACE_VAR("TilePattern.local_index()", global_coords);
706  // Global coordinates to unit and local offset:
707  auto l_pos_coords = local(global_coords);
708  auto l_coords = l_pos_coords.coords;
709  auto unit = l_pos_coords.unit;
710  index_type l_index = -1;
711  DASH_LOG_TRACE_VAR("TilePattern.local_index", l_coords);
712  DASH_LOG_TRACE_VAR("TilePattern.local_index", unit);
713 
714  if (unit == _myid) {
715  // Local coords to local offset:
716  l_index = local_at(l_coords);
717  } else {
718  // Global coordinates point to remote location, requires to construct
719  // _local_blockspec of remote unit:
720  auto remote_l_blockspec = initialize_local_blockspec(
721  _blockspec, _blocksize_spec, _teamspec,
722  unit);
723 
724  // Phase coordinates of element:
725  std::array<IndexType, NumDimensions> phase_coords{};
726  // Coordinates of the local block containing the element:
727  std::array<IndexType, NumDimensions> block_coords_l{};
728  for (auto d = 0; d < NumDimensions; ++d) {
729  auto gcoord_d = l_coords[d];
730  auto block_size_d = _blocksize_spec.extent(d);
731  phase_coords[d] = gcoord_d % block_size_d;
732  block_coords_l[d] = gcoord_d / block_size_d;
733  }
734  DASH_LOG_TRACE("TilePattern.local_index",
735  "local_coords:", l_coords,
736  "local blocks:", remote_l_blockspec.extents(),
737  "local block coords:", block_coords_l,
738  "block size:", _blocksize_spec.extents(),
739  "phase coords:", phase_coords);
740  // Number of blocks preceeding the coordinates' block:
741  auto block_offset_l = remote_l_blockspec.at(block_coords_l);
742  l_index = block_offset_l * _blocksize_spec.size() + // prec. blocks
743  _blocksize_spec.at(phase_coords); // elem. phase
744  }
745  DASH_LOG_TRACE_VAR("TilePattern.local_index >", l_index);
746 
747  return local_index_t { unit, l_index };
748  }
749 
753 
759  std::array<IndexType, NumDimensions> global(
760  team_unit_t unit,
761  const std::array<IndexType, NumDimensions> & local_coords) const
762  {
763  DASH_LOG_DEBUG("TilePattern.global()",
764  "unit:", unit,
765  "lcoords:", local_coords);
766  // Global coordinate of local element:
767  std::array<IndexType, NumDimensions> global_coords{};
768  std::array<IndexType, NumDimensions> unit_ts_coords = _teamspec.coords(
769  unit);
770  for (dim_t d = 0; d < NumDimensions; ++d) {
771  auto blocksize_d = _blocksize_spec.extent(d);
772  auto nunits_d = _teamspec.extent(d);
773  auto phase = local_coords[d] % blocksize_d;
774  auto l_block_coord_d = local_coords[d] / blocksize_d;
775  auto g_block_coord_d = (l_block_coord_d * nunits_d) +
776  unit_ts_coords[d];
777  global_coords[d] = (g_block_coord_d * blocksize_d) + phase;
778  }
779  DASH_LOG_DEBUG_VAR("TilePattern.global >", global_coords);
780  return global_coords;
781  }
782 
788  constexpr std::array<IndexType, NumDimensions> global(
789  const std::array<IndexType, NumDimensions> & local_coords) const {
790  return global(_myid, local_coords);
791  }
792 
801  IndexType global(
802  IndexType local_index) const
803  {
804  DASH_LOG_TRACE("TilePattern.global()",
805  "local_index:", local_index,
806  "unit:", _myid);
807  auto block_size = _blocksize_spec.size();
808  auto phase = local_index % block_size;
809  auto l_block_index = local_index / block_size;
810  // Block coordinate in local memory:
811  auto l_block_coord = _local_blockspec.coords(l_block_index);
812  // Coordinate of element in block:
813  auto phase_coord = _blocksize_spec.coords(phase);
814  DASH_LOG_TRACE("TilePattern.global",
815  "local block index:", l_block_index,
816  "local block coords:", l_block_coord,
817  "phase coords:", phase_coord);
818  // Coordinate of element in local memory:
819  std::array<IndexType, NumDimensions> l_coords{};
820  for (auto d = 0; d < NumDimensions; ++d) {
821  l_coords[d] = l_block_coord[d] * _blocksize_spec.extent(d) +
822  phase_coord[d];
823  }
824  std::array<IndexType, NumDimensions> g_coords =
825  global(_myid, l_coords);
826  auto offset = global_at(g_coords);
827  DASH_LOG_TRACE_VAR("TilePattern.global >", offset);
828  return offset;
829  }
830 
840  IndexType global_index(
841  team_unit_t unit,
842  const std::array<IndexType, NumDimensions> & local_coords) const
843  {
844  DASH_LOG_TRACE("TilePattern.global_index()",
845  "unit:", unit,
846  "local_coords:", local_coords);
847  std::array<IndexType, NumDimensions> global_coords =
848  global(unit, local_coords);
849  auto g_index = _memory_layout.at(global_coords);
850  DASH_LOG_TRACE_VAR("TilePattern.global_index >", g_index);
851  return g_index;
852  }
853 
867  IndexType global_at(
868  const std::array<IndexType, NumDimensions> & global_coords,
869  const ViewSpec_t & viewspec) const
870  {
871  DASH_LOG_TRACE("TilePattern.global_at()",
872  "gcoords:", global_coords,
873  "viewspec:", viewspec);
874  // Phase coordinates of element:
875  std::array<IndexType, NumDimensions> phase_coords{};
876  // Coordinates of the block containing the element:
877  std::array<IndexType, NumDimensions> block_coords{};
878  for (auto d = 0; d < NumDimensions; ++d) {
879  auto vs_coord = global_coords[d] + viewspec.offset(d);
880  phase_coords[d] = vs_coord % _blocksize_spec.extent(d);
881  block_coords[d] = vs_coord / _blocksize_spec.extent(d);
882  }
883  DASH_LOG_TRACE("TilePattern.global_at",
884  "block coords:", block_coords,
885  "phase coords:", phase_coords);
886  // Number of blocks preceeding the coordinates' block, equivalent
887  // to linear global block offset:
888  auto block_index = _blockspec.at(block_coords);
889  DASH_LOG_TRACE("TilePattern.global_at",
890  "block index:", block_index);
891  auto offset = block_index * _blocksize_spec.size() + // preceed. blocks
892  _blocksize_spec.at(phase_coords); // element phase
893  DASH_LOG_TRACE_VAR("TilePattern.global_at >", offset);
894  return offset;
895  }
896 
910  IndexType global_at(
911  const std::array<IndexType, NumDimensions> & global_coords) const
912  {
913  DASH_LOG_TRACE("TilePattern.global_at()",
914  "gcoords:", global_coords);
915  // Phase coordinates of element:
916  std::array<IndexType, NumDimensions> phase_coords;
917  // Coordinates of the block containing the element:
918  std::array<IndexType, NumDimensions> block_coords;
919 
920  for (auto d = 0; d < NumDimensions; ++d) {
921  auto vs_coord = global_coords[d];
922  phase_coords[d] = vs_coord % _blocksize_spec.extent(d);
923  block_coords[d] = vs_coord / _blocksize_spec.extent(d);
924  }
925  DASH_LOG_TRACE("TilePattern.global_at",
926  "block coords:", block_coords,
927  "phase coords:", phase_coords);
928  // Number of blocks preceeding the coordinates' block, equivalent
929  // to linear global block offset:
930  auto block_index = _blockspec.at(block_coords);
931  DASH_LOG_TRACE("TilePattern.global_at",
932  "block index:", block_index);
933  auto offset = block_index * _blocksize_spec.size() + // preceed. blocks
934  _blocksize_spec.at(phase_coords); // element phase
935  DASH_LOG_TRACE_VAR("TilePattern.global_at >", offset);
936  return offset;
937  }
938 
942 
950  IndexType at(
951  const std::array<IndexType, NumDimensions> & global_coords,
952  const ViewSpec_t & viewspec) const
953  {
954  DASH_LOG_TRACE("TilePattern.at()",
955  "gcoords:", global_coords,
956  "viewspec:", viewspec);
957  // Phase coordinates of element:
958  std::array<IndexType, NumDimensions> phase_coords;
959  // Coordinates of the block containing the element:
960  std::array<IndexType, NumDimensions> block_coords;
961  // Local coordinates of the block containing the element:
962  std::array<IndexType, NumDimensions> l_block_coords;
963  for (auto d = 0; d < NumDimensions; ++d) {
964  auto nunits_d = _teamspec.extent(d);
965  auto vs_coord = global_coords[d] + viewspec.offset(d);
966  phase_coords[d] = vs_coord % _blocksize_spec.extent(d);
967  block_coords[d] = vs_coord / _blocksize_spec.extent(d);
968  l_block_coords[d] = block_coords[d] / nunits_d;
969  }
970  index_type l_block_index = _local_blockspec.at(l_block_coords);
971  DASH_LOG_TRACE("TilePattern.at",
972  "block_coords:", block_coords,
973  "l_block_coords:", l_block_coords,
974  "l_block_index:", l_block_index,
975  "phase_coords:", phase_coords);
976  auto offset = l_block_index * _blocksize_spec.size() + // prec. blocks
977  _blocksize_spec.at(phase_coords); // elem. phase
978  DASH_LOG_TRACE_VAR("TilePattern.at >", offset);
979  return offset;
980  }
981 
990  IndexType at(
991  std::array<IndexType, NumDimensions> global_coords) const
992  {
993  DASH_LOG_TRACE("TilePattern.at()", "gcoords:", global_coords);
994  // Phase coordinates of element:
995  std::array<IndexType, NumDimensions> phase_coords{};
996  // Coordinates of the block containing the element:
997  std::array<IndexType, NumDimensions> block_coords{};
998  // Local coordinates of the block containing the element:
999  std::array<IndexType, NumDimensions> l_block_coords{};
1000  for (auto d = 0; d < NumDimensions; ++d) {
1001  auto nunits_d = _teamspec.extent(d);
1002  auto gcoord_d = global_coords[d];
1003  phase_coords[d] = gcoord_d % _blocksize_spec.extent(d);
1004  block_coords[d] = gcoord_d / _blocksize_spec.extent(d);
1005  l_block_coords[d] = block_coords[d] / nunits_d;
1006  }
1007  index_type l_block_index = _local_blockspec.at(l_block_coords);
1008  DASH_LOG_TRACE("TilePattern.at",
1009  "block_coords:", block_coords,
1010  "l_block_coords:", l_block_coords,
1011  "l_block_index:", l_block_index,
1012  "phase_coords:", phase_coords);
1013  auto offset = l_block_index * _blocksize_spec.size() + // prec. blocks
1014  _blocksize_spec.at(phase_coords); // elem. phase
1015  DASH_LOG_TRACE_VAR("TilePattern.at >", offset);
1016  return offset;
1017  }
1018 
1026  template<typename ... Values>
1027  IndexType at(Values ... values) const
1028  {
1029  static_assert(
1030  sizeof...(values) == NumDimensions,
1031  "Wrong parameter number");
1032  std::array<IndexType, NumDimensions> inputindex = {
1033  (IndexType)values...
1034  };
1035  return at(inputindex);
1036  }
1037 
1041 
1050  dim_t dim,
1052  IndexType dim_offset,
1054  team_unit_t unit,
1056  const ViewSpec_t & viewspec) const
1057  {
1058  DASH_LOG_TRACE_VAR("TilePattern.has_local_elements()", dim);
1059  DASH_LOG_TRACE_VAR("TilePattern.has_local_elements()", dim_offset);
1060  DASH_LOG_TRACE_VAR("TilePattern.has_local_elements()", unit);
1061  DASH_LOG_TRACE_VAR("TilePattern.has_local_elements()", viewspec);
1062  // Apply viewspec offset in dimension to given position
1063  dim_offset += viewspec.offset(dim);
1064  // Offset to block offset
1065  IndexType block_coord_d = dim_offset / _blocksize_spec.extent(dim);
1066  DASH_LOG_TRACE_VAR("TilePattern.has_local_elements", block_coord_d);
1067  // Coordinate of unit in team spec in given dimension
1068  IndexType teamspec_coord_d = block_coord_d % _teamspec.extent(dim);
1069  DASH_LOG_TRACE_VAR("TilePattern.has_local_elements",
1070  teamspec_coord_d);
1071  // Check if unit id lies in cartesian sub-space of team spec
1072  return _teamspec.includes_index(
1073  teamspec_coord_d,
1074  dim,
1075  dim_offset);
1076  }
1077 
1083  bool is_local(
1084  IndexType index,
1085  team_unit_t unit) const
1086  {
1087  auto glob_coords = coords(index);
1088  auto coords_unit = unit_at(glob_coords);
1089  DASH_LOG_TRACE_VAR("TilePattern.is_local >", (coords_unit == unit));
1090  return coords_unit == unit;
1091  }
1092 
1099  constexpr bool is_local(
1100  IndexType index) const
1101  {
1102  return is_local(index, _myid);
1103  }
1104 
1108 
1114  index_type block_at(
1116  const std::array<index_type, NumDimensions> & g_coords) const
1117  {
1118  std::array<index_type, NumDimensions> block_coords{};
1119  // Coord to block coord to unit coord:
1120  for (auto d = 0; d < NumDimensions; ++d) {
1121  block_coords[d] = g_coords[d] / _blocksize_spec.extent(d);
1122  }
1123  // Block coord to block index:
1124  auto block_idx = _blockspec.at(block_coords);
1125  DASH_LOG_TRACE("TilePattern.block_at",
1126  "coords", g_coords,
1127  "> block index", block_idx);
1128  return block_idx;
1129  }
1130 
1138  const std::array<index_type, NumDimensions> & g_coords) const
1139  {
1140  local_index_t l_pos;
1141 
1142  std::array<IndexType, NumDimensions> l_block_coords{};
1143  std::array<IndexType, NumDimensions> unit_ts_coords{};
1144  for (dim_t d = 0; d < NumDimensions; ++d) {
1145  auto nunits_d = _teamspec.extent(d);
1146  auto blocksize_d = _blocksize_spec.extent(d);
1147  auto block_coord_d = g_coords[d] / blocksize_d;
1148  l_block_coords[d] = block_coord_d / nunits_d;
1149  unit_ts_coords[d] = block_coord_d % nunits_d;
1150  }
1151  l_pos.unit = _teamspec.at(unit_ts_coords);
1152  l_pos.index = _local_blockspec.at(l_block_coords);
1153 
1154  DASH_LOG_TRACE("TilePattern.local_block_at >",
1155  "coords", g_coords,
1156  "unit:", l_pos.unit,
1157  "local block index:", l_pos.index);
1158  return l_pos;
1159  }
1160 
1167  ViewSpec_t block(
1168  index_type global_block_index) const
1169  {
1170  DASH_LOG_TRACE_VAR("TilePattern.block()", global_block_index);
1171  // block index -> block coords -> offset
1172  auto block_coords = _blockspec.coords(global_block_index);
1173  DASH_LOG_TRACE_VAR("TilePattern.block", block_coords);
1174  DASH_LOG_TRACE_VAR("TilePattern.block", _blocksize_spec.extents());
1175  std::array<index_type, NumDimensions> offsets{};
1176  std::array<size_type, NumDimensions> extents{};
1177  for (auto d = 0; d < NumDimensions; ++d) {
1178  auto blocksize_d = _blocksize_spec.extent(d);
1179  extents[d] = blocksize_d;
1180  offsets[d] = block_coords[d] * blocksize_d;
1181  }
1182  DASH_LOG_TRACE("TilePattern.block",
1183  "offsets:", offsets,
1184  "extents:", extents);
1185  auto block_vs = ViewSpec_t(offsets, extents);
1186  DASH_LOG_TRACE_VAR("TilePattern.block >", block_vs);
1187  return block_vs;
1188  }
1189 
1195  ViewSpec_t block(
1197  const std::array<index_type, NumDimensions> & block_coords) const
1198  {
1199  DASH_LOG_TRACE_VAR("TilePattern.block()", block_coords);
1200  // block coords -> offset
1201  DASH_LOG_TRACE_VAR("TilePattern.block", _blocksize_spec.extents());
1202  std::array<index_type, NumDimensions> offsets;
1203  std::array<size_type, NumDimensions> extents;
1204  for (auto d = 0; d < NumDimensions; ++d) {
1205  auto blocksize_d = _blocksize_spec.extent(d);
1206  extents[d] = blocksize_d;
1207  offsets[d] = block_coords[d] * blocksize_d;
1208  }
1209  DASH_LOG_TRACE("TilePattern.block",
1210  "offsets:", offsets,
1211  "extents:", extents);
1212  auto block_vs = ViewSpec_t(offsets, extents);
1213  DASH_LOG_TRACE_VAR("TilePattern.block >", block_vs);
1214  return block_vs;
1215  }
1216 
1223  constexpr ViewSpec_t local_block(
1224  index_type local_block_index) const
1225  {
1226  return local_block(_myid, local_block_index);
1227  }
1228 
1235  ViewSpec_t local_block(
1236  team_unit_t unit,
1237  index_type local_block_index) const
1238  {
1239  DASH_LOG_TRACE("TilePattern.local_block()",
1240  "unit:", unit,
1241  "lblock_idx:", local_block_index,
1242  "lblockspec:", _local_blockspec.extents());
1243 
1244  // Local block index to local block coords:
1245  auto l_block_coords = _local_blockspec.coords(local_block_index);
1246  auto unit_ts_coords = _teamspec.coords(unit);
1247  DASH_LOG_TRACE_VAR("TilePattern.local_block", l_block_coords);
1248  std::array<index_type, NumDimensions> offsets{};
1249  std::array<size_type, NumDimensions> extents{};
1250  for (auto d = 0; d < NumDimensions; ++d) {
1251  auto blocksize_d = _blocksize_spec.extent(d);
1252 
1253  // Block offsets are lobal coordinates of first block element:
1254  auto nunits_d = _teamspec.extent(d);
1255  offsets[d] = ((l_block_coords[d] * nunits_d) + unit_ts_coords[d]) *
1256  blocksize_d;
1257  // checks if the local block is the last one in this dimension
1258  auto num_blocks_d =_local_blockspec.extent(d);
1259  if(l_block_coords[d] == (num_blocks_d - 1)){
1260  size_type remaining = local_extent(d) % blocksize_d;
1261  // if block is underfilled the extent will be decreased
1262  if(remaining > 0) {
1263  blocksize_d = remaining;
1264  }
1265  }
1266  extents[d] = blocksize_d;
1267  }
1268  ViewSpec_t block_vs(offsets, extents);
1269  DASH_LOG_TRACE_VAR("TilePattern.local_block >", block_vs);
1270  return block_vs;
1271  }
1272 
1279  ViewSpec_t local_block_local(
1280  index_type local_block_index) const
1281  {
1282  DASH_LOG_TRACE_VAR("TilePattern.local_block_local()",
1283  local_block_index);
1284  // Initialize viewspec result with block extents:
1285  std::array<index_type, NumDimensions> offsets{};
1286  std::array<size_type, NumDimensions> extents =
1287  _blocksize_spec.extents();
1288  // Local block index to local block coords:
1289  auto l_block_coords = _local_blockspec.coords(local_block_index);
1290  // Local block coords to local element offset:
1291  for (auto d = 0; d < NumDimensions; ++d) {
1292  auto blocksize_d = extents[d];
1293  offsets[d] = l_block_coords[d] * blocksize_d;
1294  }
1295  ViewSpec_t block_vs(offsets, extents);
1296  DASH_LOG_TRACE_VAR("TilePattern.local_block_local >", block_vs);
1297  return block_vs;
1298  }
1299 
1303  constexpr const BlockSpec_t & blockspec() const
1304  {
1305  return _blockspec;
1306  }
1307 
1311  constexpr const BlockSpec_t & local_blockspec() const
1312  {
1313  return _local_blockspec;
1314  }
1315 
1323  constexpr SizeType blocksize(
1325  dim_t dimension) const
1326  {
1327  return _blocksize_spec.extent(dimension);
1328  }
1329 
1338  constexpr SizeType max_blocksize() const {
1339  return _blocksize_spec.size();
1340  }
1341 
1348  constexpr SizeType local_capacity() const {
1349  return local_size();
1350  }
1351 
1363  if (unit == UNDEFINED_TEAM_UNIT_ID) {
1364  return _local_memory_layout.size();
1365  }
1366  // Non-local query, requires to construct local memory layout of
1367  // remote unit:
1368  return LocalMemoryLayout_t(initialize_local_extents(unit)).size();
1369  }
1370 
1376  constexpr IndexType num_units() const {
1377  return _teamspec.size();
1378  }
1379 
1385  constexpr IndexType capacity() const {
1386  return _memory_layout.size();
1387  }
1388 
1394  constexpr IndexType size() const {
1395  return _memory_layout.size();
1396  }
1397 
1402  constexpr dash::Team & team() const {
1403  return *_team;
1404  }
1405 
1409  constexpr const DistributionSpec_t & distspec() const {
1410  return _distspec;
1411  }
1412 
1418  constexpr SizeSpec_t sizespec() const {
1419  return SizeSpec_t(_memory_layout.extents());
1420  }
1421 
1427  constexpr const std::array<SizeType, NumDimensions> & extents() const {
1428  return _memory_layout.extents();
1429  }
1430 
1437  constexpr const TeamSpec_t & teamspec() const {
1438  return _teamspec;
1439  }
1440 
1447  constexpr std::array<IndexType, NumDimensions> coords(
1449  IndexType index) const {
1450 
1451  ::std::array<IndexType, NumDimensions> pos{};
1452  auto block_coords = _blockspec.coords(index / _blocksize_spec.size());
1453  auto phase_coords = _blocksize_spec.coords(index % _blocksize_spec.size());
1454  for (auto d = 0; d < NumDimensions; ++d) {
1455  pos[d] = block_coords[d]*_blocksize_spec.extent(d) + phase_coords[d];
1456  }
1457  return pos;
1458  }
1459 
1466  constexpr std::array<IndexType, NumDimensions> coords(
1468  IndexType index,
1470  const ViewSpec_t & viewspec) const {
1471 
1472  ::std::array<IndexType, NumDimensions> pos;
1473  auto block_coords = _blockspec.coords(index / _blocksize_spec.size(),
1474  viewspec);
1475  auto phase_coords = _blocksize_spec.coords(index % _blocksize_spec.size(),
1476  viewspec);
1477  for (auto d = 0; d < NumDimensions; ++d) {
1478  pos[d] = block_coords[d]*_blocksize_spec.extent(d) + phase_coords[d];
1479  }
1480  return pos;
1481  }
1482 
1486  constexpr static MemArrange memory_order() {
1487  return Arrangement;
1488  }
1489 
1494  constexpr static dim_t ndim() {
1495  return NumDimensions;
1496  }
1497 
1503  SizeType underfilled_blocksize(dim_t dimension) const
1504  {
1505  // Underflow blocksize = regular blocksize - overflow blocksize:
1506  auto ovf_blocksize = _memory_layout.extent(dimension) %
1507  blocksize(dimension);
1508 
1509  if (ovf_blocksize == 0) {
1510  return 0;
1511  }
1512 
1513  DASH_LOG_DEBUG_VAR("TilePattern.underfilled_blocksize", ovf_blocksize);
1514  auto reg_blocksize = blocksize(dimension);
1515  return reg_blocksize - ovf_blocksize;
1516  }
1517 
1518 private:
1519 
1520  TilePattern(const PatternArguments_t & arguments)
1521  : _distspec(arguments.distspec()),
1522  _team(&arguments.team()),
1523  _myid(_team->myid()),
1524  _teamspec(arguments.teamspec()),
1525  _memory_layout(arguments.sizespec().extents()),
1526  _nunits(_teamspec.size()),
1527  _blocksize_spec(initialize_blocksizespec(
1528  arguments.sizespec(),
1529  _distspec,
1530  _teamspec)),
1531  _blockspec(initialize_blockspec(
1532  arguments.sizespec(),
1533  _blocksize_spec,
1534  _teamspec)),
1535  _local_blockspec(initialize_local_blockspec(
1536  _blockspec,
1537  _blocksize_spec,
1538  _teamspec)),
1539  _local_memory_layout(
1540  initialize_local_extents(_myid)),
1541  _local_capacity(
1542  initialize_local_capacity(_local_memory_layout))
1543  {}
1544 
1549  BlockSizeSpec_t initialize_blocksizespec(
1550  const SizeSpec_t & sizespec,
1551  const DistributionSpec_t & distspec,
1552  const TeamSpec_t & teamspec) const {
1553  DASH_LOG_TRACE("TilePattern.init_blocksizespec()",
1554  "sizespec:", sizespec.extents(),
1555  "distspec:", distspec.values(),
1556  "teamspec:", teamspec.extents());
1557  // Extents of a single block:
1558  std::array<SizeType, NumDimensions> s_blocks{};
1559  if (sizespec.size() == 0 || teamspec.size() == 0) {
1560  DASH_LOG_TRACE("TilePattern.init_blocksizespec >",
1561  "sizespec or teamspec uninitialized",
1562  "(default construction?), cancel");
1563  return BlockSizeSpec_t(s_blocks);
1564  }
1565  for (auto d = 0; d < NumDimensions; ++d) {
1566  const Distribution & dist = distspec[d];
1567  auto extent_d = sizespec.extent(d);
1568  auto units_d = teamspec.extent(d);
1569  DASH_ASSERT_GT(extent_d, 0,
1570  "Extent of size spec in dimension" << d << "is 0");
1571  DASH_ASSERT_GT(units_d, 0,
1572  "Extent of team spec in dimension" << d << "is 0");
1573  auto blocksize_d = dist.max_blocksize_in_range(
1574  extent_d, // size of range (extent)
1575  units_d // number of blocks (units)
1576  );
1577 
1578  s_blocks[d] = blocksize_d;
1579  }
1580  DASH_LOG_TRACE_VAR("TilePattern.init_blocksizespec >", s_blocks);
1581  return BlockSizeSpec_t(s_blocks);
1582  }
1583 
1588  BlockSpec_t initialize_blockspec(
1589  const SizeSpec_t & sizespec,
1590  const BlockSizeSpec_t & blocksizespec,
1591  const TeamSpec_t & teamspec) const
1592  {
1593  DASH_LOG_TRACE("TilePattern.init_blockspec()",
1594  "pattern size:", sizespec.extents(),
1595  "block size:", blocksizespec.extents(),
1596  "team size:", teamspec.extents());
1597  // Number of blocks in all dimensions:
1598  if (teamspec.size() == 0 || sizespec.size() == 0) {
1599  BlockSpec_t empty_blockspec;
1600  DASH_LOG_TRACE_VAR("TilePattern.init_blockspec >",
1601  empty_blockspec.extents());
1602  return empty_blockspec;
1603  }
1604  std::array<SizeType, NumDimensions> n_blocks{};
1605  for (auto d = 0; d < NumDimensions; ++d) {
1606  SizeType max_blocksize_d = blocksizespec.extent(d);
1607  SizeType max_blocks_d = dash::math::div_ceil(
1608  sizespec.extent(d),
1609  max_blocksize_d);
1610  n_blocks[d] = max_blocks_d;
1611  }
1612  BlockSpec_t blockspec(n_blocks);
1613  DASH_LOG_TRACE_VAR("TilePattern.init_blockspec >", n_blocks);
1614  return blockspec;
1615  }
1616 
1621  BlockSpec_t initialize_local_blockspec(
1622  const BlockSpec_t & blockspec,
1623  const BlockSizeSpec_t & blocksizespec,
1624  const TeamSpec_t & teamspec,
1625  team_unit_t unit_id = UNDEFINED_TEAM_UNIT_ID) const
1626  {
1627  DASH_LOG_TRACE_VAR("TilePattern.init_local_blockspec()",
1628  blockspec.extents());
1629  if (unit_id == DART_UNDEFINED_UNIT_ID) {
1630  unit_id = _myid;
1631  }
1632  if (blockspec.size() == 0 || teamspec.size() == 0 ||
1633  blocksizespec.size() == 0) {
1634  BlockSpec_t empty_blockspec;
1635  DASH_LOG_TRACE_VAR("TilePattern.init_local_blockspec >",
1636  empty_blockspec.extents());
1637  return empty_blockspec;
1638  }
1639  // Number of local blocks in all dimensions:
1640  auto l_blocks = blockspec.extents();
1641  // Coordinates of local unit id in team spec:
1642  auto unit_ts_coords = _teamspec.coords(unit_id);
1643  DASH_LOG_TRACE_VAR("TilePattern.init_local_blockspec", unit_ts_coords);
1644  for (auto d = 0; d < NumDimensions; ++d) {
1645  // Number of units in dimension:
1646  auto num_units_d = _teamspec.extent(d);
1647  // Number of blocks in dimension:
1648  auto num_blocks_d = _blockspec.extent(d);
1649  // Number of blocks assigned to unit in this dimension:
1650  auto num_l_blocks_d = num_blocks_d / num_units_d;
1651  auto num_odd_blocks_d = num_blocks_d % num_units_d;
1652  if (num_odd_blocks_d > unit_ts_coords[d]) {
1653  ++num_l_blocks_d;
1654  }
1655  l_blocks[d] = num_l_blocks_d;
1656  }
1657  DASH_LOG_TRACE_VAR("TilePattern.init_local_blockspec >", l_blocks);
1658  DASH_LOG_DEBUG_VAR("TilePattern.init_local_extents >", initialize_local_extents(unit_id));
1659  return BlockSpec_t(l_blocks);
1660  }
1661 
1669  SizeType initialize_local_capacity(
1670  const LocalMemoryLayout_t & local_extents) const
1671  {
1672  DASH_LOG_TRACE_VAR("TilePattern.init_local_capacity()",
1673  local_extents.extents());
1674  auto l_capacity = local_extents.size();
1675  DASH_LOG_TRACE_VAR("TilePattern.init_local_capacity >", l_capacity);
1676  return l_capacity;
1677  }
1678 
1683  void initialize_local_range()
1684  {
1685  auto local_size = _local_memory_layout.size();
1686  DASH_LOG_DEBUG_VAR("TilePattern.init_local_range()", local_size);
1687  if (local_size == 0) {
1688  _lbegin = 0;
1689  _lend = 0;
1690  } else {
1691  // First local index transformed to global index
1692  _lbegin = global(0);
1693  // Index past last local index transformed to global index
1694  _lend = global(local_size - 1) + 1;
1695  }
1696  DASH_LOG_DEBUG_VAR("TilePattern.init_local_range >", _lbegin);
1697  DASH_LOG_DEBUG_VAR("TilePattern.init_local_range >", _lend);
1698  }
1699 
1703  std::array<SizeType, NumDimensions> initialize_local_extents(
1704  team_unit_t unit) const
1705  {
1706  // Coordinates of local unit id in team spec:
1707  DASH_LOG_DEBUG_VAR("TilePattern.init_local_extents()", unit);
1708  if (_teamspec.size() == 0) {
1709  ::std::array<SizeType, NumDimensions> empty_extents = {{ }};
1710  DASH_LOG_DEBUG_VAR("TilePattern.init_local_extents >", empty_extents);
1711  return empty_extents;
1712  }
1713  auto unit_ts_coords = _teamspec.coords(unit);
1714  DASH_LOG_TRACE_VAR("TilePattern.init_local_extents", unit_ts_coords);
1715  ::std::array<SizeType, NumDimensions> l_extents{};
1716  for (auto d = 0; d < NumDimensions; ++d) {
1717  // Number of units in dimension:
1718  auto num_units_d = _teamspec.extent(d);
1719  // Number of blocks in dimension:
1720  auto num_blocks_d = _blockspec.extent(d);
1721  // Maximum extent of single block in dimension:
1722  auto blocksize_d = _blocksize_spec.extent(d);
1723  // Number of blocks assigned to unit in this dimension:
1724  auto num_l_blocks_d = num_blocks_d / num_units_d;
1725  auto num_odd_blocks_d = num_blocks_d % num_units_d;
1726  if (num_odd_blocks_d > unit_ts_coords[d]) {
1727  ++num_l_blocks_d;
1728  }
1729 
1730  // Coordinate of this unit id in teamspec in dimension:
1731  auto unit_ts_coord = unit_ts_coords[d];
1732  // Possibly there are more blocks than units in dimension and no
1733  // block left for this unit. Local extent in d then becomes 0.
1734  l_extents[d] = num_l_blocks_d * blocksize_d;
1735  // Unit id assigned to the last block in dimension:
1736  team_unit_t last_block_unit_d((num_blocks_d % num_units_d == 0)
1737  ? num_units_d - 1
1738  : (num_blocks_d % num_units_d) - 1);
1739 
1740  if(unit_ts_coord == last_block_unit_d) {
1741  // If the last block in the dimension is underfilled and
1742  // assigned to the local unit, subtract the missing extent:
1743  auto undfill_blocksize_d = underfilled_blocksize(d);
1744  DASH_LOG_TRACE_VAR("TilePattern.init_local_extents",
1745  undfill_blocksize_d);
1746  l_extents[d] -= undfill_blocksize_d;
1747  }
1748  }
1749  DASH_LOG_DEBUG_VAR("TilePattern.init_local_extents >", l_extents);
1750  return l_extents;
1751  }
1752 };
1753 
1754 template<
1755  dim_t ND,
1756  MemArrange Ar,
1757  typename Index>
1758 std::ostream & operator<<(
1759  std::ostream & os,
1760  const TilePattern<ND,Ar,Index> & pattern)
1761 {
1762  typedef Index index_t;
1763 
1764  dim_t ndim = pattern.ndim();
1765 
1766  std::string storage_order = pattern.memory_order() == ROW_MAJOR
1767  ? "ROW_MAJOR"
1768  : "COL_MAJOR";
1769 
1770  std::array<index_t, 2> blocksize;
1771  blocksize[0] = pattern.blocksize(0);
1772  blocksize[1] = pattern.blocksize(1);
1773 
1774  std::ostringstream ss;
1775  ss << "dash::"
1777  << "<"
1778  << ndim << ","
1779  << storage_order << ","
1780  << typeid(index_t).name()
1781  << ">"
1782  << "("
1783  << "SizeSpec:" << pattern.sizespec().extents() << ", "
1784  << "TeamSpec:" << pattern.teamspec().extents() << ", "
1785  << "BlockSpec:" << pattern.blockspec().extents() << ", "
1786  << "BlockSize:" << blocksize
1787  << ")";
1788 
1789  return operator<<(os, ss.str());
1790 }
1791 
1792 } // namespace dash
1793 
1794 #include <dash/pattern/TilePattern1D.h>
1795 
1796 #endif // DASH__TILE_PATTERN_H_
team_unit_t unit_at(IndexType global_pos, const ViewSpec_t &viewspec) const
Convert given global linear index to its assigned unit id.
Definition: TilePattern.h:455
constexpr team_unit_t UNDEFINED_TEAM_UNIT_ID
Invalid local unit ID.
Definition: Types.h:341
constexpr const DistributionSpec_t & distspec() const
Distribution specification of this pattern.
Definition: TilePattern.h:1409
All blocks have identical size.
constexpr local_index_t local(IndexType g_index) const
Converts global index to its associated unit and respective local index.
Definition: TilePattern.h:668
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
SizeType extent(dim_t dim) const
extent
Definition: TilePattern.h:491
constexpr const std::array< ElementType, NumDimensions > & values() const
Return value with all dimensions as array of NumDimensions elements.
Definition: Dimensional.h:142
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: TilePattern.h:840
global_unit_t myid()
Shortcut to query the global unit ID of the calling unit.
constexpr std::array< SizeType, NumDimensions > local_extents(team_unit_t unit=UNDEFINED_TEAM_UNIT_ID) const
The actual number of elements in this pattern that are local to the given unit, by dimension...
Definition: TilePattern.h:536
team_unit_t unit_at(const std::array< IndexType, NumDimensions > &coords, const ViewSpec_t &viewspec) const
unit_at
Definition: TilePattern.h:398
constexpr std::enable_if< std::is_integral< IndexType >::value, IndexType >::type index(IndexType idx)
Definition: Iterator.h:60
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...
bool has_local_elements(dim_t dim, IndexType dim_offset, team_unit_t unit, const ViewSpec_t &viewspec) const
is_local
Definition: TilePattern.h:1048
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: TilePattern.h:801
Specifies cartesian extents in a specific number of dimensions.
Definition: Cartesian.h:197
IndexType local_at(const std::array< IndexType, NumDimensions > &local_coords, const ViewSpec_t &viewspec) const
local
Definition: TilePattern.h:555
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: TilePattern.h:640
Specifies view parameters for implementing submat, rows and cols.
Definition: Dimensional.h:430
local_index_t local_block_at(const std::array< index_type, NumDimensions > &g_coords) const
Unit and local block index at given global coordinates.
Definition: TilePattern.h:1136
IndexType at(const std::array< IndexType, NumDimensions > &global_coords, const ViewSpec_t &viewspec) const
at
Definition: TilePattern.h:950
SizeType local_size(team_unit_t unit=UNDEFINED_TEAM_UNIT_ID) const
The actual number of elements in this pattern that are local to the calling unit in total...
Definition: TilePattern.h:1362
TilePattern(SizeType arg, Args &&... args)
Constructor, initializes a pattern from an argument list consisting of the pattern size (extent...
Definition: TilePattern.h:185
int dim_t
Scalar type for a dimension value, with 0 indicating the first dimension.
Definition: Types.h:39
constexpr const BlockSpec_t & blockspec() const
Cartesian arrangement of pattern blocks.
Definition: TilePattern.h:1303
team_unit_t unit_at(const std::array< IndexType, NumDimensions > &coords) const
Convert given coordinate in pattern to its assigned unit id.
Definition: TilePattern.h:429
SizeType underfilled_blocksize(dim_t dimension) const
Number of elements missing in the overflow block of given dimension compared to the regular blocksize...
Definition: TilePattern.h:1503
IndexType at(Values ... values) const
Global coordinates to local index.
Definition: TilePattern.h:1027
constexpr IndexType size() const
The number of elements arranged in this pattern.
Definition: TilePattern.h:1394
constexpr SizeType local_capacity() const
Maximum number of elements assigned to a single unit in total, equivalent to the local capacity of ev...
Definition: TilePattern.h:1348
The number of blocks assigned to units may differ.
ViewSpec_t block(index_type global_block_index) const
View spec (offset and extents) of block at global linear block index in global cartesian element spac...
Definition: TilePattern.h:1167
constexpr SizeType blocksize(dim_t dimension) const
Maximum number of elements in a single block in the given dimension.
Definition: TilePattern.h:1323
constexpr bool is_local(IndexType index) const
Whether the given global index is local to the unit that created this pattern instance.
Definition: TilePattern.h:1099
constexpr 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...
Definition: TilePattern.h:1223
Defines how a list of global indices is mapped to single units within a Team.
Definition: TilePattern.h:47
Block extents are constant for every dimension.
The number of assigned blocks is identical for every unit.
bool is_local(IndexType index, team_unit_t unit) const
Whether the given global index is local to the specified unit.
Definition: TilePattern.h:1083
size_t size() const
The number of units in this team.
Definition: Team.h:498
static constexpr MemArrange memory_order()
Memory order followed by the pattern.
Definition: TilePattern.h:1486
internal::default_signed_index default_index_t
Signed integer type used as default for index values.
Definition: Types.h:59
IndexType local_at(const std::array< IndexType, NumDimensions > &local_coords) const
Convert given local coordinates to linear local offset (index).
Definition: TilePattern.h:602
A Team instance specifies a subset of all available units.
Definition: Team.h:41
constexpr const BlockSpec_t & local_blockspec() const
Cartesian arrangement of local pattern blocks.
Definition: TilePattern.h:1311
constexpr std::array< IndexType, NumDimensions > global(const std::array< IndexType, NumDimensions > &local_coords) const
Converts local coordinates of a active unit to global coordinates.
Definition: TilePattern.h:788
constexpr IndexType num_units() const
The number of units to which this pattern&#39;s elements are mapped.
Definition: TilePattern.h:1376
constexpr const extents_type & extents() const noexcept
Extents of the cartesian space, by dimension.
Definition: Cartesian.h:402
IndexType global_at(const std::array< IndexType, NumDimensions > &global_coords, const ViewSpec_t &viewspec) const
Global coordinates and viewspec to global position in the pattern&#39;s iteration order.
Definition: TilePattern.h:867
constexpr IndexType capacity() const
The maximum number of elements arranged in this pattern.
Definition: TilePattern.h:1385
std::array< IndexType, NumDimensions > coords(IndexType index) const
Convert given linear offset (index) to cartesian coordinates.
Definition: Cartesian.h:497
Elements are contiguous in local memory within a single block and thus indexed blockwise.
IndexType at(std::array< IndexType, NumDimensions > global_coords) const
Global coordinates to local index.
Definition: TilePattern.h:990
SizeType extent(dim_t dim) const
The extent of the cartesian space in the given dimension.
Definition: Cartesian.h:412
index_type block_at(const std::array< index_type, NumDimensions > &g_coords) const
block
Definition: TilePattern.h:1114
constexpr std::array< IndexType, NumDimensions > coords(IndexType index) const
Convert given global linear offset (index) to global cartesian coordinates.
Definition: TilePattern.h:1447
Defines a cartesian, totally-ordered index space by mapping linear indices to cartesian coordinates d...
Definition: Cartesian.h:239
ViewSpec_t block(const std::array< index_type, NumDimensions > &block_coords) const
View spec (offset and extents) of block at global block coordinates.
Definition: TilePattern.h:1195
constexpr IndexType at(IndexType arg, Args... args) const
Convert the given coordinates to their respective linear index.
Definition: Cartesian.h:429
pattern_mapping_properties< pattern_mapping_tag::balanced, pattern_mapping_tag::unbalanced > mapping_properties
Satisfiable properties in pattern property category Mapping:
Definition: TilePattern.h:66
Specifies how a Pattern distributes elements to units in a specific dimension.
Definition: Distribution.h:24
std::array< IndexType, NumDimensions > global(team_unit_t unit, const std::array< IndexType, NumDimensions > &local_coords) const
global
Definition: TilePattern.h:759
constexpr SizeSpec_t sizespec() const
Size specification of the index space mapped by this pattern.
Definition: TilePattern.h:1418
team_unit_t unit_at(IndexType global_pos) const
Convert given global linear index to its assigned unit id.
Definition: TilePattern.h:470
bool operator==(const self_t &other) const
Equality comparison operator.
Definition: TilePattern.h:344
TilePattern(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: TilePattern.h:294
constexpr const TeamSpec_t & teamspec() const
Cartesian arrangement of the Team containing the units to which this pattern&#39;s elements are mapped...
Definition: TilePattern.h:1437
constexpr const std::array< SizeType, NumDimensions > & extents() const
Size specification (shape) of the index space mapped by this pattern.
Definition: TilePattern.h:1427
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
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: TilePattern.h:682
TilePattern(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: TilePattern.h:233
static constexpr dim_t ndim()
Number of dimensions of the cartesian space partitioned by the pattern.
Definition: TilePattern.h:1494
pattern_layout_properties< pattern_layout_tag::blocked, pattern_layout_tag::linear > layout_properties
Satisfiable properties in pattern property category Layout:
Definition: TilePattern.h:75
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
ViewSpec_t local_block(team_unit_t unit, index_type local_block_index) const
View spec (offset and extents) of block at local linear block index in global cartesian element space...
Definition: TilePattern.h:1235
constexpr IndexType lbegin() const
Resolves the global index of the first local element in the pattern.
Definition: TilePattern.h:376
constexpr IndexType lend() const
Resolves the global index past the last local element in the pattern.
Definition: TilePattern.h:385
SizeType extent(dim_t dim) const
The extent of the cartesian space in the given dimension.
Definition: Cartesian.h:181
pattern_partitioning_properties< pattern_partitioning_tag::rectangular, pattern_partitioning_tag::balanced > partitioning_properties
Satisfiable properties in pattern property category Partitioning:
Definition: TilePattern.h:59
constexpr SizeType max_blocksize() const
Maximum number of elements in a single block in all dimensions.
Definition: TilePattern.h:1338
constexpr std::array< IndexType, NumDimensions > coords(IndexType index, const ViewSpec_t &viewspec) const
Convert given global linear offset (index) to global cartesian coordinates.
Definition: TilePattern.h:1466
IndexType global_at(const std::array< IndexType, NumDimensions > &global_coords) const
Global coordinates to global position in the pattern&#39;s iteration order.
Definition: TilePattern.h:910
#define DART_UNDEFINED_UNIT_ID
Undefined unit ID.
Definition: dart_types.h:160
constexpr SizeType size() const noexcept
The number of discrete elements within the space spanned by the coordinate.
Definition: Cartesian.h:395
constexpr bool operator!=(const self_t &other) const
Inquality comparison operator.
Definition: TilePattern.h:364
SizeType 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: TilePattern.h:513
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
local_index_t local_index(const std::array< IndexType, NumDimensions > &global_coords) const
Resolves the unit and the local index from global coordinates.
Definition: TilePattern.h:702
constexpr SizeType size() const noexcept
The number of discrete elements within the space spanned by the coordinate.
Definition: Cartesian.h:164
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...
Definition: TilePattern.h:1279
constexpr dash::Team & team() const
The Team containing the units to which this pattern&#39;s elements are mapped.
Definition: TilePattern.h:1402
constexpr const extents_type & extents() const noexcept
Extents of the cartesian space, by dimension.
Definition: Cartesian.h:171
DistributionSpec describes distribution patterns of all dimensions,.
Definition: Dimensional.h:222
TilePattern(self_t &other)
Copy constructor using non-const lvalue reference parameter.
Definition: TilePattern.h:332
TilePattern & operator=(const self_t &other)=default
Assignment operator.
Generic type of mapping properties of a model satisfying the Pattern concept.