BQSKit / bqskit

Berkeley Quantum Synthesis Toolkit
Other
118 stars 33 forks source link

Compiler ignores custom gate set when compiling a random 2-qubit circuit #133

Closed jasonchadwick closed 1 year ago

jasonchadwick commented 1 year ago

Example to reproduce:

import bqskit
from bqskit.ext import qiskit_to_bqskit
import qiskit as qs
import qutip as qt
import numpy as np

circ = qs.QuantumCircuit(2)
u = qt.rand_unitary_haar(4)
random_unitary = qs.quantum_info.operators.Operator(np.array(u))
circ.unitary(random_unitary, [0,1], label='random')

model = bqskit.MachineModel(2, gate_set={bqskit.ir.gates.CZGate(2), bqskit.ir.gates.U3Gate(1)})
circ_bqskit = qiskit_to_bqskit(circ)
output_circuit = bqskit.compile(circ_bqskit, model=model)
print(output_circuit.gate_set)

This will print {U3Gate, CNOTGate} instead of the desired {U3Gate, CZGate} (and the circuit output_circuit will consist of CNOTs and U3 gates instead of using the desired CZ operations). This appears to be the case for any non-CNOT 2-qubit gate.

Behavior is correct when using bqskit.compile(np.array(u), model=model), so it seems that the circuit object is causing the problem.

Behavior is correct when specifying a 3-qubit gate instead of a 2-qubit gate, e.g. gate_set={bqskit.ir.gates.Toffoli(3), bqskit.ir.gates.U3Gate(1)} (if circuit size is extended to 3 qubits instead of 2).

edyounis commented 1 year ago

Thanks for the bug report!

The issue is a bit hidden here. The qiskit_to_bqskit first uses qiskit to convert the random unitary to qasm using KAK. The way qiskit encodes this into qasm is with a gate declaration, which BQSKit then parses into a CircuitGate object. This caused issues with the compile function's ability to determine the input gate set and rebase. Should be fixed now, I put up a PR if you would like to test it out. Otherwise, this will make it into the 1.1.0a3 soon and eventually the 1.1 release.