Skip to content

GateDirection pass goes outside allowed basis gates #10785

@chriseclectic

Description

@chriseclectic

Environment

  • Qiskit Terra version: 0.25
  • Python version: 3.9
  • Operating system: MacOS

What is happening?

Trying to run a clifford simulation on a fake backend with ECR basis gates leads to transpilation errors with unsupported basis gates

How can we reproduce the issue?

from qiskit import QuantumCircuit, transpile
from qiskit_aer import AerSimulator
from qiskit.providers.fake_provider import FakeSherbrooke, FakeWashington

# Stabilizer simulator for FakeSherbrooke
clifford_basis_gates = ['ecr', 'sx', 'x', 'id', 'z', 's', 'sdg']
backend = AerSimulator.from_backend(
    FakeSherbrooke(),
    method="stabilizer",
    basis_gates=clifford_basis_gates, 
)

# Circuit
qc = QuantumCircuit(2)
qc.h(0)
qc.cx(0, 1)

# Transpile
transpile(qc, backend)

Raises

TranspilerError: "Unable to translate the operations in the circuit: ['ry', 'h', 'sdg', 'sx', 's', 'ecr', 'x'] to the backend's (or manually specified) target basis: ['break_loop', 'quantum_channel', 's', 'save_expval_var', 'for_loop', 'roerror', 'continue_loop', 'save_probabilities', 'z', 'qerror_loc', 'reset', 'save_clifford', 'snapshot', 'if_else', 'id', 'save_probabilities_dict', 'ecr', 'save_state', 'save_amplitudes_sq', 'sdg', 'save_stabilizer', 'delay', 'while_loop', 'save_expval', 'set_stabilizer', 'sx', 'measure', 'barrier', 'x']. This likely means the target basis is not universal or there are additional equivalence rules needed in the EquivalenceLibrary being used. For more details on this error see: https://qiskit.org/documentation/stubs/qiskit.transpiler.passes.BasisTranslator.html#translation_errors"

What should happen?

Running with a manually specified basis gates works (though the output is not at all optimized in terms of number of 1Q gates):

transpile(qc, basis_gates=["ecr", "x", "sx", "id", "z", "s", "sdg"])
global phase: 3π/2
     ┌───┐┌────┐┌───┐ ┌─────┐     ┌──────┐┌───┐
q_0: ┤ S ├┤ √X ├┤ S ├─┤ Sdg ├─────┤0     ├┤ X ├
     ├───┤├───┬┘├───┴┐└┬───┬┘┌───┐│  Ecr │└───┘
q_1: ┤ S ├┤ S ├─┤ √X ├─┤ S ├─┤ S ├┤1     ├─────
     └───┘└───┘ └────┘ └───┘ └───┘└──────┘     

Any suggestions?

Running transpilation with a callback looks like the issues is due to the GateDirection pass which inserts non-Clifford gates outside the allowed basis gates into the circuit and causes the rest of the transpilation to fail.

def callback(**kwargs):
    print(f"{type(kwargs['pass_']).__name__} output gates: {kwargs['dag'].count_ops()}")

transpile(qc, backend, callback=callback).draw()
ContainsInstruction, gates: {'h': 1, 'cx': 1}
UnitarySynthesis, gates: {'h': 1, 'cx': 1}
HighLevelSynthesis, gates: {'h': 1, 'cx': 1}
Unroll3qOrMore, gates: {'h': 1, 'cx': 1}
SetLayout, gates: {'h': 1, 'cx': 1}
TrivialLayout, gates: {'h': 1, 'cx': 1}
CheckMap, gates: {'h': 1, 'cx': 1}
FullAncillaAllocation, gates: {'h': 1, 'cx': 1}
EnlargeWithAncilla, gates: {'h': 1, 'cx': 1}
ApplyLayout, gates: {'h': 1, 'cx': 1}
CheckMap, gates: {'h': 1, 'cx': 1}
UnitarySynthesis, gates: {'h': 1, 'cx': 1}
HighLevelSynthesis, gates: {'h': 1, 'cx': 1}
UnrollCustomDefinitions, gates: {'h': 1, 'cx': 1}
BasisTranslator, gates: {'s': 6, 'sx': 2, 'sdg': 1, 'ecr': 1, 'x': 1}
CheckGateDirection, gates: {'s': 6, 'sx': 2, 'sdg': 1, 'ecr': 1, 'x': 1}
GateDirection, gates: {'s': 6, 'sx': 2, 'sdg': 1, 'x': 1, 'ry': 2, 'ecr': 1, 'h': 2}   # NON BASIS RY INSERTED HERE
RemoveResetInZeroState, gates: {'s': 6, 'sx': 2, 'sdg': 1, 'x': 1, 'ry': 2, 'ecr': 1, 'h': 2}
Depth, gates: {'s': 6, 'sx': 2, 'sdg': 1, 'x': 1, 'ry': 2, 'ecr': 1, 'h': 2}
FixedPoint, gates: {'s': 6, 'sx': 2, 'sdg': 1, 'x': 1, 'ry': 2, 'ecr': 1, 'h': 2}
Size, gates: {'s': 6, 'sx': 2, 'sdg': 1, 'x': 1, 'ry': 2, 'ecr': 1, 'h': 2}
FixedPoint, gates: {'s': 6, 'sx': 2, 'sdg': 1, 'x': 1, 'ry': 2, 'ecr': 1, 'h': 2}
Optimize1qGatesDecomposition, gates: {'s': 6, 'sx': 2, 'sdg': 1, 'x': 1, 'ry': 2, 'ecr': 1, 'h': 2}
CXCancellation, gates: {'s': 6, 'sx': 2, 'sdg': 1, 'x': 1, 'ry': 2, 'ecr': 1, 'h': 2}
GatesInBasis, gates: {'s': 6, 'sx': 2, 'sdg': 1, 'x': 1, 'ry': 2, 'ecr': 1, 'h': 2}
UnitarySynthesis, gates: {'s': 6, 'sx': 2, 'sdg': 1, 'x': 1, 'ry': 2, 'ecr': 1, 'h': 2}
HighLevelSynthesis, gates: {'s': 6, 'sx': 2, 'sdg': 1, 'x': 1, 'ry': 2, 'ecr': 1, 'h': 2}
UnrollCustomDefinitions, gates: {'s': 6, 'sx': 2, 'sdg': 1, 'x': 1, 'ry': 2, 'ecr': 1, 'h': 2}
# raises exception here

This pass should only insert gates supported by the backend, and be updated to work with Clifford basis backends to enable simulation testing

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions