HTGS  v2.0
The Hybrid Task Graph Scheduler
MemoryManager.hpp
Go to the documentation of this file.
1 
2 // NIST-developed software is provided by NIST as a public service. You may use, copy and distribute copies of the software in any medium, provided that you keep intact this entire notice. You may improve, modify and create derivative works of the software or any portion of the software, and you may copy and distribute such modifications or works. Modified works should carry a notice stating that you changed the software and should note the date and nature of any such change. Please explicitly acknowledge the National Institute of Standards and Technology as the source of the software.
3 // NIST-developed software is expressly provided "AS IS." NIST MAKES NO WARRANTY OF ANY KIND, EXPRESS, IMPLIED, IN FACT OR ARISING BY OPERATION OF LAW, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT AND DATA ACCURACY. NIST NEITHER REPRESENTS NOR WARRANTS THAT THE OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE, OR THAT ANY DEFECTS WILL BE CORRECTED. NIST DOES NOT WARRANT OR MAKE ANY REPRESENTATIONS REGARDING THE USE OF THE SOFTWARE OR THE RESULTS THEREOF, INCLUDING BUT NOT LIMITED TO THE CORRECTNESS, ACCURACY, RELIABILITY, OR USEFULNESS OF THE SOFTWARE.
4 // You are solely responsible for determining the appropriateness of using and distributing the software and you assume all risks associated with its use, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and the unavailability or interruption of operation. This software is not intended to be used in any situation where a failure could cause risk of injury or damage to property. The software developed by NIST employees is not subject to copyright protection within the United States.
5 
13 #ifndef HTGS_MEMORYMANAGER_H
14 #define HTGS_MEMORYMANAGER_H
15 
17 
18 #include <htgs/api/ITask.hpp>
20 #include <htgs/types/MMType.hpp>
21 
22 namespace htgs {
23 
46 template<class T>
47 class MemoryManager : public ITask<MemoryData<T>, MemoryData<T>> {
48 
49  public:
58  MemoryManager(std::string name,
59  size_t memoryPoolSize,
60  std::shared_ptr<IMemoryAllocator<T>> memoryAllocator,
61  MMType type) : ITask<
62  MemoryData<T>,
63  MemoryData<T>>(1, true, false, 0L) {
64  this->allocator = memoryAllocator;
65  this->memoryPoolSize = memoryPoolSize;
66  this->pool = nullptr;
67  this->name = name;
68  this->type = type;
69  }
70 
74  ~MemoryManager() override {
75  if (this->pool != nullptr) {
76  pool->releaseAllMemory();
77 
78  delete pool;
79  pool = nullptr;
80  }
81  }
82 
87  void initialize() override {
88  this->pool = new MemoryPool<T>(this->getMemoryPoolSize());
89  std::shared_ptr<AnyConnector> anyInputConnector = this->getOwnerTaskManager()->getInputConnector();
90  std::shared_ptr<Connector<MemoryData<T>>> inputConnector = std::static_pointer_cast<Connector<MemoryData<T>>>(anyInputConnector);
91 
92  MemoryData<T> *memory = new MemoryData<T>(this->getAllocator(), inputConnector, this->getName(), this->type);
93 
94  bool allocate = false;
95  if (type == MMType::Static)
96  allocate = true;
97 
98  this->pool->fillPool(memory, this->getPipelineId(), allocate);
99  delete memory;
100  }
101 
105  void shutdown() override {
106 // bool release = false;
107 // if (type == MMType::Static)
108 // release = true;
109 // this->pool->emptyPool(release);
110  }
111 
120  void executeTask(std::shared_ptr<MemoryData<T>> data) override {
121  if (data != nullptr) {
122  if (data->getPipelineId() == this->getPipelineId()) {
123  data->memoryUsed();
124 
125  if (data->canReleaseMemory()) {
126  if (type == MMType::Static)
127  this->pool->addMemory(data);
128  else if (type == MMType::Dynamic) {
129  data->memFree();
130  this->pool->addMemory(data);
131  }
132  }
133 
134  } else {
135  std::cerr << "Memory manager received data from another pipeline!" << std::endl;
136  }
137  }
138 
139  while (!this->pool->isPoolEmpty()) {
140  this->addResult(this->pool->getMemory());
141  }
142  }
143 
147  void debug() override {
148  HTGS_DEBUG(this->getName() << " max pool size: " << this->memoryPoolSize << " isEmpty? " << this->pool->isPoolEmpty());
149  }
150 
155  virtual std::string getName() override {
156  std::string typeStr;
157  switch (this->type) {
158  case MMType::Static:typeStr = "static";
159  break;
160  case MMType::Dynamic:typeStr = "dynamic";
161  break;
162  }
163  return std::string("MM(" + typeStr + "): " + this->name);
164  }
165 
171  virtual MemoryManager<T> *copy() override {
172  return new MemoryManager<T>(this->name, this->memoryPoolSize, this->allocator, this->type);
173  }
174 
180  virtual size_t getMemoryPoolSize() {
181  return this->memoryPoolSize;
182  }
183 
188  virtual std::shared_ptr<IMemoryAllocator<T>> getAllocator() {
189  return this->allocator;
190  }
191 
197  std::string getMemoryManagerName() { return name; }
198 
203  std::string typeName() {
204 #if defined( __GLIBCXX__ ) || defined( __GLIBCPP__ )
205  int status;
206  char *realName = abi::__cxa_demangle(typeid(T).name(), 0, 0, &status);
207  std::string ret(realName);
208 
209  free(realName);
210 
211  return ret;
212 #else
213  return typeid(T).name();
214 #endif
215  }
216 
221  MMType getType() const { return type; }
222 
229  virtual std::string genDot(int flags,
230  std::string dotId,
231  std::shared_ptr<AnyConnector> input,
232  std::shared_ptr<AnyConnector> output) override {
233 
234  if ((flags & DOTGEN_FLAG_HIDE_MEM_EDGES) != 0) {
235  return "";
236  }
237 
238  std::ostringstream oss;
239 
240  if (output != nullptr) {
241  oss << dotId << " -> " << output->getDotId() << "[color=sienna];" << std::endl;
242  oss << output->getDotId() << "[label=\"" + this->typeName()
243  << "\",style=filled,shape=oval,width=.2,height=.2, fillcolor=sienna, color=sienna];" << std::endl;
244  }
245 
246  oss << dotId + ";" << std::endl;
247 
248  return oss.str();
249 
250  }
251 
252  std::string getDotFillColor() override {
253  return "sienna";
254  }
255 
256  private:
257  std::shared_ptr<IMemoryAllocator<T>> allocator;
258  size_t memoryPoolSize;
260  std::string name;
262 
263 };
264 }
265 
266 #endif //HTGS_MEMORYMANAGER_H
267 
std::shared_ptr< AnyConnector > getInputConnector() override
Gets the input Connector.
Definition: TaskManager.hpp:119
std::string getMemoryManagerName()
Gets the name of the memory manager.
Definition: MemoryManager.hpp:197
size_t memoryPoolSize
The size of the memory pool.
Definition: MemoryManager.hpp:258
virtual std::string genDot(int flags, std::string dotId, std::shared_ptr< AnyConnector > input, std::shared_ptr< AnyConnector > output) override
Virtual function that generates the input/output and per-task dot notation.
Definition: MemoryManager.hpp:229
MMType
The memory manager types.
Definition: MMType.hpp:38
void executeTask(std::shared_ptr< MemoryData< T >> data) override
Processes memory data.
Definition: MemoryManager.hpp:120
void debug() override
Provides debug output for MemoryManager.
Definition: MemoryManager.hpp:147
virtual size_t getMemoryPoolSize()
Virtual function to gets the size of the MemoryPool.
Definition: MemoryManager.hpp:180
std::string name
The name of the memory manager.
Definition: MemoryManager.hpp:260
std::string typeName()
Gets the demangled type name of the connector.
Definition: MemoryManager.hpp:203
Describes memory allocated by a MemoryManager to manage shared memory across multiple ITask...
Definition: ICudaTask.hpp:28
Creates a pool of memory that allocates/frees MemoryData.
Definition: MemoryPool.hpp:39
void addResult(std::shared_ptr< MemoryData< T > > result)
Adds results to the output list to be sent to the next connected ITask in a TaskGraph.
Definition: ITask.hpp:357
Manages the input/output of IData between Tasks.
Definition: Connector.hpp:62
size_t getPipelineId()
Gets the pipeline ID.
Definition: AnyITask.hpp:367
Implements the MemoryPool class.
#define DOTGEN_FLAG_HIDE_MEM_EDGES
Hides memory edges during dot generation.
Definition: TaskGraphDotGenFlags.hpp:20
virtual std::string getName() override
Gets the name of the MemoryManager.
Definition: MemoryManager.hpp:155
std::shared_ptr< IMemoryAllocator< T > > allocator
The allocator used for allocating and freeing memory.
Definition: MemoryManager.hpp:257
Defines the Memory Manager types MMType.
#define HTGS_DEBUG(msg)
Prints a debug message to std::cerr with standard level If DEBUG_FLAG is not defined, this equates to a no op Each message includes the file and line number for where the debug is called.
Definition: debug_message.hpp:65
void initialize() override
Initializes the MemoryManager, getting the size of the memory pool, and filling the memory pool with ...
Definition: MemoryManager.hpp:87
Processes MemoryData between two ITasks using a memory pool.
Definition: MemoryManager.hpp:47
TaskManager< MemoryData< T >, MemoryData< T > > * getOwnerTaskManager()
Gets the owner task manager for this ITask.
Definition: ITask.hpp:527
An interface to process input data and forward results within a TaskGraph.
Definition: ITask.hpp:165
Abstract class that describes how memory is allocated and freed.
Definition: IMemoryAllocator.hpp:67
MMType getType() const
Gets the memory manager type.
Definition: MemoryManager.hpp:221
MMType type
The memory manager type.
Definition: MemoryManager.hpp:261
virtual std::shared_ptr< IMemoryAllocator< T > > getAllocator()
Gets the allocator that is responsible for allocating and freeing memory for the MemoryPool.
Definition: MemoryManager.hpp:188
virtual MemoryManager< T > * copy() override
Creates a shallow copy of the MemoryManager.
Definition: MemoryManager.hpp:171
MemoryManager(std::string name, size_t memoryPoolSize, std::shared_ptr< IMemoryAllocator< T >> memoryAllocator, MMType type)
Creates the MemoryManager with the specified memory pool size and allocator.
Definition: MemoryManager.hpp:58
void shutdown() override
Shuts down the MemoryManager memory is only released when the underlying graph destructs the memory m...
Definition: MemoryManager.hpp:105
MemoryPool< T > * pool
The memory pool.
Definition: MemoryManager.hpp:259
~MemoryManager() override
Destructor.
Definition: MemoryManager.hpp:74
std::string getDotFillColor() override
Gets the color for filling the shape for graphviz dot.
Definition: MemoryManager.hpp:252
An interface to process input data and forward results within a TaskGraph.
Definition: Bookkeeper.hpp:23
Defines how memory is allocated and freed.