Skip to content

add Stim REPEAT support for scf.For loops#736

Open
johnzl-777 wants to merge 34 commits intomainfrom
john/complete-repeat-support
Open

add Stim REPEAT support for scf.For loops#736
johnzl-777 wants to merge 34 commits intomainfrom
john/complete-repeat-support

Conversation

@johnzl-777
Copy link
Copy Markdown
Contributor

@johnzl-777 johnzl-777 commented Mar 26, 2026

The second part to #723 , finally accomplishes the desired REPEAT support behavior that has been so elusive.

Some rough edges I'm not too happy with:

  • Note that UnusedYield rewrite rule is too aggressive kirin#577 causes problems when you want to express more complicated scf.For patterns like the color code memory experiment.
  • Adding measurements to a list that was made via squin.measure is fine, but declaring an empty list (even with explicit typing) falls apart. That's why you might see this weird measure(qalloc(0)) pattern.
  • I had to override the default constprop behavior which gives a huge performance boost but the way that override occurs does not seem idiomatic to me.
    • I think I figured out a more idiomatic way, but still feels funky to me

johnzl-777 and others added 6 commits March 23, 2026 23:25
Convert `for _ in range(N)` patterns to Stim `REPEAT N { ... }` blocks
when the loop body is iteration-invariant, avoiding expensive unrolling.

Key components:
- stim_cf.Repeat dialect op with emission support
- Selective Flatten that preserves REPEAT-eligible outermost loops
- MeasurementIDAnalysis scf.For handler using lattice joins for invariance
- ScfForToRepeat rewrite with unresolved record idx safety check
- HintConstInLoopBodies for propagating hints/types into loop bodies
- RemoveDeadNonStimStatements for cleanup

Passing: gates-only, rep codes, feedforward, color code, accumulators,
nested inner loops. 2 xfail: surface code memory and nested unroll
(post-loop measurement ref analysis needs further work).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 26, 2026

☂️ Python Coverage

current status: ✅

Overall Coverage

Lines Covered Coverage Threshold Status
12574 11245 89% 0% 🟢

New Files

File Coverage Status
src/bloqade/stim/dialects/stim_cf/init.py 100% 🟢
src/bloqade/stim/dialects/stim_cf/_dialect.py 100% 🟢
src/bloqade/stim/dialects/stim_cf/emit.py 100% 🟢
src/bloqade/stim/dialects/stim_cf/stmts.py 100% 🟢
src/bloqade/stim/passes/cleanup_non_stim.py 94% 🟢
src/bloqade/stim/passes/constprop_override.py 88% 🟢
src/bloqade/stim/passes/hint_const_in_loops.py 94% 🟢
src/bloqade/stim/passes/repeat_eligible.py 88% 🟢
src/bloqade/stim/rewrite/scf_for_to_repeat.py 97% 🟢
TOTAL 96% 🟢

Modified Files

File Coverage Status
src/bloqade/analysis/measure_id/impls.py 93% 🟢
src/bloqade/analysis/measure_id/lattice.py 90% 🟢
src/bloqade/squin/rewrite/_init_.py 100% 🟢
src/bloqade/stim/analysis/from_squin_validation/analysis.py 100% 🟢
src/bloqade/stim/dialects/_init_.py 100% 🟢
src/bloqade/stim/groups.py 93% 🟢
src/bloqade/stim/passes/flatten.py 100% 🟢
src/bloqade/stim/passes/squin_to_stim.py 100% 🟢
src/bloqade/stim/rewrite/_init_.py 100% 🟢
src/bloqade/stim/rewrite/ifs_to_stim_partial.py 92% 🟢
src/bloqade/stim/rewrite/qubit_to_stim.py 86% 🟢
src/bloqade/stim/rewrite/squin_measure.py 94% 🟢
src/bloqade/stim/rewrite/squin_noise.py 93% 🟢
src/bloqade/stim/rewrite/util.py 94% 🟢
TOTAL 95% 🟢

updated for commit: 86c337b by action🐍

@johnzl-777 johnzl-777 marked this pull request as ready for review March 30, 2026 13:16
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR completes REPEAT support by preserving REPEAT-eligible scf.For loops through the Squin→Stim pipeline, then converting them into a new stim.cf.Repeat IR node that emits Stim REPEAT { ... } blocks. It also refactors address handling to pass AddressAnalysis results directly into rewrite rules (removing the prior “wrap hints” mechanism) and extends measurement ID analysis to behave correctly with preserved loops.

Changes:

  • Add stim.cf.Repeat dialect + emitter and a ScfForToRepeat rewrite to lower eligible scf.For loops into Stim REPEAT blocks.
  • Update the Squin→Stim pipeline to preserve outer REPEAT-eligible loops, propagate const hints/types inside those loops, and support loop-aware measurement ID analysis.
  • Expand/adjust Stim golden tests and reference programs to validate REPEAT emission across multiple patterns (feedforward, accumulators, nested loops).

Reviewed changes

