19#ifdef NF_WITH_MPI_SUPPORT
30inline int bufferHash(
const std::string& str)
34 constexpr int maxTagValue = 32767 - 10;
35 std::size_t tag = std::hash<std::string> {}(str);
37 return (
static_cast<int>(tag) % maxTagValue) + 10;
50class HalfDuplexCommBuffer
58 HalfDuplexCommBuffer() =
default;
63 ~HalfDuplexCommBuffer() =
default;
71 HalfDuplexCommBuffer(MPIEnvironment mpiEnviron, std::vector<size_t> rankCommSize)
72 : mpiEnviron_(mpiEnviron)
74 setCommRankSize<char>(rankCommSize);
82 inline void setMPIEnvironment(MPIEnvironment mpiEnviron) { mpiEnviron_ = mpiEnviron; }
89 inline bool isCommInit()
const {
return tag_ != -1; }
97 template<
typename valueType>
98 void setCommRankSize(std::vector<size_t> rankCommSize)
101 !isCommInit(),
"Communication buffer was initialised by name: " << commName_ <<
"."
104 rankCommSize.size() == mpiEnviron_.sizeRank(),
105 "Rank size mismatch. " << rankCommSize.size() <<
" vs. " << mpiEnviron_.sizeRank()
107 typeSize_ =
sizeof(valueType);
108 rankOffset_.resize(rankCommSize.size() + 1);
109 request_.resize(rankCommSize.size(), MPI_REQUEST_NULL);
110 updateDataSize([&](
const size_t rank) {
return rankCommSize[rank]; },
sizeof(valueType));
119 template<
typename valueType>
120 void initComm(std::string commName)
123 !isCommInit(),
"Communication buffer was initialised by name: " << commName_ <<
"."
125 setType<valueType>();
126 commName_ = commName;
127 tag_ = bufferHash(commName);
135 inline const std::string& getCommName()
const {
return commName_; }
171 template<
typename valueType>
172 View<valueType> get(
const size_t rank)
174 NF_DEBUG_ASSERT(isCommInit(),
"Communication buffer is not initialised.");
175 NF_DEBUG_ASSERT(typeSize_ ==
sizeof(valueType),
"Data type (size) mismatch.");
176 return View<valueType>(
177 reinterpret_cast<valueType*
>(rankBuffer_.data() + rankOffset_[rank]),
178 (rankOffset_[rank + 1] - rankOffset_[rank]) /
sizeof(valueType)
189 template<
typename valueType>
190 View<const valueType> get(
const size_t rank)
const
192 NF_DEBUG_ASSERT(isCommInit(),
"Communication buffer is not initialised.");
193 NF_DEBUG_ASSERT(typeSize_ ==
sizeof(valueType),
"Data type (size) mismatch.");
194 return View<const valueType>(
195 reinterpret_cast<const valueType*
>(rankBuffer_.data() + rankOffset_[rank]),
196 (rankOffset_[rank + 1] - rankOffset_[rank]) /
sizeof(valueType)
203 std::string commName_ {
"unassigned"};
204 std::size_t typeSize_ {
sizeof(char)};
205 MPIEnvironment mpiEnviron_;
206 std::vector<MPI_Request> request_;
207 std::vector<char> rankBuffer_;
208 std::vector<std::size_t>
214 template<
typename valueType>
218 !isCommInit(),
"Communication buffer was initialised by name: " << commName_ <<
"."
220 if (0 == (typeSize_ -
sizeof(valueType)))
return;
222 [rankOffset = rankOffset_, typeSize = typeSize_](
const size_t rank)
223 {
return (rankOffset[rank + 1] - rankOffset[rank]) / typeSize; },
227 typeSize_ =
sizeof(valueType);
237 template<
typename func>
238 void updateDataSize(func rankSize, std::size_t newSize)
240 std::size_t dataSize = 0;
241 for (
size_t rank = 0; rank < mpiEnviron_.sizeRank(); ++rank)
243 rankOffset_[rank] = dataSize;
244 dataSize += rankSize(rank) * newSize;
246 rankOffset_.back() = dataSize;
247 if (rankBuffer_.size() < dataSize) rankBuffer_.resize(dataSize);
#define NF_DEBUG_ASSERT(condition, message)
Macro for asserting a condition and printing an error message if the condition is false (only in debu...