Hedgehog  0.0.0
A library to generate hybrid pipeline workflow systems
abstract_memory_manager.h
1 // NIST-developed software is provided by NIST as a public service. You may use, copy and distribute copies of the
2 // software in any medium, provided that you keep intact this entire notice. You may improve, modify and create
3 // derivative works of the software or any portion of the software, and you may copy and distribute such modifications
4 // or works. Modified works should carry a notice stating that you changed the software and should note the date and
5 // nature of any such change. Please explicitly acknowledge the National Institute of Standards and Technology as the
6 // source of the software. NIST-developed software is expressly provided "AS IS." NIST MAKES NO WARRANTY OF ANY KIND,
7 // EXPRESS, IMPLIED, IN FACT OR ARISING BY OPERATION OF LAW, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTY OF
8 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT AND DATA ACCURACY. NIST NEITHER REPRESENTS NOR
9 // WARRANTS THAT THE OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE, OR THAT ANY DEFECTS WILL BE
10 // CORRECTED. NIST DOES NOT WARRANT OR MAKE ANY REPRESENTATIONS REGARDING THE USE OF THE SOFTWARE OR THE RESULTS
11 // THEREOF, INCLUDING BUT NOT LIMITED TO THE CORRECTNESS, ACCURACY, RELIABILITY, OR USEFULNESS OF THE SOFTWARE. You
12 // are solely responsible for determining the appropriateness of using and distributing the software and you assume
13 // all risks associated with its use, including but not limited to the risks and costs of program errors, compliance
14 // with applicable laws, damage to or loss of data, programs or equipment, and the unavailability or interruption of
15 // operation. This software is not intended to be used in any situation where a failure could cause risk of injury or
16 // damage to property. The software developed by NIST employees is not subject to copyright protection within the
17 // United States.
18 
19 
20 #ifndef HEDGEHOG_ABSTRACT_MEMORY_MANAGER_H
21 #define HEDGEHOG_ABSTRACT_MEMORY_MANAGER_H
22 
23 #include <memory>
24 #include <mutex>
25 #include <condition_variable>
26 
27 #include "../../tools/traits.h"
28 #include "../../tools/logger.h"
29 #include "../../tools/nvtx_profiler.h"
30 #include "../../behavior/memory_manager/pool.h"
31 
33 namespace hh {
34 #ifndef DOXYGEN_SHOULD_SKIP_THIS
35 template<class ManagedMemory>
38 class MemoryData;
39 #endif //DOXYGEN_SHOULD_SKIP_THIS
40 
159 template<class ManagedMemory, class = void>
161  private:
162  int deviceId_ = 0;
163  bool initialized_ = false;
164  std::unique_ptr<behavior::Pool<ManagedMemory>> pool_ = {};
165 
166  std::shared_ptr<NvtxProfiler> profiler_ = nullptr;
167 
168  protected:
169  std::mutex memoryManagerMutex_ = {};
170 
171  public:
173  AbstractMemoryManager() = delete;
174 
177  explicit AbstractMemoryManager(size_t const &capacity)
178  : deviceId_(0) {
179  auto tempCapacity = capacity > 0 ? capacity : 1; // Cannot have an empty memory manager
180  pool_ = std::make_unique<behavior::Pool<ManagedMemory>>(tempCapacity);
181  }
182 
184  virtual ~AbstractMemoryManager() = default;
185 
188  virtual std::shared_ptr<AbstractMemoryManager<ManagedMemory>> copy() {
189  return std::make_shared<AbstractMemoryManager<ManagedMemory>>(this->capacity());
190  }
191 
194  void deviceId(int deviceId) { deviceId_ = deviceId; }
195 
198  void profiler(const std::shared_ptr<NvtxProfiler> &profiler) { this->profiler_ = profiler; }
199 
203  [[nodiscard]] size_t currentSize() {
204  std::lock_guard<std::mutex> lk(memoryManagerMutex_);
205  return this->pool()->size();
206  }
207 
210  std::shared_ptr<ManagedMemory> getManagedMemory() {
211  std::shared_ptr<ManagedMemory> managedMemory;
212  HLOG(4, "StaticMemoryManager memory pool size = " << this->currentSize())
213  managedMemory = this->pool()->pop_front();
214  HLOG(4,
215  "StaticMemoryManager After waiting: received: " << managedMemory << " pSize: " << (int) (this->pool()->size()))
216  return managedMemory;
217  };
218 
223  void recycleMemory(std::shared_ptr<MemoryData<ManagedMemory>> managedMemory) {
224  std::lock_guard<std::mutex> lk(memoryManagerMutex_);
225  managedMemory->used();
226  if (managedMemory->canBeRecycled()) {
227  this->profiler_->addReleaseMarker();
228  managedMemory->recycle();
229  this->pool_->push_back(std::dynamic_pointer_cast<ManagedMemory>(managedMemory));
230  }
231  };
232 
235  virtual void initialize() {
236  std::lock_guard<std::mutex> lk(memoryManagerMutex_);
237  if (!this->isInitialized()) {
238  this->initialized();
239  std::for_each(
240  this->pool()->begin(), this->pool()->end(),
241  [this](std::shared_ptr<ManagedMemory> &emptyShared) {
242  emptyShared = std::make_shared<ManagedMemory>();
243  emptyShared->memoryManager(this);
244  }
245  );
247  }
248  };
249 
251  virtual void initializeMemoryManager() {}
252  protected:
255  [[nodiscard]] std::unique_ptr<behavior::Pool<ManagedMemory>> const &pool() const { return pool_; }
256 
259  [[nodiscard]] size_t capacity() const { return this->pool()->capacity(); };
260 
263  [[nodiscard]] bool isInitialized() const { return initialized_; }
264 
267  [[nodiscard]] std::mutex &memoryManagerMutex() { return memoryManagerMutex_; }
268 
270  void initialized() { initialized_ = true; }
271 
274  [[nodiscard]] int deviceId() const { return deviceId_; }
275 
276 };
277 
285 template<class ManagedMemory>
286 class AbstractMemoryManager<ManagedMemory,
287  typename std::enable_if_t<!traits::is_managed_memory_v<ManagedMemory>>> {
288  public:
291  virtual void initialize() {
292  std::ostringstream oss;
293  oss << "Call Memory manager method: " << __FUNCTION__ << " without managed memory data.";
294  HLOG_SELF(0, oss.str())
295  throw (std::runtime_error(oss.str()));
296  }
297 
300  void deviceId(int) {
301  std::ostringstream oss;
302  oss << "Call Memory manager method: " << __FUNCTION__ << " without managed memory data.";
303  HLOG_SELF(0, oss.str())
304  throw (std::runtime_error(oss.str()));
305  }
306 
309  void profiler(const std::shared_ptr<NvtxProfiler> &) {
310  std::ostringstream oss;
311  oss << "Call Memory manager method: " << __FUNCTION__ << " without managed memory data.";
312  HLOG_SELF(0, oss.str())
313  throw (std::runtime_error(oss.str()));
314  }
315 
319  virtual std::shared_ptr<AbstractMemoryManager<ManagedMemory>> copy() {
320  std::ostringstream oss;
321  oss << "Call Memory manager method: " << __FUNCTION__ << " without managed memory data.";
322  HLOG_SELF(0, oss.str())
323  throw (std::runtime_error(oss.str()));
324  };
325 };
326 }
327 #endif //HEDGEHOG_ABSTRACT_MEMORY_MANAGER_H
void recycleMemory(std::shared_ptr< MemoryData< ManagedMemory >> managedMemory)
Recycle memory.
AbstractMemoryManager(size_t const &capacity)
Only used constructor.
virtual ~AbstractMemoryManager()=default
Default destructor.
std::unique_ptr< behavior::Pool< ManagedMemory > > pool_
Inside pool to store the data.
std::shared_ptr< NvtxProfiler > profiler_
NVTX profiler instance to follow memory manager state.
Hedgehog main namespace.
Abstract interface for Hedgehog&#39;s Memory manager.
AbstractMemoryManager()=delete
Deleted Default constructor.
bool isInitialized() const
Initialized flag accessor.
size_t currentSize()
Return the current size of the inside pool.
virtual std::shared_ptr< AbstractMemoryManager< ManagedMemory > > copy()
Virtual copy method used for task duplication and execution pipeline.
Memory data interface to use a data type in a Memory manager (AbstractMemoryManager or StaticMemoryMa...
Definition: memory_data.h:50
virtual void initializeMemoryManager()
User-definable initialization step for a memory manager.
void initialized()
Flag the memory manager has initialized.
size_t capacity() const
Capacity accessor.
STL namespace.
std::shared_ptr< ManagedMemory > getManagedMemory()
Get an available managed memory, block if none are available.
virtual void initialize()
Initialize the memory manager.
int deviceId() const
Device Id accessor.
void deviceId(int deviceId)
Device id setter.
std::unique_ptr< behavior::Pool< ManagedMemory > > const & pool() const
Inside pool accessor.
std::mutex & memoryManagerMutex()
User api mutex accessor.
bool initialized_
Flag to determine if AbstractMemoryManager has been initialized.
void profiler(const std::shared_ptr< NvtxProfiler > &profiler)
NVTX profiler setter.
int deviceId_
Device Id of linked task.
std::mutex memoryManagerMutex_
Mutex for user interface.