mirror of
https://github.com/jafioti/luminal.git
synced 2026-06-01 21:49:47 +09:00
Skip orphan LoopOutputSelect when its LoopOutput is missing
Companion defensive fix to16de9638. `output_body_producer` is keyed by stream_id and populated from `outputs` (LoopOutput nodes). The post-loop wiring then indexed `output_body_producer[&stream_id]` for every LoopOutputSelect, which panics with "no entry found for key" if extraction lands a LoopOutputSelect whose corresponding LoopOutput isn't in the LLIR (e.g. a genome that picked a non-LoopOutput representative for that stream's eclass). Skip the orphan select rather than panicking. The select node stays un-substituted, so the post-loop consumer's edge falls through to the select itself; the select gets removed with the other markers at the end of unroll. The consumer's edge will dangle, but that's a separate concern from the unroll-mechanism panic this prevents. Together with16de9638, this closes the two `[&key]` index sites in `unroll_loops_in_llir` that can land on a missing key when egglog extraction produces a structurally unusual LLIR. Both sites now gracefully fall through with a defensible semantic (use the body producer / select node directly), so the unroll mechanism never panics on extraction-shape variation. cuda_lite + python CUDA suites still pass. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
11
src/graph.rs
11
src/graph.rs
@@ -1969,9 +1969,16 @@ pub fn unroll_loops_in_llir(llir: &mut LLIRGraph) {
|
||||
marker_post_sub.insert(end_node, sub);
|
||||
}
|
||||
// Each LoopOutputSelect(stream, iter) routes to iter's clone of that
|
||||
// stream's body producer.
|
||||
// stream's body producer. Skip if extraction produced an orphan select
|
||||
// whose stream has no LoopOutput — leaving it un-substituted lets the
|
||||
// post-loop edge fall through to the select node itself, which gets
|
||||
// removed with the rest of the loop markers (the consumer's edge then
|
||||
// points to a removed node, but that's a separate concern from the
|
||||
// unroll mechanism's correctness invariants here).
|
||||
for (&select_node, &(stream_id, iter)) in &output_selects {
|
||||
let body_producer = output_body_producer[&stream_id];
|
||||
let Some(&body_producer) = output_body_producer.get(&stream_id) else {
|
||||
continue;
|
||||
};
|
||||
let sub = clone_map[iter]
|
||||
.get(&body_producer)
|
||||
.copied()
|
||||
|
||||
Reference in New Issue
Block a user