Updated specification #8

Merged
pca006132 merged 5 commits from updated into master 2021-06-07 10:06:52 +08:00
1 changed files with 8 additions and 0 deletions
Showing only changes of commit 30dd6a1ac1 - Show all commits

View File

@ -88,6 +88,14 @@ Only types supported in the kernel can be referenced.
does not fit into int32, it would raise an error. (Issue #2) does not fit into int32, it would raise an error. (Issue #2)
* Only `uint32`, `int32` (and range of them) can be used as index. * Only `uint32`, `int32` (and range of them) can be used as index.
### Kernel Only class
* Annotate the class with `@kernel`.
* Functions are all kernel only, including constructor.
Questions:
* Should we also do `@portable`?

Does this just refer to kernel-only classes or is this a general question?

  • In general, @portable is a decorator we use very often, so I would like to keep that.
  • For kernel-only classes, portable functions sound contradicting
  • For portable classes (if existing), that might be useful but I do not have a use case for that right now.
Does this just refer to kernel-only classes or is this a general question? - In general, `@portable` is a decorator we use very often, so I would like to keep that. - For kernel-only classes, portable functions sound contradicting - For portable classes (if existing), that might be useful but I do not have a use case for that right now.
Outdated
Review

Yes, we definitely want @portable.

Yes, we definitely want ``@portable``.

Portable would be for testing the code in the host, similar to the use case of portable functions I guess.

Portable would be for testing the code in the host, similar to the use case of portable functions I guess.
Outdated
Review

Not just testing. One use case is converting between SI units (e.g. a floating point number in volts) and chip control words (e.g. integer values to program into a DAC). This allows 1. caching the latter and 2. determination of quantization errors.

Not just testing. One use case is converting between SI units (e.g. a floating point number in volts) and chip control words (e.g. integer values to program into a DAC). This allows 1. caching the latter and 2. determination of quantization errors.

Perhaps we should give it another name? Kernel only seems a poor naming choice, I chose it previously because the object is created and destroyed in the kernel, the host has no access to it. Actually this is just an ordinary object.

Or maybe we should call the object of type EnvExperiment something like experiment object? I'm not good at naming things...

Perhaps we should give it another name? Kernel only seems a poor naming choice, I chose it previously because the object is created and destroyed in the kernel, the host has no access to it. Actually this is just an ordinary object. Or maybe we should call the object of type `EnvExperiment` something like experiment object? I'm not good at naming things...
Outdated
Review

Kernel-only sounds fine to me.

EnvExperiment is not specific to the core device (you can perfectly create an ARTIQ experiment with this class, that does not use the core device and the compiler at all) and I had also suggested to use a decorator instead of inheritance to have more possibilities to implement immutability.

Kernel-only sounds fine to me. `EnvExperiment` is not specific to the core device (you can perfectly create an ARTIQ experiment with this class, that does not use the core device and the compiler at all) and I had also suggested to [use a decorator instead of inheritance](https://git.m-labs.hk/M-Labs/nac3-spec/issues/5#issuecomment-2022) to have more possibilities to implement immutability.

I've updated the explanation, but still I'm not entirely sure if the name should be kernel only class... It does sound weird when we allow it to be portable...

I've updated the explanation, but still I'm not entirely sure if the name should be kernel only class... It does sound weird when we allow it to be portable...

So if I understand it correctly now, a kernel-only class is a class decorated with @kernel or @portable.

  • Both can be constructed inside kernels
  • @kernel classes can only be used in kernels
  • @portable classes can be constructed in kernels and on the host. Besides, objects can be shared between the kernel and the host

Regarding the kernel-only name, I am fine with that.

So if I understand it correctly now, a kernel-only class is a class decorated with `@kernel` or `@portable`. - Both can be constructed inside kernels - `@kernel` classes can only be used in kernels - `@portable` classes can be constructed in kernels and on the host. Besides, objects can be shared between the kernel and the host Regarding the kernel-only name, I am fine with that.
Outdated
Review

Or maybe, have a single type of "kernel-capable" class, decorated with @kernel.

Or maybe, have a single type of "kernel-capable" class, decorated with ``@kernel``.
Outdated
Review

That decorator simply registers the class with the compiler, and enforces Immutable in the interpreter. There are no restrictions on the type of methods (kernel, portable, rpc, host-only) that it contains.

That decorator simply registers the class with the compiler, and enforces ``Immutable`` in the interpreter. There are no restrictions on the type of methods (kernel, portable, rpc, host-only) that it contains.

Ok great, then I guess I misunderstood the situation when read it and what we discussed in #5 is still valid. So to summarize:

from artiq.experiment import *

@kernel  # Register class with the compiler and more
class Foo(EnvExperiment):

    def __init__(self):
        pass
        
    def run(self) -> None:  # Host-only function
        self.kernel_fn()  # Runs a kernel
        self.rpc_fn()  # Runs function on host
        self.portable_fn()  # Runs function on host
        self.host_only_fn()  # Runs function on host
            
    @kernel
    def kernel_fn(self) -> None:  # Kernel function
        self.rpc_fn()  # RPC call
        self.portable_fn()  # Portable, so remains in kernel
        
    @rpc
    def rpc_fn(self) -> None:  # RPC function
        pass
        
    @portable
    def portable_fn(self) -> None  # Portable function
        pass
        
    def host_only_fn(self) -> None  # Host-only function
        pass
Ok great, then I guess I misunderstood the situation when read it and what we discussed in #5 is still valid. So to summarize: ```python from artiq.experiment import * @kernel # Register class with the compiler and more class Foo(EnvExperiment): def __init__(self): pass def run(self) -> None: # Host-only function self.kernel_fn() # Runs a kernel self.rpc_fn() # Runs function on host self.portable_fn() # Runs function on host self.host_only_fn() # Runs function on host @kernel def kernel_fn(self) -> None: # Kernel function self.rpc_fn() # RPC call self.portable_fn() # Portable, so remains in kernel @rpc def rpc_fn(self) -> None: # RPC function pass @portable def portable_fn(self) -> None # Portable function pass def host_only_fn(self) -> None # Host-only function pass ```

So if I understand it correctly now, a kernel-only class is a class decorated with @kernel or @portable.

Both can be constructed inside kernels
@kernel classes can only be used in kernels
@portable classes can be constructed in kernels and on the host. Besides, objects can be shared between the kernel and the host

This is exactly what I mean by kernel-only class.

Or maybe, have a single type of "kernel-capable" class, decorated with @kernel.
That decorator simply registers the class with the compiler, and enforces Immutable in the interpreter. There are no restrictions on the type of methods (kernel, portable, rpc, host-only) that it contains.

This is different, I don't expect kernel-only class to contain host-only/rpc methods, and the semantic for kernel and portable functions are different. It would not be possible to call a method of a kernel object on the host if it is not portable.

I think the kernel-only object is just a simple object in our language, that can be fully-understood by the compiler, without dealing with the complicated stuff like RPC and host functions etc.

> So if I understand it correctly now, a kernel-only class is a class decorated with @kernel or @portable. > > Both can be constructed inside kernels > @kernel classes can only be used in kernels > @portable classes can be constructed in kernels and on the host. Besides, objects can be shared between the kernel and the host This is exactly what I mean by kernel-only class. > Or maybe, have a single type of "kernel-capable" class, decorated with @kernel. > That decorator simply registers the class with the compiler, and enforces Immutable in the interpreter. There are no restrictions on the type of methods (kernel, portable, rpc, host-only) that it contains. This is different, I don't expect kernel-only class to contain host-only/rpc methods, and the semantic for kernel and portable functions are different. It would not be possible to call a method of a kernel object on the host if it is not portable. I think the kernel-only object is just a simple object in our language, that can be fully-understood by the compiler, without dealing with the complicated stuff like RPC and host functions etc.
Outdated
Review

What is the advantage of kernel-only classes? We'd need to support classes that mix kernel, portable, rpc, and host-only methods anyway.

What is the advantage of kernel-only classes? We'd need to support classes that mix kernel, portable, rpc, and host-only methods anyway.

I agree with @sb10q that "mixed" classes are a must. Kernel-only classes could be interesting to allow construction of objects inside kernels, though tbh at this moment I do not have any use-case for that.

I agree with @sb10q that "mixed" classes are a must. Kernel-only classes could be interesting to allow construction of objects inside kernels, though tbh at this moment I do not have any use-case for that.
Outdated
Review

Objects that can be constructed inside kernels could have __init__ decorated with @portable or @kernel. But I'm not sure if we want to support them anyway.

Objects that can be constructed inside kernels could have ``__init__`` decorated with ``@portable`` or ``@kernel``. But I'm not sure if we want to support them anyway.

If the object is stored in the kernel only, RPC would have to pass the object to the host and run the method. But that probably seems fine...

If the object is stored in the kernel only, RPC would have to pass the object to the host and run the method. But that probably seems fine...

@pca006132 @sb10q also, I think the proposal in this tread makes sense, which would drop "kernel-only" classes. It is not contained in the current merge request. Should we still add this?

@pca006132 @sb10q also, I think the proposal in this tread makes sense, which would drop "kernel-only" classes. It is not contained in the current merge request. Should we still add this?

Yes, I think we can drop this, but we should make it explicit that users can create objects in the kernel if the constructor is portable or kernel. And maybe we should also document the behavior for RPC when the object only exists on the kernel. What do you think?

Yes, I think we can drop this, but we should make it explicit that users can create objects in the kernel if the constructor is `portable` or `kernel`. And maybe we should also document the behavior for RPC when the object only exists on the kernel. What do you think?
Outdated
Review

@pca006132 Sounds good.

@pca006132 Sounds good.
* Support inheritance and polymorphism?
## Generics ## Generics
We use [type variable](https://docs.python.org/3/library/typing.html#typing.TypeVar) for denoting generics. We use [type variable](https://docs.python.org/3/library/typing.html#typing.TypeVar) for denoting generics.