Skip to content

Supporting native instructions #5774

@ajavadia

Description

@ajavadia

Currently the transpiler consults backend.configuration().coupling_map and backend.configuration().basis_gates in order to map a circuit to a backend. The assumption is that all the 1-qubit gates in the basis_gates are present on all qubits, and all the 2-qubit gates in the basis_gates are present on all edges of the coupling_map.

This has some limitations, namely that we cannot support a heterogeneous gateset (different gates on different qubits). We should move towards a model where the backend is free to tune up any gate on any qubit(s) and report it, and the transpiler can optimize over those instructions.

To do this, we need:

  1. Provider v2 support:
  • Provider to parse the datastructure that the backend reports and present them as a list of Instructions [*] to qiskit. That is, each entry has the Gate plus qubits it acts on. Same for Measure/Reset, etc. This is basically a list of everything that is calibrated on the device.

  • Note a: The keys to InstructionScheduleMap should work with the elements of this list, that is InstructionScheduleMap says what the pulse sequence is for each of those calibrated gates. If one of these is not reported for some reason, a meaningful error should be raised saying that this gate is in fact calibrated, but the pulse def is not available.

  • Note b: We could have a scenario where we calibrate the same gate in two different ways, say a slow CNOT and a fast CNOT. Those should show up as two different entries in the list of Instructions, and have two separate entries in InstructionScheduleMap.

  • Note c: There are places, e.g. in the current backend properties, where defining this Instruction really helps. For example gate_length is currently keyed on (name, qubits), and this precludes backends from making gate_length depend on the parameter (e.g. one duration for rx(pi/2) and another for rx(pi/4)). Again here we need this datastructure to be keyed on Instruction, as every calibrated instruction on the backend has its own length.

  1. The stages of the compiler that work with physical circuits should be modified to work with these physical Instructions.
  • The first and most important are the basis translators. These currently assume universal gates on all qubits, but should be modified to know which Gate works on which qubit.

  • There are a lot of places where the compiler works with gate names, and these should be changed to work with Instruction or Gate objects. The reason is the backend may tune up any unitary, and we can't assume these exist in the library. So while we can give them a name, it should not be germane to the compilation process as the unitary + qubits is all you need to know about the gate.

  • A future step could be modifying layout & routing passes so they take into account the native gates on each of the physical qubits and try to steer the virtual gates onto the ones that will later be basis-translated with the least cost.

[*] Some suggestions on terminology and classes:

  • Instruction: this should be equivalent to a line of QASM or one entry in circuit.data (i.e. the gate plus its params plus its operands). (note: Currently it is used as such in instruction_schedule_map, but not in the Instruction class --- instead we use a tuple for this)
  • Operation: A quantum channel that acts on qubit(s) (reset, measure, gate, or a combination thereof)
  • Directive: Something that is a hint to compiler but does not actually execute on the processor
  • CircuitElement: everything that can go in the circuit (combination of Operation and Directive and possibly future classical code?)
  • Gate: a unitary (X is a gate. RZ(theta) is a (parameterized) gate. RZ(0.1) q0 is an instruction).

Metadata

Metadata

Labels

ISAISA-related issuestype: enhancementIt's working, but needs polishing

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions