Hi Wael!
Great to see you here again :)!
I'm honestly not too deep into the implementation side of the custom buffers, but reading
your email, I'd say, yes, that's a bug; I'd hence love to have that as an issue on our
issue tracker, unless you directly have a fix (which you seem to do).
I could technically see why in the presence of different accelerators and if our dynamic
flowgraph reconfiguration worked flawlessly, you might want to exchange buffers multiple
times – but not in practice. So, I'd say, go for it. Worst case, someone says "no!! You
can't do that, we need…", then you rightfully say "But we need …", and then (and only
then, I'd propose) we add a configuration option to switch between behaviours.
In the meantime, I'm trying to get the right eyes on this. Thank you so much!
Best regards,
Marcus
On 2026-01-26 8:08 PM, Wael Farah wrote:
Hi all,
I ran into something that looks like a bug in GNU Radio runtime related to custom buffers
and fanout, and I wanted to sanity-check it with the list before opening an issue or PR.
The scenario is roughly:
*
An upstream block with a default (host) output buffer
*
That output fans out to multiple downstream blocks
*
Each downstream block requires a custom buffer (e.g., CUDA buffers)
In this case, it looks like |flat_flowgraph::connect_block_inputs()| <https://github.com/
gnuradio/gnuradio/blob/ec7a3239645162ffea1925e6f1e6e62bf1349d03/gnuradio-runtime/lib/
flat_flowgraph.cc%23L160> ends up calling |replace_buffer()| <https://github.com/gnuradio/
gnuradio/blob/ec7a3239645162ffea1925e6f1e6e62bf1349d03/gnuradio-runtime/lib/
flat_flowgraph.cc%23L220> once per downstream edge. This results in multiple custom
buffers being allocated for the same output port, but only the last one actually remains
connected to the upstream block. The earlier buffers become orphaned, and the
corresponding downstream blocks stall waiting for data that never arrives.
From what I can tell, the root cause is that the buffer type comparison uses the upstream
block’s |output_signature()|, which is static and doesn’t reflect that |replace_buffer()|
may already have been called by a previous fanout edge. So every subsequent edge still
thinks it’s dealing with a default buffer and tries to replace it again.
I put together a small fix that:
*
Checks whether an output buffer already exists
*
Compares the /actual buffer type/ against the signature
*
Reuses the existing custom buffer if it was already replaced by an earlier
fanout edge
With this change, all downstream custom-buffer blocks share the same buffer created by the
first edge, and the flowgraph no longer hangs. I’ve tested this with flowgraphs where a
host block (e.g., |analog.sig_source|) fans out to multiple custom blocks; before the fix
it would hang, after it works as expected.
I’m currently seeing this on GNURadio _v.3.10.12.0_ release, but I also checked the
maint-3.10 branch where the same behavior still appears to be present.
Before I go any further:
Does this match others’ understanding of how buffer replacement is supposed to work in
fanout scenarios? Is there a reason GNU Radio intentionally allows multiple |
replace_buffer()| calls on the same output port?
Happy to open an issue or PR if this is indeed unintended behavior.
Thanks!
Wael