commit-gnuradio
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Commit-gnuradio] r5236 - gnuradio/branches/developers/jcorgan/disc2/gnu


From: jcorgan
Subject: [Commit-gnuradio] r5236 - gnuradio/branches/developers/jcorgan/disc2/gnuradio-core/src/lib/runtime
Date: Thu, 3 May 2007 19:02:30 -0600 (MDT)

Author: jcorgan
Date: 2007-05-03 19:02:30 -0600 (Thu, 03 May 2007)
New Revision: 5236

Modified:
   
gnuradio/branches/developers/jcorgan/disc2/gnuradio-core/src/lib/runtime/gr_block_detail.h
   
gnuradio/branches/developers/jcorgan/disc2/gnuradio-core/src/lib/runtime/gr_block_detail.i
   
gnuradio/branches/developers/jcorgan/disc2/gnuradio-core/src/lib/runtime/gr_buffer.h
   
gnuradio/branches/developers/jcorgan/disc2/gnuradio-core/src/lib/runtime/gr_runtime_impl.cc
   
gnuradio/branches/developers/jcorgan/disc2/gnuradio-core/src/lib/runtime/gr_simple_flowgraph.h
   
gnuradio/branches/developers/jcorgan/disc2/gnuradio-core/src/lib/runtime/gr_simple_flowgraph_detail.cc
   
gnuradio/branches/developers/jcorgan/disc2/gnuradio-core/src/lib/runtime/gr_simple_flowgraph_detail.h
Log:
Work in progress.  Implements hierarchical flowgraph reconfiguration with 
manual 'restart'.  Not tested very well, but works so far.

Modified: 
gnuradio/branches/developers/jcorgan/disc2/gnuradio-core/src/lib/runtime/gr_block_detail.h
===================================================================
--- 
gnuradio/branches/developers/jcorgan/disc2/gnuradio-core/src/lib/runtime/gr_block_detail.h
  2007-05-03 23:37:04 UTC (rev 5235)
+++ 
gnuradio/branches/developers/jcorgan/disc2/gnuradio-core/src/lib/runtime/gr_block_detail.h
  2007-05-04 01:02:30 UTC (rev 5236)
@@ -55,6 +55,14 @@
     return d_input[which];
   }
 
+  void clear_input (unsigned int which)
+  {
+    if (which >= d_ninputs)
+      throw std::invalid_argument ("gr_block_detail::input");
+    if (d_input[which])
+      d_input[which].reset();
+  }
+
   void set_output (unsigned int which, gr_buffer_sptr buffer);
   gr_buffer_sptr output (unsigned int which)
   {

Modified: 
gnuradio/branches/developers/jcorgan/disc2/gnuradio-core/src/lib/runtime/gr_block_detail.i
===================================================================
--- 
gnuradio/branches/developers/jcorgan/disc2/gnuradio-core/src/lib/runtime/gr_block_detail.i
  2007-05-03 23:37:04 UTC (rev 5235)
+++ 
gnuradio/branches/developers/jcorgan/disc2/gnuradio-core/src/lib/runtime/gr_block_detail.i
  2007-05-04 01:02:30 UTC (rev 5236)
@@ -46,6 +46,14 @@
     return d_input[which];
   }
 
+  void clear_input (unsigned int which)
+  {
+    if (which >= d_ninputs)
+      throw std::invalid_argument ("gr_block_detail::input");
+    if (d_input[which])
+      d_input[which].reset();
+  }
+
   void set_output (unsigned int which, gr_buffer_sptr buffer);
   gr_buffer_sptr output (unsigned int which)
   {

Modified: 
gnuradio/branches/developers/jcorgan/disc2/gnuradio-core/src/lib/runtime/gr_buffer.h
===================================================================
--- 
gnuradio/branches/developers/jcorgan/disc2/gnuradio-core/src/lib/runtime/gr_buffer.h
        2007-05-03 23:37:04 UTC (rev 5235)
+++ 
gnuradio/branches/developers/jcorgan/disc2/gnuradio-core/src/lib/runtime/gr_buffer.h
        2007-05-04 01:02:30 UTC (rev 5236)
@@ -157,6 +157,12 @@
   int items_available () const;
 
   /*!
+   * \brief Return buffer this reader reads from.
+   */
+  gr_buffer_sptr buffer () const { return d_buffer; }
+
+
+  /*!
    * \brief Return maximum number of items that could ever be available for 
reading.
    * This is used as a sanity check in the scheduler to avoid looping forever.
    */

Modified: 
gnuradio/branches/developers/jcorgan/disc2/gnuradio-core/src/lib/runtime/gr_runtime_impl.cc
===================================================================
--- 
gnuradio/branches/developers/jcorgan/disc2/gnuradio-core/src/lib/runtime/gr_runtime_impl.cc
 2007-05-03 23:37:04 UTC (rev 5235)
+++ 
gnuradio/branches/developers/jcorgan/disc2/gnuradio-core/src/lib/runtime/gr_runtime_impl.cc
 2007-05-04 01:02:30 UTC (rev 5236)
@@ -157,7 +157,7 @@
   d_top_block->d_detail->flatten(new_sfg);
   new_sfg->validate();
   new_sfg->d_detail->merge_connections(d_sfg);
-  // d_sfg = new_sfg;
+  d_sfg = new_sfg;
 
   start_threads();
 }

