diff --git a/nac3artiq/demo.py b/nac3artiq/demo/demo.py similarity index 57% rename from nac3artiq/demo.py rename to nac3artiq/demo/demo.py index 993187b0..2a4b8490 100644 --- a/nac3artiq/demo.py +++ b/nac3artiq/demo/demo.py @@ -1,19 +1,23 @@ from min_artiq import * -@kernel +@nac3 class Demo: core: Core - led: TTLOut + led0: TTLOut + led1: TTLOut def __init__(self): self.core = Core() - self.led = TTLOut(self.core, 19) + self.led0 = TTLOut(self.core, 18) + self.led1 = TTLOut(self.core, 19) @kernel def run_k(self): self.core.reset() while True: - self.led.pulse(100.*ms) + with parallel: + self.led0.pulse(100.*ms) + self.led1.pulse(100.*ms) self.core.delay(100.*ms) def run(self): diff --git a/nac3artiq/device_db.py b/nac3artiq/demo/device_db.py similarity index 100% rename from nac3artiq/device_db.py rename to nac3artiq/demo/device_db.py diff --git a/nac3artiq/kernel.ld b/nac3artiq/demo/kernel.ld similarity index 100% rename from nac3artiq/kernel.ld rename to nac3artiq/demo/kernel.ld diff --git a/nac3artiq/min_artiq.py b/nac3artiq/demo/min_artiq.py similarity index 77% rename from nac3artiq/min_artiq.py rename to nac3artiq/demo/min_artiq.py index 18355dcf..6bc4f114 100644 --- a/nac3artiq/min_artiq.py +++ b/nac3artiq/demo/min_artiq.py @@ -5,14 +5,15 @@ from numpy import int32, int64 import nac3artiq -__all__ = ["KernelInvariant", "extern", "kernel", "portable", "ms", "us", "ns", +__all__ = ["KernelInvariant", "extern", "kernel", "portable", "nac3", + "ms", "us", "ns", "Core", "TTLOut", "parallel", "sequential"] import device_db core_arguments = device_db.device_db["core"]["arguments"] -nac3 = nac3artiq.NAC3(core_arguments["target"]) +compiler = nac3artiq.NAC3(core_arguments["target"]) allow_module_registration = True registered_ids = set() @@ -26,33 +27,38 @@ def register_module_of(obj): module = getmodule(obj) module_id = id(module) if module_id not in registered_ids: - nac3.register_module(module) + compiler.register_module(module) registered_ids.add(module_id) def extern(function): + """Decorates a function declaration defined by the core device runtime.""" register_module_of(function) return function def kernel(class_or_function): + """Decorates a function or method to be executed on the core device.""" register_module_of(class_or_function) - if isclass(class_or_function): - return class_or_function - else: - @wraps(class_or_function) - def device_only(*args, **kwargs): - raise RuntimeError("Kernels must not be called directly, use core.run(kernel_function) instead") - return device_only + @wraps(class_or_function) + def device_only(*args, **kwargs): + raise RuntimeError("Kernels must not be called directly, use core.run(kernel_function) instead") + return device_only def portable(function): + """Decorates a function or method to be executed on the same device (host/core device) as the caller.""" register_module_of(function) return function -def get_defined_class(method): - return vars(sys.modules[method.__module__])[method.__qualname__.split('.')[0]] +def nac3(cls): + """ + Decorates a class to be analyzed by NAC3. + All classes containing kernels or portable methods must use this decorator. + """ + register_module_of(cls) + return cls ms = 1e-3 @@ -83,16 +89,8 @@ def rtio_input_timestamp(timeout_mu: int64, channel: int32) -> int64: def rtio_input_data(channel: int32) -> int32: raise NotImplementedError("syscall not simulated") -def at_mu(_): - raise NotImplementedError("at_mu not simulated") -def now_mu() -> int32: - raise NotImplementedError("now_mu not simulated") - -def delay_mu(_): - raise NotImplementedError("delay_mu not simulated") - -@kernel +@nac3 class Core: ref_period: float @@ -102,7 +100,7 @@ class Core: def run(self, method, *args, **kwargs): global allow_module_registration if allow_module_registration: - nac3.analyze() + compiler.analyze() allow_module_registration = False if hasattr(method, "__self__"): @@ -112,7 +110,7 @@ class Core: obj = method name = "" - nac3.compile_method(obj, name, args) + compiler.compile_method(obj, name, args) @kernel def reset(self): @@ -138,7 +136,7 @@ class Core: delay_mu(self.seconds_to_mu(dt)) -@kernel +@nac3 class TTLOut: core: Core channel: int32 @@ -178,7 +176,7 @@ class TTLOut: self.core.delay(duration) self.off() -@portable +@nac3 class KernelContextManager: @kernel def __enter__(self): @@ -190,4 +188,3 @@ class KernelContextManager: parallel = KernelContextManager() sequential = KernelContextManager() - diff --git a/nac3artiq/demo/nac3artiq.so b/nac3artiq/demo/nac3artiq.so new file mode 120000 index 00000000..d05f6c9b --- /dev/null +++ b/nac3artiq/demo/nac3artiq.so @@ -0,0 +1 @@ +../../target/release/libnac3artiq.so \ No newline at end of file diff --git a/nac3artiq/nac3artiq.so b/nac3artiq/nac3artiq.so deleted file mode 120000 index fbba2417..00000000 --- a/nac3artiq/nac3artiq.so +++ /dev/null @@ -1 +0,0 @@ -../target/release/libnac3artiq.so \ No newline at end of file diff --git a/nac3artiq/src/lib.rs b/nac3artiq/src/lib.rs index 45a01648..d683e848 100644 --- a/nac3artiq/src/lib.rs +++ b/nac3artiq/src/lib.rs @@ -120,7 +120,7 @@ impl Nac3 { } => { let kernels = decorator_list.iter().any(|decorator| { if let ast::ExprKind::Name { id, .. } = decorator.node { - id.to_string() == "kernel" || id.to_string() == "portable" + id.to_string() == "nac3" } else { false }