To follow up with our latest discussion with @tkonolige @areusch @csullivan @jwfromm et al.
The following questions are raised in our discussion: 1. Move discussion of vendor IR to tradeoffs / benefits section rather than core motivation. 2. (Section 2) Parser registration example is a little confusing (dispatch.register), probably just needs more detail, less … 3. (Section 1) Add tradeoffs section noting that this isnt a typical parser, gives much more pythonic interface, easier testing, more flexibility. 4. (Section 3) More discussion around what lives in host language. Maybe need script.host_var and script.quote in part of future work, might be worth highlighting in a future work section. 5. (Section 2) tradeoff on registration approach. Our response: ### 1. Tradeoffs: TVMScript parser is not a typical parser Unlike a typical parser that converts a token stream to an AST, which in our case, converts python source code to TIR AST, the TVMScript parser is technically speaking a transpiler that transforms a Python AST to TIR AST instead of parsing raw python. Pros: 1. Python’s AST package provides accurate parsing functionality, so that all issues around ambiguity, grammar and parser performance is a non-issue. 2. Compared with the existing monolithic TVMScript parser which is 1.5k lines of code, the transpiler provides much easier testing, more pythonic interface and more flexibility. Cons: 1. This means we are depending on Python’s AST package - which could come with breaking changes across python versions ### 2. Registration Logic The registration logic is in fact quite straightforward. For example, to support TIR’s for-loop syntax like: ```python for i, *many_j, k in T.grid(...): # or anything like T.serial/parallel/vectorized/unroll/thread_binding ... ``` The registration logic is as simple as calling into our IR-builder: ```python @dispatch.register(token="tir", type_name="For") def visit_for(self: Parser, node: doc.For) -> None: for_frame = self.eval_expr(node.iter) if not isinstance(for_frame, T.ForFrame): self.report_error( node.iter, "Expect the for loop to be one of the following: " "range, T.serial, T.grid, T.parallel, T.vectorized, T.unroll, T.thread_binding", ) with self.var_table.with_frame(): with for_frame as iters: self.eval_assign(target=node.target, source=iters, bind_value=bind_value) self.visit_body(node.body) ``` There is an alternative proposal that registration should happen at class-level instead of method-level, e.g. ```python ## Our RFC @dispatch.register(token="tir", type_name="For") def registered_method(self: Parser, node: doc.For) -> None: ... ## Alternative @dispatch.register(token="tir"): class DispatchOfTIR: @staticmethod def visit_For(self: Parser, node: doc.For) -> None: ... ``` The advantage of the alternative proposal is that it limits the users so that they have to put all the logic inside a class, while the disadvantage is that the class itself doesn’t mean anything other than a collection of static methods, which could bring some confusion if developers attempt to instantiate the class. To this end, “putting all logic inside a class” is equivalent to “putting all logic inside a file” because the class only serves as a namespace. Therefore, we believe the best design should be as minimal as possible, i.e. without a class. **Drawback**. Registry is a necessary design when it comes to supporting per-node tooling and multiple IRs at scale. However, less carefully designed registries, for example, relay operator strategy, where definitions span in multiple folders and tens of files, would lead to worse discoverability and debugging experience. On the other hand, in our particular case, because all dispatches for a certain IR is confined in a single file (e.g. [tir.py](http://tir.py/)), it would not be a particular concern. ### 3. Metaprogramming syntax A question has been raised on supporting quotations for metaprogramming in languages like MetaOCaml [1]. This feature is very cool, and it could be an important future work for well motivated use-cases. In terms of syntax, we believe the following could be like: ```python with script.quote(): ## <===== hand back control to python interpreter arbitrary python program with script.unquote(): ## <===== gain control from python interpreter parsable TVMScript ``` [1] MetaOCaml -- an OCaml dialect for multi-stage programming [https://okmij.org/ftp/ML/MetaOCaml.html](https://okmij.org/ftp/ML/MetaOCaml.html) -- Reply to this email directly or view it on GitHub: https://github.com/apache/tvm-rfcs/pull/79#issuecomment-1198582332 You are receiving this because you are subscribed to this thread. Message ID: <apache/tvm-rfcs/pull/79/c1198582...@github.com>