Modified: 
gnuradio/branches/developers/jcorgan/disc2/gnuradio-core/src/lib/runtime/gr_simple_flowgraph.h
===================================================================
--- 
gnuradio/branches/developers/jcorgan/disc2/gnuradio-core/src/lib/runtime/gr_simple_flowgraph.h
      2007-05-03 23:37:04 UTC (rev 5235)
+++ 
gnuradio/branches/developers/jcorgan/disc2/gnuradio-core/src/lib/runtime/gr_simple_flowgraph.h
      2007-05-04 01:02:30 UTC (rev 5236)
@@ -62,6 +62,7 @@
 {
 private:
   friend class gr_runtime_impl;
+  friend class gr_simple_flowgraph_detail;
   friend class gr_hier_block2_detail;
   friend gr_simple_flowgraph_sptr gr_make_simple_flowgraph();
   gr_simple_flowgraph();

Modified: 
gnuradio/branches/developers/jcorgan/disc2/gnuradio-core/src/lib/runtime/gr_simple_flowgraph_detail.cc
===================================================================
--- 
gnuradio/branches/developers/jcorgan/disc2/gnuradio-core/src/lib/runtime/gr_simple_flowgraph_detail.cc
      2007-05-03 23:37:04 UTC (rev 5235)
+++ 
gnuradio/branches/developers/jcorgan/disc2/gnuradio-core/src/lib/runtime/gr_simple_flowgraph_detail.cc
      2007-05-04 01:02:30 UTC (rev 5236)
@@ -194,45 +194,55 @@
   }
 }
 
+gr_block_detail_sptr
+gr_simple_flowgraph_detail::allocate_block_detail(gr_basic_block_sptr block)
+{
+  int ninputs = calc_used_ports(block, true).size();
+  int noutputs = calc_used_ports(block, false).size();
+  gr_block_detail_sptr detail = gr_make_block_detail(ninputs, noutputs);
+  for (int i = 0; i < noutputs; i++)
+    detail->set_output(i, allocate_buffer(block, i));
+
+  return detail;
+}
+
 void
