forked from M-Labs/artiq
1
0
Fork 0

artiq_run: reference module by filename

This commit is contained in:
Sebastien Bourdeauducq 2014-12-08 16:11:31 +08:00
parent bfe980d458
commit fd28bfbb7c
3 changed files with 23 additions and 9 deletions

View File

@ -0,0 +1,15 @@
import importlib.machinery
def file_import(filename):
modname = filename
i = modname.rfind("/")
if i > 0:
modname = modname[i+1:]
i = modname.find(".")
if i > 0:
modname = modname[:i]
modname = "file_import_" + modname
loader = importlib.machinery.SourceFileLoader(modname, filename)
return loader.load_module()

View File

@ -23,7 +23,7 @@ Copy the files ``ddb.pyon`` and ``pdb.pyon`` (containing the device and paramete
Run your code using ``artiq_run.py``, which is part of the ARTIQ front-end tools: :: Run your code using ``artiq_run.py``, which is part of the ARTIQ front-end tools: ::
$ artiq_run.py led $ artiq_run.py led.py
The LED of the device should turn on. Congratulations! You have a basic ARTIQ system up and running. The LED of the device should turn on. Congratulations! You have a basic ARTIQ system up and running.
@ -49,9 +49,9 @@ Modify the code as follows: ::
You can then turn the LED off and on by entering 0 or 1 at the prompt that appears: :: You can then turn the LED off and on by entering 0 or 1 at the prompt that appears: ::
$ artiq_run.py led $ artiq_run.py led.py
Enter desired LED state: 1 Enter desired LED state: 1
$ artiq_run.py led $ artiq_run.py led.py
Enter desired LED state: 0 Enter desired LED state: 0
What happens is the ARTIQ compiler notices that the ``input_led_state`` function does not have a ``@kernel`` decorator and thus must be executed on the host. When the core device calls it, it sends a request to the host to execute it. The host displays the prompt, collects user input, and sends the result back to the core device, which sets the LED state accordingly. What happens is the ARTIQ compiler notices that the ``input_led_state`` function does not have a ``@kernel`` decorator and thus must be executed on the host. When the core device calls it, it sends a request to the host to execute it. The host displays the prompt, collects user input, and sends the result back to the core device, which sets the LED state accordingly.
@ -89,7 +89,7 @@ Create a new file ``rtio.py`` containing the following: ::
delay(2*us) delay(2*us)
Connect an oscilloscope or logic analyzer to TTL0 (pin C11 on the Papilio Pro) and run ``artiq_run.py led``. Notice that the generated signal's period is precisely 4 microseconds, and that it has a duty cycle of precisely 50%. This is not what you would expect if the delay and the pulse were implemented with CPU-controlled GPIO: overhead from the loop management, function calls, etc. would increase the signal's period, and asymmetry in the overhead would cause duty cycle distortion. Connect an oscilloscope or logic analyzer to TTL0 (pin C11 on the Papilio Pro) and run ``artiq_run.py led.py``. Notice that the generated signal's period is precisely 4 microseconds, and that it has a duty cycle of precisely 50%. This is not what you would expect if the delay and the pulse were implemented with CPU-controlled GPIO: overhead from the loop management, function calls, etc. would increase the signal's period, and asymmetry in the overhead would cause duty cycle distortion.
Instead, inside the core device, output timing is generated by the gateware and the CPU only programs switching commands with certain timestamps that the CPU computes. This guarantees precise timing as long as the CPU can keep generating timestamps that are increasing fast enough. In case it fails to do that (and attempts to program an event with a timestamp in the past), the :class:`artiq.coredevice.runtime_exceptions.RTIOUnderflow` exception is raised. The kernel causing it may catch it (using a regular ``try... except...`` construct), or it will be propagated to the host. Instead, inside the core device, output timing is generated by the gateware and the CPU only programs switching commands with certain timestamps that the CPU computes. This guarantees precise timing as long as the CPU can keep generating timestamps that are increasing fast enough. In case it fails to do that (and attempts to program an event with a timestamp in the past), the :class:`artiq.coredevice.runtime_exceptions.RTIOUnderflow` exception is raised. The kernel causing it may catch it (using a regular ``try... except...`` construct), or it will be propagated to the host.

View File

@ -1,11 +1,11 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import argparse import argparse
import importlib
import sys import sys
from inspect import isclass from inspect import isclass
from operator import itemgetter from operator import itemgetter
from artiq.management.file_import import file_import
from artiq.language.context import * from artiq.language.context import *
from artiq.management import pyon from artiq.management import pyon
from artiq.management.dpdb import DeviceParamDB from artiq.management.dpdb import DeviceParamDB
@ -37,8 +37,8 @@ def _get_args():
help="function to run") help="function to run")
parser.add_argument("-u", "--unit", default=None, parser.add_argument("-u", "--unit", default=None,
help="unit to run") help="unit to run")
parser.add_argument("module", parser.add_argument("file",
help="module containing the unit to run") help="file containing the unit to run")
return parser.parse_args() return parser.parse_args()
@ -54,8 +54,7 @@ def main():
unit_inst = ELFRunner(dpdb) unit_inst = ELFRunner(dpdb)
unit_inst.run(args.file, args.function) unit_inst.run(args.file, args.function)
else: else:
sys.path.append(".") module = file_import(args.file)
module = importlib.import_module(args.module)
if args.unit is None: if args.unit is None:
units = [(k, v) for k, v in module.__dict__.items() units = [(k, v) for k, v in module.__dict__.items()
if k[0] != "_" and isclass(v) and issubclass(v, AutoContext) and v is not AutoContext] if k[0] != "_" and isclass(v) and issubclass(v, AutoContext) and v is not AutoContext]