diff options
author | Martin Braun <martin.braun@ettus.com> | 2019-06-03 23:28:19 -0700 |
---|---|---|
committer | Martin Braun <martin.braun@ettus.com> | 2019-11-26 11:49:24 -0800 |
commit | 01f08d3fa5ae0cd8a2fc3c6e1112117a1f7f9768 (patch) | |
tree | 7fb49f7e0ab5329c29c292df001cd61390eae5f0 /host | |
parent | 802afa6eecee368ec8e28044ce22fd39c0f93ae8 (diff) | |
download | uhd-01f08d3fa5ae0cd8a2fc3c6e1112117a1f7f9768.tar.gz uhd-01f08d3fa5ae0cd8a2fc3c6e1112117a1f7f9768.tar.bz2 uhd-01f08d3fa5ae0cd8a2fc3c6e1112117a1f7f9768.zip |
rfnoc: Add check_topology() API to nodes
This API lets blocks decide if their current topology is OK for them,
and make decisions based on their topology.
Diffstat (limited to 'host')
-rw-r--r-- | host/include/uhd/rfnoc/node.hpp | 28 | ||||
-rw-r--r-- | host/lib/include/uhdlib/rfnoc/graph.hpp | 7 | ||||
-rw-r--r-- | host/lib/include/uhdlib/rfnoc/node_accessor.hpp | 11 | ||||
-rw-r--r-- | host/lib/rfnoc/graph.cpp | 36 | ||||
-rw-r--r-- | host/lib/rfnoc/node.cpp | 17 |
5 files changed, 99 insertions, 0 deletions
diff --git a/host/include/uhd/rfnoc/node.hpp b/host/include/uhd/rfnoc/node.hpp index 09ae76e9a..f9a1272e1 100644 --- a/host/include/uhd/rfnoc/node.hpp +++ b/host/include/uhd/rfnoc/node.hpp @@ -324,7 +324,35 @@ protected: */ void post_action(const res_source_info& edge_info, action_info::sptr action); + /************************************************************************** + * Graph Interaction + *************************************************************************/ + /*! Check if the current connections "work" for this block + * + * The default implementation simply checks if all connections are within + * the valid range, i.e., no \p connected_inputs element is larger than + * get_num_input_ports(), etc. This can be overridden, but keep in mind that + * blocks need some kind of tolerance here, because blocks may simply not + * be part of the current application, and left unconnected. This check is + * more meant for blocks that simply don't work of only one of two ports is + * connected, or situations like that. + * + * Note that this method is always called when a graph is committed, i.e., + * no connections will be added or removed without calling this method + * again, unless the user bypasses calling uhd::rfnoc_graph::commit(). This + * method can therefore be used to make decisions about the behaviour of + * the block. + * + * \param connected_inputs A list of input ports that are connected + * \param connected_outputs A list of output ports that are connected + * \returns true if the block can deal with this configuration + */ + virtual bool check_topology(const std::vector<size_t>& connected_inputs, + const std::vector<size_t>& connected_outputs); + /************************************************************************** + * Attributes + *************************************************************************/ //! A dirtifyer object, useful for properties that always need updating. static dirtifier_t ALWAYS_DIRTY; diff --git a/host/lib/include/uhdlib/rfnoc/graph.hpp b/host/lib/include/uhdlib/rfnoc/graph.hpp index 49dc62551..4b08b5842 100644 --- a/host/lib/include/uhdlib/rfnoc/graph.hpp +++ b/host/lib/include/uhdlib/rfnoc/graph.hpp @@ -236,6 +236,13 @@ private: */ bool _assert_edge_props_consistent(rfnoc_graph_t::edge_descriptor edge); + /*! Query all blocks on their topology + * + * \throws uhd::runtime_error if any of the blocks doesn't like its + * configuration + */ + void _check_topology(); + /************************************************************************** * Attributes *************************************************************************/ diff --git a/host/lib/include/uhdlib/rfnoc/node_accessor.hpp b/host/lib/include/uhdlib/rfnoc/node_accessor.hpp index 827c87dd2..3351c5531 100644 --- a/host/lib/include/uhdlib/rfnoc/node_accessor.hpp +++ b/host/lib/include/uhdlib/rfnoc/node_accessor.hpp @@ -97,6 +97,17 @@ public: { node->receive_action(port_info, action); } + + /*! Check topology for this block + * + * See node_t::check_topology() for details + */ + bool check_topology(node_t* node, + const std::vector<size_t>& connected_inputs, + const std::vector<size_t>& connected_outputs) + { + return node->check_topology(connected_inputs, connected_outputs); + } }; diff --git a/host/lib/rfnoc/graph.cpp b/host/lib/rfnoc/graph.cpp index f687e8984..cbb7ab140 100644 --- a/host/lib/rfnoc/graph.cpp +++ b/host/lib/rfnoc/graph.cpp @@ -177,6 +177,7 @@ void graph_t::commit() { if (_release_count) { _release_count--; + _check_topology(); } UHD_LOG_TRACE(LOG_ID, "graph::commit() => " << _release_count.load()); resolve_all_properties(); @@ -524,6 +525,41 @@ bool graph_t::_assert_edge_props_consistent(rfnoc_graph_t::edge_descriptor edge) return props_match; } +void graph_t::_check_topology() +{ + node_accessor_t node_accessor{}; + bool topo_ok = true; + auto v_iterators = boost::vertices(_graph); + for (auto it = v_iterators.first; it != v_iterators.second; ++it) { + node_ref_t node = boost::get(vertex_property_t(), _graph, *it); + std::vector<size_t> connected_inputs; + std::vector<size_t> connected_outputs; + auto ie_iters = boost::in_edges(*it, _graph); + for (auto it = ie_iters.first; it != ie_iters.second; ++it) { + graph_edge_t edge_info = boost::get(edge_property_t(), _graph, *it); + connected_inputs.push_back(edge_info.dst_port); + } + auto oe_iters = boost::out_edges(*it, _graph); + for (auto it = oe_iters.first; it != oe_iters.second; ++it) { + graph_edge_t edge_info = boost::get(edge_property_t(), _graph, *it); + connected_outputs.push_back(edge_info.src_port); + } + + if (!node_accessor.check_topology(node, connected_inputs, connected_outputs)) { + UHD_LOG_ERROR(LOG_ID, + "Node " << node->get_unique_id() + << "cannot handle its current topology! (" + << connected_inputs.size() << "inputs, " + << connected_outputs.size() << " outputs)"); + topo_ok = false; + } + } + + if (!topo_ok) { + throw uhd::runtime_error("Graph topology is not valid!"); + } +} + std::pair<graph_t::node_ref_t, graph_t::graph_edge_t> graph_t::_find_neighbour( rfnoc_graph_t::vertex_descriptor origin, res_source_info port_info) { diff --git a/host/lib/rfnoc/node.cpp b/host/lib/rfnoc/node.cpp index 33649b23f..7eff22eab 100644 --- a/host/lib/rfnoc/node.cpp +++ b/host/lib/rfnoc/node.cpp @@ -154,6 +154,23 @@ void node_t::post_action( _post_action_cb(edge_info, action); } +bool node_t::check_topology(const std::vector<size_t>& connected_inputs, + const std::vector<size_t>& connected_outputs) +{ + for (size_t port : connected_inputs) { + if (port >= get_num_input_ports()) { + return false; + } + } + for (size_t port : connected_outputs) { + if (port >= get_num_output_ports()) { + return false; + } + } + + return true; +} + /*** Private methods *********************************************************/ property_base_t* node_t::_find_property( res_source_info src_info, const std::string& id) const |