triage artiq issues #3
Loading…
Reference in New Issue
No description provided.
Delete Branch "%!s(<nil>)"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
it would be really useful if someone could go over the artiq issue tracker and collect all the compiler/language related issues and sort them by type (performance, documentation/language foot-guns, feature requests) and then comment on how the new proposal makes things better/worse. This also applies to the thread on new compiler design
It seems to me that quite a lot of foot-guns are not documented or discussed in the issues, probably the experienced users are used to them...
I've collected some issues that seems more related to language design and less related to particular implementation problems.
Data type confusion for ARTIQ Python #656
The builtin datatypes provided by ARTIQ-Python is under-documented for tuples. The comments in the issue also suggested better error message when unsupported operation is encountered, and provide a section in the manual to list some commonly used but unsupported Python features like
dict
.This is mostly documentation issue. The new proposal makes things better by 1) Listing supported features, so future documentation would be easier. 2) Allowing constant indexing for tuples, which may help to simplify some use cases for tuples (but tuple is still not iterable).
manual: document object mutability and lifetimes #717
Still documentation issues. Partially related to #1 (regarding data passing for attributes)
Another issue is that the lifetime rule is currently broken in the compiler: compiler: Audit escape analysis for assignments #1301, compiler: Function return values (?) not life-time-tracked #1497.
The current proposal (not documented yet as I'm not sure how to properly explain what the code does...) provides a simple rule for lifetime, handles static lifetime and parameters' lifetime (not proven to be correct). Not sure if the rules are too conservative.
Returning list/array from kernel #1298
Documentation issue and Feature request? Not addressed in the current proposal, as the proposal currently focuses on the broader language issues like types and lifetime, but not yet touched on kernel attribute writeback.
super() on core device #617
Feaeture request. Seems not hard to implement, but multiple inheritance might be an issue. I might have to check how python handles
super()
.Type inference breaks inheritance #1119
Documentation and feature request. Current artiq-python compiler only supports code reuse for inheritance, rather than polymorphism. The current proposal added explicit cast to base class by
virtual
(not really sure where to put the base class annotation currently, but this is just syntactic issue).Unexpected behavior with dynamic function calls #1451
The current proposal does not support function pointer. We can probably support it later, but lifetime issues would be a pain...
llvm/compiler: FP related slowness #1007
Performance issue and design problem, stating that the current compiler use virtual calls for methods.
This proposal, although forgot to state explicitly, disallows dynamic dispatch for method calls. Dynamic dispatch is allowed when the user cast the object to its base class via
virtual
, and assigning function pointer to class attribute is also prohibited.Exception object causes memory corruption #1491
Related to implementation in core device. Exception object really requires memory allocation. This proposal does not deal with this problem.
New Compiler Scoping Issue #1542
Too long to summarize here.
And I would check other things that are not labeled as compiler, and maybe give some of my thoughts about the design issue later, after lunch.
And there are tons of bugs related to compiler performance issue and type inferencing problems.
For performance issue, I think rust would deliver some speedup (constant factor probably). This would not solve the superlinear speed regarding array compilation though.
For type inferencing, the current proposal requires every (sub-)expression to be typed, and forbids type coercion, so it should be relatively simple. Another benefit of using rust is that it requires exhaustive matching, so it would be less likely to hit unimplemented cases thus less compiler internal errors.
But that would be solved by the simpler type system, right?
Probably, I don't see anything in the current type system that would cause array compilation to have superlinear speed. Is the current artiq-python compiler so slow as it sets up many type equations and try to solve them?
I think I also have to look at how to type check the thing via pyo3...
Other issues:
How to identify whether a class would be compiled or not? In #1119 the class is not annotated but can be used in the kernel. I think it may be better to require annotations, to differentiate them and speed up compilation (less call to python interpreter).
inhomogeneous kernel lists #519
I think supporting polymorphism would be enough for this case.
Other issues are mainly implementation issues IMO, but I think there are still other design problems not in the issue tracker that worth discussing.
I think the implicit model used in ARTIQ currently would be OK here. Start with the first kernel (i.e. the call that resulted in the compiler being invoked), and if a reference resolves to another class, then add that class to what should be compiled. This "embedding" step can still be separated from nac3core.
What annotations are you proposing otherwise? Can you post some example code showing them?
That works, but it would be slow, especially if we do parallel compilation later, as this would require many call to the CPython runtime for resolving the identifier, which would probably need to hold the GIL.
If there are annotations, we can get all the classes and their method signatures in one go, and work on the type checking and code generation independently for every function body, similar to how headers work.
I would propose something like a
device
annotation like this:Yes, the GIL would need to be used.
Won't there be the same problem if the class definitions are spread across several Python modules?
@device
is not a good name since some of the classes would be user-defined parts of an experiment and not necessarily device drivers. How about simply using the same decorator@kernel
?It cannot be derived from the presence of
@kernel
or@portable
decorators on the methods of a class, since it is valid to have data-only classes used in kernels.Initially we would just hold the GIL until we fetched all the dependencies. Without any checking and code generation, this should be fast.
Otherwise we would have to call the CPython interpreter when we are checking the function bodies, this would require us to have a way to communicate with CPython interpreter, probably with a callback in nac3core (currently implemented, but not sure if there would be some lifetime issue, in the worse case we would have to use multithread and
sync_channel
to resolve the problem...), and getting/releasing the lock frequently which may have some performance penalty.OK, I think the name is not a great deal at this stage.
Yes
Right, but what if you have a kernel that references a class that is defined in another module?
foo.py:
bar.py:
Currently, I plan to get all type signatures before starting to check method body and do codegen. So when we check
Bar.__init__
, we would already have the signature ofFoo.__init__
, no need to consult the CPython interpreter. And this requires us to know all the classes that our compiler is concerned with.Note that both
__init__
methods are not kernels and are executed on the host.We still have the signature for RPCs, although the type for each argument is any type...
But the
foo
object would already have been created (on the host) when the kernelBar.quux
is called.How will the compiler find the
Foo
class in the other module, which is required byself.foo.a
?