discuss-gnuradio
[Top][All Lists]
Advanced

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

Re: [Discuss-gnuradio] Two more potential tag propagation improvements


From: Jeff Long
Subject: Re: [Discuss-gnuradio] Two more potential tag propagation improvements
Date: Sat, 6 Jan 2018 12:13:11 -0500
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.5.0

How much error would be produced by having the executor determine rr_in_offset and rr_out_offset by assuming the current rate holds over the current window of data?

offset = (new_tag.offset - rr_in_offset) * mp_rrate + rr_out_offset + one_half;

This would not require an API change.

You could add a field rr_offset_mode to Block, give it default RR_OFFSET_MODE_GLOBAL for the usual case, and RR_OFFSET_MODE_WINDOW for those blocks that want to use the current rate for the current window.

RR_OFFSET_MODE_GLOBAL:
offset = tag.offset * mp_rrate + one_half;

RR_OFFSET_MODE_WINDOW
offset = (tag.offset - window_start_in) * mp_rrate + window_start_out + one_half;

If there are blocks where this local linear assumption causes too much error, those blocks can do their own tag propagation.

On 01/06/2018 10:01 AM, Andy Walls wrote:
Hi Marcus and Jeff:

So now that I've got something working for correct tag propagation with
a static relative rate through one block, I'm ready to tackle some
other problems.

1. The runtime performing (or at least assisting) correct tag
propagation for blocks with a changing relative rate.

2. Precision tag propagation through multiple rate changing blocks
using fractional tag offsets.  See the discussion at
https://lists.gnu.org/archive/html/discuss-gnuradio/2017-11/msg00089.html
for the gist of this one.

(If some thinks either of the above shouldn't be implemented, let me know.
I don't want to waste time on dead-ends.)

The conceptual solutions for these require API changes that are not
backward compatable.  They can't be fixed on the master branch, and
they have to be fixed on the next branch.

#2 above is a big, wide ranging change, and Marcus has already provided
a sketch of some of it, so I'll do that one last. :)

Regarding #1:
Off list, Jeff requested that the runtime be fixed to correct tag
propagation for block that change their relative rate.  My initial
response was not to bother trying, since the runtime doesn't have
enough information - only the block itself can perform correct tag
propagation.

However, if we allow blocks that change their relative rate to give the
runtime more information about the rate change, then the runtime can
actually do most of the work for tag propagation.

For some background, my latest pull request for a tag propagation fix
made these relevant changes:

1. Modified or added these API methods:

     gr::block::set_relative_rate(double relative_rate);
     gr::block::set_relative_rate(uint64_t interpolation, uint64_t decimation);
     gr::block::set_inverse_relative_rate(double inverse_relative_rate);

2. Changed the tag offset propagation arithmetic to use multiple
precision integer rationals:

      ...
      static const mpq_class one_half(1, 2);
      ...
           else {
             mpz_class offset;
             for(t = rtags.begin(); t != rtags.end(); t++) {
               tag_t new_tag = *t;
               offset = new_tag.offset * mp_rrate + one_half;
               new_tag.offset = offset.get_ui();
               out_buf->add_item_tag(new_tag);
             }
           }
      ...


The expression

        offset = new_tag.offset * mp_rrate + one_half;

can be viewed as a degenerate case of a more general expression

        offset = (new_tag.offset - rr_in_offset) * mp_rrate + rr_out_offset + 
one_half;

Where rr_in_offset is the input sample offset where the particular
mp_rrate value is first valid, and rr_out_offset is the output sample
offset where the particular mp_rrate value is first valid.

The runtime currently assumes these rr_(in|out)_offset values are
always 0.

So the solution, at a high level, is for the blocks performing relative
rate changes to provide values for rr_in_offset and rr_out_offset along
with every change to the relative rate.  Then the runtime can take care
of the rest of the tag propagation headaches.

So the API for setting relative rate then becomes:

        gr::block::set_relative_rate(double relative_rate, uint64_t in_offset = 
0, uint64_t out_offset = 0);
        gr::block::set_relative_rate(uint64_t interpolation, uint64_t 
decimation, uint64_t in_offset = 0, uint64_t out_offset = 0);
        gr::block::set_inverse_relative_rate(double inverse_relative_rate, 
uint64_t in_offset = 0, uint64_t out_offset = 0);

But since the runtime would now maintian a dynamic structure of
(relative rate, in offset, out offset) tuples, the external API for
getting relative rate gets a little messy/ambiguous.  I'm not sure what
to do about that yet.

This concept can support blocks that change their relative rate with
every output sample, such as the PFB clock sync blocks and the symbol
synchronizer blocks.

I suppose I'll test it with the symbol synchronizer blocks, since I now
see that they don't do correct tag propagation if their output rate is
set to anything higher than 1 sample/symbol. :P

Regards,
Andy





reply via email to

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