ARTIQ RPC support #25

Closed
opened 2021-09-24 14:05:24 +08:00 by sb10q · 2 comments

To be implemented in nac3artiq, may use the same API as #24

To be implemented in nac3artiq, may use the same API as #24
pca006132 was assigned by sb10q 2021-09-24 14:05:24 +08:00
sb10q added the
high-priority
label 2021-09-29 08:46:03 +08:00
sb10q added this to the Prealpha milestone 2021-11-19 16:50:44 +08:00
Poster
Owner
See also: https://github.com/m-labs/artiq/issues/1086

Synchronous RPC is now supported in branch rpc. Only basic test is done. Use nac3 branch of artiq and apply the following patches:

diff --git a/artiq/coredevice/comm_kernel.py b/artiq/coredevice/comm_kernel.py
index cdb54a11..d9f9743e 100644
--- a/artiq/coredevice/comm_kernel.py
+++ b/artiq/coredevice/comm_kernel.py
@@ -545,7 +545,7 @@ class CommKernel:
         if service_id == 0:
             def service(obj, attr, value): return setattr(obj, attr, value)
         else:
-            service = embedding_map.retrieve_object(service_id)
+            service = embedding_map.retrieve_function(service_id)
         logger.debug("rpc service: [%d]%r%s %r %r -> %s", service_id, service,
                      (" (async)" if is_async else ""), args, kwargs, return_tags)
 
diff --git a/artiq/coredevice/core.py b/artiq/coredevice/core.py
index 96683857..8ba6f4b1 100644
--- a/artiq/coredevice/core.py
+++ b/artiq/coredevice/core.py
@@ -6,6 +6,7 @@ import nac3artiq
 from artiq.language.core import *
 from artiq.language import core as core_language
 from artiq.language.units import *
+from artiq.language.embedding_map import EmbeddingMap
 
 from artiq.coredevice.comm_kernel import CommKernel, CommKernelDummy
 
@@ -55,11 +56,12 @@ class Core:
         self.core = self
         self.comm.core = self
         self.compiler = nac3artiq.NAC3(target)
+        self.embedding_map = EmbeddingMap()
 
     def close(self):
         self.comm.close()
 
-    def compile(self, method, args, kwargs, file_output=None):
+    def compile(self, method, args, kwargs, embedding_map, file_output=None):
         if core_language._allow_registration:
             self.compiler.analyze(core_language._registered_functions, core_language._registered_classes)
             core_language._allow_registration = False
@@ -72,18 +74,18 @@ class Core:
             name = ""
 
         if file_output is None:
-            return self.compiler.compile_method_to_mem(obj, name, args)
+            return self.compiler.compile_method_to_mem(obj, name, args, embedding_map)
         else:
-            self.compiler.compile_method_to_file(obj, name, args, file_output)
+            self.compiler.compile_method_to_file(obj, name, args, file_output, embedding_map)
 
     def run(self, function, args, kwargs):
-        kernel_library = self.compile(function, args, kwargs)
+        kernel_library = self.compile(function, args, kwargs, self.embedding_map)
         if self.first_run:
             self.comm.check_system_info()
             self.first_run = False
         self.comm.load(kernel_library)
         self.comm.run()
-        self.comm.serve(None, None, None)
+        self.comm.serve(self.embedding_map, None, None)
 
     @portable
     def seconds_to_mu(self, seconds: float) -> int64:
diff --git a/artiq/language/__init__.py b/artiq/language/__init__.py
index 99c019a7..14547175 100644
--- a/artiq/language/__init__.py
+++ b/artiq/language/__init__.py
@@ -3,6 +3,7 @@ from artiq.language.core import *
 from artiq.language.environment import *
 from artiq.language.units import *
 from artiq.language.scan import *
+from artiq.language.embedding_map import *
 from . import import_cache
 
 __all__ = ["import_cache"]
@@ -10,3 +11,4 @@ __all__.extend(core.__all__)
 __all__.extend(environment.__all__)
 __all__.extend(units.__all__)
 __all__.extend(scan.__all__)
+__all__.extend(embedding_map.__all__)
diff --git a/artiq/language/core.py b/artiq/language/core.py
index b9f5fe8a..29f056c1 100644
--- a/artiq/language/core.py
+++ b/artiq/language/core.py
@@ -104,6 +104,7 @@ def rpc(arg=None, flags={}):
         def inner_decorator(function):
             return rpc(function, flags)
         return inner_decorator
+    return arg
 
 
 @nac3

Example that works:

from artiq.experiment import *
from artiq.coredevice.core import Core
from numpy import int32


@rpc
def test(a: int32):
    print('test' + str(a))

@nac3
class NAC3Devices(EnvExperiment):
    core: KernelInvariant[Core]

    def build(self):
        self.setattr_device("core")
        self.list = [1, 2, 3, 4]

    @rpc
    def get_list(self) -> list[int32]:
        return self.list

    @rpc
    def send_list(self, l: list[int32]):
        print(l)

    @kernel
    def run(self):
        l = self.get_list()
        self.send_list(l)
        for v in self.get_list():
            test(v)
Synchronous RPC is now supported in branch rpc. Only basic test is done. Use nac3 branch of artiq and apply the following patches: ```diff diff --git a/artiq/coredevice/comm_kernel.py b/artiq/coredevice/comm_kernel.py index cdb54a11..d9f9743e 100644 --- a/artiq/coredevice/comm_kernel.py +++ b/artiq/coredevice/comm_kernel.py @@ -545,7 +545,7 @@ class CommKernel: if service_id == 0: def service(obj, attr, value): return setattr(obj, attr, value) else: - service = embedding_map.retrieve_object(service_id) + service = embedding_map.retrieve_function(service_id) logger.debug("rpc service: [%d]%r%s %r %r -> %s", service_id, service, (" (async)" if is_async else ""), args, kwargs, return_tags) diff --git a/artiq/coredevice/core.py b/artiq/coredevice/core.py index 96683857..8ba6f4b1 100644 --- a/artiq/coredevice/core.py +++ b/artiq/coredevice/core.py @@ -6,6 +6,7 @@ import nac3artiq from artiq.language.core import * from artiq.language import core as core_language from artiq.language.units import * +from artiq.language.embedding_map import EmbeddingMap from artiq.coredevice.comm_kernel import CommKernel, CommKernelDummy @@ -55,11 +56,12 @@ class Core: self.core = self self.comm.core = self self.compiler = nac3artiq.NAC3(target) + self.embedding_map = EmbeddingMap() def close(self): self.comm.close() - def compile(self, method, args, kwargs, file_output=None): + def compile(self, method, args, kwargs, embedding_map, file_output=None): if core_language._allow_registration: self.compiler.analyze(core_language._registered_functions, core_language._registered_classes) core_language._allow_registration = False @@ -72,18 +74,18 @@ class Core: name = "" if file_output is None: - return self.compiler.compile_method_to_mem(obj, name, args) + return self.compiler.compile_method_to_mem(obj, name, args, embedding_map) else: - self.compiler.compile_method_to_file(obj, name, args, file_output) + self.compiler.compile_method_to_file(obj, name, args, file_output, embedding_map) def run(self, function, args, kwargs): - kernel_library = self.compile(function, args, kwargs) + kernel_library = self.compile(function, args, kwargs, self.embedding_map) if self.first_run: self.comm.check_system_info() self.first_run = False self.comm.load(kernel_library) self.comm.run() - self.comm.serve(None, None, None) + self.comm.serve(self.embedding_map, None, None) @portable def seconds_to_mu(self, seconds: float) -> int64: diff --git a/artiq/language/__init__.py b/artiq/language/__init__.py index 99c019a7..14547175 100644 --- a/artiq/language/__init__.py +++ b/artiq/language/__init__.py @@ -3,6 +3,7 @@ from artiq.language.core import * from artiq.language.environment import * from artiq.language.units import * from artiq.language.scan import * +from artiq.language.embedding_map import * from . import import_cache __all__ = ["import_cache"] @@ -10,3 +11,4 @@ __all__.extend(core.__all__) __all__.extend(environment.__all__) __all__.extend(units.__all__) __all__.extend(scan.__all__) +__all__.extend(embedding_map.__all__) diff --git a/artiq/language/core.py b/artiq/language/core.py index b9f5fe8a..29f056c1 100644 --- a/artiq/language/core.py +++ b/artiq/language/core.py @@ -104,6 +104,7 @@ def rpc(arg=None, flags={}): def inner_decorator(function): return rpc(function, flags) return inner_decorator + return arg @nac3 ``` Example that works: ```python from artiq.experiment import * from artiq.coredevice.core import Core from numpy import int32 @rpc def test(a: int32): print('test' + str(a)) @nac3 class NAC3Devices(EnvExperiment): core: KernelInvariant[Core] def build(self): self.setattr_device("core") self.list = [1, 2, 3, 4] @rpc def get_list(self) -> list[int32]: return self.list @rpc def send_list(self, l: list[int32]): print(l) @kernel def run(self): l = self.get_list() self.send_list(l) for v in self.get_list(): test(v) ```
sb10q closed this issue 2022-02-13 13:36:28 +08:00
Sign in to join this conversation.
No Milestone
No Assignees
2 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: M-Labs/nac3#25
There is no content yet.