NRP Core  1.4.1
computational_graph_manager.h
Go to the documentation of this file.
1 /* * NRP Core - Backend infrastructure to synchronize simulations
2  *
3  * Copyright 2020-2023 NRP Team
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  * This project has received funding from the European Union’s Horizon 2020
18  * Framework Programme for Research and Innovation under the Specific Grant
19  * Agreement No. 945539 (Human Brain Project SGA3).
20  */
21 
22 #ifndef COMPUTATION_GRAPH_MANAGER_H
23 #define COMPUTATION_GRAPH_MANAGER_H
24 
25 
26 #include <boost/python.hpp>
27 #include <nlohmann/json.hpp>
28 
31 
34 
37 
46 {
47 public:
48 
50 
51  // Delete move and copy operators. This ensures this class is a singleton
54 
57 
62 
67 
75  void registerNode(std::shared_ptr<ComputationalNode>& obj)
76  {
77  // Registers node
78  if(!_nodes.count(obj->id()))
79  _nodes.emplace(obj->id(), obj);
80  // There is a node with the same name but different type
81  else if(obj->type() != _nodes[obj->id()]->type() )
82  throw NRPException::logCreate("Duplicated node name: \"" + obj->id() + "\" in nodes with type \"" +
83  obj->typeStr() + " and \"" +
84  _nodes[obj->id()]->typeStr() + "\". This is not allowed.");
85  // There is a node with the same name and type is Functional
86  else if(obj->type() == ComputationalNode::Functional)
87  throw NRPException::logCreate("Duplicated Node Name: Attempt to register Functional Node with name \"" + obj->id() + "\". But a node with that name already exists.");
88  else
89  obj = _nodes[obj->id()];
90  }
91 
95  ComputationalNode* getNode(const std::string& id)
96  {
97  if(_nodes.count(id))
98  return _nodes.at(id).get();
99  else
100  return nullptr;
101  }
102 
106  template<class T_IN, class T_OUT>
108  {
109  if(!source || !target)
110  throw NRPException::logCreate("Attempt to register edge in computational graph from nullptrs");
111 
112  if(!_nodes.count(source->parent()->id()) || !_nodes.count(target->parent()->id()))
113  throw NRPException::logCreate("Attempt to register edge between nodes " + source->parent()->id() + " and " +
114  target->parent()->id() + ", but they are not registered in the graph");
115 
116  // TODO: if just ComputationalGraphManager is allowed to call 'subscribeTo' it would be ensured that all
117  // port connections are reflected in the graph
118  target->subscribeTo(source);
119 
120  _graph.insert_edge(source->parent(), target->parent());
121  }
122 
126  void compute()
127  { _graph.compute(); }
128 
132  void configure()
133  {
134  _graph.configure();
135 
136  // Warn about disconnected nodes in the graph
137  for(const auto& node : _nodes)
138  if(!node.second->isVisited())
139  NRPLogger::warn("Graph node \"" + node.second->id() + "\" is disconnected. It will not be executed.");
140  }
141 
146  {
147  for(const auto& node : _nodes)
148  node.second->graphLoadedCB();
149  }
150 
154  void clear()
155  {
156  _graph.clear();
157  _nodes.clear();
158  }
159 
161  { _graph.setExecMode(mode); }
162 
164  { return _graph.getExecMode(); }
165 
166 private:
167 
168  ComputationalGraphManager() = default;
169  static std::unique_ptr<ComputationalGraphManager> _instance;
170 
171  ComputationalGraph _graph;
172  std::map<std::string, std::shared_ptr<ComputationalNode> > _nodes;
173 };
174 
175 
176 #endif //COMPUTATION_GRAPH_MANAGER_H
ComputationalGraphManager::registerEdge
void registerEdge(OutputPort< T_IN > *source, InputPort< T_IN, T_OUT > *target)
Connects an InputPort to an Output port and registers an edge in the graph between their parent nodes...
Definition: computational_graph_manager.h:107
NRPLogger::warn
static void warn(const FormatString &fmt, const Args &...args)
NRP logging function with message formatting for warning level.
Definition: nrp_logger.h:149
ComputationalGraphManager::configure
void configure()
Configure ComputationalGraph.
Definition: computational_graph_manager.h:132
ComputationalGraph::clear
void clear()
Clear graph.
Definition: computational_graph.h:86
computational_graph.h
ComputationalGraph::insert_edge
void insert_edge(const vertex &a, const vertex &b)
Insert edge.
Definition: computational_graph.h:67
ComputationalGraph::getExecMode
ExecMode getExecMode()
Definition: computational_graph.h:206
Port::parent
ComputationalNode * parent() const
Returns the port parent node.
Definition: port.h:53
ComputationalGraph::compute
void compute()
Executes all nodes in the graph in order.
Definition: computational_graph.h:149
ComputationalGraphManager::compute
void compute()
Executes ComputationalGraph.
Definition: computational_graph_manager.h:126
python_error_handler.h
ComputationalGraph::setExecMode
void setExecMode(ExecMode mode)
Definition: computational_graph.h:198
ComputationalGraphManager::resetInstance
static ComputationalGraphManager & resetInstance()
Reset singleton instance.
Definition: computational_graph_manager.cpp:36
nrp_exceptions.h
ComputationalGraphManager::registerNode
void registerNode(std::shared_ptr< ComputationalNode > &obj)
Register a node in the graph.
Definition: computational_graph_manager.h:75
ComputationalGraphManager::clear
void clear()
Resets ComputationalGraphManager.
Definition: computational_graph_manager.h:154
ComputationalGraphManager::getExecMode
ComputationalGraph::ExecMode getExecMode()
Definition: computational_graph_manager.h:163
ComputationalNode::id
const std::string & id() const
Returns the node 'id'.
Definition: computational_node.h:57
ComputationalGraphManager::operator=
ComputationalGraphManager & operator=(const ComputationalGraphManager &)=delete
ComputationalGraphManager::getInstance
static ComputationalGraphManager & getInstance()
Get singleton instance of ComputationalGraphManager.
Definition: computational_graph_manager.cpp:31
computational_node.h
ComputationalGraphManager::getNode
ComputationalNode * getNode(const std::string &id)
Retrieve a node from the graph as a pointer.
Definition: computational_graph_manager.h:95
ComputationalGraphManager::~ComputationalGraphManager
virtual ~ComputationalGraphManager()
Definition: computational_graph_manager.cpp:26
ComputationalGraph::ExecMode
ExecMode
Definition: computational_graph.h:62
output_port.h
NRPException::logCreate
static EXCEPTION logCreate(LOG_EXCEPTION_T &exception, const std::string &msg, NRPLogger::spdlog_out_fcn_t spdlogCall=NRPLogger::critical)
Definition: nrp_exceptions.h:73
ComputationalGraphManager::setExecMode
void setExecMode(ComputationalGraph::ExecMode mode)
Definition: computational_graph_manager.h:160
OutputPort
Implementation of an output port in the computation graph.
Definition: output_port.h:36
ComputationalNode::Functional
@ Functional
Definition: computational_node.h:38
InputPort
Implementation of an input port in the computation graph.
Definition: input_port.h:42
ComputationalGraph::configure
void configure()
Creates the graph execution structure and call 'configure' on each node.
Definition: computational_graph.h:102
ComputationalGraphManager::graphLoadComplete
void graphLoadComplete()
Function to be called externally after all nodes has been added to the graph.
Definition: computational_graph_manager.h:145
ComputationalGraph
Definition: computational_graph.h:53
ComputationalGraphManager
Singleton class managing a computational graph.
Definition: computational_graph_manager.h:45
InputPort::subscribeTo
void subscribeTo(OutputPort< T_IN > *port)
Subscribes this port to an OutputPort 'port'.
Definition: input_port.h:57
ComputationalNode
Base class implementing a node in the computational graph.
Definition: computational_node.h:31
input_port.h