aboutsummaryrefslogtreecommitdiffstats
path: root/host
diff options
context:
space:
mode:
authorMartin Braun <martin.braun@ettus.com>2019-06-03 23:28:19 -0700
committerMartin Braun <martin.braun@ettus.com>2019-11-26 11:49:24 -0800
commit01f08d3fa5ae0cd8a2fc3c6e1112117a1f7f9768 (patch)
tree7fb49f7e0ab5329c29c292df001cd61390eae5f0 /host
parent802afa6eecee368ec8e28044ce22fd39c0f93ae8 (diff)
downloaduhd-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.hpp28
-rw-r--r--host/lib/include/uhdlib/rfnoc/graph.hpp7
-rw-r--r--host/lib/include/uhdlib/rfnoc/node_accessor.hpp11
-rw-r--r--host/lib/rfnoc/graph.cpp36
-rw-r--r--host/lib/rfnoc/node.cpp17
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