Hedgehog  0.0.0
A library to generate hybrid pipeline workflow systems
hh::Graph< GraphOutput, GraphInputs > Class Template Reference

Main Hedgehog object that does computation. More...

#include "graph.h"

Inheritance diagram for hh::Graph< GraphOutput, GraphInputs >:
Inheritance graph
Collaboration diagram for hh::Graph< GraphOutput, GraphInputs >:
Collaboration graph

Public Member Functions

 Graph ()
 Default graph constructor, the default name is "Graph".
 
 Graph (std::string_view const &name)
 Graph constructor with a custom name. More...
 
 Graph (std::string_view const &name, std::unique_ptr< AbstractScheduler > scheduler)
 Graph constructor with a custom name and a custom scheduler. More...
 
virtual ~Graph ()=default
 Default Graph destructor.
 
std::shared_ptr< core::CoreNodecore () final
 Graph core accessor. More...
 
std::string_view const & name ()
 Graph name accessor. More...
 
void deviceId (int deviceId)
 Device Id for the graph, all inside nodes will be bound to this device Id. More...
 
template<class UserDefinedMultiReceiver , class InputsMR = typename UserDefinedMultiReceiver::inputs_t, class InputsG = typename behavior::MultiReceivers<GraphInputs...>::inputs_t, class isMultiReceiver = typename std::enable_if_t< std::is_base_of_v<typename helper::HelperMultiReceiversType<InputsMR>::type, UserDefinedMultiReceiver> >, class isInputCompatible = typename std::enable_if_t<traits::is_included_v<InputsMR, InputsG>>>
void input (std::shared_ptr< UserDefinedMultiReceiver > input)
 Set a node as input for the graph. More...
 
template<class UserDefinedSender , class IsSender = typename std::enable_if_t< std::is_base_of_v< behavior::Sender<GraphOutput>, UserDefinedSender > >>
void output (std::shared_ptr< UserDefinedSender > output)
 Set a node as output for the graph. More...
 
template<class UserDefinedSender , class UserDefinedMultiReceiver , class Output = typename UserDefinedSender::output_t, class Inputs = typename UserDefinedMultiReceiver::inputs_t, class IsSender = typename std::enable_if_t<std::is_base_of_v<behavior::Sender<Output>, UserDefinedSender>>, class IsMultiReceivers = typename std::enable_if_t< std::is_base_of_v< typename helper::HelperMultiReceiversType<Inputs>::type, UserDefinedMultiReceiver > >>
void addEdge (std::shared_ptr< UserDefinedSender > from, std::shared_ptr< UserDefinedMultiReceiver > to)
 Add a directed edge from a compatible "from" node to "to" node. More...
 
void executeGraph ()
 Launch the graph once it has been structured. More...
 
template<class Input , class = typename std::enable_if_t<traits::Contains<Input, GraphInputs...>::value>>
void pushData (std::shared_ptr< Input > data)
 Push data into the graph. More...
 
void finishPushingData ()
 Signal the graph that no more data will be pushed into the graph.
 
std::shared_ptr< GraphOutput > getBlockingResult ()
 Get a data out of the graph. More...
 
void waitForTermination ()
 Wait for the graph to terminate (data to be processed, all threads to join)
 
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, the graph is saved into the file dotFilePath. More...
 
- Public Member Functions inherited from hh::behavior::Node
virtual std::string extraPrintingInformation () const
 Adds node information to print in the dot file. More...
 
virtual bool canTerminate ()
 Determine if the node can terminate. More...
 

Private Attributes

std::shared_ptr< core::CoreGraph< GraphOutput, GraphInputs... > > graphCore_ = nullptr
 Graph core as shared_ptr.
 
std::set< std::shared_ptr< Node > > insideNodes_ = {}
 Graph's inside nodes, register user node in case it's not saved elsewhere.
 

Additional Inherited Members

- Public Types inherited from hh::behavior::MultiReceivers< GraphInputs... >
using inputs_t = std::tuple< Inputs... >
 Tuple with the list of input types.
 
- Public Types inherited from hh::behavior::Sender< GraphOutput >
using output_t = GraphOutput
 Output Type.
 

Detailed Description

template<class GraphOutput, class ... GraphInputs>
class hh::Graph< GraphOutput, GraphInputs >

Main Hedgehog object that does computation.

Hedgehog represents an algorithm with a dataflow graph.

Data in the graph represents any primitive type, struct, class, etc., that is used to pass to operations.

Data is sent to the graph through the method Graph::pushData, while broadcasts to all input nodes. A node is an input node if:

  • The node is registered as graph's input with Graph::input,
  • The node can receive data,
  • At least one of the node's input types matches to a graph's input type. Data of this common type received by the graph will be transferred to this node.

Directed edges can be added between two nodes "from" to "to" with Graph::addEdge, if:

  • The from's output type is one of to's input type,
  • from is a node that can send data,
  • to is a node that can receive data.

Data is received from the Graph with Graph::getBlockingResult, from output nodes. A node is an output node if:

  • The node is registered as a graph's output with Graph::output (there can be any number of nodes registered as output),
  • The node can send data,
  • The node's output type matches a graph's output type.

Data is sent to the graph with Graph::pushData, which will be directed to the input tasks. Each input task will be executed with their Execute::execute method.

The graph needs to be signaled to terminate with Graph::finishPushingData, when all data has been pushed.

While results are available Graph::getBlockingResult will return a shared_ptr with a value. The call is blocking, so the thread handling the graph will wait to get the result. The final value from Graph::getBlockingResult is nullptr, which is an indicator that the graph has terminated.

Before deletion, Graph::waitForTermination needs to be called to wait for inside threads to terminate.

Also, a graph visualization is available through the call to Graph::createDotFile.

For computation with an accelerator a graph can be bound to a device with Graph::deviceId, in this case all inside nodes will be bound to this device. If the computation is distributed through multiple accelerators, the graph can be copied for each accelerator, and set to a specific device with an AbstractExecutionPipeline.

A graph can be embedded into another graph as a node. To help sharing a specialized graph, the specialized graph can derive from Graph and be used as-is. Once linked into another graph, the inner graph cannot be manipulated (modified, such as adding edges).

Template Parameters
GraphOutputGraph Output Type
GraphInputsGraph Input types

Definition at line 85 of file graph.h.

Constructor & Destructor Documentation

◆ Graph() [1/2]

template<class GraphOutput, class ... GraphInputs>
hh::Graph< GraphOutput, GraphInputs >::Graph ( std::string_view const &  name)
inlineexplicit

Graph constructor with a custom name.

Parameters
nameGraph's name

Definition at line 104 of file graph.h.

◆ Graph() [2/2]

template<class GraphOutput, class ... GraphInputs>
hh::Graph< GraphOutput, GraphInputs >::Graph ( std::string_view const &  name,
std::unique_ptr< AbstractScheduler scheduler 
)
inlineexplicit

Graph constructor with a custom name and a custom scheduler.

A variation of tutorial 1:

Graph<MatrixBlockData<MatrixType, 'c', Ord>, TripletMatrixBlockData<MatrixType, Ord>>
graphHadamard("Tutorial 1 : Hadamard Product", std::make_unique<DefaultScheduler>());
// or
std::unique_ptr<DefaultScheduler> scheduler = std::make_unique<DefaultScheduler>();
Graph<MatrixBlockData<MatrixType, 'c', Ord>, TripletMatrixBlockData<MatrixType, Ord>>
graphHadamard("Tutorial 1 : Hadamard Product", std::move(scheduler));
Attention
The scheduler can not be a nullptr
Parameters
nameGraph's name
schedulerCustom scheduler

Definition at line 124 of file graph.h.

Member Function Documentation

◆ addEdge()

template<class GraphOutput, class ... GraphInputs>
template<class UserDefinedSender , class UserDefinedMultiReceiver , class Output = typename UserDefinedSender::output_t, class Inputs = typename UserDefinedMultiReceiver::inputs_t, class IsSender = typename std::enable_if_t<std::is_base_of_v<behavior::Sender<Output>, UserDefinedSender>>, class IsMultiReceivers = typename std::enable_if_t< std::is_base_of_v< typename helper::HelperMultiReceiversType<Inputs>::type, UserDefinedMultiReceiver > >>
void hh::Graph< GraphOutput, GraphInputs >::addEdge ( std::shared_ptr< UserDefinedSender >  from,
std::shared_ptr< UserDefinedMultiReceiver >  to 
)
inline

Add a directed edge from a compatible "from" node to "to" node.

Template Parameters
UserDefinedSenderSender type that should derive from Sender
UserDefinedMultiReceiverReceiver type that should derive from MultiReceivers
OutputSender output type
InputsTuple with MultiReceivers input types
IsSenderDefined if UserDefinedSender is derived from Sender
IsMultiReceiversDefined if UserDefinedMultiReceiver is derived from MultiReceivers
Parameters
fromNode that will send the data
toNode that will receiver the data

Definition at line 212 of file graph.h.

◆ core()

template<class GraphOutput, class ... GraphInputs>
std::shared_ptr<core::CoreNode> hh::Graph< GraphOutput, GraphInputs >::core ( )
inlinefinalvirtual

Graph core accessor.

Returns
Graph core

Implements hh::behavior::Node.

Definition at line 141 of file graph.h.

Here is the caller graph for this function:

◆ createDotFile()

template<class GraphOutput, class ... GraphInputs>
void hh::Graph< GraphOutput, GraphInputs >::createDotFile ( std::filesystem::path const &  dotFilePath,
ColorScheme  colorScheme = ColorScheme::NONE,
StructureOptions  structureOptions = StructureOptions::NONE,
DebugOptions  debugOption = DebugOptions::NONE 
)
inline

Create a dot file representing a snapshot of the state of the graph at the moment of the call, the graph is saved into the file dotFilePath.

Parameters
dotFilePathPath where the file is stored
colorSchemeColor scheme used to color the tasks, either to show difference in execution or in waiting time , or nothing. Blue is faster, Red slower.
structureOptionsShow how the graph is represented, with or without input queue size, with or without all task clusters
debugOptionShows tasks as pointer values and their connections between the nodes.

Definition at line 259 of file graph.h.

Here is the caller graph for this function:

◆ deviceId()

template<class GraphOutput, class ... GraphInputs>
void hh::Graph< GraphOutput, GraphInputs >::deviceId ( int  deviceId)
inline

Device Id for the graph, all inside nodes will be bound to this device Id.

Parameters
deviceIdDevice Id to set

Definition at line 149 of file graph.h.

◆ executeGraph()

template<class GraphOutput, class ... GraphInputs>
void hh::Graph< GraphOutput, GraphInputs >::executeGraph ( )
inline

Launch the graph once it has been structured.

Create the clone of inside nodes, and launches threads for each task.

Definition at line 223 of file graph.h.

◆ getBlockingResult()

template<class GraphOutput, class ... GraphInputs>
std::shared_ptr<GraphOutput> hh::Graph< GraphOutput, GraphInputs >::getBlockingResult ( )
inline

Get a data out of the graph.

  • If the graph is not terminated:
    • If an output data is available: the output data is returned,
    • If no output data is available: the call is blocking until an output data is available
  • If the graph is terminated : return nullptr
    Attention
    If finishPushingData is not called there is risk of deadlock
    Returns
    An output data or nullptr

Definition at line 246 of file graph.h.

◆ input()

template<class GraphOutput, class ... GraphInputs>
template<class UserDefinedMultiReceiver , class InputsMR = typename UserDefinedMultiReceiver::inputs_t, class InputsG = typename behavior::MultiReceivers<GraphInputs...>::inputs_t, class isMultiReceiver = typename std::enable_if_t< std::is_base_of_v<typename helper::HelperMultiReceiversType<InputsMR>::type, UserDefinedMultiReceiver> >, class isInputCompatible = typename std::enable_if_t<traits::is_included_v<InputsMR, InputsG>>>
void hh::Graph< GraphOutput, GraphInputs >::input ( std::shared_ptr< UserDefinedMultiReceiver >  input)
inline

Set a node as input for the graph.

Template Parameters
UserDefinedMultiReceiverNode's type
InputsMRTuple of UserDefinedMultiReceiver's input type
InputsGTuple of Graph's input type
isMultiReceiverDefined if UserDefinedMultiReceiver is derived from MultiReceiver
isInputCompatibleDefined if UserDefinedMultiReceiver and Graph (this) are compatible
Parameters
inputNode to set as Graph's input

Definition at line 166 of file graph.h.

Here is the caller graph for this function:

◆ name()

template<class GraphOutput, class ... GraphInputs>
std::string_view const& hh::Graph< GraphOutput, GraphInputs >::name ( )
inline

Graph name accessor.

Returns
Graph name

Definition at line 145 of file graph.h.

Here is the caller graph for this function:

◆ output()

template<class GraphOutput, class ... GraphInputs>
template<class UserDefinedSender , class IsSender = typename std::enable_if_t< std::is_base_of_v< behavior::Sender<GraphOutput>, UserDefinedSender > >>
void hh::Graph< GraphOutput, GraphInputs >::output ( std::shared_ptr< UserDefinedSender >  output)
inline

Set a node as output for the graph.

Template Parameters
UserDefinedSenderNode's type
IsSenderDefined if UserDefinedSender is derived from sender and has the same output as Graph's output
Parameters
outputNode to set as Graph's output

Definition at line 186 of file graph.h.

◆ pushData()

template<class GraphOutput, class ... GraphInputs>
template<class Input , class = typename std::enable_if_t<traits::Contains<Input, GraphInputs...>::value>>
void hh::Graph< GraphOutput, GraphInputs >::pushData ( std::shared_ptr< Input >  data)
inline

Push data into the graph.

data is sent to all nodes that have been added with Graph::input

Template Parameters
InputData input type
Parameters
dataData to push into the graph

Definition at line 233 of file graph.h.


The documentation for this class was generated from the following file: