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>

Reply via email to