-
Notifications
You must be signed in to change notification settings - Fork 7
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
Handling global backend for protocols involving circuits #1076
Changes from 3 commits
cf08f45
8c52ce5
53ba1be
713956b
a86f91d
8ea8342
b7195db
9edcba8
7c5aed5
61039a9
59f95e3
d519948
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,32 @@ | ||
from typing import Optional | ||
|
||
from qibo import Circuit | ||
from qibo.backends.abstract import Backend | ||
from qibo.backends import construct_backend, get_backend | ||
from qibo.transpiler.pipeline import Passes | ||
from qibo.transpiler.unroller import NativeGates, Unroller | ||
from qibolab import MetaBackend | ||
from qibolab.platform import Platform | ||
from qibolab.qubits import QubitId | ||
|
||
|
||
def _get_platforms(): | ||
"""Qibolab platforms.""" | ||
try: | ||
platforms = list(MetaBackend().list_available()) | ||
except RuntimeError: | ||
platforms = [] | ||
|
||
return platforms + ["dummy"] | ||
|
||
|
||
AVAILABLE_PLATFORMS = _get_platforms() | ||
"""Available qibolab platforms.""" | ||
|
||
|
||
def transpile_circuits( | ||
circuits: list[Circuit], | ||
qubit_maps: list[list[QubitId]], | ||
backend: Backend, | ||
platform: Platform, | ||
transpiler: Optional[Passes], | ||
): | ||
"""Transpile and pad `circuits` according to the platform. | ||
|
@@ -28,14 +44,13 @@ def transpile_circuits( | |
are all string or all integers. | ||
""" | ||
transpiled_circuits = [] | ||
|
||
qubits = list(backend.platform.qubits) | ||
if isinstance(qubit_maps[0][0], str): | ||
for i, qubit_map in enumerate(qubit_maps): | ||
qubit_map = map(lambda x: qubits.index(x), qubit_map) | ||
qubit_maps[i] = list(qubit_map) | ||
if backend.name == "qibolab": | ||
platform_nqubits = backend.platform.nqubits | ||
if platform.name in AVAILABLE_PLATFORMS: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe I just forgot, but in which case is this condition supposed to be false? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it should be False when we transpile circuits that are executed on simultation so no transpilation at all. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Ah, I see. But in that case there should be no My advice would be to drop any simulation reference, and assume it is always Qibolab (possibly the emulator, but still Qibolab). |
||
qubits = list(platform.qubits) | ||
if isinstance(qubit_maps[0][0], str): | ||
for i, qubit_map in enumerate(qubit_maps): | ||
qubit_map = map(lambda x: qubits.index(x), qubit_map) | ||
qubit_maps[i] = list(qubit_map) | ||
platform_nqubits = platform.nqubits | ||
for circuit, qubit_map in zip(circuits, qubit_maps): | ||
new_circuit = pad_circuit(platform_nqubits, circuit, qubit_map) | ||
transpiled_circ, _ = transpiler(new_circuit) | ||
|
@@ -48,7 +63,7 @@ def transpile_circuits( | |
def execute_transpiled_circuits( | ||
circuits: list[Circuit], | ||
qubit_maps: list[list[QubitId]], | ||
backend: Backend, | ||
platform: Platform, | ||
transpiler: Optional[Passes], | ||
initial_states=None, | ||
nshots=1000, | ||
|
@@ -66,9 +81,13 @@ def execute_transpiled_circuits( | |
transpiled_circuits = transpile_circuits( | ||
circuits, | ||
qubit_maps, | ||
backend, | ||
platform, | ||
transpiler, | ||
) | ||
if platform.name in AVAILABLE_PLATFORMS: | ||
backend = construct_backend(backend="qibolab", platform=platform) | ||
else: | ||
backend = get_backend() | ||
return transpiled_circuits, backend.execute_circuits( | ||
transpiled_circuits, initial_states=initial_states, nshots=nshots | ||
) | ||
|
@@ -77,7 +96,7 @@ def execute_transpiled_circuits( | |
def execute_transpiled_circuit( | ||
circuit: Circuit, | ||
qubit_map: list[QubitId], | ||
backend: Backend, | ||
platform: Platform, | ||
transpiler: Optional[Passes], | ||
initial_state=None, | ||
nshots=1000, | ||
|
@@ -96,22 +115,26 @@ def execute_transpiled_circuit( | |
transpiled_circ = transpile_circuits( | ||
[circuit], | ||
[qubit_map], | ||
backend, | ||
platform, | ||
transpiler, | ||
)[0] | ||
if platform.name in AVAILABLE_PLATFORMS: | ||
backend = construct_backend(backend="qibolab", platform=platform) | ||
else: | ||
backend = get_backend() | ||
return transpiled_circ, backend.execute_circuit( | ||
transpiled_circ, initial_state=initial_state, nshots=nshots | ||
) | ||
|
||
|
||
def dummy_transpiler(backend) -> Optional[Passes]: | ||
def dummy_transpiler(platform) -> Optional[Passes]: | ||
""" | ||
If the backend is `qibolab`, a transpiler with just an unroller is returned, | ||
otherwise None. | ||
""" | ||
if backend.name == "qibolab": | ||
if platform.name in AVAILABLE_PLATFORMS: | ||
unroller = Unroller(NativeGates.default()) | ||
return Passes(connectivity=backend.platform.topology, passes=[unroller]) | ||
return Passes(connectivity=platform.topology, passes=[unroller]) | ||
return None | ||
|
||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not a comment on this PR, but just a point raised as a consequence.
Maybe we should actually drop this exception: if there is no path, we should already return an empty list.
It should be sufficient to do it here:
https://github.com/qiboteam/qibolab/blob/6b2a7b790e8d58d52be937c2f41b8606459a3bf1/src/qibolab/_core/platform/load.py#L23-L26
This should result in
.list_available()
returning an empty list, and.load()
raising a different error.@stavros11