From 8674875007b57266449dbdcefde7038290a98de8 Mon Sep 17 00:00:00 2001 From: Robert Jordens Date: Mon, 18 Jan 2016 21:28:09 -0700 Subject: [PATCH 01/10] versioneer: remote tag_prefix = v does not seem to be stripped correctly --- artiq/_version.py | 2 +- setup.cfg | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/artiq/_version.py b/artiq/_version.py index e552924ec..97f363f57 100644 --- a/artiq/_version.py +++ b/artiq/_version.py @@ -41,7 +41,7 @@ def get_config(): cfg = VersioneerConfig() cfg.VCS = "git" cfg.style = "pep440" - cfg.tag_prefix = "v" + cfg.tag_prefix = "" cfg.parentdir_prefix = "artiq-" cfg.versionfile_source = "artiq/_version.py" cfg.verbose = False diff --git a/setup.cfg b/setup.cfg index cd2bed54b..c8d846cbf 100644 --- a/setup.cfg +++ b/setup.cfg @@ -3,5 +3,5 @@ VCS = git style = pep440 versionfile_source = artiq/_version.py versionfile_build = artiq/_version.py -tag_prefix = v +tag_prefix = parentdir_prefix = artiq- From cf17be92e3c651a2aa635eb55d20a7835b0e5900 Mon Sep 17 00:00:00 2001 From: Robert Jordens Date: Mon, 18 Jan 2016 21:41:42 -0700 Subject: [PATCH 02/10] doc: add artiq_flash --- artiq/frontend/artiq_flash.py | 7 ++++++- doc/manual/utilities.rst | 11 +++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/artiq/frontend/artiq_flash.py b/artiq/frontend/artiq_flash.py index 2cc1bd6c1..df3b330a0 100755 --- a/artiq/frontend/artiq_flash.py +++ b/artiq/frontend/artiq_flash.py @@ -10,7 +10,7 @@ import artiq from artiq.frontend.bit2bin import bit2bin -def main(): +def get_argparser(): parser = argparse.ArgumentParser( formatter_class=argparse.RawDescriptionHelpFormatter, description="ARTIQ flashing/deployment tool", @@ -43,6 +43,11 @@ Prerequisites: parser.add_argument("ACTION", nargs="*", default="proxy bitstream bios runtime start".split(), help="actions to perform, default: %(default)s") + return parser + + +def main(): + parser = get_argparser() opts = parser.parse_args() config = { diff --git a/doc/manual/utilities.rst b/doc/manual/utilities.rst index c7d9e7274..c79f6cc6a 100644 --- a/doc/manual/utilities.rst +++ b/doc/manual/utilities.rst @@ -1,6 +1,10 @@ Utilities ========= +.. Sort these tool by some subjective combination of their + typical sequence and expected frequency of use. + + Local running tool ------------------ @@ -93,6 +97,13 @@ This tool compiles key/value pairs into a binary image suitable for flashing int :ref: artiq.frontend.artiq_mkfs.get_argparser :prog: artiq_mkfs +Flashing/Loading tool +--------------------- + +.. argparse:: + :ref: artiq.frontend.artiq_flash.get_argparser + :prog: artiq_flash + .. _core-device-configuration-tool: Core device configuration tool From 1d7858c7bc7428aaa9f8e0cee92eb9f1630539f3 Mon Sep 17 00:00:00 2001 From: whitequark Date: Tue, 19 Jan 2016 18:52:36 +0000 Subject: [PATCH 03/10] Fix formatting. --- artiq/test/harness.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/artiq/test/harness.py b/artiq/test/harness.py index e3bc15fcc..9828dc462 100644 --- a/artiq/test/harness.py +++ b/artiq/test/harness.py @@ -13,13 +13,13 @@ import sys, os, argparse, importlib def main(): parser = argparse.ArgumentParser(description=__doc__) - parser.add_argument('-m', metavar='mod', type=str, - help='run library module as a script') - parser.add_argument('args', type=str, nargs='+', - help='arguments passed to program in sys.argv[1:]') + parser.add_argument("-m", metavar="mod", type=str, + help="run library module as a script") + parser.add_argument("args", type=str, nargs="+", + help="arguments passed to program in sys.argv[1:]") args = parser.parse_args(sys.argv[1:]) - artiq_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) + artiq_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) sys.path.insert(1, artiq_path) if args.m: @@ -28,7 +28,7 @@ def main(): else: sys.argv[1:] = args.args[1:] with open(args.args[0]) as f: - code = compile(f.read(), args.args[0], 'exec') + code = compile(f.read(), args.args[0], "exec") exec(code, globals()) if __name__ == "__main__": From e42fd9ca311e7ef57745ff2bfc6b42b1b68532b1 Mon Sep 17 00:00:00 2001 From: Robert Jordens Date: Tue, 19 Jan 2016 18:25:31 -0700 Subject: [PATCH 04/10] doc: use actual version --- doc/manual/conf.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/doc/manual/conf.py b/doc/manual/conf.py index 4568bae41..c92b30aa8 100644 --- a/doc/manual/conf.py +++ b/doc/manual/conf.py @@ -36,7 +36,9 @@ for module in mock_modules: # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. -#sys.path.insert(0, os.path.abspath('.')) +sys.path.insert(0, os.path.abspath('..')) + +from artiq._version import get_versions # -- General configuration ------------------------------------------------ @@ -73,9 +75,11 @@ copyright = '2014-2016, M-Labs Limited' # built documents. # # The short X.Y version. -version = 'prerelease' +# version = 'prerelease' # The full version, including alpha/beta/rc tags. -release = 'prerelease' +# release = 'prerelease' +release = get_versions()['version'] +version = release.split('+', 1)[0] # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. @@ -120,7 +124,7 @@ pygments_style = 'sphinx' # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. -html_theme = 'default' +html_theme = 'classic' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the From f0860beffd0143a543be3c76785c9a096fc5aee2 Mon Sep 17 00:00:00 2001 From: Robert Jordens Date: Tue, 19 Jan 2016 20:09:10 -0700 Subject: [PATCH 05/10] pdq2: wire up more of the pipeline --- artiq/devices/pdq2/driver.py | 8 ++- artiq/devices/pdq2/mediator.py | 3 +- artiq/wavesynth/coefficients.py | 4 +- .../coredevice_examples/transport.py | 49 +++++++++---------- 4 files changed, 31 insertions(+), 33 deletions(-) diff --git a/artiq/devices/pdq2/driver.py b/artiq/devices/pdq2/driver.py index d51a14992..088ac6df0 100644 --- a/artiq/devices/pdq2/driver.py +++ b/artiq/devices/pdq2/driver.py @@ -193,6 +193,8 @@ class Pdq2: def program_frame(self, frame_data): segments = [c.new_segment() for c in self.channels] + for segment in segments: + segment.line(typ=3, data=b"", trigger=True, duration=10, aux=1) for i, line in enumerate(frame_data): # segments are concatenated dac_divider = line.get("dac_divider", 1) shift = int(log(dac_divider, 2)) @@ -209,9 +211,11 @@ class Pdq2: shift=shift, duration=duration, trigger=trigger, **target_data) # append an empty line to stall the memory reader before jumping - # through the frame table + # through the frame table (`wait` does not prevent reading + # the next line) for segment in segments: - segment.line(typ=3, data=b"", trigger=True, duration=10) + segment.line(typ=3, data=b"", trigger=True, duration=1, + jump=True, aux=1) return segments def program(self, program): diff --git a/artiq/devices/pdq2/mediator.py b/artiq/devices/pdq2/mediator.py index 27265bf9e..3ce1cd420 100644 --- a/artiq/devices/pdq2/mediator.py +++ b/artiq/devices/pdq2/mediator.py @@ -111,6 +111,7 @@ class _Frame: "dac_divider": dac_divider, "duration": duration, "channel_data": channel_data, + "trigger": False, } for dac_divider, duration, channel_data in segment.lines] segment_program[0]["trigger"] = True r += segment_program @@ -156,7 +157,7 @@ class _Frame: class CompoundPDQ2: def __init__(self, dmgr, pdq2_devices, trigger_device, frame_devices): self.core = dmgr.get("core") - self.pdq2s = [dmgr.get(d) for d in self.pdq2_devices] + self.pdq2s = [dmgr.get(d) for d in pdq2_devices] self.trigger = dmgr.get(trigger_device) self.frame0 = dmgr.get(frame_devices[0]) self.frame1 = dmgr.get(frame_devices[1]) diff --git a/artiq/wavesynth/coefficients.py b/artiq/wavesynth/coefficients.py index b204b2ba0..6898785d7 100644 --- a/artiq/wavesynth/coefficients.py +++ b/artiq/wavesynth/coefficients.py @@ -143,14 +143,12 @@ class CoefficientSource: return build_segment(durations, coefficients, target=target, variable=variable) - def extend_segment(self, segment, trigger=True, *args, **kwargs): + def extend_segment(self, segment, *args, **kwargs): """Extend a wavesynth segment. See `get_segment()` for arguments. """ for i, line in enumerate(self.get_segment_data(*args, **kwargs)): - if i == 0: - line["trigger"] = trigger segment.add_line(**line) diff --git a/examples/master/repository/coredevice_examples/transport.py b/examples/master/repository/coredevice_examples/transport.py index 97c5abb7e..15f94666a 100644 --- a/examples/master/repository/coredevice_examples/transport.py +++ b/examples/master/repository/coredevice_examples/transport.py @@ -4,11 +4,11 @@ import numpy as np from artiq import * +from artiq.wavesynth.coefficients import SplineSource -# data is usually precomputed offline -transport_data = dict( - t=np.linspace(0, 10, 101), # waveform time - u=np.random.randn(101, 4*3*3), # waveform data, +transport = SplineSource( + x=np.linspace(0, 10, 101), # waveform time + y=np.random.rand(4*3*3, 101)*1e-6, # waveform data, # 4 devices, 3 board each, 3 dacs each ) @@ -16,37 +16,33 @@ class Transport(EnvExperiment): """Transport""" def build(self): - self.setattr_device("core") - self.setattr_device("bd") - self.setattr_device("bdd") - self.setattr_device("pmt") - self.setattr_device("electrodes") + self.core = self.get_device("core") + self.bd_sw = self.get_device("bd_sw") + self.pmt = self.get_device("pmt") + self.electrodes = self.get_device("electrodes") - self.setattr_argument("wait_at_stop", NumberValue(100*us)) - self.setattr_argument("speed", NumberValue(1.5)) - self.setattr_argument("repeats", NumberValue(100)) - self.setattr_argument("nbins", NumberValue(100)) + self.wait_at_stop = self.get_argument("wait_at_stop", + NumberValue(100*us)) + self.speed = self.get_argument("speed", NumberValue(1.5)) + self.repeats = self.get_argument("repeats", NumberValue(100)) + self.nbins = self.get_argument("nbins", NumberValue(100)) def calc_waveforms(self, stop): - t = transport_data["t"][:stop]*self.speed - u = transport_data["u"][:stop] - self.electrodes.disarm() self.tf = self.electrodes.create_frame() - self.tf.create_segment(t, u, name="to_stop") + to_stop = self.tf.create_segment("to_stop") + from_stop = self.tf.create_segment("from_stop") + transport.extend_segment(to_stop, 0, stop, scale=self.speed) # append the reverse transport (from stop to 0) # both durations are the same in this case - self.tf.create_segment(t[-1] - t[::-1], u[::-1], name="from_stop") + transport.extend_segment(from_stop, 0, stop, scale=self.speed) # distributes frames to the sub-devices in CompoundPDQ2 # and uploads them self.electrodes.arm() @kernel def cool(self): - with parallel: - self.bd.pulse(200*MHz, 1*ms) - self.bdd.pulse(300*MHz, 1*ms) - self.bd.pulse(210*MHz, 100*us) + self.bd_sw.pulse(1*ms) @kernel def transport(self): @@ -65,10 +61,9 @@ class Transport(EnvExperiment): @kernel def detect(self): with parallel: - self.bd.pulse(220*MHz, 100*us) + self.bd_sw.pulse(100*us) self.pmt.gate_rising(100*us) - self.bd.on(200*MHz) - self.bdd.on(300*MHz) + self.bd_sw.on() return self.pmt.count() @kernel @@ -79,7 +74,7 @@ class Transport(EnvExperiment): @kernel def repeat(self): - self.histogram = [0 for _ in range(self.nbins)] + self.histogram[:] = [0 for _ in range(self.nbins)] for i in range(self.repeats): n = self.one() @@ -100,5 +95,5 @@ class Transport(EnvExperiment): def run(self): # scan transport endpoint - stops = range(10, len(transport_data["t"]), 10) + stops = range(10, len(transport.x), 10) self.scan(stops) From 641ef57458a7c2a90e2c4f87437243c09744b197 Mon Sep 17 00:00:00 2001 From: Robert Jordens Date: Tue, 19 Jan 2016 20:16:27 -0700 Subject: [PATCH 06/10] pdq2/mediator: raise instances, not classes --- artiq/devices/pdq2/mediator.py | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/artiq/devices/pdq2/mediator.py b/artiq/devices/pdq2/mediator.py index 3ce1cd420..4d8bb65ff 100644 --- a/artiq/devices/pdq2/mediator.py +++ b/artiq/devices/pdq2/mediator.py @@ -45,9 +45,9 @@ class _Segment: def add_line(self, duration, channel_data, dac_divider=1): if self.frame.invalidated: - raise InvalidatedError + raise InvalidatedError() if self.frame.pdq.armed: - raise ArmError + raise ArmError() self.lines.append((dac_divider, duration, channel_data)) def get_duration(self): @@ -59,13 +59,13 @@ class _Segment: @kernel def advance(self): if self.frame.invalidated: - raise InvalidatedError + raise InvalidatedError() if not self.frame.pdq.armed: - raise ArmError + raise ArmError() # If a frame is currently being played, check that we are next. if (self.frame.pdq.current_frame >= 0 and self.frame.pdq.next_segment != self.segment_number): - raise SegmentSequenceError + raise SegmentSequenceError() self.frame.advance() @@ -83,9 +83,9 @@ class _Frame: def create_segment(self, name=None): if self.invalidated: - raise InvalidatedError + raise InvalidatedError() if self.pdq.armed: - raise ArmError + raise ArmError() segment = _Segment(self, self.segment_count) if name is not None: if hasattr(self, name): @@ -120,17 +120,17 @@ class _Frame: @kernel def advance(self): if self.invalidated: - raise InvalidatedError + raise InvalidatedError() if not self.pdq.armed: - raise ArmError + raise ArmError() call_t = now_mu() trigger_start_t = call_t - seconds_to_mu(trigger_duration/2) if self.pdq.current_frame >= 0: # PDQ is in the middle of a frame. Check it is us. - if self.frame.pdq.current_frame != self.frame_number: - raise FrameActiveError + if self.pdq.current_frame != self.frame_number: + raise FrameActiveError() else: # PDQ is in the jump table - set the selection signals # to play our first segment. @@ -176,7 +176,7 @@ class CompoundPDQ2: def arm(self): if self.armed: - raise ArmError + raise ArmError() for frame in self.frames: frame._arm() self.armed = True @@ -200,7 +200,7 @@ class CompoundPDQ2: def create_frame(self): if self.armed: - raise ArmError + raise ArmError() r = _Frame(self, len(self.frames)) self.frames.append(r) return r From 3573a8750aa46860b03df94c213c83fd7be84303 Mon Sep 17 00:00:00 2001 From: whitequark Date: Wed, 20 Jan 2016 03:20:25 +0000 Subject: [PATCH 07/10] transforms.inferencer: give a suggestion on "raise Exception". --- artiq/compiler/transforms/inferencer.py | 11 ++++++++++- artiq/test/lit/exceptions/error_raise_class.py | 5 +++++ 2 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 artiq/test/lit/exceptions/error_raise_class.py diff --git a/artiq/compiler/transforms/inferencer.py b/artiq/compiler/transforms/inferencer.py index 2a95c01e1..8432f9cae 100644 --- a/artiq/compiler/transforms/inferencer.py +++ b/artiq/compiler/transforms/inferencer.py @@ -1221,10 +1221,19 @@ class Inferencer(algorithm.Visitor): if node.exc is not None: exc_type = node.exc.type if not types.is_var(exc_type) and not builtins.is_exception(exc_type): + if types.is_exn_constructor(exc_type): + notes = [diagnostic.Diagnostic("note", + "this value is an exception constructor; use {suggestion} instead", + {"suggestion": node.exc.loc.source() + "()"}, + node.exc.loc)] + else: + notes = [] + diag = diagnostic.Diagnostic("error", "cannot raise a value of type {type}, which is not an exception", {"type": types.TypePrinter().name(exc_type)}, - node.exc.loc) + node.loc, + notes=notes) self.engine.process(diag) def visit_Assert(self, node): diff --git a/artiq/test/lit/exceptions/error_raise_class.py b/artiq/test/lit/exceptions/error_raise_class.py new file mode 100644 index 000000000..3c85f0dc8 --- /dev/null +++ b/artiq/test/lit/exceptions/error_raise_class.py @@ -0,0 +1,5 @@ +# RUN: %python -m artiq.compiler.testbench.signature +diag %s >%t +# RUN: OutputCheck %s --file-to-check=%t + +# CHECK-L: ${LINE:+1}: note: this value is an exception constructor; use IndexError() instead +raise IndexError From e664fe38b029a0cb425344be63a08d1cc4d98a68 Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Wed, 20 Jan 2016 09:18:50 -0500 Subject: [PATCH 08/10] targets/kc705: fix DDS_RTIO_CLK_RATIO for AD9914. Closes #238 --- artiq/gateware/targets/kc705.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/artiq/gateware/targets/kc705.py b/artiq/gateware/targets/kc705.py index 71c069281..4503c2b73 100755 --- a/artiq/gateware/targets/kc705.py +++ b/artiq/gateware/targets/kc705.py @@ -133,8 +133,6 @@ class _NIST_QCx(MiniSoC, AMPSoC): self.submodules.rtio_crg = _RTIOCRG(self.platform, self.crg.cd_sys.clk) self.submodules.rtio = rtio.RTIO(rtio_channels) self.config["RTIO_FINE_TS_WIDTH"] = self.rtio.fine_ts_width - assert self.rtio.fine_ts_width <= 3 - self.config["DDS_RTIO_CLK_RATIO"] = 8 >> self.rtio.fine_ts_width self.submodules.rtio_moninj = rtio.MonInj(rtio_channels) if isinstance(self.platform.toolchain, XilinxVivadoToolchain): @@ -198,6 +196,8 @@ class NIST_QC1(_NIST_QCx): rtio_channels.append(rtio.Channel.from_phy(phy)) self.config["RTIO_DDS_CHANNEL"] = len(rtio_channels) + assert self.rtio.fine_ts_width <= 3 + self.config["DDS_RTIO_CLK_RATIO"] = 8 >> self.rtio.fine_ts_width self.config["DDS_CHANNEL_COUNT"] = 8 self.config["DDS_AD9858"] = True phy = dds.AD9858(platform.request("dds"), 8) @@ -246,6 +246,8 @@ class NIST_QC2(_NIST_QCx): rtio_channels.append(rtio.Channel.from_phy(phy)) self.config["RTIO_DDS_CHANNEL"] = len(rtio_channels) + assert self.rtio.fine_ts_width <= 3 + self.config["DDS_RTIO_CLK_RATIO"] = 24 >> self.rtio.fine_ts_width self.config["DDS_CHANNEL_COUNT"] = 11 self.config["DDS_AD9914"] = True self.config["DDS_ONEHOT_SEL"] = True From cb5fd08713aa7d64a0c54df752cf1128ce138426 Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Wed, 20 Jan 2016 09:38:44 -0500 Subject: [PATCH 09/10] targets/kc705: fix e664fe3 --- artiq/gateware/targets/kc705.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/artiq/gateware/targets/kc705.py b/artiq/gateware/targets/kc705.py index 4503c2b73..6cefef172 100755 --- a/artiq/gateware/targets/kc705.py +++ b/artiq/gateware/targets/kc705.py @@ -196,8 +196,6 @@ class NIST_QC1(_NIST_QCx): rtio_channels.append(rtio.Channel.from_phy(phy)) self.config["RTIO_DDS_CHANNEL"] = len(rtio_channels) - assert self.rtio.fine_ts_width <= 3 - self.config["DDS_RTIO_CLK_RATIO"] = 8 >> self.rtio.fine_ts_width self.config["DDS_CHANNEL_COUNT"] = 8 self.config["DDS_AD9858"] = True phy = dds.AD9858(platform.request("dds"), 8) @@ -210,6 +208,8 @@ class NIST_QC1(_NIST_QCx): rtio_channels.append(rtio.LogChannel()) self.add_rtio(rtio_channels) + assert self.rtio.fine_ts_width <= 3 + self.config["DDS_RTIO_CLK_RATIO"] = 8 >> self.rtio.fine_ts_width class NIST_QC2(_NIST_QCx): @@ -246,8 +246,6 @@ class NIST_QC2(_NIST_QCx): rtio_channels.append(rtio.Channel.from_phy(phy)) self.config["RTIO_DDS_CHANNEL"] = len(rtio_channels) - assert self.rtio.fine_ts_width <= 3 - self.config["DDS_RTIO_CLK_RATIO"] = 24 >> self.rtio.fine_ts_width self.config["DDS_CHANNEL_COUNT"] = 11 self.config["DDS_AD9914"] = True self.config["DDS_ONEHOT_SEL"] = True @@ -261,6 +259,8 @@ class NIST_QC2(_NIST_QCx): rtio_channels.append(rtio.LogChannel()) self.add_rtio(rtio_channels) + assert self.rtio.fine_ts_width <= 3 + self.config["DDS_RTIO_CLK_RATIO"] = 24 >> self.rtio.fine_ts_width def main(): From 4dd0693f6a638f472561347321ffe43f9c3596c0 Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Wed, 20 Jan 2016 19:40:30 -0500 Subject: [PATCH 10/10] add release notes/process --- RELEASES | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 RELEASES diff --git a/RELEASES b/RELEASES new file mode 100644 index 000000000..876b4f92b --- /dev/null +++ b/RELEASES @@ -0,0 +1,23 @@ +Release process +=============== + +Maintain the release notes in this file with a list of new features and API changes in each major release. + +Major releases: +1. Create branch release-X from master. +2. Remove any unfinished features. +3. Test and fix any problems found. +4. Tag X.0. + +Minor (bugfix) releases: +1. Backport bugfixes from the master branch or fix bugs specific to old releases into the currently maintained release-X branch(es). +2. When significant bugs have been fixed, tag X.Y+1. +3. To help dealing with regressions, no new features or refactorings should be implemented in release-X branches. Those happen in the master branch, and then a new release-X+1 branch is created. + + +Release notes +============= + +1.0 +--- +* First release