Skip to content

Commit 7a4661b

Browse files
hmenkeMobellaaj
andcommitted
Expand API surface and test cases
This adds a new abstraction for MPI_Group to be able to use the post-start-complete-wait RMA cycle. Also adds documentation and more tests. Co-authored-by: Mohamed Aziz Bellaaj <aziiizbelaj@gmail.com>
1 parent f61a0e6 commit 7a4661b

File tree

6 files changed

+736
-141
lines changed

6 files changed

+736
-141
lines changed

c++/mpi/group.hpp

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
// Copyright (c) 2024 Simons Foundation
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0.txt
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
//
15+
// Authors: Thomas Hahn, Alexander Hampel, Olivier Parcollet, Nils Wentzell
16+
17+
/**
18+
* @file
19+
* @brief Provides a C++ wrapper class for an @p MPI_Group object.
20+
*/
21+
22+
#pragma once
23+
24+
#include "./communicator.hpp"
25+
#include "./environment.hpp"
26+
27+
#include <mpi.h>
28+
29+
#include <cstdlib>
30+
#include <unistd.h>
31+
32+
namespace mpi {
33+
34+
/**
35+
* @ingroup mpi_essentials
36+
* @brief C++ wrapper around @p MPI_Group providing various convenience functions.
37+
*
38+
* @details It stores an @p MPI_Group object as its only member which by default is set to @p MPI_GROUP_NULL.
39+
*/
40+
class group {
41+
// Wrapped @p MPI_Group object.
42+
MPI_Group _grp = MPI_GROUP_NULL;
43+
44+
public:
45+
/// Construct a communicator with @p MPI_GROUP_NULL.
46+
group() = default;
47+
48+
/// Deleted copy constructor.
49+
group(group const &) = delete;
50+
51+
/// Deleted copy assignment operator.
52+
group &operator=(group const &) = delete;
53+
54+
/// Move constructor leaves moved-from object with @p MPI_GROUP_NULL.
55+
group(group &&other) noexcept : _grp{std::exchange(other._grp, MPI_GROUP_NULL)} {}
56+
57+
/// Move assignment operator leaves moved-from object with @p MPI_GROUP_NULL.
58+
group &operator=(group &&rhs) noexcept {
59+
if (this != std::addressof(rhs)) {
60+
this->free();
61+
this->_grp = std::exchange(rhs._grp, MPI_GROUP_NULL);
62+
}
63+
return *this;
64+
}
65+
66+
/**
67+
* @brief Take ownership of an existing @p MPI_Group object.
68+
* @param grp The group to be handled.
69+
*/
70+
explicit group(MPI_Group grp) : _grp(grp) {}
71+
72+
/**
73+
* @brief Create a group from a communicator.
74+
* @param c The communicator from which to create a group.
75+
*/
76+
explicit group(communicator c) {
77+
if (has_env) { MPI_Comm_group(c.get(), &_grp); }
78+
}
79+
80+
/// Get the wrapped @p MPI_Group object.
81+
[[nodiscard]] MPI_Group get() const noexcept { return _grp; }
82+
83+
/// Check if the contained @p MPI_Group is @p MPI_GROUP_NULL.
84+
[[nodiscard]] bool is_null() const noexcept { return _grp == MPI_GROUP_NULL; }
85+
86+
/// Rank of the calling process in the given group.
87+
[[nodiscard]] int rank() const {
88+
int rank = 0;
89+
if (has_env) { MPI_Group_rank(_grp, &rank); }
90+
return rank;
91+
}
92+
93+
/// Size of a group.
94+
[[nodiscard]] int size() const {
95+
int size = 1;
96+
if (has_env) { MPI_Group_size(_grp, &size); }
97+
return size;
98+
}
99+
100+
/**
101+
* @brief Produces a group by reordering an existing group and taking only listed members.
102+
* @param ranks List of ranks to include in the new group.
103+
* @returns New group containing only the listed members.
104+
*/
105+
group incl(std::vector<int> const &ranks) const {
106+
MPI_Group newgroup = MPI_GROUP_NULL;
107+
if (has_env) { MPI_Group_incl(_grp, ranks.size(), ranks.data(), &newgroup); }
108+
return group(newgroup);
109+
}
110+
111+
/// Free the group.
112+
void free() {
113+
if (has_env) {
114+
if (_grp != MPI_GROUP_NULL) { MPI_Group_free(&_grp); }
115+
}
116+
}
117+
};
118+
119+
} // namespace mpi

0 commit comments

Comments
 (0)