BQSKit / bqskit

Berkeley Quantum Synthesis Toolkit
Other
106 stars 31 forks source link

Converting a parameterized Qiskit.QuantumCircuit to BQSKit.Circuit #218

Open nquetschlich opened 5 months ago

nquetschlich commented 5 months ago

Hi there,

I am currently playing around with BQSKit and its usage/integration into our MQT Predictor that combined compilation passes from different compilers and, therefore, needs conversions between the different formats to represent quantum circuits.

Currently, we rely on Qiskit.QuantumCircuit as our intermediate representation. When executing a compilation pass from a different compiler (e.g., BQSKit) we use the usually provided transformation functions (such as bqskit.ext.qiskit_to_bqskit and bqskit.ext.bqskit_to_qiskit). While this works very well for non-parameterized circuits, it fails for parameterized ones since those transformations currently rely on openQASM 2.0 that does not support parameterized gates.

However, pytket for example implement its own transformation that also supports those gates, see here. Do you have any plans to pursue a similar approach or could give me some guidance how I could implement it in a similar fashion?

I tried to play around a bit and started to write a routine:

from qiskit import Quantumcircuit
import bqskit

def qiskit_to_bqskit(original_qc: QuantumCircuit) -> bqskit.ir.CIrcuit:
    parsed_qc = bqskit.ir.CIrcuit(qc.num_qubits)
    for instr, qargs, cargs in original_qc.data:
        if instr.name == 'rzz':
            parameter = instr.params[0]
            q0, q1 = qargs[0].index, qargs[1].index
            parsed_qc.append_gate(ZZGate(), [q0, q1], [parameter])
   <....> 

However, I am not sure how to deal with the parameter when it comes as a qiskit.circuit.Parameter and how to add the parameter's name.

edyounis commented 5 months ago

Thanks for bringing this issue up. Can you share an example qasm file of a parameterized circuit? We support parameterized gates as that is how we synthesize circuits, but I want to make sure I understand your request well before recommending something.

nquetschlich commented 5 months ago

Thanks for bringing this issue up. Can you share an example qasm file of a parameterized circuit? We support parameterized gates as that is how we synthesize circuits, but I want to make sure I understand your request well before recommending something.

Hi Ed, of course. In general, we would like to convert a Qiskit.QuantumCircuit object with symbolic parameters such as in this example:

from qiskit import QuantumCircuit
from qiskit.circuit import Parameter
from bqskit.ext import qiskit_to_bqskit
qc = QuantumCircuit(1)
qc.rz(Parameter("x"),0)
bqskit_circuit = qiskit_to_bqskit(qc)

Which unfortunately fails, since openQASM 2.0 does not support symbolic parameters and, as far as I understand, BQSKit converts using openQASM 2.0.

For TKET for example, the conversion using

from pytket.extensions.qiskit import qiskit_to_tk
qiskit_to_tk(qc)

works since they implemented their own converter by iterating over the qiskit circuit and creating a TKET one from it without using openQASM 2.0. For our work, it would be very helpful if BQSKit would be able to behave similarly or if there would a some kind of workaround.

edyounis commented 5 months ago

Thanks for providing a simple example and clarifying this. Yeah, BQSKit's IR currently only supports instantiated circuits. As of right now, we are missing some features necessary for you to translate symbolic circuits as simply as you would like.

That being said, all of our circuits are, in a sense, parameterized. You can build a circuit with an RZGate and set its parameters to anything. You can then "re-instantiate" that circuit according to a cost function or target to something else through the circuit.instantiate method. From this perspective, all of our circuits are also parametrized all of the time.

If you would like to differentiate between fixed and free parameters in a circuit, you can use the FrozenParameterGate, which is a composed gate. This will allow you to fix specific gate parameters in a circuit such that they will never change under instantiation. You can also freeze certain parameters in a gate through their methods: with_frozen_params and with_all_frozen_params. These methods just wrap the gate in a FrozenParameterGate.

Hopefully, this gives you a workaround or a place to start thinking about your problem. I do want to keep this issue open and discussion going, as there are improvements that we can make here. Some features I would like to see added to BQSKit:

We also need to expand our qasm support into 3.0. Feel free to add anything here. It also might help if you provide more detail on your use case.

nquetschlich commented 5 months ago

Thanks for coming back to me with and your detailed answer.

I like to provide some more details how we like to use BQSKit. In general, we try to implement BQSKit as another supported compiler in our MQT Predictor. The goal of it is to provide a software tool that combines various compilers (so far Qiskit and TKET, soon also BQSKit) and uses reinforcement learning to learn the optimal compilation sequences based on the transpilation pass level. To make it a bit more graspable, one result you be that an uncompiled quantum circuit should be synthesized using compiler A, mapped using compiler B, and optimized using compiler C because the each of the respective compiler offers the most promising transpilation pass for the considered task.

For that, we use Qiskit’s QuantumCircuit as the intermediate representation and when a different compiler is used for a certain transpilation pass, the quantum circuit is converted into the respective format, the pass is applied and it is converted back to a Qiskit.QuantumCircuit again. While this already works well for circuits without symbolic parameters when also considering BQSKit, it fails for parameterized ones.

In that regard, thanks a lot for the suggested workaround. We will evaluate in the next weeks, whether we will pursue it.