Branch data Line data Source code
1 : : //
2 : : // Class Window
3 : : // Defines an interface to perform one-sided communication.
4 : : // The term RMA stands for remote memory accesss.
5 : : //
6 : : #include "Utility/IpplException.h"
7 : :
8 : : namespace ippl {
9 : : namespace mpi {
10 : : namespace rma {
11 : :
12 : : template <TargetComm Target>
13 : 60 : Window<Target>::~Window() {
14 : 60 : MPI_Win_free(&win_m);
15 : 60 : }
16 : :
17 : : template <TargetComm Target>
18 : : template <std::contiguous_iterator Iter>
19 : 60 : bool Window<Target>::create(const Communicator& comm, Iter first, Iter last) {
20 : : static_assert(isActiveTarget<Target>::value,
21 : : "No active target communication window");
22 : :
23 [ - + ]: 60 : if (allocated_m) {
24 : 0 : return false;
25 : : }
26 : 60 : allocated_m = true;
27 : :
28 : 60 : count_m = std::distance(first, last);
29 : 60 : int dispUnit = sizeof(typename Iter::value_type);
30 : 60 : MPI_Aint size = (MPI_Aint)count_m * dispUnit;
31 : 60 : MPI_Win_create(&(*first), size, dispUnit, MPI_INFO_NULL, comm, &win_m);
32 : :
33 : 60 : return allocated_m;
34 : : }
35 : :
36 : : template <TargetComm Target>
37 : : template <std::contiguous_iterator Iter>
38 : : bool Window<Target>::attach(const Communicator& comm, Iter first, Iter last) {
39 : : if (attached_m) {
40 : : return false;
41 : : }
42 : : attached_m = true;
43 : :
44 : : if (!allocated_m) {
45 : : MPI_Win_create_dynamic(MPI_INFO_NULL, comm, &win_m);
46 : : allocated_m = true;
47 : : }
48 : :
49 : : count_m = std::distance(first, last);
50 : : MPI_Aint size = (MPI_Aint)count_m * sizeof(typename Iter::value_type);
51 : : MPI_Win_attach(win_m, &(*first), size);
52 : :
53 : : return attached_m;
54 : : }
55 : :
56 : : template <TargetComm Target>
57 : : template <std::contiguous_iterator Iter>
58 : : bool Window<Target>::detach(Iter first) {
59 : : if (!attached_m) {
60 : : return false;
61 : : }
62 : : attached_m = false;
63 : : MPI_Win_detach(win_m, &(*first));
64 : : return true;
65 : : }
66 : :
67 : : template <TargetComm Target>
68 : 0 : void Window<Target>::fence(int asrt) {
69 : : static_assert(isActiveTarget<Target>::value,
70 : : "No active target communication window");
71 : 0 : MPI_Win_fence(asrt, win_m);
72 : 0 : }
73 : :
74 : : template <TargetComm Target>
75 : : template <std::contiguous_iterator Iter>
76 : : void Window<Target>::put(Iter first, Iter last, int dest, unsigned int pos,
77 : : Request* request) {
78 : : MPI_Datatype datatype = get_mpi_datatype<typename Iter::value_type>(*first);
79 : : auto count = std::distance(first, last);
80 : : if (count > count_m) {
81 : : throw IpplException("Window::put", "Count exceeds RMA window size.");
82 : : }
83 : : if (request == nullptr) {
84 : : MPI_Put(&(*first), count, datatype, dest, (MPI_Aint)pos, count, datatype,
85 : : win_m);
86 : : } else {
87 : : MPI_Rput(&(*first), count, datatype, dest, (MPI_Aint)pos, count, datatype,
88 : : win_m, *request);
89 : : }
90 : : }
91 : :
92 : : template <TargetComm Target>
93 : : template <typename T>
94 : 0 : void Window<Target>::put(const T& value, int dest, unsigned int pos, Request* request) {
95 : 0 : this->put(&value, dest, pos, request);
96 : 0 : }
97 : :
98 : : template <TargetComm Target>
99 : : template <typename T>
100 : 0 : void Window<Target>::put(const T* value, int dest, unsigned int pos, Request* request) {
101 : 0 : MPI_Datatype datatype = get_mpi_datatype<T>(*value);
102 [ # # ]: 0 : if (request == nullptr) {
103 : 0 : MPI_Put(value, 1, datatype, dest, (MPI_Aint)pos, 1, datatype, win_m);
104 : : } else {
105 : 0 : MPI_Rput(value, 1, datatype, dest, (MPI_Aint)pos, 1, datatype, win_m, *request);
106 : : }
107 : 0 : }
108 : :
109 : : template <TargetComm Target>
110 : : template <std::contiguous_iterator Iter>
111 : : void Window<Target>::get(Iter first, Iter last, int source, unsigned int pos,
112 : : Request* request) {
113 : : MPI_Datatype datatype = get_mpi_datatype<typename Iter::value_type>(*first);
114 : : auto count = std::distance(first, last);
115 : : if (count > count_m) {
116 : : throw IpplException("Window::put", "Count exceeds RMA window size.");
117 : : }
118 : : if (request == nullptr) {
119 : : MPI_Get(&(*first), count, datatype, source, (MPI_Aint)pos, count, datatype,
120 : : win_m);
121 : : } else {
122 : : MPI_Rget(&(*first), count, datatype, source, (MPI_Aint)pos, count, datatype,
123 : : win_m, *request);
124 : : }
125 : : }
126 : :
127 : : template <TargetComm Target>
128 : : template <typename T>
129 : : void Window<Target>::get(T& value, int source, unsigned int pos, Request* request) {
130 : : this->get(&value, source, pos, request);
131 : : }
132 : :
133 : : template <TargetComm Target>
134 : : template <typename T>
135 : : void Window<Target>::get(T* value, int source, unsigned int pos, Request* request) {
136 : : MPI_Datatype datatype = get_mpi_datatype<T>(*value);
137 : : if (request == nullptr) {
138 : : MPI_Get(value, 1, datatype, source, (MPI_Aint)pos, 1, datatype, win_m);
139 : : } else {
140 : : MPI_Rget(value, 1, datatype, source, (MPI_Aint)pos, 1, datatype, win_m,
141 : : *request);
142 : : }
143 : : }
144 : :
145 : : /*
146 : : * Passive target communication:
147 : : */
148 : : template <TargetComm Target>
149 : : void Window<Target>::flush(int rank) {
150 : : static_assert(!isActiveTarget<Target>::value,
151 : : "No passive target communication window");
152 : : MPI_Win_flush(rank, win_m);
153 : : }
154 : :
155 : : template <TargetComm Target>
156 : : void Window<Target>::flushall() {
157 : : static_assert(!isActiveTarget<Target>::value,
158 : : "No passive target communication window");
159 : : MPI_Win_flush_all(win_m);
160 : : }
161 : :
162 : : template <TargetComm Target>
163 : : void Window<Target>::lock(int locktype, int rank, int asrt) {
164 : : static_assert(!isActiveTarget<Target>::value,
165 : : "No passive target communication window");
166 : : MPI_Win_lock(locktype, rank, asrt, win_m);
167 : : }
168 : :
169 : : template <TargetComm Target>
170 : : void Window<Target>::lockall(int asrt) {
171 : : static_assert(!isActiveTarget<Target>::value,
172 : : "No passive target communication window");
173 : : MPI_Win_lock_all(asrt, win_m);
174 : : }
175 : :
176 : : template <TargetComm Target>
177 : : void Window<Target>::unlock(int rank) {
178 : : static_assert(!isActiveTarget<Target>::value,
179 : : "No passive target communication window");
180 : : MPI_Win_unlock(rank, win_m);
181 : : }
182 : :
183 : : template <TargetComm Target>
184 : : void Window<Target>::unlockall() {
185 : : static_assert(!isActiveTarget<Target>::value,
186 : : "No passive target communication window");
187 : : MPI_Win_unlock_all(win_m);
188 : : }
189 : :
190 : : } // namespace rma
191 : : } // namespace mpi
192 : : } // namespace ippl
|