5 #include <boost/range/adaptor/reversed.hpp>
7 #include <boost/graph/topological_sort.hpp>
30 boost::graph_traits<Graph>::in_edge_iterator
e, e_end;
31 boost::tie(
e, e_end) = boost::in_edges(baseNode, graph);
32 for( ;
e!=e_end; ++
e ) {
56 boost::graph_traits<Graph>::out_edge_iterator
e, e_end;
57 boost::tie(
e, e_end) = boost::out_edges(baseNode, graph);
58 for( ;
e!=e_end; ++
e ) {
76 std::vector<std::shared_ptr<ConstantPiece> >
const& constantPieces,
77 std::vector<std::string>
const& inputNames,
78 std::map<unsigned int, std::string>
const& inTypes,
79 std::shared_ptr<WorkPiece> outputPiece) :
WorkPiece(inTypes, constantPieces.size(), outputPiece->OutputTypes(), outputPiece->numOutputs), wgraph(wgraph), outputID(outputPiece->ID()), constantPieces(constantPieces) {
82 boost::topological_sort(
wgraph->graph, std::front_inserter(
runOrder));
93 for(
unsigned int i=0; i<
numInputs; ++i ) {
95 boost::graph_traits<Graph>::vertex_iterator
v, v_end;
96 boost::tie(
v, v_end) = vertices(
wgraph->graph);
103 filtered_graphs[i] = std::make_shared<boost::filtered_graph<Graph, DependentEdgePredicate, DependentPredicate> >(
wgraph->graph, eFilt, nFilt);
122 for(
int i=0; i<
outputs.size(); ++i) {
307 for(
unsigned int i=0; i<inputs.size(); ++i ) {
312 std::map<unsigned int, std::vector<std::pair<unsigned int, unsigned int> > >
WorkGraphPiece::InputNodes(boost::graph_traits<Graph>::vertex_descriptor
const& node)
const {
314 std::map<unsigned int, std::vector<std::pair<unsigned int, unsigned int> > > inMap;
317 boost::graph_traits<Graph>::in_edge_iterator
e, e_end;
318 for( tie(
e, e_end)=boost::in_edges(node,
wgraph->graph);
e!=e_end; ++
e ) {
320 const unsigned int id =
wgraph->GetPiece(boost::source(*
e,
wgraph->graph))->ID();
321 const unsigned int inNum =
wgraph->graph[*
e]->inputDim;
322 const unsigned int outNum =
wgraph->graph[*
e]->outputDim;
325 auto it = inMap.find(
id);
327 if( it==inMap.end() ) {
329 inMap[
id] = std::vector<std::pair<unsigned int, unsigned int> >(1, std::pair<unsigned int, unsigned int>(inNum, outNum));
332 inMap[
id].push_back(std::pair<unsigned int, unsigned int>(inNum, outNum));
349 std::vector<boost::any>
const& output =
wgraph->GetPiece(it)->Evaluate(ins);
356 const int numIns =
wgraph->GetPiece(node)->numInputs;
359 const std::map<unsigned int, std::vector<std::pair<unsigned int, unsigned int> > >& inMap =
InputNodes(node);
361 boost::any empty = boost::none;
365 for(
auto edge : inMap ) {
367 for(
auto in_out : edge.second ) {
369 ins[in_out.first] =
valMap.at(edge.first)[in_out.second];
376 std::vector<std::tuple<unsigned int, unsigned int, unsigned int> >
WorkGraphPiece::RequiredOutputs(boost::graph_traits<FilteredGraph>::vertex_descriptor
const& node,
unsigned int const wrtIn,
unsigned int const wrtOut)
const {
378 const unsigned int nodeID =
filtered_graphs[wrtIn]->operator[](node)->piece->ID();
381 std::vector<std::tuple<unsigned int, unsigned int, unsigned int> > requiredOuts;
385 requiredOuts.push_back(std::tuple<unsigned int, unsigned int, unsigned int>(nodeID, wrtOut, wrtIn));
391 boost::graph_traits<FilteredGraph>::out_edge_iterator eout, eout_end;
392 for( tie(eout, eout_end)=boost::out_edges(node, *
filtered_graphs[wrtIn]); eout!=eout_end; ++eout ) {
395 const unsigned int outNum =
filtered_graphs[wrtIn]->operator[](*eout)->outputDim;
396 const unsigned int inNum =
filtered_graphs[wrtIn]->operator[](*eout)->inputDim;
399 auto it = std::find(requiredOuts.begin(), requiredOuts.end(), std::tuple<unsigned int, unsigned int, unsigned int>(
id, outNum, inNum));
400 if( it==requiredOuts.end() ) {
401 requiredOuts.push_back(std::tuple<unsigned int, unsigned int, unsigned int>(
id, outNum, inNum));
408 std::vector<std::tuple<unsigned int, unsigned int, unsigned int> >
WorkGraphPiece::RequiredInputs(boost::graph_traits<FilteredGraph>::vertex_descriptor
const& node,
unsigned int const wrtIn)
const {
410 const int numIns =
filtered_graphs[wrtIn]->operator[](node)->piece->numInputs;
412 std::vector<std::tuple<unsigned int, unsigned int, unsigned int> > requiredIns;
413 requiredIns.reserve(numIns);
416 boost::graph_traits<FilteredGraph>::in_edge_iterator ein, ein_end;
417 for( tie(ein, ein_end)=boost::in_edges(node, *
filtered_graphs[wrtIn]); ein!=ein_end; ++ein ) {
420 const unsigned int outNum =
filtered_graphs[wrtIn]->operator[](*ein)->outputDim;
421 const unsigned int inNum =
filtered_graphs[wrtIn]->operator[](*ein)->inputDim;
424 requiredIns.push_back(std::tuple<unsigned int, unsigned int, unsigned int>(
id, outNum, inNum));
Determine if the source of an edge is downstream of an input.
bool operator()(const boost::graph_traits< Graph >::edge_descriptor &edge) const
DependentPredicate nodePred
The nodes that are downstream of the input.
DependentEdgePredicate()
Required default constructor.
const Graph * graph
The graph holding all the nodes.
This class keeps track of which nodes are downstream of a specified input.
bool operator()(const boost::graph_traits< Graph >::vertex_descriptor &node) const
DependentPredicate()
Required default constructor.
void DownstreamNodes(const boost::graph_traits< Graph >::vertex_descriptor &baseNode, Graph const &graph)
std::vector< boost::graph_traits< Graph >::vertex_descriptor > doesDepend
A vector of all the nodes downstream of the input node.
bool operator()(const boost::graph_traits< Graph >::vertex_descriptor &node) const
std::vector< boost::graph_traits< Graph >::vertex_descriptor > doesDepend
A vector of all the nodes downstream of the input node.
void UpstreamNodes(const boost::graph_traits< Graph >::vertex_descriptor &baseNode, Graph const &graph)
std::vector< std::tuple< unsigned int, unsigned int, unsigned int > > RequiredOutputs(boost::graph_traits< FilteredGraph >::vertex_descriptor const &node, unsigned int const wrtIn, unsigned int wrtOut) const
Get the required outputs for a node in one of the filtered graphs.
std::map< unsigned int, std::vector< std::pair< unsigned int, unsigned int > > > InputNodes(boost::graph_traits< Graph >::vertex_descriptor const &node) const
Get a the input nodes for a node.
void SetInputs(ref_vector< boost::any > const &inputs)
Set the inputs.
virtual void EvaluateImpl(ref_vector< boost::any > const &inputs) override
Evaluate each muq::Modeling::WorkPiece in the graph.
void OutputMap()
Fill the map from each node's muq::Modeling::WorkPiece::ID to its outputs.
virtual ~WorkGraphPiece()
Default destructor.
unsigned int outputID
The ID of the WorkPiece corresponding to the output node.
std::vector< std::shared_ptr< FilteredGraph > > filtered_graphs
std::vector< std::tuple< unsigned int, unsigned int, unsigned int > > RequiredInputs(boost::graph_traits< FilteredGraph >::vertex_descriptor const &node, unsigned int const wrtIn) const
Get the required inputs for a node in one of the filtered graphs.
std::unordered_map< unsigned int, ref_vector< boost::any > > valMap
A the map from each node's muq::Modeling::WorkPiece::ID to its outputs.
std::shared_ptr< WorkGraph > wgraph
The WorkGraph associated with this WorkGraphPiece.
std::deque< boost::graph_traits< Graph >::vertex_descriptor > runOrder
Run order computed during construction (input->output order)
std::vector< std::shared_ptr< ConstantPiece > > constantPieces
The muq::Modeling::ConstantPiece's that store the inputs.
std::vector< std::deque< boost::graph_traits< Graph >::vertex_descriptor > > derivRunOrders
Base class for MUQ's modelling envronment.
const unsigned int id
A unique ID number assigned by the constructor.
static ref_vector< const boost::any > ToRefVector(std::vector< boost::any > const &anyVec)
Create vector of references from a vector of boost::any's.
unsigned int ID() const
Get the unique ID number.
friend class WorkGraphPiece
@ Inputs
The constructor fixes the input number and possibly the types.
std::vector< boost::any > outputs
The outputs.
int numInputs
The number of inputs.
std::vector< std::reference_wrapper< const T > > ref_vector
A vector of references to something ...
boost::adjacency_list< boost::vecS, boost::vecS, boost::bidirectionalS, std::shared_ptr< WorkGraphNode >, std::shared_ptr< WorkGraphEdge > > Graph
Define a directed graph type.
A helper struct that determines if a node in the graph has a given name.