GNU Radio Manual and C++ API Reference  3.10.9.1
The Free & Open Software Radio Ecosystem
flowgraph.h
Go to the documentation of this file.
1 /* -*- c++ -*- */
2 /*
3  * Copyright 2006,2007,2013 Free Software Foundation, Inc.
4  *
5  * This file is part of GNU Radio
6  *
7  * SPDX-License-Identifier: GPL-3.0-or-later
8  *
9  */
10 
11 #ifndef INCLUDED_GR_RUNTIME_FLOWGRAPH_H
12 #define INCLUDED_GR_RUNTIME_FLOWGRAPH_H
13 
14 #include <gnuradio/api.h>
15 #include <gnuradio/basic_block.h>
16 #include <gnuradio/io_signature.h>
17 
18 namespace gr {
19 
20 /*!
21  * \brief Class representing a specific input or output graph endpoint
22  * \ingroup internal
23  */
25 {
26 private:
27  basic_block_sptr d_basic_block;
28  int d_port;
29 
30 public:
31  endpoint() : d_basic_block(), d_port(0) {}
32  endpoint(basic_block_sptr block, int port)
33  {
34  d_basic_block = block;
35  d_port = port;
36  }
37  basic_block_sptr block() const { return d_basic_block; }
38  int port() const { return d_port; }
39  std::string identifier() const
40  {
41  return d_basic_block->alias() + ":" + std::to_string(d_port);
42  };
43 
44  bool operator==(const endpoint& other) const;
45 };
46 
47 inline bool endpoint::operator==(const endpoint& other) const
48 {
49  return (d_basic_block == other.d_basic_block && d_port == other.d_port);
50 }
51 
53 {
54 private:
55  basic_block_sptr d_basic_block;
56  pmt::pmt_t d_port;
57  bool d_is_hier;
58 
59 public:
60  msg_endpoint() : d_basic_block(), d_port(pmt::PMT_NIL) {}
61  msg_endpoint(basic_block_sptr block, pmt::pmt_t port, bool is_hier = false)
62  {
63  d_basic_block = block;
64  d_port = port;
65  d_is_hier = is_hier;
66  }
67  basic_block_sptr block() const { return d_basic_block; }
68  pmt::pmt_t port() const { return d_port; }
69  bool is_hier() const { return d_is_hier; }
70  void set_hier(bool h) { d_is_hier = h; }
71  std::string identifier() const
72  {
73  return d_basic_block->alias() + ":" + pmt::symbol_to_string(d_port);
74  }
75 
76  bool operator==(const msg_endpoint& other) const;
77 };
78 
79 inline bool msg_endpoint::operator==(const msg_endpoint& other) const
80 {
81  return (d_basic_block == other.d_basic_block && pmt::equal(d_port, other.d_port));
82 }
83 
84 // Hold vectors of gr::endpoint objects
85 typedef std::vector<endpoint> endpoint_vector_t;
86 typedef std::vector<endpoint>::iterator endpoint_viter_t;
87 
88 /*!
89  *\brief Class representing a connection between to graph endpoints
90  */
92 {
93 public:
94  edge() : d_src(), d_dst(){};
95  edge(const endpoint& src, const endpoint& dst) : d_src(src), d_dst(dst) {}
96  ~edge();
97 
98  const endpoint& src() const { return d_src; }
99  const endpoint& dst() const { return d_dst; }
100  std::string identifier() const
101  {
102  return d_src.identifier() + "->" + d_dst.identifier();
103  }
104 
105 private:
106  endpoint d_src;
107  endpoint d_dst;
108 };
109 
110 // Hold vectors of gr::edge objects
111 typedef std::vector<edge> edge_vector_t;
112 typedef std::vector<edge>::iterator edge_viter_t;
113 
114 
115 /*!
116  *\brief Class representing a msg connection between to graph msg endpoints
117  */
119 {
120 public:
121  msg_edge() : d_src(), d_dst(){};
122  msg_edge(const msg_endpoint& src, const msg_endpoint& dst) : d_src(src), d_dst(dst) {}
124 
125  const msg_endpoint& src() const { return d_src; }
126  const msg_endpoint& dst() const { return d_dst; }
127  std::string identifier() const
128  {
129  return d_src.identifier() + "->" + d_dst.identifier();
130  }
131 
132 private:
133  msg_endpoint d_src;
134  msg_endpoint d_dst;
135 };
136 
137 // Hold vectors of gr::msg_edge objects
138 typedef std::vector<msg_edge> msg_edge_vector_t;
139 typedef std::vector<msg_edge>::iterator msg_edge_viter_t;
140 
141 // Create a shared pointer to a heap allocated flowgraph
142 // (types defined in runtime_types.h)
144 
145 /*!
146  * \brief Class representing a directed, acyclic graph of basic blocks
147  * \ingroup internal
148  */
150 {
151 public:
152  friend GR_RUNTIME_API flowgraph_sptr make_flowgraph();
153 
154  /*!
155  * \brief Destruct an arbitrary flowgraph
156  */
157  virtual ~flowgraph();
158 
159  /*!
160  * \brief Connect two endpoints
161  * \details
162  * Checks the validity of both endpoints, and whether the
163  * destination is unused so far, then adds the edge to the internal list of
164  * edges.
165  */
166  void connect(const endpoint& src, const endpoint& dst);
167 
168  /*!
169  * \brief Disconnect two endpoints
170  */
171  void disconnect(const endpoint& src, const endpoint& dst);
172 
173  /*!
174  * \brief convenience wrapper; used to connect two endpoints
175  */
176  void connect(basic_block_sptr src_block,
177  int src_port,
178  basic_block_sptr dst_block,
179  int dst_port);
180 
181  /*!
182  * \brief convenience wrapper; used to disconnect two endpoints
183  */
184  void disconnect(basic_block_sptr src_block,
185  int src_port,
186  basic_block_sptr dst_block,
187  int dst_port);
188 
189  /*!
190  * \brief Connect two message endpoints
191  * \details
192  * Checks the validity of both endpoints, then adds the edge to the
193  * internal list of edges.
194  */
195  void connect(const msg_endpoint& src, const msg_endpoint& dst);
196 
197  /*!
198  * \brief Disconnect two message endpoints
199  */
200  void disconnect(const msg_endpoint& src, const msg_endpoint& dst);
201 
202  /*!
203  * \brief Validate flow graph
204  * \details
205  * Gathers all used blocks, checks the contiguity of all connected in- and
206  * outputs, and calls the check_topology method of each block.
207  */
208  void validate();
209 
210  /*!
211  * \brief Clear existing flowgraph
212  */
213  void clear();
214 
215  /*!
216  * \brief Get vector of edges
217  */
218  const edge_vector_t& edges() const { return d_edges; }
219 
220  /*!
221  * \brief Get vector of message edges
222  */
223  const msg_edge_vector_t& msg_edges() const { return d_msg_edges; }
224 
225  /*!
226  * \brief calculates all used blocks in a flow graph
227  * \details
228  * Iterates over all message edges and stream edges, noting both endpoints in a
229  * vector.
230  *
231  * \return a unique vector of used blocks
232  */
234 
235  /*!
236  * \brief topologically sort blocks
237  * \details
238  * Uses depth-first search to return a sorted vector of blocks
239  *
240  * \return toplogically sorted vector of blocks. All the sources come first.
241  */
243 
244  /*!
245  * \brief Calculate vector of disjoint graph partitions
246  * \return vector of disjoint vectors of topologically sorted blocks
247  */
248  std::vector<basic_block_vector_t> partition();
249 
250 protected:
256 
258  std::vector<int> calc_used_ports(basic_block_sptr block, bool check_inputs);
259  basic_block_vector_t calc_downstream_blocks(basic_block_sptr block, int port);
261  bool has_block_p(basic_block_sptr block);
262  edge calc_upstream_edge(basic_block_sptr block, int port);
263 
264 private:
265  void check_valid_port(gr::io_signature::sptr sig, int port);
266  void check_valid_port(const msg_endpoint& e);
267  void check_dst_not_used(const endpoint& dst);
268  void check_type_match(const endpoint& src, const endpoint& dst);
269  edge_vector_t calc_connections(basic_block_sptr block,
270  bool check_inputs); // false=use outputs
271  void check_contiguity(basic_block_sptr block,
272  const std::vector<int>& used_ports,
273  bool check_inputs);
274 
275  basic_block_vector_t calc_downstream_blocks(basic_block_sptr block);
276  basic_block_vector_t calc_reachable_blocks(basic_block_sptr block,
277  basic_block_vector_t& blocks);
278  void reachable_dfs_visit(basic_block_sptr block, basic_block_vector_t& blocks);
279  basic_block_vector_t calc_adjacent_blocks(basic_block_sptr block,
280  basic_block_vector_t& blocks);
281  basic_block_vector_t sort_sources_first(basic_block_vector_t& blocks);
282  bool source_p(basic_block_sptr block);
283  void topological_dfs_visit(basic_block_sptr block, basic_block_vector_t& output);
284 };
285 
286 // Convenience functions
287 inline void flowgraph::connect(basic_block_sptr src_block,
288  int src_port,
289  basic_block_sptr dst_block,
290  int dst_port)
291 {
292  connect(endpoint(src_block, src_port), endpoint(dst_block, dst_port));
293 }
294 
295 inline void flowgraph::disconnect(basic_block_sptr src_block,
296  int src_port,
297  basic_block_sptr dst_block,
298  int dst_port)
299 {
300  disconnect(endpoint(src_block, src_port), endpoint(dst_block, dst_port));
301 }
302 
303 inline std::ostream& operator<<(std::ostream& os, const endpoint endp)
304 {
305  os << endp.identifier();
306  return os;
307 }
308 
309 inline std::ostream& operator<<(std::ostream& os, const edge edge)
310 {
311  os << edge.identifier();
312  return os;
313 }
314 
315 inline std::ostream& operator<<(std::ostream& os, const msg_endpoint endp)
316 {
317  os << endp.identifier();
318  return os;
319 }
320 
321 inline std::ostream& operator<<(std::ostream& os, const msg_edge edge)
322 {
323  os << edge.identifier();
324  return os;
325 }
326 
327 std::string dot_graph_fg(flowgraph_sptr fg);
328 
329 } /* namespace gr */
330 
331 #endif /* INCLUDED_GR_RUNTIME_FLOWGRAPH_H */
The abstract base class for all 'terminal' processing blocks.
Definition: gnuradio-runtime/include/gnuradio/block.h:63
Class representing a connection between to graph endpoints.
Definition: flowgraph.h:92
const endpoint & src() const
Definition: flowgraph.h:98
const endpoint & dst() const
Definition: flowgraph.h:99
std::string identifier() const
Definition: flowgraph.h:100
edge(const endpoint &src, const endpoint &dst)
Definition: flowgraph.h:95
edge()
Definition: flowgraph.h:94
Class representing a specific input or output graph endpoint.
Definition: flowgraph.h:25
std::string identifier() const
Definition: flowgraph.h:39
endpoint(basic_block_sptr block, int port)
Definition: flowgraph.h:32
bool operator==(const endpoint &other) const
Definition: flowgraph.h:47
int port() const
Definition: flowgraph.h:38
endpoint()
Definition: flowgraph.h:31
basic_block_sptr block() const
Definition: flowgraph.h:37
Class representing a directed, acyclic graph of basic blocks.
Definition: flowgraph.h:150
gr::logger_ptr d_debug_logger
Definition: flowgraph.h:255
basic_block_vector_t d_blocks
Definition: flowgraph.h:251
basic_block_vector_t calc_used_blocks()
calculates all used blocks in a flow graph
basic_block_vector_t calc_downstream_blocks(basic_block_sptr block, int port)
void connect(const msg_endpoint &src, const msg_endpoint &dst)
Connect two message endpoints.
basic_block_vector_t topological_sort(basic_block_vector_t &blocks)
topologically sort blocks
edge_vector_t calc_upstream_edges(basic_block_sptr block)
edge_vector_t d_edges
Definition: flowgraph.h:252
edge calc_upstream_edge(basic_block_sptr block, int port)
const edge_vector_t & edges() const
Get vector of edges.
Definition: flowgraph.h:218
void disconnect(const msg_endpoint &src, const msg_endpoint &dst)
Disconnect two message endpoints.
std::vector< int > calc_used_ports(basic_block_sptr block, bool check_inputs)
void validate()
Validate flow graph.
void disconnect(const endpoint &src, const endpoint &dst)
Disconnect two endpoints.
std::vector< basic_block_vector_t > partition()
Calculate vector of disjoint graph partitions.
msg_edge_vector_t d_msg_edges
Definition: flowgraph.h:253
bool has_block_p(basic_block_sptr block)
const msg_edge_vector_t & msg_edges() const
Get vector of message edges.
Definition: flowgraph.h:223
void clear()
Clear existing flowgraph.
friend GR_RUNTIME_API flowgraph_sptr make_flowgraph()
gr::logger_ptr d_logger
Definition: flowgraph.h:254
virtual ~flowgraph()
Destruct an arbitrary flowgraph.
void connect(const endpoint &src, const endpoint &dst)
Connect two endpoints.
std::shared_ptr< io_signature > sptr
Definition: io_signature.h:52
Class representing a msg connection between to graph msg endpoints.
Definition: flowgraph.h:119
~msg_edge()
Definition: flowgraph.h:123
std::string identifier() const
Definition: flowgraph.h:127
const msg_endpoint & src() const
Definition: flowgraph.h:125
const msg_endpoint & dst() const
Definition: flowgraph.h:126
msg_edge(const msg_endpoint &src, const msg_endpoint &dst)
Definition: flowgraph.h:122
msg_edge()
Definition: flowgraph.h:121
Definition: flowgraph.h:53
bool is_hier() const
Definition: flowgraph.h:69
void set_hier(bool h)
Definition: flowgraph.h:70
basic_block_sptr block() const
Definition: flowgraph.h:67
bool operator==(const msg_endpoint &other) const
Definition: flowgraph.h:79
pmt::pmt_t port() const
Definition: flowgraph.h:68
msg_endpoint(basic_block_sptr block, pmt::pmt_t port, bool is_hier=false)
Definition: flowgraph.h:61
msg_endpoint()
Definition: flowgraph.h:60
std::string identifier() const
Definition: flowgraph.h:71
#define GR_RUNTIME_API
Definition: gnuradio-runtime/include/gnuradio/api.h:18
GNU Radio logging wrapper.
Definition: basic_block.h:29
std::vector< msg_edge >::iterator msg_edge_viter_t
Definition: flowgraph.h:139
std::vector< edge >::iterator edge_viter_t
Definition: flowgraph.h:112
std::shared_ptr< logger > logger_ptr
Definition: logger.h:250
std::string dot_graph_fg(flowgraph_sptr fg)
std::vector< basic_block_sptr > basic_block_vector_t
Definition: basic_block.h:431
std::vector< msg_edge > msg_edge_vector_t
Definition: flowgraph.h:138
bool operator==(const io_signature &lhs, const io_signature &rhs)
std::vector< edge > edge_vector_t
Definition: flowgraph.h:111
std::vector< endpoint > endpoint_vector_t
Definition: flowgraph.h:85
std::vector< endpoint >::iterator endpoint_viter_t
Definition: flowgraph.h:86
GR_RUNTIME_API flowgraph_sptr make_flowgraph()
std::ostream & operator<<(std::ostream &os, basic_block_sptr basic_block)
Definition: basic_block.h:436
Definition: pmt.h:38
PMT_API bool equal(const pmt_t &x, const pmt_t &y)
PMT_API const std::string symbol_to_string(const pmt_t &sym)
std::shared_ptr< pmt_base > pmt_t
typedef for shared pointer (transparent reference counting).
Definition: pmt.h:83
#define PMT_NIL
Definition: pmt.h:121