preCICE v3.1.1
Loading...
Searching...
No Matches
Communication.cpp
Go to the documentation of this file.
1#include <algorithm>
2#include <memory>
3#include <ostream>
4#include <vector>
5
6#include "Communication.hpp"
7#include "Request.hpp"
10#include "utils/assertion.hpp"
11
12namespace precice::com {
13
14void Communication::connectIntraComm(std::string const &participantName,
15 std::string const &tag,
16 int rank,
17 int size)
18{
19 if (size == 1)
20 return;
21
22 std::string primaryName = participantName + "Primary";
23 std::string secondaryName = participantName + "Secondary";
24
25 constexpr Rank rankOffset = 1;
26 int secondaryRanksSize = size - rankOffset;
27 if (rank == 0) {
28 PRECICE_INFO("Connecting Primary rank to {} Secondary ranks", secondaryRanksSize);
29 prepareEstablishment(primaryName, secondaryName);
30 acceptConnection(primaryName, secondaryName, tag, rank, rankOffset);
31 cleanupEstablishment(primaryName, secondaryName);
32 } else {
33 int secondaryRank = rank - rankOffset;
34 PRECICE_INFO("Connecting Secondary rank #{} to Primary rank", secondaryRank);
35 requestConnection(primaryName, secondaryName, tag, secondaryRank, secondaryRanksSize);
36 }
37}
38
43{
44 PRECICE_TRACE(itemsToSend.size(), itemsToReceive.size());
45 PRECICE_ASSERT(itemsToSend.size() == itemsToReceive.size());
46
47 std::copy(itemsToSend.begin(), itemsToSend.end(), itemsToReceive.begin());
48
49 std::vector<double> received(itemsToReceive.size());
50 // receive local results from secondary ranks
51 for (Rank rank : remoteCommunicatorRanks()) {
52 auto request = aReceive(received, rank + _rankOffset);
53 request->wait();
54 for (size_t i = 0; i < itemsToReceive.size(); i++) {
55 itemsToReceive[i] += received[i];
56 }
57 }
58}
59
61{
62 PRECICE_TRACE(itemsToSend.size(), itemsToReceive.size());
63 PRECICE_ASSERT(itemsToSend.size() == itemsToReceive.size());
64
65 auto request = aSend(itemsToSend, primaryRank);
66 request->wait();
67}
68
69void Communication::reduceSum(int itemToSend, int &itemToReceive)
70{
72
73 itemToReceive = itemToSend;
74
75 // receive local results from secondary ranks
76 for (Rank rank : remoteCommunicatorRanks()) {
77 auto request = aReceive(itemToSend, rank + _rankOffset);
78 request->wait();
79 itemToReceive += itemToSend;
80 }
81}
82
83void Communication::reduceSum(int itemToSend, int &itemToReceive, Rank primaryRank)
84{
86
87 auto request = aSend(itemToSend, primaryRank);
88 request->wait();
89}
90
95{
96 PRECICE_TRACE(itemsToSend.size(), itemsToReceive.size());
97 PRECICE_ASSERT(itemsToSend.size() == itemsToReceive.size());
98
99 reduceSum(itemsToSend, itemsToReceive);
100
101 // send reduced result to all secondary ranks
104 for (Rank rank : remoteCommunicatorRanks()) {
105 requests.push_back(aSend(itemsToReceive, rank + _rankOffset));
106 }
107 Request::wait(requests);
108}
109
114{
115 PRECICE_TRACE(itemsToSend.size(), itemsToReceive.size());
116 PRECICE_ASSERT(itemsToSend.size() == itemsToReceive.size());
117
118 reduceSum(itemsToSend, itemsToReceive, primaryRank);
119 // receive reduced data from primary rank
120 receive(itemsToReceive, primaryRank + _rankOffset);
121}
122
123void Communication::allreduceSum(double itemToSend, double &itemToReceive)
124{
126
127 itemToReceive = itemToSend;
128
129 // receive local results from secondary ranks
130 for (Rank rank : remoteCommunicatorRanks()) {
131 auto request = aReceive(itemToSend, rank + _rankOffset);
132 request->wait();
133 itemToReceive += itemToSend;
134 }
135
136 // send reduced result to all secondary ranks
138 for (Rank rank : remoteCommunicatorRanks()) {
139 requests[rank] = aSend(itemToReceive, rank + _rankOffset);
140 }
141 Request::wait(requests);
142}
143
144void Communication::allreduceSum(double itemToSend, double &itemsToReceive, Rank primaryRank)
145{
147
148 auto request = aSend(itemToSend, primaryRank);
149 request->wait();
150 // receive reduced data from primary rank
151 receive(itemsToReceive, primaryRank + _rankOffset);
152}
153
154void Communication::allreduceSum(int itemToSend, int &itemToReceive)
155{
157
158 itemToReceive = itemToSend;
159
160 // receive local results from secondary ranks
161 for (Rank rank : remoteCommunicatorRanks()) {
162 auto request = aReceive(itemToSend, rank + _rankOffset);
163 request->wait();
164 itemToReceive += itemToSend;
165 }
166
167 // send reduced result to all secondary ranks
169 for (Rank rank : remoteCommunicatorRanks()) {
170 requests[rank] = aSend(itemToReceive, rank + _rankOffset);
171 }
172 Request::wait(requests);
173}
174
175void Communication::allreduceSum(int itemToSend, int &itemToReceive, Rank primaryRank)
176{
178
179 auto request = aSend(itemToSend, primaryRank);
180 request->wait();
181 // receive reduced data from primary rank
182 receive(itemToReceive, primaryRank + _rankOffset);
183}
184
186{
187 PRECICE_TRACE(itemsToSend.size());
188
190
191 for (Rank rank : remoteCommunicatorRanks()) {
192 requests[rank] = aSend(itemsToSend, rank + _rankOffset);
193 }
194
195 Request::wait(requests);
196}
197
198void Communication::broadcast(precice::span<int> itemsToReceive, Rank rankBroadcaster)
199{
200 PRECICE_TRACE(itemsToReceive.size());
201
202 receive(itemsToReceive, rankBroadcaster + _rankOffset);
203}
204
205void Communication::broadcast(int itemToSend)
206{
208
210
211 for (Rank rank : remoteCommunicatorRanks()) {
212 requests[rank] = aSend(itemToSend, rank + _rankOffset);
213 }
214
215 Request::wait(requests);
216}
217
218void Communication::broadcast(int &itemToReceive, Rank rankBroadcaster)
219{
221 receive(itemToReceive, rankBroadcaster + _rankOffset);
222}
223
225{
226 PRECICE_TRACE(itemsToSend.size());
227
229
230 for (Rank rank : remoteCommunicatorRanks()) {
231 requests[rank] = aSend(itemsToSend, rank + _rankOffset);
232 }
233
234 Request::wait(requests);
235}
236
238 int rankBroadcaster)
239{
240 PRECICE_TRACE(itemsToReceive.size());
241 receive(itemsToReceive, rankBroadcaster + _rankOffset);
242}
243
244void Communication::broadcast(double itemToSend)
245{
247
249
250 for (Rank rank : remoteCommunicatorRanks()) {
251 requests[rank] = aSend(itemToSend, rank + _rankOffset);
252 }
253
254 Request::wait(requests);
255}
256
257void Communication::broadcast(double &itemToReceive, Rank rankBroadcaster)
258{
260 receive(itemToReceive, rankBroadcaster + _rankOffset);
261}
262
263void Communication::broadcast(bool itemToSend)
264{
266 int item = itemToSend;
267 broadcast(item);
268}
269
270void Communication::broadcast(bool &itemToReceive, Rank rankBroadcaster)
271{
273 int item;
274 broadcast(item, rankBroadcaster);
275 itemToReceive = item;
276}
277
279{
280 broadcast(static_cast<int>(v.size()));
282}
283
285{
286 int size = 0;
287 broadcast(size, rankBroadcaster);
288
289 v.clear();
290 v.resize(size);
291 broadcast(precice::span<int>{v}, rankBroadcaster);
292}
293
295{
296 broadcast(static_cast<int>(v.size()));
298}
299
301{
302 int size = 0;
303 broadcast(size, rankBroadcaster);
304
305 v.clear();
306 v.resize(size);
307 broadcast(precice::span<double>{v}, rankBroadcaster);
308}
309
311{
312 int size = itemsToSend.size();
313 send(size, rankReceiver);
314 if (size > 0) {
315 send(itemsToSend, rankReceiver);
316 }
317}
318
320{
321 int size = itemsToSend.size();
322 send(size, rankReceiver);
323 if (size > 0) {
324 send(itemsToSend, rankReceiver);
325 }
326}
327
329{
330 int size{-1};
331 receive(size, rankSender);
332 PRECICE_ASSERT(size >= 0);
333 std::vector<int> result;
334 if (size > 0) {
335 result.resize(size);
336 receive(result, rankSender);
337 }
338 return result;
339}
340
342{
343 int size{-1};
344 receive(size, rankSender);
345 PRECICE_ASSERT(size >= 0);
346 std::vector<double> result;
347 if (size > 0) {
348 result.resize(size);
349 receive(result, rankSender);
350 }
351 return result;
352}
353
355{
356 return rank - _rankOffset;
357}
358
360 std::string const & participantName,
361 std::string const & tag,
362 int rank,
363 int size,
364 com::Communication &left,
365 com::Communication &right)
366{
367 PRECICE_ASSERT(!left.isConnected());
368 PRECICE_ASSERT(!right.isConnected());
369 PRECICE_ASSERT(rank >= 0 && rank < size && size > 0);
370
371 if (size == 1) {
372 return;
373 }
374
375 const int prevProc = (rank - 1 + size) % size;
376 const int nextProc = (rank + 1) % size;
377
378 std::string prevName = participantName + std::to_string(prevProc);
379 std::string thisName = participantName + std::to_string(rank);
380 std::string nextName = participantName + std::to_string(nextProc);
381 if ((rank % 2) == 0) {
382 left.prepareEstablishment(prevName, thisName);
383 left.acceptConnection(prevName, thisName, tag, 0);
384 left.cleanupEstablishment(prevName, thisName);
385
386 right.requestConnection(thisName, nextName, tag, 0, 1);
387 } else {
388 right.requestConnection(thisName, nextName, tag, 0, 1);
389
390 left.prepareEstablishment(prevName, thisName);
391 left.acceptConnection(prevName, thisName, tag, 0);
392 left.cleanupEstablishment(prevName, thisName);
393 }
394}
395
396} // namespace precice::com
#define PRECICE_TRACE(...)
Definition LogMacros.hpp:95
#define PRECICE_INFO(...)
Definition LogMacros.hpp:13
#define PRECICE_ASSERT(...)
Definition assertion.hpp:87
Interface for all interprocess communication classes.
virtual void cleanupEstablishment(std::string const &acceptorName, std::string const &requesterName)
Clean-up environment used to establish the communication.
virtual PtrRequest aSend(precice::span< const int > itemsToSend, Rank rankReceiver)=0
virtual void receive(std::string &itemToReceive, Rank rankSender)=0
Receives a std::string from process with given rank.
std::vector< int > receiveRange(Rank rankSender, AsVectorTag< int >)
Receives a range of ints as a vector<int>
void connectIntraComm(std::string const &participantName, std::string const &tag, int rank, int size)
auto remoteCommunicatorRanks()
Returns a range over all valid remote ranks.
virtual void prepareEstablishment(std::string const &acceptorName, std::string const &requesterName)
Prepare environment used to establish the communication.
virtual size_t getRemoteCommunicatorSize()=0
Returns the number of processes in the remote communicator.
virtual void acceptConnection(std::string const &acceptorName, std::string const &requesterName, std::string const &tag, int acceptorRank, int rankOffset=0)=0
Accepts connection from another communicator, which has to call requestConnection().
int _rankOffset
Rank offset for primaries-secondary communication, since ranks are from 0 to size-2.
void sendRange(precice::span< const double > itemsToSend, Rank rankReceiver)
Sends a range of doubles (size + content)
virtual int adjustRank(Rank rank) const
Adjusts the given rank bases on the _rankOffset.
virtual void requestConnection(std::string const &acceptorName, std::string const &requesterName, std::string const &tag, int requesterRank, int requesterCommunicatorSize)=0
Connects to another communicator, which has to call acceptConnection().
virtual PtrRequest aReceive(precice::span< double > itemsToReceive, int rankSender)=0
Asynchronously receives an array of double values.
virtual void allreduceSum(precice::span< double const > itemsToSend, precice::span< double > itemsToReceive, Rank primaryRank)
virtual void send(std::string const &itemToSend, Rank rankReceiver)=0
Sends a std::string to process with given rank.
virtual void reduceSum(precice::span< double const > itemsToSend, precice::span< double > itemsToReceive, Rank primaryRank)
Performs a reduce summation on the rank given by primaryRank.
virtual void broadcast(precice::span< const int > itemsToSend)
virtual void wait()=0
A C++ 11 implementation of the non-owning C++20 std::span type.
Definition span.hpp:284
constexpr iterator begin() const noexcept
Definition span.hpp:503
constexpr iterator end() const noexcept
Definition span.hpp:505
constexpr size_type size() const noexcept
Definition span.hpp:469
T clear(T... args)
T copy(T... args)
contains the data communication abstraction layer.
void connectCircularComm(std::string const &participantName, std::string const &tag, int rank, int size, com::Communication &left, com::Communication &right)
int Rank
Definition Types.hpp:37
T push_back(T... args)
T reserve(T... args)
T resize(T... args)
T size(T... args)
T to_string(T... args)