2#include <boost/container/flat_map.hpp>
3#include <boost/io/ios_state.hpp>
36 communication->send(
static_cast<int>(m.
size()), rankReceiver);
38 for (
auto const &i : m) {
39 auto const &rank = i.first;
40 auto const &indices = i.second;
41 communication->send(rank, rankReceiver);
42 communication->sendRange(indices, rankReceiver);
53 communication->receive(size, rankSender);
57 communication->receive(rank, rankSender);
58 m[rank] = communication->receiveRange(rankSender, AsVectorTag<int>{});
65 communication->broadcast(
static_cast<int>(m.
size()));
67 for (
auto const &i : m) {
68 auto const &rank = i.first;
69 auto const &indices = i.second;
70 communication->broadcast(rank);
71 communication->broadcast(indices);
81 communication->broadcast(size, rankBroadcaster);
85 communication->broadcast(rank, rankBroadcaster);
86 communication->broadcast(m[rank], rankBroadcaster);
108 for (
auto &j : i.second) {
109 oss << i.first <<
":" << j <<
'\n';
140 maximum =
std::max(maximum,
static_cast<size_t>(size));
141 minimum =
std::min(minimum,
static_cast<size_t>(size));
151 maximum =
std::max(maximum,
static_cast<size_t>(size));
152 minimum =
std::min(minimum,
static_cast<size_t>(size));
157 if (minimum > maximum)
160 auto average =
static_cast<double>(total);
167 <<
"Number of Communication Partners per Interface Process:"
169 <<
" Total: " << total <<
"\n"
170 <<
" Maximum: " << maximum <<
"\n"
171 <<
" Minimum: " << minimum <<
"\n"
172 <<
" Average: " << average <<
"\n"
173 <<
"Number of Interface Processes: " << count <<
"\n"
186 size += i.second.size();
196 maximum =
std::max(maximum,
static_cast<size_t>(size));
197 minimum =
std::min(minimum,
static_cast<size_t>(size));
208 maximum =
std::max(maximum,
static_cast<size_t>(size));
209 minimum =
std::min(minimum,
static_cast<size_t>(size));
215 if (minimum > maximum)
218 auto average =
static_cast<double>(total);
225 <<
"Number of LVDIs per Interface Process:"
227 <<
" Total: " << total <<
'\n'
228 <<
" Maximum: " << maximum <<
'\n'
229 <<
" Minimum: " << minimum <<
'\n'
230 <<
" Average: " << average <<
'\n'
231 <<
"Number of Interface Processes: " << count <<
'\n'
269 auto iterator = thisVertexDistribution.
find(thisRank);
270 if (iterator == thisVertexDistribution.
end()) {
280 for (
const auto &[rank, vertices] : otherVertexDistribution) {
290 if (iterator->second.empty() || vertices.empty() || (vertices.back() < iterator->second.at(0)) || (vertices.at(0) > iterator->second.back())) {
299 vertices.begin(), vertices.end(),
302 if (!inters.
empty()) {
303 communicationMap.
insert({rank, std::move(inters)});
306 return communicationMap;
313 _communicationFactory(
std::move(communicationFactory))
338 PRECICE_DEBUG(
"Exchange vertex distribution between both primary ranks");
339 Event e0(
"m2n.exchangeVertexDistribution");
354 _mesh->setVertexDistribution(vertexDistribution);
378 vertexDistribution, requesterVertexDistribution);
384 print(communicationMap);
388#ifdef P2P_LCM_PRINT_STATS
394 Event e4(
"m2n.createCommunications");
395 e4.
addData(
"Connections", communicationMap.
size());
396 if (communicationMap.
empty()) {
411 communicationMap.
size());
414 for (
auto const &comMap : communicationMap) {
415 int globalRequesterRank = comMap.first;
416 auto indices = std::move(communicationMap[globalRequesterRank]);
432 if (localConnectedRanks.
empty()) {
444 localConnectedRanks.
size());
448 for (
int connectedRank : localConnectedRanks) {
465 PRECICE_DEBUG(
"Exchange vertex distribution between both primary ranks");
466 Event e0(
"m2n.exchangeVertexDistribution");
469 c->requestConnection(acceptorName, requesterName,
470 "TMP-PRIMARYCOM-" +
_mesh->getName(),
482 _mesh->setVertexDistribution(vertexDistribution);
506 vertexDistribution, acceptorVertexDistribution);
512 print(communicationMap);
516#ifdef P2P_LCM_PRINT_STATS
522 Event e4(
"m2n.createCommunications");
523 e4.
addData(
"Connections", communicationMap.
size());
524 if (communicationMap.
empty()) {
533 for (
auto &i : communicationMap)
534 acceptingRanks.
emplace(i.first);
542 _communication->requestConnectionAsClient(acceptorName, requesterName,
547 for (
auto &i : communicationMap) {
548 auto globalAcceptorRank = i.first;
549 auto indices = std::move(i.second);
565 if (localConnectedRanks.
empty()) {
577 _communication->requestConnectionAsClient(acceptorName, requesterName,
581 for (
auto &connectedRank : localConnectedRanks) {
592 _mappings.push_back({i.remoteRank, std::move(localCommunicationMap[i.remoteRank]), i.request, {}});
619 auto buffer = std::make_shared<std::vector<double>>();
620 buffer->reserve(mapping.indices.size() * valueDimension);
621 for (
auto index : mapping.indices) {
622 for (
int d = 0; d < valueDimension; ++d) {
623 buffer->push_back(itemsToSend[
index * valueDimension + d]);
641 mapping.recvBuffer.resize(mapping.indices.size() * valueDimension);
646 mapping.request->wait();
649 for (
auto index : mapping.indices) {
650 for (
int d = 0; d < valueDimension; ++d) {
651 itemsToReceive[
index * valueDimension + d] += mapping.recvBuffer[i * valueDimension + d];
692 _communication->sendRange(localCommunicationMap[connectionData.remoteRank], connectionData.remoteRank);
700 localCommunicationMap[connectionData.remoteRank] =
_communication->receiveRange(connectionData.remoteRank, AsVectorTag<int>{});
704void PointToPointCommunication::checkBufferedRequests(
bool blocking)
708 for (
auto it = bufferedRequests.begin(); it != bufferedRequests.end();) {
709 if (it->first->test())
710 it = bufferedRequests.erase(it);
714 if (bufferedRequests.empty())
#define PRECICE_DEBUG(...)
#define PRECICE_TRACE(...)
#define PRECICE_ASSERT(...)
T back_inserter(T... args)
Interface for all distributed solver to solver communication classes.
mesh::PtrMesh _mesh
mesh that dictates the distribution of this mapping
void scatterAllCommunicationMap(CommunicationMap &localCommunicationMap) override
Scatters a communication map over connected ranks on remote participant.
PointToPointCommunication(com::PtrCommunicationFactory communicationFactory, mesh::PtrMesh mesh)
void broadcastSendMesh() override
Broadcasts a mesh to connected ranks on remote participant.
void gatherAllCommunicationMap(CommunicationMap &localCommunicationMap) override
Gathers a communication maps from connected ranks on remote participant.
void broadcastSend(int itemToSend) override
Broadcasts an int to connected ranks on remote participant.
bool isConnected() const override
Returns true, if a connection to a remote participant has been established.
std::vector< Mapping > _mappings
Local (for process rank in the current participant) vector of mappings (one to service each point-to-...
std::vector< ConnectionData > _connectionDataVector
Local (for process rank in the current participant) vector of ConnectionData (one to service each poi...
void acceptPreConnection(std::string const &acceptorName, std::string const &requesterName) override
Accepts connection from participant, which has to call requestPreConnection(). Only initial connectio...
com::PtrCommunicationFactory _communicationFactory
void receive(precice::span< double > itemsToReceive, int valueDimension=1) override
Receives a subset of local double values corresponding to local indices deduced from the current and ...
std::list< std::pair< std::shared_ptr< com::Request >, std::shared_ptr< std::vector< double > > > > bufferedRequests
void broadcastReceiveAll(std::vector< int > &itemToReceive) override
Receives an int per connected rank on remote participant @para[out] itemToReceive received ints from ...
void requestPreConnection(std::string const &acceptorName, std::string const &requesterName) override
Requests connection from participant, which has to call acceptConnection(). Only initial connection i...
void completeSecondaryRanksConnection() override
Completes the secondary connections for both acceptor and requester by updating the vertex list in _m...
~PointToPointCommunication() override
void checkBufferedRequests(bool blocking)
Checks all stored requests for completion and removes associated buffers.
void acceptConnection(std::string const &acceptorName, std::string const &requesterName) override
Accepts connection from participant, which has to call requestConnection().
void requestConnection(std::string const &acceptorName, std::string const &requesterName) override
Requests connection from participant, which has to call acceptConnection().
com::PtrCommunication _communication
Communication class used for this PointToPointCommunication.
void closeConnection() override
Disconnects from communication space, i.e. participant.
void broadcastReceiveAllMesh() override
Receive mesh partitions per connected rank on remote participant.
void send(precice::span< double const > itemsToSend, int valueDimension=1) override
Sends a subset of local double values corresponding to local indices deduced from the current and rem...
void stop()
Stops a running event.
void addData(std::string_view key, int value)
Adds named integer data, associated to an event.
A C++ 11 implementation of the non-owning C++20 std::span type.
PRECICE_SPAN_NODISCARD constexpr bool empty() const noexcept
constexpr iterator begin() const noexcept
constexpr iterator end() const noexcept
static Rank getRank()
Current rank.
static bool isPrimary()
True if this process is running the primary rank.
static auto allSecondaryRanks()
Returns an iterable range over salve ranks [1, _size)
static bool isSecondary()
True if this process is running a secondary rank.
static com::PtrCommunication & getCommunication()
Intra-participant communication.
void sendMesh(Communication &communication, int rankReceiver, const mesh::Mesh &mesh)
std::shared_ptr< Request > PtrRequest
void receiveMesh(Communication &communication, int rankSender, mesh::Mesh &mesh)
contains the logic of the parallel communication between participants.
std::map< int, std::vector< int > > buildCommunicationMap(mesh::Mesh::VertexDistribution const &thisVertexDistribution, mesh::Mesh::VertexDistribution const &otherVertexDistribution, int thisRank=utils::IntraComm::getRank())
void print(std::map< int, std::vector< int > > const &m)
void broadcastReceive(mesh::Mesh::VertexDistribution &m, int rankBroadcaster, const com::PtrCommunication &communication=utils::IntraComm::getCommunication())
void printCommunicationPartnerCountStats(std::map< int, std::vector< int > > const &m)
void printLocalIndexCountStats(std::map< int, std::vector< int > > const &m)
void receive(mesh::Mesh::VertexDistribution &m, int rankSender, const com::PtrCommunication &communication)
void broadcast(mesh::Mesh::VertexDistribution &m)
void send(mesh::Mesh::VertexDistribution const &m, int rankReceiver, const com::PtrCommunication &communication)
void broadcastSend(mesh::Mesh::VertexDistribution const &m, const com::PtrCommunication &communication=utils::IntraComm::getCommunication())
static constexpr SynchronizeTag Synchronize
Convenience instance of the SynchronizeTag.
void set_intersection_indices(InputIt1 ref1, InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, OutputIt d_first)
This function is by and large the same as std::set_intersection(). The only difference is that we don...
T setprecision(T... args)