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: 99104499f998
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: ec645d35896f
Choose a head ref
  • 2 commits
  • 2 files changed
  • 1 contributor

Commits on Nov 20, 2016

  1. Copy the full SHA
    5119fa3 View commit details
  2. Copy the full SHA
    ec645d3 View commit details
Showing with 34 additions and 6 deletions.
  1. +5 −4 artiq/coredevice/dds.py
  2. +29 −2 doc/manual/compiler.rst
9 changes: 5 additions & 4 deletions artiq/coredevice/dds.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from artiq.language.core import *
from artiq.language.types import *
from artiq.language.units import *
from numpy import int64


_PHASE_MODE_DEFAULT = -1
@@ -111,20 +112,20 @@ def frequency_to_ftw(self, frequency):
"""Returns the frequency tuning word corresponding to the given
frequency.
"""
return round(int(2, width=64)**32*frequency/self.core_dds.sysclk)
return round(float(int64(2)**32*frequency/self.core_dds.sysclk))

@portable(flags=["fast-math"])
def ftw_to_frequency(self, ftw):
"""Returns the frequency corresponding to the given frequency tuning
word.
"""
return ftw*self.core_dds.sysclk/int(2, width=64)**32
return ftw*self.core_dds.sysclk/int64(2)**32

@portable(flags=["fast-math"])
def turns_to_pow(self, turns):
"""Returns the phase offset word corresponding to the given phase
in turns."""
return round(turns*2**self.pow_width)
return round(float(turns*2**self.pow_width))

@portable(flags=["fast-math"])
def pow_to_turns(self, pow):
@@ -135,7 +136,7 @@ def pow_to_turns(self, pow):
@portable(flags=["fast-math"])
def amplitude_to_asf(self, amplitude):
"""Returns amplitude scale factor corresponding to given amplitude."""
return round(amplitude*0x0fff)
return round(float(amplitude*0x0fff))

@portable(flags=["fast-math"])
def asf_to_amplitude(self, asf):
31 changes: 29 additions & 2 deletions doc/manual/compiler.rst
Original file line number Diff line number Diff line change
@@ -10,7 +10,7 @@ A number of Python features can be used inside a kernel for compilation and exec

* Booleans
* 32-bit signed integers (default size)
* 64-bit signed integers (use ``int(n, width=64)`` to convert)
* 64-bit signed integers (use ``numpy.int64`` to convert)
* Double-precision floating point numbers
* Lists of any supported types
* User-defined classes, with attributes of any supported types (attributes that are not used anywhere in the kernel are ignored)
@@ -36,7 +36,7 @@ The Python types correspond to ARTIQ type annotations as follows:
+-------------+-------------------------+
| bool | TBool |
+-------------+-------------------------+
| int | TInt32, TInt64 |
| int | TInt32 or TInt64 |
+-------------+-------------------------+
| float | TFloat |
+-------------+-------------------------+
@@ -46,6 +46,33 @@ The Python types correspond to ARTIQ type annotations as follows:
+-------------+-------------------------+
| range | TRange32, TRange64 |
+-------------+-------------------------+
| numpy.int32 | TInt32 |
+-------------+-------------------------+
| numpy.int64 | TInt64 |
+-------------+-------------------------+
| numpy.float64 | TFloat |
+-------------+-------------------------+

Pitfalls
--------

The ARTIQ compiler accepts *nearly* a strict subset of Python 3. However, by necessity there
is a number of differences that can lead to bugs.

Arbitrary-length integers are not supported at all on the core device; all integers are
either 32-bit or 64-bit. This especially affects calculations that result in a 32-bit signed
overflow; if the compiler detects a constant that doesn't fit into 32 bits, the entire expression
will be upgraded to 64-bit arithmetics, however if all constants are small, 32-bit arithmetics
will be used even if the result will overflow. Overflows are not detected.

The result of calling the builtin ``round`` function is different when used with
the builtin ``float`` type and the ``numpy.float64`` type on the host interpreter; ``round(1.0)``
returns an integer value 1, whereas ``round(numpy.float64(1.0))`` returns a floating point value
``numpy.float64(1.0)``. Since both ``float`` and ``numpy.float64`` are mapped to
the builtin ``float`` type on the core device, this can lead to problems in functions marked
``@portable``; the workaround is to explicitly cast the argument of ``round`` to ``float``:
``round(float(numpy.float64(1.0)))`` returns an integer on the core device as well as on the host
interpreter.

Additional optimizations
------------------------