2017-07-05 08:27:48 +03:00
|
|
|
"""Tag class for TVM operators."""
|
2018-09-27 05:02:27 +03:00
|
|
|
import warnings
|
2018-06-28 05:50:30 +03:00
|
|
|
from ._ffi.base import decorate
|
2017-07-05 08:27:48 +03:00
|
|
|
|
|
|
|
class TagScope(object):
|
|
|
|
"""Tag scope object to set tag for operators, working as context
|
|
|
|
manager and decorator both. See also tag_scope.
|
|
|
|
"""
|
2018-09-27 05:02:27 +03:00
|
|
|
_current = None
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def get_current(cls):
|
|
|
|
if cls._current:
|
|
|
|
cls._current.accessed = True
|
|
|
|
return cls._current
|
|
|
|
|
2017-07-05 08:27:48 +03:00
|
|
|
def __init__(self, tag):
|
|
|
|
self._old_scope = None
|
|
|
|
self.tag = tag
|
2018-09-27 05:02:27 +03:00
|
|
|
self.accessed = False
|
2017-07-05 08:27:48 +03:00
|
|
|
|
|
|
|
def __enter__(self):
|
2018-09-27 05:02:27 +03:00
|
|
|
if TagScope._current is not None:
|
2017-07-05 08:27:48 +03:00
|
|
|
raise ValueError("nested op_tag is not allowed for now")
|
2018-09-27 05:02:27 +03:00
|
|
|
self._old_scope = TagScope._current
|
|
|
|
TagScope._current = self
|
2017-07-05 08:27:48 +03:00
|
|
|
return self
|
|
|
|
|
|
|
|
def __exit__(self, ptype, value, trace):
|
|
|
|
assert self._old_scope is None
|
2018-09-27 05:02:27 +03:00
|
|
|
if not self.accessed:
|
|
|
|
warnings.warn("Tag '%s' declared via TagScope was not used." % (self.tag,))
|
|
|
|
TagScope._current = self._old_scope
|
2017-07-05 08:27:48 +03:00
|
|
|
|
|
|
|
def __call__(self, fdecl):
|
2017-07-08 02:02:35 +03:00
|
|
|
def tagged_fdecl(func, *args, **kwargs):
|
2017-07-05 08:27:48 +03:00
|
|
|
with self:
|
2017-07-08 02:02:35 +03:00
|
|
|
return func(*args, **kwargs)
|
|
|
|
return decorate(fdecl, tagged_fdecl)
|
2017-07-05 08:27:48 +03:00
|
|
|
|
|
|
|
|
|
|
|
def tag_scope(tag):
|
|
|
|
"""The operator tag scope.
|
|
|
|
|
|
|
|
Parameters
|
|
|
|
----------
|
|
|
|
tag: str
|
|
|
|
The tag name.
|
|
|
|
|
|
|
|
Returns
|
|
|
|
-------
|
|
|
|
tag_scope: TagScope
|
|
|
|
The tag scope object, which can be used as decorator or
|
|
|
|
context manger.
|
|
|
|
|
|
|
|
Example
|
|
|
|
-------
|
|
|
|
.. code-block:: python
|
|
|
|
|
|
|
|
n = tvm.var('n')
|
|
|
|
m = tvm.var('m')
|
2017-10-24 18:52:03 +03:00
|
|
|
l = tvm.var('l')
|
2017-07-05 08:27:48 +03:00
|
|
|
A = tvm.placeholder((n, l), name='A')
|
2017-10-24 18:52:03 +03:00
|
|
|
B = tvm.placeholder((m, l), name='B')
|
2017-07-05 08:27:48 +03:00
|
|
|
k = tvm.reduce_axis((0, l), name='k')
|
|
|
|
|
|
|
|
with tvm.tag_scope(tag='matmul'):
|
|
|
|
C = tvm.compute((n, m), lambda i, j: tvm.sum(A[i, k] * B[j, k], axis=k))
|
|
|
|
|
|
|
|
# or use tag_scope as decorator
|
|
|
|
@tvm.tag_scope(tag="conv")
|
|
|
|
def compute_relu(data):
|
|
|
|
return tvm.compute(data.shape, lambda *i: tvm.select(data(*i) < 0, 0.0, data(*i)))
|
|
|
|
"""
|
|
|
|
return TagScope(tag)
|