Skip to content

Commit

Permalink
Fix typing of inserted UnitaryGates in quantum_volume (#13479) (#13481)
Browse files Browse the repository at this point in the history
There was a small typing issue in the quantum_volume implementation
where there was a mismatch in the Python type and the rust type. The
UnitaryGate were being added to the circuit as a rust space
PyInstruction instead of a PyGate. This was incorrect as UnitaryGate is
unitary and a gate type in python, this mismatch was causing subsequent
transpilation or anything working with the unitaries in the quantum
volume circuit from rust to mischaracterize the operations as
non-unitary so things like getting the matrix would fail. This commit
corrects the typing so the gates are added as a unitary operation in the
rust typing.

This will get much simpler and less error prone when #13272 is
implemented and we have a rust native UnitaryGate type.

(cherry picked from commit 4bb1432)

Co-authored-by: Matthew Treinish <[email protected]>
  • Loading branch information
mergify[bot] and mtreinish authored Nov 22, 2024
1 parent be44c82 commit ddbb63c
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 5 deletions.
9 changes: 4 additions & 5 deletions crates/accelerate/src/circuit_library/quantum_volume.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use rayon::prelude::*;
use qiskit_circuit::circuit_data::CircuitData;
use qiskit_circuit::imports::UNITARY_GATE;
use qiskit_circuit::operations::Param;
use qiskit_circuit::operations::PyInstruction;
use qiskit_circuit::operations::PyGate;
use qiskit_circuit::packed_instruction::PackedOperation;
use qiskit_circuit::{Clbit, Qubit};
use smallvec::{smallvec, SmallVec};
Expand Down Expand Up @@ -127,17 +127,16 @@ pub fn quantum_volume(
let unitary_gate = UNITARY_GATE
.get_bound(py)
.call((unitary.clone(), py.None(), false), Some(&kwargs))?;
let instruction = PyInstruction {
let instruction = PyGate {
qubits: 2,
clbits: 0,
params: 1,
op_name: "unitary".to_string(),
control_flow: false,
instruction: unitary_gate.unbind(),
gate: unitary_gate.unbind(),
};
let qubit = layer_index * 2;
Ok((
PackedOperation::from_instruction(Box::new(instruction)),
PackedOperation::from_gate(Box::new(instruction)),
smallvec![Param::Obj(unitary.unbind().into())],
vec![permutation[qubit], permutation[qubit + 1]],
vec![],
Expand Down
19 changes: 19 additions & 0 deletions test/python/transpiler/test_preset_passmanagers.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

from qiskit import QuantumCircuit, ClassicalRegister, QuantumRegister
from qiskit.circuit import Qubit, Gate, ControlFlowOp, ForLoopOp
from qiskit.circuit.library import quantum_volume
from qiskit.compiler import transpile
from qiskit.transpiler import CouplingMap, Layout, PassManager, TranspilerError, Target
from qiskit.circuit.library import U2Gate, U3Gate, QuantumVolume, CXGate, CZGate, XGate
Expand Down Expand Up @@ -343,6 +344,24 @@ def test_v1(self, circuit, level, backend):
)
self.assertIsInstance(result, QuantumCircuit)

@data(0, 1, 2, 3)
def test_quantum_volume_function_transpile(self, opt_level):
"""Test quantum_volume transpilation."""
qc = quantum_volume(10, 10, 12345)
backend = GenericBackendV2(
num_qubits=100,
basis_gates=["cz", "rz", "sx", "x", "id"],
coupling_map=CouplingMap.from_grid(10, 10),
)
pm = generate_preset_pass_manager(opt_level, backend)
res = pm.run(qc)
for inst in res.data:
self.assertTrue(
backend.target.instruction_supported(
inst.operation.name, qargs=tuple(res.find_bit(x).index for x in inst.qubits)
)
)


@ddt
class TestPassesInspection(QiskitTestCase):
Expand Down

0 comments on commit ddbb63c

Please sign in to comment.