Project Overview

GNU Radio is a free software development toolkit that provides the signal processing runtime and processing blocks to implement software radios using readily-available, low-cost external RF hardware and commodity processors. It is widely used in hobbyist, academic and commercial environments to support wireless communications research as well as to implement real-world radio systems.


Block Core Affinity

I just pushed an update to master/next of GNU Radio that allows us to specifically set the affinity of a block to a particular core. We can do this pretty easily because each block is its own thread in the Thread-Per-Block scheduler, so really what we are doing is setting the thread affinity.

The reason to introduce this behavior is to help us start developing an understanding of GNU Radio on many-core machines. For example, we've been contacted by the Parallella project, and this kind of functionality might be crucial to working well on that platform. On most current systems, we can talk about multi-core, which are a small (up to a dozen or two) number of the same types of processors with shared memory and local cache. The OS scheduler probably does a fantastic job with scheduling the threads in this situations, and kernels like Linux have alternative scheduling strategies we can use for specific purposes. But in a many-core system where we have heterogeneous cores and maybe different access to memory transfers or DMA to IO devices, the ability to selectively choose which cores to run on may be more important. Think about a situation where you want your UHD source block to run on the core that has the closest/fastest access to the GigE system. I'm not saying that this will actually work or help in these scenarios, but it's worth it to make this kind of research and experimentation available.

The API for this is pretty straight-forward, and block affinity can be set before and during the flowgraph run. On a given block, you just call the function 'set_processor_affinity()'.

Notice that the function takes a list (a Python list or a C++ vector of ints), so you can set the affinity to a group of cores if you want. There's an example of how to use this in gnuradio-core/src/examples/mp-sched/ When you run it, watch your CPU usage monitor(s). This runs two gigantic filters that are designed to take up most of a core, one is set to core 0 and the other is set to either core 0 or 1. As long as at least 1 of the cores specified is present, the system will just use that, so this example will run even on single-core machines (but I have not tested this behavior in Windows). On systems with 2 or more cores, core 0 will be largely taken up by the first filter. The second filter could use core 0, but will likely be scheduled to use core 1.

One thing to note: this is not fully cross-platform. Setting thread affinity seems to be a delicate subject and not fully supported. In fact, the pthread library call pthread_setaffinity_np has that suffix 'np' to specify that it is implicitly non-portable. The GNU Radio Utilities and Etc. Library (GRUEL) has been updated to provide abstracted calls for the different OSes that we support for this. Right now, we have Linux and Windows support. I tried to get OSX support, but their API isn't exactly what we are looking for (they are interested in sharing cache lines, not specifically tying a thread to a core). So until things change, our GRUEL thread affinity calls in OSX are nops.

In the Doxygen manual, look for the Related Pages page named 'Block Thread Affinity' for more details.


Project Updates

As always, we've been hard at work on extending and improving the features in GNU Radio. This is just a quick update on a few of the things we've been working on recently.

First, I have been adding specific pages to the Doxygen Manual that catalogue and describe certain features and functions of GNU Radio. You can find these in the "Related Pages" section. They feature discussions and examples for how to use some of the features in GNU Radio that might not otherwise be obvious. I like this model since it keeps the documentation of the code directly integrated into the code and the build system. You can always have a local copy of the manual for your version. We're also not trying, then, to keep multiple versions of code documentation all over the place.

Today, to make things easier, I expanded our Documentation section on the main GNU Radio webpage to directly link to some of these pages. I'm not sure how many others have found them or are using them already, but I wanted to make sure it was easy to what was available and where to locate the information.

The other thing that I wanted to mention today is the work that's been done on the QTGUI blocks. These are visualization tools for signals in GNU Radio. We've been significantly improving them over the past few months.

The first major improvement has been to add direct user control over the parameters while operating live. The figure below shows a screenshot of the gr-qtgui example **. First, notice the overall color scheme. This is based of the ability to use QT style sheets that can define the look of a QTGUI app. In this running example, I right-clicked outside of the curve canvas itself (where right-click means to unzoom) to pull up the menu. As you can see, the menu allows us to adjust a number of parameters. Some of these are available in all plotters, but others are specific to the type of plot (the FFT size or averaging would be meaningless in a time domain or constellation plot). In this figure, I have adjusted the color of line 'Data 0' to red, increased the width of the other two lines, changed the FFT size to 512, and turned on averaging. I then stopped the graph and tool a screen shot to make this image (notice, though, that there is a 'Save' option in the drop-down menu; this saves the current plot, but it would not have included the menu information).

I would encourage anyone using the QTGUI plotters to play around in these menus to understand the kind of flexibility we now have while looking at signals.

Finally, before this post gets too much longer, I wanted to also note that we have just added a new QTGUI plotter to do time raster plots. These types of plots show samples in time, line by line, so both x and y axes are in time. This is often used for looking at data and packet structure. The GNU Radio plotters can accept multiple signals in that are then plotted as an overlay. The intensity is then shown as the sum of the samples, so it will be higher when then overlap and lower when they are different.

The figure below shows the output of the example that is shipped with GNU Radio. It has one signal that has 10 zeros, then 80 bits of alternating ones and zeros, and then ended with another 10 zeros. Another signal is then overlaid on top that just has a pattern of 3 one part-way into the vector. These vectors are then repeated. We can see the bright white stripe is where we get the 3 ones from signal 1 on top of the samples in signal 0.


Also note the diagonal. We draw these figures on a grid of a number of rows and number of columns. If we had 100 columns in this example, the samples would be plotted in straight columns. But in many situations where these types of plots are useful, we may have some fractional offset we want to handle. This example is showing us that we can set the number of columns to 100.25, so there's a quarter bit overlap between rows that causes this diagonal. Using the drop-down menu, we can adjust the number of columns to 100 to get what we see below.



Update on Filter Design Tool

Some quick work between myself and (mostly) Sreeraj helped me realize something that I instantly wanted to do with his new API for using gr_filter_design. I just wanted to publicize it here.

The gr_filter_design tool nicely ties into Python and GNU Radio projects. We launch the filter design tool from the program and can have it return the resulting filter to us in the code to use directly with our filters. Sreeraj also adds a callback function, so that every time the filter design is updated, this callback function is called and it is passed the filter object.

So what did I want to do? I wanted to do a live update of the filter on a live signal. So we built up an example (found in gr-filter/examples/ that constructs a simple flowgraph. Two sinusoids are created at different frequencies, some channel noise is added to them, then they are passed through a filter and finally displayed on a QT GUI. The filter starts of with just a single tap of 1, so it's really not doing any filtering.

We then have a function called 'update_filter' that is used as the callback function with the filter design tool. So when you run this program, both the filter design tool and the QT GUI window showing the signal pop up. Whenever we design a new filter, we can immediately see the effects on the real signal that's running through GNU Radio. I've put a screen shot of both windows below.

This image shows the original signal (we've just been storing the maximum value at all FFT points since the start, so we turn on that plot curve) and the new signal through our filter. In this static case, I just designed a band-reject filter around the higher frequency.

Here's another fun experiment that I did. I first created a simple low-pass filter, so the higher frequency signal was rejected but the lower frequency wasn't. I then used the pole-zero plot to move around a couple of the poles onto the unit circle. Setting two of them at the right phase orientation allowed me to put zeros at the frequency of the lower signal. We can see that we've almost cancelled that one out now, too. I used two because the accuracy of getting just a single zero on the correct frequency was too great, so putting two around it allowed me to hit it pretty good with a null in the filter.

Really good fun (if signal processing is within your definition of fun). Also, really instructive and educational. Seeing how these filters behave as we update their parameters and poles and zeros can really help you learn what's going on with the signal processing.


New Documentation for New Features

Because we've been working on new features in GNU Radio that are not part of a standard GNU Radio application with blocks and a streaming model, I've felt it's increasingly important to explain and document these. So I just pushed some new updates that expand the Doxygen manual with new pages for these new features.

(Also, I'm trying to use the word 'new' here as much as possible, apparently.)

If you build the Doxygen manual, the main page now points to sub-pages for things like:

  • Polymorphic Types
  • Message Passing
  • Metadata Information
  • Instructions for using Volk in GNU Radio
  • Polyphase Filterbanks

Some of these pages have been in the manual for a while, some of them are new. And I plan on adding more of these over time. One reason to have them in this format in the Doxygen manual is because they're part of the source code so that everyone can have access to them, they are tracked in our version control system, and so we can nicely co-locate it all in one place. Also, I plan on adding new links on that directly point to these pages in the manual that get's published on the website. Some of these pages are not in any release, so we'll wait until we release 3.6.3 (this weekend if all goes well) before we put it all together on

Important New Feature

If you haven't already seen our announcements about it, I want to point out the manual page that describes the use of our new message passing system. The API, design, and some examples can all be found in the Doxygen manual page "Message Passing." This is a really powerful new feature that we want to start using as much as possible.



New Filter Design Tool in 'next'

Our 'next' branch now contains the updated gr_filter_design tool! Thanks to Sreeraj Rajendran for his fantastic work on this! Also, thanks to Google for supporting the work through the 2012 Google Summer of Code.

When you build and install the 'next' branch, you'll now get access to the updated design tool. If you haven't seen any of the discussions about it from the conference or anywhere else, check out this YouTube video describing it's capabilities. Below is a screen shot just taken of the version that's now a part of our 'next' branch:

Make sure to check out the examples in the GNU Radio source code (gr-filter/examples/gr_filtdes_*.py). These show you have you can programmatically call the design tool and have it return an object containing the filter parameters and taps.