/home/runner/work/HiCR/HiCR/include/hicr/frontends/objectStore/objectStore.hpp Source File

HiCR: /home/runner/work/HiCR/HiCR/include/hicr/frontends/objectStore/objectStore.hpp Source File
HiCR
objectStore.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 <atomic>
27
33
34enum
35{
40};
41
42namespace HiCR::objectStore
43{
44
49using compoundId_t = uint64_t;
50
115{
116 public:
117
127 ObjectStore(CommunicationManager &communicationManager,
129 MemoryManager &memoryManager,
130 std::shared_ptr<MemorySpace> memorySpace,
131 Instance::instanceId_t instanceId)
132 : _memoryManager(memoryManager),
133 _communicationManager(communicationManager),
134 _tag(tag),
135 _memorySpace(memorySpace),
136 _instanceId(instanceId)
137 {}
138
142 ~ObjectStore() = default;
143
149 [[nodiscard]] std::shared_ptr<MemorySpace> getMemorySpace() const { return _memorySpace; }
150
161 [[nodiscard]] __INLINE__ std::shared_ptr<DataObject> createObject(void *ptr, size_t size, blockId id)
162 {
163 // Register the given allocation as a memory slot
164 auto slot = _memoryManager.registerLocalMemorySlot(_memorySpace, ptr, size);
165
166 return std::make_shared<DataObject>(_instanceId, id, slot);
167 }
168
178 [[nodiscard]] __INLINE__ std::shared_ptr<DataObject> createObject(std::shared_ptr<LocalMemorySlot> slot, blockId id)
179 {
180 return std::make_shared<DataObject>(_instanceId, id, slot);
181 }
182
190 __INLINE__ void publish(std::shared_ptr<DataObject> dataObject)
191 {
192 blockId objectId = dataObject->_id;
193
194 if (dataObject->_globalSlot)
195 {
196 _communicationManager.destroyPromotedGlobalMemorySlot(dataObject->_globalSlot);
197 HICR_THROW_LOGIC("Trying to publish a block that has already been published."); // FIXME: What do we do with republishing?
198 }
199 // One-sided publish of the global slot
200 auto globalSlot = _communicationManager.promoteLocalMemorySlot(dataObject->_localSlot, _tag);
201
202 dataObject->_globalSlot = globalSlot;
203 _globalObjects.insert({dataObject->_instanceId << OBJECT_STORE_KEY_INSTANCE_ID_BITS | objectId, dataObject});
204 }
205
250 __INLINE__ std::shared_ptr<LocalMemorySlot> get(DataObject &dataObject)
251 {
252 // Deduce globally unique block ID for the GlobalMemorySlot key, by combining the given instance and block IDs
253 compoundId_t compoundId = dataObject._instanceId << OBJECT_STORE_KEY_INSTANCE_ID_BITS | dataObject._id;
254
255 _globalObjects[compoundId] = std::make_shared<DataObject>(dataObject);
256
257 // If the data object has never been fetched before, allocate a local memory slot for it
258 if (dataObject._localSlot == nullptr)
259 {
260 // Allocate a local memory slot for the block, associate it with the global slot and add it to the blocks of the given instance
261 auto newSlot = _memoryManager.allocateLocalMemorySlot(_memorySpace, dataObject._size);
262 dataObject._localSlot = newSlot;
263 }
264
265 if (dataObject._globalSlot == nullptr) HICR_THROW_LOGIC("Trying to get a block that has not been properly transferred.");
266
267 // Initiate the data movement from the owner to the current worker
268 _communicationManager.memcpy(dataObject._localSlot, 0, dataObject._globalSlot, 0, dataObject._size);
269 return dataObject._localSlot;
270
271 // Notes: Consider a variant (maybe hidden under another layer/wrapper) that allows to get portion
272 // of the block, using offset and size
273 }
274
285 __INLINE__ void destroy(DataObject &dataObject)
286 {
287 // Only free the local memory slot if it is a fetched object, which means the local slot allocation
288 // was done by the object store during a call to #get
289 if (dataObject._instanceId != _instanceId)
290 {
291 if (dataObject._localSlot) _memoryManager.freeLocalMemorySlot(dataObject._localSlot);
292 }
293
294 if (dataObject._globalSlot) _communicationManager.destroyPromotedGlobalMemorySlot(dataObject._globalSlot);
295
296 compoundId_t compoundId = dataObject._instanceId << OBJECT_STORE_KEY_INSTANCE_ID_BITS | dataObject._id;
297 auto it = _globalObjects.find(compoundId);
298
299 if (it != _globalObjects.end()) { _globalObjects.erase(it); }
300 }
301
309 __INLINE__ handle serialize(DataObject &dataObject)
310 {
311 auto ret = handle{};
312 ret.instanceId = dataObject._instanceId;
313 ret.id = dataObject._id;
314 ret.size = dataObject._size;
315 uint8_t *serializedGlobalSlot = _communicationManager.serializeGlobalMemorySlot(dataObject._globalSlot); // implicitly produces allocation
316 std::memcpy(ret.serializedGlobalSlot, serializedGlobalSlot, sizeof(ret.serializedGlobalSlot));
317
318 // free the allocation produced by serialize() TODO: dangerous, remove
319 delete[] serializedGlobalSlot;
320 return ret;
321 }
322
330 __INLINE__ std::shared_ptr<DataObject> deserialize(const handle &handle)
331 {
332 auto dataObject = std::make_shared<DataObject>(handle.instanceId, handle.id, nullptr);
333 dataObject->_size = handle.size;
334 dataObject->_globalSlot =
335 _communicationManager.deserializeGlobalMemorySlot(reinterpret_cast<uint8_t *>(const_cast<uint8_t(*)[28 + sizeof(size_t)]>(&handle.serializedGlobalSlot)), _tag);
336 return dataObject;
337 }
338
354 __INLINE__ bool fence()
355 {
356 _communicationManager.fence(_tag);
357 return true;
358 }
359
370 __INLINE__ bool fence(const std::shared_ptr<DataObject> &dataObject)
371 {
372 // Use the zero-cost variant of fence with (sent,recv) = (0,1)
373 _communicationManager.fence(dataObject->_localSlot, 0, 1);
374 return true;
375 }
376
377#ifdef HICR_ENABLE_NONBLOCKING_FENCE // Dummy flag for when we implement non-blocking fence
397 static bool test_fence(const Tag &tag);
398#endif
399
400 private:
401
405 MemoryManager &_memoryManager;
406
410 CommunicationManager &_communicationManager;
411
417 const GlobalMemorySlot::tag_t _tag;
418
422 const std::shared_ptr<MemorySpace> _memorySpace;
423
430 std::map<compoundId_t, std::shared_ptr<DataObject>> _globalObjects{};
431
435 const Instance::instanceId_t _instanceId;
436};
437
438} // namespace HiCR::objectStore
Definition communicationManager.hpp:54
virtual std::shared_ptr< GlobalMemorySlot > promoteLocalMemorySlot(const std::shared_ptr< LocalMemorySlot > &localMemorySlot, GlobalMemorySlot::tag_t tag)
Definition communicationManager.hpp:177
virtual uint8_t * serializeGlobalMemorySlot(const std::shared_ptr< HiCR::GlobalMemorySlot > &globalSlot) const
Definition communicationManager.hpp:148
__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 fence(GlobalMemorySlot::tag_t tag)
Definition communicationManager.hpp:377
virtual std::shared_ptr< GlobalMemorySlot > deserializeGlobalMemorySlot(uint8_t *buffer, GlobalMemorySlot::tag_t tag)
Definition communicationManager.hpp:161
virtual void destroyPromotedGlobalMemorySlot(const std::shared_ptr< GlobalMemorySlot > &memorySlot)
Definition communicationManager.hpp:236
uint64_t tag_t
Definition globalMemorySlot.hpp:49
uint64_t instanceId_t
Definition instance.hpp:44
Definition memoryManager.hpp:51
__INLINE__ void freeLocalMemorySlot(const std::shared_ptr< HiCR::LocalMemorySlot > &memorySlot)
Definition memoryManager.hpp:138
virtual std::shared_ptr< LocalMemorySlot > registerLocalMemorySlot(const std::shared_ptr< HiCR::MemorySpace > &memorySpace, void *const ptr, const size_t size)
Definition memoryManager.hpp:86
__INLINE__ std::shared_ptr< LocalMemorySlot > allocateLocalMemorySlot(const std::shared_ptr< MemorySpace > &memorySpace, const size_t size)
Definition memoryManager.hpp:66
Definition dataObject.hpp:79
Definition objectStore.hpp:115
__INLINE__ bool fence()
Definition objectStore.hpp:354
__INLINE__ std::shared_ptr< DataObject > deserialize(const handle &handle)
Definition objectStore.hpp:330
__INLINE__ handle serialize(DataObject &dataObject)
Definition objectStore.hpp:309
__INLINE__ std::shared_ptr< DataObject > createObject(std::shared_ptr< LocalMemorySlot > slot, blockId id)
Definition objectStore.hpp:178
__INLINE__ void destroy(DataObject &dataObject)
Definition objectStore.hpp:285
__INLINE__ void publish(std::shared_ptr< DataObject > dataObject)
Definition objectStore.hpp:190
__INLINE__ std::shared_ptr< LocalMemorySlot > get(DataObject &dataObject)
Definition objectStore.hpp:250
ObjectStore(CommunicationManager &communicationManager, GlobalMemorySlot::tag_t tag, MemoryManager &memoryManager, std::shared_ptr< MemorySpace > memorySpace, Instance::instanceId_t instanceId)
Definition objectStore.hpp:127
__INLINE__ bool fence(const std::shared_ptr< DataObject > &dataObject)
Definition objectStore.hpp:370
std::shared_ptr< MemorySpace > getMemorySpace() const
Definition objectStore.hpp:149
__INLINE__ std::shared_ptr< DataObject > createObject(void *ptr, size_t size, blockId id)
Definition objectStore.hpp:161
Provides a definition for the base backend's communication manager class.
Provides a definition for a HiCR Global Memory Slot class.
Provides a definition for the HiCR Instance class.
Provides a definition for the base backend's memory manager class.
Provides functionality for a data object over HiCR.
uint32_t blockId
Definition dataObject.hpp:36
#define HICR_THROW_LOGIC(...)
Definition exceptions.hpp:67
uint64_t compoundId_t
Definition objectStore.hpp:49
@ OBJECT_STORE_KEY_INSTANCE_ID_BITS
Definition objectStore.hpp:39
Definition dataObject.hpp:45
blockId id
Definition dataObject.hpp:54
uint8_t serializedGlobalSlot[28+sizeof(size_t)]
Definition dataObject.hpp:64
size_t size
Definition dataObject.hpp:59
Instance::instanceId_t instanceId
Definition dataObject.hpp:49