Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: m-labs/artiq
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 2456e795dd2d
Choose a base ref
...
head repository: m-labs/artiq
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: efd1c24ed726
Choose a head ref
  • 4 commits
  • 10 files changed
  • 1 contributor

Commits on Apr 7, 2015

  1. Copy the full SHA
    5e046dc View commit details
  2. Copy the full SHA
    fda4ee1 View commit details
  3. Copy the full SHA
    ca89b6d View commit details
  4. Copy the full SHA
    efd1c24 View commit details
Showing with 135 additions and 44 deletions.
  1. +9 −6 artiq/coredevice/core.py
  2. +74 −0 artiq/frontend/artiq_compile.py
  3. +4 −27 artiq/frontend/artiq_run.py
  4. +1 −1 artiq/language/db.py
  5. +7 −6 artiq/master/worker_db.py
  6. +23 −0 artiq/tools.py
  7. +4 −3 artiq/transforms/inline.py
  8. +1 −0 conda/artiq/meta.yaml
  9. +11 −1 doc/manual/utilities.rst
  10. +1 −0 setup.py
15 changes: 9 additions & 6 deletions artiq/coredevice/core.py
Original file line number Diff line number Diff line change
@@ -103,20 +103,23 @@ def transform_stack(self, func_def, rpc_map, exception_map,
remove_dead_code(func_def)
debug_unparse("remove_dead_code_2", func_def)

def run(self, k_function, k_args, k_kwargs):
# transform/simplify AST
def compile(self, k_function, k_args, k_kwargs, with_attr_writeback=True):
debug_unparse = _make_debug_unparse("remove_dead_code_2")

func_def, rpc_map, exception_map = inline(
self, k_function, k_args, k_kwargs)
self, k_function, k_args, k_kwargs, with_attr_writeback)
debug_unparse("inline", func_def)

self.transform_stack(func_def, rpc_map, exception_map, debug_unparse)

# compile to machine code and run
binary = get_runtime_binary(self.runtime_env, func_def)

return binary, rpc_map, exception_map

def run(self, k_function, k_args, k_kwargs):
binary, rpc_map, exception_map = self.compile(
k_function, k_args, k_kwargs)
self.comm.load(binary)
self.comm.run(func_def.name)
self.comm.run(k_function.__name__)
self.comm.serve(rpc_map, exception_map)

@kernel
74 changes: 74 additions & 0 deletions artiq/frontend/artiq_compile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#!/usr/bin/env python3

import logging
import argparse

from artiq.protocols.file_db import FlatFileDB
from artiq.master.worker_db import DBHub
from artiq.tools import *


logger = logging.getLogger(__name__)


def get_argparser():
parser = argparse.ArgumentParser(description="ARTIQ static compiler")

verbosity_args(parser)
parser.add_argument("-d", "--ddb", default="ddb.pyon",
help="device database file")
parser.add_argument("-p", "--pdb", default="pdb.pyon",
help="parameter database file")

parser.add_argument("-e", "--experiment", default=None,
help="experiment to compile")

parser.add_argument("-o", "--output", default=None,
help="output file")
parser.add_argument("file",
help="file containing the experiment to compile")
parser.add_argument("arguments", nargs="*", help="run arguments")

return parser


def main():
args = get_argparser().parse_args()
init_logger(args)

ddb = FlatFileDB(args.ddb)
pdb = FlatFileDB(args.pdb)
dbh = DBHub(ddb, pdb, rdb=None, read_only=True)

try:
module = file_import(args.file)
exp = get_experiment(module, args.experiment)
arguments = parse_arguments(args.arguments)
exp_inst = exp(dbh, **arguments)

if (not hasattr(exp.run, "k_function_info")
or not exp.run.k_function_info):
raise ValueError("Experiment entry point must be a kernel")
core_name = exp.run.k_function_info.core_name
core = getattr(exp_inst, core_name)

binary, rpc_map, _ = core.compile(exp.run.k_function_info.k_function,
[exp_inst], {},
with_attr_writeback=False)
finally:
dbh.close_devices()

if rpc_map:
raise ValueError("Experiment must not use RPC")

output = args.output
if output is None:
output = args.file
if output.endswith(".py"):
output = output[:-3]
output += ".elf"
with open(output, "wb") as f:
f.write(binary)

if __name__ == "__main__":
main()
31 changes: 4 additions & 27 deletions artiq/frontend/artiq_run.py
Original file line number Diff line number Diff line change
@@ -10,11 +10,10 @@
import h5py

from artiq.language.db import *
from artiq.language.experiment import is_experiment, Experiment
from artiq.protocols import pyon
from artiq.language.experiment import Experiment
from artiq.protocols.file_db import FlatFileDB
from artiq.master.worker_db import DBHub, ResultDB
from artiq.tools import file_import, verbosity_args, init_logger
from artiq.tools import *


logger = logging.getLogger(__name__)
@@ -99,28 +98,6 @@ def get_argparser(with_file=True):
return parser


def _parse_arguments(arguments):
d = {}
for argument in arguments:
name, eq, value = argument.partition("=")
d[name] = pyon.decode(value)
return d


def _get_experiment(module, experiment=None):
if experiment:
return getattr(module, experiment)

exps = [(k, v) for k, v in module.__dict__.items()
if is_experiment(v)]
if not exps:
logger.error("No experiments in module")
if len(exps) > 1:
logger.warning("Multiple experiments (%s), using first",
", ".join(k for (k, v) in exps))
return exps[0][1]


def _build_experiment(dbh, args):
if hasattr(args, "file"):
if args.file.endswith(".elf"):
@@ -136,8 +113,8 @@ def _build_experiment(dbh, args):
else:
module = sys.modules["__main__"]
file = getattr(module, "__file__")
exp = _get_experiment(module, args.experiment)
arguments = _parse_arguments(args.arguments)
exp = get_experiment(module, args.experiment)
arguments = parse_arguments(args.arguments)
return exp(dbh,
scheduler=DummyScheduler(),
run_params=dict(file=file,
2 changes: 1 addition & 1 deletion artiq/language/db.py
Original file line number Diff line number Diff line change
@@ -82,7 +82,7 @@ def __init__(self, dbh=None, **kwargs):
raise KeyError("Device '{}' not found".format(k))
object.__setattr__(self, k, dev)
self.build()
if self.dbh is not None:
if self.dbh is not None and self.realtime_results:
self.dbh.add_rt_results(self.realtime_results)

def __getattr__(self, name):
13 changes: 7 additions & 6 deletions artiq/master/worker_db.py
Original file line number Diff line number Diff line change
@@ -84,17 +84,18 @@ def _create_device(desc, dbh):
class DBHub:
"""Connects device, parameter and result databases to experiment.
Handle device driver creation and destruction.
"""
def __init__(self, ddb, pdb, rdb):
def __init__(self, ddb, pdb, rdb, read_only=False):
self.ddb = ddb
self.active_devices = OrderedDict()

self.get_parameter = pdb.request
self.set_parameter = pdb.set
self.add_rt_results = rdb.add_rt_results
self.get_result = rdb.request
self.set_result = rdb.set

if not read_only:
self.set_parameter = pdb.set
self.add_rt_results = rdb.add_rt_results
self.get_result = rdb.request
self.set_result = rdb.set

def get_device(self, name):
if name in self.active_devices:
23 changes: 23 additions & 0 deletions artiq/tools.py
Original file line number Diff line number Diff line change
@@ -7,6 +7,16 @@
import time
import os.path

from artiq.language.experiment import is_experiment
from artiq.protocols import pyon


def parse_arguments(arguments):
d = {}
for argument in arguments:
name, eq, value = argument.partition("=")
d[name] = pyon.decode(value)
return d

def format_arguments(arguments):
fmtargs = []
@@ -41,6 +51,19 @@ def file_import(filename):
return module


def get_experiment(module, experiment=None):
if experiment:
return getattr(module, experiment)

exps = [(k, v) for k, v in module.__dict__.items()
if is_experiment(v)]
if not exps:
raise ValueError("No experiments in module")
if len(exps) > 1:
raise ValueError("More than one experiment found in module")
return exps[0][1]


def verbosity_args(parser):
group = parser.add_argument_group("verbosity")
group.add_argument("-v", "--verbose", default=0, action="count",
7 changes: 4 additions & 3 deletions artiq/transforms/inline.py
Original file line number Diff line number Diff line change
@@ -467,7 +467,7 @@ def get_attr_writeback(attribute_namespace, rpc_mapper, loc_node):
return attr_writeback


def inline(core, k_function, k_args, k_kwargs):
def inline(core, k_function, k_args, k_kwargs, with_attr_writeback):
# OrderedDict prevents non-determinism in attribute init
attribute_namespace = OrderedDict()
in_use_names = copy(embeddable_func_names)
@@ -486,7 +486,8 @@ def inline(core, k_function, k_args, k_kwargs):
kwargs=k_kwargs)

func_def.body[0:0] = get_attr_init(attribute_namespace, func_def)
func_def.body += get_attr_writeback(attribute_namespace, mappers.rpc,
func_def)
if with_attr_writeback:
func_def.body += get_attr_writeback(attribute_namespace, mappers.rpc,
func_def)

return func_def, mappers.rpc.get_map(), mappers.exception.get_map()
1 change: 1 addition & 0 deletions conda/artiq/meta.yaml
Original file line number Diff line number Diff line change
@@ -10,6 +10,7 @@ build:
number: {{ environ.get("GIT_DESCRIBE_NUMBER", 0) }}
entry_points:
- artiq_client = artiq.frontend.artiq_client:main
- artiq_compile = artiq.frontend.artiq_compile:main
- artiq_ctlmgr = artiq.frontend.artiq_ctlmgr:main
- artiq_master = artiq.frontend.artiq_master:main
- artiq_rpctool = artiq.frontend.artiq_rpctool:main
12 changes: 11 additions & 1 deletion doc/manual/utilities.rst
Original file line number Diff line number Diff line change
@@ -9,7 +9,7 @@ Local running tool
:prog: artiq_run

Remote Procedure Call tool
------------------------------
--------------------------

.. argparse::
:ref: artiq.frontend.artiq_rpctool.get_argparser
@@ -72,3 +72,13 @@ in order to call remote functions of an ARTIQ controller.

$ artiq_rpctool.py ::1 3253 call get_attenuation
5.0 dB

Static compiler
---------------

This tool compiles an experiment into a ELF file. It is primarily used to prepare binaries for the default experiment loaded in non-volatile storage of the core device.
Experiments compiled with this tool are not allowed to use RPCs, and their ``run`` entry point must be a kernel.

.. argparse::
:ref: artiq.frontend.artiq_compile.get_argparser
:prog: artiq_compile
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
@@ -11,6 +11,7 @@

scripts = [
"artiq_client=artiq.frontend.artiq_client:main",
"artiq_compile=artiq.frontend.artiq_compile:main",
"artiq_ctlmgr=artiq.frontend.artiq_ctlmgr:main",
"artiq_master=artiq.frontend.artiq_master:main",
"artiq_rpctool=artiq.frontend.artiq_rpctool:main",