/home/runner/work/HiCR/HiCR/include/hicr/backends/pthreads/communicationManager.hpp Source File

HiCR: /home/runner/work/HiCR/HiCR/include/hicr/backends/pthreads/communicationManager.hpp Source File
HiCR
communicationManager.hpp
Go to the documentation of this file.
1/*
2 * Copyright 2025 Huawei Technologies Co., Ltd.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
24#pragma once
25
26#include <cstring>
27#include "pthread.h"
31
32namespace HiCR::backend::pthreads
33{
34
41{
42 public:
43
49 CommunicationManager(const size_t fenceCount = 1)
50 : HiCR::CommunicationManager()
51 {
52 // Initializing barrier for fence operation
53 pthread_barrier_init(&_barrier, nullptr, fenceCount);
54
55 // Initializing mutex object
56 pthread_mutex_init(&_mutex, nullptr);
57 }
58
63 {
64 // Freeing barrier memory
65 pthread_barrier_destroy(&_barrier);
66
67 // Freeing mutex memory
68 pthread_mutex_destroy(&_mutex);
69 }
70
71 __INLINE__ std::shared_ptr<HiCR::GlobalMemorySlot> getGlobalMemorySlotImpl(const HiCR::backend::hwloc::GlobalMemorySlot::tag_t tag,
73 {
74 if (_shadowMap.find(tag) != _shadowMap.end())
75 {
76 if (_shadowMap[tag].find(globalKey) != _shadowMap[tag].end())
77 return _shadowMap[tag][globalKey];
78 else
79 return nullptr;
80 }
81 else { return nullptr; }
82 }
83
92 __INLINE__ std::shared_ptr<HiCR::GlobalMemorySlot> promoteLocalMemorySlot(const std::shared_ptr<HiCR::LocalMemorySlot> &memorySlot, HiCR::GlobalMemorySlot::tag_t tag) override
93 {
94 // Creating new (generic) global memory slot
95 auto globalMemorySlot = std::make_shared<HiCR::backend::hwloc::GlobalMemorySlot>(tag, 0 /* key */, memorySlot);
96
97 // Returning the global memory slot
98 return globalMemorySlot;
99 }
100
106 __INLINE__ void destroyPromotedGlobalMemorySlot(const std::shared_ptr<HiCR::GlobalMemorySlot> &memorySlot) override
107 {
108 // Nothing to do here
109 }
110
111 private:
112
116 pthread_barrier_t _barrier{};
117
121 pthread_mutex_t _mutex{};
122
123 __INLINE__ void exchangeGlobalMemorySlotsImpl(const HiCR::GlobalMemorySlot::tag_t tag, const std::vector<globalKeyMemorySlotPair_t> &memorySlots) override
124 {
125 // Synchronize all intervening threads in this call
126 barrier();
127
128 // Simply adding local memory slots to the global map
129 for (const auto &entry : memorySlots)
130 {
131 // Getting global key
132 auto globalKey = entry.first;
133
134 // Getting local memory slot to promot
135 auto memorySlot = entry.second;
136
137 // Creating new memory slot
138 auto globalMemorySlot = std::make_shared<HiCR::backend::hwloc::GlobalMemorySlot>(tag, globalKey, memorySlot);
139
140 // Registering memory slot
141 registerGlobalMemorySlot(globalMemorySlot);
142 _shadowMap[tag][globalKey] = globalMemorySlot;
143 }
144
145 // Do not allow any thread to continue until the exchange is made
146 barrier();
147 }
148
149 __INLINE__ void queryMemorySlotUpdatesImpl(std::shared_ptr<HiCR::LocalMemorySlot> memorySlot) override
150 {
151 // This function should check and update the abstract class for completed memcpy operations
152 }
153
157 __INLINE__ void barrier() { pthread_barrier_wait(&_barrier); }
158
164 __INLINE__ void fenceImpl(const HiCR::GlobalMemorySlot::tag_t tag) override { barrier(); }
165
166 __INLINE__ void memcpyImpl(const std::shared_ptr<HiCR::LocalMemorySlot> &destination,
167 const size_t dst_offset,
168 const std::shared_ptr<HiCR::LocalMemorySlot> &source,
169 const size_t src_offset,
170 const size_t size) override
171 {
172 // Getting slot pointers
173 const auto srcPtr = source->getPointer();
174 const auto dstPtr = destination->getPointer();
175
176 // Calculating actual offsets
177 const auto actualSrcPtr = (void *)(static_cast<uint8_t *>(srcPtr) + src_offset);
178 const auto actualDstPtr = (void *)(static_cast<uint8_t *>(dstPtr) + dst_offset);
179
180 // Running memcpy now
181 std::memcpy(actualDstPtr, actualSrcPtr, size);
182
183 // Increasing recv/send counters
184 increaseMessageRecvCounter(*destination);
186 }
187
194 __INLINE__ void destroyGlobalMemorySlotImpl(std::shared_ptr<HiCR::GlobalMemorySlot> memorySlot) override
195 {
196 // Nothing to do here
197 }
198
199 __INLINE__ void memcpyImpl(const std::shared_ptr<HiCR::GlobalMemorySlot> &destination,
200 const size_t dst_offset,
201 const std::shared_ptr<HiCR::LocalMemorySlot> &source,
202 const size_t src_offset,
203 const size_t size) override
204 {
205 // Getting up-casted pointer for the execution unit
206 auto dst = dynamic_pointer_cast<HiCR::GlobalMemorySlot>(destination);
207
208 // Checking whether the execution unit passed is compatible with this backend
209 if (dst == nullptr) HICR_THROW_LOGIC("The passed destination memory slot is not supported by this backend\n");
210
211 // Checking whether the memory slot is local. This backend only supports local data transfers
212 if (dst->getSourceLocalMemorySlot() == nullptr) HICR_THROW_LOGIC("The passed destination memory slot is not local (required by this backend)\n");
213
214 // Executing actual memcpy
215 memcpy(dst->getSourceLocalMemorySlot(), dst_offset, source, src_offset, size);
216
217 // Increasing message received/sent counters for both memory slots
218 increaseMessageRecvCounter(*destination->getSourceLocalMemorySlot());
220 }
221
222 __INLINE__ void memcpyImpl(const std::shared_ptr<HiCR::LocalMemorySlot> &destination,
223 const size_t dst_offset,
224 const std::shared_ptr<HiCR::GlobalMemorySlot> &source,
225 const size_t src_offset,
226 const size_t size) override
227 {
228 // Getting up-casted pointer for the execution unit
229 auto src = dynamic_pointer_cast<HiCR::GlobalMemorySlot>(source);
230
231 // Checking whether the memory slot is compatible with this backend
232 if (src == nullptr) HICR_THROW_LOGIC("The passed source memory slot is not supported by this backend\n");
233
234 // Checking whether the memory slot is local. This backend only supports local data transfers
235 if (src->getSourceLocalMemorySlot() == nullptr) HICR_THROW_LOGIC("The passed source memory slot is not local (required by this backend)\n");
236
237 // Executing actual memcpy
238 memcpy(destination, dst_offset, src->getSourceLocalMemorySlot(), src_offset, size);
239
240 // Increasing message received/sent counters for both memory slots
241 increaseMessageRecvCounter(*destination);
242 increaseMessageSentCounter(*source->getSourceLocalMemorySlot());
243 }
244
245 __INLINE__ bool acquireGlobalLockImpl(std::shared_ptr<HiCR::GlobalMemorySlot> memorySlot) override
246 {
247 // Getting up-casted pointer for the execution unit
248 auto m = dynamic_pointer_cast<hwloc::GlobalMemorySlot>(memorySlot);
249
250 // Checking whether the execution unit passed is compatible with this backend
251 if (m == nullptr) HICR_THROW_LOGIC("The passed memory slot is not supported by this backend\n");
252
253 // Locking mutex
254 return m->trylock();
255 }
256
257 __INLINE__ void releaseGlobalLockImpl(std::shared_ptr<HiCR::GlobalMemorySlot> memorySlot) override
258 {
259 // Getting up-casted pointer for the execution unit
260 auto m = dynamic_pointer_cast<hwloc::GlobalMemorySlot>(memorySlot);
261
262 // Checking whether the execution unit passed is compatible with this backend
263 if (m == nullptr) HICR_THROW_LOGIC("The passed memory slot is not supported by this backend\n");
264
265 // Locking mutex
266 m->unlock();
267 }
268
269 __INLINE__ void lock() override
270 {
271 // Locking the pthread mutex
272 pthread_mutex_lock(&_mutex);
273 }
274
275 __INLINE__ void unlock() override
276 {
277 // Locking the pthread mutex
278 pthread_mutex_unlock(&_mutex);
279 }
280
281 private:
282
283 // this map shadows the core HiCR map _globalMemorySlotTagKeyMap
284 // to support getGlobalMemorySlot implementation
285 // for this backend
287};
288
289} // namespace HiCR::backend::pthreads
Provides a definition for the global memory slot class for the HWLoc backend.
Definition communicationManager.hpp:54
std::map< GlobalMemorySlot::tag_t, globalKeyToMemorySlotMap_t > globalMemorySlotTagKeyMap_t
Definition communicationManager.hpp:70
__INLINE__ void memcpy(const std::shared_ptr< LocalMemorySlot > &destination, size_t dst_offset, const std::shared_ptr< LocalMemorySlot > &source, size_t src_offset, size_t size)
Definition communicationManager.hpp:267
__INLINE__ void registerGlobalMemorySlot(const std::shared_ptr< GlobalMemorySlot > &memorySlot)
Definition communicationManager.hpp:503
__INLINE__ void increaseMessageRecvCounter(HiCR::LocalMemorySlot &memorySlot) noexcept
Definition communicationManager.hpp:652
__INLINE__ void increaseMessageSentCounter(HiCR::LocalMemorySlot &memorySlot) noexcept
Definition communicationManager.hpp:659
uint64_t tag_t
Definition globalMemorySlot.hpp:49
uint64_t globalKey_t
Definition globalMemorySlot.hpp:44
Definition communicationManager.hpp:41
__INLINE__ std::shared_ptr< HiCR::GlobalMemorySlot > promoteLocalMemorySlot(const std::shared_ptr< HiCR::LocalMemorySlot > &memorySlot, HiCR::GlobalMemorySlot::tag_t tag) override
Definition communicationManager.hpp:92
__INLINE__ std::shared_ptr< HiCR::GlobalMemorySlot > getGlobalMemorySlotImpl(const HiCR::backend::hwloc::GlobalMemorySlot::tag_t tag, const HiCR::backend::hwloc::GlobalMemorySlot::globalKey_t globalKey) override
Definition communicationManager.hpp:71
~CommunicationManager() override
Definition communicationManager.hpp:62
CommunicationManager(const size_t fenceCount=1)
Definition communicationManager.hpp:49
__INLINE__ void destroyPromotedGlobalMemorySlot(const std::shared_ptr< HiCR::GlobalMemorySlot > &memorySlot) override
Definition communicationManager.hpp:106
Provides a definition for the base backend's communication manager class.
Provides a definition for a HiCR Local Memory Slot class.
#define HICR_THROW_LOGIC(...)
Definition exceptions.hpp:67