qiskit
qiskit copied to clipboard
Set-up a most basic circuit equivalence checker
Summary
The first pull request in the list: https://github.com/Qiskit/qiskit-terra/issues/5692#issuecomment-766782160
Details and comments
Still in progress, to be ready requires:
- [x] Testing.
- [x] Documentation.
- [x] Style and lint.
What can be done to perform CI testing to the Aer option of the equivalence checker? I see four options:
- Skip tests that import Aer (as far as I see, this is what the VQE tests do with
AerPauliExpectation
) - code will remain untested for many platforms. - Move the equivalence checker to another repository:
qiskit-aer
, or its own repository - cumbersome. - Copy the very same tests to
qiskit-aer
- code duplication. - Make Terra's CI install Aer and run these tests properly - this is my preferred option. Since the same issue arises also with
AerPauliExpectation
, we conclude that this is a general problem that requires a general solution.
Following the discussion in #5783, I'll modify the tests to skip Aer if not installed.
This is ready for review. See the context in https://github.com/Qiskit/qiskit-terra/issues/5692#issuecomment-773188012. By the way, we may consider to replace the term "equivalence" with something else, to avoid confusion with the equivalence library.
Maybe i can add to this discussion from an external point of view. I was not quite sure whether to post this here or at the corresponding issue, so feel free to move it there.
As you might know by now, our group at JKU Linz is actively developing a tool for quantum circuit equivalence checking (https://github.com/iic-jku/qcec) and we are very eagerly following all your developments. The way we see things currently is in line with what @ajavadia and @chriseclectic propose in their comments above:
In our point of view, the main application looks something like "I give you two circuits and you tell me how they are related". There is one verify
function that takes two circuits and a desired method as input, applies the chosen method and returns the type of equivalence (non-equivalent, unitary-equivalent, equivalent up to global phase, etc.).
Currently, we differentiate between two types of methods:
- functional equivalence checking: the (unitary) functionality of both circuits is compared.
- simulation-based equivalence checking: both circuits are simulated with various kinds of input stimuli and the fidelity of the resulting states is computed.
Both techniques have several degrees of freedom which can be somewhat configured as options when calling the verify
function, e.g., application scheme during functional equivalence checking or type of stimuli used in simulations.
Under the hood, each method has its own class that is derived from some common base class EquivalenceChecker
. The Python bindings then expose this functionality through a unified interface (i.e. verify
function).
Any discussion on this may also help the development of our tool and ease the process of trying to incorporate it into Qiskit.
I think it would be nice if printing the result would immediately show whether the circuits are equivalent, without having to call .equivalent
on top. This could e.g. be done by overriding the __str__
method on the result object so we get:
result = checker.run(circuit1, circuit2)
print(result) # True or False
print(type(result)) # EquivalenceCheckerResult
Secondly, if we end up using classes, it would probably sense to locate this in the algorithms since they have the exact same structure:
algo = Algorithm(algorithm settings) # takes things like backend and settings, like here
result = algo.run(problem input) # returns special result type, like here
I think it would be nice if printing the result would immediately show whether the circuits are equivalent, without having to call
.equivalent
on top.
maybe via EquivalenceCheckerResult.__bool__
?
Secondly, if we end up using classes, it would probably sense to locate this in the algorithms since they have the exact same structure:
I strongly agree with this.
Thanks @Cryoris and @1ucian0, these are good points
@chriseclectic @ajavadia @1ucian0 @burgholzer Ready for a new cycle of review. Note that some of the previous review comments were not addressed in the code but in answers in #5692.
I'm curious: why trap raise
at all? Is it saving the user work to have to check a boolean for failure vs letting them do their own trapping?
@ecpeterson Which raise
are you referring to?
I mean the unknown raise that's trapped here: https://github.com/Qiskit/qiskit-terra/pull/5700/files#diff-0bd9ce629c038afb2f5894b7da1497a43a7121518abd96f859dbd4a309b0e376R136 .
@ecpeterson Essentially yes (save the user work etc.). The idea is that the equivalence checker doesn't crash but always return a result. If something went wrong, this will be reflected in the result.
does this PR closes https://github.com/Qiskit/qiskit-terra/issues/761 ?
Have there been recent updates about this PR or circuit equivalence in general?
Have there been recent updates about this PR or circuit equivalence in general?
Please excuse the shameless plug here:
If you are interested in an easy-to-use and scalable equivalence checker that works out of the box with Qiskit, have a look at MQT QCEC (https://github.com/cda-tum/mqt-qcec, pip install mqt.qcec
).
Verifying the equivalence of two Qiskit circuits is as easy as
from mqt.qcec import verify
res = verify(qc1, qc2)
Note that the tool uses dedicated data structures (decision diagrams and ZX calculus) plus dedicated verification schemes to make the verification way more scalable than the simple construction and comparison of the circuits' unitaries. More information can be found in the documentation at https://mqt.rtfd.io/projects/qcec