From 17ecd355309600b997e303b41efb3d33af33c3dc Mon Sep 17 00:00:00 2001 From: spaqin Date: Tue, 1 Mar 2022 17:36:03 +0800 Subject: [PATCH 1/5] test_i2c: fix for missing readback --- artiq/test/coredevice/test_i2c.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/artiq/test/coredevice/test_i2c.py b/artiq/test/coredevice/test_i2c.py index 7b589cb4e..e8293db9d 100644 --- a/artiq/test/coredevice/test_i2c.py +++ b/artiq/test/coredevice/test_i2c.py @@ -3,7 +3,7 @@ import os, unittest from artiq.experiment import * from artiq.test.hardware_testbench import ExperimentCase from artiq.coredevice.exceptions import I2CError -from artiq.coredevice.i2c import I2CSwitch +from artiq.coredevice.i2c import I2CSwitch, i2c_read_byte class I2CSwitchTest(EnvExperiment): @@ -16,7 +16,9 @@ class I2CSwitchTest(EnvExperiment): passed = True for i in range(8): self.i2c_switch.set(i) - if self.i2c_switch.readback() != 1 << i: + # this will work only with pca9548 (like on kc705) + # otherwise we cannot guarantee exact readback values + if i2c_read_byte(self.i2c_switch.busno, self.i2c_switch.address) != 1 << i: passed = False self.set_dataset("passed", passed) From 51fa1b5e5e7e55bde014e56339fe4b43a7f28347 Mon Sep 17 00:00:00 2001 From: spaqin Date: Fri, 4 Mar 2022 14:01:35 +0800 Subject: [PATCH 2/5] drtio: fix i2c switch --- artiq/firmware/runtime/kern_hwreq.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/artiq/firmware/runtime/kern_hwreq.rs b/artiq/firmware/runtime/kern_hwreq.rs index a80a7b71a..dff852b50 100644 --- a/artiq/firmware/runtime/kern_hwreq.rs +++ b/artiq/firmware/runtime/kern_hwreq.rs @@ -117,7 +117,7 @@ mod remote_i2c { } pub fn switch_select(io: &Io, aux_mutex: &Mutex, linkno: u8, destination: u8, busno: u8, address: u8, mask: u8) -> Result { - let reply = drtio::aux_transact(io, aux_mutex, linkno, &drtioaux::Packet::I2cPca954xSelectRequest { + let reply = drtio::aux_transact(io, aux_mutex, linkno, &drtioaux::Packet::I2cSwitchSelectRequest { destination: destination, busno: busno, address: address, From 232f28c0e858a09b23ed501371b44c4875951a4d Mon Sep 17 00:00:00 2001 From: spaqin Date: Fri, 4 Mar 2022 14:07:39 +0800 Subject: [PATCH 3/5] kern_hw: fix return type --- artiq/firmware/runtime/kern_hwreq.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/artiq/firmware/runtime/kern_hwreq.rs b/artiq/firmware/runtime/kern_hwreq.rs index dff852b50..952a18439 100644 --- a/artiq/firmware/runtime/kern_hwreq.rs +++ b/artiq/firmware/runtime/kern_hwreq.rs @@ -116,7 +116,7 @@ mod remote_i2c { } } - pub fn switch_select(io: &Io, aux_mutex: &Mutex, linkno: u8, destination: u8, busno: u8, address: u8, mask: u8) -> Result { + pub fn switch_select(io: &Io, aux_mutex: &Mutex, linkno: u8, destination: u8, busno: u8, address: u8, mask: u8) -> Result<(), &'static str> { let reply = drtio::aux_transact(io, aux_mutex, linkno, &drtioaux::Packet::I2cSwitchSelectRequest { destination: destination, busno: busno, From ac55da81d85d21b8f47e85ace068a815a1e55137 Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Sun, 6 Mar 2022 18:24:57 +0800 Subject: [PATCH 4/5] core: support precompilation of kernels --- artiq/coredevice/core.py | 62 ++++++++++++++++--- .../kc705_nist_clock/repository/precompile.py | 20 ++++++ artiq/test/coredevice/test_compile.py | 28 +++++++++ 3 files changed, 101 insertions(+), 9 deletions(-) create mode 100644 artiq/examples/kc705_nist_clock/repository/precompile.py diff --git a/artiq/coredevice/core.py b/artiq/coredevice/core.py index 529c42f98..406a7c961 100644 --- a/artiq/coredevice/core.py +++ b/artiq/coredevice/core.py @@ -1,5 +1,6 @@ import os, sys import numpy +from functools import wraps from pythonparser import diagnostic @@ -120,7 +121,52 @@ class Core: except diagnostic.Error as error: raise CompileError(error.diagnostic) from error + def _run_compiled(self, kernel_library, embedding_map, symbolizer, demangler): + if self.first_run: + self.comm.check_system_info() + self.first_run = False + self.comm.load(kernel_library) + self.comm.run() + self.comm.serve(embedding_map, symbolizer, demangler) + def run(self, function, args, kwargs): + result = None + @rpc(flags={"async"}) + def set_result(new_result): + nonlocal result + result = new_result + embedding_map, kernel_library, symbolizer, demangler = \ + self.compile(function, args, kwargs, set_result) + self._run_compiled(kernel_library, embedding_map, symbolizer, demangler) + return result + + def precompile(self, function, *args, **kwargs): + """Precompile a kernel and return a callable that executes it on the core device + at a later time. + + Arguments to the kernel are set at compilation time and passed to this function, + as additional positional and keyword arguments. + The returned callable accepts no arguments. + + Precompiled kernels may use RPCs. + + Object attributes at the beginning of a precompiled kernel execution have the + values they had at precompilation time. If up-to-date values are required, + use RPC to read them. + Similarly, modified values are not written back, and explicit RPC should be used + to modify host objects. + Carefully review the source code of drivers calls used in precompiled kernels, as + they may rely on host object attributes being transfered between kernel calls. + Examples include code used to control DDS phase, and Urukul RF switch control + via the CPLD register. + + The return value of the callable is the return value of the kernel, if any. + + The callable may be called several times. + """ + if not hasattr(function, "artiq_embedded"): + raise ValueError("Argument is not a kernel") + result = None @rpc(flags={"async"}) def set_result(new_result): @@ -128,17 +174,15 @@ class Core: result = new_result embedding_map, kernel_library, symbolizer, demangler = \ - self.compile(function, args, kwargs, set_result) + self.compile(function, args, kwargs, set_result, attribute_writeback=False) - if self.first_run: - self.comm.check_system_info() - self.first_run = False + @wraps(function) + def run_precompiled(): + nonlocal result + self._run_compiled(kernel_library, embedding_map, symbolizer, demangler) + return result - self.comm.load(kernel_library) - self.comm.run() - self.comm.serve(embedding_map, symbolizer, demangler) - - return result + return run_precompiled @portable def seconds_to_mu(self, seconds): diff --git a/artiq/examples/kc705_nist_clock/repository/precompile.py b/artiq/examples/kc705_nist_clock/repository/precompile.py new file mode 100644 index 000000000..6bfaaf057 --- /dev/null +++ b/artiq/examples/kc705_nist_clock/repository/precompile.py @@ -0,0 +1,20 @@ +from artiq.experiment import * + + +class Precompile(EnvExperiment): + def build(self): + self.setattr_device("core") + self.hello_str = "hello ARTIQ" + + def prepare(self): + self.precompiled = self.core.precompile(self.hello, "world") + + @kernel + def hello(self, arg): + print(self.hello_str, arg) + self.hello_str = "nowriteback" + + def run(self): + self.precompiled() + self.hello_str = "noupdate" + self.precompiled() diff --git a/artiq/test/coredevice/test_compile.py b/artiq/test/coredevice/test_compile.py index 060cd1b8f..efb6073d5 100644 --- a/artiq/test/coredevice/test_compile.py +++ b/artiq/test/coredevice/test_compile.py @@ -20,6 +20,28 @@ class CheckLog(EnvExperiment): core_log("test_artiq_compile") + +class _Precompile(EnvExperiment): + def build(self): + self.setattr_device("core") + self.x = 1 + self.y = 2 + self.z = 3 + + def set_attr(self, value): + self.x = value + + @kernel + def the_kernel(self, arg): + self.set_attr(arg + self.y) + self.z = 23 + + def run(self): + precompiled = self.core.precompile(self.the_kernel, 40) + self.y = 0 + precompiled() + + class TestCompile(ExperimentCase): def test_compile(self): core_addr = self.device_mgr.get_desc("core")["arguments"]["host"] @@ -34,3 +56,9 @@ class TestCompile(ExperimentCase): log = mgmt.get_log() self.assertIn("test_artiq_compile", log) mgmt.close() + + def test_precompile(self): + exp = self.create(_Precompile) + exp.run() + self.assertEqual(exp.x, 42) + self.assertEqual(exp.z, 3) From b02abc2bf4d6b3d33cfaec2d6672d943ec5fbdec Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Sun, 6 Mar 2022 18:30:08 +0800 Subject: [PATCH 5/5] remove legacy versioning files --- BETA | 0 MAJOR_VERSION | 1 - artiq/_version.py | 11 +---------- versioneer.py | 11 +---------- 4 files changed, 2 insertions(+), 21 deletions(-) delete mode 100644 BETA delete mode 100644 MAJOR_VERSION diff --git a/BETA b/BETA deleted file mode 100644 index e69de29bb..000000000 diff --git a/MAJOR_VERSION b/MAJOR_VERSION deleted file mode 100644 index 7f8f011eb..000000000 --- a/MAJOR_VERSION +++ /dev/null @@ -1 +0,0 @@ -7 diff --git a/artiq/_version.py b/artiq/_version.py index b3c3d5be4..87dc270e3 100644 --- a/artiq/_version.py +++ b/artiq/_version.py @@ -1,13 +1,4 @@ import os def get_version(): - override = os.getenv("VERSIONEER_OVERRIDE") - if override: - return override - srcroot = os.path.join(os.path.dirname(os.path.abspath(__file__)), os.pardir) - with open(os.path.join(srcroot, "MAJOR_VERSION"), "r") as f: - version = f.read().strip() - version += ".unknown" - if os.path.exists(os.path.join(srcroot, "BETA")): - version += ".beta" - return version + return os.getenv("VERSIONEER_OVERRIDE", default="7.0.beta") diff --git a/versioneer.py b/versioneer.py index dd191d875..0c8fbaf35 100644 --- a/versioneer.py +++ b/versioneer.py @@ -11,16 +11,7 @@ def get_rev(): """ def get_version(): - override = os.getenv("VERSIONEER_OVERRIDE") - if override: - return override - srcroot = os.path.dirname(os.path.abspath(__file__)) - with open(os.path.join(srcroot, "MAJOR_VERSION"), "r") as f: - version = f.read().strip() - version += ".unknown" - if os.path.exists(os.path.join(srcroot, "BETA")): - version += ".beta" - return version + return os.getenv("VERSIONEER_OVERRIDE", default="7.0.beta") def get_rev(): return os.getenv("VERSIONEER_REV", default="unknown")