Multiple asynchronous channels in parallel

Hello list,

I am trying to build a real-time signal processing system that captures
wide signal bandwidth(contains multiple channels) using 1 USRP, then
send it to parallel signal chains afterspitingthem using filters.
The system works for a short period and exit with segfault. (the single
channel is completely stable)
The channels containasynchronousdata packets and some are empty. This
yield to have different processing speed based on the channel contents.
After all, some channels are consuming samples faster than others.
consume_each function update the read-write pointers faster which
“might” be the cause of the segfault I am getting.

Is there any limitation on real-processing of multiple channel in
current gnu-radioimplementation (from the consume_each criteria)?
If not, is there any example of multipleasynchronouschannel capturing/
processing, that helps to track the problem source?

Regards,
Alyafawi

On Tue, Sep 17, 2013 at 4:50 AM, Alyafawi [email protected] wrote:

consume_each function update the read-write pointers faster which “might” be
the cause of the segfault I am getting.

Is there any limitation on real-processing of multiple channel in current
gnu-radio implementation (from the consume_each criteria)?

Nope. This behavior should be absolutely fine. And anyways shouldn’t
result in a segfault. Are you using your own blocks in this setup? If
so, double check them to make sure you’re doing all the right
book-keeping with the consume/produce methods. That tends to be where
people have issues.

If it’s all blocks that come with GNU Radio, can you post the
flowgraph? We should really not be seeing segfaults.

If not, is there any example of multiple asynchronous channel capturing/
processing, that helps to track the problem source?

Not off the top of my head, at least with examples that come with GNU
Radio.

Regards,
Alyafawi


Tom
Visit us at GRCon13 Oct. 1 - 4
http://www.trondeau.com/grcon13

Am I missing something with the book-keeping term? to me I am just
defining
the nitems_items_required and how much to consume after each block call.


View this message in context:
http://gnuradio.4.n7.nabble.com/multiple-asynchronous-channels-in-parallel-tp43656p43679.html
Sent from the GnuRadio mailing list archive at Nabble.com.

Yes, I am using my own module that searches for messages. The flow graph
structure contains usrp source → LPF → my own module.

I am controlling them using nitems_items_required[0] = noutput_items *
(message length)
and I call consume_each after each round with the proper number of
processed
samples.

The single channel version of the code is quite stable. Now, I just
capture
a wider band, and canalize using the filter offset.

empty channels will consume samples faster than channels containing
messages, so the scheduler is handling the read/write pointers to avoid
writing on memory requested by other branches?


View this message in context:
http://gnuradio.4.n7.nabble.com/multiple-asynchronous-channels-in-parallel-tp43656p43678.html
Sent from the GnuRadio mailing list archive at Nabble.com.

On Tue, Sep 17, 2013 at 11:08 AM, alyafawi [email protected] wrote:

Yes, I am using my own module that searches for messages. The flow graph
structure contains usrp source → LPF → my own module.

I am controlling them using nitems_items_required[0] = noutput_items *
(message length)

So you are defining this in the forecast function?

What is the item size (input and output) that you specify with the
io_signatures in the constructor?

and I call consume_each after each round with the proper number of processed
samples.

You’ve asked the scheduler to provide noutput_items number of messages
worth of input data. So you have to make sure you’re consuming the
message length in number of input items each time through.

Basically, it sounds like you’re doing things right. When I say
“book-keeping” I mean to make sure that the number of items in and out
for each block are consumed and produced correctly by understanding
the item size and what you’ve processed. As I said, it sounds like you
understand things, but just work through the math again to double
check. What might be happening is that you’re not consuming or
producing the right number of items, which is going to throw off your
read/write pointers in the buffers, possibly writing someplace you’re
not supposed to, which is causing the segfault.

The single channel version of the code is quite stable. Now, I just capture
a wider band, and canalize using the filter offset.

empty channels will consume samples faster than channels containing
messages, so the scheduler is handling the read/write pointers to avoid
writing on memory requested by other branches?

Well, ‘faster’ is an ambiguous term in an SDR GPP. The blocks are
probably completing their work faster, but the scheduler is still
moving stuff in proportion to everything else. So empty channels may
have that path finish faster than others, but it would just be waiting
until their is more data made available to it. Since you’re coming in
through the same radio front end and passing it through filters of
(presumably) equal length, all those samples get there at the same
time. And all of your branches are processing faster than real-time or
you’d start experience overflows from the radio.

On the other hand, the addition of the blocks will change how the
scheduler moves data around, so that could be a different effect
that’s causing issues than them being different rates.

Probably best to debug this offline without a USRP in the path, which
can help stabilize things and make runs more consistent.


Tom
Visit us at GRCon13 Oct. 1 - 4
http://www.trondeau.com/grcon13

On Wed, Sep 18, 2013 at 3:20 AM, alyafawi [email protected] wrote:

whenever I found I message, I convert it to char array, and send it to the
next module.

I am using gr_block where it accept different ratios of input/output rates.
But with my current implementation, this ratio is not M:N, where M, N are
integers, it can be any ratio (nitems:sample_number as in the attached file)

From my understanding to the scheduler, the left over samples in the module
(provided = X, consumed = Y, left = X-Y) will be concatenated in the front
of the new stream, regardless how much was left.

Yes, that’s correct.

could it be I have to keep the provided:consume ratio as an integers ratio?
then I achieve this using local buffers in the module ?

The ratio doesn’t need to be an integer.

I checked the timestamp of messages captured by two USRPs running single
channel code in parallel, the resolution was within one symbol duration
(1/R). while the multi channel code, showed a difference of more than one
symbol duration (> 1/R) which I thought its due to samples disorder while
splitting the branches. That lead me to the first question about “faster”

Unfortunately, there is only so much I can do to help you with these
problems. As I said, you seem to have a good grasp on what’s supposed
to happen. I have a feeling you’re just implementing something wrong.

My advice again is to not use a USRP for debugging the block. Create a
simulation of 2 channels of data and feed that in and keep track of
how many you’re consuming, how many you’re producing, the message
sizes, etc.

Often, when it comes to these problems, I find it really helpful to
draw out the buffers and the boundaries and walk through it step by
step to make sure I’m taking care of all items correctly.


Tom
GRCon13 Oct. 1 - 4
http://www.trondeau.com/grcon13

for a single channel (quite stable):

USRP – LPF – Module –

for multi channel (exit with segfault)

         -- LPF -- Module --

USRP – LPF – Module –

– LPF – Module –

I am using xlating_fir_filter_ccf with the proper frequency offset
value.

I have attached a draft of my module block, pleased to have a look at it
if
I am producing/consuming samples wrongly.

Yes, I am defining nitems_items_required in the forecast. input/ output
size
as follow:
gr_make_io_signature(MIN_IN, MAX_IN, sizeof(gr_complex)),
gr_make_io_signature(MIN_OUT, MAX_OUT, 23)),
whenever I found I message, I convert it to char array, and send it to
the
next module.

I am using gr_block where it accept different ratios of input/output
rates.
But with my current implementation, this ratio is not M:N, where M, N
are
integers, it can be any ratio (nitems:sample_number as in the attached
file)

From my understanding to the scheduler, the left over samples in the
module
(provided = X, consumed = Y, left = X-Y) will be concatenated in the
front
of the new stream, regardless how much was left.

could it be I have to keep the provided:consume ratio as an integers
ratio?
then I achieve this using local buffers in the module ?

I checked the timestamp of messages captured by two USRPs running single
channel code in parallel, the resolution was within one symbol duration
(1/R). while the multi channel code, showed a difference of more than
one
symbol duration (> 1/R) which I thought its due to samples disorder
while
splitting the branches. That lead me to the first question about
“faster”


View this message in context:
http://gnuradio.4.n7.nabble.com/multiple-asynchronous-channels-in-parallel-tp43656p43699.html
Sent from the GnuRadio mailing list archive at Nabble.com.

Tom R. wrote in post #1122054:

On Wed, Sep 18, 2013 at 3:20 AM, alyafawi [email protected] wrote:

whenever I found I message, I convert it to char array, and send it to the
next module.

I am using gr_block where it accept different ratios of input/output rates.
But with my current implementation, this ratio is not M:N, where M, N are
integers, it can be any ratio (nitems:sample_number as in the attached file)

From my understanding to the scheduler, the left over samples in the module
(provided = X, consumed = Y, left = X-Y) will be concatenated in the front
of the new stream, regardless how much was left.

Yes, that’s correct.

could it be I have to keep the provided:consume ratio as an integers ratio?
then I achieve this using local buffers in the module ?

The ratio doesn’t need to be an integer.

I checked the timestamp of messages captured by two USRPs running single
channel code in parallel, the resolution was within one symbol duration
(1/R). while the multi channel code, showed a difference of more than one
symbol duration (> 1/R) which I thought its due to samples disorder while
splitting the branches. That lead me to the first question about “faster”

Unfortunately, there is only so much I can do to help you with these
problems. As I said, you seem to have a good grasp on what’s supposed
to happen. I have a feeling you’re just implementing something wrong.

My advice again is to not use a USRP for debugging the block. Create a
simulation of 2 channels of data and feed that in and keep track of
how many you’re consuming, how many you’re producing, the message
sizes, etc.

Often, when it comes to these problems, I find it really helpful to
draw out the buffers and the boundaries and walk through it step by
step to make sure I’m taking care of all items correctly.


Tom
GRCon13 Oct. 1 - 4
GNU Radio Conference 2013 — Rondeau Research

I followed your advice for tracking the problem. Thanks a lot.
I improved the code performance to support more channels in parallel.

Since I am using C++ to create the flow graph, I made the following
updates: 1- connecting one USRP sptr to multiple branches has been
replaced with a new gnuradio module that duplicates the stream between
branches. 2- There might be memory access violation with *input in my
gnuradio module (up to my findings). So I stored the incoming data in a
local buffer directly.

with these updates, the code supports 10 channels in parallel without
any problem.