Skip to content

Commit

Permalink
Rename tvm.hybrid.script to tvm.script. (apache#6522)
Browse files Browse the repository at this point in the history
  • Loading branch information
tkonolige authored Sep 26, 2020
1 parent 9555c99 commit c662638
Show file tree
Hide file tree
Showing 18 changed files with 200 additions and 191 deletions.
14 changes: 7 additions & 7 deletions docs/dev/hybrid_script.rst
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ Features
Software Emulation
~~~~~~~~~~~~~~~~~~

In software emulation, the most interesting thing is the decorator ``tvm.hybrid.script``.
In software emulation, the most interesting thing is the decorator ``tvm.te.hybrid.script``.
This decorator helps 2 things:

1. Importing runtime variables
Expand All @@ -40,7 +40,7 @@ This decorator helps 2 things:

Correct me if I am wrong: I believe that how 1. is implemented is dangerous, but I have no
choice. What I did is to add those names into python dict ``func.__global__`` and after
the call to ``func`` is done, those names will be cleaned up.
the call to ``func`` is done, those names will be cleaned up.

Overload is simple: the decorator checks the arguments' types and determines which function
should be actually called.
Expand All @@ -49,16 +49,16 @@ should be actually called.
Backend Compilation
~~~~~~~~~~~~~~~~~~~

Compilation is a large module, you can see ``python/tvm/hybrid/var_decl.py`` and
``python/tvm/hybrid/parser.py`` for more details. The first stage determines the
usage, or more accurately the declaration of each variable and the second stage does
the actual IR generation.
Compilation is a large module, you can see ``python/tvm/te/hybrid/`` for more
details. The first stage determines the usage, or more accurately the
declaration of each variable and the second stage does the actual IR
generation.

Attributes
~~~~~~~~~~

So far, ONLY tensors' `shape` attribute is supported. You can see ``visit_Subscript``
in ``python/tvm/hybrid/parser.py`` for more details. This is a hacky solution, I just
in ``python/tvm/te/hybrid/parser.py`` for more details. This is a hacky solution, I just
check the attributes when subscript.

Loops
Expand Down
3 changes: 0 additions & 3 deletions python/tvm/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,6 @@
# tvm.parser
from . import parser

# tvm tir hybrid script
from . import hybrid

# others
from . import arith

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
"""Hybrid Script APIs of TVM Python Package, aimed to support TIR"""
"""TVM Script APIs of TVM Python Package, aimed to support TIR"""

from .utils import create_module, ashybrid, script
from .utils import create_module, asscript, tir, module
from .parser import from_source
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
"""FFI APIs for tvm.hybrid"""
"""FFI APIs for tvm.tvmscript"""
import tvm._ffi

tvm._ffi._init_api("hybrid", __name__)
tvm._ffi._init_api("script", __name__)
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
"""Hybrid Script Parser Intrinsic Functions
"""TVM Script Parser Intrinsic Functions
IRNodes (StmtNodes without body, PrimExprNodes and more) are called intrins
"""
Expand Down
File renamed without changes.
48 changes: 24 additions & 24 deletions python/tvm/hybrid/parser.py → python/tvm/script/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
"""Hybrid Script Parser For TIR"""
"""TVM Script Parser For TIR"""
# pylint: disable=invalid-name, missing-docstring, inconsistent-return-statements, no-else-return
# pylint: disable=unnecessary-comprehension, unused-argument, import-outside-toplevel
# pylint: disable=unused-import
Expand All @@ -35,16 +35,16 @@
from . import _ffi_api


class HybridParserError(RuntimeError):
"""Hybrid Parser Runtime Error"""
class TVMScriptParserError(RuntimeError):
"""TVM script Parser Runtime Error"""


class HybridParser(ast.NodeVisitor):
class TVMScriptParser(ast.NodeVisitor):
"""Python AST visitor pass which finally lowers it to TIR
Notes for extension:
1. To support new types of AST nodes. Add a function visit_xxx().
2. To support new functions
We divide allowed function calls in hybrid script into 3 categories,
We divide allowed function calls in TVM script into 3 categories,
which is intrin, scope_handler and special_stmt.
1) intrin functions ought to have return value.
User can also register intrin category function into parser.
Expand Down Expand Up @@ -168,7 +168,7 @@ def report_error(self, message, lineno=None, col_offset=None):
lineno = self.current_lineno
if col_offset is None:
col_offset = self.current_col_offset
raise HybridParserError(self.wrap_line_col(message, lineno, col_offset))
raise TVMScriptParserError(self.wrap_line_col(message, lineno, col_offset))

def get_body(self):
body = []
Expand Down Expand Up @@ -196,28 +196,28 @@ def visit_Module(self, node):
"""Module visitor
AST abstract grammar:
Module(stmt* body, type_ignore* type_ignore)
By now we support two format of hybrid script shown below.
By now we support two format of TVM script shown below.
Example
-------
1. Generate a Function(If the code is printed, then it may bring meta)
1. Generate a PrimFunc (If the code is printed, then it may also contain metadata)
.. code-block:: python
import tvm
@tvm.hybrid.script
@tvm.script
def A(...):
...
# call hybrid parser when call this function, get a Function
# returns a PrimFunc
func = A
2. Generate an IRModule
.. code-block:: python
import tvm
@tvm.hybrid.script
@tvm.script
class MyMod():
def A(...):
...
Expand All @@ -227,7 +227,7 @@ def B(...):
__tvm_meta__ = ...
# call hybrid parser during construction, get an IRModule
# returns an IRModule
mod = MyMod()
"""

Expand All @@ -237,7 +237,7 @@ def B(...):
elif len(node.body) == 2:
if isinstance(node.body[0], ast.Assign):
node.body[0], node.body[1] = node.body[1], node.body[0]
if isinstance(node.body[0], ast.FunctionDef) and HybridParser.is_meta(node.body[1]):
if isinstance(node.body[0], ast.FunctionDef) and TVMScriptParser.is_meta(node.body[1]):
# function with meta
self.init_meta(MetaUnparser().visit(node.body[1].value))
return self.visit(node.body[0])
Expand All @@ -257,7 +257,7 @@ def visit_ClassDef(self, node):
for body_element in node.body:
if isinstance(body_element, ast.FunctionDef):
pass
elif HybridParser.is_meta(body_element) and not count:
elif TVMScriptParser.is_meta(body_element) and not count:
count = True
self.init_meta(MetaUnparser().visit(body_element.value))
else:
Expand Down Expand Up @@ -526,9 +526,9 @@ def visit_BinOp(self, node):

lhs = self.visit(node.left)
rhs = self.visit(node.right)
if not isinstance(node.op, tuple(HybridParser._binop_maker.keys())):
if not isinstance(node.op, tuple(TVMScriptParser._binop_maker.keys())):
self.report_error("BinOp " + str(type(node.op)) + " is not supported now")
return HybridParser._binop_maker[type(node.op)](lhs, rhs)
return TVMScriptParser._binop_maker[type(node.op)](lhs, rhs)

def visit_Compare(self, node):
"""Compare visitor
Expand All @@ -542,7 +542,7 @@ def visit_Compare(self, node):
for i in range(len(node.ops)):
lhs = ops[i]
rhs = ops[i + 1]
res.append(HybridParser._binop_maker[type(node.ops[i])](lhs, rhs))
res.append(TVMScriptParser._binop_maker[type(node.ops[i])](lhs, rhs))
return _all(*res)

def visit_BoolOp(self, node):
Expand All @@ -552,7 +552,7 @@ def visit_BoolOp(self, node):
"""

values = [self.visit(value) for value in node.values]
return HybridParser._binop_maker[type(node.op)](*values)
return TVMScriptParser._binop_maker[type(node.op)](*values)

def visit_UnaryOp(self, node):
"""UnaryOp visitor
Expand All @@ -561,9 +561,9 @@ def visit_UnaryOp(self, node):
"""

operand = self.visit(node.operand)
if not isinstance(node.op, tuple(HybridParser._unaryop_maker.keys())):
if not isinstance(node.op, tuple(TVMScriptParser._unaryop_maker.keys())):
self.report_error("UnaryOp " + str(type(node.op)) + " is not supported now")
return HybridParser._unaryop_maker[type(node.op)](operand)
return TVMScriptParser._unaryop_maker[type(node.op)](operand)

def visit_Subscript(self, node):
"""Subscript visitor
Expand Down Expand Up @@ -734,11 +734,11 @@ def from_source(src, func_lineno=0):
"""

root = ast.parse(src)
parser = HybridParser(src, func_lineno)
parser = TVMScriptParser(src, func_lineno)

try:
return parser.visit(root)
except HybridParserError as e:
except TVMScriptParserError as e:
raise e
except TVMError as e:
# TVM internal c++ error, we have to process the error message and inject line info
Expand All @@ -752,7 +752,7 @@ def from_source(src, func_lineno=0):
raise TVMError("\n".join(inject_e))
except Exception as e:
inject_e = parser.wrap_line_col(str(e), parser.current_lineno, parser.current_col_offset)
raise HybridParserError(inject_e)
raise TVMScriptParserError(inject_e)


tvm._ffi._init_api("hybrid", __name__)
tvm._ffi._init_api("script", __name__)
16 changes: 7 additions & 9 deletions python/tvm/hybrid/registry.py → python/tvm/script/registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
"""Hybrid Script Parser Function Registry """
"""TVM Script Parser Function Registry """
# pylint: disable=inconsistent-return-statements
import inspect
from enum import Enum
Expand Down Expand Up @@ -217,14 +217,14 @@ def get_arg_list(origin_func, category, with_var=False):
if not with_var:
if len(args) < 3 or args[0] != "parser" or args[1] != "node" or args[2] != "body":
raise RuntimeError(
"TVM Hybrid Script register error : the first three arguments of "
"TVM Script register error : the first three arguments of "
"this with scope handler must be parser, node, body"
)
args = args[3:]
else:
if len(args) < 2 or args[0] != "parser" or args[1] != "node":
raise RuntimeError(
"TVM Hybrid Script register error : the first two arguments of "
"TVM Script register error : the first two arguments of "
"this with scope handler must be parser, node"
)
args = args[2:]
Expand All @@ -237,26 +237,24 @@ def get_arg_list(origin_func, category, with_var=False):
or args[3] != "loop_vars"
):
raise RuntimeError(
"TVM Hybrid Script register error : the first three arguments of for scope handler"
"TVM Script register error : the first three arguments of for scope handler"
"must be parser, node, body, loop_vars"
)
args = args[4:]
elif category == Category.SPECIAL_STMT:
if len(args) < 2 or args[0] != "parser" or args[1] != "node":
raise RuntimeError(
"TVM Hybrid Script register error : the first three arguments of special stmt"
"TVM Script register error : the first three arguments of special stmt"
"must be parser, node"
)
args = args[2:]

if full_arg_spec.varkw is not None:
raise RuntimeError(
"TVM Hybrid Script register error : variable keyword argument is not supported now"
"TVM Script register error : variable keyword argument is not supported now"
)
if not len(full_arg_spec.kwonlyargs) == 0:
raise RuntimeError(
"TVM Hybrid Script register error : keyword only argument is not supported now"
)
raise RuntimeError("TVM Script register error : keyword only argument is not supported now")

pos_only = list()
for arg in args[: len(args) - len(defaults)]:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
"""Hybrid Script Scope Emitter for TIR"""
"""TVM Script Scope Emitter for TIR"""

from tvm.te import schedule

Expand Down Expand Up @@ -52,7 +52,7 @@ def remove_symbol(self, name):
if name in symbols:
symbols.pop(name)
return
raise RuntimeError("Internal error of hybrid parser: no symbol named" + name)
raise RuntimeError("Internal error of tvm script parser: no symbol named" + name)

def lookup_symbol(self, name):
"""Look up symbol by name"""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
"""Hybrid Script Parser Scope Handler Functions
"""TVM Script Parser Scope Handler Functions
This module provides the functions registered into parser under with_scope or for_scope category.
Scope handler nodes are StmtNodes with body, which are used to handle such scenarios.
1. For scope handler
When registering a for scope handler, the first 4 arguments must be parser, node, body, loop_vars
and these arguments will provided by Hybrid Script parser automatically
and these arguments will provided by TVM Script parser automatically
.. code-block:: python
for loop_vars in tir.xxx():
2. With scope handler
Expand All @@ -41,14 +41,14 @@
with tir.xxx() as target:
3) without as & concise
the first 3 arguments must be parser, node, body
Hybrid Script parser will parse the body automatically
TVM Script parser will parse the body automatically
Example : tir.allocate()/tir.realize()/tir.attr()
.. code-block:: python
tir.xxx()
with tir.xxx():
4) without as & not concise
the first 3 arguments must be parser, node, body
Hybrid Script parser will parse the body automatically
TVM Script parser will parse the body automatically
Example : tir.assert()/tir.let()
.. code-block:: python
with tir.xxx():
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
"""Hybrid Script Parser Special Stmt Functions
"""TVM Script Parser Special Stmt Functions
This module provides the functions registered into parser under special_stmt category.
special_stmt functions don't correspond to an IRNode in the AST directly. It is usually
used for some information that is not suitable to be printed directly.
Expand Down
Loading

0 comments on commit c662638

Please sign in to comment.