Skip to content

Commit 2167992

Browse files
Johannes Schmitztrondeau
Johannes Schmitz
authored andcommitted
runtime: adds ability to output flowgraph in dot format (resolves issue 245).
1 parent 0f18a39 commit 2167992

File tree

8 files changed

+79
-19
lines changed

8 files changed

+79
-19
lines changed

gnuradio-runtime/include/gnuradio/flowgraph.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ namespace gr {
165165

166166
// Connect two msg endpoints
167167
void connect(const msg_endpoint &src, const msg_endpoint &dst);
168-
168+
169169
// Disconnect two msg endpoints
170170
void disconnect(const msg_endpoint &src, const msg_endpoint &dst);
171171

@@ -177,7 +177,7 @@ namespace gr {
177177

178178
// Return vector of edges
179179
const edge_vector_t &edges() const { return d_edges; }
180-
180+
181181
// Return vector of msg edges
182182
const msg_edge_vector_t &msg_edges() const { return d_msg_edges; }
183183

@@ -265,6 +265,8 @@ namespace gr {
265265
return os;
266266
}
267267

268+
std::string dot_graph_fg (flowgraph_sptr fg);
269+
268270
} /* namespace gr */
269271

270272
#endif /* INCLUDED_GR_RUNTIME_FLOWGRAPH_H */

gnuradio-runtime/include/gnuradio/hier_block2.h

+6-1
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ namespace gr {
179179
bool has_msg_port(pmt::pmt_t which_port) {
180180
return message_port_is_hier(which_port) || basic_block::has_msg_port(which_port);
181181
}
182-
182+
183183
bool message_port_is_hier(pmt::pmt_t port_id) {
184184
return message_port_is_hier_in(port_id) || message_port_is_hier_out(port_id);
185185
}
@@ -235,6 +235,11 @@ namespace gr {
235235
std::vector<int> processor_affinity();
236236
};
237237

238+
/*!
239+
* \brief Return hierarchical block's flow graph represented in dot language
240+
*/
241+
GR_RUNTIME_API std::string dot_graph(hier_block2_sptr hierblock2);
242+
238243
inline hier_block2_sptr cast_to_hier_block2_sptr(basic_block_sptr block) {
239244
return boost::dynamic_pointer_cast<hier_block2, basic_block>(block);
240245
}

gnuradio-runtime/lib/flowgraph.cc

+31-2
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ namespace gr {
149149
}
150150
}
151151

152-
void
152+
void
153153
flowgraph::check_valid_port(const msg_endpoint &e)
154154
{
155155
if(FLOWGRAPH_DEBUG)
@@ -496,7 +496,7 @@ namespace gr {
496496
check_valid_port(src);
497497
check_valid_port(dst);
498498
for(msg_edge_viter_t p = d_msg_edges.begin(); p != d_msg_edges.end(); p++) {
499-
if(p->src() == src && p->dst() == dst){
499+
if(p->src() == src && p->dst() == dst){
500500
throw std::runtime_error("connect called on already connected edge!");
501501
}
502502
}
@@ -517,4 +517,33 @@ namespace gr {
517517
throw std::runtime_error("disconnect called on non-connected edge!");
518518
}
519519

520+
std::string
521+
dot_graph_fg(flowgraph_sptr fg)
522+
{
523+
basic_block_vector_t blocks = fg->calc_used_blocks();
524+
edge_vector_t edges = fg->edges();
525+
526+
std::stringstream out;
527+
528+
out << "digraph flowgraph {" << std::endl;
529+
530+
// Define nodes and set labels
531+
for(basic_block_viter_t block = blocks.begin(); block != blocks.end(); ++block) {
532+
out << (*block)->unique_id()
533+
<< " [ label=\"" << (*block)->name() << "\" ]"
534+
<< std::endl;
535+
}
536+
537+
// Define edges
538+
for(edge_viter_t edge = edges.begin(); edge != edges.end(); ++edge) {
539+
out << edge->src().block()->unique_id()
540+
<< " -> "
541+
<< edge->dst().block()->unique_id() << std::endl;
542+
}
543+
544+
out << "}" << std::endl;
545+
546+
return out.str();
547+
}
548+
520549
} /* namespace gr */

gnuradio-runtime/lib/hier_block2.cc

+7
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626

2727
#include <gnuradio/hier_block2.h>
2828
#include <gnuradio/io_signature.h>
29+
#include <gnuradio/flowgraph.h>
2930
#include "hier_block2_detail.h"
3031
#include <iostream>
3132

@@ -175,4 +176,10 @@ namespace gr {
175176
return d_detail->processor_affinity();
176177
}
177178

179+
std::string
180+
dot_graph(hier_block2_sptr hierblock2)
181+
{
182+
return dot_graph_fg(hierblock2->flatten());
183+
}
184+
178185
} /* namespace gr */

gnuradio-runtime/python/gnuradio/gr/hier_block2.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
# Boston, MA 02110-1301, USA.
2020
#
2121

22-
from runtime_swig import hier_block2_swig
22+
from runtime_swig import hier_block2_swig, dot_graph
2323
import pmt
2424

2525
#
@@ -126,3 +126,7 @@ def message_port_register_hier_in(self, portname):
126126
def message_port_register_hier_out(self, portname):
127127
self.primitive_message_port_register_hier_out(pmt.intern(portname));
128128

129+
def dot_graph(self):
130+
'''Return graph representation in dot language'''
131+
return dot_graph(self._hb)
132+

gnuradio-runtime/python/gnuradio/gr/top_block.py

+16-12
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@
2121

2222
from runtime_swig import top_block_swig, \
2323
top_block_wait_unlocked, top_block_run_unlocked, \
24-
top_block_start_unlocked, top_block_stop_unlocked
24+
top_block_start_unlocked, top_block_stop_unlocked, \
25+
dot_graph_tb
2526

2627
#import gnuradio.gr.gr_threading as _threading
2728
import gr_threading as _threading
@@ -92,18 +93,18 @@ class top_block(object):
9293
python subclassing.
9394
"""
9495
def __init__(self, name="top_block"):
95-
self._tb = top_block_swig(name)
96+
self._tb = top_block_swig(name)
9697

9798
def __getattr__(self, name):
9899
if not hasattr(self, "_tb"):
99100
raise RuntimeError("top_block: invalid state--did you forget to call gr.top_block.__init__ in a derived class?")
100-
return getattr(self._tb, name)
101+
return getattr(self._tb, name)
101102

102103
def start(self, max_noutput_items=10000000):
103-
top_block_start_unlocked(self._tb, max_noutput_items)
104+
top_block_start_unlocked(self._tb, max_noutput_items)
104105

105106
def stop(self):
106-
top_block_stop_unlocked(self._tb)
107+
top_block_stop_unlocked(self._tb)
107108

108109
def run(self, max_noutput_items=10000000):
109110
self.start(max_noutput_items)
@@ -122,16 +123,16 @@ def connect(self, *points):
122123
'''
123124
if len (points) < 1:
124125
raise ValueError, ("connect requires at least one endpoint; %d provided." % (len (points),))
125-
else:
126-
if len(points) == 1:
127-
self._tb.primitive_connect(points[0].to_basic_block())
128-
else:
129-
for i in range (1, len (points)):
130-
self._connect(points[i-1], points[i])
126+
else:
127+
if len(points) == 1:
128+
self._tb.primitive_connect(points[0].to_basic_block())
129+
else:
130+
for i in range (1, len (points)):
131+
self._connect(points[i-1], points[i])
131132

132133
def msg_connect(self, src, srcport, dst, dstport):
133134
self.primitive_msg_connect(src.to_basic_block(), srcport, dst.to_basic_block(), dstport);
134-
135+
135136
def msg_disconnect(self, src, srcport, dst, dstport):
136137
self.primitive_msg_disconnect(src.to_basic_block(), srcport, dst.to_basic_block(), dstport);
137138

@@ -169,3 +170,6 @@ def _disconnect(self, src, dst):
169170
self._tb.primitive_disconnect(src_block.to_basic_block(), src_port,
170171
dst_block.to_basic_block(), dst_port)
171172

173+
def dot_graph(self):
174+
'''Return graph representation in dot language'''
175+
return dot_graph_tb(self._tb)

gnuradio-runtime/swig/hier_block2.i

+2
Original file line numberDiff line numberDiff line change
@@ -93,4 +93,6 @@ namespace gr {
9393

9494
gr::hier_block2_sptr to_hier_block2(); // Needed for Python type coercion
9595
};
96+
97+
std::string dot_graph(hier_block2_sptr hierblock2);
9698
}

gnuradio-runtime/swig/top_block.i

+8-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ namespace gr {
5353
gr::top_block_sptr to_top_block(); // Needed for Python type coercion
5454
};
5555
}
56-
56+
5757
#ifdef SWIGPYTHON
5858

5959
%inline %{
@@ -88,6 +88,13 @@ void top_block_stop_unlocked(gr::top_block_sptr r) throw (std::runtime_error)
8888
r->stop();
8989
)
9090
}
91+
92+
std::string
93+
dot_graph_tb(gr::top_block_sptr r)
94+
{
95+
return dot_graph(r);
96+
}
97+
9198
%}
9299

93100
#endif

0 commit comments

Comments
 (0)