Open drslebedev opened 2 weeks ago
The
processBulk
function is called independently of the available samples on otherSync
and/orAsync
ports.
Can you clarify when processBulk
is called and when it isn't called? For example, for a block with Sync
input and Async
output, is processBulk
called if there are zero items available in the input?
The user can change the sample ratio iteration-to-iteration using
input.consume()
andoutput.publish()
Will this stop being true for Sync
ports? The kind of use case that I have in mind for a Sync
input and Sync
output block that sometimes doesn't respect its M:N
ratio is a block like the GR 3.10 Symbol Sync. Usually it decimates by a fixed ratio (the GR 3.10 block allows this ratio to be a float
, but for the sake of the example let's suppose the ratio is a rational number). But the decimation is done in terms of a closed loop that depends on the values of the input, so sometimes the block "slips" one input sample forward or backwards by consuming one more or one less samples than the nominal ratio would indicate.
Reading the section on "consume() / publish() Only for Async Ports", it seems that this will be the case. In this case it might perhaps be necessary to have a way for blocks with Async
ports to indicate a rough input_samples/ouput_samples
relation.
Specially important in this case is to clarify what happens with busy polling a processBulk()
function for a block with only Async
ports. If consume()
and publish()
are removed for Sync
ports, then every block that doesn't have a definite M:N
input/output relation needs to be Async
-only, but most of this blocks need some input to produce some output.
If at least one Async
output port is present, processBulk
is always called, even if no input samples are available (unless Async output port constraints are not met, namely min/max port constraints).
We consider introducing a policy to prevent busy polling and only call processBulk
for Async
ports if input samples are available.
Will this stop being true for Sync ports?
Yes, because users can easily ignoring N:M ratio using consume()/publish(). If the ratio is not fixed one should use Async ports.
Thanks for the clarifications. What I don't understand is, for a block with a single input port and a single output port, which are the differences between the cases:
Looking at the list of differences between Sync and Async ports, I see that one of them is that if there is one Async port then processBulk()
is called continuously (this isn't really a port-specific property, but a block-specific property), and that N:M Resampling
is not taken into account (this isn't really a property of a single port, but a property that relates an input port and an output port). Maybe these all three cases behave the same? Maybe only the Async input, Async output makes sense? The Async
annotation is applied at the level of ports, but to me it seems that its semantics affect properties that belong to a larger construct than just a single port.
In general, these three cases behave similarly, but there are some differences to note.
The main differences between these cases lie in how constraints are applied:
For the output port:
processBulk
is invoked only if input samples are available.processBulk
is invoked even if no input samples are available, which can be controlled.Additionally, for an Async port, a user can call consume()
and publish()
.
For a block with a single Async input and a single Sync output, does processBulk()
only get called if the input has some samples available? Wouldn't this kind of block ought to behave as a source block (so its processBulk()
always gets called) which has an additional input that may or may not have samples at any point?
For the output Sync
port, the processBulk
function is only invoked when input samples are available. Otherwise, it's unclear how many samples to provide for the Sync
output port, as Sync
ports do not support a publish()
call.
For a Source
block with an additional Async
input, it seems that both the input and output need to be Async
.
With this issue we want to review the semantic of
Async
ports and clearly define the difference betweenSync
andAsync
cases.Number of samples constraints
There are two types of constraints used to calculate the input and output number of samples to be processed:
Sync
andAsync
ports.Sync
ports.Sync
andAsync
Port BehaviorsSync Ports:
Sync
ports.M:N
ratio between input and output samples. TheprocessBulk
is called withk*M
inputs andk*N
outputs.Async Ports:
processBulk
function is called independently of the available samples on otherSync
and/orAsync
ports.input.consume()
andoutput.publish()
.Examples
4
Sync
+ 1Async
Inputs -> 1Sync
Output:Sync
inputs have consistent input (same number of samples) andAsync
has some input samples (fulfilling port constraints) -> callprocessBulk
.Sync
inputs have consistent input (fulfilling port + resampling constraints),Async
has no input (or input does not fulfill port constraints) -> callprocessBulk
(Async
port has no input samples).Sync
input constraints,Async
has input (fulfilling port constraints) -> callprocessBulk
(no samples for inputSync
ports, no samples for outputSync
port, only samples for inputAsync
port).Sync
input available and noAsync
data -> do not callprocessBulk
.Sync
and/orAsync
Inputs -> 4Sync
+ 1Async
Outputs:Async
output port is present, always callprocessBulk
(unlessAsync
output port constraints are not met). This is because the user can calloutput.publish()
even if no input samples are present. Note: This can lead to performance issues due to busy polling.processBulk
can be invoked upto 4G/s.processBulk
forAsync
ports if input samples are available. This can be a port policy.consume()
/publish()
Only forAsync
PortsM:N
resampling ratio and stride forSync
ports usingconsume()/publish()
. This ensures the resampling ratio and the consistent number of input/output samples are maintained.~ConsumablePortRange
and its counterpart or even statically disabled.produce/consume
or usestatic_assert
for better error messages.Async
ports.TODO
Async
/Sync
structs.ConsumablePortRange
logic, andProducablePortRange
.