Skip to content

Commit afc9607

Browse files
authored
Number of qubits in CLI job list view (#682)
1 parent 0bce301 commit afc9607

File tree

4 files changed

+94
-9
lines changed

4 files changed

+94
-9
lines changed

metriq_gym/cli.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,14 @@
2525
logger = logging.getLogger(__name__)
2626
logger.setLevel(logging.INFO)
2727

28-
LIST_JOBS_HEADERS = ["Metriq-gym Job Id", "Provider", "Device", "Type", "Dispatch time (UTC)"]
28+
LIST_JOBS_HEADERS = [
29+
"Metriq-gym Job Id",
30+
"Provider",
31+
"Device",
32+
"Type",
33+
"# Qubits",
34+
"Dispatch time (UTC)",
35+
]
2936
LIST_JOBS_HEADERS_FULL = ["Suite ID"] + LIST_JOBS_HEADERS
3037

3138
LATEST_JOB_ID = "latest"

metriq_gym/job_manager.py

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import os
1010
import pprint
1111
import logging
12-
from typing import Any
12+
from typing import Any, Sequence
1313

1414
from tabulate import tabulate
1515
from metriq_gym.constants import JobType
@@ -52,7 +52,23 @@ def __post_init__(self) -> None:
5252
plat["device"] = self.device_name
5353
self.platform = plat
5454

55-
def to_table_row(self, show_suite_id: bool) -> list[str | None]:
55+
def num_qubits(self) -> int | None:
56+
preferred_keys = ("num_qubits", "qubits", "width", "max_qubits")
57+
value: Any | None = None
58+
for key in preferred_keys:
59+
if key in self.params:
60+
value = self.params.get(key)
61+
break
62+
63+
if isinstance(value, bool):
64+
return None
65+
if isinstance(value, int):
66+
return value
67+
if isinstance(value, float) and value.is_integer():
68+
return int(value)
69+
return None
70+
71+
def to_table_row(self, show_suite_id: bool) -> Sequence[str | int | None]:
5672
return (
5773
[
5874
self.suite_id,
@@ -64,6 +80,7 @@ def to_table_row(self, show_suite_id: bool) -> list[str | None]:
6480
self.provider_name,
6581
self.device_name,
6682
self.job_type,
83+
self.num_qubits(),
6784
self.dispatch_time.isoformat(),
6885
]
6986

tests/unit/test_cli.py

Lines changed: 65 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,77 @@ def test_list_jobs_all(capsys):
4444

4545
# Expected output using tabulate
4646
table = [
47-
["1234", "ibm", "ibmq_qasm_simulator", "Quantum Volume", "2021-09-01T12:00:00"],
48-
["5678", "ionq", "ionq_simulator", "Quantum Volume", "2021-09-02T12:00:00"],
47+
["1234", "ibm", "ibmq_qasm_simulator", "Quantum Volume", None, "2021-09-01T12:00:00"],
48+
["5678", "ionq", "ionq_simulator", "Quantum Volume", None, "2021-09-02T12:00:00"],
4949
]
5050
expected_output = tabulate(table, headers=LIST_JOBS_HEADERS, tablefmt="grid") + "\n"
5151

5252
assert captured.out == expected_output
5353

5454

55+
def test_list_jobs_prefers_max_qubits_for_qft(capsys):
56+
mock_jobs = [
57+
MetriqGymJob(
58+
id="qft1",
59+
device_name="local_sim",
60+
provider_name="local",
61+
job_type=JobType.QUANTUM_FOURIER_TRANSFORM,
62+
dispatch_time=datetime.fromisoformat("2021-09-01T12:00:00"),
63+
params={"max_qubits": 6},
64+
data={},
65+
)
66+
]
67+
68+
list_jobs(mock_jobs, show_index=False, show_suite_id=False)
69+
captured = capsys.readouterr()
70+
71+
table = [["qft1", "local", "local_sim", "Quantum Fourier Transform", 6, "2021-09-01T12:00:00"]]
72+
expected_output = tabulate(table, headers=LIST_JOBS_HEADERS, tablefmt="grid") + "\n"
73+
assert captured.out == expected_output
74+
75+
76+
def test_list_jobs_uses_width_alias_for_num_qubits(capsys):
77+
mock_jobs = [
78+
MetriqGymJob(
79+
id="mc1",
80+
device_name="local_sim",
81+
provider_name="local",
82+
job_type=JobType.MIRROR_CIRCUITS,
83+
dispatch_time=datetime.fromisoformat("2021-09-01T12:00:00"),
84+
params={"width": 11, "max_qubits": 20},
85+
data={},
86+
)
87+
]
88+
89+
list_jobs(mock_jobs, show_index=False, show_suite_id=False)
90+
captured = capsys.readouterr()
91+
92+
table = [["mc1", "local", "local_sim", "Mirror Circuits", 11, "2021-09-01T12:00:00"]]
93+
expected_output = tabulate(table, headers=LIST_JOBS_HEADERS, tablefmt="grid") + "\n"
94+
assert captured.out == expected_output
95+
96+
97+
def test_list_jobs_uses_qubits_alias_for_num_qubits(capsys):
98+
mock_jobs = [
99+
MetriqGymJob(
100+
id="q2",
101+
device_name="local_sim",
102+
provider_name="local",
103+
job_type=JobType.WIT,
104+
dispatch_time=datetime.fromisoformat("2021-09-01T12:00:00"),
105+
params={"qubits": 9},
106+
data={},
107+
)
108+
]
109+
110+
list_jobs(mock_jobs, show_index=False, show_suite_id=False)
111+
captured = capsys.readouterr()
112+
113+
table = [["q2", "local", "local_sim", "WIT", 9, "2021-09-01T12:00:00"]]
114+
expected_output = tabulate(table, headers=LIST_JOBS_HEADERS, tablefmt="grid") + "\n"
115+
assert captured.out == expected_output
116+
117+
55118
def test_list_jobs_no_jobs(capsys):
56119
"""Test listing jobs when no jobs are recorded."""
57120
# Mock no jobs

uv.lock

Lines changed: 2 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)