Hedgehog  3.1.0
A library to generate hybrid pipeline workflow systems
Loading...
Searching...
No Matches
core_graph.h
Go to the documentation of this file.
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
21#ifndef HEDGEHOG_CORE_GRAPH_H
22#define HEDGEHOG_CORE_GRAPH_H
23
24#include <map>
25#include <ostream>
26
27#include "../abstractions/base/clonable_abstraction.h"
28#include "../abstractions/base/cleanable_abstraction.h"
29#include "../abstractions/base/node/graph_node_abstraction.h"
30
31#include "../abstractions/node/graph_inputs_management_abstraction.h"
32#include "../abstractions/node/graph_outputs_management_abstraction.h"
33
34#include "../abstractions/base/node/execution_pipeline_node_abstraction.h"
35
36#include "../../tools/traits.h"
37#include "../../tools/meta_functions.h"
38#include "../../api/graph/scheduler.h"
39#include "../../api/printer/printer.h"
40#include "../../api/graph/default_scheduler.h"
41
43namespace hh {
44
45#ifndef DOXYGEN_SHOULD_SKIP_THIS
49template<size_t Separator, class ...AllTypes>
50class Graph;
51#endif //DOXYGEN_SHOULD_SKIP_THIS
52
54namespace core {
55
56#ifndef DOXYGEN_SHOULD_SKIP_THIS
60template<size_t Separator, class ...AllTypes>
61class CoreExecutionPipeline;
62#endif //DOXYGEN_SHOULD_SKIP_THIS
63
65template<size_t Separator, class...AllTypes>
66using GIM = tool::GraphInputsManagementAbstractionTypeDeducer_t<tool::Inputs<Separator, AllTypes...>>;
67
69template<size_t Separator, class...AllTypes>
70using GOM = tool::GraphOutputsManagementAbstractionTypeDeducer_t<tool::Outputs<Separator, AllTypes...>>;
71
75template<size_t Separator, class ...AllTypes>
76class CoreGraph :
80 public GIM<Separator, AllTypes...>,
81 public GOM<Separator, AllTypes...> {
82 private:
84 friend CoreExecutionPipeline<Separator, AllTypes...>;
85 std::unique_ptr<Scheduler> const
86 scheduler_ = nullptr;
87
88 hh::Graph<Separator, AllTypes...> *const graph_;
89 public:
94 explicit CoreGraph(std::string const &name,
95 std::unique_ptr<Scheduler> scheduler,
97 GraphNodeAbstraction(name), scheduler_(std::move(scheduler)), graph_(graph) {
98 this->source()->registerNode(this);
99 this->sink()->registerNode(this);
100 }
101
105 CoreGraph(CoreGraph const &rhs, std::map<NodeAbstraction *, std::shared_ptr<NodeAbstraction>> &correspondenceMap)
106 : GraphNodeAbstraction(rhs.name()),
108 scheduler_(rhs.scheduler_->create()), graph_(rhs.graph_) {
109 this->source()->registerNode(this);
110 this->sink()->registerNode(this);
111 duplicateInsideNodes(rhs, correspondenceMap);
112 }
113
115 ~CoreGraph() override = default;
116
122 template<
123 class CoreInputTypes,
124 tool::CompatibleInputCore<CoreInputTypes, typename GIM<Separator, AllTypes...>::inputs_t> InputCore
125 >
126 void setInputForAllCommonTypes(InputCore *const core) {
127 testRegistered(__FUNCTION__);
128 using Input_t = tool::Intersect_t<CoreInputTypes, typename GIM<Separator, AllTypes...>::inputs_t>;
129 using Indices = std::make_index_sequence<std::tuple_size_v<Input_t>>;
131 if (dynamic_cast<abstraction::SlotAbstraction *>(core) == nullptr) {
132 std::ostringstream oss;
133 oss << "The receiver node " << core->name()
134 << "has a malformed core (missing inheritance to SlotAbstraction)";
135 throw (std::runtime_error(oss.str()));
136 }
137
138 callAddInputNodeToGraph<Input_t>(core, Indices{});
139 }
140
147 template<
148 class InputType,
149 class CoreInputTypes,
151 InputType,
152 CoreInputTypes,
153 typename GIM<Separator, AllTypes...>::inputs_t> InputCore>
154 void setInputForACommonType(InputCore *const core) {
155 testRegistered(__FUNCTION__);
156 using input_t = tool::Intersect_t<CoreInputTypes, typename GIM<Separator, AllTypes...>::inputs_t>;
157 using Indices = std::make_index_sequence<std::tuple_size_v<input_t>>;
158
159 testAbstractReceivers<input_t>(core, Indices{});
160
162 this->template addInputNodeToGraph<InputType>(core);
163 }
164
169 template<
170 class CoreOutputTypes,
171 tool::CompatibleOutputCore<CoreOutputTypes, typename GOM<Separator, AllTypes...>::outputs_t> OutputCore>
172 void setOutputForAllCommonTypes(OutputCore *const core) {
173 testRegistered(__FUNCTION__);
174 using CommonTypes = tool::Intersect_t<CoreOutputTypes, typename GOM<Separator, AllTypes...>::outputs_t>;
175 using Indices = std::make_index_sequence<std::tuple_size_v<CommonTypes>>;
176 Indices indices{};
177 testAbstractSenders<CoreOutputTypes>(core, indices);
179 callAddOutputNodeToGraph<CommonTypes>(core, indices);
180 }
181
187 template<class OutputType,
188 class CoreOutputTypes,
190 OutputType, CoreOutputTypes, typename GOM<Separator, AllTypes...
191 >::outputs_t> OutputCore>
192 void setOutputForACommonType(OutputCore *const core) {
193 testRegistered(__FUNCTION__);
194
195 using OutputType_t = std::tuple<OutputType>;
196 using IndicesCommonTypes = std::make_index_sequence<std::tuple_size_v<OutputType_t>>;
197 IndicesCommonTypes indices{};
198 testAbstractSenders<OutputType_t>(core, indices);
199
201 this->template addOutputNodeToGraph<OutputType>(core);
202 }
203
209 template<class OutputTypesSenderTuple, class InputTypeReceiverTuple>
210 void addEdgeForAllCommonTypes(NodeAbstraction *const senderCore, NodeAbstraction *const receiverCore) {
211 testRegistered(__FUNCTION__);
212
214
215 using IndicesCommonTypes = std::make_index_sequence<std::tuple_size_v<CommonTypes>>;
216 IndicesCommonTypes indices{};
217
218 static_assert(
219 std::tuple_size_v<CommonTypes> != 0,
220 "When adding an edge between two nodes, they should share at least one type."
221 );
222
223 testAbstractReceivers<CommonTypes>(receiverCore, indices);
224 testAbstractSenders<CommonTypes>(senderCore, indices);
225
226 registerNodeInsideGraph(senderCore);
227 registerNodeInsideGraph(receiverCore);
228
229 connectNotifierToSlot(senderCore, receiverCore);
230 drawEdges<CommonTypes>(senderCore, receiverCore, indices);
231 }
232
239 template<class CommonType,
240 class OutputTypesSenderTuple,
241 class InputTypeReceiverTuple>
242 void addEdgeForACommonType(NodeAbstraction *const senderCore, NodeAbstraction *const receiverCore) {
243 testRegistered(__FUNCTION__);
244 using CommonType_t = std::tuple<CommonType>;
245 using Indices = std::make_index_sequence<std::tuple_size_v<CommonType_t>>;
246 Indices indices{};
247
249 static_assert(
250 std::tuple_size_v<CommonTypes> != 0,
251 "When adding an edge between two nodes, they should share at least one type.");
252 static_assert(
253 tool::isContainedInTuple_v<CommonType, CommonTypes>,
254 "The type should be part of the types shared between the two cores that you want to connect."
255 );
256
257 testAbstractReceivers<CommonType_t>(receiverCore, indices);
258 testAbstractSenders<CommonType_t>(senderCore, indices);
259
260 registerNodeInsideGraph(senderCore);
261 registerNodeInsideGraph(receiverCore);
262
263 connectNotifierToSlot(senderCore, receiverCore);
264 drawEdge<CommonType>(senderCore, receiverCore);
265 }
266
270 void executeGraph(bool waitForInitialization) {
271 testRegistered(__FUNCTION__);
273 createInnerGroupsAndLaunchThreads(waitForInitialization);
274 auto finishCreationTime = std::chrono::system_clock::now();
275 this->graphConstructionDuration(finishCreationTime - this->graphStartCreation());
276 this->startExecutionTimeStamp(std::chrono::system_clock::now());
277 }
278
282 testRegistered(__FUNCTION__);
283 this->terminateSource();
284 }
285
289 joinThreads();
290 std::chrono::time_point<std::chrono::system_clock>
291 endExecutionTimeStamp = std::chrono::system_clock::now();
292 this->incrementExecutionDuration(endExecutionTimeStamp - this->startExecutionTimeStamp());
293 }
294
298 template<tool::MatchInputTypeConcept<tool::Inputs<Separator, AllTypes...>> CompatibleInputType_t>
299 void broadcastAndNotifyAllInputNodes(std::shared_ptr<CompatibleInputType_t> &data) {
300
301 testRegistered(__FUNCTION__);
302 this->sendInputDataToSource(data);
303 }
304
307 void visit(Printer *printer) override {
308 if (printer->registerNode(this)) {
309 printer->printGraphHeader(this);
310 this->printSource(printer);
311 this->printSink(printer);
312
313 for (auto insideNodeGroups : *(this->insideNodesAndGroups_)) {
314 if (insideNodeGroups.second.size() == 0) {
315 if(auto printableNode = dynamic_cast<abstraction::PrintableAbstraction*>(insideNodeGroups.first))
316 printableNode->visit(printer);
317 } else {
318 printer->printGroup(insideNodeGroups.first, insideNodeGroups.second);
319 }
320 }
321 printer->printGraphFooter(this);
322 }
323 }
324
327 void cleanGraph() {
328 testRegistered(__FUNCTION__);
329 if (this->graphStatus_ != Status::TERM) {
330 std::unordered_set<behavior::Cleanable *> cleanableSet;
331 for (auto insideNodeGroups : *(this->insideNodesAndGroups_)) {
332 if (auto cleanableReresentative =
333 dynamic_cast<hh::core::abstraction::CleanableAbstraction *>(insideNodeGroups.first)) {
334 cleanableReresentative->gatherCleanable(cleanableSet);
335 for (auto copy : insideNodeGroups.second) {
336 dynamic_cast<hh::core::abstraction::CleanableAbstraction *>(copy)->gatherCleanable(cleanableSet);
337 }
338 }
339 }
340 for (auto &cleanableNode : cleanableSet) {
341 cleanableNode->clean();
342 }
343 } else {
344 throw std::runtime_error("It is not possible to clean a graph while it is terminating.");
345 }
346 }
347
351 [[nodiscard]] std::vector<std::pair<std::string const, std::string const>> ids() const override {
352 std::vector<std::pair<std::string const, std::string const>> idInputNodesAndGroups;
353 for (auto inputNodes : abstraction::SlotAbstraction::connectedNotifiers()) {
354 for (auto inputNotifier : inputNodes->notifiers()) {
355 if (auto inputNode = dynamic_cast<NodeAbstraction *>(inputNotifier)) {
356 for (auto const &id : inputNode->ids()) { idInputNodesAndGroups.push_back(id); }
357 } else {
358 throw std::runtime_error("An input node should derive from NodeAbstraction.");
359 }
360 }
361 }
362 return idInputNodesAndGroups;
363 }
364
367 [[nodiscard]] behavior::Node *node() const override { return graph_; }
368
369 private:
371 void joinThreads() override { this->scheduler_->joinAll(); }
372
374 void setInside() override {
376 this->disconnectSource();
377 this->disconnectSink();
378 }
379
384 void registerNodeInsideGraph(NodeAbstraction *const core) override {
385 if (core->isRegistered()) {
386 if (core->belongingGraph() != this) {
387 std::ostringstream oss;
388 oss << "You can not modify a graph that is connected inside another graph.";
389 throw (std::runtime_error(oss.str()));
390 }
391 } else {
392 if (core != this) {
393 core->registerNode(this);
394 this->insideNodesAndGroups_->insert({core, {}});
395 } else {
396 std::ostringstream oss;
397 oss << "You can not add a graph to itself.";
398 throw (std::runtime_error(oss.str()));
399 }
400 }
401 }
402
407 template<class InputTypes, size_t ...Indices>
408 void callAddInputNodeToGraph(NodeAbstraction *const core, std::index_sequence<Indices...>) {
409 (this->template addInputNodeToGraph<std::tuple_element_t<Indices, InputTypes>>(core), ...);
410 }
411
416 template<class OutputTypes, size_t ...Indices>
417 void callAddOutputNodeToGraph(NodeAbstraction *const core, std::index_sequence<Indices...>) {
418 (this->template addOutputNodeToGraph<std::tuple_element_t<Indices, OutputTypes>>(core), ...);
419 }
420
425 void connectNotifierToSlot(NodeAbstraction *senderCore, NodeAbstraction *receiverCore) {
426 auto notifierAbstraction = dynamic_cast<abstraction::NotifierAbstraction *>(senderCore);
427 auto slotAbstraction = dynamic_cast<abstraction::SlotAbstraction *>(receiverCore);
428
429 if (notifierAbstraction == nullptr) {
430 std::ostringstream oss;
431 oss << "The sender node " << senderCore->name()
432 << "has a malformed core (missing inheritance to NotifierAbstraction)";
433 throw (std::runtime_error(oss.str()));
434 }
435
436 if (slotAbstraction == nullptr) {
437 std::ostringstream oss;
438 oss << "The receiver node " << receiverCore->name()
439 << "has a malformed core (missing inheritance to SlotAbstraction)";
440 throw (std::runtime_error(oss.str()));
441 }
442
443 for (auto notifier : notifierAbstraction->notifiers()) {
444 for (auto slot : slotAbstraction->slots()) {
445 notifier->addSlot(slot);
446 slot->addNotifier(notifier);
447 }
448 }
449 }
450
455 template<class CommonType>
456 void drawEdge(NodeAbstraction *const senderCore, NodeAbstraction *const receiverCore) {
457 auto senderAbstraction = dynamic_cast<abstraction::SenderAbstraction<CommonType> *>(senderCore);
458 auto receiverAbstraction = dynamic_cast<abstraction::ReceiverAbstraction<CommonType> *>(receiverCore);
459
460 assert(senderAbstraction != nullptr && receiverAbstraction != nullptr);
461
462 for (auto sender : senderAbstraction->senders()) {
463 for (auto receiver : receiverAbstraction->receivers()) {
464 sender->addReceiver(receiver);
465 receiver->addSender(sender);
466 }
467 }
468 }
469
475 template<class CommonTypes, size_t ...Indexes>
477 NodeAbstraction *const senderCore,
478 NodeAbstraction *const receiverCore,
479 std::index_sequence<Indexes...>) {
480 (drawEdge<std::tuple_element_t<Indexes, CommonTypes>>(senderCore, receiverCore), ...);
481 }
482
488 template<class TupleInputs, size_t... Indices>
489 void testAbstractReceivers(NodeAbstraction *const core, std::index_sequence<Indices...>) {
490 // The core inherits from ReceiverAbstraction for every input common types between the node and the graph
492 == nullptr) || ... )) {
493 std::ostringstream oss;
494 oss << "The node " << core->name()
495 << " does not have a well defined core (missing inheritance from ReceiverAbstraction).";
496 throw std::runtime_error(oss.str());
497 }
498 }
499
505 template<class TupleOutputs, size_t... Indices>
506 void testAbstractSenders(NodeAbstraction *const core, std::index_sequence<Indices...>) {
507 // The core inherits from ReceiverAbstraction for every input common types between the node and the graph
509 == nullptr) || ... )) {
510 std::ostringstream oss;
511 oss << "The node " << core->name()
512 << " does not have a well defined core (missing inheritance from SenderAbstraction).";
513 throw std::runtime_error(oss.str());
514 }
515 }
516
519 void testRegistered(auto const &funcName) {
520 if (this->isRegistered()) {
521 std::ostringstream oss;
522 oss << "You can not modify a graph that is connected inside another graph: " << funcName;
523 throw (std::runtime_error(oss.str()));
524 }
525 }
526
529 void createInnerGroupsAndLaunchThreads(bool waitForInitialization) override {
530 for (auto const &insideNode : *this->insideNodesAndGroups_) {
531 if (auto copyableNode = dynamic_cast<abstraction::AnyGroupableAbstraction *>(insideNode.first)) {
532 copyableNode->createGroup(*this->insideNodesAndGroups_);
533 for (auto &copy : insideNode.second) {
534 copy->registerNode(this);
535 }
536 } else if (auto graph = dynamic_cast<GraphNodeAbstraction *>(insideNode.first)) {
537 graph->createInnerGroupsAndLaunchThreads(waitForInitialization);
538 } else if (auto ep = dynamic_cast<abstraction::ExecutionPipelineNodeAbstraction *>(insideNode.first)) {
539 ep->launchGraphThreads(waitForInitialization);
540 }
541 }
542 launchThreads(waitForInitialization);
543 }
544
547 void launchThreads(bool waitForInitialization) {
548 std::set<NodeAbstraction *> nodeAbstractions;
549 for (auto &insideNode : *this->insideNodesAndGroups_) {
550 nodeAbstractions.insert(insideNode.first);
551 std::for_each(
552 insideNode.second.cbegin(), insideNode.second.cend(),
553 [&nodeAbstractions](auto &nodeAbstraction) { nodeAbstractions.insert(nodeAbstraction); });
554 }
555 scheduler_->spawnThreads(nodeAbstractions, waitForInitialization);
556 }
557
560 void gatherCleanable(std::unordered_set<hh::behavior::Cleanable *> &cleanableSet) override {
561 for (auto insideNodeGroups : *(this->insideNodesAndGroups_)) {
562 if (auto cleanableReresentative =
563 dynamic_cast<hh::core::abstraction::CleanableAbstraction *>(insideNodeGroups.first)) {
564 cleanableReresentative->gatherCleanable(cleanableSet);
565 for (auto copy : insideNodeGroups.second) {
566 if (auto cleanableCopy = dynamic_cast<hh::core::abstraction::CleanableAbstraction *>(copy)) {
567 cleanableCopy->gatherCleanable(cleanableSet);
568 } else { throw std::runtime_error("A copy of a cleanable node should be a cleanable node."); }
569 }
570 }
571 }
572 }
573
577 std::shared_ptr<abstraction::NodeAbstraction> clone(std::map<NodeAbstraction *,
578 std::shared_ptr<NodeAbstraction>> &correspondenceMap) override {
579 return std::make_shared<CoreGraph<Separator, AllTypes...>>(*this, correspondenceMap);
580 }
581
586 std::map<NodeAbstraction *, std::shared_ptr<NodeAbstraction>> &correspondenceMap) {
587 auto originalInsideNodes = *(rhs.insideNodesAndGroups_);
588 std::shared_ptr<NodeAbstraction> nodeClone;
589
590 for (auto &originalNode : originalInsideNodes) {
591 if (auto originalAsClonable = dynamic_cast<abstraction::ClonableAbstraction *>(originalNode.first)) {
592 if (!correspondenceMap.contains(originalNode.first)) {
593 nodeClone = originalAsClonable->clone(correspondenceMap);
594 storeClone(nodeClone);
595 this->registerNodeInsideGraph(nodeClone.get());
596 correspondenceMap.insert({originalNode.first, nodeClone});
597 }
598 }
599 }
600
601 this->duplicateSourceEdges(rhs, correspondenceMap);
602 this->duplicateSinkEdges(rhs, correspondenceMap);
603
604 for (auto &originalNode : originalInsideNodes) {
605 if (auto originalAsClonable = dynamic_cast<abstraction::ClonableAbstraction *>(originalNode.first)) {
606 originalAsClonable->duplicateEdge(correspondenceMap);
607 }
608 }
609 }
610
613 void duplicateEdge(std::map<NodeAbstraction *, std::shared_ptr<NodeAbstraction>> &mapping) override {
614 this->duplicateOutputEdges(mapping);
615 }
616
617};
618}
619}
620#endif //HEDGEHOG_CORE_GRAPH_H
Hedgehog main namespace.
typename internals::Intersect< Tuple1, Tuple2 >::type Intersect_t
Helper getting the intersection of types between two type tuples.
typename internals::Splitter< delta, Types... >::Inputs Inputs
Helper getting the input types from a list of template types (variadic)
typename internals::Splitter< delta, Types... >::Outputs Outputs
Helper getting the output types from a list of template types (variadic)
tool::GraphOutputsManagementAbstractionTypeDeducer_t< tool::Outputs< Separator, AllTypes... > > GOM
Type alias for an GraphOutputsManagementAbstraction from the list of template parameters.
Definition: core_graph.h:70
tool::GraphInputsManagementAbstractionTypeDeducer_t< tool::Inputs< Separator, AllTypes... > > GIM
Type alias for an GraphInputsManagementAbstraction from the list of template parameters.
Definition: core_graph.h:66
Hedgehog graph abstraction.
Definition: graph.h:137
Printer abstraction to get a snapshot of the metrics of the Hedgehog graph.
Definition: printer.h:52
virtual void printGraphFooter(core::abstraction::GraphNodeAbstraction const *graph)=0
Print graph footer.
bool registerNode(core::abstraction::NodeAbstraction const *nodeAbstraction)
Register a visited node.
Definition: printer.h:113
virtual void printGroup(core::abstraction::NodeAbstraction *representative, std::vector< core::abstraction::NodeAbstraction * > const &group)=0
Print group of nodes.
virtual void printGraphHeader(core::abstraction::GraphNodeAbstraction const *graph)=0
Print graph header.
Behavior abstraction for the base node.
Definition: node.h:32
Abstraction for cores/nodes that can form groups.
CleanableAbstraction()=default
Constructor used by the CoreGraph to have the handles to clean inner cleanable nodes.
Core abstraction for clonable nodes, nodes duplicated by execution pipeline.
void storeClone(std::shared_ptr< abstraction::NodeAbstraction > const &clone)
Store a core clone.
Core abstraction to notify slots.
Core's abstraction to receive a piece of data.
Core abstraction to send data.
Core's abstraction to receive a signal.
std::set< NotifierAbstraction * > const & connectedNotifiers() const
Accessor to the NotifierAbstraction attached to this slot, protected with mutex.
void addNotifier(NotifierAbstraction *const notifier)
Add a NotifierAbstraction to this slot.
std::chrono::nanoseconds const & graphConstructionDuration() const
Graph construction duration accessor.
GraphNodeAbstraction(std::string const &name)
Base graph abstraction.
std::chrono::time_point< std::chrono::system_clock > const & graphStartCreation() const
Graph start creation timestamp accessor.
std::unique_ptr< std::map< NodeAbstraction *, std::vector< NodeAbstraction * > > > const insideNodesAndGroups_
All nodes of the graph, mapped to their group nodes.
std::chrono::time_point< std::chrono::system_clock > const & startExecutionTimeStamp() const
Accessor to the starting execution timestamp.
NodeAbstraction(std::string name)
Core node constructor using the core's name.
bool isRegistered() const
Accessor to registration flag.
void incrementExecutionDuration(std::chrono::nanoseconds const &exec)
Increment execution duration.
std::string const & name() const
Accessor to the core's name.
PrintAbstraction, used to determine if the node should be visited by the printer and colored.
Graph core.
Definition: core_graph.h:81
void cleanGraph()
Clean the graph.
Definition: core_graph.h:327
std::unique_ptr< Scheduler > const scheduler_
Scheduler used by the graph.
Definition: core_graph.h:86
void callAddInputNodeToGraph(NodeAbstraction *const core, std::index_sequence< Indices... >)
Call addInputNodeToGraph for all type-elements of a tuple.
Definition: core_graph.h:408
void visit(Printer *printer) override
Visit the graph.
Definition: core_graph.h:307
void joinThreads() override
Wait for the threads to join.
Definition: core_graph.h:371
void drawEdges(NodeAbstraction *const senderCore, NodeAbstraction *const receiverCore, std::index_sequence< Indexes... >)
Do the actual typed connections between a sender and receiver.
Definition: core_graph.h:476
void callAddOutputNodeToGraph(NodeAbstraction *const core, std::index_sequence< Indices... >)
Call addOutputNodeToGraph for all type-elements of a tuple.
Definition: core_graph.h:417
std::shared_ptr< abstraction::NodeAbstraction > clone(std::map< NodeAbstraction *, std::shared_ptr< NodeAbstraction > > &correspondenceMap) override
Clone the current graph.
Definition: core_graph.h:577
void setInputForAllCommonTypes(InputCore *const core)
Connect a core's node as input of the graph for all compatible types.
Definition: core_graph.h:126
void createInnerGroupsAndLaunchThreads(bool waitForInitialization) override
Create the inner groups and launch the threads inside of a graph.
Definition: core_graph.h:529
void executeGraph(bool waitForInitialization)
Execute the graph.
Definition: core_graph.h:270
void testAbstractSenders(NodeAbstraction *const core, std::index_sequence< Indices... >)
Test a core if it can send data of specific types.
Definition: core_graph.h:506
~CoreGraph() override=default
Default destructor.
void testAbstractReceivers(NodeAbstraction *const core, std::index_sequence< Indices... >)
Test a core if it can receives data of specific types.
Definition: core_graph.h:489
void testRegistered(auto const &funcName)
Test if the graph has been registered.
Definition: core_graph.h:519
void addEdgeForACommonType(NodeAbstraction *const senderCore, NodeAbstraction *const receiverCore)
Connect two nodes together for a common type.
Definition: core_graph.h:242
void setOutputForAllCommonTypes(OutputCore *const core)
Connect a core's node as output of the graph for all compatible types.
Definition: core_graph.h:172
std::vector< std::pair< std::string const, std::string const > > ids() const override
Node ids [nodeId, nodeGroupId] accessor.
Definition: core_graph.h:351
CoreGraph(CoreGraph const &rhs, std::map< NodeAbstraction *, std::shared_ptr< NodeAbstraction > > &correspondenceMap)
Copy constructor using an added correspondence map.
Definition: core_graph.h:105
void broadcastAndNotifyAllInputNodes(std::shared_ptr< CompatibleInputType_t > &data)
Broadcast an input data to all inputs nodes.
Definition: core_graph.h:299
behavior::Node * node() const override
Node accessor.
Definition: core_graph.h:367
void connectNotifierToSlot(NodeAbstraction *senderCore, NodeAbstraction *receiverCore)
Connect a notifier to a slot, used when connecting two nodes.
Definition: core_graph.h:425
void duplicateInsideNodes(CoreGraph const &rhs, std::map< NodeAbstraction *, std::shared_ptr< NodeAbstraction > > &correspondenceMap)
Clone all of the inside nodes.
Definition: core_graph.h:585
void finishPushingData()
Indicate to the graph that no more input will be sent, trigger the termination of the graph.
Definition: core_graph.h:280
CoreGraph(std::string const &name, std::unique_ptr< Scheduler > scheduler, hh::Graph< Separator, AllTypes... > *graph)
Core Graph constructor using the name and the scheduler.
Definition: core_graph.h:94
hh::Graph< Separator, AllTypes... > *const graph_
Graph attached to this core.
Definition: core_graph.h:88
void waitForTermination()
Wait for the graph to terminate.
Definition: core_graph.h:288
void launchThreads(bool waitForInitialization)
Launch the threads with the scheduler.
Definition: core_graph.h:547
void duplicateEdge(std::map< NodeAbstraction *, std::shared_ptr< NodeAbstraction > > &mapping) override
Duplicate the graph output's edges.
Definition: core_graph.h:613
void gatherCleanable(std::unordered_set< hh::behavior::Cleanable * > &cleanableSet) override
Gather cleanable nodes.
Definition: core_graph.h:560
void registerNodeInsideGraph(NodeAbstraction *const core) override
Register a node inside of a graph.
Definition: core_graph.h:384
void addEdgeForAllCommonTypes(NodeAbstraction *const senderCore, NodeAbstraction *const receiverCore)
Connect two nodes together for all common types.
Definition: core_graph.h:210
void drawEdge(NodeAbstraction *const senderCore, NodeAbstraction *const receiverCore)
Do the actual typed connection between a sender and receiver.
Definition: core_graph.h:456
void setInputForACommonType(InputCore *const core)
Connect a core's node as input of the graph for an compatible input type.
Definition: core_graph.h:154
void setOutputForACommonType(OutputCore *const core)
Connect a core's node as output of the graph for a compatible type.
Definition: core_graph.h:192
void setInside() override
Set the graph as inside of another graph.
Definition: core_graph.h:374
Test if an input type is in the list of input types (tuple)
Definition: concepts.h:98
Test if a core can be input of a graph (derives from core::abstraction::NodeAbstraction and shares at...
Definition: concepts.h:130
Test if a core can be input of a graph for a type (derives from core::abstraction::NodeAbstraction an...
Definition: concepts.h:142
Test if a core can be output of a graph (derives from core::abstraction::NodeAbstraction and shares a...
Definition: concepts.h:153
Test if a core can be output of a graph for a type (derives from core::abstraction::NodeAbstraction a...
Definition: concepts.h:166