Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Fix RuntimeError when converting qiskit instructions. #203

Merged
merged 12 commits into from
Nov 15, 2023
20 changes: 7 additions & 13 deletions pytket/extensions/qiskit/qiskit_convert.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@
# Special types:
Barrier: OpType.Barrier,
Instruction: OpType.CircBox,
Gate: OpType.CustomGate,
Gate: OpType.CircBox,
Measure: OpType.Measure,
Reset: OpType.Reset,
Initialize: OpType.StatePreparationBox,
Expand Down Expand Up @@ -476,7 +476,7 @@ def add_qiskit_data(self, data: "QuantumCircuitData") -> None:

elif optype == OpType.Barrier:
self.tkc.add_barrier(qubits)
elif optype in (OpType.CircBox, OpType.CustomGate):
elif optype == OpType.CircBox:
qregs = (
[QuantumRegister(instr.num_qubits, "q")]
if instr.num_qubits > 0
Expand All @@ -490,17 +490,10 @@ def add_qiskit_data(self, data: "QuantumCircuitData") -> None:
builder = CircuitBuilder(qregs, cregs)
builder.add_qiskit_data(instr.definition)
subc = builder.circuit()
if optype == OpType.CircBox:
cbox = CircBox(subc)
self.tkc.add_circbox(cbox, qubits + bits, **condition_kwargs) # type: ignore
else:
# warning, this will catch all `Gate` instances
# that were not picked up as a subclass in _known_qiskit_gate
params = [param_to_tk(p) for p in instr.params]
gate_def = CustomGateDef.define(
instr.name, subc, list(subc.free_symbols())
)
self.tkc.add_custom_gate(gate_def, params, qubits + bits) # type: ignore
subc.name = instr.name
cbox = CircBox(subc)
self.tkc.add_circbox(cbox, qubits + bits, **condition_kwargs) # type: ignore

elif optype == OpType.CU3 and type(instr) == qiskit_gates.CUGate:
if instr.params[-1] == 0:
self.tkc.add_gate(
Expand Down Expand Up @@ -744,6 +737,7 @@ def append_tk_command_to_qiskit(
_supported_tket_gates
| _additional_multi_controlled_gates
| {OpType.Unitary1qBox, OpType.Unitary2qBox, OpType.Unitary3qBox}
| {OpType.CustomGate}
)


Expand Down
20 changes: 19 additions & 1 deletion tests/qiskit_convert_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
)
from qiskit.quantum_info import Pauli, SparsePauliOp # type: ignore
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed that pylint didn't pick up this unused import in previous workflow runs.

I'd expect it to complain about this.

from qiskit.transpiler import PassManager # type: ignore
from qiskit.circuit.library import RYGate, MCMT, XXPlusYYGate, PauliEvolutionGate, UnitaryGate # type: ignore
from qiskit.circuit.library import RYGate, MCMT, XXPlusYYGate, PauliEvolutionGate, UnitaryGate, RealAmplitudes # type: ignore
import qiskit.circuit.library.standard_gates as qiskit_gates # type: ignore
from qiskit.circuit import Parameter
from qiskit.synthesis import SuzukiTrotter # type: ignore
Expand Down Expand Up @@ -1013,3 +1013,21 @@ def test_failed_conversion_error() -> None:
NotImplementedError, match=r"Conversion of qiskit's xx_plus_yy instruction"
):
qiskit_to_tk(qc)


def test_RealAmplitudes_conversion() -> None:
qc = QuantumCircuit(3)

params = [np.pi / 2] * 9
real_amps1 = RealAmplitudes(3, reps=2)

real_amps2 = real_amps1.assign_parameters(params)
qc.compose(real_amps2, qubits=[0, 1, 2], inplace=True)

converted_tkc = qiskit_to_tk(qc)
assert converted_tkc.n_gates == 1
assert converted_tkc.n_gates_of_type(OpType.CircBox) == 1
DecomposeBoxes().apply(converted_tkc)
assert converted_tkc.name == "RealAmplitudes"
assert converted_tkc.n_gates_of_type(OpType.CX) == 4
assert converted_tkc.n_gates_of_type(OpType.Ry) == 9