Hedgehog  3.1.0
A library to generate hybrid pipeline workflow systems
Loading...
Searching...
No Matches
graph_outputs_management_abstraction.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_GRAPH_OUTPUTS_MANAGEMENT_ABSTRACTION_H
22#define HEDGEHOG_GRAPH_OUTPUTS_MANAGEMENT_ABSTRACTION_H
23
24#include <ostream>
25#include "../../parts/graph_sink.h"
26
27#include "../base/input_output/slot_abstraction.h"
28#include "../base/input_output/sender_abstraction.h"
29#include "../base/input_output/notifier_abstraction.h"
30#include "../base/input_output/receiver_abstraction.h"
31
32#include "../../../tools/concepts.h"
33#include "../../implementors/concrete_implementor/graph/graph_notifier.h"
34#include "../../implementors/concrete_implementor/graph/graph_sender.h"
36namespace hh {
38namespace core {
40namespace abstraction {
41
44template<class ...Outputs>
47 public SenderAbstraction<Outputs> ... {
48 private:
49 std::unique_ptr<GraphSink < Outputs...>> sink_ = nullptr;
50
51 public:
52 using outputs_t = std::tuple<Outputs...>;
53
56 NotifierAbstraction(std::make_shared<implementor::GraphNotifier>()),
57 SenderAbstraction<Outputs>(std::make_shared<implementor::GraphSender<Outputs>>())...,
58 sink_(std::make_unique<GraphSink < Outputs...>>
59 ()) {}
60
63
66 auto getBlockingResult() { return sink_->getBlockingResult(); }
67
68 protected:
71 std::unique_ptr<GraphSink < Outputs...>> const & sink() const { return sink_; }
72
76 template<class OutputDataType>
77 void addOutputNodeToGraph(NodeAbstraction *const outputNode) {
78 auto outputAsNotifier = dynamic_cast<NotifierAbstraction *>(outputNode);
79 auto outputAsSender = dynamic_cast<SenderAbstraction<OutputDataType> *>(outputNode);
80 assert(outputAsNotifier != nullptr && outputAsSender != nullptr);
81
82 if (sink_ != nullptr) {
83 auto sinkAsReceiver = static_cast<ReceiverAbstraction<OutputDataType> *> (sink_.get());
84 auto sinkAsSlot = static_cast<SlotAbstraction *> (sink_.get());
85
86 for (auto receiver : sinkAsReceiver->receivers()) {
87 for (auto sender : outputAsSender->senders()) {
88 sender->addReceiver(receiver);
89 receiver->addSender(sender);
90 }
91 }
92
93 for (auto slot : sinkAsSlot->slots()) {
94 for (auto notifier : outputAsNotifier->notifiers()) {
95 slot->addNotifier(notifier);
96 notifier->addSlot(slot);
97 }
98 }
99 }
100 }
101
104 if (sink_) {
105 auto sinkAsSlot = static_cast<SlotAbstraction *> (sink_.get());
106 for (auto slot : sinkAsSlot->slots()) {
107 for (auto outputNotifier : sink_->connectedNotifiers()) {
108 for (auto notifier : outputNotifier->notifiers()) {
109 this->notifiers().insert(notifier);
110 notifier->removeSlot(slot);
111 }
112 }
113 }
114 (disconnectSinkFromSender<Outputs>(), ...);
115 sink_ = nullptr;
116 }
117 }
118
121 void printSink(Printer *printer) {
122 if (this->sink_) {
123 this->sink_->print(printer);
124 }
125 }
126
131 std::map<abstraction::NodeAbstraction *, std::shared_ptr<NodeAbstraction>> &mapping) {
132 (duplicateSinkEdge<Outputs>(rhs, mapping), ...);
133 }
134
137 void duplicateOutputEdges(std::map<abstraction::NodeAbstraction *, std::shared_ptr<NodeAbstraction>> &mapping){
139 this->duplicateEdgeNotifier(mapping);
140 }
141
142 private:
145 template<class Output>
147 auto sourceAsReceiver = static_cast<ReceiverAbstraction<Output> *>(sink_.get());
148 for (auto receiver : sourceAsReceiver->receivers()) {
149 for (auto outputSender : receiver->connectedSenders()) {
150 for (auto sender : outputSender->senders()) {
151 SenderAbstraction<Output>::senders().insert(sender);
152 sender->removeReceiver(receiver);
153 }
154 }
155 }
156 }
157
158
163 template<class Output>
165 std::map<abstraction::NodeAbstraction *, std::shared_ptr<NodeAbstraction>> &correspondenceMap) {
166 for (auto &sender : ((SenderAbstraction<Output>*)&rhs)->senders()) {
167 if (auto senderAsClonable = dynamic_cast<abstraction::ClonableAbstraction *>(sender)) {
168 if (auto senderAsNode = dynamic_cast<abstraction::NodeAbstraction *>(sender)) {
169 if (!correspondenceMap.contains(senderAsNode)) {
170 auto duplicate = senderAsClonable->clone(correspondenceMap);
171 dynamic_cast<hh::core::abstraction::GraphNodeAbstraction *>(this)->registerNodeInsideGraph(duplicate.get());
172 correspondenceMap.insert({senderAsNode, duplicate});
173 }
174
175 auto outputNode = correspondenceMap.at(senderAsNode).get();
176
177 auto outputAsNotifier = dynamic_cast<NotifierAbstraction *>(outputNode);
178 auto outputAsSender = dynamic_cast<SenderAbstraction<Output> *>(outputNode);
179
180 assert(outputAsNotifier != nullptr && outputAsSender != nullptr);
181
182 for (auto & outputNotifier : outputAsNotifier->notifiers()) {
183 this->notifiers().insert(outputNotifier);
184 }
185
186 for (auto & outputSender : outputAsSender->senders()) {
187 SenderAbstraction<Output>::senders().insert(outputSender);
188 }
189
190 } else {
191 throw std::runtime_error("An input node core is not a NodeAbstraction.");
192 }
193 }
194 }
195 }
196
197};
198}
199}
200}
201#endif //HEDGEHOG_GRAPH_OUTPUTS_MANAGEMENT_ABSTRACTION_H
Hedgehog main namespace.
Printer abstraction to get a snapshot of the metrics of the Hedgehog graph.
Definition: printer.h:52
Core abstraction for clonable nodes, nodes duplicated by execution pipeline.
Core abstraction to notify slots.
void duplicateEdgeNotifier(std::map< abstraction::NodeAbstraction *, std::shared_ptr< NodeAbstraction > > &mapping)
Duplicate edges of the current notifier to slots to clone in map.
std::set< NotifierAbstraction * > const & notifiers() const
Const accessor to notifiers.
Core's abstraction to receive a piece of data.
Core abstraction to send data.
std::set< SenderAbstraction< Output > * > const & senders() const
Const accessor to senders.
void duplicateEdgeSender(std::map< abstraction::NodeAbstraction *, std::shared_ptr< NodeAbstraction > > &mapping)
Duplicate edges of the current sender to receiver to clone in map.
Core's abstraction to receive a signal.
void addNotifier(NotifierAbstraction *const notifier)
Add a NotifierAbstraction to this slot.
void disconnectSinkFromSender()
Disconnect the sink from the graph's output senders.
void duplicateSinkEdge(GraphOutputsManagementAbstraction< Outputs... > const &rhs, std::map< abstraction::NodeAbstraction *, std::shared_ptr< NodeAbstraction > > &correspondenceMap)
Duplicate sink edge.
void duplicateSinkEdges(GraphOutputsManagementAbstraction< Outputs... > const &rhs, std::map< abstraction::NodeAbstraction *, std::shared_ptr< NodeAbstraction > > &mapping)
Duplicate sink edges.
std::tuple< Outputs... > outputs_t
Accessor to the output types.
void duplicateOutputEdges(std::map< abstraction::NodeAbstraction *, std::shared_ptr< NodeAbstraction > > &mapping)
Duplicate output edges.
~GraphOutputsManagementAbstraction() override=default
Default destructor.
void addOutputNodeToGraph(NodeAbstraction *const outputNode)
Add an output node in the graph.
std::unique_ptr< GraphSink< Outputs... > > const & sink() const
Accessor to the graph's sink.
auto getBlockingResult()
Get a blocking result for the outer graph from the sink.
std::unique_ptr< GraphSink< Outputs... > > sink_
Graph's sink.
Sink of the graph, only used in an outer graph.
Definition: graph_sink.h:43