+gr_simple_flowgraph_detail::connect_block_inputs(gr_basic_block_sptr block)
+{
+  gr_block_sptr grblock(boost::dynamic_pointer_cast<gr_block, 
gr_basic_block>(block));
+  if (!grblock)
+    throw std::runtime_error("found non-gr_block");
+  
+  // Get its detail and edges that feed into it
+  gr_block_detail_sptr detail = grblock->detail();
+  gr_edge_vector_t in_edges = calc_upstream_edges(block);
+  
+  // For each edge that feeds into it
+  for (gr_edge_viter_t e = in_edges.begin(); e != in_edges.end(); e++) {
+    // Set the buffer reader on the destination port to the output
+    // buffer on the source port
+    int dst_port = (*e)->dst().port();
+    int src_port = (*e)->src().port();
+    gr_basic_block_sptr src_block = (*e)->src().block();
+    gr_block_sptr src_grblock(boost::dynamic_pointer_cast<gr_block, 
gr_basic_block>(src_block));
+    if (!grblock)
+      throw std::runtime_error("found non-gr_block");
+    gr_buffer_sptr src_buffer = src_grblock->detail()->output(src_port);
+    
+    detail->set_input(dst_port, gr_buffer_add_reader(src_buffer, 
grblock->history()-1));
+  }
+}
+
+void
 gr_simple_flowgraph_detail::setup_connections()
 {
   // Assign block details to blocks
-  for (gr_basic_block_viter_t p = d_blocks.begin(); p != d_blocks.end(); p++) {
-    int ninputs = calc_used_ports(*p, true).size();
-    int noutputs = calc_used_ports(*p, false).size();
-    gr_block_detail_sptr detail = gr_make_block_detail(ninputs, noutputs);
-    for (int i = 0; i < noutputs; i++)
-      detail->set_output(i, allocate_buffer(*p, i));
+  for (gr_basic_block_viter_t p = d_blocks.begin(); p != d_blocks.end(); p++)
+    boost::dynamic_pointer_cast<gr_block, 
gr_basic_block>(*p)->set_detail(allocate_block_detail(*p));
 
-    boost::dynamic_pointer_cast<gr_block, 
gr_basic_block>(*p)->set_detail(detail);
-  }
-
   // Connect inputs to outputs for each block
-  for(gr_basic_block_viter_t p = d_blocks.begin(); p != d_blocks.end(); p++) {
-    gr_block_sptr grblock(boost::dynamic_pointer_cast<gr_block, 
gr_basic_block>(*p));
-    if (!grblock)
-      throw std::runtime_error("setup_connections found non-gr_block");
-
-    // Get its detail and edges that feed into it
-    gr_block_detail_sptr detail = grblock->detail();
-    gr_edge_vector_t in_edges = calc_upstream_edges(*p);
-
-    // For each edge that feeds into it
-    for (gr_edge_viter_t e = in_edges.begin(); e != in_edges.end(); e++) {
-      // Set the input reader on the destination port to the output
-      // buffer on the source port
-      int dst_port = (*e)->dst().port();
-      int src_port = (*e)->src().port();
-      gr_basic_block_sptr src_block = (*e)->src().block();
-      gr_block_sptr src_grblock(boost::dynamic_pointer_cast<gr_block, 
gr_basic_block>(src_block));
-      if (!grblock)
-       throw std::runtime_error("setup_connections found non-gr_block");
-      gr_buffer_sptr src_buffer = src_grblock->detail()->output(src_port);
-
-      detail->set_input(dst_port, gr_buffer_add_reader(src_buffer, 
grblock->history()-1));
-    }
-  }
+  for(gr_basic_block_viter_t p = d_blocks.begin(); p != d_blocks.end(); p++)
+    connect_block_inputs(*p);
 }
 
 gr_buffer_sptr
@@ -478,12 +488,96 @@
   output.push_back(result_block);
 }
 
+bool
+gr_simple_flowgraph_detail::has_block_p(gr_basic_block_sptr block)
+{
+  gr_basic_block_viter_t result;
+  result = std::find(d_blocks.begin(), d_blocks.end(), block);
+  return (result != d_blocks.end());
+}
+
+gr_edge_sptr
+gr_simple_flowgraph_detail::calc_upstream_edge(gr_basic_block_sptr block, int 
port)
+{
+  gr_edge_sptr result;
+
+  for (gr_edge_viter_t p = d_edges.begin(); p != d_edges.end(); p++) {
+    if ((*p)->dst().block() == block && (*p)->dst().port() == port) {
+      result = (*p);
+      break;
+    }
+  }
+
+  return result;
+}
+
 void
-gr_simple_flowgraph_detail::merge_connections(gr_simple_flowgraph_sptr sfg)
+gr_simple_flowgraph_detail::merge_connections(gr_simple_flowgraph_sptr old_sfg)
 {
+  // If a block is new, allocate detail and output buffers
+  for (gr_basic_block_viter_t p = d_blocks.begin(); p != d_blocks.end(); p++) {
+    gr_block_sptr block(boost::dynamic_pointer_cast<gr_block, 
gr_basic_block>(*p));
+
+    if (!block->detail())
+      block->set_detail(allocate_block_detail(*p));
+  }
+
   // For each block used in new flow graph, see if it exists in old flow graph
   for (gr_basic_block_viter_t p = d_blocks.begin(); p != d_blocks.end(); p++) {
     if (GR_SIMPLE_FLOWGRAPH_DETAIL_DEBUG)
-      std::cout << "merge: testing " << (*p) << std::endl;
+      std::cout << "merge: testing " << (*p) << "...";
+    
+    if (old_sfg->d_detail->has_block_p(*p)) {
+
+      // Block exists in old flow graph
+      if (GR_SIMPLE_FLOWGRAPH_DETAIL_DEBUG)
+       std::cout << "already exists" << std::endl;
+
+      // Fish out the number of inputs on existing block detail
+      gr_block_sptr block(boost::dynamic_pointer_cast<gr_block, 
gr_basic_block>(*p));
+      int ninputs = block->detail()->ninputs();
+
+      // Iterate through the inputs and see what needs to be done
+      for (int i = 0; i < ninputs; i++) {
+       if (GR_SIMPLE_FLOWGRAPH_DETAIL_DEBUG)
+         std::cout << "Checking input " << i << "...";
+
+       gr_edge_sptr edge = calc_upstream_edge(*p, i);
+       // The input edge went away
+       if (!edge) {
+         if (GR_SIMPLE_FLOWGRAPH_DETAIL_DEBUG)
+           std::cout << "not assigned, removing old reader if any" << 
std::endl;
+         block->detail()->clear_input(i);
+         continue;
+       }
+
+       // Fish out existing buffer reader and see if it matches correct buffer 
from edge list
+       gr_block_sptr src_block(boost::dynamic_pointer_cast<gr_block, 
gr_basic_block>(edge->src().block()));
+       gr_block_detail_sptr src_detail = src_block->detail();
+       gr_buffer_sptr buffer = src_detail->output(edge->src().port());
+       gr_buffer_reader_sptr reader = block->detail()->input(i);
+       
+       // If there's a match, skip to next input
+       if (buffer == reader->buffer()) {
+         if (GR_SIMPLE_FLOWGRAPH_DETAIL_DEBUG)
+           std::cout << "matched" << std::endl;
+         continue;
+       }
+       else {
+         if (GR_SIMPLE_FLOWGRAPH_DETAIL_DEBUG)
+           std::cout << "no longer valid" << std::endl;
+
+         // Create new buffer reader and assign
+         block->detail()->set_input(i, gr_buffer_add_reader(buffer, 
block->history()-1));
+       }
+      }
+    }
+    else {
+      if (GR_SIMPLE_FLOWGRAPH_DETAIL_DEBUG)
+       std::cout << "new block" << std::endl;
+
+      // This block just needs buffer readers at this point
+      connect_block_inputs(*p);
+    }
   }
 }

Modified: 
gnuradio/branches/developers/jcorgan/disc2/gnuradio-core/src/lib/runtime/gr_simple_flowgraph_detail.h
===================================================================
--- 
gnuradio/branches/developers/jcorgan/disc2/gnuradio-core/src/lib/runtime/gr_simple_flowgraph_detail.h
       2007-05-03 23:37:04 UTC (rev 5235)
+++ 
gnuradio/branches/developers/jcorgan/disc2/gnuradio-core/src/lib/runtime/gr_simple_flowgraph_detail.h
       2007-05-04 01:02:30 UTC (rev 5236)
@@ -79,9 +79,12 @@
   void setup_connections();
   void merge_connections(gr_simple_flowgraph_sptr sfg);
 
+  void connect_block_inputs(gr_basic_block_sptr block);
+  gr_block_detail_sptr allocate_block_detail(gr_basic_block_sptr block);
   gr_buffer_sptr allocate_buffer(gr_basic_block_sptr block, int port);
   gr_basic_block_vector_t calc_downstream_blocks(gr_basic_block_sptr block, 
int port);
   gr_basic_block_vector_t calc_downstream_blocks(gr_basic_block_sptr block);
+  gr_edge_sptr calc_upstream_edge(gr_basic_block_sptr block, int port);
   gr_edge_vector_t calc_upstream_edges(gr_basic_block_sptr block);
   gr_basic_block_vector_t calc_used_blocks();
   std::vector<gr_block_vector_t> partition();
@@ -92,7 +95,8 @@
   bool source_p(gr_basic_block_sptr block);
   gr_basic_block_vector_t sort_sources_first(gr_basic_block_vector_t &blocks);
   void topological_dfs_visit(gr_basic_block_sptr block, gr_block_vector_t 
&output);
-        
+  bool has_block_p(gr_basic_block_sptr block);
+
 public:
   ~gr_simple_flowgraph_detail();
 };





reply via email to

[Prev in Thread] Current Thread [Next in Thread]