From 5df07218117819352cb8b35c10056858d66ad065 Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Sun, 17 Dec 2023 19:43:41 +0800 Subject: [PATCH] dashboard,client: add device argument overrides to expid --- artiq/dashboard/experiments.py | 30 ++++++++++++++++++++++++++++-- artiq/frontend/artiq_client.py | 6 +++++- artiq/tools.py | 27 ++++++++++++++++++++++++++- 3 files changed, 59 insertions(+), 4 deletions(-) diff --git a/artiq/dashboard/experiments.py b/artiq/dashboard/experiments.py index 762a85df2..8526fdf32 100644 --- a/artiq/dashboard/experiments.py +++ b/artiq/dashboard/experiments.py @@ -13,6 +13,7 @@ from artiq.gui.entries import procdesc_to_entry, ScanEntry from artiq.gui.fuzzy_select import FuzzySelectWidget from artiq.gui.tools import (LayoutWidget, WheelFilter, log_level_to_name, get_open_file_name) +from artiq.tools import parse_devarg_override, unparse_devarg_override logger = logging.getLogger(__name__) @@ -305,7 +306,7 @@ class _ExperimentDock(QtWidgets.QMdiSubWindow): flush = self.flush flush.setToolTip("Flush the pipeline (of current- and higher-priority " "experiments) before starting the experiment") - self.layout.addWidget(flush, 2, 2, 1, 2) + self.layout.addWidget(flush, 2, 2) flush.setChecked(scheduling["flush"]) @@ -313,6 +314,20 @@ class _ExperimentDock(QtWidgets.QMdiSubWindow): scheduling["flush"] = bool(checked) flush.stateChanged.connect(update_flush) + devarg_override = QtWidgets.QComboBox() + devarg_override.setEditable(True) + devarg_override.lineEdit().setPlaceholderText("Override device arguments") + devarg_override.lineEdit().setClearButtonEnabled(True) + devarg_override.insertItem(0, "core:analyze_at_run_end=True") + self.layout.addWidget(devarg_override, 2, 3) + + devarg_override.setCurrentText(options["devarg_override"]) + + def update_devarg_override(text): + options["devarg_override"] = text + devarg_override.editTextChanged.connect(update_devarg_override) + self.devarg_override = devarg_override + log_level = QtWidgets.QComboBox() log_level.addItems(log_levels) log_level.setCurrentIndex(1) @@ -466,6 +481,9 @@ class _ExperimentDock(QtWidgets.QMdiSubWindow): return try: + if "devarg_override" in expid: + self.devarg_override.setCurrentText( + unparse_devarg_override(expid["devarg_override"])) self.log_level.setCurrentIndex(log_levels.index( log_level_to_name(expid["log_level"]))) if ("repo_rev" in expid and @@ -639,7 +657,8 @@ class ExperimentManager: else: # mutated by _ExperimentDock options = { - "log_level": logging.WARNING + "log_level": logging.WARNING, + "devarg_override": "" } if expurl[:5] == "repo:": options["repo_rev"] = None @@ -734,7 +753,14 @@ class ExperimentManager: entry_cls = procdesc_to_entry(argument["desc"]) argument_values[name] = entry_cls.state_to_value(argument["state"]) + try: + devarg_override = parse_devarg_override(options["devarg_override"]) + except: + logger.error("Failed to parse device argument overrides for %s", expurl) + return + expid = { + "devarg_override": devarg_override, "log_level": options["log_level"], "file": file, "class_name": class_name, diff --git a/artiq/frontend/artiq_client.py b/artiq/frontend/artiq_client.py index 4e7667465..d945f6853 100755 --- a/artiq/frontend/artiq_client.py +++ b/artiq/frontend/artiq_client.py @@ -23,7 +23,8 @@ from sipyco.sync_struct import Subscriber from sipyco.broadcast import Receiver from sipyco import common_args, pyon -from artiq.tools import scale_from_metadata, short_format, parse_arguments +from artiq.tools import (scale_from_metadata, short_format, parse_arguments, + parse_devarg_override) from artiq import __version__ as artiq_version @@ -68,6 +69,8 @@ def get_argparser(): parser_add.add_argument("-r", "--revision", default=None, help="use a specific repository revision " "(defaults to head, ignored without -R)") + parser_add.add_argument("--devarg-override", default="", + help="specify device arguments to override") parser_add.add_argument("--content", default=False, action="store_true", help="submit by content") @@ -146,6 +149,7 @@ def _action_submit(remote, args): raise ValueError("Failed to parse run arguments") from err expid = { + "devarg_override": parse_devarg_override(args.devarg_override), "log_level": logging.WARNING + args.quiet*10 - args.verbose*10, "class_name": args.class_name, "arguments": arguments, diff --git a/artiq/tools.py b/artiq/tools.py index dec615b51..46c0ce2f7 100644 --- a/artiq/tools.py +++ b/artiq/tools.py @@ -18,7 +18,9 @@ from artiq.language.environment import is_public_experiment from artiq.language import units -__all__ = ["parse_arguments", "elide", "scale_from_metadata", +__all__ = ["parse_arguments", + "parse_devarg_override", "unparse_devarg_override", + "elide", "scale_from_metadata", "short_format", "file_import", "get_experiment", "exc_to_warning", "asyncio_wait_or_cancel", @@ -36,6 +38,29 @@ def parse_arguments(arguments): return d +def parse_devarg_override(devarg_override): + devarg_override_dict = {} + for item in devarg_override.split(): + device, _, override = item.partition(":") + if not override: + raise ValueError + if device not in devarg_override_dict: + devarg_override_dict[device] = {} + argument, _, value = override.partition("=") + if not value: + raise ValueError + devarg_override_dict[device][argument] = pyon.decode(value) + return devarg_override_dict + + +def unparse_devarg_override(devarg_override): + devarg_override_strs = [ + "{}:{}={}".format(device, argument, pyon.encode(value)) + for device, overrides in devarg_override.items() + for argument, value in overrides.items()] + return " ".join(devarg_override_strs) + + def elide(s, maxlen): elided = False if len(s) > maxlen: