Skip to content

Stim REPEAT support #630

Closed
johnzl-777 wants to merge 77 commits intomainfrom
john/repeat-support
Closed

Stim REPEAT support #630
johnzl-777 wants to merge 77 commits intomainfrom
john/repeat-support

Conversation

@johnzl-777
Copy link
Contributor

@johnzl-777 johnzl-777 commented Nov 20, 2025

This PR enables scf.For statements with the proper format to be represented as a Stim REPEAT statement. There can be no dependence on the iterator variable and the number of iterations must be known at the time of the rewrite.

Per feedback I received from the team presentation and some additional help from Phillip I’ve been able to eliminate the dependency on CSE ordering. CSE can now be invoked at any time in the pass with no impact on the correctness of the resulting program.

That being said, there are definitely areas I’d like to work on to expand the the supported semantics for QEC researchers.

  1. There is a limitation on how far back you can index measurements that have occurred. This seems fine for something like a surface code memory experiment (which I have as a unit test) but becomes problematic for something like color code memory experiments where, in initialization, you have two sets of measurements that happen on the same qubits and then outside of the loop, you declare a time-based detector. That detector needs to access measurements that exceed the number of qubits being measured.
REPEAT 2 {
	MR 0 1 2
}
DETECTOR rec[-3] rec[-6] # you wouldn't be able to access this

I imagine if the number of iterations is propagated and perhaps some mechanism to accumulate measurements (say, py.binop.add with ilists) is carefully relaxed on invariance checking this could be supportable.

  1. Potentially premature optimization but it might be more space efficient to have some lattice element that represents a RANGE of record indices. GetItem naturally complicates things but it would encourage a “lazier” growth of the GlobalRecordState than the current structure.

@johnzl-777 johnzl-777 marked this pull request as ready for review February 5, 2026 13:46
Copy link
Member

@weinbe58 weinbe58 left a comment

Choose a reason for hiding this comment

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

I have some minor changes but overall it looks good! great job!

Note that it looks like this PR also closes #671

cc: @rafaelha

Comment on lines +31 to +45
new_block = ir.Block()
for stmt in node.body.blocks[0].stmts:
if isinstance(stmt, scf.stmts.Yield):
continue
stmt.detach()
new_block.stmts.append(stmt)

new_region = ir.Region(new_block)

# Create the REPEAT statement
repeat_stmt = cf.stmts.REPEAT(
count=const_repeat_num.result,
body=new_region,
)
node.replace_by(repeat_stmt)
Copy link
Member

Choose a reason for hiding this comment

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

you should not need to copy the statements over you can first check that all uses of the body's block arguments are the Yield statement, if not you can give up on the rewrite, otherwise you can delete the yield statement then delete the block arguments in-place safely after.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Wait, I don't think this can be the case though there's definitely uses of the block args beyond just the resulting yield.

The simplest counter example I can give is the repetition code structure test in test_scf_for_to_repeat.py, your block args get touched by other statements in the body (such as measure) and THEN get yielded.

@johnzl-777 johnzl-777 marked this pull request as draft February 9, 2026 15:53
@johnzl-777
Copy link
Contributor Author

Putting this in draft mode (again), it should be possible to partially resolve one of the limitations I mentioned in terms of the restriction on accessing much older measurements that were created in a loop or before the loop because the number of iterations isn't really factored in

@johnzl-777
Copy link
Contributor Author

johnzl-777 commented Mar 6, 2026

This will now be superseded by #723 but things like tests and constant handling will probably be carried over.

When can their glory fade?
O the wild charge they made!
All the world wonder’d.
Honor the charge they made!
Honor the Light Brigade,
Noble six hundred!

  • from The Charge of the Light Brigade by Alfred Tennyson

@johnzl-777 johnzl-777 closed this Mar 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants