Skip to content

feat: multi-output task support#635

Merged
gbin merged 6 commits into
masterfrom
yang/feat/multi_output
Jan 12, 2026
Merged

feat: multi-output task support#635
gbin merged 6 commits into
masterfrom
yang/feat/multi_output

Conversation

@makeecat

@makeecat makeecat commented Jan 12, 2026

Copy link
Copy Markdown
Collaborator

Summary

Implemented multi-output task support end-to-end (runtime plan, codegen, monitoring topology, sim support) with deterministic port ordering and backward compatibility

Related Issue: #383

Detail Changes

  • Extended output_msg! to return tuple packs and updated runtime plan/output-port mapping logic for multi-output routing (core/cu29_runtime/src/cutask.rs, core/cu29_runtime/src/curuntime.rs).
  • Updated monitoring topology and render topology to expose ordered output ports and keep metadata stable (core/cu29_runtime/src/monitoring.rs, core/cu29_runtime/src/config.rs).
  • Reworked derive codegen for output packs, getters, sim support, stamping/clearing, and bridge routing (core/cu29_derive/src/lib.rs).
  • Added multi-output example app and README documentation, plus workspace membership updates (examples/cu_multi_output, Cargo.toml, README.md).
  • Builds inputs from incoming edge IDs and sorts by edge id so a task can receive multiple outputs from the same source without type-order mismatches
  • Adds a TOV on the first output, includes the extra sinks/relay task, and updates LoopbackTask to a single-input pass-through.

@makeecat makeecat self-assigned this Jan 12, 2026
@makeecat makeecat added the enhancement New feature or request label Jan 12, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: cd0d183fa5

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread core/cu29_runtime/src/curuntime.rs Outdated
Comment on lines +702 to +705
let msg_type =
graph.get_connection_msg_type(pid, id).unwrap_or_else(|| {
panic!("Missing connection type from node {pid} to {id}")
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Use per-edge msg type for multi-output inputs

This lookup uses get_connection_msg_type(pid, id), which in CuGraph is backed by find_edge and only returns the first edge between the two nodes. If a multi-output task connects multiple msg types to the same downstream task (two cnx entries with the same src/dst but different msg), every input from that parent will be tagged with the first msg type and src_port. That makes the generated input tuple pull the wrong port (or duplicate the first type), so the build fails or the runtime misroutes the second connection. This needs to be resolved per edge, not per node pair.

Useful? React with 👍 / 👎.

@makeecat makeecat requested a review from gbin January 12, 2026 15:18
Comment thread README.md Outdated
- Port ordering follows the first appearance order in `cnx` for that source task.
- Fan-out with the same `msg` type shares the same output port.

Limitation: A task cannot expose two distinct output ports with the same payload type.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Giving it some thoughts but I think it might be reasonable as a quirk. The alternative would be named outputs like the bridges but this makes this super complicated and wonky on the backward compat.

@gbin

gbin commented Jan 12, 2026

Copy link
Copy Markdown
Collaborator
image just dag still works :)

Comment thread README.md Outdated
}

fn process(&mut self, _clock: &RobotClock, output: &mut Self::Output<'_>) -> CuResult<()> {
output.0.set_payload(42);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe add a TOV on one of the output as they are independent

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done in 1265de4

@@ -0,0 +1,11 @@
(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we do like the bridge testing here and add a bunch of missions with some variation in the routing like here https://github.com/copper-project/copper-rs/blob/master/examples/cu_bridge_test/copperconfig.ron because there are a lot of corner cases:

what if one task gets both inputs? if an output is left open? Is a loopback error is correctly spotted?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Both inputs: covered by the both_inputs mission in examples/cu_multi_output/copperconfig.ron and
    tasks::BothSink in examples/cu_multi_output/src/main.rs.
  • Output left open: covered by the open_output mission in examples/cu_multi_output/copperconfig.ron using
    tasks::DropBoolSink in examples/cu_multi_output/src/main.rs to intentionally drop one output.
  • Loopback error: validated via a dedicated config+test (core/cu29_runtime/tests/loopback_config.ron, core/ cu29_runtime/tests/loopback.rs) and explicit detection in core/cu29_runtime/src/curuntime.rs. The example
    config no longer includes a self-loop because it breaks compile-time planning.

Comment thread core/cu29_runtime/src/config.rs Outdated
Comment thread core/cu29_runtime/src/monitoring.rs Outdated
…an receive multiple outputs from the same source without type-order mismatches; adds a TOV on the first output, includes the extra sinks/relay task, and updates LoopbackTask to a single-input pass-through; adds the missions/routing variants and removes the self-loop to keep the graph acyclic
@makeecat makeecat requested a review from gbin January 12, 2026 18:28

@gbin gbin left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's merge this

@gbin gbin merged commit 80c9434 into master Jan 12, 2026
23 checks passed
@gbin gbin deleted the yang/feat/multi_output branch January 12, 2026 19:37
@makeecat makeecat linked an issue Jan 22, 2026 that may be closed by this pull request
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement multiple outputs per task after all

2 participants