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

Only apply MCMT plugin on MCMTGate #13596

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions qiskit/transpiler/passes/synthesis/hls_plugins.py
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,7 @@
C3XGate,
C4XGate,
PauliEvolutionGate,
MCMTGate,
ModularAdderGate,
HalfAdderGate,
FullAdderGate,
Expand Down Expand Up @@ -1156,6 +1157,9 @@ class MCMTSynthesisDefault(HighLevelSynthesisPlugin):

def run(self, high_level_object, coupling_map=None, target=None, qubits=None, **options):
# first try to use the V-chain synthesis if enough auxiliary qubits are available
if not isinstance(high_level_object, MCMTGate):
return None

if (
decomposition := MCMTSynthesisVChain().run(
high_level_object, coupling_map, target, qubits, **options
Expand All @@ -1170,6 +1174,9 @@ class MCMTSynthesisNoAux(HighLevelSynthesisPlugin):
"""A V-chain based synthesis for ``MCMTGate``."""

def run(self, high_level_object, coupling_map=None, target=None, qubits=None, **options):
if not isinstance(high_level_object, MCMTGate):
return None

base_gate = high_level_object.base_gate
ctrl_state = options.get("ctrl_state", None)

Expand All @@ -1195,6 +1202,9 @@ class MCMTSynthesisVChain(HighLevelSynthesisPlugin):
"""A V-chain based synthesis for ``MCMTGate``."""

def run(self, high_level_object, coupling_map=None, target=None, qubits=None, **options):
if not isinstance(high_level_object, MCMTGate):
return None

if options.get("num_clean_ancillas", 0) < high_level_object.num_ctrl_qubits - 1:
return None # insufficient number of auxiliary qubits

Expand Down
9 changes: 9 additions & 0 deletions releasenotes/notes/fix-mcmt-to-gate-ec84e1c625312444.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
fixes:
- |
Fixed a bug where any instruction called ``"mcmt"`` would be passed into the high-level
synthesis routine for a :class:`.MCMTGate`, which causes a failure or invalid result.
In particular, this could happen accidentally when handling the :class:`.MCMT` _circuit_,
named ``"mcmt"``, and implicitly converting it into an instruction e.g. when appending
it to a circuit.
Fixed `#13563 <https://github.com/Qiskit/qiskit/issues/13563>`__.
13 changes: 13 additions & 0 deletions test/python/circuit/library/test_mcmt.py
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,19 @@ def test_gate_with_parameters_vchain(self):
self.assertEqual(circuit.num_parameters, 1)
self.assertIs(circuit.parameters[0], theta)

def test_mcmt_circuit_as_gate(self):
"""Test the MCMT plugin is only triggered for the gate, not the same-named circuit.

Regression test of #13563.
"""
circuit = QuantumCircuit(2)
gate = RYGate(0.1)
mcmt = MCMT(gate=gate, num_ctrl_qubits=1, num_target_qubits=1)
circuit.append(mcmt, circuit.qubits) # append the MCMT circuit as gate called "MCMT"

transpiled = transpile(circuit, basis_gates=["u", "cx"])
self.assertTrue(Operator(transpiled).equiv(gate.control(1)))


if __name__ == "__main__":
unittest.main()
Loading