Fenix @develop
 
Loading...
Searching...
No Matches
comm.hpp
1#ifndef FENIX_MPIXX_COMM_HPP
2#define FENIX_MPIXX_COMM_HPP
3
4#include <mpi.h>
5#include <utility>
6
7#include "fenix/mpixx/util.hpp"
8
9namespace fenix::mpixx {
10
11// RAII wrapper for MPI_Comm with move-only semantics
12// Owns an MPI_Comm handle and automatically frees it on destruction.
13// Accessors check MPI initialization state and return MPI_COMM_NULL
14// if MPI is not initialized or has been finalized.
15class Comm {
16 public:
17 explicit Comm(MPI_Comm comm) noexcept : comm_(comm) {}
18 Comm() noexcept : Comm(MPI_COMM_NULL) {}
19 virtual ~Comm() { free(); }
20
21 // frees old comm before taking ownership
22 Comm& operator=(Comm&& o);
23 Comm& operator=(MPI_Comm c) { return *this = Comm(c); }
24 Comm(Comm&& o) noexcept { *this = std::move(o); }
25
26 // Disable copy
27 Comm(const Comm&) = delete;
28 Comm& operator=(const Comm&) = delete;
29
30 MPI_Comm get() const noexcept { return mpi_active() ? comm_ : MPI_COMM_NULL; }
31
32 // Implicit conversion to MPI_Comm
33 operator MPI_Comm() const noexcept { return get(); }
34
35 explicit operator bool() const noexcept { return get() != MPI_COMM_NULL; }
36
37 // Release ownership of the communicator without freeing it
38 MPI_Comm release() noexcept;
39
40 // Basic MPI_Comm function overloads
41 int size() const;
42 int rank() const;
43 bool is_revoked() const;
44 int revoke();
45 virtual void free(); // safe even if comm_ is MPI_COMM_NULL
46
47 // Static versions taking raw MPI_Comm
48 static int size(MPI_Comm comm);
49 static int rank(MPI_Comm comm);
50 static bool is_revoked(MPI_Comm comm);
51 static int revoke(MPI_Comm comm);
52
53 // MPI_Comm creation overloads
54 Comm dup() const;
55 Comm dup_with_info(MPI_Info info) const;
56
57 Comm create(MPI_Group group) const;
58 Comm create_group(MPI_Group group, int tag) const;
59
60 Comm split(int color, int key) const;
61 Comm split_type(int split_type, int key, MPI_Info info) const;
62
63 Comm intercomm_create(
64 int local_leader, MPI_Comm peer_comm, int remote_leader, int tag
65 ) const;
66
67 Comm shrink() const;
68
69 // Static MPI_Comm creation overloads (taking an input comm)
70 static Comm dup(MPI_Comm comm);
71 static Comm dup_with_info(MPI_Comm comm, MPI_Info info);
72
73 static Comm create(MPI_Comm comm, MPI_Group group);
74 static Comm create_group(MPI_Comm comm, MPI_Group group, int tag);
75
76 static Comm split(MPI_Comm comm, int color, int key);
77 static Comm split_type(MPI_Comm comm, int split_type, int key, MPI_Info info);
78
79 static Comm intercomm_create(
80 MPI_Comm local_comm, int local_leader, MPI_Comm peer_comm,
81 int remote_leader, int tag
82 );
83
84 static Comm shrink(MPI_Comm comm);
85
86 private:
87 MPI_Comm comm_ = MPI_COMM_NULL;
88};
89
90// Non-owning reference to an MPI_Comm
91// Does not free the communicator on destruction, only releases ownership.
92// Useful for storing communicators that are owned elsewhere.
93// Unlike Comm, CommRef is copyable since it doesn't own the resource.
94class CommRef : public Comm {
95 public:
96 // Implicit constructor from MPI_Comm
97 CommRef(MPI_Comm comm = MPI_COMM_NULL) : Comm(comm) {}
98
99 // Construct from Comm (non-owning reference)
100 CommRef(const Comm& c) : Comm(c.get()) {}
101
102 // Copy operations (allowed for non-owning reference)
103 CommRef(const CommRef& o) : Comm(o.get()) {}
104 CommRef& operator=(const CommRef& o) {
105 *this = o.get();
106 return *this;
107 }
108
109 // Assign from Comm (non-owning reference)
110 CommRef& operator=(const Comm& c) {
111 *this = c.get();
112 return *this;
113 }
114
115 // Move assignment - release old comm without freeing it
116 CommRef& operator=(CommRef&& o) {
117 if (this != &o) {
118 (void)release(); // Just release the old one, don't free
119 *this = o.release(); // Assign the new comm via operator=(MPI_Comm)
120 }
121 return *this;
122 }
123 CommRef& operator=(MPI_Comm c) {
124 (void)release(); // Just release the old one, don't free
125 // Directly assign to base class via Comm's assignment operator
126 Comm::operator=(Comm(c));
127 return *this;
128 }
129
130 ~CommRef() override { (void)release(); }
131};
132
133} // namespace fenix::mpixx
134
135#endif // FENIX_MPIXX_COMM_HPP
Definition comm.hpp:94
Definition comm.hpp:15