Skip to content

Commit e694e64

Browse files
Merge pull request #1077 from qiboteam/native_gates
Native gates directly defined by the platform
2 parents 852b163 + a04745a commit e694e64

File tree

1 file changed

+63
-5
lines changed

1 file changed

+63
-5
lines changed

src/qibocal/auto/transpile.py

+63-5
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,18 @@
11
from typing import Optional
22

3-
from qibo import Circuit
3+
from qibo import Circuit, gates
44
from qibo.backends import Backend
55
from qibo.transpiler.pipeline import Passes
66
from qibo.transpiler.unroller import NativeGates, Unroller
7+
from qibolab.compilers.compiler import Compiler
8+
from qibolab.pulses import PulseSequence
79
from qibolab.qubits import QubitId
810

11+
REPLACEMENTS = {
12+
"RX": "GPI2",
13+
"MZ": "M",
14+
}
15+
916

1017
def transpile_circuits(
1118
circuits: list[Circuit],
@@ -97,19 +104,70 @@ def execute_transpiled_circuit(
97104
backend,
98105
transpiler,
99106
)[0]
100-
101107
return transpiled_circ, backend.execute_circuit(
102108
transpiled_circ, initial_state=initial_state, nshots=nshots
103109
)
104110

105111

112+
def natives(platform):
113+
"""
114+
Return the list of native gates defined in the `platform`.
115+
This function assumes the native gates to be the same for each
116+
qubit and pair.
117+
"""
118+
pair = next(iter(platform.pairs.values()))
119+
qubit = next(iter(platform.qubits.values()))
120+
two_qubit_natives = list(pair.native_gates.raw)
121+
single_qubit_natives = list(qubit.native_gates.raw)
122+
# Solve Qibo-Qibolab mismatch
123+
single_qubit_natives.append("RZ")
124+
single_qubit_natives.append("Z")
125+
single_qubit_natives.remove("RX12")
126+
new_single_natives = [REPLACEMENTS.get(i, i) for i in single_qubit_natives]
127+
return new_single_natives + two_qubit_natives
128+
129+
130+
def create_rule(native):
131+
def rule(qubits_ids, platform, parameters=None):
132+
if len(qubits_ids[1]) == 1:
133+
native_gate = platform.qubits[tuple(qubits_ids[1])].native_gates
134+
else:
135+
native_gate = platform.pairs[tuple(qubits_ids[1])].native_gates
136+
pulses = getattr(native_gate, native).pulses
137+
return PulseSequence(pulses), {}
138+
139+
return rule
140+
141+
142+
def set_compiler(backend, natives_):
143+
"""
144+
Set the compiler to execute the native gates defined by the platform.
145+
"""
146+
compiler = backend.compiler
147+
rules = {}
148+
for native in natives_:
149+
gate = getattr(gates, native)
150+
if gate not in compiler.rules:
151+
rules[gate] = create_rule(native)
152+
else:
153+
rules[gate] = compiler.rules[gate]
154+
rules[gates.I] = compiler.rules[gates.I]
155+
backend.compiler = Compiler(rules=rules)
156+
157+
106158
def dummy_transpiler(backend: Backend) -> Passes:
107159
"""
108160
If the backend is `qibolab`, a transpiler with just an unroller is returned,
109-
otherwise None.
161+
otherwise `None`. This function overwrites the compiler defined in the
162+
backend, taking into account the native gates defined in the`platform` (see
163+
:func:`set_compiler`).
110164
"""
111-
unroller = Unroller(NativeGates.default())
112-
return Passes(connectivity=backend.platform.topology, passes=[unroller])
165+
platform = backend.platform
166+
native_gates = natives(platform)
167+
set_compiler(backend, native_gates)
168+
native_gates = [getattr(gates, x) for x in native_gates]
169+
unroller = Unroller(NativeGates.from_gatelist(native_gates))
170+
return Passes(connectivity=platform.topology, passes=[unroller])
113171

114172

115173
def pad_circuit(nqubits, circuit: Circuit, qubit_map: list[int]) -> Circuit:

0 commit comments

Comments
 (0)