From 98211ab60b9690659369a208f1bcb8b69f4a9111 Mon Sep 17 00:00:00 2001 From: ZihengJiang Date: Mon, 25 Sep 2017 20:57:39 -0700 Subject: [PATCH 1/3] Move target to tvm; rename convolution as conv2d --- python/tvm/__init__.py | 1 + python/tvm/target.py | 63 +++++++++++++++++++ topi/python/topi/__init__.py | 1 - topi/python/topi/nn/__init__.py | 2 +- .../topi/nn/{convolution.py => conv2d.py} | 8 +-- .../topi/rasp/{convolution.py => conv2d.py} | 12 ++-- ...opi_convolution.py => test_topi_conv2d.py} | 18 +++--- 7 files changed, 84 insertions(+), 21 deletions(-) create mode 100644 python/tvm/target.py rename topi/python/topi/nn/{convolution.py => conv2d.py} (98%) rename topi/python/topi/rasp/{convolution.py => conv2d.py} (96%) rename topi/tests/python/{test_topi_convolution.py => test_topi_conv2d.py} (71%) diff --git a/python/tvm/__init__.py b/python/tvm/__init__.py index f3f908f2ef53..4bc20aac7dd6 100644 --- a/python/tvm/__init__.py +++ b/python/tvm/__init__.py @@ -14,6 +14,7 @@ from . import module from . import node from . import ir_builder +from . import target from . import ndarray as nd from .ndarray import context, cpu, gpu, opencl, cl, metal, mtl, vpi, rocm diff --git a/python/tvm/target.py b/python/tvm/target.py new file mode 100644 index 000000000000..8fcc44519703 --- /dev/null +++ b/python/tvm/target.py @@ -0,0 +1,63 @@ +"""Target management API of tvm""" + +from __future__ import absolute_import + +class Target(object): + """A Target describes the target type on which computation should be carried on""" + default_target = None + str2type = {'x86': 1, 'cuda': 2, 'rasp': 3} + type2str = {1: 'x86', 2: 'cuda', 3: 'rasp'} + def __init__(self, target_type): + """Constructs a context.""" + if isinstance(target_type, Target): + self.target_typeid = target_type.target_typeid + else: + self.target_typeid = Target.str2type[target_type] + + @property + def target_type(self): + """Returns the target type of current target.""" + return Target.type2str[self.target_typeid] + + def __hash__(self): + """Compute hash value of target for dictionary lookup""" + return hash(self.target_typeid) + + def __eq__(self, other): + """Compares two targets. Two targets are equal if they + have the same target type. + """ + return isinstance(other, Target) and \ + self.target_typeid == other.target_typeid + + def __str__(self): + return '%s' % (self.target_type) + + def __repr__(self): + return self.__str__() + + def __enter__(self): + self._old_target = Target.default_target + Target.default_target = self + return self + + def __exit__(self, ptype, value, trace): + Target.default_target = self._old_target + +Target.default_target = Target('x86') + +def x86(): + """Returns a x86 target.""" + return Target('x86') + +def cuda(): + """Returns a cuda target.""" + return Target('cuda') + +def rasp(): + """Returns a rasp target.""" + return Target('rasp') + +def current_target(): + """Returns the current target.""" + return Target.default_target diff --git a/topi/python/topi/__init__.py b/topi/python/topi/__init__.py index 0322f65bc8cc..1306f9d9cac8 100644 --- a/topi/python/topi/__init__.py +++ b/topi/python/topi/__init__.py @@ -16,6 +16,5 @@ from . import nn from . import cuda from . import rasp -from . import target from . import testing from . import util diff --git a/topi/python/topi/nn/__init__.py b/topi/python/topi/nn/__init__.py index 46edac975183..514149b00aa0 100644 --- a/topi/python/topi/nn/__init__.py +++ b/topi/python/topi/nn/__init__.py @@ -3,7 +3,7 @@ from __future__ import absolute_import as _abs from .batch_norm import * -from .convolution import * +from .conv2d import * from .depthwise_convolution import * from .elemwise import * from .dilate import * diff --git a/topi/python/topi/nn/convolution.py b/topi/python/topi/nn/conv2d.py similarity index 98% rename from topi/python/topi/nn/convolution.py rename to topi/python/topi/nn/conv2d.py index 6fe59781729d..9a410eaf3205 100644 --- a/topi/python/topi/nn/convolution.py +++ b/topi/python/topi/nn/conv2d.py @@ -1,5 +1,5 @@ # pylint: disable=invalid-name, unused-variable, too-many-locals -"""Convolution operators""" +"""Conv2D operators""" from __future__ import absolute_import as _abs from collections import namedtuple import tvm @@ -8,7 +8,7 @@ from ..util import simplify from .. import target as _target -# workload description of convolution +# workload description of conv2d Workload = namedtuple('Workload', ['height', 'width', 'in_filter', 'out_filter', 'hkernel', 'wkernel', 'hpad', 'wpad', 'hstride', 'wstride']) @@ -43,8 +43,8 @@ # platform specific declaration _CONV_DECLARATION = {} -def convolution(data, kernel, stride, padding, layout='NCHW'): - """Convolution operator. +def conv2d(data, kernel, stride, padding, layout='NCHW'): + """Conv2D operator. Parameters ---------- diff --git a/topi/python/topi/rasp/convolution.py b/topi/python/topi/rasp/conv2d.py similarity index 96% rename from topi/python/topi/rasp/convolution.py rename to topi/python/topi/rasp/conv2d.py index cb607f4075fb..aeee3d7e356d 100644 --- a/topi/python/topi/rasp/convolution.py +++ b/topi/python/topi/rasp/conv2d.py @@ -1,13 +1,13 @@ # pylint: disable=invalid-name,unused-variable,invalid-name -"""Convolution schedule on raspberry pi""" +"""Conv2D schedule on raspberry pi""" from __future__ import absolute_import as _abs import tvm from .. import target as _target from .. import tag -from ..nn.convolution import SpatialPack, Im2ColPack -from ..nn.convolution import _CONV_DECLARATION, _CONV_SCHEDULE -from ..nn.convolution import _WORKLOADS, _SCH_TO_DECL_FUNC -from ..nn.convolution import _get_workload, _get_schedule +from ..nn.conv2d import SpatialPack, Im2ColPack +from ..nn.conv2d import _CONV_DECLARATION, _CONV_SCHEDULE +from ..nn.conv2d import _WORKLOADS, _SCH_TO_DECL_FUNC +from ..nn.conv2d import _get_workload, _get_schedule from ..nn.util import infer_pad, infer_stride _SCHEDULES = [ @@ -264,7 +264,7 @@ def _schedule_im2col_conv2d(s, data, data_pad, data_col, data_vec, return s -def schedule_convolution(outs): +def schedule_conv2d(outs): """Create schedule for tensors""" s = tvm.create_schedule([x.op for x in outs]) diff --git a/topi/tests/python/test_topi_convolution.py b/topi/tests/python/test_topi_conv2d.py similarity index 71% rename from topi/tests/python/test_topi_convolution.py rename to topi/tests/python/test_topi_conv2d.py index 5dcedf4a4891..b731bfee997a 100644 --- a/topi/tests/python/test_topi_convolution.py +++ b/topi/tests/python/test_topi_conv2d.py @@ -1,4 +1,4 @@ -"""Example code to do convolution.""" +"""Example code to do conv2d.""" import os import numpy as np import tvm @@ -7,20 +7,20 @@ from topi.util import get_const_tuple -def verify_convolution(batch, in_size, in_channel, num_filter, kernel, stride, padding): +def verify_conv2d(batch, in_size, in_channel, num_filter, kernel, stride, padding): in_height = in_width = in_size - with topi.target.rasp(): + with tvm.target.rasp(): A = tvm.placeholder((batch, in_channel, in_height, in_width), name='A') W = tvm.placeholder((num_filter, in_channel, kernel, kernel), name='W') - B = topi.nn.convolution(A, W, stride, padding) + B = topi.nn.conv2d(A, W, stride, padding) - s = topi.rasp.schedule_convolution([B]) + s = topi.rasp.schedule_conv2d([B]) a_shape = get_const_tuple(A.shape) w_shape = get_const_tuple(W.shape) dtype = A.dtype - @memoize("topi.tests.test_topi_convolution.verify_convolution") + @memoize("topi.tests.test_topi_conv2d.verify_conv2d") def get_ref_data(): a_np = np.random.uniform(size=a_shape).astype(dtype) w_np = np.random.uniform(size=w_shape).astype(dtype) @@ -37,8 +37,8 @@ def get_ref_data(): func(a, w, b) np.testing.assert_allclose(b.asnumpy(), b_np, rtol=1e-5) -def test_convolution(): - verify_convolution(1, 56, 64, 64, 3, 1, 1) +def test_conv2d(): + verify_conv2d(1, 56, 64, 64, 3, 1, 1) if __name__ == "__main__": - test_convolution() + test_conv2d() From 2f8d3dbd7acd570a75c58832ff422be4b2978d9b Mon Sep 17 00:00:00 2001 From: ZihengJiang Date: Mon, 25 Sep 2017 21:55:07 -0700 Subject: [PATCH 2/3] Fix --- topi/python/topi/rasp/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/topi/python/topi/rasp/__init__.py b/topi/python/topi/rasp/__init__.py index 21f68e0c23a6..f0f605eeba9d 100644 --- a/topi/python/topi/rasp/__init__.py +++ b/topi/python/topi/rasp/__init__.py @@ -2,4 +2,4 @@ """Raspberry pi specific declaration and schedules.""" from __future__ import absolute_import as _abs -from .convolution import * +from .conv2d import * From 4425c853df87cabb9e1c24e8785fcb05a4f0be65 Mon Sep 17 00:00:00 2001 From: ZihengJiang Date: Tue, 26 Sep 2017 11:22:38 -0700 Subject: [PATCH 3/3] Fix --- topi/python/topi/nn/conv2d.py | 6 ++-- topi/python/topi/rasp/conv2d.py | 2 +- topi/python/topi/target.py | 63 --------------------------------- 3 files changed, 4 insertions(+), 67 deletions(-) delete mode 100644 topi/python/topi/target.py diff --git a/topi/python/topi/nn/conv2d.py b/topi/python/topi/nn/conv2d.py index 9a410eaf3205..fc20d9a9bd15 100644 --- a/topi/python/topi/nn/conv2d.py +++ b/topi/python/topi/nn/conv2d.py @@ -3,10 +3,10 @@ from __future__ import absolute_import as _abs from collections import namedtuple import tvm +from tvm import target as _target from .pad import pad from .util import get_pad_tuple from ..util import simplify -from .. import target as _target # workload description of conv2d Workload = namedtuple('Workload', @@ -75,9 +75,9 @@ def conv2d(data, kernel, stride, padding, layout='NCHW'): # default declaration if layout == 'NCHW': - conv2d_nchw(data, kernel, stride, padding) + return conv2d_nchw(data, kernel, stride, padding) elif layout == 'HWCN': - conv2d_hwcn(data, kernel, stride, padding) + return conv2d_hwcn(data, kernel, stride, padding) else: raise ValueError("not support this layout {} yet".format(layout)) diff --git a/topi/python/topi/rasp/conv2d.py b/topi/python/topi/rasp/conv2d.py index aeee3d7e356d..f48bd4a16ee1 100644 --- a/topi/python/topi/rasp/conv2d.py +++ b/topi/python/topi/rasp/conv2d.py @@ -2,7 +2,7 @@ """Conv2D schedule on raspberry pi""" from __future__ import absolute_import as _abs import tvm -from .. import target as _target +from tvm import target as _target from .. import tag from ..nn.conv2d import SpatialPack, Im2ColPack from ..nn.conv2d import _CONV_DECLARATION, _CONV_SCHEDULE diff --git a/topi/python/topi/target.py b/topi/python/topi/target.py deleted file mode 100644 index a4724a960972..000000000000 --- a/topi/python/topi/target.py +++ /dev/null @@ -1,63 +0,0 @@ -"""Target management API of topi""" - -from __future__ import absolute_import - -class Target(object): - """A Target describes the target type on which computation should be carried on""" - default_target = None - str2type = {'x86': 1, 'cuda': 2, 'rasp': 3} - type2str = {1: 'x86', 2: 'cuda', 3: 'rasp'} - def __init__(self, target_type): - """Constructs a context.""" - if isinstance(target_type, Target): - self.target_typeid = target_type.target_typeid - else: - self.target_typeid = Target.str2type[target_type] - - @property - def target_type(self): - """Returns the target type of current target.""" - return Target.type2str[self.target_typeid] - - def __hash__(self): - """Compute hash value of target for dictionary lookup""" - return hash(self.target_typeid) - - def __eq__(self, other): - """Compares two targets. Two targets are equal if they - have the same target type. - """ - return isinstance(other, Target) and \ - self.target_typeid == other.target_typeid - - def __str__(self): - return '%s' % (self.target_type) - - def __repr__(self): - return self.__str__() - - def __enter__(self): - self._old_target = Target.default_target - Target.default_target = self - return self - - def __exit__(self, ptype, value, trace): - Target.default_target = self._old_target - -Target.default_target = Target('x86') - -def x86(): - """Returns a x86 target.""" - return Target('x86') - -def cuda(): - """Returns a cuda target.""" - return Target('cuda') - -def rasp(): - """Returns a rasp target.""" - return Target('rasp') - -def current_target(): - """Returns the current target.""" - return Target.default_target