Zero ninput_items_required[0]

Hi list,

I am designing very simple FSK modulator. The principle of operation is
following:
based on symbol value nco generates baseband signa. The problem is
somewhere in my forecast function, but I can’t figure out where,
probably
because of misunderstanfing of something.

The body of my forecast function is:

ninput_items_required[0] = noutput_items * d_sym_rate / d_sampling_freq;
printf(“ninput_items_required %d, noutput_items %d\n”,
ninput_items_required[0], noutput_items);

when i run execution, the output is following:

ninput_items_required 8, noutput_items 4096
ninput_items_required 4, noutput_items 2048
ninput_items_required 2, noutput_items 1024
ninput_items_required 1, noutput_items 512
ninput_items_required 0, noutput_items 256
ninput: 0, produced: 0

The last line of the output comes from general_work function and prints
number of input items and number of produced output samples.
Can somebody explain me why forecast is called 5 times, till number of
input items reach 0, and after that nothing is possible in work
function,
cause it won’t enter the loop since ninput_items = 0;

Thanks,

On Fri, Oct 18, 2013 at 02:32:48PM +0200, Nemanja S. wrote:

The body of my forecast function is:

ninput_items_required[0] = noutput_items * d_sym_rate / d_sampling_freq;
printf(“ninput_items_required %d, noutput_items %d\n”, ninput_items_required
[0], noutput_items);

If d_sym_rate and d_sampling_freq are integers, integer division will
cause ninput_items_required to be zero for small values of
noutput_items.

of input items and number of produced output samples.

Can somebody explain me why forecast is called 5 times, till number of input
items reach 0, and after that nothing is possible in work function, cause it
won’t enter the loop since ninput_items = 0;

Depending on the state of the buffers, the scheduler calls forecast()
until it finds a value of ninput_items_required that works (it tries to
process as much as possible). In your case, there is probably some
situation where the input buffer is not full.
The way you’ve set up forecast(), the scheduler will eventually find out
that it doesn’t need any items to produce at least 256 output items. So
it calls work() with no input data, expecting 256 output items.
But since you can’t produce anything without input, nothing happens.

It seems like what you want is a sync_decimator, got a gr::block. This
means you set relative_rate in the ctor and don’t need to handle all of
this
yourself. Make sure you don’t set relative_rate to zero, again!
In a sync_decimator, you won’t need forecast() at all and your work
function is much simpler. The scheduler will also never try to call a
sycn_decimator w/o input.

MB


Karlsruhe Institute of Technology (KIT)
Communications Engineering Lab (CEL)

Dipl.-Ing. Martin B.
Research Associate

Kaiserstraße 12
Building 05.01
76131 Karlsruhe

Phone: +49 721 608-43790
Fax: +49 721 608-46071
www.cel.kit.edu

KIT – University of the State of Baden-Württemberg and
National Laboratory of the Helmholtz Association

Hi Nemanja,

Considering following flowgraph, assume your block is A, and assume all
blocks work with the same itemsize.
$\fbox{\textrm C}\rightarrow\fbox{\textrm
B}\rightarrow\fbox{\text{\textbf{A}}}\rightarrow\fbox{\textrm D}$

