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

Inverse of MCX gates generated without qubits for ancillae #4953

Closed
kdk opened this issue Aug 19, 2020 · 0 comments · Fixed by #5020
Closed

Inverse of MCX gates generated without qubits for ancillae #4953

kdk opened this issue Aug 19, 2020 · 0 comments · Fixed by #5020
Assignees
Labels
bug Something isn't working stable backport potential The bug might be minimal and/or import enough to be port to stable

Comments

@kdk
Copy link
Member

kdk commented Aug 19, 2020

Information

  • Qiskit Terra version: master @ 7d79ab0
  • Python version: 3.5
  • Operating system: osx

What is the current behavior?

Inverting an mcx gate (with ancilla) falls back to ControlledGate.inverse which builds the definition of the inverse gate without ancilla. This leads to an error when transpiling because the inverse gate uses fewer qubits than the original.

Steps to reproduce the problem

>>> import qiskit as qk
>>> qc = qk.QuantumCircuit(5)
>>> qc.mcx([0,1,2],4,[3], mode='v-chain')
>>> qk.transpile(qc, basis_gates=['u3', 'cx']).count_ops()
OrderedDict([('u3', 16), ('cx', 12)])
>>> qk.transpile(qc.inverse(), basis_gates=['u3', 'cx']).count_ops()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/kevin.krsulichibm.com/q/qiskit-terra/qiskit/compiler/transpile.py", line 214, in transpile
    circuits = parallel_map(_transpile_circuit, list(zip(circuits, transpile_args)))
  File "/Users/kevin.krsulichibm.com/q/qiskit-terra/qiskit/tools/parallel.py", line 106, in parallel_map
    return [task(values[0], *task_args, **task_kwargs)]
  File "/Users/kevin.krsulichibm.com/q/qiskit-terra/qiskit/compiler/transpile.py", line 315, in _transpile_circuit
    output_name=transpile_config['output_name'])
  File "/Users/kevin.krsulichibm.com/q/qiskit-terra/qiskit/transpiler/passmanager.py", line 212, in run
    return self._run_single_circuit(circuits, output_name, callback)
  File "/Users/kevin.krsulichibm.com/q/qiskit-terra/qiskit/transpiler/passmanager.py", line 275, in _run_single_circuit
    result = running_passmanager.run(circuit, output_name=output_name, callback=callback)
  File "/Users/kevin.krsulichibm.com/q/qiskit-terra/qiskit/transpiler/runningpassmanager.py", line 113, in run
    dag = self._do_pass(pass_, dag, passset.options)
  File "/Users/kevin.krsulichibm.com/q/qiskit-terra/qiskit/transpiler/runningpassmanager.py", line 143, in _do_pass
    dag = self._run_this_pass(pass_, dag)
  File "/Users/kevin.krsulichibm.com/q/qiskit-terra/qiskit/transpiler/runningpassmanager.py", line 155, in _run_this_pass
    new_dag = pass_.run(dag)
  File "/Users/kevin.krsulichibm.com/q/qiskit-terra/qiskit/transpiler/passes/basis/unroll_custom_definitions.py", line 88, in run
    dag.substitute_node_with_dag(node, unrolled_dag)
  File "/Users/kevin.krsulichibm.com/q/qiskit-terra/qiskit/dagcircuit/dagcircuit.py", line 842, in substitute_node_with_dag
    self._check_wires_list(wires, node)
  File "/Users/kevin.krsulichibm.com/q/qiskit-terra/qiskit/dagcircuit/dagcircuit.py", line 716, in _check_wires_list
    % (wire_tot, len(wires)))
qiskit.dagcircuit.exceptions.DAGCircuitError: 'expected 5 wires, got 4'
>>> print(MCXVChain(num_ctrl_qubits=3).definition)
     ┌───────┐     ┌───────┐
q_0: ┤0      ├─────┤0      ├
     │       │     │       │
q_1: ┤1      ├─────┤1      ├
     │       │     │       │
q_2: ┤  RCCX ├──■──┤  RCCX ├
     │       │┌─┴─┐│       │
q_3: ┤       ├┤ X ├┤       ├
     │       │└─┬─┘│       │
q_4: ┤2      ├──■──┤2      ├
     └───────┘     └───────┘
>>> print(MCXVChain(num_ctrl_qubits=3).inverse().definition)

q_0: ──■──
       │
q_1: ──■──
       │
q_2: ──■──
     ┌─┴─┐
q_3: ┤ X ├
     └───┘

Suggested solutions

Adding something to class MCXGate like

def inverse(self):
    return self.copy()
@kdk kdk added bug Something isn't working stable backport potential The bug might be minimal and/or import enough to be port to stable labels Aug 19, 2020
@kdk kdk self-assigned this Aug 25, 2020
@mergify mergify bot closed this as completed in #5020 Sep 4, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working stable backport potential The bug might be minimal and/or import enough to be port to stable
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant