-
Notifications
You must be signed in to change notification settings - Fork 1
No-cloning validation analysis #607
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
☂️ Python Coverage
Overall Coverage
New Files
Modified FilesNo covered modified files...
|
…n. Simplified error handling of Scf.Ifelse
| self, frame: ForwardFrame[QubitValidation], node: ir.Statement | ||
| ) -> tuple[QubitValidation, ...]: | ||
| """Check for qubit usage violations and return lattice values.""" | ||
| if not isinstance(node, func.Invoke): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just some questions for my understanding:
Why is this not a method impl for func.Invoke?
Also, this seems to be assuming that all func.Invoke are stdlib functions. What if a user calls their own subroutine? If I understand correctly, this will result in an error for that if the user-defined function has any qubit arguments whose addresses overlap. Is that correct and expected?
Just to be clear: I don't really see a (valid) use-case when a user would do that, but then again it's very simple to write a kernel function that is perfectly valid even when called with overlapping qubit arguments.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Currently, the analysis is able to distinguish between safe user-defined functions and unsafe ones.
e.g. foo is called with overlapping qubit 1 but it's implementation is safe:
@squin.kernel
def kernel(a: int):
q = squin.qalloc(4)
squin.cx(q[0], q[0]) # definite cloning error
def foo(q1, q2):
squin.cx(q1,q[3])
foo(q[1], q[1]) This is the reported error:
Validation failed with 1 violation(s):
No-Cloning Validation:
- Qubit[0] cloned at CX gate.
File "/Users/Documents/kirin-workspace/bloqade-circuit/test/analysis/validation/test_compose_validation.py", line 12, col 4
│ def kernel(a: int):
│ q = squin.qalloc(4)
12│ squin.cx(q[0], q[0]) # definite cloning error
│ ^^^^^^^^^^^^^^^^^^^^
│ def foo(q1, q2):
│ squin.cx(q1,q[3])
│ foo(q[1], q[1])
(1 sub-exception)And here is an unsafe user defined function:
@squin.kernel
def kernel(a: int):
q = squin.qalloc(4)
squin.cx(q[0], q[0]) # definite cloning error
def foo(q1, q2):
squin.cx(q1,q2)
foo(q[1], q[1]) The report:
Validation failed with 2 violation(s):
No-Cloning Validation:
- Qubit[0] cloned at CX gate.
File "/Users/Documents/kirin-workspace/bloqade-circuit/test/analysis/validation/test_compose_validation.py", line 12, col 4
│ def bad_kernel(a: int):
│ q = squin.qalloc(4)
12│ squin.cx(q[0], q[0]) # definite cloning error
│ ^^^^^^^^^^^^^^^^^^^^
│ def foo(q1, q2):
│ squin.cx(q1,q2)
│ foo(q[1], q[1])
- Qubit[1] cloned at FOO gate.
File "/Users/Documents/kirin-workspace/bloqade-circuit/test/analysis/validation/test_compose_validation.py", line 15, col 4
│ def foo(q1, q2):
│ squin.cx(q1,q2)
15│ foo(q[1], q[1])
│ ^^^
(2 sub-exceptions)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Granted this error message might be a little misleading: "Qubit[1] cloned at FOO gate."
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I understand, but what I mean is this: if I change foo in the above to e.g.
def foo(q1, q2):
squin.x(q1)
squin.x(q2)then calling foo(q[0], q[0]) is fine since there's no overlapping operation. Still, this will be reported as an error.
Again, I don't see a valid use case for this (why would you want to write something like the above?), but I just wanted to make sure this behavior was expected.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh I see what you mean now. No, that behavior is not expected.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess we could introduce some heuristic to define what function is a stdlib function and only then apply the analysis. @Roger-luo is there a way to do this via modules in kirin as of yet?
no-cloning validation analysis with a validation framework to compose multiple validation analyses. Implemented using a lattice for tracking definite and potential cloning violations. Addresses this issue.
For example this kernel has 1 definite and 1 potential violation of the no-cloning theorem.
IR printing:
Validation reporting:
No-Cloning Validation Analysis Implementation
NoCloningValidationclass inanalysis.pythat tracks qubit usage and detects cloning violations, distinguishing between definite (Must) and potential (May) errors.QubitValidationlattice inlattice.pywith four states (Bottom, Must, May, Top), supporting precise tracking and merging of violation information.Testing
test_no_cloning.pyto verify detection of cloning violations in various scenarios, including various control gates, conditionals, and parallel gates,.Composite Validation Framework Usage: