forked from M-Labs/artiq
environment, artiq_run: introduce interactive arguments
This commit is contained in:
parent
a0450555e2
commit
7688f380b1
|
@ -41,6 +41,7 @@ Highlights:
|
|||
+ CTRL+SHIFT+C cascades experiment windows
|
||||
* Datasets can now be associated with units and scale factors, and displayed accordingly in the dashboard
|
||||
including applets, like widgets such as ``NumberValue`` already did in earlier ARTIQ versions.
|
||||
* Experiments can now request arguments interactively from the user at any time.
|
||||
* Persistent datasets are now stored in a LMDB database for improved performance.
|
||||
* Python's built-in types (such as ``float``, or ``List[...]``) can now be used in type annotations on
|
||||
kernel functions.
|
||||
|
|
|
@ -13,7 +13,7 @@ import h5py
|
|||
|
||||
from llvmlite import binding as llvm
|
||||
|
||||
from sipyco import common_args
|
||||
from sipyco import common_args, pyon
|
||||
|
||||
from artiq import __version__ as artiq_version
|
||||
from artiq.language.environment import EnvExperiment, ProcessArgumentManager
|
||||
|
@ -166,9 +166,28 @@ def get_argparser(with_file=True):
|
|||
return parser
|
||||
|
||||
|
||||
class ArgumentManager(ProcessArgumentManager):
|
||||
def get_interactive(self, interactive_arglist):
|
||||
result = dict()
|
||||
for key, processor, group, tooltip in interactive_arglist:
|
||||
success = False
|
||||
while not success:
|
||||
user_input = input("{}:{} (group={}, tooltip={}): ".format(
|
||||
key, type(processor).__name__, group, tooltip))
|
||||
try:
|
||||
user_input_deser = pyon.decode(user_input)
|
||||
value = processor.process(user_input_deser)
|
||||
except:
|
||||
logger.error("failed to process user input, retrying", exc_info=True)
|
||||
else:
|
||||
success = True
|
||||
result[key] = value
|
||||
return result
|
||||
|
||||
|
||||
def _build_experiment(device_mgr, dataset_mgr, args):
|
||||
arguments = parse_arguments(args.arguments)
|
||||
argument_mgr = ProcessArgumentManager(arguments)
|
||||
argument_mgr = ArgumentManager(arguments)
|
||||
managers = (device_mgr, dataset_mgr, argument_mgr, {})
|
||||
if hasattr(args, "file"):
|
||||
is_tar = tarfile.is_tarfile(args.file)
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
from collections import OrderedDict
|
||||
from inspect import isclass
|
||||
from contextlib import contextmanager
|
||||
from types import SimpleNamespace
|
||||
|
||||
from sipyco import pyon
|
||||
|
||||
|
@ -212,6 +214,9 @@ class TraceArgumentManager:
|
|||
self.requested_args[key] = processor, group, tooltip
|
||||
return None
|
||||
|
||||
def get_interactive(self, interactive_arglist):
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class ProcessArgumentManager:
|
||||
def __init__(self, unprocessed_arguments):
|
||||
|
@ -233,6 +238,10 @@ class ProcessArgumentManager:
|
|||
raise AttributeError("Supplied argument(s) not queried in experiment: " +
|
||||
", ".join(unprocessed))
|
||||
|
||||
def get_interactive(self, interactive_arglist):
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class HasEnvironment:
|
||||
"""Provides methods to manage the environment of an experiment (arguments,
|
||||
devices, datasets)."""
|
||||
|
@ -322,6 +331,28 @@ class HasEnvironment:
|
|||
kernel_invariants = getattr(self, "kernel_invariants", set())
|
||||
self.kernel_invariants = kernel_invariants | {key}
|
||||
|
||||
@contextmanager
|
||||
def interactive(self):
|
||||
"""Request arguments from the user interactively.
|
||||
|
||||
This context manager returns a namespace object on which the method
|
||||
`setattr_argument` should be called, with the usual semantics.
|
||||
|
||||
When the context manager terminates, the experiment is blocked
|
||||
and the user is presented with the requested argument widgets.
|
||||
After the user enters values, the experiment is resumed and
|
||||
the namespace contains the values of the arguments."""
|
||||
interactive_arglist = []
|
||||
namespace = SimpleNamespace()
|
||||
def setattr_argument(key, processor=None, group=None, tooltip=None):
|
||||
interactive_arglist.append((key, processor, group, tooltip))
|
||||
namespace.setattr_argument = setattr_argument
|
||||
yield namespace
|
||||
del namespace.setattr_argument
|
||||
argdict = self.__argument_mgr.get_interactive(interactive_arglist)
|
||||
for key, value in argdict.items():
|
||||
setattr(namespace, key, value)
|
||||
|
||||
def get_device_db(self):
|
||||
"""Returns the full contents of the device database."""
|
||||
return self.__device_mgr.get_device_db()
|
||||
|
|
Loading…
Reference in New Issue