20 #ifndef HEDGEHOG_CORE_NODE_H 21 #define HEDGEHOG_CORE_NODE_H 32 #include "../../api/printer/abstract_printer.h" 33 #include "../../behavior/node.h" 34 #include "../../tools/logger.h" 42 #ifndef DOXYGEN_SHOULD_SKIP_THIS 45 #endif //DOXYGEN_SHOULD_SKIP_THIS 52 hasBeenRegistered_ =
false,
53 isCudaRelated_ =
false,
59 size_t numberThreads_ = 1;
61 std::string_view name_ =
"";
66 *belongingNode_ =
nullptr,
67 *coreClusterNode_ =
nullptr;
69 std::shared_ptr<std::multimap<CoreNode *, std::shared_ptr<CoreNode>>>
70 insideNodes_ =
nullptr;
72 std::chrono::duration<uint64_t, std::micro>
73 creationDuration_ = std::chrono::duration<uint64_t, std::micro>::zero(),
74 executionDuration_ = std::chrono::duration<uint64_t, std::micro>::zero(),
75 waitDuration_ = std::chrono::duration<uint64_t, std::micro>::zero(),
76 memoryWaitDuration_ = std::chrono::duration<uint64_t, std::micro>::zero();
78 std::chrono::time_point<std::chrono::high_resolution_clock>
const 79 creationTimeStamp_ = std::chrono::high_resolution_clock::now();
81 std::chrono::time_point<std::chrono::high_resolution_clock>
82 startExecutionTimeStamp_ = std::chrono::high_resolution_clock::now();
93 : isActive_(false), name_(name), type_(type), coreClusterNode_(this) {
94 numberThreads_ = numberThreads == 0 ? 1 : numberThreads;
96 "Creating CoreNode with type: " << (
int) type <<
", name: " << name <<
" and number of Threads: " 97 << this->numberThreads_)
98 this->insideNodes_ = std::make_shared<std::multimap<CoreNode *, std::shared_ptr<CoreNode>>>();
103 HLOG_SELF(0,
"Destructing CoreNode")
108 virtual std::shared_ptr<CoreNode> clone() = 0;
114 [[nodiscard]]
virtual std::string
id()
const {
115 std::stringstream ss{};
122 [[nodiscard]]
virtual std::vector<std::pair<std::string, std::string>>
ids()
const {
123 return {{this->id(), this->coreClusterNode()->id()}};
128 [[nodiscard]] std::string_view
const &
name()
const {
return name_; }
136 [[nodiscard]]
bool isInside()
const {
return isInside_; }
148 [[nodiscard]]
int threadId()
const {
return threadId_; }
160 [[nodiscard]] std::shared_ptr<std::multimap<
CoreNode *,
167 [[nodiscard]] std::shared_ptr<std::multimap<CoreNode *, std::shared_ptr<CoreNode>>> &
insideNodes() {
173 [[nodiscard]] std::chrono::duration<uint64_t, std::micro>
const &
executionTime()
const {
return executionDuration_; }
177 [[nodiscard]] std::chrono::duration<uint64_t, std::micro>
const &
waitTime()
const {
return waitDuration_; }
181 [[nodiscard]] std::chrono::duration<uint64_t, std::micro>
const &
memoryWaitTime()
const {
182 return memoryWaitDuration_;
187 [[nodiscard]]
bool isInCluster()
const {
return this->isInCluster_; }
191 [[nodiscard]]
bool isActive()
const {
return isActive_; }
199 [[nodiscard]]
virtual int graphId() {
return this->belongingNode()->graphId(); }
203 [[nodiscard]]
virtual int deviceId() {
return this->belongingNode()->deviceId(); }
207 [[nodiscard]]
virtual std::chrono::duration<uint64_t, std::micro>
maxExecutionTime()
const {
208 return this->executionDuration_;
213 [[nodiscard]]
virtual std::chrono::duration<uint64_t, std::micro>
minExecutionTime()
const {
214 return this->executionDuration_;
219 [[nodiscard]]
virtual std::chrono::duration<uint64_t, std::micro>
maxWaitTime()
const {
return this->waitDuration_; }
223 [[nodiscard]]
virtual std::chrono::duration<uint64_t, std::micro>
minWaitTime()
const {
return this->waitDuration_; }
227 [[nodiscard]] std::chrono::time_point<std::chrono::high_resolution_clock>
const &
creationTimeStamp()
const {
228 return creationTimeStamp_;
234 return startExecutionTimeStamp_;
239 [[nodiscard]] std::chrono::duration<uint64_t,
245 return executionDuration_;
251 auto ret = this->executionTime();
252 if (this->isInCluster()) {
253 std::chrono::duration<uint64_t, std::micro> sum = std::chrono::duration<uint64_t, std::micro>::zero();
254 for (
auto it = this->belongingNode()->insideNodes()->equal_range(this->coreClusterNode()).first;
255 it != this->belongingNode()->insideNodes()->equal_range(this->coreClusterNode()).second; ++it) {
256 sum += it->second->executionTime();
258 ret = sum / this->numberThreads();
266 auto ret = this->waitTime();
267 if (this->isInCluster()) {
268 std::chrono::duration<uint64_t, std::micro> sum = std::chrono::duration<uint64_t, std::micro>::zero();
269 for (
auto it = this->belongingNode()->insideNodes()->equal_range(this->coreClusterNode()).first;
270 it != this->belongingNode()->insideNodes()->equal_range(this->coreClusterNode()).second; ++it) {
271 sum += it->second->waitTime();
273 ret = sum / this->numberThreads();
281 auto ret = this->memoryWaitTime();
282 if (this->isInCluster()) {
283 std::chrono::duration<uint64_t, std::micro> sum = std::chrono::duration<uint64_t, std::micro>::zero();
284 for (
auto it = this->belongingNode()->insideNodes()->equal_range(this->coreClusterNode()).first;
285 it != this->belongingNode()->insideNodes()->equal_range(this->coreClusterNode()).second; ++it) {
286 sum += it->second->memoryWaitTime();
288 ret = sum / this->numberThreads();
297 if (this->isInCluster()) {
298 auto mean = this->meanExecTimeCluster().count(), meanSquare = mean * mean;
299 for (
auto it = this->belongingNode()->insideNodes()->equal_range(this->coreClusterNode()).first;
300 it != this->belongingNode()->insideNodes()->equal_range(this->coreClusterNode()).second; ++it) {
301 ret += (uint64_t) std::pow(it->second->executionTime().count(), 2) - meanSquare;
303 ret /= this->numberThreads();
304 ret = (uint64_t) std::sqrt(ret);
313 if (this->isInCluster()) {
314 auto mean = this->meanWaitTimeCluster().count(), meanSquare = mean * mean;
315 for (
auto it = this->belongingNode()->insideNodes()->equal_range(this->coreClusterNode()).first;
316 it != this->belongingNode()->insideNodes()->equal_range(this->coreClusterNode()).second; ++it) {
317 ret += (uint64_t) std::pow(it->second->waitTime().count(), 2) - meanSquare;
319 ret /= this->numberThreads();
320 ret = (uint64_t) std::sqrt(ret);
329 if (this->isInCluster()) {
330 auto mean = this->meanMemoryWaitTimeCluster().count(), meanSquare = mean * mean;
331 for (
auto it = this->belongingNode()->insideNodes()->equal_range(this->coreClusterNode()).first;
332 it != this->belongingNode()->insideNodes()->equal_range(this->coreClusterNode()).second; ++it) {
333 ret += (uint64_t) std::pow(it->second->memoryWaitTime().count(), 2) - meanSquare;
335 ret /= this->numberThreads();
336 ret = (uint64_t) std::sqrt(ret);
344 uint64_t min = std::numeric_limits<uint64_t>::max();
347 if (this->isInCluster()) {
348 for (
auto it = this->belongingNode()->insideNodes()->equal_range(this->coreClusterNode()).first;
349 it != this->belongingNode()->insideNodes()->equal_range(this->coreClusterNode()).second; ++it) {
350 val = it->second->waitTime().count();
351 if (val < min) { min = val; }
352 if (val > max) { max = val; }
355 min = this->meanWaitTimeCluster().count();
364 uint64_t min = std::numeric_limits<uint64_t>::max();
367 if (this->isInCluster()) {
368 for (
auto it = this->belongingNode()->insideNodes()->equal_range(this->coreClusterNode()).first;
369 it != this->belongingNode()->insideNodes()->equal_range(this->coreClusterNode()).second; ++it) {
370 val = it->second->memoryWaitTime().count();
371 if (val < min) { min = val; }
372 if (val > max) { max = val; }
375 min = this->meanMemoryWaitTimeCluster().count();
384 uint64_t min = std::numeric_limits<uint64_t>::max();
387 if (this->isInCluster()) {
388 for (
auto it = this->belongingNode()->insideNodes()->equal_range(this->coreClusterNode()).first;
389 it != this->belongingNode()->insideNodes()->equal_range(this->coreClusterNode()).second; ++it) {
390 val = it->second->executionTime().count();
391 if (val < min) { min = val; }
392 if (val > max) { max = val; }
395 min = this->meanExecTimeCluster().count();
406 if (this->isInCluster()) {
407 for (
auto it = this->belongingNode()->insideNodes()->equal_range(this->coreClusterNode()).first;
408 it != this->belongingNode()->insideNodes()->equal_range(this->coreClusterNode()).second; ++it) {
409 ret += it->second->isActive() ? 1 : 0;
412 ret = this->isActive() ? 1 : 0;
425 std::chrono::time_point<std::chrono::high_resolution_clock>
const &startExecutionTimeStamp) {
426 startExecutionTimeStamp_ = startExecutionTimeStamp;
430 virtual void deviceId(
int deviceId) { this->belongingNode()->deviceId(deviceId); }
448 void name(std::string_view
const &name) { name_ =
name; }
476 void creationDuration(std::chrono::duration<uint64_t, std::micro>
const &creationDuration) {
477 creationDuration_ = creationDuration;
483 executionDuration_ = executionDuration;
489 this->memoryWaitDuration_ += memoryWait;
503 virtual void createCluster(std::shared_ptr<std::multimap<CoreNode *, std::shared_ptr<CoreNode>>> &) {};
511 virtual void duplicateEdge(
512 CoreNode *duplicateNode, std::map<CoreNode *, std::shared_ptr<CoreNode>> &correspondenceMap) = 0;
524 virtual std::set<CoreSlot *> getSlots() = 0;
530 HLOG_SELF(0,
"Remove inside node " << coreNode->
id() <<
")")
531 this->insideNodes()->erase(coreNode);
551 HLOG_SELF(0,
"Add InsideNode " << coreNode->name() <<
"(" << coreNode->id() <<
")")
552 if (insideNodes_->find(coreNode.get()) == insideNodes_->end()) {
553 coreNode->belongingNode(
this);
554 coreNode->hasBeenRegistered(
true);
555 insideNodes_->insert({coreNode.get(), coreNode});
561 void incrementWaitDuration(std::chrono::duration<uint64_t, std::micro>
const &wait) { this->waitDuration_ += wait; }
566 this->executionDuration_ += exec;
571 #endif //HEDGEHOG_CORE_NODE_H NodeType type() const
Node type accessor.
void incrementExecutionDuration(std::chrono::duration< uint64_t, std::micro > const &exec)
Increment execution duration.
std::pair< uint64_t, uint64_t > minmaxWaitTimeCluster() const
Compute and return the min and max wait time for all tasks in the node cluster.
void startExecutionTimeStamp(std::chrono::time_point< std::chrono::high_resolution_clock > const &startExecutionTimeStamp)
Execution timestamp setter.
virtual std::chrono::duration< uint64_t, std::micro > minWaitTime() const
Minimum waiting time accessor.
std::chrono::duration< uint64_t, std::micro > meanMemoryWaitTimeCluster() const
Compute and return the mean memory wait time for all tasks in the node cluster.
void isInside(bool isInside)
Set the node as being inside another one.
std::pair< uint64_t, uint64_t > minmaxMemoryWaitTimeCluster() const
Compute and return the min and max memory wait time for all tasks in the node cluster.
std::shared_ptr< std::multimap< CoreNode *, std::shared_ptr< CoreNode > > > const & insideNodes() const
Inside node accessor.
virtual std::string extraPrintingInformation()
Extra printing information accessor.
void coreClusterNode(CoreNode *coreClusterNode)
Set the main cluster node to associate to this node.
std::shared_ptr< std::multimap< CoreNode *, std::shared_ptr< CoreNode > > > & insideNodes()
Inside nodes accessor.
bool isCudaRelated() const
Is related to CUDA, used to have a green background on the dot file.
virtual std::chrono::duration< uint64_t, std::micro > minExecutionTime() const
Minimum execution time accessor.
virtual void deviceId(int deviceId)
Device id setter.
std::chrono::duration< uint64_t, std::micro > meanExecTimeCluster() const
Compute and return the mean execution time for all tasks in the node cluster.
virtual void setInside()
Set the node as inside, (inside a graph)
void setInCluster()
Set the task as part of a cluster.
bool isActive() const
Is active property accessor.
void removeInsideNode(CoreNode *coreNode)
Remove a node from the registered inside nodes.
size_t numberActiveThreadInCluster() const
Compute and return the number of active nodes in a cluster.
void isActive(bool isActive)
Is active property setter.
void threadId(uint8_t threadId)
Set the thread id.
virtual void createCluster(std::shared_ptr< std::multimap< CoreNode *, std::shared_ptr< CoreNode >>> &)
Define how to create a cluster for the node, by default do nothing.
void name(std::string_view const &name)
Name node setter.
std::chrono::time_point< std::chrono::high_resolution_clock > const & creationTimeStamp() const
Creation timestamp accessor.
uint64_t stdvMemoryWaitTimeCluster() const
Compute and return the standard deviation memory wait time for all tasks in the node cluster...
Node Behavior definition.
Slot interface, receive notification from CoreNotifier.
void numberThreads(size_t numberThreads)
Number of threads setter.
virtual void joinThreads()
Define what is done when the thread is joined.
Main Hedgehog object that does computation.
int threadId() const
Thread id accessor.
virtual int graphId()
Graph id accessor.
uint64_t stdvWaitTimeCluster() const
Compute and return the standard deviation wait time for all tasks in the node cluster.
std::pair< uint64_t, uint64_t > minmaxExecTimeCluster() const
Compute and return the min and max execution time for all tasks in the node cluster.
void copyInnerStructure(CoreNode *rhs)
Copy inner structure from rhs nodes to this.
CoreNode * coreClusterNode() const
Main cluster core node link to this node accessor.
NodeType
Hedgehog node's type.
void addUniqueInsideNode(const std::shared_ptr< CoreNode > &coreNode)
Add a node to the inside nodes.
virtual void run()
Run method, main execution.
virtual void preRun()
Method defining what to do before the run.
Main Hedgehog core abstraction.
CoreNode(std::string_view const &name, NodeType const type, size_t numberThreads)
Core node only constructor.
uint64_t stdvExecTimeCluster() const
Compute and return the standard deviation execution time for all tasks in the node cluster...
Hedgehog graph's node, used to manage an AbstractState.
virtual void postRun()
Method defining what to do after the run.
std::chrono::time_point< std::chrono::high_resolution_clock > const & startExecutionTimeStamp() const
Execution start timestamp accessor.
std::chrono::duration< uint64_t, std::micro > const & executionDuration() const
Execution duration accessor.
std::chrono::duration< uint64_t, std::micro > meanWaitTimeCluster() const
Compute and return the mean wait time for all tasks in the node cluster.
bool isInCluster() const
In cluster property accessor.
std::string_view const & name() const
Node name accessor.
void isCudaRelated(bool isCudaRelated)
Is CUDA related property setter.
virtual std::chrono::duration< uint64_t, std::micro > maxWaitTime() const
Maximum waiting time accessor.
std::chrono::duration< uint64_t, std::micro > const & memoryWaitTime() const
Memory wait time accessor.
size_t numberThreads() const
Number of threads associated accessor.
CoreNode * belongingNode() const
Belonging node accessor.
bool hasBeenRegistered() const
Node registration property accessor.
virtual int deviceId()
Device id accessor.
void incrementWaitDuration(std::chrono::duration< uint64_t, std::micro > const &wait)
Increment wait duration.
void belongingNode(CoreNode *belongingNode)
Belonging node setter.
NodeType const type_
Node type.
std::chrono::duration< uint64_t, std::micro > const & executionTime() const
Execution time accessor.
virtual ~CoreNode()
Default virtual destructor.
std::chrono::duration< uint64_t, std::micro > const & creationDuration() const
Creation duration accessor.
void hasBeenRegistered(bool hasBeenRegistered)
Has been registered property setter.
virtual std::chrono::duration< uint64_t, std::micro > maxExecutionTime() const
Maximum execution time accessor.
void executionDuration(std::chrono::duration< uint64_t, std::micro > const &executionDuration)
Execution duration setter.
bool isInside() const
Node inside property accessor.
virtual std::vector< std::pair< std::string, std::string > > ids() const
Input node ids [nodeId, nodeIdCluster] accessor.
virtual std::string id() const
Unique Id accessor.
std::chrono::duration< uint64_t, std::micro > const & waitTime() const
Wait time accessor.
void incrementWaitForMemoryDuration(std::chrono::duration< uint64_t, std::micro > const &memoryWait)
Add wait for memory duration to total duration.
void creationDuration(std::chrono::duration< uint64_t, std::micro > const &creationDuration)
Creation duration setter.