NeoFOAM
WIP Prototype of a modern OpenFOAM core
Loading...
Searching...
No Matches
communicator.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: MIT
2// SPDX-FileCopyrightText: 2023 NeoFOAM authors
3#pragma once
4
5#include <vector>
6#include <unordered_map>
7#include <memory>
8
9
11
12#ifdef NF_WITH_MPI_SUPPORT
16#endif
17
18namespace NeoFOAM
19{
20
21#ifdef NF_WITH_MPI_SUPPORT
25struct NodeCommMap
26{
27 label local_idx;
28};
29
33using RankCommMap = std::vector<NodeCommMap>;
34
38using CommMap = std::vector<RankCommMap>;
39
47class Communicator
48{
49public:
50
51 using bufferType = mpi::FullDuplexCommBuffer;
52
56 Communicator() = default;
57
61 ~Communicator() = default;
62
70 Communicator(mpi::MPIEnvironment mpiEnviron, CommMap rankSendMap, CommMap rankReceiveMap)
71 : mpiEnviron_(mpiEnviron), sendMap_(rankSendMap), receiveMap_(rankReceiveMap)
72 {
74 mpiEnviron_.sizeRank() == rankSendMap.size(),
75 "Size of rankSendSize does not match MPI size."
76 );
78 mpiEnviron_.sizeRank() == rankReceiveMap.size(),
79 "Size of rankReceiveSize does not match MPI size."
80 );
81 };
82
89 template<typename valueType>
90 void startComm(Field<valueType>& field, const std::string& commName)
91 {
93 CommBuffer_.find(commName) == CommBuffer_.end() || (!CommBuffer_[commName]),
94 "There is already an ongoing communication for key " << commName << "."
95 );
96
97 CommBuffer_[commName] = findDuplexBuffer();
98 if (!CommBuffer_[commName])
99 {
100 CommBuffer_[commName] = createNewDuplexBuffer();
101 }
102
103 CommBuffer_[commName]->initComm<valueType>(commName);
104 for (size_t rank = 0; rank < mpiEnviron_.sizeRank(); ++rank)
105 {
106 auto rankBuffer = CommBuffer_[commName]->getSend<valueType>(rank);
107 for (size_t data = 0; data < sendMap_[rank].size(); ++data)
108 rankBuffer[data] = field(static_cast<size_t>(sendMap_[rank][data].local_idx));
109 }
110 CommBuffer_[commName]->startComm();
111 }
112
118 bool isComplete(std::string commName);
119
126 template<typename valueType>
127 void finaliseComm(Field<valueType>& field, std::string commName)
128 {
130 CommBuffer_.find(commName) != CommBuffer_.end() && CommBuffer_[commName],
131 "No communication associated with key: " << commName
132 );
133
134 CommBuffer_[commName]->waitComplete();
135 for (size_t rank = 0; rank < mpiEnviron_.sizeRank(); ++rank)
136 {
137 auto rankBuffer = CommBuffer_[commName]->getReceive<valueType>(rank);
138 for (size_t data = 0; data < receiveMap_[rank].size(); ++data)
139 field(static_cast<size_t>(receiveMap_[rank][data].local_idx)) = rankBuffer[data];
140 }
141 CommBuffer_[commName]->finaliseComm();
142 CommBuffer_[commName] = nullptr;
143 }
144
145private:
146
147 mpi::MPIEnvironment mpiEnviron_;
148 CommMap sendMap_;
149 CommMap receiveMap_;
150 std::vector<bufferType> buffers;
151 std::unordered_map<std::string, bufferType*>
152 CommBuffer_;
159 bufferType* findDuplexBuffer();
160
165 bufferType* createNewDuplexBuffer();
166};
167#endif
168
169} // namespace NeoFOAM
#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:211
int32_t label
Definition label.hpp:13