Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

fix: Allow circuits containing CnZ gates to run on AerBackend #369

Merged
merged 12 commits into from
Sep 10, 2024
1 change: 1 addition & 0 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Unreleased
* Add conversion of controlled unitary gates from qiskit to tket.
* Initialize `TketAutoPass` with a `BackendV2`.
* Update `TketBackend` to derive from `BackendV2`.
* Fix to allow `AerBackend` to work with multi-controlled Z gates.

0.55.0 (July 2024)
------------------
Expand Down
4 changes: 3 additions & 1 deletion pytket/extensions/qiskit/qiskit_convert.py
Original file line number Diff line number Diff line change
Expand Up @@ -758,7 +758,9 @@ def append_tk_command_to_qiskit(
if optype == OpType.CnY:
return qcirc.append(qiskit_gates.YGate().control(len(qargs) - 1), qargs)
if optype == OpType.CnZ:
return qcirc.append(qiskit_gates.ZGate().control(len(qargs) - 1), qargs)
new_gate = qiskit_gates.ZGate().control(len(qargs) - 1)
new_gate.name = "mcz"
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can you freely choose this name? Could we do cnz?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Unfortunately 'cnz' doesn't work because AerSimulater accepts the name 'mcz'.
In general, AerSimulater accepts the gete list on blow
#368 (comment)

return qcirc.append(new_gate, qargs)
if optype == OpType.CnRy:
# might as well do a bit more checking
assert len(op.params) == 1
Expand Down
14 changes: 14 additions & 0 deletions tests/backend_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -1498,3 +1498,17 @@ def test_noisy_density_matrix_simulation() -> None:
assert noisy_dm.shape == (8, 8)
# Check purity to verify mixed state
assert np.trace(noisy_dm**2).real < 0.99


def test_mc_gate_on_aer() -> None:
"""Test for cm gates support in aer simulators
https://github.com/CQCL/pytket-qiskit/issues/368"""
b = AerBackend()
c = Circuit(3, 3)
c.X(0).X(1)
c.H(2)
c.add_gate(OpType.CnZ, [0, 1, 2])
c.H(2)
c.measure_all()
r = b.run_circuit(c, n_shots=10)
assert r.get_counts() == Counter({(1, 1, 1): 10})
4 changes: 2 additions & 2 deletions tests/qiskit_convert_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -828,7 +828,7 @@ def test_multicontrolled_gate_conversion() -> None:
assert my_tkc.n_gates_of_type(OpType.CnRy) == 2
my_new_qc = tk_to_qiskit(my_tkc)
qiskit_ops = my_new_qc.count_ops()
assert qiskit_ops["c3y"] and qiskit_ops["c3z"] and qiskit_ops["c3ry"] == 2
assert qiskit_ops["c3y"] and qiskit_ops["mcz"] and qiskit_ops["c3ry"] == 2
tcirc = qiskit_to_tk(my_new_qc)
unitary_after = tcirc.get_unitary()
assert compare_unitaries(unitary_before, unitary_after)
Expand Down Expand Up @@ -1034,7 +1034,7 @@ def test_ccz_conversion() -> None:
assert tkc_ccz.n_gates_of_type(OpType.CnZ) == tkc_ccz.n_gates == 2
# bidirectional CnZ conversion already supported
qc_ccz2 = tk_to_qiskit(tkc_ccz)
assert qc_ccz2.count_ops()["ccz"] == 2
assert qc_ccz2.count_ops()["mcz"] == 2
tkc_ccz2 = qiskit_to_tk(qc_ccz2)
assert compare_unitaries(tkc_ccz.get_unitary(), tkc_ccz2.get_unitary())

Expand Down