Hedgehog  0.0.0
A library to generate hybrid pipeline workflow systems
graph.h
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 #ifndef HEDGEHOG_GRAPH_H
21 #define HEDGEHOG_GRAPH_H
22 
23 #include <cassert>
24 #include <ostream>
25 
26 #include "scheduler/abstract_scheduler.h"
27 #include "printer/dot_printer.h"
28 #include "../core/node/core_graph.h"
29 #include "../tools/helper.h"
30 #include "../tools/traits.h"
31 #include "../tools/logger.h"
32 #include "../behavior/io/multi_receivers.h"
33 #include "../behavior/io/sender.h"
34 
36 namespace hh {
37 
84 template<class GraphOutput, class ...GraphInputs>
85 class Graph :
86  public behavior::MultiReceivers<GraphInputs...>,
87  public behavior::Sender<GraphOutput>,
88  public virtual behavior::Node {
89  static_assert(traits::isUnique<GraphInputs...>, "A Graph can't accept multiple inputs with the same type.");
90  static_assert(sizeof... (GraphInputs) >= 1, "A node need to have one output type and at least one output type.");
91  private:
92  std::shared_ptr<core::CoreGraph<GraphOutput, GraphInputs...>> graphCore_ = nullptr;
93  std::set<std::shared_ptr<Node>> insideNodes_ = {};
94 
96  public:
98  Graph() {
99  graphCore_ = std::make_shared<core::CoreGraph<GraphOutput, GraphInputs...>>(this, core::NodeType::Graph, "Graph");
100  }
101 
104  explicit Graph(std::string_view const &name) {
105  graphCore_ = std::make_shared<core::CoreGraph<GraphOutput, GraphInputs...>>(this, core::NodeType::Graph, name);
106  }
107 
124  explicit Graph(std::string_view const &name, std::unique_ptr<AbstractScheduler> scheduler) {
125  if (!scheduler) {
126  std::ostringstream oss;
127  oss << "Internal error, the graph's scheduler is null, please instantiate an AbstractScheduler.";
128  HLOG_SELF(0, oss.str())
129  throw (std::runtime_error(oss.str()));
130  }
131  graphCore_ =
132  std::make_shared<core::CoreGraph<GraphOutput, GraphInputs...>>(
133  this, core::NodeType::Graph, name, std::move(scheduler));
134  }
135 
137  virtual ~Graph() = default;
138 
141  std::shared_ptr<core::CoreNode> core() final { return this->graphCore_; }
142 
145  std::string_view const &name() { return this->core()->name(); }
146 
149  void deviceId(int deviceId) { this->graphCore_->deviceId(deviceId); }
150 
158  template<
159  class UserDefinedMultiReceiver,
160  class InputsMR = typename UserDefinedMultiReceiver::inputs_t,
161  class InputsG = typename behavior::MultiReceivers<GraphInputs...>::inputs_t,
162  class isMultiReceiver = typename std::enable_if_t<
163  std::is_base_of_v<typename helper::HelperMultiReceiversType<InputsMR>::type, UserDefinedMultiReceiver>
164  >,
165  class isInputCompatible = typename std::enable_if_t<traits::is_included_v<InputsMR, InputsG>>>
166  void input(std::shared_ptr<UserDefinedMultiReceiver> input) {
167  assert(input != nullptr);
168  this->insideNodes_.insert(input);
169  auto test = std::dynamic_pointer_cast<typename helper::HelperMultiReceiversType<InputsMR>::type>(input);
170  if (test == nullptr) { std::cout << "big problem " << input << std::endl; }
171  this->graphCore_->input(test);
172  }
173 
178  template<
179  class UserDefinedSender,
180  class IsSender = typename std::enable_if_t<
181  std::is_base_of_v<
182  behavior::Sender<GraphOutput>, UserDefinedSender
183  >
184  >
185  >
186  void output(std::shared_ptr<UserDefinedSender> output) {
187  assert(output != nullptr);
188  this->insideNodes_.insert(output);
189  this->graphCore_->output(std::static_pointer_cast<behavior::Sender<GraphOutput>>(output));
190  }
191 
201  template<
202  class UserDefinedSender, class UserDefinedMultiReceiver,
203  class Output = typename UserDefinedSender::output_t,
204  class Inputs = typename UserDefinedMultiReceiver::inputs_t,
205  class IsSender = typename std::enable_if_t<std::is_base_of_v<behavior::Sender<Output>, UserDefinedSender>>,
206  class IsMultiReceivers = typename std::enable_if_t<
207  std::is_base_of_v<
208  typename helper::HelperMultiReceiversType<Inputs>::type, UserDefinedMultiReceiver
209  >
210  >
211  >
212  void addEdge(std::shared_ptr<UserDefinedSender> from, std::shared_ptr<UserDefinedMultiReceiver> to) {
213  static_assert(traits::Contains_v<Output, Inputs>,
214  "The given io cannot be linked to this io: No common types.");
215  this->insideNodes_.insert(from);
216  this->insideNodes_.insert(to);
217  this->graphCore_->addEdge(std::static_pointer_cast<behavior::Sender<Output>>(from),
218  std::static_pointer_cast<typename helper::HelperMultiReceiversType<Inputs>::type>(to));
219  }
220 
223  void executeGraph() { this->graphCore_->executeGraph(); }
224 
229  template<
230  class Input,
231  class = typename std::enable_if_t<traits::Contains<Input, GraphInputs...>::value>
232  >
233  void pushData(std::shared_ptr<Input> data) { this->graphCore_->broadcastAndNotifyToAllInputs(data); }
234 
236  void finishPushingData() { this->graphCore_->finishPushingData(); }
237 
246  std::shared_ptr<GraphOutput> getBlockingResult() { return this->graphCore_->getBlockingResult(); }
247 
249  void waitForTermination() { this->graphCore_->waitForTermination(); }
250 
259  void createDotFile(std::filesystem::path const &dotFilePath,
260  ColorScheme colorScheme = ColorScheme::NONE,
261  StructureOptions structureOptions = StructureOptions::NONE,
262  DebugOptions debugOption = DebugOptions::NONE) {
263  auto core = this->core().get();
264  DotPrinter printer(std::filesystem::absolute(dotFilePath), colorScheme, structureOptions, debugOption, core);
265  core->visit(&printer);
266  }
267 };
268 
269 }
270 #endif //HEDGEHOG_GRAPH_H
void waitForTermination()
Wait for the graph to terminate (data to be processed, all threads to join)
Definition: graph.h:249
void pushData(std::shared_ptr< Input > data)
Push data into the graph.
Definition: graph.h:233
std::shared_ptr< core::CoreGraph< GraphOutput, GraphInputs... > > graphCore_
Graph core as shared_ptr.
Definition: graph.h:92
std::shared_ptr< GraphOutput > getBlockingResult()
Get a data out of the graph.
Definition: graph.h:246
void addEdge(std::shared_ptr< UserDefinedSender > from, std::shared_ptr< UserDefinedMultiReceiver > to)
Add a directed edge from a compatible "from" node to "to" node.
Definition: graph.h:212
Printer to produce a dot representation of the current state of the graph.
Definition: dot_printer.h:59
Graph(std::string_view const &name)
Graph constructor with a custom name.
Definition: graph.h:104
StructureOptions
Enum structural options.
Definition: dot_printer.h:44
std::set< std::shared_ptr< Node > > insideNodes_
Graph&#39;s inside nodes, register user node in case it&#39;s not saved elsewhere.
Definition: graph.h:93
Hedgehog main namespace.
void finishPushingData()
Signal the graph that no more data will be pushed into the graph.
Definition: graph.h:236
Sender Behavior definition, node has an output type.
Definition: sender.h:32
Check if a template T is in Template pack Ts.
Definition: traits.h:77
Graph()
Default graph constructor, the default name is "Graph".
Definition: graph.h:98
virtual ~Graph()=default
Default Graph destructor.
DebugOptions
Enum to enable debug printing.
Definition: dot_printer.h:52
Node Behavior definition.
Definition: node.h:39
void createDotFile(std::filesystem::path const &dotFilePath, ColorScheme colorScheme=ColorScheme::NONE, StructureOptions structureOptions=StructureOptions::NONE, DebugOptions debugOption=DebugOptions::NONE)
Create a dot file representing a snapshot of the state of the graph at the moment of the call...
Definition: graph.h:259
Main Hedgehog object that does computation.
Definition: graph.h:85
void output(std::shared_ptr< UserDefinedSender > output)
Set a node as output for the graph.
Definition: graph.h:186
std::string_view const & name()
Graph name accessor.
Definition: graph.h:145
MultiReceivers Behavior definition, node has a list of input types.
Core associated to the Graph.
Definition: core_graph.h:63
void executeGraph()
Launch the graph once it has been structured.
Definition: graph.h:223
std::shared_ptr< core::CoreNode > core() final
Graph core accessor.
Definition: graph.h:141
No added coloration.
Graph(std::string_view const &name, std::unique_ptr< AbstractScheduler > scheduler)
Graph constructor with a custom name and a custom scheduler.
Definition: graph.h:124
Base definition of HelperMultiReceiversType.
Definition: helper.h:50
ColorScheme
Enum color options.
Definition: dot_printer.h:37
void deviceId(int deviceId)
Device Id for the graph, all inside nodes will be bound to this device Id.
Definition: graph.h:149
std::tuple< Inputs... > inputs_t
Tuple with the list of input types.
void input(std::shared_ptr< UserDefinedMultiReceiver > input)
Set a node as input for the graph.
Definition: graph.h:166