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.