-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Content of include/mpi was refactored into its own repo
Now we use it via contrib/ directory
- Loading branch information
Showing
24 changed files
with
1,269 additions
and
985 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
#pragma once | ||
|
||
#include "mpi.h" | ||
|
||
enum { UNDEFINED = MPI_UNDEFINED, ANY_SOURCE = MPI_ANY_SOURCE, ANY_TAG = MPI_ANY_TAG }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
#pragma once | ||
|
||
#include "fmt/printf.h" | ||
#include "mpi.h" | ||
|
||
namespace mpicpp_lite { | ||
|
||
inline int | ||
error_class(int code) | ||
{ | ||
int err_class; | ||
MPI_Error_class(code, &err_class); | ||
return err_class; | ||
} | ||
|
||
/// Return an error message for a given error code | ||
/// | ||
/// @param code Error code | ||
/// @return Error message | ||
inline std::string | ||
error_message(int code) | ||
{ | ||
char buffer[MPI_MAX_ERROR_STRING]; | ||
int len; | ||
MPI_Error_string(code, buffer, &len); | ||
std::string msg(buffer); | ||
return msg; | ||
} | ||
|
||
namespace internal { | ||
|
||
/// Terminate the run | ||
inline void | ||
terminate(MPI_Comm comm, int status = 1) | ||
{ | ||
MPI_Abort(comm, status); | ||
} | ||
|
||
inline void | ||
check_mpi_error(MPI_Comm comm, int ierr, const char * file, int line) | ||
{ | ||
if (ierr) { | ||
fmt::print(stderr, | ||
"[ERROR] MPI error {} at {}:{}: {}\n", | ||
ierr, | ||
file, | ||
line, | ||
error_message(error_class(ierr))); | ||
terminate(comm, ierr); | ||
} | ||
} | ||
|
||
} // namespace internal | ||
|
||
/// Check that MPI call was successful. | ||
#define MPI_CHECK_SELF(ierr) \ | ||
mpicpp_lite::internal::check_mpi_error(this->comm, ierr, __FILE__, __LINE__) | ||
|
||
#define MPI_CHECK(ierr) \ | ||
mpicpp_lite::internal::check_mpi_error(MPI_COMM_WORLD, ierr, __FILE__, __LINE__) | ||
|
||
} // namespace mpicpp_lite |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,187 @@ | ||
#pragma once | ||
|
||
#include "mpi.h" | ||
#include "Enums.h" | ||
#include "Error.h" | ||
|
||
namespace mpicpp_lite { | ||
|
||
/// Wrapper around `MPI_Group` | ||
class Group { | ||
public: | ||
enum ComparisonResult { IDENTICAL = MPI_IDENT, SIMILAR = MPI_SIMILAR, UNEQUAL = MPI_UNEQUAL }; | ||
|
||
/// Create group from an `MPI_Group` | ||
/// | ||
/// @param group `MPI_Group` used to initialize this object | ||
Group(const MPI_Group & group); | ||
|
||
/// Returns the rank of this process in the given group | ||
/// | ||
/// @return Rank of the calling process in group, or MPI_UNDEFINED if the process is not a | ||
/// member | ||
int rank() const; | ||
|
||
/// Returns the size of a group | ||
/// | ||
/// @return Number of processes in the group | ||
int size() const; | ||
|
||
/// Produces a group by reordering an existing group and taking only listed members | ||
/// | ||
/// @param ranks Ranks of processes in group to appear in the new group | ||
/// @return New group derived from this group, in the order defined by `ranks` | ||
Group include(const std::vector<int> & ranks) const; | ||
|
||
/// Produces a group by reordering an existing group and taking only unlisted members | ||
/// | ||
/// @param ranks Array of integer ranks of processes in group not to appear in the new group | ||
/// @return New group derived from this group, preserving the order defined by group | ||
Group exclude(const std::vector<int> & ranks) const; | ||
|
||
/// Frees the group | ||
void free(); | ||
|
||
/// Translates the rank of a process in one group to the one in another group | ||
/// | ||
/// @param in_rank Rank in this group | ||
/// @param out_group Destination group | ||
/// @return Rank in destination group, or `UNDEFINED` when no correspondence exists | ||
int translate_rank(int in_rank, const Group & out_group); | ||
|
||
/// Translates the ranks of processes in one group to those in another group | ||
/// | ||
/// @param in_ranks Array of valid ranks in this group | ||
/// @param out_group Destination group | ||
/// @return Array of corresponding ranks in destination group, `UNDEFINED` when no | ||
/// correspondence exists | ||
std::vector<int> translate_ranks(const std::vector<int> & in_ranks, const Group & out_group); | ||
|
||
/// Type cast operator so we can pass this class directly into MPI calls | ||
operator const MPI_Group &() const { return this->group; } | ||
|
||
public: | ||
/// Compares two groups | ||
/// | ||
/// @param g1 First group | ||
/// @param g2 Second group | ||
/// @return `IDENTICAL` if the order and members of the two groups are the same, `SIMILAR` if | ||
/// only the members are the same, and `UNEQUAL` otherwise | ||
static ComparisonResult compare(const Group & g1, const Group & g2); | ||
|
||
/// Produces a group by combining two groups | ||
/// | ||
/// @param g1 First group | ||
/// @param g2 Second group | ||
/// @return Union group | ||
static Group join(const Group & g1, const Group & g2); | ||
|
||
/// Produces a group as the intersection of two existing groups | ||
/// | ||
/// @param g1 First group | ||
/// @param g2 Second group | ||
/// @return Intersection group | ||
static Group intersection(const Group & g1, const Group & g2); | ||
|
||
/// Makes a group from the difference of two groups | ||
/// | ||
/// @param g1 First group | ||
/// @param g2 Second group | ||
/// @return Difference group | ||
static Group difference(const Group & g1, const Group & g2); | ||
|
||
private: | ||
MPI_Group group; | ||
}; | ||
|
||
inline Group::Group(const MPI_Group & group) : group(group) {} | ||
|
||
inline Group | ||
Group::include(const std::vector<int> & ranks) const | ||
{ | ||
MPI_Group new_group; | ||
MPI_CHECK(MPI_Group_incl(this->group, ranks.size(), ranks.data(), &new_group)); | ||
return { new_group }; | ||
} | ||
|
||
inline Group | ||
Group::exclude(const std::vector<int> & ranks) const | ||
{ | ||
MPI_Group new_group; | ||
MPI_CHECK(MPI_Group_excl(this->group, ranks.size(), ranks.data(), &new_group)); | ||
return { new_group }; | ||
} | ||
|
||
inline void | ||
Group::free() | ||
{ | ||
MPI_CHECK(MPI_Group_free(&this->group)); | ||
this->group = UNDEFINED; | ||
} | ||
|
||
inline int | ||
Group::rank() const | ||
{ | ||
int r; | ||
MPI_CHECK(MPI_Group_rank(this->group, &r)); | ||
return r; | ||
} | ||
|
||
inline int | ||
Group::size() const | ||
{ | ||
int sz; | ||
MPI_CHECK(MPI_Group_size(this->group, &sz)); | ||
return sz; | ||
} | ||
|
||
inline int | ||
Group::translate_rank(int in_rank, const Group & out_group) | ||
{ | ||
int out_rank; | ||
MPI_CHECK(MPI_Group_translate_ranks(this->group, 1, &in_rank, out_group, &out_rank)); | ||
return out_rank; | ||
} | ||
|
||
inline std::vector<int> | ||
Group::translate_ranks(const std::vector<int> & in_ranks, const Group & out_group) | ||
{ | ||
int n = in_ranks.size(); | ||
std::vector<int> ranks2(n); | ||
MPI_CHECK(MPI_Group_translate_ranks(this->group, n, in_ranks.data(), out_group, ranks2.data())); | ||
return ranks2; | ||
} | ||
|
||
inline Group::ComparisonResult | ||
Group::compare(const Group & g1, const Group & g2) | ||
{ | ||
int result; | ||
MPI_CHECK(MPI_Group_compare(g1, g2, &result)); | ||
return static_cast<ComparisonResult>(result); | ||
} | ||
|
||
inline Group | ||
Group::join(const Group & g1, const Group & g2) | ||
{ | ||
MPI_Group new_group; | ||
MPI_CHECK(MPI_Group_union(g1, g2, &new_group)); | ||
return { new_group }; | ||
} | ||
|
||
inline Group | ||
Group::intersection(const Group & g1, const Group & g2) | ||
{ | ||
MPI_Group new_group; | ||
MPI_CHECK(MPI_Group_intersection(g1, g2, &new_group)); | ||
return { new_group }; | ||
} | ||
|
||
inline Group | ||
Group::difference(const Group & g1, const Group & g2) | ||
{ | ||
MPI_Group new_group; | ||
MPI_CHECK(MPI_Group_difference(g1, g2, &new_group)); | ||
return { new_group }; | ||
} | ||
|
||
} // namespace mpicpp_lite |
Oops, something went wrong.