21#ifndef HEDGEHOG_ANY_COPYABLE_ABSTRACTION_H
22#define HEDGEHOG_ANY_COPYABLE_ABSTRACTION_H
36namespace abstraction {
43 std::shared_ptr<std::set<AnyGroupableAbstraction *>>
group_ =
nullptr;
68 [[nodiscard]] std::string
nodeId()
const {
70 return thisAsNode->id();
72 throw std::runtime_error(
"A group representative should be a NodeAbstraction.");
78 [[nodiscard]] std::shared_ptr<std::set<AnyGroupableAbstraction *>>
const &
group()
const {
84 [[nodiscard]] std::shared_ptr<std::set<NodeAbstraction *>>
groupAsNodes()
const {
85 auto ret = std::make_shared<std::set<NodeAbstraction *>>();
86 for (
auto copyable : *
group_) {
87 if (
auto node =
dynamic_cast<NodeAbstraction *
>(copyable)) { ret->insert(node); }
101 return representativeAsNode->id();
103 throw std::runtime_error(
"A group representative should be a NodeAbstraction.");
121 count = (
size_t) std::count_if(
122 this->group_->cbegin(), this->group_->cend(),
123 [](
auto nodeInGroup) {
125 return taskGroup->isActive();
127 throw std::runtime_error(
"All the nodes in a group should be of the same type: the representative is a "
128 "TaskNodeAbstraction, but not the nodes in its group.");
141 std::pair<std::chrono::nanoseconds, std::chrono::nanoseconds> minMax =
142 {std::chrono::nanoseconds::zero(), std::chrono::nanoseconds::zero()};
145 auto minMaxElem = std::minmax_element(
146 this->group_->cbegin(), this->group_->cend(),
147 [](
auto lhs,
auto rhs) {
148 auto lhsAsTask = dynamic_cast<TaskNodeAbstraction const *>(lhs);
149 auto rhsAsTask = dynamic_cast<TaskNodeAbstraction const *>(rhs);
150 if (lhsAsTask && rhsAsTask) {
151 return lhsAsTask->waitDuration() < rhsAsTask->waitDuration();
153 throw std::runtime_error(
"All the nodes in a group should be of the same type, the representative is of"
154 " type TaskNodeAbstraction but not the nodes in its group.");
161 if (minTask && maxTask) {
162 minMax = {minTask->
waitDuration(), maxTask->waitDuration()};
164 throw std::runtime_error(
"All the nodes in a group should be of the same type, the representative is of"
165 " type TaskNodeAbstraction but not the nodes in its group.");
176 std::pair<std::chrono::nanoseconds, std::chrono::nanoseconds> meanSD =
177 {std::chrono::nanoseconds::zero(), std::chrono::nanoseconds::zero()};
179 std::chrono::nanoseconds
180 sum = std::chrono::nanoseconds::zero(),
181 mean = std::chrono::nanoseconds::zero();
185 for (
auto taskInGroup : *this->group_) {
190 throw std::runtime_error(
"All nodes in a group should be of the same type, the representative derives from "
191 "TaskNodeAbstraction but not the group members.");
194 mean = sum / (this->group_->size());
196 for (
auto taskInGroup : *this->group_) {
199 auto diff = (double) (task->waitDuration().count() - mean.count());
202 throw std::runtime_error(
"All nodes in a group should be of the same type, the representative derives from "
203 "TaskNodeAbstraction but not the group members.");
208 std::chrono::nanoseconds((int64_t) std::sqrt(sd / (
double) this->group_->size()))};
216 auto groupAsNode = this->groupAsNodes();
217 auto minMaxElem = std::minmax_element(
218 groupAsNode->cbegin(), groupAsNode->cend(),
219 [](
auto lhs,
auto rhs) {
220 return lhs->executionDuration() < rhs->executionDuration();
223 return {(*minMaxElem.first)->executionDuration(),
224 (*minMaxElem.second)->executionDuration()};
230 auto groupAsNode = groupAsNodes();
231 std::pair<std::chrono::nanoseconds, std::chrono::nanoseconds> meanSD =
232 {std::chrono::nanoseconds::zero(), std::chrono::nanoseconds::zero()};
234 std::chrono::nanoseconds
235 sum = std::chrono::nanoseconds::zero(),
236 mean = std::chrono::nanoseconds::zero();
240 for (
auto taskInGroup : *groupAsNode) {
241 sum += taskInGroup->executionDuration();
243 mean = sum / (groupAsNode->size());
245 for (
auto taskInGroup : *groupAsNode) {
246 sd += (double) (taskInGroup->executionDuration().count() - mean.count()) *
247 (
double) (taskInGroup->executionDuration().count() - mean.count());
250 meanSD = {mean, std::chrono::nanoseconds((int64_t) std::sqrt(sd / (
double) groupAsNode->size()))};
259 std::pair<std::chrono::nanoseconds, std::chrono::nanoseconds> minMax =
260 {std::chrono::nanoseconds::zero(), std::chrono::nanoseconds::zero()};
263 auto minMaxElem = std::minmax_element(
264 this->group_->cbegin(), this->group_->cend(),
265 [](
auto lhs,
auto rhs) {
266 auto lhsAsTask = dynamic_cast<TaskNodeAbstraction const *>(lhs);
267 auto rhsAsTask = dynamic_cast<TaskNodeAbstraction const *>(rhs);
268 if (lhsAsTask && rhsAsTask) {
269 return lhsAsTask->perElementExecutionDuration() < rhsAsTask->perElementExecutionDuration();
271 throw std::runtime_error(
"All the nodes in a group should be of the same type, the representative is of"
272 " type TaskNodeAbstraction but not the group members.");
279 if (minTask && maxTask) {
282 throw std::runtime_error(
"All the nodes in a group should be of the same type, the representative is of"
283 " type TaskNodeAbstraction but not the group members.");
293 std::pair<std::chrono::nanoseconds, std::chrono::nanoseconds> meanSD =
294 {std::chrono::nanoseconds::zero(), std::chrono::nanoseconds::zero()};
296 std::chrono::nanoseconds
297 sum = std::chrono::nanoseconds::zero(),
298 mean = std::chrono::nanoseconds::zero();
302 for (
auto taskInGroup : *this->group_) {
307 throw std::runtime_error(
"All the nodes in a group should be of the same type, the representative is of"
308 " type TaskNodeAbstraction but not the group members.");
311 mean = sum / (this->group_->size());
313 for (
auto taskInGroup : *this->group_) {
316 auto diff = (double) (task->perElementExecutionDuration().count() - mean.count());
319 throw std::runtime_error(
"All the nodes in a group should be of the same type, the representative is of"
320 " type TaskNodeAbstraction but not the group members.");
323 meanSD = {mean, std::chrono::nanoseconds((int64_t) std::sqrt(sd / (
double) this->group_->size()))};
332 std::pair<std::chrono::nanoseconds, std::chrono::nanoseconds> minMax =
333 {std::chrono::nanoseconds::zero(), std::chrono::nanoseconds::zero()};
335 auto minMaxElem = std::minmax_element(
336 this->group_->cbegin(), this->group_->cend(),
337 [](
auto lhs,
auto rhs) {
338 auto lhsAsTask = dynamic_cast<TaskNodeAbstraction const *>(lhs);
339 auto rhsAsTask = dynamic_cast<TaskNodeAbstraction const *>(rhs);
340 if (lhsAsTask && rhsAsTask) {
341 return lhsAsTask->memoryWaitDuration() < rhsAsTask->memoryWaitDuration();
343 throw std::runtime_error(
"All the nodes in a group should be of the same type, the representative is of"
344 " type TaskNodeAbstraction but not the nodes in the group.");
350 if (minTask && maxTask) {
353 throw std::runtime_error(
"All the nodes in a group should be of the same type, the representative is of"
354 " type TaskNodeAbstraction but not the nodes in the group.");
364 std::pair<std::chrono::nanoseconds, std::chrono::nanoseconds> meanSD =
365 {std::chrono::nanoseconds::zero(), std::chrono::nanoseconds::zero()};
367 std::chrono::nanoseconds
368 sum = std::chrono::nanoseconds::zero(),
369 mean = std::chrono::nanoseconds::zero();
373 for (
auto taskInGroup : *this->group_) {
378 throw std::runtime_error(
"All the nodes in a group should be of the same type, the representative is of"
379 " type TaskNodeAbstraction but not the group members.");
382 mean = sum / (this->group_->size());
384 for (
auto taskInGroup : *this->group_) {
387 auto diff = (double) (task->memoryWaitDuration().count() - mean.count());
390 throw std::runtime_error(
"All the nodes in a group should be of the same type, the representative is of"
391 " type TaskNodeAbstraction but not the group members.");
394 meanSD = {mean, std::chrono::nanoseconds((int64_t) std::sqrt(sd / (
double) this->group_->size()))};
403 std::pair<size_t, size_t> minMax = {0, 0};
406 auto minMaxElem = std::minmax_element(
407 this->group_->cbegin(), this->group_->cend(),
408 [](
auto lhs,
auto rhs) {
409 auto lhsAsTask = dynamic_cast<TaskNodeAbstraction const *>(lhs);
410 auto rhsAsTask = dynamic_cast<TaskNodeAbstraction const *>(rhs);
411 if (lhsAsTask && rhsAsTask) {
412 return lhsAsTask->numberReceivedElements() < rhsAsTask->numberReceivedElements();
414 throw std::runtime_error(
"All the nodes in a group should be of the same type, the representative is of"
415 " type TaskNodeAbstraction but not the nodes in the group.");
421 if (minTask && maxTask) {
424 throw std::runtime_error(
"All the nodes in a group should be of the same type, the representative is of"
425 " type TaskNodeAbstraction but not the nodes in the group.");
436 std::pair<double, double> meanSD = {0, 0};
439 double mean = 0, sd = 0;
441 for (
auto taskInGroup : *this->group_) {
444 sum += task->numberReceivedElements();
446 throw std::runtime_error(
"All the nodes in a group should be of the same type, the representative is of"
447 " type TaskNodeAbstraction but not the nodes in the group.");
450 mean = (double) sum / (
double) (this->group_->size());
452 for (
auto taskInGroup : *this->group_) {
458 throw std::runtime_error(
"All the nodes in a group should be of the same type, the representative is of"
459 " type TaskNodeAbstraction but not the nodes in the group.");
463 meanSD = {mean, std::sqrt(sd / (
double) this->group_->size())};
Abstraction for cores/nodes that can form groups.
std::shared_ptr< std::set< AnyGroupableAbstraction * > > group_
Node's group.
std::pair< std::chrono::nanoseconds, std::chrono::nanoseconds > meanSDMemoryWaitTimePerElementGroup() const
Accessor to the mean / standard deviation wait time duration of the nodes in the group.
void group(std::shared_ptr< std::set< AnyGroupableAbstraction * > > const &group)
Group setter.
std::pair< std::chrono::nanoseconds, std::chrono::nanoseconds > meanSDExecutionDurationGroup() const
Accessor to the mean / standard deviation execution duration of the nodes in the group.
std::pair< double, double > meanSDNumberElementsReceivedGroup() const
Accessor to the mean / standard deviation number of elements received in the group.
std::string groupRepresentativeId() const
Group id representative accessor.
std::shared_ptr< std::set< AnyGroupableAbstraction * > > const & group() const
Group of cores accessor.
virtual void createGroup(std::map< NodeAbstraction *, std::vector< NodeAbstraction * > > &)=0
Create a group to insert in the map.
std::string nodeId() const
Accessor to the node id (redirection to NodeAbstraction::nodeId)
size_t const numberThreads_
Number of threads.
std::pair< std::chrono::nanoseconds, std::chrono::nanoseconds > minmaxWaitDurationGroup() const
Accessor to the min / max wait duration of the nodes in the group.
bool isInGroup() const
Test if a group is needed.
std::pair< std::chrono::nanoseconds, std::chrono::nanoseconds > minmaxMemoryWaitTimeGroup() const
Accessor to the min / max wait time duration of the nodes in the group.
size_t numberActiveThreadInGroup() const
Accessor to the number of nodes alive in the group.
std::pair< std::chrono::nanoseconds, std::chrono::nanoseconds > minmaxExecTimePerElementGroup() const
Accessor to the min / max execution per elements duration of the nodes in the group.
std::pair< std::chrono::nanoseconds, std::chrono::nanoseconds > meanSDWaitDurationGroup() const
Accessor to the mean / standard deviation wait duration of the nodes in the group.
AnyGroupableAbstraction(size_t const numberThreads)
Constructor using the number of threads.
std::shared_ptr< std::set< NodeAbstraction * > > groupAsNodes() const
Create a set of the NodeAbstraction constituting the group.
void groupRepresentative(AnyGroupableAbstraction *groupRepresentative)
Group representative setter.
AnyGroupableAbstraction * groupRepresentative() const
Group representative accessor.
std::pair< size_t, size_t > minmaxNumberElementsReceivedGroup() const
Accessor to the min / max number of elements received in the group.
std::pair< std::chrono::nanoseconds, std::chrono::nanoseconds > meanSDExecTimePerElementGroup() const
Accessor to the mean / standard deviation execution per elements duration of the nodes in the group.
AnyGroupableAbstraction * groupRepresentative_
Group representative.
std::pair< std::chrono::nanoseconds, std::chrono::nanoseconds > minmaxExecutionDurationGroup() const
Accessor to the min / max execution duration of the nodes in the group.
size_t numberThreads() const
Accessor to the number of threads.
virtual ~AnyGroupableAbstraction()=default
Default destructor.
Base core node abstraction.
Task core abstraction used to define some method for task-like behaving cores like CoreExecutionPipel...
std::chrono::nanoseconds const & memoryWaitDuration() const
Accessor to the duration the node was in a memory wait state.
std::chrono::nanoseconds perElementExecutionDuration() const
Accessor to the duration the average duration of processing an input data.
std::chrono::nanoseconds const & waitDuration() const
Accessor to the duration the node was in a wait state.
size_t numberReceivedElements() const
Accessor to the number of received elements.