1 #ifndef DASH__MAKE_PATTERN_H_ 2 #define DASH__MAKE_PATTERN_H_ 4 #include <dash/Pattern.h> 6 #include <dash/pattern/PatternProperties.h> 7 #include <dash/pattern/BlockPattern.h> 8 #include <dash/pattern/TilePattern.h> 9 #include <dash/pattern/ShiftTilePattern.h> 11 #include <dash/util/UnitLocality.h> 12 #include <dash/util/TeamLocality.h> 13 #include <dash/util/Locality.h> 14 #include <dash/util/Config.h> 16 #include <dash/Distribution.h> 17 #include <dash/Dimensional.h> 25 typename PartitioningTags,
30 TeamSpec<SizeSpecType::ndim::value, typename SizeSpecType::index_type>
33 const SizeSpecType & sizespec,
35 typename SizeSpecType::size_type n_nodes = 0,
36 typename SizeSpecType::size_type n_numa_dom = 0,
37 typename SizeSpecType::size_type n_cores = 0)
39 typedef typename SizeSpecType::size_type extent_t;
40 typedef typename SizeSpecType::index_type index_t;
43 const dim_t ndim = SizeSpecType::ndim::value;
46 std::array<extent_t, ndim> team_extents{};
48 team_extents[1] = n_units;
51 DASH_LOG_TRACE(
"dash::make_team_spec",
52 "step 1 - initial team extents:", team_extents);
59 auto n_elem_total = sizespec.
size();
61 std::set<extent_t> blocking;
64 blocking.insert(n_numa_dom);
65 team_extents = dash::math::balance_extents(team_extents, blocking);
67 blocking.insert(n_cores);
70 DASH_LOG_TRACE(
"dash::make_team_spec",
71 "step 2 - team extents after balancing on NUMA domains:",
73 DASH_LOG_TRACE_VAR(
"dash::make_team_spec", blocking);
79 PartitioningTags::rectangular ||
80 (!MappingTags::diagonal && !MappingTags::neighbor &&
81 !MappingTags::multiple))) {
83 DASH_LOG_TRACE(
"dash::make_team_spec",
84 "- optimizing for minimal number of blocks");
85 team_extents = dash::math::balance_extents(team_extents, blocking);
86 if (team_extents[0] == n_units) {
88 DASH_LOG_TRACE(
"dash::make_team_spec",
89 "- minimize number of blocks for blocking", blocking);
92 DASH_LOG_TRACE(
"dash::make_team_spec",
93 "step 3 - team extents after minimal partitioning:",
99 extent_t small_factor_found = 0;
100 auto team_factors_d0 = dash::math::factorize(team_extents[0]);
101 auto team_factors_d1 = dash::math::factorize(team_extents[1]);
102 DASH_LOG_TRACE(
"dash::make_team_spec",
103 "- team extent factors in dim 0:", team_factors_d0);
104 DASH_LOG_TRACE(
"dash::make_team_spec",
105 "- team extent factors in dim 1:", team_factors_d1);
107 MappingTags::multiple) {
108 DASH_LOG_TRACE(
"dash::make_team_spec",
109 "optimizing for multiple blocks per unit");
110 for (
auto small_factor_kv : team_factors_d0) {
111 auto small_factor = small_factor_kv.first;
113 if (team_extents[0] % small_factor &&
114 sizespec.extent(0) % small_factor == 0) {
115 team_extents[0] /= small_factor;
116 team_extents[1] *= small_factor;
117 small_factor_found = small_factor;
122 if (small_factor_found == 0) {
123 for (
auto small_factor_kv : team_factors_d1) {
124 auto small_factor = small_factor_kv.first;
125 if (team_extents[1] % small_factor &&
126 sizespec.extent(1) % small_factor == 0) {
127 team_extents[1] /= small_factor;
128 team_extents[0] *= small_factor;
129 small_factor_found = small_factor;
135 DASH_LOG_TRACE(
"dash::make_team_spec",
136 "- smallest blocking factor:", small_factor_found);
137 DASH_LOG_TRACE(
"dash::make_team_spec",
138 "step 4 - team extents after multiple mapping:",
142 extent_t bulk_min = std::max<extent_t>(
143 dash::util::Config::get<extent_t>(
144 "DASH_BULK_MIN_SIZE_BYTES"),
147 DASH_LOG_TRACE(
"dash::make_team_spec",
148 "- optimizing for bulk min size", bulk_min);
149 auto team_factors = dash::math::factorize(n_units);
150 extent_t block_size = 1;
151 for (
auto d = 0; d <
ndim; ++d) {
152 auto block_extent_d = sizespec.extent(d) / team_extents[d];
153 block_size *= block_extent_d;
156 if (block_size * 8 < bulk_min && small_factor_found > 0) {
158 auto unbalance_factor = team_factors_d1.begin()->first;
159 DASH_LOG_TRACE(
"dash::make_team_spec",
160 "- unbalancing with factor", unbalance_factor);
161 team_extents[0] *= unbalance_factor;
162 team_extents[1] /= unbalance_factor;
166 DASH_LOG_TRACE(
"dash::make_team_spec >",
167 "step 5 - team extents after adjusting for bulk min size:",
171 teamspec.
resize(team_extents);
179 typename PartitioningTags,
180 typename MappingTags,
187 const SizeSpecType & sizespec,
189 typename SizeSpecType::size_type n_nodes = 0,
190 typename SizeSpecType::size_type n_numa_dom = 0,
191 typename SizeSpecType::size_type n_cores = 0)
193 DASH_LOG_TRACE_VAR(
"dash::make_team_spec()", sizespec.extents());
194 DASH_LOG_TRACE_VAR(
"dash::make_team_spec", team.size());
198 n_nodes = tloc.num_nodes();
199 if (0 >= n_nodes) { n_nodes = 1; }
201 if (0 >= n_numa_dom) {
202 n_numa_dom = tloc.domain().scope_domains(
203 dash::util::Locality::Scope::NUMA).size() / n_nodes;
204 if (0 >= n_numa_dom) {
205 n_numa_dom = tloc.domain().scope_domains(
206 dash::util::Locality::Scope::Package).size() / n_nodes;
208 if (0 >= n_numa_dom) { n_numa_dom = 1; }
211 n_cores = tloc.num_cores();
212 if (0 >= n_cores) { n_cores = 1; }
239 typename PartitioningTags,
240 typename MappingTags,
248 const SizeSpecType & sizespec,
250 const TeamSpecType & teamspec)
252 typedef typename SizeSpecType::size_type extent_t;
254 DASH_LOG_TRACE(
"dash::make_distribution_spec()");
256 const dim_t ndim = SizeSpecType::ndim::value;
259 std::array<dash::Distribution, ndim> distributions = {{ }};
260 extent_t min_block_extent = sizespec.size();
261 if (PartitioningTags::minimal) {
264 for (
auto d = 0; d < SizeSpecType::ndim::value; ++d) {
265 auto extent_d = sizespec.extent(d);
266 auto nunits_d = teamspec.extent(d);
267 auto blocksize_d = extent_d / nunits_d;
268 if (blocksize_d < min_block_extent) {
269 min_block_extent = blocksize_d;
272 DASH_LOG_TRACE(
"dash::make_distribution_spec",
273 "minimum block extent for square blocks:",
277 for (
auto d = 0; d < SizeSpecType::ndim::value; ++d) {
278 auto extent_d = sizespec.extent(d);
279 auto nunits_d = teamspec.extent(d);
280 DASH_LOG_TRACE(
"dash::make_distribution_spec",
282 "extent[d]:", extent_d,
283 "nunits[d]:", nunits_d);
284 auto nblocks_d = nunits_d;
285 if (MappingTags::diagonal || MappingTags::neighbor) {
288 nblocks_d = teamspec.size();
289 DASH_LOG_TRACE(
"dash::make_distribution_spec",
290 "diagonal or neighbor mapping",
291 "d", d,
"nblocks_d", nblocks_d);
292 }
else if (PartitioningTags::minimal) {
294 nblocks_d = nunits_d;
295 if (!MappingTags::balanced) {
298 nblocks_d = extent_d / min_block_extent;
299 DASH_LOG_TRACE(
"dash::make_distribution_spec",
300 "minimal partitioning, mapping not balanced",
301 "d", d,
"nblocks_d", nblocks_d);
303 }
else if (MappingTags::balanced) {
305 if (nblocks_d % teamspec.extent(d) > 0) {
309 "dash::make_distribution_spec: cannot distribute " <<
310 nblocks_d <<
" blocks to " <<
311 nunits_d <<
" units in dimension " << d);
314 auto tilesize_d = extent_d / nblocks_d;
315 DASH_LOG_TRACE(
"dash::make_distribution_spec",
316 "tile size in dimension", d,
":", tilesize_d);
317 if (PartitioningTags::balanced) {
319 if (extent_d % tilesize_d > 0) {
323 "dash::make_distribution_spec: cannot distribute " <<
324 extent_d <<
" elements to " <<
325 nblocks_d <<
" blocks in dimension " << d);
328 if (LayoutTags::linear && LayoutTags::blocked) {
329 distributions[d] = dash::TILE(tilesize_d);
331 distributions[d] = dash::BLOCKCYCLIC(tilesize_d);
333 DASH_LOG_TRACE_VAR(
"dash::make_distribution_spec", distributions[d]);
336 DASH_LOG_TRACE_VAR(
"dash::make_distribution_spec >", distributions);
338 DASH_LOG_TRACE_VAR(
"dash::make_distribution_spec >", distspec);
363 typename std::enable_if<
364 !MappingTags::diagonal &&
365 PartitioningTags::rectangular &&
366 PartitioningTags::balanced &&
367 !PartitioningTags::unbalanced &&
371 typename SizeSpecType::index_type>
375 const SizeSpecType & sizespec,
377 const TeamSpecType & teamspec)
380 const dim_t ndim = SizeSpecType::ndim::value;
382 typedef typename SizeSpecType::index_type index_t;
384 DASH_LOG_TRACE(
"dash::make_pattern", PartitioningTags());
385 DASH_LOG_TRACE(
"dash::make_pattern", MappingTags());
386 DASH_LOG_TRACE(
"dash::make_pattern", LayoutTags());
387 DASH_LOG_TRACE_VAR(
"dash::make_pattern", sizespec.extents());
388 DASH_LOG_TRACE_VAR(
"dash::make_pattern", teamspec.extents());
400 pattern_t pattern(sizespec,
430 typename std::enable_if<
431 MappingTags::diagonal &&
432 (LayoutTags::blocked ||
433 (PartitioningTags::balanced &&
434 SizeSpecType::ndim::value == 1)),
437 typename SizeSpecType::index_type>
441 const SizeSpecType & sizespec,
443 const TeamSpecType & teamspec)
446 const dim_t ndim = SizeSpecType::ndim::value;
448 typedef typename SizeSpecType::index_type index_t;
450 DASH_LOG_TRACE(
"dash::make_pattern", PartitioningTags());
451 DASH_LOG_TRACE(
"dash::make_pattern", MappingTags());
452 DASH_LOG_TRACE(
"dash::make_pattern", LayoutTags());
453 DASH_LOG_TRACE_VAR(
"dash::make_pattern", sizespec.extents());
454 DASH_LOG_TRACE_VAR(
"dash::make_pattern", teamspec.extents());
466 pattern_t pattern(sizespec,
491 typename std::enable_if<
492 LayoutTags::canonical,
495 typename SizeSpecType::index_type >
499 const SizeSpecType & sizespec,
501 const TeamSpecType & teamspec)
504 const dim_t ndim = SizeSpecType::ndim::value;
506 typedef typename SizeSpecType::index_type index_t;
508 DASH_LOG_TRACE(
"dash::make_pattern", PartitioningTags());
509 DASH_LOG_TRACE(
"dash::make_pattern", MappingTags());
510 DASH_LOG_TRACE(
"dash::make_pattern", LayoutTags());
522 pattern_t pattern(sizespec,
530 #endif // DASH__MAKE_PATTERN_H_
Defines how a list of global indices is mapped to single units within a Team.
This class is a simple memory pool which holds allocates elements of size ValueType.
int dim_t
Scalar type for a dimension value, with 0 indicating the first dimension.
std::enable_if< !MappingTags::diagonal &&PartitioningTags::rectangular &&PartitioningTags::balanced &&!PartitioningTags::unbalanced &&LayoutTags::blocked, TilePattern< SizeSpecType::ndim::value, dash::ROW_MAJOR, typename SizeSpecType::index_type >>::type make_pattern(const SizeSpecType &sizespec, const TeamSpecType &teamspec)
Generic Abstract Factory for models of the Pattern concept.
Defines how a list of global indices is mapped to single units within a Team.
DistributionSpec< SizeSpecType::ndim::value > make_distribution_spec(const SizeSpecType &sizespec, const TeamSpecType &teamspec)
Generic Abstract Factory for instances of dash::DistributionSpec.
A Team instance specifies a subset of all available units.
Defines how a list of global indices is mapped to single units within a Team.
constexpr dim_t ndim(const DimensionalType &d)
Specifies the arrangement of team units in a specified number of dimensions.
Hierarchical locality domains of a specified team.
TeamSpec< SizeSpecType::ndim::value, typename SizeSpecType::index_type > make_team_spec(const SizeSpecType &sizespec, int n_units, typename SizeSpecType::size_type n_nodes=0, typename SizeSpecType::size_type n_numa_dom=0, typename SizeSpecType::size_type n_cores=0)
constexpr SizeType size() const noexcept
The number of discrete elements within the space spanned by the coordinate.
void resize(SizeType arg, Args... args)
Change the extent of the cartesian space in every dimension.
static Team & All()
The invariant Team instance containing all available units.
DistributionSpec describes distribution patterns of all dimensions,.
Generic type of mapping properties of a model satisfying the Pattern concept.