KaMPIng 0.1.0
(Near) zero-overhead C++ MPI bindings.
Loading...
Searching...
No Matches
rank_ranges.hpp
Go to the documentation of this file.
1// This file is part of KaMPIng.
2//
3// Copyright 2023 The KaMPIng Authors
4//
5// KaMPIng is free software : you can redistribute it and/or modify it under the terms of the GNU Lesser General Public
6// License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later
7// version. KaMPIng is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
8// implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
9// for more details.
10//
11// You should have received a copy of the GNU Lesser General Public License along with KaMPIng. If not, see
12// <https://www.gnu.org/licenses/>.
13
14/// @file
15/// @brief Defines utility classes for communicator creation using range based ranks descriptions.
16///
17#pragma once
18
19#include <algorithm>
20#include <cstddef>
21
22namespace kamping {
23/// @brief Struct encapsulating a MPI rank range triplet as used in functions like \c MPI_Group_range_incl/excl.
24///
25struct RankRange {
26 int first; ///< First rank contained in the rank range.
27 int last; ///< Last rank contained in the rank range.
28 int stride; ///< Stride used in the rank range.
29};
30
31/// @brief RankRanges encapsulate multiple rank ranges which are used in functions like \c MPI_Group_range_incl/excl.
32///
33/// \c MPI_Group_range_incl/excl use multidimensional integer arrays to represent rank ranges. One can therefore use
34/// plain c-style multi dimensional arrays directly which results in a zero-cost abstraction or use any container type
35/// storing \c RankRange object which are then converted to the required plain c-style array.
37public:
38 /// @brief Constructor taking a plain two dimension c-style array.
39 /// @param rank_range_array Pointer to int[3] representing contiguously stored plain MPI rank ranges.
40 /// @param size Number of ranges stored in this array.
41 RankRanges(int (*rank_range_array)[3], size_t size)
42 : _is_lib_allocated{false},
43 _rank_range_array{rank_range_array},
44 _size{size} {}
45
46 /// @brief Constructor taking any container storing \c RankRange objects.
47 /// @param ranges Container storing \c RankRange objects.
48 template <typename RangeContainer>
50 : _is_lib_allocated{true},
51 _rank_range_array{new int[ranges.size()][3]},
52 _size{ranges.size()} {
53 static_assert(
54 std::is_same_v<typename RangeContainer::value_type, RankRange>,
55 "Container's value_type must be RankRange!"
56 );
57
58 for (size_t i = 0; i < ranges.size(); ++i) {
59 auto const& range = ranges[i];
60 _rank_range_array[i][0] = range.first;
61 _rank_range_array[i][1] = range.last;
62 _rank_range_array[i][2] = range.stride;
63 }
64 }
65
66 ///@brief Destroys objects and deallocates any memory allocated during construction.
68 if (_is_lib_allocated) {
69 delete[] _rank_range_array;
70 }
71 }
72
73 /// @brief Get non-owning access to the underlying c-style array storing the rank ranges.
74 /// @return Underlying c-style array of type int (*)[3].
75 auto get() const {
76 return _rank_range_array;
77 }
78
79 /// @brief Number of ranges stored in this object.
80 /// @return Number of ranges.
81 auto size() const {
82 return _size;
83 }
84
85 /// @brief Checks whether the rank ranges contain a certain rank.
86 /// @return Whether rank ranges contain a certain rank.
87 bool contains(int rank) const {
88 return std::any_of(_rank_range_array, _rank_range_array + _size, [&](auto const& plain_rank_range) {
90 bool const is_between_bounds = rank >= rank_range.first && rank <= rank_range.last;
91 int const diff_to_start = rank - rank_range.first;
92 bool const is_multiple_of_stride = diff_to_start % rank_range.stride == 0;
94 });
95 }
96
97private:
98 bool const _is_lib_allocated; ///< Flag indicating whether the array needs to be freed upon object construction.
99 int (*_rank_range_array)[3]; ///< Underlying c-style array of type int (*)[3].
100 size_t _size; ///< Number of ranges stored in this object.
101};
102} // namespace kamping
STL-compatible allocator for requesting memory using the builtin MPI allocator.
Definition allocator.hpp:32
RankRanges encapsulate multiple rank ranges which are used in functions like MPI_Group_range_incl/exc...
Definition rank_ranges.hpp:36
auto get() const
Get non-owning access to the underlying c-style array storing the rank ranges.
Definition rank_ranges.hpp:75
RankRanges(int(*rank_range_array)[3], size_t size)
Constructor taking a plain two dimension c-style array.
Definition rank_ranges.hpp:41
auto size() const
Number of ranges stored in this object.
Definition rank_ranges.hpp:81
~RankRanges()
Destroys objects and deallocates any memory allocated during construction.
Definition rank_ranges.hpp:67
bool contains(int rank) const
Checks whether the rank ranges contain a certain rank.
Definition rank_ranges.hpp:87
RankRanges(RangeContainer const &ranges)
Constructor taking any container storing RankRange objects.
Definition rank_ranges.hpp:49
Struct encapsulating a MPI rank range triplet as used in functions like MPI_Group_range_incl/excl.
Definition rank_ranges.hpp:25
int first
First rank contained in the rank range.
Definition rank_ranges.hpp:26
int stride
Stride used in the rank range.
Definition rank_ranges.hpp:28
int last
Last rank contained in the rank range.
Definition rank_ranges.hpp:27