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



Reply via email to