NeoN
A framework for CFD software
Loading...
Searching...
No Matches
communicator.hpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2023 - 2026 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::Environment 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_.contains(commName) || (!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] =
111 field.view()[static_cast<localIdx>(sendMap_[rank][data].local_idx)];
112 }
113 CommBuffer_[commName]->startComm();
114 }
115
121 bool isComplete(std::string commName);
122
129 template<typename valueType>
130 void finaliseComm(Vector<valueType>& field, std::string commName)
131 {
133 CommBuffer_.contains(commName) && CommBuffer_[commName],
134 "No communication associated with key: " << commName
135 );
136
137 CommBuffer_[commName]->waitComplete();
138 for (size_t rank = 0; rank < mpiEnviron_.sizeRank(); ++rank)
139 {
140 auto rankBuffer = CommBuffer_[commName]->getReceive<valueType>(rank);
141 for (size_t data = 0; data < receiveMap_[rank].size(); ++data)
142 field.view()[static_cast<localIdx>(receiveMap_[rank][data].local_idx)] =
143 rankBuffer[data];
144 }
145 CommBuffer_[commName]->finaliseComm();
146 CommBuffer_[commName] = nullptr;
147 }
148
149private:
150
151 mpi::Environment mpiEnviron_;
152 CommMap sendMap_;
153 CommMap receiveMap_;
154 std::vector<bufferType> buffers;
155 std::unordered_map<std::string, bufferType*>
156 CommBuffer_;
163 bufferType* findDuplexBuffer();
164
169 bufferType* createNewDuplexBuffer();
170};
171#endif
172
173} // 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:190
Integer types used throughout NeoN.
Definition array.hpp:18
int32_t localIdx
Definition label.hpp:50
int32_t label
Definition label.hpp:44