-
Notifications
You must be signed in to change notification settings - Fork 0
Description
Copied from munich-quantum-toolkit/core #923
What's the problem this feature will solve?
It's been a while since Qiskit has introduced "Classical feedforward and control flow", which matches OpenQASM 3's "Looping and branching".
Within the MQT, support for these dynamic circuit primitives is still limited.
We support mid-circuit measurements, reset operations, as well as a limited set of classically-controlled operations, which roughly match the capabilities of OpenQASM 2's if statement (see https://arxiv.org/abs/1707.03429v2). See also the MQT Core IR quickstart guide.
The goal of this issue is to add proper support for Qiskit's IfElseOp to the MQT Core IR so that Qiskit circuits using such instructions can be imported into the MQT, used within it, as well as exported back to Qiskit.
This requires
- adapting the MQT Core IR to be capable of properly representing an
if (...) { ... } else { ... }construct - adapting the Qiskit import and export routines to handle the newly-supported operation
- adapting the OpenQASM3 parser and exporter to handle the newly supported operation.
- refactoring any dependant code to use the new functionality.
Describe the solution you'd like
Any solution to this issue may take inspiration from the way Qiskit is handling these operations. Specifically, the ControlFlowOp class as well as the IfElseOp class.
It probably makes sense to replicate a similar operation hierarchy in MQT Core.
So instead of
Operation --> ClassicControlledOperation
it is probably reasonable to refactor this to
Operation --> ControlFlowOperation --> IfElseOperation
For the purpose of this PR, it is fine if the IfElseOperation only supports conditions in the form they are currently supported throughout MQT Core, that is
- either a full classical register is compared to an integer, or
- a single bit is compared against a Boolean value.
Where to find the respective code?
The classically-controlled operations are currently defined here: https://github.com/munich-quantum-toolkit/core/blob/main/include/mqt-core/ir/operations/ClassicControlledOperation.hpp and contain the following members
https://github.com/munich-quantum-toolkit/core/blob/d88d1f091b1257d8b7b4ae48521f19ed60602b76/include/mqt-core/ir/operations/ClassicControlledOperation.hpp#L132-L136
They are exposed as utility functions in the QuantumComputation class
https://github.com/munich-quantum-toolkit/core/blob/d88d1f091b1257d8b7b4ae48521f19ed60602b76/include/mqt-core/ir/QuantumComputation.hpp#L336-L362
In a similar fashion, they are exposed to Python
- https://github.com/munich-quantum-toolkit/core/blob/d88d1f091b1257d8b7b4ae48521f19ed60602b76/src/python/ir/operations/register_classic_controlled_operation.cpp#L22-L81
- https://github.com/munich-quantum-toolkit/core/blob/d88d1f091b1257d8b7b4ae48521f19ed60602b76/src/python/ir/register_quantum_computation.cpp#L421-L473
Neither the Qiskit import nor the export handles that type of gate yet:
- https://github.com/munich-quantum-toolkit/core/blob/d88d1f091b1257d8b7b4ae48521f19ed60602b76/src/mqt/core/plugins/qiskit/qiskit_to_mqt.py#L113-L171
- https://github.com/munich-quantum-toolkit/core/blob/d88d1f091b1257d8b7b4ae48521f19ed60602b76/src/mqt/core/plugins/qiskit/mqt_to_qiskit.py#L267-L269
The OpenQASM 3 importer breaks down if-else statements into two separate ClassicControlledOperations: https://github.com/munich-quantum-toolkit/core/blob/d88d1f091b1257d8b7b4ae48521f19ed60602b76/src/qasm3/Importer.cpp#L892-L929
The corresponding exporter works for the limited scope of the ClassicControlledOperation: https://github.com/munich-quantum-toolkit/core/blob/d88d1f091b1257d8b7b4ae48521f19ed60602b76/src/ir/operations/ClassicControlledOperation.cpp#L130-L153
Further places where the ClassicControlledOperation class is used can easily be found via code search.