qiskit icon indicating copy to clipboard operation
qiskit copied to clipboard

Set-up a most basic circuit equivalence checker

Open yaelbh opened this issue 4 years ago • 14 comments

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.

yaelbh avatar Jan 25 '21 15:01 yaelbh

What can be done to perform CI testing to the Aer option of the equivalence checker? I see four options:

  1. 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.
  2. Move the equivalence checker to another repository: qiskit-aer, or its own repository - cumbersome.
  3. Copy the very same tests to qiskit-aer - code duplication.
  4. 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.

yaelbh avatar Feb 04 '21 11:02 yaelbh

Following the discussion in #5783, I'll modify the tests to skip Aer if not installed.

yaelbh avatar Feb 04 '21 13:02 yaelbh

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.

yaelbh avatar Feb 04 '21 20:02 yaelbh

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.

burgholzer avatar Feb 10 '21 16:02 burgholzer

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

Cryoris avatar Feb 18 '21 15:02 Cryoris

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.

1ucian0 avatar Feb 19 '21 10:02 1ucian0

Thanks @Cryoris and @1ucian0, these are good points

yaelbh avatar Feb 21 '21 08:02 yaelbh

@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.

yaelbh avatar Jul 26 '21 07:07 yaelbh

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 avatar Sep 21 '21 18:09 ecpeterson

@ecpeterson Which raise are you referring to?

yaelbh avatar Sep 29 '21 14:09 yaelbh

I mean the unknown raise that's trapped here: https://github.com/Qiskit/qiskit-terra/pull/5700/files#diff-0bd9ce629c038afb2f5894b7da1497a43a7121518abd96f859dbd4a309b0e376R136 .

ecpeterson avatar Sep 29 '21 16:09 ecpeterson

@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.

yaelbh avatar Sep 30 '21 05:09 yaelbh

does this PR closes https://github.com/Qiskit/qiskit-terra/issues/761 ?

1ucian0 avatar Oct 03 '21 08:10 1ucian0

Have there been recent updates about this PR or circuit equivalence in general?

edoaltamura avatar Feb 26 '24 15:02 edoaltamura

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

burgholzer avatar Mar 05 '24 17:03 burgholzer