1 #ifndef DASH__TEAM_SPEC_H_ 2 #define DASH__TEAM_SPEC_H_ 4 #include <dash/Types.h> 5 #include <dash/Dimensional.h> 6 #include <dash/Exception.h> 7 #include <dash/Cartesian.h> 8 #include <dash/internal/Logging.h> 16 #include <type_traits> 17 #include <initializer_list> 37 typedef typename std::make_unsigned<IndexType>::type
55 DASH_LOG_TRACE_VAR(
"TeamSpec(t)", team.is_null());
56 auto team_size = team.is_null() ? 0 : team.size();
58 this->_extents[0] = team_size;
59 for (
auto d = 1; d < MaxDimensions; ++d) {
60 this->_extents[d] = 1;
62 this->
resize(this->_extents);
96 DASH_LOG_TRACE_VAR(
"TeamSpec(ts, dist, t)", team.is_null());
98 if (this->
size() != team.size()) {
101 "Size of team " << team.size() <<
" differs from " <<
102 "size of teamspec " << this->
size() <<
" in TeamSpec()");
107 if (other._is_linear && distribution.
rank() > 1) {
111 bool major_tiled_dim_set =
false;
112 for (
auto d = 0; d < MaxDimensions; ++d) {
113 this->_extents[d] = 1;
114 if (!major_tiled_dim_set &&
115 distribution[d].type == dash::internal::DIST_TILE) {
116 this->_extents[d] = team.size();
117 major_tiled_dim_set =
true;
121 for (
auto d = 0; d < MaxDimensions; ++d) {
122 if (distribution[d].type == dash::internal::DIST_NONE) {
123 this->_extents[d] = 1;
127 this->_extents[d] = team.size();
133 DASH_LOG_TRACE_VAR(
"TeamSpec(ts, dist, t)", this->_extents);
134 this->
resize(this->_extents);
135 DASH_LOG_TRACE_VAR(
"TeamSpec(ts, dist, t)", this->
size());
148 DASH_LOG_TRACE_VAR(
"TeamSpec(dist, t)", team.is_null());
149 bool distrib_dim_set =
false;
151 bool major_tiled_dim_set =
false;
152 for (
auto d = 0; d < MaxDimensions; ++d) {
153 this->_extents[d] = 1;
154 if (!major_tiled_dim_set &&
155 distribution[d].type == dash::internal::DIST_TILE) {
156 this->_extents[d] = team.size();
157 major_tiled_dim_set =
true;
161 for (
auto d = 0; d < MaxDimensions; ++d) {
162 if (distribution[d].type == dash::internal::DIST_NONE) {
163 this->_extents[d] = 1;
165 this->_extents[d] = team.size();
166 if (distrib_dim_set) {
169 "TeamSpec(DistributionSpec, Team) only allows " 170 "one distributed dimension");
172 distrib_dim_set =
true;
177 DASH_LOG_TRACE_VAR(
"TeamSpec(dist, t)", this->_extents);
178 this->
resize(this->_extents);
179 DASH_LOG_TRACE_VAR(
"TeamSpec(dist, t)", this->
size());
192 template<
typename ... Types>
199 this->
resize(this->_extents);
200 DASH_LOG_TRACE_VAR(
"TeamSpec(size,...)", this->_extents);
219 this->
resize(this->_extents);
220 DASH_LOG_TRACE_VAR(
"TeamSpec({extents})", this->_extents);
236 DASH_LOG_TRACE_VAR(
"TeamSpec.balance_extents()", this->_extents);
237 DASH_LOG_TRACE_VAR(
"TeamSpec.balance_extents()", this->
size());
238 if(MaxDimensions <= 1) {
242 std::multiset<SizeType> new_extents;
245 for (
auto d = 0; d < MaxDimensions; ++d) {
246 num_units *= this->_extents[d];
247 this->_extents[d] = 1;
248 new_extents.insert(1);
253 auto teamsize_prime_factors = dash::math::factorize(num_units);
257 for (
auto it = teamsize_prime_factors.rbegin();
258 it != teamsize_prime_factors.rend();
260 DASH_LOG_TRACE(
"TeamSpec.balance_extents()",
261 "factor:", it->first,
"x", it->second);
262 for (
auto i = 1; i < it->second + 1; ++i) {
263 new_extents.insert(it->first * *new_extents.begin());
264 new_extents.erase(new_extents.begin());
269 for (
auto it = new_extents.rbegin();
270 it != new_extents.rend();
272 this->_extents[d] = *it;
275 this->
resize(this->_extents);
277 DASH_LOG_TRACE_VAR(
"TeamSpec.balance_extents() ->", this->_extents);
300 auto neighbor_coords = this->
coords(_myid);
302 for (
auto offset_d : offsets) {
303 neighbor_coords[d] += offset_d;
304 if (neighbor_coords[d] < 0 ||
305 neighbor_coords[d] >= this->_extents[d]) {
310 return team_unit_t(static_cast<dart_unit_t>(this->
at(neighbor_coords)));
315 auto neighbor_coords = this->
coords(_myid);
316 for (
dim_t d = 0; d < MaxDimensions; ++d) {
317 neighbor_coords[d] += offsets[d];
318 if (neighbor_coords[d] < 0 ||
319 neighbor_coords[d] >= this->_extents[d]) {
323 return team_unit_t(static_cast<dart_unit_t>(this->
at(neighbor_coords)));
352 auto neighbor_coords = this->
coords(_myid);
354 for (
auto offset_d : offsets) {
355 neighbor_coords[d] += offset_d;
356 if (neighbor_coords[d] < 0) {
357 neighbor_coords[d] = this->_extents[d] + offset_d;
358 }
else if(neighbor_coords[d] >= this->_extents[d]) {
359 neighbor_coords[d] %= this->_extents[d];
363 return team_unit_t(static_cast<dart_unit_t>(this->
at(neighbor_coords)));
368 auto neighbor_coords = this->
coords(_myid);
370 for (
dim_t d = 0; d < MaxDimensions; ++d) {
371 neighbor_coords[d] += offsets[d];
372 if (neighbor_coords[d] < 0) {
373 neighbor_coords[d] = this->_extents[d] + offsets[d];
374 }
else if(neighbor_coords[d] >= this->_extents[d]) {
375 neighbor_coords[d] %= this->_extents[d];
378 return team_unit_t(static_cast<dart_unit_t>(this->
at(neighbor_coords)));
388 IndexType dim_offset)
const 392 return (index >= 0 && index < this->
size());
394 return parent_t::includes_index(index, dimension, dim_offset);
411 template<
typename... Args>
415 sizeof...(Args) == MaxDimensions-1,
416 "Invalid number of arguments");
417 std::array<SizeType, MaxDimensions>
extents =
418 {{ arg, (SizeType)(args)... }};
425 template<
typename SizeType_>
438 this->_extents[dim] =
extent;
463 for (
auto d = 0; d < MaxDimensions; ++d) {
464 if (this->_extents[d] > 1) {
468 if (_rank == 0) _rank = 1;
475 bool _is_linear =
false;
483 #endif // DASH__TEAM_SPEC_H_ constexpr team_unit_t UNDEFINED_TEAM_UNIT_ID
Invalid local unit ID.
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...
global_unit_t myid()
Shortcut to query the global unit ID of the calling unit.
constexpr std::enable_if< std::is_integral< IndexType >::value, IndexType >::type index(IndexType idx)
This class is a simple memory pool which holds allocates elements of size ValueType.
constexpr dim_t rank() const
The number of dimensions of the value.
bool is_tiled() const
Whether the distribution is tiled in any dimension.
dim_t rank() const
The actual number of dimensions with extent greater than 1 in this team arragement, that is the dimension of the vector space spanned by the team arrangement's extents.
TeamSpec(const DistributionSpec< MaxDimensions > &distribution, Team &team=dash::Team::All())
Constructor, creates an instance of TeamSpec from a team (set of units) and a distribution spec...
int dim_t
Scalar type for a dimension value, with 0 indicating the first dimension.
void balance_extents()
Tries to equally distribute the units across the dimensions.
void resize(SizeType arg, Args... args)
Change the extent of the cartesian space in every dimension.
internal::default_signed_index default_index_t
Signed integer type used as default for index values.
A Team instance specifies a subset of all available units.
constexpr const extents_type & extents() const noexcept
Extents of the cartesian space, by dimension.
std::array< IndexType, NumDimensions > coords(IndexType index) const
Convert given linear offset (index) to cartesian coordinates.
SizeType extent(dim_t dim) const
The extent of the cartesian space in the given dimension.
TeamSpec(SizeType value, Types ... values)
Constructor, initializes new instance of TeamSpec with extents specified in argument list...
Defines a cartesian, totally-ordered index space by mapping linear indices to cartesian coordinates d...
TeamSpec(Team &team=dash::Team::All())
Constructor, creates an instance of TeamSpec from a team (set of units) with all team units organized...
void resize_dim(dim_t dim, SizeType extent)
Change the extent of the cartesian space in the given dimension.
team_unit_t neighbor(std::initializer_list< int > offsets) const
Resolve unit id at given offset in Cartesian team grid relative to the active unit's position in the ...
constexpr IndexType at(IndexType arg, Args... args) const
Convert the given coordinates to their respective linear index.
Specifies the arrangement of team units in a specified number of dimensions.
SizeType num_units(dim_t dimension) const
The number of units (extent) available in the given dimension.
struct dash::unit_id< dash::local_unit, dart_team_unit_t > team_unit_t
Unit ID to use for team-local IDs.
team_unit_t periodic_neighbor(std::initializer_list< int > offsets) const
Resolve unit id at given offset in Cartesian team grid relative to the active unit's position in the ...
TeamSpec(const std::array< SizeType, MaxDimensions > &extents)
Constructor, initializes new instance of TeamSpec with extents specified in array by dimension...
TeamSpec(const self_t &other, const DistributionSpec< MaxDimensions > &distribution, Team &team=dash::Team::All())
Constructor, creates an instance of TeamSpec with given extents from a team (set of units) and a dist...
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.
void resize(const std::array< SizeType_, MaxDimensions > &extents)
Change the extent of the cartesian space in every dimension.
DistributionSpec describes distribution patterns of all dimensions,.