NeoN
A framework for CFD software
Loading...
Searching...
No Matches
communicator.hpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2023 - 2025 NeoN authors
2//
3// SPDX-License-Identifier: MIT
4
5#pragma once
6
7#include <vector>
8#include <unordered_map>
9#include <memory>
10
11
12#include "NeoN/fields/field.hpp"
13
14#ifdef NF_WITH_MPI_SUPPORT
18#endif
19
20namespace NeoN
21{
22
23#ifdef NF_WITH_MPI_SUPPORT
27struct NodeCommMap
28{
29 label local_idx;
30};
31
35using RankCommMap = std::vector<NodeCommMap>;
36
40using CommMap = std::vector<RankCommMap>;
41
49class Communicator
50{
51public:
52
53 using bufferType = mpi::FullDuplexCommBuffer;
54
58 Communicator() = default;
59
63 ~Communicator() = default;
64
72 Communicator(mpi::MPIEnvironment mpiEnviron, CommMap rankSendMap, CommMap rankReceiveMap)
73 : mpiEnviron_(mpiEnviron), sendMap_(rankSendMap), receiveMap_(rankReceiveMap)
74 {
76 mpiEnviron_.sizeRank() == rankSendMap.size(),
77 "Size of rankSendSize does not match MPI size."
78 );
80 mpiEnviron_.sizeRank() == rankReceiveMap.size(),
81 "Size of rankReceiveSize does not match MPI size."
82 );
83 };
84
91 template<typename valueType>
92 void startComm(Vector<valueType>& field, const std::string& commName)
93 {
95 CommBuffer_.find(commName) == CommBuffer_.end() || (!CommBuffer_[commName]),
96 "There is already an ongoing communication for key " << commName << "."
97 );
98
99 CommBuffer_[commName] = findDuplexBuffer();
100 if (!CommBuffer_[commName])
101 {
102 CommBuffer_[commName] = createNewDuplexBuffer();
103 }
104
105 CommBuffer_[commName]->initComm<valueType>(commName);
106 for (size_t rank = 0; rank < mpiEnviron_.sizeRank(); ++rank)
107 {
108 auto rankBuffer = CommBuffer_[commName]->getSend<valueType>(rank);
109 for (size_t data = 0; data < sendMap_[rank].size(); ++data)
110 rankBuffer[data] = field(static_cast<size_t>(sendMap_[rank][data].local_idx));
111 }
112 CommBuffer_[commName]->startComm();
113 }
114
120 bool isComplete(std::string commName);
121
128 template<typename valueType>
129 void finaliseComm(Vector<valueType>& field, std::string commName)
130 {
132 CommBuffer_.find(commName) != CommBuffer_.end() && CommBuffer_[commName],
133 "No communication associated with key: " << commName
134 );
135
136 CommBuffer_[commName]->waitComplete();
137 for (size_t rank = 0; rank < mpiEnviron_.sizeRank(); ++rank)
138 {
139 auto rankBuffer = CommBuffer_[commName]->getReceive<valueType>(rank);
140 for (size_t data = 0; data < receiveMap_[rank].size(); ++data)
141 field(static_cast<size_t>(receiveMap_[rank][data].local_idx)) = rankBuffer[data];
142 }
143 CommBuffer_[commName]->finaliseComm();
144 CommBuffer_[commName] = nullptr;
145 }
146
147private:
148
149 mpi::MPIEnvironment mpiEnviron_;
150 CommMap sendMap_;
151 CommMap receiveMap_;
152 std::vector<bufferType> buffers;
153 std::unordered_map<std::string, bufferType*>
154 CommBuffer_;
161 bufferType* findDuplexBuffer();
162
167 bufferType* createNewDuplexBuffer();
168};
169#endif
170
171} // namespace NeoN
#define NF_DEBUG_ASSERT(condition, message)
Macro for asserting a condition and printing an error message if the condition is false (only in debu...
Definition error.hpp:213
Definition array.hpp:20
int32_t label
Definition label.hpp:26