Skip to content

Commit ad14ef6

Browse files
Merge pull request #595 from qiboteam/bot
Add platform and backend entries to qq commands
2 parents 20fb7d0 + c784cc6 commit ad14ef6

13 files changed

+835
-690
lines changed

poetry.lock

+547-604
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

runcards/monitor.yml

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
2+
actions:
3+
4+
- id: t1
5+
priority: 00
6+
operation: t1_msr
7+
main: t2
8+
parameters:
9+
delay_before_readout_start: 50
10+
delay_before_readout_end: 100000
11+
delay_before_readout_step: 2500
12+
nshots: 1024
13+
14+
- id: t2
15+
priority: 10
16+
operation: t2_msr
17+
main: readout characterization
18+
parameters:
19+
delay_between_pulses_start: 50
20+
delay_between_pulses_end: 100000
21+
delay_between_pulses_step: 2500
22+
nshots: 1024
23+
24+
- id: readout characterization
25+
priority: 20
26+
# main: standard rb bootstrap
27+
operation: readout_characterization
28+
parameters:
29+
nshots: 5000
30+
31+
# - id: standard rb bootstrap
32+
# priority: 40
33+
# operation: standard_rb
34+
# parameters:
35+
# depths: [10, 100, 150, 200, 250, 300]
36+
# niter: 8
37+
# nshots: 256
38+
# n_bootstrap: 10

src/qibocal/auto/runcard.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
"""Specify runcard layout, handles (de)serialization."""
2+
import os
23
from functools import cached_property
34
from typing import Any, NewType, Optional, Union
45

@@ -47,10 +48,9 @@ class Runcard:
4748
"""Structure of an execution runcard."""
4849

4950
actions: list[Action]
50-
qubits: Union[list[QubitId], list[tuple[QubitId, QubitId]]]
51+
qubits: Optional[Union[list[QubitId], list[tuple[QubitId, QubitId]]]] = None
5152
backend: str = "qibolab"
52-
platform: str = "dummy"
53-
# TODO: pass custom runcard (?)
53+
platform: str = os.environ.get("QIBO_PLATFORM", "dummy")
5454

5555
@cached_property
5656
def backend_obj(self) -> Backend:

src/qibocal/cli/_base.py

+40-7
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import click
66
import yaml
77

8+
from ..auto.runcard import Runcard
89
from .acquisition import acquire as acquisition
910
from .autocalibration import autocalibrate
1011
from .fit import fit as fitting
@@ -43,23 +44,39 @@ def command():
4344
help="Use --no-update option to avoid updating iteratively the platform."
4445
"With this option the new runcard will not be produced.",
4546
)
46-
def auto(runcard, folder, force, update):
47+
@click.option(
48+
"--platform",
49+
default=None,
50+
help="Name of the Qibolab platform.",
51+
)
52+
@click.option(
53+
"--backend",
54+
default=None,
55+
help="Name of the Qibo backend.,",
56+
)
57+
def auto(runcard, folder, force, update, platform, backend):
4758
"""Autocalibration
4859
4960
Arguments:
5061
5162
- RUNCARD: runcard with declarative inputs.
5263
"""
53-
card = yaml.safe_load(runcard.read_text(encoding="utf-8"))
54-
autocalibrate(card, folder, force, update)
64+
runcard = Runcard.load(yaml.safe_load(runcard.read_text(encoding="utf-8")))
65+
66+
if platform is not None:
67+
runcard.platform = platform
68+
if backend is not None:
69+
runcard.backend = backend
70+
71+
autocalibrate(runcard, folder, force, update)
5572

5673

5774
@command.command(context_settings=CONTEXT_SETTINGS)
5875
@click.argument(
5976
"runcard", metavar="RUNCARD", type=click.Path(exists=True, path_type=pathlib.Path)
6077
)
6178
@click.option(
62-
"folder",
79+
"--folder",
6380
"-o",
6481
type=click.Path(path_type=pathlib.Path),
6582
help="Output folder. If not provided a standard name will generated.",
@@ -70,15 +87,31 @@ def auto(runcard, folder, force, update):
7087
is_flag=True,
7188
help="Use --force option to overwrite the output folder.",
7289
)
73-
def acquire(runcard, folder, force):
90+
@click.option(
91+
"--platform",
92+
default=None,
93+
help="Name of the Qibolab platform.",
94+
)
95+
@click.option(
96+
"--backend",
97+
default=None,
98+
help="Name of the Qibo backend.,",
99+
)
100+
def acquire(runcard, folder, force, platform, backend):
74101
"""Data acquisition
75102
76103
Arguments:
77104
78105
- RUNCARD: runcard with declarative inputs.
79106
"""
80-
card = yaml.safe_load(runcard.read_text(encoding="utf-8"))
81-
acquisition(card, folder, force)
107+
runcard = Runcard.load(yaml.safe_load(runcard.read_text(encoding="utf-8")))
108+
109+
if platform is not None:
110+
runcard.platform = platform
111+
if backend is not None:
112+
runcard.backend = backend
113+
114+
acquisition(runcard, folder, force)
82115

83116

84117
@command.command(context_settings=CONTEXT_SETTINGS)

src/qibocal/cli/acquisition.py

+12-11
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
from ..auto.execute import Executor
99
from ..auto.history import add_timings_to_meta
1010
from ..auto.mode import ExecutionMode
11-
from ..auto.runcard import Runcard
1211
from .utils import (
1312
META,
1413
PLATFORM,
@@ -19,33 +18,34 @@
1918
)
2019

2120

22-
def acquire(card, folder, force):
21+
def acquire(runcard, folder, force):
2322
"""Data acquisition
2423
2524
Arguments:
2625
2726
- RUNCARD: runcard with declarative inputs.
2827
"""
29-
# load and initialize Runcard from file
30-
runcard = Runcard.load(card)
3128

29+
# rename for brevity
30+
backend = runcard.backend_obj
31+
platform = runcard.platform_obj
3232
# generate output folder
3333
path = generate_output_folder(folder, force)
34-
# generate meta
35-
meta = generate_meta(runcard, path)
3634

35+
# set backend, platform and qubits
36+
qubits = create_qubits_dict(qubits=runcard.qubits, platform=platform)
37+
38+
# generate meta
39+
meta = generate_meta(backend, platform, path)
3740
# dump platform
38-
if runcard.backend == "qibolab":
39-
dump_runcard(runcard.platform_obj, path / PLATFORM)
41+
if backend.name == "qibolab":
42+
dump_runcard(platform, path / PLATFORM)
4043

4144
# dump action runcard
4245
(path / RUNCARD).write_text(yaml.safe_dump(asdict(runcard)))
4346
# dump meta
4447
(path / META).write_text(json.dumps(meta, indent=4))
4548

46-
# allocate qubits, runcard and executor
47-
qubits = create_qubits_dict(runcard)
48-
platform = runcard.platform_obj
4949
executor = Executor.load(runcard, path, platform, qubits)
5050

5151
# connect and initialize platform
@@ -59,6 +59,7 @@ def acquire(card, folder, force):
5959

6060
e = datetime.datetime.now(datetime.timezone.utc)
6161
meta["end-time"] = e.strftime("%H:%M:%S")
62+
6263
# stop and disconnect platform
6364
if platform is not None:
6465
platform.stop()

src/qibocal/cli/autocalibration.py

+18-15
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
from ..auto.execute import Executor
99
from ..auto.history import add_timings_to_meta
1010
from ..auto.mode import ExecutionMode
11-
from ..auto.runcard import Runcard
1211
from ..cli.report import ReportBuilder
1312
from .utils import (
1413
META,
@@ -21,32 +20,35 @@
2120
)
2221

2322

24-
def autocalibrate(card, folder, force, update):
23+
def autocalibrate(runcard, folder, force, update):
2524
"""Autocalibration
2625
2726
Arguments:
2827
2928
- RUNCARD: runcard with declarative inputs.
3029
"""
31-
# load and initialize Runcard from file
32-
runcard = Runcard.load(card)
3330

31+
# rename for brevity
32+
backend = runcard.backend_obj
33+
platform = runcard.platform_obj
3434
# generate output folder
3535
path = generate_output_folder(folder, force)
36-
# generate meta
37-
meta = generate_meta(runcard, path)
3836

37+
# allocate qubits
38+
qubits = create_qubits_dict(qubits=runcard.qubits, platform=platform)
39+
40+
# generate meta
41+
meta = generate_meta(backend, platform, path)
3942
# dump platform
40-
if runcard.backend == "qibolab":
41-
dump_runcard(runcard.platform_obj, path / PLATFORM)
43+
if backend.name == "qibolab":
44+
dump_runcard(platform, path / PLATFORM)
45+
4246
# dump action runcard
4347
(path / RUNCARD).write_text(yaml.safe_dump(asdict(runcard)))
4448
# dump meta
4549
(path / META).write_text(json.dumps(meta, indent=4))
4650

47-
# allocate qubits, runcard and executor
48-
qubits = create_qubits_dict(runcard)
49-
platform = runcard.platform_obj
51+
# allocate executor
5052
executor = Executor.load(runcard, path, platform, qubits, update)
5153

5254
# connect and initialize platform
@@ -55,13 +57,14 @@ def autocalibrate(card, folder, force, update):
5557
platform.setup()
5658
platform.start()
5759

58-
e = datetime.datetime.now(datetime.timezone.utc)
59-
meta["end-time"] = e.strftime("%H:%M:%S")
6060
# run protocols
61-
for task_uid in executor.run(mode=ExecutionMode.autocalibration):
62-
report = ReportBuilder(path, runcard.qubits, executor, meta, executor.history)
61+
for _ in executor.run(mode=ExecutionMode.autocalibration):
62+
report = ReportBuilder(path, qubits, executor, meta, executor.history)
6363
report.run(path)
6464

65+
e = datetime.datetime.now(datetime.timezone.utc)
66+
meta["end-time"] = e.strftime("%H:%M:%S")
67+
6568
# stop and disconnect platform
6669
if platform is not None:
6770
platform.stop()

src/qibocal/cli/fit.py

+21-9
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import json
33

44
import yaml
5+
from qibo.backends import GlobalBackend
56
from qibolab.serialize import dump_runcard
67

78
from ..auto.execute import Executor
@@ -19,23 +20,34 @@ def fit(path, update):
1920
- FOLDER: input folder.
2021
2122
"""
22-
# load path, meta, runcard and executor
23-
meta = yaml.safe_load((path / META).read_text())
23+
# load meta
24+
meta = json.loads((path / META).read_text())
25+
# load runcard
2426
runcard = Runcard.load(yaml.safe_load((path / RUNCARD).read_text()))
25-
qubits = create_qubits_dict(runcard)
27+
28+
# set backend, platform and qubits
29+
GlobalBackend.set_backend(backend=meta["backend"], platform=meta["platform"])
30+
backend = GlobalBackend()
31+
platform = backend.platform
32+
qubits = create_qubits_dict(qubits=runcard.qubits, platform=platform)
33+
34+
# load executor
2635
executor = Executor.load(
27-
runcard, path, update=update, platform=runcard.platform_obj, qubits=qubits
36+
runcard, path, update=update, platform=platform, qubits=qubits
2837
)
2938

3039
# perform post-processing
3140
list(executor.run(mode=ExecutionMode.fit))
3241

33-
# dump updated runcard
34-
if runcard.platform_obj is not None and update:
35-
dump_runcard(runcard.platform_obj, path / UPDATED_PLATFORM)
36-
37-
# update time in meta.yml
42+
# update time in meta
3843
meta = add_timings_to_meta(meta, executor.history)
3944
e = datetime.datetime.now(datetime.timezone.utc)
4045
meta["end-time"] = e.strftime("%H:%M:%S")
46+
47+
# dump updated runcard
48+
if platform is not None and update: # pragma: no cover
49+
# cannot test update since dummy may produce wrong values and trigger errors
50+
dump_runcard(platform, path / UPDATED_PLATFORM)
51+
52+
# dump json
4153
(path / META).write_text(json.dumps(meta, indent=4))

src/qibocal/cli/report.py

+13-4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1+
import json
12
import tempfile
23
from functools import cached_property
34
from pathlib import Path
45

56
import yaml
7+
from qibo.backends import GlobalBackend
68
from qibolab.qubits import QubitId
79

810
from qibocal.auto.execute import Executor
@@ -26,15 +28,22 @@ def report(path):
2628
- FOLDER: input folder.
2729
2830
"""
29-
# load path, meta and runcard
30-
meta = yaml.safe_load((path / META).read_text())
31+
# load meta
32+
meta = json.loads((path / META).read_text())
33+
# load runcard
3134
runcard = Runcard.load(yaml.safe_load((path / RUNCARD).read_text()))
32-
qubits = create_qubits_dict(runcard)
35+
36+
# set backend, platform and qubits
37+
GlobalBackend.set_backend(backend=meta["backend"], platform=meta["platform"])
38+
backend = GlobalBackend()
39+
platform = backend.platform
40+
qubits = create_qubits_dict(qubits=runcard.qubits, platform=platform)
41+
3342
# load executor
3443
executor = Executor.load(runcard, path, qubits=qubits)
3544

3645
# produce html
37-
builder = ReportBuilder(path, runcard.qubits, executor, meta)
46+
builder = ReportBuilder(path, qubits, executor, meta)
3847
builder.run(path)
3948

4049

0 commit comments

Comments
 (0)