good question, but basically, when running, when A is done with a run of
work, it’s thread notifies blocks “upstream” (B in this case) that it
has consumed N input items, making that space available for new output;
GNU radio then calls forecast of B with a noutput_items M_i = floor( 2
** ( floor(log_2 N) - i) <= N, i in {0,1,…,floor(log_2 N) +1} to fill
that space. However, if the upstream block B needs more input items than
C has provided, GNU Radio will repeatedly reduce the number of samples
it asks for until B needs less or equal samples as C has produced.

In your case, this only happens for 0 output items; thus your
general_work gets called with 0 input items, as Martin already stated.
So what happens then? Since A has not provided any more output items for
the blocks downstream, D can’t do anything that it has not already been
doing. The downstream part of the flowgraph stalls. Upstream part: Since
GNU Radio has not been able to supply you with more than 0 input items,
we can assume that the upstream part of the flowgraph is stuck, or done.
Therefore, execution ends here.

Greetings,
Marcus

Thank you Martin, I will try with the sync_decimator, but it is also
important for me to unterstand what’s happening here.
So, I have vector source -> throttle -> fsk_modulator -> scope sink.
Vector source generates 8 symbols. From where scheduler starts, from
source
or from the sink? And why it didn’t stop for any value before 0? What
should I add into general block to avoid this?

Thank you


Discuss-gnuradio mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/discuss-gnuradio


Discuss-gnuradio mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/discuss-gnuradio


Discuss-gnuradio mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/discuss-gnuradio

Hm, I don’t know why this should really happen before your source’s work
function is called.
But basically, maybe this is part of GNU Radio trying to figure out how
to assign buffers; I haven’t dived very deep into that aspect of the
runtime.
However, since your forecast told GR that you’re able to produce samples
without input, I could imagine that your work gets scheduled
simultaneously with those of your sources.
To circumvent that, just don’t lie :wink: and tell the scheduler that you
need input to produce output.

Greetings,
Marcus

On Tue, Oct 22, 2013 at 02:22:20PM +0200, Nemanja S. wrote:

Or maybe the question should be like this: on which parameter to rely when
making general work function, number of iput items or number of output items?

As I just said, in a sync_interpolator, you’re not using general_work(),
and your question goes away.

MB


Karlsruhe Institute of Technology (KIT)
Communications Engineering Lab (CEL)

Dipl.-Ing. Martin B.
Research Associate

Kaiserstraße 12
Building 05.01
76131 Karlsruhe

Phone: +49 721 608-43790
Fax: +49 721 608-46071
www.cel.kit.edu

KIT – University of the State of Baden-Württemberg and
National Laboratory of the Helmholtz Association

On Tue, Oct 22, 2013 at 02:20:04PM +0200, Nemanja S. wrote:

Hello guys again!

Based on Martins suggestion and Marucs’ explanation I copied some principles
from sync_interpolator and situation looks much better. I used function
set_output_multiple and set_relative rate and now the outcome of calling

FYI: When using sync_interpolator, it will call set_relative_rate for
you (that’s why you specify an interpolation rate).

And as u can see it always offers integer multiple of samp_rate/sym_rate. The
problem comes now when i run the flowgraph with vector source that repeats the
pattern. After calling forecast program executes work function but it provides
me 32768 input samples which is of course silly:

work function, ninput: 32768, noutput: 4000

Don’t worry about that. In all sync blocks, the output buffer is what’s
relevant. If you fill up the output buffer in this case, you will
consume 8 input items.
How are you even getting the number of input items?
sync_interpolator::work() doesn’t tell you that.

It still seems like you’re abusing the API somehow.

MB


Karlsruhe Institute of Technology (KIT)
Communications Engineering Lab (CEL)

Dipl.-Ing. Martin B.
Research Associate

Kaiserstraße 12
Building 05.01
76131 Karlsruhe

Phone: +49 721 608-43790
Fax: +49 721 608-46071
www.cel.kit.edu

KIT – University of the State of Baden-Württemberg and
National Laboratory of the Helmholtz Association

Well, I still didn’t try with interpolator, cause it seems that it will
work. I’d rather try to make it with general block and also learn more
about how the stuff work.
That’s why I said that I used principles used for interpolator.
Ok, I am now tracking number of produces items and it works ok, from the
buffers point of view.

Thanks guys very much

To be completely clear:
In your original post you stated that your block really behaves like a
sync_interpolator/decimator. Yet, you’re reinventing the wheel by
copying the wheel into your code.
DO NOT just copy code to you not-sync block from sync_block if you want
sync_interpolator/decimator’s behaviour. That’s totally confusing, a
waste of time, and will lead to code that is badly maintanable.
Instead, just make a subclass of sync_interpolator/decimator and replace
its work function. You get all the features, free, well-tested, and
maintained by someone else.
If you, however, really need to implement something that works like
sync_interpolator/decimator most of the time but needs to drop samples
occasionally or something like that, you might be better of splitting
your functionality to a sync_interpolator that does all the processing,
and a non-sync block, that wraps the state machine (or whatever) to do
the dropping (or whatever). However, from what you’ve posted, this does
not seem necessary - just make a new block with “gr_modtool add”, use
“decimator” or “interpolator” as type, copy over your general work
function’s body to the work function and fix it accordingly, so that it
no longer manually produces and consumes items.

Greetings,
Marcus