Copilot reviewed 42 out of 42 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
test/stim/passes/test_squin_noise_to_stim.py Updates tests to pass address_analysis directly into SquinNoiseToStim (no more address wrapping).
test/stim/passes/test_scf_for_to_repeat.py New end-to-end tests validating scf.For → Stim REPEAT emission across multiple loop patterns.
test/stim/passes/test_record_idx_helper.py Updates helper tests to use the new IfToStimPartial(address_analysis=...) API.
test/stim/passes/stim_reference_programs/scf_for/test_nested_unroll.stim New golden Stim output for nested loop unroll + outer REPEAT behavior.
test/stim/passes/stim_reference_programs/scf_for/surface_code_memory.stim New golden Stim output for a larger REPEAT-based surface-code style loop.
test/stim/passes/stim_reference_programs/scf_for/repeat_on_gates_only.stim New golden Stim output for gate-only loops lowered to REPEAT.
test/stim/passes/stim_reference_programs/scf_for/rep_code_structure.stim New golden Stim output for repetition-code structure lowered to REPEAT.
test/stim/passes/stim_reference_programs/scf_for/rep_code.stim New golden Stim output for a full repetition-code style kernel.
test/stim/passes/stim_reference_programs/scf_for/feedforward_inside_loop.stim New golden Stim output validating feedforward lowering inside REPEAT loops.
test/stim/passes/stim_reference_programs/scf_for/color_code_init.stim New golden Stim output validating REPEAT emission in a color-code init pattern.
test/stim/passes/stim_reference_programs/scf_for/accumulator_prepend_initialized_all_iters.stim New golden Stim output validating prepend accumulator semantics across all iterations.
test/stim/passes/stim_reference_programs/scf_for/accumulator_prepend_initialized.stim New golden Stim output validating prepend accumulator semantics.
test/stim/passes/stim_reference_programs/scf_for/accumulator_prepend_empty_init_all_iters.stim New golden Stim output validating prepend accumulator with empty init across all iterations.
test/stim/passes/stim_reference_programs/scf_for/accumulator_prepend_empty_init.stim New golden Stim output validating prepend accumulator with empty init.
test/stim/passes/stim_reference_programs/scf_for/accumulator_append_initialized_all_iters.stim New golden Stim output validating append accumulator semantics across all iterations.
test/stim/passes/stim_reference_programs/scf_for/accumulator_append_initialized.stim New golden Stim output validating append accumulator semantics.
test/stim/passes/stim_reference_programs/scf_for/accumulator_append_empty_init_all_iters.stim New golden Stim output validating append accumulator with empty init across all iterations.
test/stim/passes/stim_reference_programs/scf_for/accumulator_append_empty_init.stim New golden Stim output validating append accumulator with empty init.
test/stim/passes/stim_reference_programs/annotate/nested_for.stim Updates annotate golden to emit REPEAT rather than duplicated blocks.
src/bloqade/stim/rewrite/util.py Switches qubit index insertion helper to consume Address directly (no AddressAttribute).
src/bloqade/stim/rewrite/squin_noise.py Refactors noise rewrite to use passed-in address_analysis instead of wrapped hints.
src/bloqade/stim/rewrite/squin_measure.py Refactors measurement rewrite to use passed-in address_analysis instead of wrapped hints.
src/bloqade/stim/rewrite/scf_for_to_repeat.py New rewrite lowering eligible scf.For loops to stim.cf.Repeat.
src/bloqade/stim/rewrite/qubit_to_stim.py Refactors gate/reset rewrites to use passed-in address_analysis instead of wrapped hints.
src/bloqade/stim/rewrite/ifs_to_stim_partial.py Refactors IfElse partial lowering to use passed-in address_analysis.
src/bloqade/stim/rewrite/init.py Exports ScfForToRepeat.
src/bloqade/stim/passes/squin_to_stim.py Reorders/extends pipeline: preserve loops, hint const in loops, add REPEAT lowering + cleanup.
src/bloqade/stim/passes/repeat_eligible.py New helper for determining REPEAT eligibility and extracting constant loop ranges.
src/bloqade/stim/passes/hint_const_in_loops.py New pass to propagate const hints/types within preserved loop bodies.
src/bloqade/stim/passes/flatten.py Updates flattening/unrolling strategy to preserve outer REPEAT-eligible loops.
src/bloqade/stim/passes/constprop_override.py New scf.For constprop override with early termination to avoid O(N) analysis time.
src/bloqade/stim/passes/cleanup_non_stim.py New cleanup rewrite to delete dead non-stim statements after conversion.
src/bloqade/stim/groups.py Adds stim_cf dialect to the Stim dialect group.
src/bloqade/stim/dialects/stim_cf/stmts.py New stim.cf.Repeat statement definition.
src/bloqade/stim/dialects/stim_cf/emit.py Adds Stim emitter support for RepeatREPEAT { ... }.
src/bloqade/stim/dialects/stim_cf/_dialect.py Defines the stim.cf dialect.
src/bloqade/stim/dialects/stim_cf/init.py Exposes stim.cf dialect components.
src/bloqade/stim/dialects/init.py Includes stim_cf in the dialect export list.
src/bloqade/stim/analysis/from_squin_validation/analysis.py Extends validation to inspect func.Invoke callees for unsupported predicates.
src/bloqade/squin/rewrite/wrap_analysis.py Removes the prior address-wrapping rewrite mechanism.
src/bloqade/squin/rewrite/init.py Removes exports of the deleted wrap-analysis helpers.
src/bloqade/analysis/measure_id/impls.py Adds empty-list neutral concat handling and a loop-aware scf.For analysis implementation.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@johnzl-777 johnzl-777 requested review from david-pl and weinbe58 March 30, 2026 14:02
Copy link
Copy Markdown
Collaborator

@david-pl david-pl left a comment

Choose a reason for hiding this comment

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

Overall, looks very good! Just some minor comments and two slightly larger things:

  • I think the count on the Repeat statement should be an info.attribute. That might make a few things simpler.
  • I'm a bit worried about the pass that deletes statements from other dialects left at the end of the pass.

@johnzl-777 johnzl-777 requested a review from david-pl April 3, 2026 18:27
@Roger-luo Roger-luo added area: STIM Area: STIM emulator integration, traces, and representations. category: feature Category: new feature or feature request. labels Apr 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: STIM Area: STIM emulator integration, traces, and representations. category: feature Category: new feature or feature request.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants