Merge pull request !3869 from looop5/remove_redundant_code_in_gputags/v0.7.0-beta
| @@ -1 +1 @@ | |||||
| Subproject commit 949a45538ccb7ae94ad73386b5e3e77005112eea | |||||
| Subproject commit 5fe7e5c8377dccfd35c9f661e10ed3dc136208c5 | |||||
| @@ -1,7 +0,0 @@ | |||||
| mindspore_add_pkg(dlpack | |||||
| VER 0.2 | |||||
| HEAD_ONLY ./ | |||||
| URL https://github.com/dmlc/dlpack/archive/0acb731e0e43d15deee27b66f10e4c5b4e667913.zip | |||||
| MD5 6b8093f17ad4e830d3c63eb3171c4b45) | |||||
| @@ -1,7 +0,0 @@ | |||||
| mindspore_add_pkg(dmlc-core | |||||
| VER 0.3 | |||||
| HEAD_ONLY ./ | |||||
| URL https://github.com/dmlc/dmlc-core/archive/808f485387f9a03f78fa9f1159f387d0d91b7a28.zip | |||||
| MD5 ea36f94c57752bf40fb02dfc362f1ed9) | |||||
| @@ -1,7 +0,0 @@ | |||||
| mindspore_add_pkg(rang | |||||
| VER 3.1.0 | |||||
| HEAD_ONLY ./ | |||||
| URL https://github.com/agauniyal/rang/archive/cabe04d6d6b05356fa8f9741704924788f0dd762.zip | |||||
| MD5 0c5c9b251fea9ee7ce32f188655be0ea) | |||||
| @@ -1,15 +0,0 @@ | |||||
| set(incubator_tvm_gpu_CXXFLAGS "-D_FORTIFY_SOURCE=2 -O2") | |||||
| set(incubator_tvm_gpu_CFLAGS "-D_FORTIFY_SOURCE=2 -O2") | |||||
| mindspore_add_pkg(incubator_tvm_gpu | |||||
| VER 0.6.0 | |||||
| LIBS tvm | |||||
| URL https://github.com/apache/incubator-tvm/archive/v0.6.0.tar.gz | |||||
| MD5 9cbbd32545a776023acabbba270449fe | |||||
| CUSTOM_CMAKE ${CMAKE_SOURCE_DIR}/third_party/patch/incubator-tvm/ | |||||
| SUBMODULES ${dlpack_DIRPATH} ${dmlc-core_DIRPATH} ${rang_DIRPATH} | |||||
| SOURCEMODULES topi/python/topi python/tvm | |||||
| PATCHES ${CMAKE_SOURCE_DIR}/third_party/patch/incubator-tvm/find_library.patch | |||||
| ${CMAKE_SOURCE_DIR}/third_party/patch/incubator-tvm/include.patch | |||||
| ${CMAKE_SOURCE_DIR}/third_party/patch/incubator-tvm/src_pass.patch | |||||
| CMAKE_OPTION " ") | |||||
| add_library(mindspore::tvm ALIAS incubator_tvm_gpu::tvm) | |||||
| @@ -47,11 +47,6 @@ if (ENABLE_CPU) | |||||
| endif() | endif() | ||||
| if (ENABLE_GPU) | if (ENABLE_GPU) | ||||
| include(${CMAKE_SOURCE_DIR}/cmake/external_libs/dlpack.cmake) | |||||
| include(${CMAKE_SOURCE_DIR}/cmake/external_libs/dmlc_core.cmake) | |||||
| include(${CMAKE_SOURCE_DIR}/cmake/external_libs/rang.cmake) | |||||
| include(${CMAKE_SOURCE_DIR}/cmake/external_libs/tvm_gpu.cmake) | |||||
| if (ENABLE_MPI) | if (ENABLE_MPI) | ||||
| include(${CMAKE_SOURCE_DIR}/cmake/external_libs/nccl.cmake) | include(${CMAKE_SOURCE_DIR}/cmake/external_libs/nccl.cmake) | ||||
| endif() | endif() | ||||
| @@ -245,29 +245,6 @@ install( | |||||
| COMPONENT mindspore | COMPONENT mindspore | ||||
| ) | ) | ||||
| if (ENABLE_GPU) | |||||
| install( | |||||
| DIRECTORY ${CMAKE_SOURCE_DIR}/mindspore/_akg | |||||
| DESTINATION ${INSTALL_PY_DIR}/../ | |||||
| COMPONENT mindspore | |||||
| ) | |||||
| if (EXISTS ${incubator_tvm_gpu_ROOT}) | |||||
| file(GLOB_RECURSE GLOG_LIB_LIST ${incubator_tvm_gpu_LIBPATH}/lib*) | |||||
| install( | |||||
| FILES ${GLOG_LIB_LIST} | |||||
| DESTINATION ${INSTALL_LIB_DIR} | |||||
| COMPONENT mindspore | |||||
| ) | |||||
| install( | |||||
| DIRECTORY | |||||
| ${incubator_tvm_gpu_ROOT}/topi/python/topi | |||||
| ${incubator_tvm_gpu_ROOT}/python/tvm | |||||
| DESTINATION ${INSTALL_PY_DIR}/../_akg | |||||
| COMPONENT mindspore | |||||
| ) | |||||
| endif () | |||||
| endif () | |||||
| if ((ENABLE_D OR ENABLE_GPU) AND ENABLE_AKG) | if ((ENABLE_D OR ENABLE_GPU) AND ENABLE_AKG) | ||||
| set (AKG_PATH ${CMAKE_SOURCE_DIR}/build/mindspore/akg) | set (AKG_PATH ${CMAKE_SOURCE_DIR}/build/mindspore/akg) | ||||
| install( | install( | ||||
| @@ -1,18 +0,0 @@ | |||||
| # Copyright 2019 Huawei Technologies Co., Ltd | |||||
| # | |||||
| # Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| # you may not use this file except in compliance with the License. | |||||
| # You may obtain a copy of the License at | |||||
| # | |||||
| # http://www.apache.org/licenses/LICENSE-2.0 | |||||
| # | |||||
| # Unless required by applicable law or agreed to in writing, software | |||||
| # distributed under the License is distributed on an "AS IS" BASIS, | |||||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| # See the License for the specific language governing permissions and | |||||
| # limitations under the License. | |||||
| """__init__""" | |||||
| from . import add_path | |||||
| from .op_build import op_build | |||||
| from .message import compilewithjson | |||||
| @@ -1,62 +0,0 @@ | |||||
| # Copyright 2020 Huawei Technologies Co., Ltd | |||||
| # | |||||
| # Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| # you may not use this file except in compliance with the License. | |||||
| # You may obtain a copy of the License at | |||||
| # | |||||
| # http://www.apache.org/licenses/LICENSE-2.0 | |||||
| # | |||||
| # Unless required by applicable law or agreed to in writing, software | |||||
| # distributed under the License is distributed on an "AS IS" BASIS, | |||||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| # See the License for the specific language governing permissions and | |||||
| # limitations under the License. | |||||
| """add tvm path""" | |||||
| import sys | |||||
| import os | |||||
| def AKGAddPath(): | |||||
| """_akg add path.""" | |||||
| pwd = os.path.dirname(os.path.realpath(__file__)) | |||||
| tvm_path = os.path.realpath(pwd) | |||||
| if tvm_path not in sys.path: | |||||
| sys.path.insert(0, tvm_path) | |||||
| else: | |||||
| sys.path.remove(tvm_path) | |||||
| sys.path.insert(0, tvm_path) | |||||
| class AKGMetaPathFinder: | |||||
| """class AKGMetaPath finder.""" | |||||
| def find_module(self, fullname, path=None): | |||||
| """method _akg find module.""" | |||||
| _ = path | |||||
| if fullname.startswith("_akg.tvm"): | |||||
| rname = fullname[5:] | |||||
| return AKGMetaPathLoader(rname) | |||||
| if fullname.startswith("_akg.topi"): | |||||
| rname = fullname[5:] | |||||
| return AKGMetaPathLoader(rname) | |||||
| return None | |||||
| class AKGMetaPathLoader: | |||||
| """class AKGMetaPathLoader loader.""" | |||||
| def __init__(self, rname): | |||||
| self.__rname = rname | |||||
| def load_module(self, fullname): | |||||
| if self.__rname in sys.modules: | |||||
| sys.modules.pop(self.__rname) | |||||
| AKGAddPath() | |||||
| __import__(self.__rname, globals(), locals()) | |||||
| self.__target_module = sys.modules[self.__rname] | |||||
| sys.modules[fullname] = self.__target_module | |||||
| return self.__target_module | |||||
| sys.meta_path.insert(0, AKGMetaPathFinder()) | |||||
| @@ -1,39 +0,0 @@ | |||||
| # Copyright 2019 Huawei Technologies Co., Ltd | |||||
| # | |||||
| # Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| # you may not use this file except in compliance with the License. | |||||
| # You may obtain a copy of the License at | |||||
| # | |||||
| # http://www.apache.org/licenses/LICENSE-2.0 | |||||
| # | |||||
| # Unless required by applicable law or agreed to in writing, software | |||||
| # distributed under the License is distributed on an "AS IS" BASIS, | |||||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| # See the License for the specific language governing permissions and | |||||
| # limitations under the License. | |||||
| """__init__""" | |||||
| from .equal import Equal | |||||
| from .equal import gpu_schedule_Equal | |||||
| from .tile import Tile | |||||
| from .tile import gpu_schedule_Tile | |||||
| from .cast import Cast | |||||
| from .cast import gpu_schedule_Cast | |||||
| from .relu6 import ReLU6, gpu_schedule_ReLU6 | |||||
| from .relu6_grad import ReLU6Grad, gpu_schedule_ReLU6Grad | |||||
| from .squeeze import Squeeze, gpu_schedule_Squeeze | |||||
| from .squeeze_grad import SqueezeGrad, gpu_schedule_SqueezeGrad | |||||
| from .mean import SimpleMean, gpu_schedule_SimpleMean | |||||
| from .mean_grad import SimpleMeanGrad, gpu_schedule_SimpleMeanGrad | |||||
| from .mul import Mul, gpu_schedule_Mul | |||||
| from .hsigmoid import HSigmoid, gpu_schedule_HSigmoid | |||||
| from .hsigmoid_grad import HSigmoidGrad, gpu_schedule_HSigmoidGrad | |||||
| from .hswish import HSwish, gpu_schedule_HSwish | |||||
| from .hswish_grad import HSwishGrad, gpu_schedule_HSwishGrad | |||||
| from .logical_or import LogicalOr, gpu_schedule_LogicalOr | |||||
| from .logical_not import LogicalNot, gpu_schedule_LogicalNot | |||||
| from .logical_and import LogicalAnd, gpu_schedule_LogicalAnd | |||||
| from .sub import Sub, gpu_schedule_Sub | |||||
| from .less_equal import LessEqual, gpu_schedule_LessEqual | |||||
| from .notequal import NotEqual, gpu_schedule_NotEqual | |||||
| from .greater_equal import GreaterEqual, gpu_schedule_GreaterEqual | |||||
| @@ -1,45 +0,0 @@ | |||||
| # Copyright 2019 Huawei Technologies Co., Ltd | |||||
| # | |||||
| # Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| # you may not use this file except in compliance with the License. | |||||
| # You may obtain a copy of the License at | |||||
| # | |||||
| # http://www.apache.org/licenses/LICENSE-2.0 | |||||
| # | |||||
| # Unless required by applicable law or agreed to in writing, software | |||||
| # distributed under the License is distributed on an "AS IS" BASIS, | |||||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| # See the License for the specific language governing permissions and | |||||
| # limitations under the License. | |||||
| """cast""" | |||||
| import logging | |||||
| import _akg.tvm | |||||
| from _akg.ops.math import cast | |||||
| from _akg.topi.generic import schedule_elemwise | |||||
| def Cast(x, dst_type): | |||||
| """cast.""" | |||||
| if x.dtype == "int64" and dst_type == "float16": | |||||
| x = cast.cast(x, "float32") | |||||
| return cast.cast(x, dst_type) | |||||
| def gpu_schedule_Cast(outs): | |||||
| """ | |||||
| gpu schedule for cast. | |||||
| Args: | |||||
| outs (tvm.tensor.Tensor): outputs of compute. | |||||
| Returns: | |||||
| sch (schedule.Schedule): The created schedule. | |||||
| """ | |||||
| device = 'cuda' | |||||
| ctx = _akg.tvm.context(device, 0) | |||||
| if not ctx.exist: | |||||
| logging.info("Skip because %s is not enabled", device) | |||||
| return None | |||||
| with _akg.tvm.target.create(device): | |||||
| sch = schedule_elemwise(outs) | |||||
| return sch | |||||
| @@ -1,56 +0,0 @@ | |||||
| # Copyright 2019 Huawei Technologies Co., Ltd | |||||
| # | |||||
| # Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| # you may not use this file except in compliance with the License. | |||||
| # You may obtain a copy of the License at | |||||
| # | |||||
| # http://www.apache.org/licenses/LICENSE-2.0 | |||||
| # | |||||
| # Unless required by applicable law or agreed to in writing, software | |||||
| # distributed under the License is distributed on an "AS IS" BASIS, | |||||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| # See the License for the specific language governing permissions and | |||||
| # limitations under the License. | |||||
| """default schedule function for GPU""" | |||||
| from queue import Queue | |||||
| import _akg.tvm as tvm | |||||
| DEFAULT_GPU_THREAD = 1024 | |||||
| def default_schedule(outs): | |||||
| """ | |||||
| default schedule function. | |||||
| Args: | |||||
| outs (Union[tvm.tensor.Tensor, list[tvm.tensor.Tensor]]): outputs of compute. | |||||
| Returns: | |||||
| sch (schedule.Schedule): The created schedule. | |||||
| """ | |||||
| if not isinstance(outs, tvm.tensor.Tensor) and not isinstance(outs, list): | |||||
| raise ValueError("outs should be list of _akg.tvm.tensor.Tensor or _akg.tvm.tensor.Tensor") | |||||
| device = 'cuda' | |||||
| ctx = tvm.context(device, 0) | |||||
| if not ctx.exist: | |||||
| raise SystemError("Skip because %s is not enabled" % device) | |||||
| outs_list = [outs] if isinstance(outs, tvm.tensor.Tensor) else outs | |||||
| with tvm.target.create(device): | |||||
| sch = tvm.create_schedule(outs_list[0].op) | |||||
| outputs_tensor = Queue() | |||||
| outputs_tensor.put(outs_list[0]) | |||||
| op_list = [] | |||||
| while not outputs_tensor.empty(): | |||||
| out = outputs_tensor.get() | |||||
| if out.op not in op_list and isinstance(out.op, tvm.tensor.ComputeOp): | |||||
| op_list.append(out.op) | |||||
| for input_tensor in out.op.input_tensors: | |||||
| outputs_tensor.put(input_tensor) | |||||
| for op in op_list: | |||||
| stage = sch[op.output(0)] | |||||
| bx, tx = stage.split(op.axis[0], factor=DEFAULT_GPU_THREAD) | |||||
| stage.bind(bx, tvm.thread_axis("blockIdx.x")) | |||||
| stage.bind(tx, tvm.thread_axis("threadIdx.x")) | |||||
| return sch | |||||
| @@ -1,40 +0,0 @@ | |||||
| # Copyright 2019 Huawei Technologies Co., Ltd | |||||
| # | |||||
| # Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| # you may not use this file except in compliance with the License. | |||||
| # You may obtain a copy of the License at | |||||
| # | |||||
| # http://www.apache.org/licenses/LICENSE-2.0 | |||||
| # | |||||
| # Unless required by applicable law or agreed to in writing, software | |||||
| # distributed under the License is distributed on an "AS IS" BASIS, | |||||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| # See the License for the specific language governing permissions and | |||||
| # limitations under the License. | |||||
| """equal""" | |||||
| import _akg.tvm | |||||
| from _akg.ops.math import equal | |||||
| from _akg.topi.generic import schedule_elemwise | |||||
| def Equal(x, y): | |||||
| """equal.""" | |||||
| return equal.equal(x, y) | |||||
| def gpu_schedule_Equal(outs): | |||||
| """ | |||||
| gpu schedule for Equal. | |||||
| Args: | |||||
| outs (tvm.tensor.Tensor): outputs of compute. | |||||
| Returns: | |||||
| sch (schedule.Schedule): The created schedule. | |||||
| """ | |||||
| device = 'cuda' | |||||
| ctx = _akg.tvm.context(device, 0) | |||||
| if not ctx.exist: | |||||
| raise SystemError("Skip because %s is not enabled" % device) | |||||
| with _akg.tvm.target.create(device): | |||||
| sch = schedule_elemwise(outs) | |||||
| return sch | |||||
| @@ -1,41 +0,0 @@ | |||||
| # Copyright 2020 Huawei Technologies Co., Ltd | |||||
| # | |||||
| # Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| # you may not use this file except in compliance with the License. | |||||
| # You may obtain a copy of the License at | |||||
| # | |||||
| # http://www.apache.org/licenses/LICENSE-2.0 | |||||
| # | |||||
| # Unless required by applicable law or agreed to in writing, software | |||||
| # distributed under the License is distributed on an "AS IS" BASIS, | |||||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| # See the License for the specific language governing permissions and | |||||
| # limitations under the License. | |||||
| """greater_equal""" | |||||
| import _akg.tvm | |||||
| from _akg.ops.math import greater_equal | |||||
| from _akg.topi.generic import schedule_elemwise | |||||
| def GreaterEqual(x, y): | |||||
| """GreaterEqual.""" | |||||
| return greater_equal.greater_equal(x, y) | |||||
| def gpu_schedule_GreaterEqual(outs): | |||||
| """ | |||||
| GPU schedule for GreaterEqual. | |||||
| Args: | |||||
| outs (tvm.tensor.Tensor): Outputs of compute. | |||||
| Returns: | |||||
| sch (schedule.Schedule): The created schedule. | |||||
| """ | |||||
| device = 'cuda' | |||||
| ctx = _akg.tvm.context(device, 0) | |||||
| if not ctx.exist: | |||||
| raise SystemError("Skip because %s is not enabled" % device) | |||||
| with _akg.tvm.target.create(device): | |||||
| sch = schedule_elemwise(outs) | |||||
| return sch | |||||
| @@ -1,63 +0,0 @@ | |||||
| # Copyright 2019 Huawei Technologies Co., Ltd | |||||
| # | |||||
| # Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| # you may not use this file except in compliance with the License. | |||||
| # You may obtain a copy of the License at | |||||
| # | |||||
| # http://www.apache.org/licenses/LICENSE-2.0 | |||||
| # | |||||
| # Unless required by applicable law or agreed to in writing, software | |||||
| # distributed under the License is distributed on an "AS IS" BASIS, | |||||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| # See the License for the specific language governing permissions and | |||||
| # limitations under the License. | |||||
| """hsigmoid""" | |||||
| import _akg.topi as topi | |||||
| import _akg.tvm as tvm | |||||
| from _akg.topi import tag | |||||
| @tvm.tag_scope(tag=tag.ELEMWISE) | |||||
| def topi_nn_hsigmoid(x): | |||||
| """ | |||||
| topi hsigmoid | |||||
| Args: | |||||
| x: | |||||
| Returns: | |||||
| """ | |||||
| return tvm.compute(x.shape, lambda *i: tvm.if_then_else(x(*i) <= -3, 0, | |||||
| tvm.if_then_else(x(*i) >= 3, 1, | |||||
| (x(*i) + 3) / 6))) | |||||
| def HSigmoid(x): | |||||
| """ | |||||
| HSigmoid | |||||
| Args: | |||||
| x: | |||||
| Returns: | |||||
| """ | |||||
| return topi_nn_hsigmoid(x) | |||||
| def gpu_schedule_HSigmoid(outs): | |||||
| """ | |||||
| gpu schedule HSigmoid | |||||
| Args: | |||||
| outs: | |||||
| Returns: | |||||
| """ | |||||
| device = 'cuda' | |||||
| ctx = tvm.context(device, 0) | |||||
| if not ctx.exist: | |||||
| raise SystemError("Skip because %s is not enabled" % device) | |||||
| with tvm.target.create(device): | |||||
| sch = topi.cuda.schedule_elemwise(outs) | |||||
| return sch | |||||
| @@ -1,51 +0,0 @@ | |||||
| # Copyright 2019 Huawei Technologies Co., Ltd | |||||
| # | |||||
| # Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| # you may not use this file except in compliance with the License. | |||||
| # You may obtain a copy of the License at | |||||
| # | |||||
| # http://www.apache.org/licenses/LICENSE-2.0 | |||||
| # | |||||
| # Unless required by applicable law or agreed to in writing, software | |||||
| # distributed under the License is distributed on an "AS IS" BASIS, | |||||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| # See the License for the specific language governing permissions and | |||||
| # limitations under the License. | |||||
| """HSigmoid grad""" | |||||
| import _akg.topi as topi | |||||
| import _akg.tvm as tvm | |||||
| def HSigmoidGrad(y_grad, x): | |||||
| """ | |||||
| HSigmoidGrad | |||||
| Args: | |||||
| y_grad: | |||||
| x: | |||||
| Returns: | |||||
| """ | |||||
| return tvm.compute(x.shape, lambda *i: tvm.if_then_else(x(*i) <= -3, 0, | |||||
| tvm.if_then_else(x(*i) >= 3, 0, | |||||
| y_grad(*i) / 6))) | |||||
| def gpu_schedule_HSigmoidGrad(outs): | |||||
| """ | |||||
| gpu schedule ReLU6Grad | |||||
| Args: | |||||
| outs: | |||||
| Returns: | |||||
| """ | |||||
| device = 'cuda' | |||||
| ctx = tvm.context(device, 0) | |||||
| if not ctx.exist: | |||||
| raise SystemError("Skip because %s is not enabled" % device) | |||||
| with tvm.target.create(device): | |||||
| sch = topi.cuda.schedule_elemwise(outs) | |||||
| return sch | |||||
| @@ -1,63 +0,0 @@ | |||||
| # Copyright 2019 Huawei Technologies Co., Ltd | |||||
| # | |||||
| # Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| # you may not use this file except in compliance with the License. | |||||
| # You may obtain a copy of the License at | |||||
| # | |||||
| # http://www.apache.org/licenses/LICENSE-2.0 | |||||
| # | |||||
| # Unless required by applicable law or agreed to in writing, software | |||||
| # distributed under the License is distributed on an "AS IS" BASIS, | |||||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| # See the License for the specific language governing permissions and | |||||
| # limitations under the License. | |||||
| """HSwish""" | |||||
| import _akg.topi as topi | |||||
| import _akg.tvm as tvm | |||||
| from _akg.topi import tag | |||||
| @tvm.tag_scope(tag=tag.ELEMWISE) | |||||
| def topi_nn_HSwish(x): | |||||
| """ | |||||
| topi HSwish | |||||
| Args: | |||||
| x: | |||||
| Returns: | |||||
| """ | |||||
| return tvm.compute(x.shape, lambda *i: tvm.if_then_else(x(*i) <= -3, 0, | |||||
| tvm.if_then_else(x(*i) >= 3, x(*i), | |||||
| x(*i) * (x(*i) + 3) / 6))) | |||||
| def HSwish(x): | |||||
| """ | |||||
| HSwish | |||||
| Args: | |||||
| x: | |||||
| Returns: | |||||
| """ | |||||
| return topi_nn_HSwish(x) | |||||
| def gpu_schedule_HSwish(outs): | |||||
| """ | |||||
| gpu schedule HSwish | |||||
| Args: | |||||
| outs: | |||||
| Returns: | |||||
| """ | |||||
| device = 'cuda' | |||||
| ctx = tvm.context(device, 0) | |||||
| if not ctx.exist: | |||||
| raise SystemError("Skip because %s is not enabled" % device) | |||||
| with tvm.target.create(device): | |||||
| sch = topi.cuda.schedule_elemwise(outs) | |||||
| return sch | |||||
| @@ -1,53 +0,0 @@ | |||||
| # Copyright 2019 Huawei Technologies Co., Ltd | |||||
| # | |||||
| # Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| # you may not use this file except in compliance with the License. | |||||
| # You may obtain a copy of the License at | |||||
| # | |||||
| # http://www.apache.org/licenses/LICENSE-2.0 | |||||
| # | |||||
| # Unless required by applicable law or agreed to in writing, software | |||||
| # distributed under the License is distributed on an "AS IS" BASIS, | |||||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| # See the License for the specific language governing permissions and | |||||
| # limitations under the License. | |||||
| """HSwishGrad""" | |||||
| import _akg.topi as topi | |||||
| import _akg.tvm as tvm | |||||
| def HSwishGrad(y_grad, x): | |||||
| """ | |||||
| HSwishGrad | |||||
| Args: | |||||
| y_grad: | |||||
| x: | |||||
| Returns: | |||||
| """ | |||||
| shape = x.shape | |||||
| res0 = tvm.compute(shape, lambda *i: tvm.if_then_else(x(*i) <= -3, 0, y_grad(*i) * (2 * x(*i) + 3) / 6)) | |||||
| res6 = tvm.compute(shape, lambda *i: tvm.if_then_else(x(*i) >= 3, y_grad(*i), res0(*i))) | |||||
| return res6 | |||||
| def gpu_schedule_HSwishGrad(outs): | |||||
| """ | |||||
| gpu schedule HSwishGrad | |||||
| Args: | |||||
| outs: | |||||
| Returns: | |||||
| """ | |||||
| device = 'cuda' | |||||
| ctx = tvm.context(device, 0) | |||||
| if not ctx.exist: | |||||
| raise SystemError("Skip because %s is not enabled" % device) | |||||
| with tvm.target.create(device): | |||||
| sch = topi.cuda.schedule_elemwise(outs) | |||||
| return sch | |||||
| @@ -1,40 +0,0 @@ | |||||
| # Copyright 2020 Huawei Technologies Co., Ltd | |||||
| # | |||||
| # Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| # you may not use this file except in compliance with the License. | |||||
| # You may obtain a copy of the License at | |||||
| # | |||||
| # http://www.apache.org/licenses/LICENSE-2.0 | |||||
| # | |||||
| # Unless required by applicable law or agreed to in writing, software | |||||
| # distributed under the License is distributed on an "AS IS" BASIS, | |||||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| # See the License for the specific language governing permissions and | |||||
| # limitations under the License. | |||||
| """less_equal""" | |||||
| import _akg.tvm | |||||
| from _akg.ops.math import less_equal | |||||
| from _akg.topi.generic import schedule_elemwise | |||||
| def LessEqual(x, y): | |||||
| """LessEqual.""" | |||||
| return less_equal.less_equal(x, y) | |||||
| def gpu_schedule_LessEqual(outs): | |||||
| """ | |||||
| GPU schedule for LessEqual. | |||||
| Args: | |||||
| outs (tvm.tensor.Tensor): Outputs of compute. | |||||
| Returns: | |||||
| sch (schedule.Schedule): The created schedule. | |||||
| """ | |||||
| device = 'cuda' | |||||
| ctx = _akg.tvm.context(device, 0) | |||||
| if not ctx.exist: | |||||
| raise SystemError("Skip because %s is not enabled" % device) | |||||
| with _akg.tvm.target.create(device): | |||||
| sch = schedule_elemwise(outs) | |||||
| return sch | |||||
| @@ -1,40 +0,0 @@ | |||||
| # Copyright 2020 Huawei Technologies Co., Ltd | |||||
| # | |||||
| # Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| # you may not use this file except in compliance with the License. | |||||
| # You may obtain a copy of the License at | |||||
| # | |||||
| # http://www.apache.org/licenses/LICENSE-2.0 | |||||
| # | |||||
| # Unless required by applicable law or agreed to in writing, software | |||||
| # distributed under the License is distributed on an "AS IS" BASIS, | |||||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| # See the License for the specific language governing permissions and | |||||
| # limitations under the License. | |||||
| """logical_and""" | |||||
| import _akg.tvm | |||||
| from _akg.ops.math import logical_and | |||||
| from _akg.topi.generic import schedule_elemwise | |||||
| def LogicalAnd(x, y): | |||||
| """LogicalAnd.""" | |||||
| return logical_and.logical_and(x, y) | |||||
| def gpu_schedule_LogicalAnd(outs): | |||||
| """ | |||||
| GPU schedule for LogicalAnd. | |||||
| Args: | |||||
| outs (tvm.tensor.Tensor): outputs of compute. | |||||
| Returns: | |||||
| sch (schedule.Schedule): The created schedule. | |||||
| """ | |||||
| device = 'cuda' | |||||
| ctx = _akg.tvm.context(device, 0) | |||||
| if not ctx.exist: | |||||
| raise SystemError("Skip because %s is not enabled" % device) | |||||
| with _akg.tvm.target.create(device): | |||||
| sch = schedule_elemwise(outs) | |||||
| return sch | |||||
| @@ -1,40 +0,0 @@ | |||||
| # Copyright 2020 Huawei Technologies Co., Ltd | |||||
| # | |||||
| # Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| # you may not use this file except in compliance with the License. | |||||
| # You may obtain a copy of the License at | |||||
| # | |||||
| # http://www.apache.org/licenses/LICENSE-2.0 | |||||
| # | |||||
| # Unless required by applicable law or agreed to in writing, software | |||||
| # distributed under the License is distributed on an "AS IS" BASIS, | |||||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| # See the License for the specific language governing permissions and | |||||
| # limitations under the License. | |||||
| """logical_not""" | |||||
| import _akg.tvm | |||||
| from _akg.ops.math import logical_not | |||||
| from _akg.topi.generic import schedule_elemwise | |||||
| def LogicalNot(x): | |||||
| """LogicalNot.""" | |||||
| return logical_not.logical_not(x) | |||||
| def gpu_schedule_LogicalNot(outs): | |||||
| """ | |||||
| GPU schedule for LogicalNot. | |||||
| Args: | |||||
| outs (tvm.tensor.Tensor): outputs of compute. | |||||
| Returns: | |||||
| sch (schedule.Schedule): The created schedule. | |||||
| """ | |||||
| device = 'cuda' | |||||
| ctx = _akg.tvm.context(device, 0) | |||||
| if not ctx.exist: | |||||
| raise SystemError("Skip because %s is not enabled" % device) | |||||
| with _akg.tvm.target.create(device): | |||||
| sch = schedule_elemwise(outs) | |||||
| return sch | |||||
| @@ -1,40 +0,0 @@ | |||||
| # Copyright 2020 Huawei Technologies Co., Ltd | |||||
| # | |||||
| # Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| # you may not use this file except in compliance with the License. | |||||
| # You may obtain a copy of the License at | |||||
| # | |||||
| # http://www.apache.org/licenses/LICENSE-2.0 | |||||
| # | |||||
| # Unless required by applicable law or agreed to in writing, software | |||||
| # distributed under the License is distributed on an "AS IS" BASIS, | |||||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| # See the License for the specific language governing permissions and | |||||
| # limitations under the License. | |||||
| """logical_or""" | |||||
| import _akg.tvm | |||||
| from _akg.ops.math import logical_or | |||||
| from _akg.topi.generic import schedule_elemwise | |||||
| def LogicalOr(x, y): | |||||
| """LogicalOr.""" | |||||
| return logical_or.logical_or(x, y) | |||||
| def gpu_schedule_LogicalOr(outs): | |||||
| """ | |||||
| GPU schedule for LogicalOr. | |||||
| Args: | |||||
| outs (tvm.tensor.Tensor): outputs of compute. | |||||
| Returns: | |||||
| sch (schedule.Schedule): The created schedule. | |||||
| """ | |||||
| device = 'cuda' | |||||
| ctx = _akg.tvm.context(device, 0) | |||||
| if not ctx.exist: | |||||
| raise SystemError("Skip because %s is not enabled" % device) | |||||
| with _akg.tvm.target.create(device): | |||||
| sch = schedule_elemwise(outs) | |||||
| return sch | |||||
| @@ -1,80 +0,0 @@ | |||||
| # Copyright 2019 Huawei Technologies Co., Ltd | |||||
| # | |||||
| # Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| # you may not use this file except in compliance with the License. | |||||
| # You may obtain a copy of the License at | |||||
| # | |||||
| # http://www.apache.org/licenses/LICENSE-2.0 | |||||
| # | |||||
| # Unless required by applicable law or agreed to in writing, software | |||||
| # distributed under the License is distributed on an "AS IS" BASIS, | |||||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| # See the License for the specific language governing permissions and | |||||
| # limitations under the License. | |||||
| """mean op compute and schedule""" | |||||
| import _akg.tvm as tvm | |||||
| from _akg.ops.math.mean import mean | |||||
| from .default_schedule import DEFAULT_GPU_THREAD | |||||
| def Mean(x, axis=None, keepdims=True): | |||||
| """mean.""" | |||||
| outs = mean(x, axis, keepdims) | |||||
| # remove useless mean_output | |||||
| if isinstance(outs, tuple): | |||||
| outs = outs[0] | |||||
| if outs.op.name == "mean_output": | |||||
| outs = outs.op.input_tensors[0] | |||||
| return outs | |||||
| def gpu_schedule_Mean(outs): | |||||
| """ | |||||
| gpu schedule function for mean. | |||||
| Args: | |||||
| outs (tvm.tensor.Tensor): outputs of compute. | |||||
| Returns: | |||||
| sch (schedule.Schedule): The created schedule. | |||||
| """ | |||||
| out = outs[0] if isinstance(outs, list) else outs | |||||
| device = "cuda" | |||||
| with tvm.target.create(device): | |||||
| sch = tvm.create_schedule(out.op) | |||||
| if out.op.name == "T_divide": | |||||
| tensor_c = out | |||||
| else: # squeeze | |||||
| tensor_c = out.op.input_tensors[0] | |||||
| tensor_b = tensor_c.op.input_tensors[0] | |||||
| if len(tensor_c.op.axis) >= 2: | |||||
| sch[tensor_b].compute_at(sch[tensor_c], tensor_c.op.axis[1]) | |||||
| else: | |||||
| sch[tensor_b].compute_at(sch[tensor_c], tensor_c.op.axis[0]) | |||||
| bx, tx = sch[tensor_c].split(tensor_c.op.axis[0], factor=DEFAULT_GPU_THREAD) | |||||
| sch[tensor_c].bind(bx, tvm.thread_axis("blockIdx.x")) | |||||
| sch[tensor_c].bind(tx, tvm.thread_axis("threadIdx.x")) | |||||
| return sch | |||||
| def SimpleMean(x): | |||||
| """ | |||||
| SimpleMean compute the mean of the input 4D Tensor over last two axises and keep reduced dimensions. | |||||
| Args: | |||||
| x (tvm.tensor.Tensor): Tensor of type float16, float32. | |||||
| Returns: | |||||
| tvm.tensor.Tensor, has the same type as x, output shape will be (a, b, 1, 1) if input Tensor x is (a, b, c, d). | |||||
| """ | |||||
| axis = (2, 3) | |||||
| keepdims = True | |||||
| return Mean(x, axis, keepdims) | |||||
| def gpu_schedule_SimpleMean(outs): | |||||
| """gpu schedule function for SimpleMean.""" | |||||
| return gpu_schedule_Mean(outs) | |||||
| @@ -1,90 +0,0 @@ | |||||
| # Copyright 2019 Huawei Technologies Co., Ltd | |||||
| # | |||||
| # Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| # you may not use this file except in compliance with the License. | |||||
| # You may obtain a copy of the License at | |||||
| # | |||||
| # http://www.apache.org/licenses/LICENSE-2.0 | |||||
| # | |||||
| # Unless required by applicable law or agreed to in writing, software | |||||
| # distributed under the License is distributed on an "AS IS" BASIS, | |||||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| # See the License for the specific language governing permissions and | |||||
| # limitations under the License. | |||||
| """mean_grad""" | |||||
| import _akg.tvm as tvm | |||||
| import _akg | |||||
| from _akg.ops.math import mean | |||||
| from .default_schedule import DEFAULT_GPU_THREAD | |||||
| def mean_ad(head, input_shape, axis, keepdims): | |||||
| """mean autodiff.""" | |||||
| tensor_a = tvm.placeholder(input_shape, head.dtype, "A") | |||||
| tensor_b = mean.mean(tensor_a, axis, keepdims) | |||||
| # remove useless mean_output | |||||
| if isinstance(tensor_b, tuple): | |||||
| tensor_b = tensor_b[0] | |||||
| if tensor_b.op.name == "mean_output": | |||||
| tensor_b = tensor_b.op.input_tensors[0] | |||||
| jacs = list(_akg.differentiate(tensor_b, [tensor_a], head)) | |||||
| return jacs[0] | |||||
| def MeanGrad(y_grad, input_shape, axis=None, keepdims=True): | |||||
| """Mean Grad.""" | |||||
| if axis is None and not keepdims: | |||||
| raise ValueError("Mean not support (axis=None && keepdims=False) now") | |||||
| return mean_ad(y_grad, input_shape, axis, keepdims) | |||||
| def gpu_schedule_MeanGrad(outs): | |||||
| """gpu schedule MeanGrad.""" | |||||
| out = outs[0] if isinstance(outs, list) else outs | |||||
| device = "cuda" | |||||
| with tvm.target.create(device): | |||||
| sch = tvm.create_schedule(out.op) | |||||
| tensor_c = out | |||||
| tensor_b = tensor_c.op.input_tensors[0] | |||||
| if len(tensor_c.op.axis) >= 2: | |||||
| sch[tensor_b].compute_at(sch[tensor_c], tensor_c.op.axis[1]) | |||||
| else: | |||||
| sch[tensor_b].compute_at(sch[tensor_c], tensor_c.op.axis[0]) | |||||
| bx, tx = sch[tensor_c].split(tensor_c.op.axis[0], factor=DEFAULT_GPU_THREAD) | |||||
| sch[tensor_c].bind(bx, tvm.thread_axis("blockIdx.x")) | |||||
| sch[tensor_c].bind(tx, tvm.thread_axis("threadIdx.x")) | |||||
| return sch | |||||
| def SimpleMeanGrad(HEAD, input_shape): | |||||
| """ | |||||
| Compute Simple Mean Grad. | |||||
| Args: | |||||
| HEAD (tvm.tensor.Tensor): output gradient, dy, defined in Primitive. | |||||
| input_shape (Union[list[int], tuple[int]]): shape of mean input, x.shape. | |||||
| Returns: | |||||
| tvm.tensor.Tensor, gradient of mean input. | |||||
| """ | |||||
| axis = (2, 3) | |||||
| keepdims = True | |||||
| return MeanGrad(HEAD, input_shape, axis, keepdims) | |||||
| def gpu_schedule_SimpleMeanGrad(outs): | |||||
| """ | |||||
| gpu schedule SimpleMeanGrad. | |||||
| Args: | |||||
| outs (tvm.tensor.Tensor): outputs of compute. | |||||
| Returns: | |||||
| sch (schedule.Schedule): The created schedule. | |||||
| """ | |||||
| return gpu_schedule_MeanGrad(outs) | |||||
| @@ -1,41 +0,0 @@ | |||||
| # Copyright 2019 Huawei Technologies Co., Ltd | |||||
| # | |||||
| # Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| # you may not use this file except in compliance with the License. | |||||
| # You may obtain a copy of the License at | |||||
| # | |||||
| # http://www.apache.org/licenses/LICENSE-2.0 | |||||
| # | |||||
| # Unless required by applicable law or agreed to in writing, software | |||||
| # distributed under the License is distributed on an "AS IS" BASIS, | |||||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| # See the License for the specific language governing permissions and | |||||
| # limitations under the License. | |||||
| """mul""" | |||||
| import _akg.topi as topi | |||||
| import _akg.tvm as tvm | |||||
| from _akg.ops.math import mul | |||||
| def Mul(x, y): | |||||
| """mul.""" | |||||
| return mul.mul(x, y) | |||||
| def gpu_schedule_Mul(outs): | |||||
| """ | |||||
| gpu schedule for mul. | |||||
| Args: | |||||
| outs (tvm.tensor.Tensor): outputs of compute. | |||||
| Returns: | |||||
| sch (schedule.Schedule): The created schedule. | |||||
| """ | |||||
| device = 'cuda' | |||||
| ctx = tvm.context(device, 0) | |||||
| if not ctx.exist: | |||||
| raise SystemError("Skip because %s is not enabled" % device) | |||||
| with tvm.target.create(device): | |||||
| sch = topi.cuda.schedule_broadcast(outs) | |||||
| return sch | |||||
| @@ -1,41 +0,0 @@ | |||||
| # Copyright 2020 Huawei Technologies Co., Ltd | |||||
| # | |||||
| # Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| # you may not use this file except in compliance with the License. | |||||
| # You may obtain a copy of the License at | |||||
| # | |||||
| # http://www.apache.org/licenses/LICENSE-2.0 | |||||
| # | |||||
| # Unless required by applicable law or agreed to in writing, software | |||||
| # distributed under the License is distributed on an "AS IS" BASIS, | |||||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| # See the License for the specific language governing permissions and | |||||
| # limitations under the License. | |||||
| """notequal""" | |||||
| import _akg.tvm | |||||
| from _akg.ops.math import notequal | |||||
| from _akg.topi.generic import schedule_elemwise | |||||
| def NotEqual(x, y): | |||||
| """notequal.""" | |||||
| return notequal.notequal(x, y) | |||||
| def gpu_schedule_NotEqual(outs): | |||||
| """ | |||||
| gpu schedule for NotEqual. | |||||
| Args: | |||||
| outs (tvm.tensor.Tensor): outputs of compute. | |||||
| Returns: | |||||
| sch (schedule.Schedule): The created schedule. | |||||
| """ | |||||
| device = 'cuda' | |||||
| ctx = _akg.tvm.context(device, 0) | |||||
| if not ctx.exist: | |||||
| raise SystemError("Skip because %s is not enabled" % device) | |||||
| with _akg.tvm.target.create(device): | |||||
| sch = schedule_elemwise(outs) | |||||
| return sch | |||||
| @@ -1,54 +0,0 @@ | |||||
| # Copyright 2019 Huawei Technologies Co., Ltd | |||||
| # | |||||
| # Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| # you may not use this file except in compliance with the License. | |||||
| # You may obtain a copy of the License at | |||||
| # | |||||
| # http://www.apache.org/licenses/LICENSE-2.0 | |||||
| # | |||||
| # Unless required by applicable law or agreed to in writing, software | |||||
| # distributed under the License is distributed on an "AS IS" BASIS, | |||||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| # See the License for the specific language governing permissions and | |||||
| # limitations under the License. | |||||
| """relu6""" | |||||
| import _akg.topi as topi | |||||
| import _akg.tvm as tvm | |||||
| from _akg.topi import tag | |||||
| @tvm.tag_scope(tag=tag.ELEMWISE) | |||||
| def topi_nn_relu6(x): | |||||
| """topi nn relu6.""" | |||||
| return tvm.compute(x.shape, lambda *i: tvm.min(tvm.max(x(*i), tvm.const(0, x.dtype)), tvm.const(6, x.dtype))) | |||||
| def ReLU6(x): | |||||
| """ | |||||
| Compute elementwise with function: min(max(x, 0), 6). | |||||
| Args: | |||||
| x (tvm.tensor.Tensor): Tensor of type float16, float32. | |||||
| Returns: | |||||
| tvm.tensor.Tensor, has same type and shape as input. | |||||
| """ | |||||
| return topi_nn_relu6(x) | |||||
| def gpu_schedule_ReLU6(outs): | |||||
| """ | |||||
| gpu schedule ReLU6. | |||||
| Args: | |||||
| outs (tvm.tensor.Tensor): outputs of compute. | |||||
| Returns: | |||||
| sch (schedule.Schedule): The created schedule. | |||||
| """ | |||||
| device = 'cuda' | |||||
| ctx = tvm.context(device, 0) | |||||
| if not ctx.exist: | |||||
| raise SystemError("Skip because %s is not enabled" % device) | |||||
| with tvm.target.create(device): | |||||
| sch = topi.cuda.schedule_elemwise(outs) | |||||
| return sch | |||||
| @@ -1,59 +0,0 @@ | |||||
| # Copyright 2019 Huawei Technologies Co., Ltd | |||||
| # | |||||
| # Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| # you may not use this file except in compliance with the License. | |||||
| # You may obtain a copy of the License at | |||||
| # | |||||
| # http://www.apache.org/licenses/LICENSE-2.0 | |||||
| # | |||||
| # Unless required by applicable law or agreed to in writing, software | |||||
| # distributed under the License is distributed on an "AS IS" BASIS, | |||||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| # See the License for the specific language governing permissions and | |||||
| # limitations under the License. | |||||
| """relu6 grad""" | |||||
| import _akg.topi as topi | |||||
| import _akg.tvm as tvm | |||||
| def ReLU6Grad(y_grad, x): | |||||
| """ | |||||
| Computes Gradients of Rectified Linear 6. | |||||
| Args: | |||||
| y_grad (tvm.tensor.Tensor): Tensor of type float16, float32, gradients backpropagated to the ReLU6 op. | |||||
| x (tvm.tensor.Tensor): Tensor of type float16/float32, inputs that where passed to the ReLU6 op, or its outputs. | |||||
| Returns: | |||||
| tvm.tensor.Tensor, has same type and shape as x. | |||||
| """ | |||||
| shape = x.shape | |||||
| dtype = x.dtype | |||||
| zero = tvm.const(0, dtype) | |||||
| six = tvm.const(6, dtype) | |||||
| res0 = tvm.compute(shape, lambda *i: tvm.if_then_else(x(*i) >= zero, x(*i), zero)) | |||||
| res6 = tvm.compute(shape, lambda *i: tvm.if_then_else(x(*i) >= six, zero, res0(*i))) | |||||
| res = tvm.compute(shape, lambda *i: tvm.if_then_else(res6(*i) == zero, zero, y_grad(*i))) | |||||
| return res | |||||
| def gpu_schedule_ReLU6Grad(outs): | |||||
| """ | |||||
| gpu schedule ReLU6Grad. | |||||
| Args: | |||||
| outs (tvm.tensor.Tensor): outputs of compute. | |||||
| Returns: | |||||
| sch (schedule.Schedule): The created schedule. | |||||
| """ | |||||
| device = 'cuda' | |||||
| ctx = tvm.context(device, 0) | |||||
| if not ctx.exist: | |||||
| raise SystemError("Skip because %s is not enabled" % device) | |||||
| with tvm.target.create(device): | |||||
| sch = topi.cuda.schedule_elemwise(outs) | |||||
| return sch | |||||
| @@ -1,50 +0,0 @@ | |||||
| # Copyright 2019 Huawei Technologies Co., Ltd | |||||
| # | |||||
| # Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| # you may not use this file except in compliance with the License. | |||||
| # You may obtain a copy of the License at | |||||
| # | |||||
| # http://www.apache.org/licenses/LICENSE-2.0 | |||||
| # | |||||
| # Unless required by applicable law or agreed to in writing, software | |||||
| # distributed under the License is distributed on an "AS IS" BASIS, | |||||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| # See the License for the specific language governing permissions and | |||||
| # limitations under the License. | |||||
| """squeeze""" | |||||
| import _akg.topi as topi | |||||
| import _akg.tvm as tvm | |||||
| def Squeeze(x, axis=None): | |||||
| """ | |||||
| Remove the dimensions which have shape size 1. | |||||
| Args: | |||||
| x (tvm.tensor.Tensor): Tensor, input whose shape is to be squeeze. | |||||
| axis (Union[list, tuple, int, None]): specify which size 1 dimension to be removed. | |||||
| Returns: | |||||
| tvm.tensor.Tensor, has the same type and element as x, but some size 1 dimensions are removed. | |||||
| """ | |||||
| return topi.squeeze(x, axis) | |||||
| def gpu_schedule_Squeeze(outs): | |||||
| """ | |||||
| gpu schedule Squeeze. | |||||
| Args: | |||||
| outs (tvm.tensor.Tensor): outputs of compute. | |||||
| Returns: | |||||
| sch (schedule.Schedule): The created schedule. | |||||
| """ | |||||
| device = 'cuda' | |||||
| ctx = tvm.context(device, 0) | |||||
| if not ctx.exist: | |||||
| raise SystemError("Skip because %s is not enabled" % device) | |||||
| with tvm.target.create(device): | |||||
| sch = topi.cuda.schedule_injective(outs) | |||||
| return sch | |||||
| @@ -1,44 +0,0 @@ | |||||
| # Copyright 2019 Huawei Technologies Co., Ltd | |||||
| # | |||||
| # Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| # you may not use this file except in compliance with the License. | |||||
| # You may obtain a copy of the License at | |||||
| # | |||||
| # http://www.apache.org/licenses/LICENSE-2.0 | |||||
| # | |||||
| # Unless required by applicable law or agreed to in writing, software | |||||
| # distributed under the License is distributed on an "AS IS" BASIS, | |||||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| # See the License for the specific language governing permissions and | |||||
| # limitations under the License. | |||||
| """squeeze grad""" | |||||
| import _akg.topi as topi | |||||
| def SqueezeGrad(y_grad, x_shape): | |||||
| """ | |||||
| Computes gradients for squeeze op. | |||||
| Args: | |||||
| y_grad (tvm.tensor.Tensor): the gradient needed to be propagation. | |||||
| x_shape (Union[list, tuple]): output Tensor shape. | |||||
| Returns: | |||||
| tvm.tensor.Tensor: output gradient. | |||||
| """ | |||||
| return topi.reshape(y_grad, x_shape) | |||||
| def gpu_schedule_SqueezeGrad(outs): | |||||
| """ | |||||
| gpu schedule SqueezeGrad. | |||||
| Args: | |||||
| outs (tvm.tensor.Tensor): outputs of compute. | |||||
| Returns: | |||||
| sch (schedule.Schedule): The created schedule. | |||||
| """ | |||||
| from .default_schedule import default_schedule | |||||
| return default_schedule(outs) | |||||
| @@ -1,40 +0,0 @@ | |||||
| # Copyright 2020 Huawei Technologies Co., Ltd | |||||
| # | |||||
| # Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| # you may not use this file except in compliance with the License. | |||||
| # You may obtain a copy of the License at | |||||
| # | |||||
| # http://www.apache.org/licenses/LICENSE-2.0 | |||||
| # | |||||
| # Unless required by applicable law or agreed to in writing, software | |||||
| # distributed under the License is distributed on an "AS IS" BASIS, | |||||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| # See the License for the specific language governing permissions and | |||||
| # limitations under the License. | |||||
| """sub""" | |||||
| import _akg.tvm | |||||
| from _akg.ops.math import sub | |||||
| from _akg.topi.generic import schedule_elemwise | |||||
| def Sub(x, y): | |||||
| """Sub.""" | |||||
| return sub.sub(x, y) | |||||
| def gpu_schedule_Sub(outs): | |||||
| """ | |||||
| GPU schedule for Sub. | |||||
| Args: | |||||
| outs (tvm.tensor.Tensor): outputs of compute. | |||||
| Returns: | |||||
| sch (schedule.Schedule): The created schedule. | |||||
| """ | |||||
| device = 'cuda' | |||||
| ctx = _akg.tvm.context(device, 0) | |||||
| if not ctx.exist: | |||||
| raise SystemError("Skip because %s is not enabled" % device) | |||||
| with _akg.tvm.target.create(device): | |||||
| sch = schedule_elemwise(outs) | |||||
| return sch | |||||
| @@ -1,39 +0,0 @@ | |||||
| # Copyright 2019 Huawei Technologies Co., Ltd | |||||
| # | |||||
| # Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| # you may not use this file except in compliance with the License. | |||||
| # You may obtain a copy of the License at | |||||
| # | |||||
| # http://www.apache.org/licenses/LICENSE-2.0 | |||||
| # | |||||
| # Unless required by applicable law or agreed to in writing, software | |||||
| # distributed under the License is distributed on an "AS IS" BASIS, | |||||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| # See the License for the specific language governing permissions and | |||||
| # limitations under the License. | |||||
| """tile""" | |||||
| import _akg.tvm | |||||
| from _akg.ops.array import tile | |||||
| from _akg.topi.generic import schedule_elemwise | |||||
| def Tile(x, multiples): | |||||
| """tile.""" | |||||
| return tile.tile(x, multiples) | |||||
| def gpu_schedule_Tile(outs): | |||||
| """ | |||||
| gpu schedule for tile. | |||||
| Args: | |||||
| outs (tvm.tensor.Tensor): outputs of compute. | |||||
| Returns: | |||||
| sch (schedule.Schedule): The created schedule. | |||||
| """ | |||||
| device = 'cuda' | |||||
| ctx = _akg.tvm.context(device, 0) | |||||
| if not ctx.exist: | |||||
| raise SystemError("Skip because %s is not enabled" % device) | |||||
| with _akg.tvm.target.create(device): | |||||
| s = schedule_elemwise(outs) | |||||
| return s | |||||
| @@ -1,104 +0,0 @@ | |||||
| # Copyright 2019 Huawei Technologies Co., Ltd | |||||
| # | |||||
| # Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| # you may not use this file except in compliance with the License. | |||||
| # You may obtain a copy of the License at | |||||
| # | |||||
| # http://www.apache.org/licenses/LICENSE-2.0 | |||||
| # | |||||
| # Unless required by applicable law or agreed to in writing, software | |||||
| # distributed under the License is distributed on an "AS IS" BASIS, | |||||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| # See the License for the specific language governing permissions and | |||||
| # limitations under the License. | |||||
| """message""" | |||||
| import importlib.util | |||||
| import json | |||||
| import json.decoder as jd | |||||
| import logging | |||||
| import traceback | |||||
| import os.path | |||||
| from pathlib import Path | |||||
| import _akg.tvm | |||||
| from _akg.utils import validation_check as vc_util | |||||
| from _akg.utils.dsl_create import TensorUtils | |||||
| from . import gpu | |||||
| from . import op_build | |||||
| @vc_util.check_input_type(str) | |||||
| def compilewithjson(json_str): | |||||
| """compile with json.""" | |||||
| try: | |||||
| kernel_info = json.loads(json_str) | |||||
| except jd.JSONDecodeError: | |||||
| logging.error(traceback.format_exc()) | |||||
| return False | |||||
| op_name = kernel_info['name'] | |||||
| op_func = None | |||||
| processor = 'aicore' | |||||
| if 'process' in kernel_info: | |||||
| processor = kernel_info['process'] | |||||
| # get custom ops implementation first. | |||||
| if 'impl_path' in kernel_info and kernel_info['impl_path'] is not None: | |||||
| impl_path = os.path.realpath(kernel_info['impl_path']) | |||||
| if os.path.isfile(impl_path): | |||||
| custom_mod_name = Path(impl_path).resolve().stem | |||||
| mod_spec = importlib.util.spec_from_file_location( | |||||
| custom_mod_name, impl_path) | |||||
| custom_mod = importlib.util.module_from_spec(mod_spec) | |||||
| mod_spec.loader.exec_module(custom_mod) | |||||
| op_func = getattr(custom_mod, op_name, None) | |||||
| # get built-in ops. | |||||
| if op_func is None: | |||||
| if processor == 'cuda': | |||||
| op_func = getattr(gpu, op_name, None) | |||||
| if op_func is None: | |||||
| logging.error( | |||||
| "this op not supported, please check op name %s", str(op_name)) | |||||
| return False | |||||
| args = {} | |||||
| tsr = [] | |||||
| for input_desc in kernel_info['input_desc']: | |||||
| if len(input_desc) == 1: | |||||
| tensor_shape = input_desc[0]['shape'] | |||||
| tensor_shape = (1,) if not tensor_shape else tensor_shape | |||||
| vc_util.shape_dtype_max_size_check(tensor_shape) | |||||
| args[input_desc[0]['name']] = _akg.tvm.placeholder( | |||||
| shape=tensor_shape, name=input_desc[0]['tensor_name'], dtype=input_desc[0]['data_type']) | |||||
| tsr.append(args[input_desc[0]['name']]) | |||||
| else: | |||||
| tmp_input = [] | |||||
| for tmp_desc in input_desc: | |||||
| tensor_shape = tmp_desc['shape'] | |||||
| tensor_shape = (1,) if not tensor_shape else tensor_shape | |||||
| vc_util.shape_dtype_max_size_check(tensor_shape) | |||||
| tmp_input.append(_akg.tvm.placeholder( | |||||
| shape=tensor_shape, name=tmp_desc['tensor_name'], dtype=tmp_desc['data_type'])) | |||||
| args[input_desc[0]['name']] = tmp_input | |||||
| tsr = tsr + tmp_input | |||||
| if kernel_info['attr']: | |||||
| for ext_arg in kernel_info['attr']: | |||||
| args[ext_arg['name']] = ext_arg['value'] | |||||
| output = op_func(**args) | |||||
| if isinstance(output, (list, tuple)): | |||||
| from inspect import isfunction | |||||
| tmp_outputs = [] | |||||
| for elem in output: | |||||
| if not isfunction(elem) or isinstance(elem, dict): | |||||
| tmp_outputs.append(elem) | |||||
| output = tmp_outputs | |||||
| else: | |||||
| output = [output] | |||||
| tsr = tsr + [i for i in output if TensorUtils.is_output_value(i)] | |||||
| return op_build([op_name], output, tsr, processor, kernel_info['op']) | |||||
| @@ -1,69 +0,0 @@ | |||||
| # Copyright 2019 Huawei Technologies Co., Ltd | |||||
| # | |||||
| # Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| # you may not use this file except in compliance with the License. | |||||
| # You may obtain a copy of the License at | |||||
| # | |||||
| # http://www.apache.org/licenses/LICENSE-2.0 | |||||
| # | |||||
| # Unless required by applicable law or agreed to in writing, software | |||||
| # distributed under the License is distributed on an "AS IS" BASIS, | |||||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| # See the License for the specific language governing permissions and | |||||
| # limitations under the License. | |||||
| """op_build""" | |||||
| import os | |||||
| import fcntl | |||||
| import types | |||||
| import typing | |||||
| import logging | |||||
| import traceback | |||||
| import _akg.tvm | |||||
| import _akg | |||||
| from _akg import save_gpu_param as gpu_utils | |||||
| from _akg.utils import validation_check as vc_util | |||||
| @vc_util.check_input_type(list, (list, tuple), (list, tuple), str, str) | |||||
| def op_build(opnames, computes, args, device, kernel_name): | |||||
| """op_build""" | |||||
| kernel_meta_path = "./cuda_meta_" + str(os.getpid()) + "/" | |||||
| if device == "cuda": | |||||
| cuda_path = os.path.realpath(kernel_meta_path) | |||||
| if not os.path.isdir(cuda_path): | |||||
| os.makedirs(cuda_path) | |||||
| if not opnames: | |||||
| logging.error("no opname given.") | |||||
| return None | |||||
| schedule_name = 'gpu_schedule_' + opnames[0] | |||||
| schedule_func = getattr(_akg.gpu, schedule_name) | |||||
| if not isinstance(schedule_func, (types.FunctionType, typing.Callable)): | |||||
| logging.error("no schedule func found %s", str(schedule_name)) | |||||
| return None | |||||
| ptx_file = os.path.realpath(kernel_meta_path + kernel_name + ".ptx") | |||||
| if os.path.exists(ptx_file): | |||||
| os.chmod(ptx_file, 0o600) | |||||
| try: | |||||
| with open(ptx_file, 'at') as file: | |||||
| fcntl.flock(file.fileno(), fcntl.LOCK_EX) | |||||
| file.seek(0, 2) | |||||
| if file.tell() == 0: | |||||
| s = schedule_func(computes) | |||||
| foo = _akg.tvm.build(s, args, device, name=kernel_name) | |||||
| ptx_code = foo.imported_modules[0].get_source("ptx") | |||||
| file.write(ptx_code) | |||||
| json_file = os.path.realpath( | |||||
| kernel_meta_path + kernel_name + ".json") | |||||
| kernel_info = (ptx_code, json_file, kernel_name) | |||||
| gpu_utils.save_gpu_params(s, args, kernel_info) | |||||
| os.chmod(ptx_file, 0o400) | |||||
| except IOError: | |||||
| logging.error(traceback.format_exc()) | |||||
| return None | |||||
| return True | |||||
| logging.error("Not support device %s.", device) | |||||
| return None | |||||
| @@ -1,36 +0,0 @@ | |||||
| # Copyright 2019 Huawei Technologies Co., Ltd | |||||
| # | |||||
| # Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| # you may not use this file except in compliance with the License. | |||||
| # You may obtain a copy of the License at | |||||
| # | |||||
| # http://www.apache.org/licenses/LICENSE-2.0 | |||||
| # | |||||
| # Unless required by applicable law or agreed to in writing, software | |||||
| # distributed under the License is distributed on an "AS IS" BASIS, | |||||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| # See the License for the specific language governing permissions and | |||||
| # limitations under the License. | |||||
| """operator dsl function: tile""" | |||||
| import _akg.tvm | |||||
| import _akg.topi | |||||
| from _akg.utils import validation_check as vc_util | |||||
| @vc_util.check_input_type(_akg.tvm.tensor.Tensor, (list, tuple)) | |||||
| def tile(data, multiples): | |||||
| """ | |||||
| Repeats the data in the specified dimensions according to the multiples. | |||||
| Args: | |||||
| data (tvm.tensor.Tensor): Tensor. | |||||
| multiples (Union[list, tuple]): Elements must be int. The number of repetitions. | |||||
| Returns: | |||||
| tvm.tensor.Tensor, has the same dtype as data. | |||||
| """ | |||||
| vc_util.check_shape(data.shape) | |||||
| vc_util.check_int_list(multiples, "multiples") | |||||
| output = _akg.topi.tile(data, multiples) | |||||
| return output | |||||
| @@ -1,36 +0,0 @@ | |||||
| # Copyright 2019 Huawei Technologies Co., Ltd | |||||
| # | |||||
| # Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| # you may not use this file except in compliance with the License. | |||||
| # You may obtain a copy of the License at | |||||
| # | |||||
| # http://www.apache.org/licenses/LICENSE-2.0 | |||||
| # | |||||
| # Unless required by applicable law or agreed to in writing, software | |||||
| # distributed under the License is distributed on an "AS IS" BASIS, | |||||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| # See the License for the specific language governing permissions and | |||||
| # limitations under the License. | |||||
| """operator dsl function: cast""" | |||||
| import _akg.tvm | |||||
| import _akg.topi | |||||
| from _akg.utils import validation_check as vc_util | |||||
| @vc_util.check_input_type(_akg.tvm.tensor.Tensor, str) | |||||
| def cast(data, dst_type): | |||||
| """ | |||||
| cast data to target type. | |||||
| Args: | |||||
| data (tvm.tensor.Tensor): Tensor to be casted. | |||||
| dst_type (str): target cast type. | |||||
| Returns: | |||||
| tvm.tensor.Tensor, type is dst_type. | |||||
| """ | |||||
| vc_util.check_shape(data.shape) | |||||
| out = _akg.topi.cast(data, dst_type) | |||||
| return out | |||||
| @@ -1,54 +0,0 @@ | |||||
| # Copyright 2019 Huawei Technologies Co., Ltd | |||||
| # | |||||
| # Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| # you may not use this file except in compliance with the License. | |||||
| # You may obtain a copy of the License at | |||||
| # | |||||
| # http://www.apache.org/licenses/LICENSE-2.0 | |||||
| # | |||||
| # Unless required by applicable law or agreed to in writing, software | |||||
| # distributed under the License is distributed on an "AS IS" BASIS, | |||||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| # See the License for the specific language governing permissions and | |||||
| # limitations under the License. | |||||
| """operator dsl function: equal""" | |||||
| import _akg.tvm | |||||
| import _akg.topi | |||||
| from _akg.utils.dsl_create import produce_shapes | |||||
| from _akg.utils import validation_check as vc_util | |||||
| @vc_util.check_input_type(_akg.tvm.tensor.Tensor, _akg.tvm.tensor.Tensor) | |||||
| def equal(input1, input2): | |||||
| """ | |||||
| check whether input1 equals to input2. | |||||
| Args: | |||||
| input1 (tvm.tensor.Tensor): Tensor. | |||||
| input2 (tvm.tensor.Tensor): Tensor. | |||||
| Returns: | |||||
| tvm.tensor.Tensor. If input1 equal to input2 return True, else return False. | |||||
| """ | |||||
| shape1 = [x.value for x in input1.shape] | |||||
| shape2 = [x.value for x in input2.shape] | |||||
| vc_util.check_shape(shape1) | |||||
| vc_util.check_shape(shape2) | |||||
| shape1, shape2, shape = produce_shapes(shape1, shape2) | |||||
| vc_util.elemwise_dtype_check(input1.dtype, input2.dtype) | |||||
| dtype = input1.dtype | |||||
| # get equal compute | |||||
| t_value = _akg.tvm.compute(shape, lambda *indice: _akg.tvm.const(1, dtype), "T") | |||||
| f_value = _akg.tvm.compute(shape, lambda *indice: _akg.tvm.const(0, dtype), "F") | |||||
| input1_bro = _akg.topi.broadcast_to(input1, shape) | |||||
| input2_bro = _akg.topi.broadcast_to(input2, shape) | |||||
| c_out = _akg.tvm.compute(shape, lambda *indice: _akg.tvm.expr.Select(input1_bro[indice] == input2_bro[indice], | |||||
| t_value[indice], f_value[indice]), name="C") | |||||
| res = _akg.tvm.compute(shape, lambda *indice: c_out(*indice).astype("bool"), name="res") | |||||
| return res | |||||
| @@ -1,54 +0,0 @@ | |||||
| # Copyright 2020 Huawei Technologies Co., Ltd | |||||
| # | |||||
| # Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| # you may not use this file except in compliance with the License. | |||||
| # You may obtain a copy of the License at | |||||
| # | |||||
| # http://www.apache.org/licenses/LICENSE-2.0 | |||||
| # | |||||
| # Unless required by applicable law or agreed to in writing, software | |||||
| # distributed under the License is distributed on an "AS IS" BASIS, | |||||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| # See the License for the specific language governing permissions and | |||||
| # limitations under the License. | |||||
| """operator dsl function: greaterequal""" | |||||
| import _akg.tvm | |||||
| import _akg.topi | |||||
| from _akg.utils.dsl_create import produce_shapes | |||||
| from _akg.utils import validation_check as vc_util | |||||
| @vc_util.check_input_type(_akg.tvm.tensor.Tensor, _akg.tvm.tensor.Tensor) | |||||
| def greater_equal(input1, input2): | |||||
| """ | |||||
| Check whether input1 greaterquals to input2. | |||||
| Args: | |||||
| input1 (tvm.tensor.Tensor): Tensor. | |||||
| input2 (tvm.tensor.Tensor): Tensor. | |||||
| Returns: | |||||
| tvm.tensor.Tensor. If input1 greaterquals to input2 return True, else return False. | |||||
| """ | |||||
| shape1 = [x.value for x in input1.shape] | |||||
| shape2 = [x.value for x in input2.shape] | |||||
| vc_util.check_shape(shape1) | |||||
| vc_util.check_shape(shape2) | |||||
| shape1, shape2, shape = produce_shapes(shape1, shape2) | |||||
| vc_util.elemwise_dtype_check(input1.dtype, input2.dtype) | |||||
| dtype = input1.dtype | |||||
| # get greaterquals compute | |||||
| t_value = _akg.tvm.compute(shape, lambda *indice: _akg.tvm.const(1, dtype), "T") | |||||
| f_value = _akg.tvm.compute(shape, lambda *indice: _akg.tvm.const(0, dtype), "F") | |||||
| input1_bro = _akg.topi.broadcast_to(input1, shape) | |||||
| input2_bro = _akg.topi.broadcast_to(input2, shape) | |||||
| c_out = _akg.tvm.compute(shape, lambda *indice: _akg.tvm.expr.Select(input1_bro[indice] >= input2_bro[indice], | |||||
| t_value[indice], f_value[indice]), name="C") | |||||
| res = _akg.tvm.compute(shape, lambda *indice: c_out(*indice).astype("bool"), name="res") | |||||
| return res | |||||
| @@ -1,54 +0,0 @@ | |||||
| # Copyright 2020 Huawei Technologies Co., Ltd | |||||
| # | |||||
| # Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| # you may not use this file except in compliance with the License. | |||||
| # You may obtain a copy of the License at | |||||
| # | |||||
| # http://www.apache.org/licenses/LICENSE-2.0 | |||||
| # | |||||
| # Unless required by applicable law or agreed to in writing, software | |||||
| # distributed under the License is distributed on an "AS IS" BASIS, | |||||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| # See the License for the specific language governing permissions and | |||||
| # limitations under the License. | |||||
| """operator dsl function: lessequal""" | |||||
| import _akg.tvm | |||||
| import _akg.topi | |||||
| from _akg.utils.dsl_create import produce_shapes | |||||
| from _akg.utils import validation_check as vc_util | |||||
| @vc_util.check_input_type(_akg.tvm.tensor.Tensor, _akg.tvm.tensor.Tensor) | |||||
| def less_equal(input1, input2): | |||||
| """ | |||||
| Check whether input1 lessequals to input2. | |||||
| Args: | |||||
| input1 (tvm.tensor.Tensor): Tensor. | |||||
| input2 (tvm.tensor.Tensor): Tensor. | |||||
| Returns: | |||||
| tvm.tensor.Tensor. If input1 lessequal to input2 return True, else return False. | |||||
| """ | |||||
| shape1 = [x.value for x in input1.shape] | |||||
| shape2 = [x.value for x in input2.shape] | |||||
| vc_util.check_shape(shape1) | |||||
| vc_util.check_shape(shape2) | |||||
| shape1, shape2, shape = produce_shapes(shape1, shape2) | |||||
| vc_util.elemwise_dtype_check(input1.dtype, input2.dtype) | |||||
| dtype = input1.dtype | |||||
| # get lessequal compute | |||||
| t_value = _akg.tvm.compute(shape, lambda *indice: _akg.tvm.const(1, dtype), "T") | |||||
| f_value = _akg.tvm.compute(shape, lambda *indice: _akg.tvm.const(0, dtype), "F") | |||||
| input1_bro = _akg.topi.broadcast_to(input1, shape) | |||||
| input2_bro = _akg.topi.broadcast_to(input2, shape) | |||||
| c_out = _akg.tvm.compute(shape, lambda *indice: _akg.tvm.expr.Select(input1_bro[indice] <= input2_bro[indice], | |||||
| t_value[indice], f_value[indice]), name="C") | |||||
| res = _akg.tvm.compute(shape, lambda *indice: c_out(*indice).astype("bool"), name="res") | |||||
| return res | |||||
| @@ -1,41 +0,0 @@ | |||||
| # Copyright 2020 Huawei Technologies Co., Ltd | |||||
| # | |||||
| # Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| # you may not use this file except in compliance with the License. | |||||
| # You may obtain a copy of the License at | |||||
| # | |||||
| # http://www.apache.org/licenses/LICENSE-2.0 | |||||
| # | |||||
| # Unless required by applicable law or agreed to in writing, software | |||||
| # distributed under the License is distributed on an "AS IS" BASIS, | |||||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| # See the License for the specific language governing permissions and | |||||
| # limitations under the License. | |||||
| """operator dsl function: logical_and""" | |||||
| import _akg.tvm | |||||
| import _akg.topi | |||||
| from _akg.utils import validation_check as vc_util | |||||
| @vc_util.check_input_type(_akg.tvm.tensor.Tensor, _akg.tvm.tensor.Tensor) | |||||
| def logical_and(input1, input2): | |||||
| """ | |||||
| Compute logical_and of input1 and input2. | |||||
| Args: | |||||
| input1 (tvm.tensor.Tensor): Tensor. | |||||
| input2 (tvm.tensor.Tensor): Tensor. | |||||
| Returns: | |||||
| tvm.tensor.Tensor. LogicalAnd of input1 and input2. | |||||
| """ | |||||
| vc_util.elemwise_dtype_check(input1.dtype, input2.dtype) | |||||
| shape1 = [x.value for x in input1.shape] | |||||
| shape2 = [x.value for x in input2.shape] | |||||
| vc_util.check_shape(shape1) | |||||
| vc_util.check_shape(shape2) | |||||
| res = _akg.topi.logical_and(input1, input2) | |||||
| return res | |||||
| @@ -1,32 +0,0 @@ | |||||
| # Copyright 2019 Huawei Technologies Co., Ltd | |||||
| # | |||||
| # Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| # you may not use this file except in compliance with the License. | |||||
| # You may obtain a copy of the License at | |||||
| # | |||||
| # http://www.apache.org/licenses/LICENSE-2.0 | |||||
| # | |||||
| # Unless required by applicable law or agreed to in writing, software | |||||
| # distributed under the License is distributed on an "AS IS" BASIS, | |||||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| # See the License for the specific language governing permissions and | |||||
| # limitations under the License. | |||||
| """operator dsl function: logical_not""" | |||||
| import _akg.tvm | |||||
| import _akg.topi | |||||
| from _akg.utils import validation_check as vc_util | |||||
| @vc_util.check_input_type(_akg.tvm.tensor.Tensor) | |||||
| def logical_not(input1): | |||||
| """ | |||||
| Compute logical_not of input1. | |||||
| Args: | |||||
| input1 (tvm.tensor.Tensor): Tensor. | |||||
| Returns: | |||||
| tvm.tensor.Tensor. | |||||
| """ | |||||
| res = _akg.topi.logical_not(input1) | |||||
| return res | |||||
| @@ -1,41 +0,0 @@ | |||||
| # Copyright 2020 Huawei Technologies Co., Ltd | |||||
| # | |||||
| # Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| # you may not use this file except in compliance with the License. | |||||
| # You may obtain a copy of the License at | |||||
| # | |||||
| # http://www.apache.org/licenses/LICENSE-2.0 | |||||
| # | |||||
| # Unless required by applicable law or agreed to in writing, software | |||||
| # distributed under the License is distributed on an "AS IS" BASIS, | |||||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| # See the License for the specific language governing permissions and | |||||
| # limitations under the License. | |||||
| """operator dsl function: logical_or""" | |||||
| import _akg.tvm | |||||
| import _akg.topi | |||||
| from _akg.utils import validation_check as vc_util | |||||
| @vc_util.check_input_type(_akg.tvm.tensor.Tensor, _akg.tvm.tensor.Tensor) | |||||
| def logical_or(input1, input2): | |||||
| """ | |||||
| Compute logical_or of input1 and input2. | |||||
| Args: | |||||
| input1 (tvm.tensor.Tensor): Tensor. | |||||
| input2 (tvm.tensor.Tensor): Tensor. | |||||
| Returns: | |||||
| tvm.tensor.Tensor. LogicalOr of input1 and input2. | |||||
| """ | |||||
| vc_util.elemwise_dtype_check(input1.dtype, input2.dtype) | |||||
| shape1 = [x.value for x in input1.shape] | |||||
| shape2 = [x.value for x in input2.shape] | |||||
| vc_util.check_shape(shape1) | |||||
| vc_util.check_shape(shape2) | |||||
| res = _akg.topi.logical_or(input1, input2) | |||||
| return res | |||||
| @@ -1,47 +0,0 @@ | |||||
| # Copyright 2019 Huawei Technologies Co., Ltd | |||||
| # | |||||
| # Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| # you may not use this file except in compliance with the License. | |||||
| # You may obtain a copy of the License at | |||||
| # | |||||
| # http://www.apache.org/licenses/LICENSE-2.0 | |||||
| # | |||||
| # Unless required by applicable law or agreed to in writing, software | |||||
| # distributed under the License is distributed on an "AS IS" BASIS, | |||||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| # See the License for the specific language governing permissions and | |||||
| # limitations under the License. | |||||
| """operator dsl function: mean""" | |||||
| import _akg.topi | |||||
| import _akg.tvm | |||||
| from _akg.utils import format_transform as ft_util | |||||
| from _akg.utils import validation_check as vc_util | |||||
| from _akg.ops.math import sum_value | |||||
| @vc_util.check_input_type(_akg.tvm.tensor.Tensor, (list, tuple, int, type(None)), (bool, type(None))) | |||||
| def mean(data, axis=None, keepdims=False): | |||||
| """ | |||||
| Computes the mean of the values of a Tensor over the whole dataset. | |||||
| Args: | |||||
| data (tvm.tensor.Tensor): Tensor. | |||||
| axis (Union[list, tuple, int, None]): If the tuple is empty, the axis equal to None. | |||||
| keepdims (bool): If keepdims equal to True, the result shape length is same to input shape length. | |||||
| Returns: | |||||
| tvm.tensor.Tensor, has the same type as data. If keepdims equal to True, all reduced dimensions are | |||||
| retained with length 1. else these reduced axis will be eliminate. | |||||
| """ | |||||
| shape = [x.value for x in data.shape] | |||||
| vc_util.reduce_axis_check(shape, axis) | |||||
| axis = ft_util.refine_reduce_axis(data, axis) | |||||
| count = 1 | |||||
| for i in axis: | |||||
| count *= shape[i] | |||||
| output, _ = sum_value.sum_value(data, axis, keepdims) | |||||
| res = _akg.topi.divide(output, count) | |||||
| return res | |||||
| @@ -1,43 +0,0 @@ | |||||
| # Copyright 2019 Huawei Technologies Co., Ltd | |||||
| # | |||||
| # Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| # you may not use this file except in compliance with the License. | |||||
| # You may obtain a copy of the License at | |||||
| # | |||||
| # http://www.apache.org/licenses/LICENSE-2.0 | |||||
| # | |||||
| # Unless required by applicable law or agreed to in writing, software | |||||
| # distributed under the License is distributed on an "AS IS" BASIS, | |||||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| # See the License for the specific language governing permissions and | |||||
| # limitations under the License. | |||||
| """operator dsl function: mul""" | |||||
| import _akg.topi | |||||
| from _akg.utils import validation_check as vc_util | |||||
| @vc_util.check_input_type(_akg.tvm.tensor.Tensor, _akg.tvm.tensor.Tensor) | |||||
| def mul(l_input, r_input): | |||||
| """ | |||||
| Calculate x * y element-wise. | |||||
| Note: | |||||
| mul supports broadcasting. | |||||
| Args: | |||||
| l_input (tvm.tensor.Tensor): Tensor. | |||||
| r_input (tvm.tensor.Tensor): Tensor. | |||||
| Returns: | |||||
| tvm.tensor.Tensor, has the same type as l_input and r_input. | |||||
| """ | |||||
| shape1 = [x.value for x in l_input.shape] | |||||
| shape2 = [x.value for x in r_input.shape] | |||||
| vc_util.check_shape(shape1) | |||||
| vc_util.check_shape(shape2) | |||||
| vc_util.auto_broadcast_check(shape1, shape2) | |||||
| vc_util.elemwise_dtype_check(l_input.dtype, r_input.dtype) | |||||
| output = _akg.topi.multiply(l_input, r_input) | |||||
| return output | |||||
| @@ -1,54 +0,0 @@ | |||||
| # Copyright 2020 Huawei Technologies Co., Ltd | |||||
| # | |||||
| # Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| # you may not use this file except in compliance with the License. | |||||
| # You may obtain a copy of the License at | |||||
| # | |||||
| # http://www.apache.org/licenses/LICENSE-2.0 | |||||
| # | |||||
| # Unless required by applicable law or agreed to in writing, software | |||||
| # distributed under the License is distributed on an "AS IS" BASIS, | |||||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| # See the License for the specific language governing permissions and | |||||
| # limitations under the License. | |||||
| """operator dsl function: notequal""" | |||||
| import _akg.tvm | |||||
| import _akg.topi | |||||
| from _akg.utils.dsl_create import produce_shapes | |||||
| from _akg.utils import validation_check as vc_util | |||||
| @vc_util.check_input_type(_akg.tvm.tensor.Tensor, _akg.tvm.tensor.Tensor) | |||||
| def notequal(input1, input2): | |||||
| """ | |||||
| check whether input1 notequals to input2. | |||||
| Args: | |||||
| input1 (tvm.tensor.Tensor): Tensor. | |||||
| input2 (tvm.tensor.Tensor): Tensor. | |||||
| Returns: | |||||
| tvm.tensor.Tensor. If input1 notequal to input2 return True, else return False. | |||||
| """ | |||||
| shape1 = [x.value for x in input1.shape] | |||||
| shape2 = [x.value for x in input2.shape] | |||||
| vc_util.check_shape(shape1) | |||||
| vc_util.check_shape(shape2) | |||||
| shape1, shape2, shape = produce_shapes(shape1, shape2) | |||||
| vc_util.elemwise_dtype_check(input1.dtype, input2.dtype) | |||||
| dtype = input1.dtype | |||||
| # get notequal compute | |||||
| t_value = _akg.tvm.compute(shape, lambda *indice: _akg.tvm.const(1, dtype), "T") | |||||
| f_value = _akg.tvm.compute(shape, lambda *indice: _akg.tvm.const(0, dtype), "F") | |||||
| input1_bro = _akg.topi.broadcast_to(input1, shape) | |||||
| input2_bro = _akg.topi.broadcast_to(input2, shape) | |||||
| c_out = _akg.tvm.compute(shape, lambda *indice: _akg.tvm.expr.Select(input1_bro[indice] != input2_bro[indice], | |||||
| t_value[indice], f_value[indice]), name="C") | |||||
| res = _akg.tvm.compute(shape, lambda *indice: c_out(*indice).astype("bool"), name="res") | |||||
| return res | |||||
| @@ -1,40 +0,0 @@ | |||||
| # Copyright 2019 Huawei Technologies Co., Ltd | |||||
| # | |||||
| # Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| # you may not use this file except in compliance with the License. | |||||
| # You may obtain a copy of the License at | |||||
| # | |||||
| # http://www.apache.org/licenses/LICENSE-2.0 | |||||
| # | |||||
| # Unless required by applicable law or agreed to in writing, software | |||||
| # distributed under the License is distributed on an "AS IS" BASIS, | |||||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| # See the License for the specific language governing permissions and | |||||
| # limitations under the License. | |||||
| """operator dsl function: sub""" | |||||
| import _akg.topi | |||||
| import _akg.tvm | |||||
| from _akg.utils import validation_check as vc_util | |||||
| @vc_util.check_input_type(_akg.tvm.tensor.Tensor, _akg.tvm.tensor.Tensor) | |||||
| def sub(data1, data2): | |||||
| """ | |||||
| Computes data1 - data2 elementwise, broadcast is supported. | |||||
| Args: | |||||
| data1 (tvm.tensor.Tensor): Tensor. | |||||
| data2 (tvm.tensor.Tensor): Tensor of same type as data1, if shape(data2) != shape(data1), broadcast will happen. | |||||
| Returns: | |||||
| tvm.tensor.Tensor, subtracted result, with same type as input tensors and broadcasted shape of data1 and data2. | |||||
| """ | |||||
| vc_util.elemwise_dtype_check(data1.dtype, data2.dtype) | |||||
| vc_util.check_shape(data1.shape) | |||||
| vc_util.check_shape(data2.shape) | |||||
| vc_util.auto_broadcast_check(data1.shape, data2.shape) | |||||
| res = _akg.topi.subtract(data1, data2) | |||||
| return res | |||||
| @@ -1,45 +0,0 @@ | |||||
| # Copyright 2019 Huawei Technologies Co., Ltd | |||||
| # | |||||
| # Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| # you may not use this file except in compliance with the License. | |||||
| # You may obtain a copy of the License at | |||||
| # | |||||
| # http://www.apache.org/licenses/LICENSE-2.0 | |||||
| # | |||||
| # Unless required by applicable law or agreed to in writing, software | |||||
| # distributed under the License is distributed on an "AS IS" BASIS, | |||||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| # See the License for the specific language governing permissions and | |||||
| # limitations under the License. | |||||
| """operator dsl function: sum""" | |||||
| import _akg.topi | |||||
| import _akg.tvm | |||||
| from _akg.utils import format_transform as ft_util | |||||
| from _akg.utils import validation_check as vc_util | |||||
| @vc_util.check_input_type(_akg.tvm.tensor.Tensor, (list, tuple, int, type(None)), (bool, type(None))) | |||||
| def sum_value(inputs, axis=None, keepdims=False): | |||||
| """ | |||||
| Compute the sum of elements across dimensions of a tensor. | |||||
| Args: | |||||
| inputs (tvm.tensor.Tensor): Tensor. | |||||
| axis (Union[list, tuple, int, None]): If the list or tuple is empty, the axis equal to None. | |||||
| keepdims (bool): If keepdims equal to True, the result shape length is same to input shape length. | |||||
| Returns: | |||||
| tvm.tensor.Tensor, has same type as input. If keepdims is True, all reduced dimensions are retained | |||||
| with length 1, else these reduced axis will be eliminate. | |||||
| """ | |||||
| axis = ft_util.refine_reduce_axis(inputs, axis) | |||||
| vc_util.check_shape(inputs.shape) | |||||
| if not axis: | |||||
| output = _akg.topi.identity(inputs) | |||||
| else: | |||||
| output = _akg.topi.sum(inputs, axis=axis, keepdims=keepdims) | |||||
| return output | |||||
| @@ -1,87 +0,0 @@ | |||||
| # Copyright 2019 Huawei Technologies Co., Ltd | |||||
| # | |||||
| # Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| # you may not use this file except in compliance with the License. | |||||
| # You may obtain a copy of the License at | |||||
| # | |||||
| # http://www.apache.org/licenses/LICENSE-2.0 | |||||
| # | |||||
| # Unless required by applicable law or agreed to in writing, software | |||||
| # distributed under the License is distributed on an "AS IS" BASIS, | |||||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| # See the License for the specific language governing permissions and | |||||
| # limitations under the License. | |||||
| """save gpu param""" | |||||
| import os | |||||
| import hashlib | |||||
| import _akg.tvm | |||||
| from _akg.tvm import schedule | |||||
| from _akg.utils import validation_check as vc_util | |||||
| def get_dim(dim, axis=True): | |||||
| """get dim info""" | |||||
| dims_str = { | |||||
| "grid_dim0": "// attr [iter_var(blockIdx.x, , blockIdx.x)] thread_extent = ", | |||||
| "grid_dim1": "// attr [iter_var(blockIdx.y, , blockIdx.y)] thread_extent = ", | |||||
| "grid_dim2": "// attr [iter_var(blockIdx.z, , blockIdx.z)] thread_extent = ", | |||||
| "block_dim0": "// attr [iter_var(threadIdx.x, , threadIdx.x)] thread_extent = ", | |||||
| "block_dim1": "// attr [iter_var(threadIdx.y, , threadIdx.y)] thread_extent = ", | |||||
| "block_dim2": "// attr [iter_var(threadIdx.z, , threadIdx.z)] thread_extent = " | |||||
| } | |||||
| dim_to_axis = { | |||||
| "grid_dim0": '"blockIdx.x" : ', | |||||
| "grid_dim1": '"blockIdx.y" : ', | |||||
| "grid_dim2": '"blockIdx.z" : ', | |||||
| "block_dim0": '"threadIdx.x" : ', | |||||
| "block_dim1": '"threadIdx.y" : ', | |||||
| "block_dim2": '"threadIdx.z" : ' | |||||
| } | |||||
| if axis: | |||||
| return dim_to_axis.get(dim) | |||||
| return dims_str.get(dim) | |||||
| def parse_params(file, dim, ir): | |||||
| """parse parameters""" | |||||
| dim_str = get_dim(dim, axis=False) | |||||
| pos = ir.find(dim_str) | |||||
| if pos != -1: | |||||
| index = pos + len(dim_str) | |||||
| param_temp = get_dim(dim) | |||||
| while ir[index].isdigit(): | |||||
| param_temp += ir[index] | |||||
| index += 1 | |||||
| file.write(param_temp + ",\n") | |||||
| else: | |||||
| param_temp = get_dim(dim) + '1' | |||||
| file.write(param_temp + ",\n") | |||||
| @vc_util.check_input_type(schedule.Schedule, (list, tuple), tuple) | |||||
| def save_gpu_params(s, args, kernel_info): | |||||
| """save gpu parameters""" | |||||
| ptx_code = kernel_info[0] | |||||
| file_name = kernel_info[1] | |||||
| kernel_name = kernel_info[2] | |||||
| ir = str(_akg.tvm.lower(s, args, simple_mode=True)) | |||||
| file_path = os.path.realpath(file_name) | |||||
| if os.path.exists(file_path): | |||||
| os.remove(file_path) | |||||
| sha256 = hashlib.sha256() | |||||
| sha256.update(ptx_code.encode("utf-8")) | |||||
| hash_str = sha256.hexdigest() | |||||
| with os.fdopen(os.open(file_path, os.O_WRONLY | os.O_CREAT, 0o400), 'w') as fo: | |||||
| fo.write("{\n") | |||||
| fo.write('"kernelName" : ' + '"' + kernel_name + "_kernel0" + '",\n') | |||||
| parse_params(fo, "grid_dim0", ir) | |||||
| parse_params(fo, "grid_dim1", ir) | |||||
| parse_params(fo, "grid_dim2", ir) | |||||
| parse_params(fo, "block_dim0", ir) | |||||
| parse_params(fo, "block_dim1", ir) | |||||
| parse_params(fo, "block_dim2", ir) | |||||
| fo.write('"sha256" : ' + '"' + hash_str + '"\n') | |||||
| fo.write("}\n") | |||||
| @@ -1,122 +0,0 @@ | |||||
| # Copyright 2019 Huawei Technologies Co., Ltd | |||||
| # | |||||
| # Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| # you may not use this file except in compliance with the License. | |||||
| # You may obtain a copy of the License at | |||||
| # | |||||
| # http://www.apache.org/licenses/LICENSE-2.0 | |||||
| # | |||||
| # Unless required by applicable law or agreed to in writing, software | |||||
| # distributed under the License is distributed on an "AS IS" BASIS, | |||||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| # See the License for the specific language governing permissions and | |||||
| # limitations under the License. | |||||
| """dsl create helping function""" | |||||
| import _akg | |||||
| from _akg.utils import format_transform as ft_util | |||||
| class TensorUtils: | |||||
| """Class for creating tensor.""" | |||||
| CREATE_SCH_ONLY = 'create_sch_only' | |||||
| @classmethod | |||||
| def get_tensor_attrs(cls, tensor): | |||||
| """get tensor attrs.""" | |||||
| tensor_attrs = dict() | |||||
| if "attrs" in dir(tensor.op): | |||||
| tensor_attrs = dict(tensor.op.attrs.items()) | |||||
| return tensor_attrs | |||||
| @classmethod | |||||
| def update_tensor_attrs(cls, tensor, attrs): | |||||
| """update tensor attrs.""" | |||||
| tensor_attrs = cls.get_tensor_attrs(tensor) | |||||
| tensor_attrs.update(attrs) | |||||
| tensor = _akg.tvm.compute(tensor.shape, | |||||
| lambda *indice: tensor[indice], | |||||
| name=tensor.op.name, | |||||
| tag=tensor.op.tag, | |||||
| attrs=tensor_attrs) | |||||
| return tensor | |||||
| @classmethod | |||||
| def is_create_sch_only(cls, tensor): | |||||
| tensor_attrs = cls.get_tensor_attrs(tensor) | |||||
| if cls.CREATE_SCH_ONLY in tensor_attrs.keys(): | |||||
| return True | |||||
| return False | |||||
| @classmethod | |||||
| def is_output_value(cls, tensor): | |||||
| """check output value.""" | |||||
| return not cls.is_create_sch_only(tensor) | |||||
| @classmethod | |||||
| def inplace_set(cls, input_tensor, output_tensor, buffer_name="data_buf"): | |||||
| """inplace set.""" | |||||
| input_tensor_shape = ft_util.get_shape(input_tensor) | |||||
| output_tensor_shape = ft_util.get_shape(output_tensor) | |||||
| if not input_tensor_shape == output_tensor_shape: | |||||
| raise RuntimeError("Shape of the input_tensor and the output_tensor should be equal, " | |||||
| "but got %s and %s"%(input_tensor_shape, output_tensor_shape)) | |||||
| output_tensor = cls.update_tensor_attrs(output_tensor, {cls.CREATE_SCH_ONLY: 1}) | |||||
| data_buf = _akg.tvm.decl_buffer(input_tensor.shape, input_tensor.dtype, name=buffer_name) | |||||
| binds_info = {input_tensor: data_buf, output_tensor: data_buf} | |||||
| return output_tensor, binds_info | |||||
| @classmethod | |||||
| def inplace_set_tensors(cls, input_tensors, output_tensors, buffer_names=None): | |||||
| """ | |||||
| inplace set for tensors | |||||
| Args: | |||||
| in_tensors (Union[list, tuple]): Origin input tensors. | |||||
| out_tensors (Union[list, tuple]): Origin output tensors. | |||||
| buffer_names (Union[list, tuple] or None): Buffer names used to bind. | |||||
| Return: | |||||
| inplace_tensors (list): Output tensors with the inplace info. | |||||
| binds_infos (dict): Dictionary that maps the input tensor and the output | |||||
| tensor to buffer. | |||||
| """ | |||||
| if not buffer_names: | |||||
| buffer_names = ["data_buf_%s" % i for i in range(len(input_tensors))] | |||||
| for arg in (input_tensors, output_tensors, buffer_names): | |||||
| if not isinstance(arg, (tuple, list)): | |||||
| raise RuntimeError("arg must be tuple or list!") | |||||
| if len(input_tensors) != len(output_tensors) or len(input_tensors) != len(buffer_names): | |||||
| raise RuntimeError("length of the input_tensors, output_tensors and buffer_names must be equal!") | |||||
| inplace_tensors = [] | |||||
| binds_infos = dict() | |||||
| for input_tensor, output_tensor, buffer_name in zip(input_tensors, output_tensors, buffer_names): | |||||
| inplace_tensor, binds_info = cls.inplace_set(input_tensor, output_tensor, buffer_name) | |||||
| inplace_tensors.append(inplace_tensor) | |||||
| binds_infos.update(binds_info) | |||||
| return inplace_tensors, binds_infos | |||||
| def produce_shapes(shape1, shape2): | |||||
| """two input shapes produce three output shape.""" | |||||
| shape1 = list(shape1) | |||||
| shape2 = list(shape2) | |||||
| flag = 0 | |||||
| if len(shape1) < len(shape2): | |||||
| shape1, shape2 = shape2, shape1 | |||||
| flag = 1 | |||||
| output_shape_len = len(shape1) | |||||
| dec = output_shape_len - len(shape2) | |||||
| for i in range(dec): | |||||
| shape2 = [1] + shape2 | |||||
| out_shape = [] | |||||
| for i in range(output_shape_len): | |||||
| if (shape1[i] != shape2[i]) and (shape1[i] != 1) and (shape2[i] != 1): | |||||
| raise RuntimeError("input shapes not match!") | |||||
| out_shape.append(shape1[i] if shape1[i] > shape2[i] else shape2[i]) | |||||
| if flag == 1: | |||||
| shape1, shape2 = shape2, shape1 | |||||
| return shape1, shape2, out_shape | |||||
| @@ -1,80 +0,0 @@ | |||||
| # Copyright 2019 Huawei Technologies Co., Ltd | |||||
| # | |||||
| # Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| # you may not use this file except in compliance with the License. | |||||
| # You may obtain a copy of the License at | |||||
| # | |||||
| # http://www.apache.org/licenses/LICENSE-2.0 | |||||
| # | |||||
| # Unless required by applicable law or agreed to in writing, software | |||||
| # distributed under the License is distributed on an "AS IS" BASIS, | |||||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| # See the License for the specific language governing permissions and | |||||
| # limitations under the License. | |||||
| """format transform function""" | |||||
| import _akg | |||||
| def refine_reduce_axis(input_content, axis): | |||||
| """make reduce axis legal.""" | |||||
| shape = get_shape(input_content) | |||||
| if axis is None: | |||||
| axis = [i for i in range(len(shape))] | |||||
| elif isinstance(axis, int): | |||||
| axis = [axis] | |||||
| elif not isinstance(axis, (tuple, list)): | |||||
| raise TypeError("axis must be one of the type int,tuple,list or None") | |||||
| if len(axis) > len(shape): | |||||
| raise ValueError("axis size must not larger than shape size") | |||||
| axis = list(axis) | |||||
| for i, _ in enumerate(axis): | |||||
| if axis[i] < 0: | |||||
| axis[i] += len(shape) | |||||
| if axis[i] >= len(shape): | |||||
| raise ValueError(("axis value-{} exceeds len(axis) which is invalid".format(axis[i]))) | |||||
| axis.sort(reverse=True) | |||||
| return axis | |||||
| def get_shape_from_tensor(data): | |||||
| """translate _akg.tvm.shape to list type in python.""" | |||||
| tvm_shape = data.shape | |||||
| py_shape = [] | |||||
| for i in tvm_shape: | |||||
| if isinstance(i, _akg.tvm.expr.Var): | |||||
| py_shape.append(i) | |||||
| else: | |||||
| py_shape.append(i.value) | |||||
| return py_shape | |||||
| def tvm_shape_to_list(tvm_shape): | |||||
| """translate _akg.tvm.shape to list type in python.""" | |||||
| py_shape = [] | |||||
| for i in tvm_shape: | |||||
| if isinstance(i, _akg.tvm.expr.Var): | |||||
| py_shape.append(i) | |||||
| else: | |||||
| py_shape.append(i.value) | |||||
| return py_shape | |||||
| def get_shape(data): | |||||
| """get shape and save it as list.""" | |||||
| if isinstance(data, _akg.tvm.tensor.Tensor): | |||||
| shape = get_shape_from_tensor(data) | |||||
| elif isinstance(data, _akg.tvm.container.Array): | |||||
| shape = tvm_shape_to_list(data) | |||||
| elif isinstance(data, int): | |||||
| shape = [data] | |||||
| elif isinstance(data, (tuple, list)): | |||||
| shape = list(data) | |||||
| else: | |||||
| raise TypeError("Refine axis does not support type {} for now.".format(type(data))) | |||||
| return shape | |||||
| @@ -1,233 +0,0 @@ | |||||
| # Copyright 2019 Huawei Technologies Co., Ltd | |||||
| # | |||||
| # Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| # you may not use this file except in compliance with the License. | |||||
| # You may obtain a copy of the License at | |||||
| # | |||||
| # http://www.apache.org/licenses/LICENSE-2.0 | |||||
| # | |||||
| # Unless required by applicable law or agreed to in writing, software | |||||
| # distributed under the License is distributed on an "AS IS" BASIS, | |||||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| # See the License for the specific language governing permissions and | |||||
| # limitations under the License. | |||||
| """validation check functions""" | |||||
| from functools import wraps, reduce | |||||
| from _akg.utils.format_transform import get_shape | |||||
| MAX_DATA_SIZE = 2 ** 31 | |||||
| def check_input_type_dict(input_dict, input_key, input_name): | |||||
| """ | |||||
| check input parameter type for new type: dict. | |||||
| Note: | |||||
| rule1: key of input_dict should be in the input_key | |||||
| rule2: type of input_dict[shape] should be in (list, tuple), if have shape | |||||
| rule3: type of input_dict[dtype] should be in (str), if have dtype | |||||
| Args: | |||||
| input_dict (dict): input_dict | |||||
| input_key (list or tuple): all input key list, the key of input must in input_key | |||||
| input_name (str): input param name, only used for error print | |||||
| Returns: | |||||
| None | |||||
| """ | |||||
| def _check_input_type(input_key, input_type): | |||||
| if not isinstance(input_dict[input_key], input_type): | |||||
| raise RuntimeError( | |||||
| "the input parameter %s[%s] must be %s, while type of input is %s" % | |||||
| (input_name, input_key, input_type, type(input_dict[input_key]))) | |||||
| for key in input_dict.keys(): | |||||
| if key not in input_key: | |||||
| raise RuntimeError( | |||||
| "the input parameter %s must have arrt <%s>" % | |||||
| (input_name, key)) | |||||
| # check shape's type of input_dict, if have shape | |||||
| if key == "shape": | |||||
| _check_input_type(key, (list, tuple)) | |||||
| # check dtype's type of input_dict, if have dtype | |||||
| if key == "dtype": | |||||
| _check_input_type(key, (str,)) | |||||
| def check_input_type_list_tuple(inputs, expect): | |||||
| """check inputs by a list or tuple of expected types.""" | |||||
| if not isinstance(inputs, expect[1][0]): | |||||
| raise RuntimeError("the input parameter %s must be (list, tuple), while" | |||||
| " type of input is %s" % (expect[0], type(inputs))) | |||||
| for inp in inputs: | |||||
| if not isinstance(inp, expect[1][1]): | |||||
| raise RuntimeError("The element in parameter %s must be %s, while " | |||||
| "type of input is %s" % ( | |||||
| expect[0], expect[1][1], type(inp))) | |||||
| def check_input_type(*type_args, **_type_kwargs): | |||||
| """check input parameter type.""" | |||||
| def out_wrapper(func): | |||||
| """outer wrapper function.""" | |||||
| formal_parameter = func.__code__.co_varnames | |||||
| formal_parameter_list = list(zip(formal_parameter, type_args)) | |||||
| @wraps(func) | |||||
| def in_wrapper(*args, **kwargs): | |||||
| """inner wrapper function.""" | |||||
| for i, arg_v in enumerate(args): | |||||
| # add for new input dict, if dict, will check shape and dtype | |||||
| if isinstance(arg_v, dict): | |||||
| check_input_type_dict(arg_v, arg_v.keys(), | |||||
| formal_parameter_list[i][0]) | |||||
| if isinstance(formal_parameter_list[i][1], tuple): | |||||
| if isinstance(formal_parameter_list[i][1][0], tuple) \ | |||||
| and len(formal_parameter_list[i][1]) == 2: | |||||
| check_input_type_list_tuple(arg_v, formal_parameter_list[i]) | |||||
| continue | |||||
| if not isinstance(arg_v, formal_parameter_list[i][1]): | |||||
| raise RuntimeError("the %sth input parameter %s must be %s, " | |||||
| "while type of input is %s" % (str(i), formal_parameter_list[i][0], | |||||
| formal_parameter_list[i][1], | |||||
| type(arg_v))) | |||||
| for i in kwargs: | |||||
| for j in formal_parameter_list: | |||||
| if i in j: | |||||
| if not isinstance(kwargs[i], j[1]): | |||||
| raise RuntimeError("the input parameter %s must be " | |||||
| "%s, while type of input is %s" | |||||
| "" % (i, j[1], type(kwargs[i]))) | |||||
| break | |||||
| return func(*args, **kwargs) | |||||
| return in_wrapper | |||||
| return out_wrapper | |||||
| def shape_dtype_max_size_check(shape): | |||||
| """check validation of tensor's shape.""" | |||||
| if shape: | |||||
| mul = int(reduce(lambda x, y: int(x) * int(y), shape)) | |||||
| if mul > MAX_DATA_SIZE: | |||||
| error_msg = "*".join([str(sh) for sh in shape]) | |||||
| raise RuntimeError("Invalid shape, data is {} bytes ({}), which " | |||||
| "exceed max data size {} bytes" | |||||
| .format(mul, error_msg, MAX_DATA_SIZE)) | |||||
| def check_shape(tensor, length=None, tensor_name=""): | |||||
| """The common check rule for placeholder data.""" | |||||
| shape = get_shape(tensor) | |||||
| if not shape: | |||||
| raise RuntimeError("The ndim of input tensor {} must more than 0, " | |||||
| "actual input is {}".format(tensor_name, len(shape))) | |||||
| for shape_v in shape: | |||||
| if not isinstance(shape_v, int) or shape_v <= 0: | |||||
| raise RuntimeError("The type of tensor {} axis value must be " | |||||
| "positive int and value more than 0," | |||||
| "actual input is ({}) {}". | |||||
| format(tensor_name, type(shape_v), shape_v)) | |||||
| if length and len(shape) != length: | |||||
| raise ValueError('The length of {} should be {}, while actual length is {}'. | |||||
| format(tensor_name, length, len(shape))) | |||||
| def ops_dtype_check(dtype, args): | |||||
| """check validation of op's dtype.""" | |||||
| expected_dtype = list() | |||||
| def _get_expect_dtype(expected_dtype, arg): | |||||
| if isinstance(arg, str): | |||||
| expected_dtype.append(arg) | |||||
| elif isinstance(arg, (list, tuple)): | |||||
| for t in arg: | |||||
| _get_expect_dtype(expected_dtype, t) | |||||
| else: | |||||
| raise TypeError("arg should be either a string, " | |||||
| "or a list/tuple of string, " | |||||
| "while current is {}".format(type(arg))) | |||||
| _get_expect_dtype(expected_dtype, args) | |||||
| if isinstance(dtype, (list, tuple)): | |||||
| checking_dtype = [d.lower() for d in dtype] | |||||
| elif isinstance(dtype, str): | |||||
| checking_dtype = [dtype.lower()] | |||||
| else: | |||||
| raise TypeError("dtype should be either a string or a tuple/list of string") | |||||
| error_msg = "Supported dtype: {}, while received dtype: {}" | |||||
| if not set(checking_dtype).issubset(set(expected_dtype)): | |||||
| raise RuntimeError(error_msg.format(expected_dtype, checking_dtype)) | |||||
| def reduce_axis_check(reduce_shape, reduce_axis): | |||||
| """check validation of reduce axis for certain reduce shape.""" | |||||
| dim = len(reduce_shape) | |||||
| if dim == 1 and int(reduce_shape[0]) == 1: | |||||
| raise RuntimeError("Error, reduce shape is 1. Scalar is not supported " | |||||
| "for reduction, please input a vector.") | |||||
| if isinstance(reduce_axis, int): | |||||
| if reduce_axis not in range(-dim, dim): | |||||
| raise RuntimeError("Reduce axis should be in range [%d. %d)" | |||||
| "" % (-dim, dim)) | |||||
| elif isinstance(reduce_axis, (tuple, list)): | |||||
| if len(reduce_axis) > len(reduce_shape): | |||||
| raise RuntimeError("Reduce axis list exceed reduce shape length: " | |||||
| "%d vs %d, error" % (len(reduce_axis), len(reduce_shape))) | |||||
| processed_axis = [] | |||||
| for axis in reduce_axis: | |||||
| processed_axis.append(int(axis + dim) if axis < 0 else int(axis)) | |||||
| if len(set(processed_axis)) < len(processed_axis): | |||||
| raise RuntimeError("Reduce axis list contains %d duplicated element, please check" | |||||
| % (len(processed_axis) - len(set(processed_axis)))) | |||||
| for axis in processed_axis: | |||||
| if axis >= dim: | |||||
| raise RuntimeError("Invalid reduce axis, axis should less than %d" % dim) | |||||
| elif reduce_axis is not None: | |||||
| raise RuntimeError("axis should be a list, tuple or int.") | |||||
| def elemwise_dtype_check(dtype_a, dtype_b, supported_type=None): | |||||
| """check validation of tensor's dtype for element-wise op.""" | |||||
| if supported_type: | |||||
| ops_dtype_check(dtype_a, supported_type) | |||||
| ops_dtype_check(dtype_b, supported_type) | |||||
| if dtype_a.lower() != dtype_b.lower(): | |||||
| raise RuntimeError("Element-wise operation needs same data type, while " | |||||
| "current is %s vs %s" % (dtype_a.lower(), dtype_b.lower())) | |||||
| def auto_broadcast_check(shape_a, shape_b): | |||||
| """automatic broadcast check.""" | |||||
| shape_l = get_shape(shape_a) | |||||
| shape_r = get_shape(shape_b) | |||||
| if len(shape_l) <= len(shape_r): | |||||
| shape_short = shape_l | |||||
| shape_long = shape_r | |||||
| else: | |||||
| shape_short = shape_r | |||||
| shape_long = shape_l | |||||
| dim_diff = len(shape_long) - len(shape_short) | |||||
| for i in range(dim_diff): | |||||
| shape_short.insert(0, 1) | |||||
| for i, shp in enumerate(shape_short): | |||||
| if int(shp) != int(shape_long[i]) and 1 not in [int(shp), int(shape_long[i])]: | |||||
| raise RuntimeError("Invalid auto broadcast, dim %d should be 1 or equal, " | |||||
| "while now is %d vs %d" % (i, shp, shape_long[i])) | |||||
| def check_int_list(array, array_name): | |||||
| """check whether all the elements are integers.""" | |||||
| for num in array: | |||||
| if not isinstance(num, int): | |||||
| raise RuntimeError("Type of value in %s should be int, but got type %s" % (array_name, type(num))) | |||||
| @@ -146,7 +146,7 @@ class BuildPy(build_py): | |||||
| super().run() | super().run() | ||||
| mindspore_dir = os.path.join(pkg_dir, 'build', 'lib', 'mindspore') | mindspore_dir = os.path.join(pkg_dir, 'build', 'lib', 'mindspore') | ||||
| update_permissions(mindspore_dir) | update_permissions(mindspore_dir) | ||||
| mindspore_dir = os.path.join(pkg_dir, 'build', 'lib', '_akg') | |||||
| mindspore_dir = os.path.join(pkg_dir, 'build', 'lib', 'akg') | |||||
| update_permissions(mindspore_dir) | update_permissions(mindspore_dir) | ||||
| @@ -1,91 +0,0 @@ | |||||
| #!/bin/bash | |||||
| # Copyright 2019 Huawei Technologies Co., Ltd | |||||
| # | |||||
| # Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| # you may not use this file except in compliance with the License. | |||||
| # You may obtain a copy of the License at | |||||
| # | |||||
| # http://www.apache.org/licenses/LICENSE-2.0 | |||||
| # | |||||
| # Unless required by applicable law or agreed to in writing, software | |||||
| # distributed under the License is distributed on an "AS IS" BASIS, | |||||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| # See the License for the specific language governing permissions and | |||||
| # limitations under the License. | |||||
| # ============================================================================ | |||||
| PWD_PATH=`pwd` | |||||
| THIRD_PARTY_PATH=$(cd "$(dirname $0)"; pwd) | |||||
| if [ $# -lt 1 ]; then | |||||
| echo "Usage: sh apply_patches.sh [build_dir]" | |||||
| echo " build_dir is the directory where you type \"cmake\"" | |||||
| echo " Open source software incubator-tvm will be copied to build_dir" | |||||
| echo " where patches will be applied on." | |||||
| exit 1 | |||||
| fi | |||||
| BUILD_PATH=$1 | |||||
| if [ -d ${BUILD_PATH}/incubator-tvm ]; then | |||||
| rm -rf ${BUILD_PATH}/incubator-tvm | |||||
| fi | |||||
| DLPACK_PATH=$2 | |||||
| DMLC_PATH=$3 | |||||
| RANG_PATH=$4 | |||||
| TVM_PATH=$5 | |||||
| mkdir ${BUILD_PATH}/incubator-tvm | |||||
| cp -rf ${TVM_PATH}/* ${BUILD_PATH}/incubator-tvm/ | |||||
| cp -rf ${DLPACK_PATH}/* ${BUILD_PATH}/incubator-tvm/3rdparty/dlpack/ | |||||
| cp -rf ${DMLC_PATH}/* ${BUILD_PATH}/incubator-tvm/3rdparty/dmlc-core/ | |||||
| cp -rf ${RANG_PATH}/* ${BUILD_PATH}/incubator-tvm/3rdparty/rang/ | |||||
| check_dir_not_empty() | |||||
| { | |||||
| if [ ! $# -eq 1 ]; then | |||||
| echo "Usage: check_dir_not_empty dir_path" | |||||
| exit 1 | |||||
| fi | |||||
| if [ ! -d $1 ]; then | |||||
| echo "Directory $1 does not exist." | |||||
| exit 1 | |||||
| fi | |||||
| fileCounts=`ls $1 | wc -l` | |||||
| if [ ${fileCounts} -eq 0 ]; then | |||||
| echo "Directory $1 is empty." | |||||
| exit 1 | |||||
| fi | |||||
| } | |||||
| apply_patch() | |||||
| { | |||||
| if [ ! $# -eq 1 ]; then | |||||
| echo "Usage: apply_patch patch_name" | |||||
| exit 1 | |||||
| fi | |||||
| if [ ! -f $1 ]; then | |||||
| echo "Patch $1 does not exist." | |||||
| exit 1 | |||||
| fi | |||||
| patch -p1 < $1 | |||||
| if [ $? -eq 0 ]; then | |||||
| echo "Patch $1 applied successfully." | |||||
| else | |||||
| echo "Patch $1 not applied." | |||||
| fi | |||||
| } | |||||
| # apply patches on tvm | |||||
| TVM_PATH=${BUILD_PATH}/incubator-tvm | |||||
| TVM_PATCH_PATH=${THIRD_PARTY_PATH}/patch/incubator-tvm | |||||
| check_dir_not_empty "${TVM_PATH}" | |||||
| check_dir_not_empty "${TVM_PATCH_PATH}" | |||||
| cd ${TVM_PATH} | |||||
| apply_patch "${TVM_PATCH_PATH}/cmake.patch" | |||||
| apply_patch "${TVM_PATCH_PATH}/find_library.patch" | |||||
| apply_patch "${TVM_PATCH_PATH}/include.patch" | |||||
| apply_patch "${TVM_PATCH_PATH}/src_pass.patch" | |||||
| cd ${PWD_PATH} | |||||
| @@ -1,100 +0,0 @@ | |||||
| cmake_minimum_required(VERSION 3.2) | |||||
| project(tvm C CXX) | |||||
| set(TVM_DIR ${CMAKE_CURRENT_SOURCE_DIR}) | |||||
| # Utility functions | |||||
| include(${TVM_DIR}/cmake/util/Util.cmake) | |||||
| include(${TVM_DIR}/cmake/util/FindCUDA.cmake) | |||||
| # include directories | |||||
| include_directories(AFTER "${TVM_DIR}/include") | |||||
| include_directories(AFTER "${TVM_DIR}/src") | |||||
| include_directories(AFTER "${TVM_DIR}") | |||||
| include_directories(AFTER "${TVM_DIR}/src/schedule") | |||||
| include_directories(AFTER "${TVM_DIR}/3rdparty/dmlc-core/include") | |||||
| include_directories(AFTER "${TVM_DIR}/3rdparty/dlpack/include") | |||||
| include_directories(AFTER "${TVM_DIR}/3rdparty/compiler-rt") | |||||
| include_directories(AFTER "${TVM_DIR}/3rdparty/rang/include") | |||||
| # lib contain dlopen and dlclose | |||||
| set(TVM_RUNTIME_LINKER_LIBS ${CMAKE_DL_LIBS}) | |||||
| # add source group | |||||
| file(GLOB_RECURSE GROUP_SOURCE "${TVM_DIR}/src/*.cc" "src/*.cc") | |||||
| file(GLOB_RECURSE GROUP_INCLUDE "${TVM_DIR}/src/*.h" | |||||
| "${TVM_DIR}/include/*.h" "src/*.h" "include/*.h") | |||||
| assign_source_group("Source" ${GROUP_SOURCE}) | |||||
| assign_source_group("Include" ${GROUP_INCLUDE}) | |||||
| file(GLOB COMPILER_SRCS | |||||
| "pre_activate/gpu/*.cc" | |||||
| ${TVM_DIR}/src/api/*.cc | |||||
| ${TVM_DIR}/src/arithmetic/*.cc | |||||
| ${TVM_DIR}/src/autotvm/*.cc | |||||
| ${TVM_DIR}/src/codegen/*.cc | |||||
| ${TVM_DIR}/src/lang/*.cc | |||||
| ${TVM_DIR}/src/pass/*.cc | |||||
| ${TVM_DIR}/src/op/*.cc | |||||
| ${TVM_DIR}/src/node/*.cc | |||||
| ${TVM_DIR}/src/schedule/*.cc | |||||
| ${TVM_DIR}/src/runtime/*.cc | |||||
| ${TVM_DIR}/src/runtime/vm/*.cc | |||||
| ${TVM_DIR}/src/runtime/vm/profiler/*.cc | |||||
| ${TVM_DIR}/src/codegen/stackvm/*.cc) | |||||
| file(GLOB_RECURSE RELAY_SRCS ${TVM_DIR}/src/relay/*.cc) | |||||
| list(APPEND COMPILER_SRCS ${RELAY_SRCS}) | |||||
| file(GLOB DATATYPE_SRCS ${TVM_DIR}/src/codegen/datatype/*.cc) | |||||
| list(APPEND COMPILER_SRCS ${DATATYPE_SRCS}) | |||||
| file(GLOB COMPILER_VERILOG_SRCS ${TVM_DIR}/src/codegen/verilog/*.cc) | |||||
| list(APPEND COMPILER_SRCS ${COMPILER_VERILOG_SRCS}) | |||||
| file(GLOB TOPI_SRCS ${TVM_DIR}/topi/src/*.cc) | |||||
| file(GLOB RUNTIME_SRCS | |||||
| ${TVM_DIR}/src/runtime/*.cc | |||||
| ${TVM_DIR}/src/runtime/vm/*.cc | |||||
| ${TVM_DIR}/src/runtime/stub/*.cc | |||||
| ${TVM_DIR}/src/runtime/stackvm/*.cc) | |||||
| file(GLOB COMPILER_OFF_SRCS | |||||
| ${TVM_DIR}/src/codegen/opt/build_*_off.cc) | |||||
| list(REMOVE_ITEM COMPILER_OFF_SRCS | |||||
| ${TVM_DIR}/src/codegen/opt/build_cuda_off.cc) | |||||
| set(USE_CUDA "ON") | |||||
| list(APPEND COMPILER_SRCS ${COMPILER_OFF_SRCS}) | |||||
| # Module rules | |||||
| include(${TVM_DIR}/cmake/modules/CUDA.cmake) | |||||
| set(CMAKE_C_FLAGS_AKG -pipe -Wall -fPIC -fstack-protector-all) | |||||
| set(CMAKE_C_FLAGS_AKG ${CMAKE_C_FLAGS_AKG} -Wl,-z,relro,-z,now,-z,noexecstack) | |||||
| set(CMAKE_CXX_FLAGS_AKG -std=c++11 -pipe -Wall -fPIC -fstack-protector-all) | |||||
| set(CMAKE_CXX_FLAGS_AKG ${CMAKE_CXX_FLAGS_AKG} -Wl,-z,relro,-z,now,-z,noexecstack) | |||||
| if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug") | |||||
| message("-- Build in Debug mode") | |||||
| set(CMAKE_C_FLAGS_AKG ${CMAKE_C_FLAGS_AKG} -O0 -g -rdynamic) | |||||
| set(CMAKE_CXX_FLAGS_AKG ${CMAKE_CXX_FLAGS_AKG} -O0 -g -rdynamic) | |||||
| else() | |||||
| message("-- Build in Release mode") | |||||
| set(CMAKE_C_FLAGS_AKG ${CMAKE_C_FLAGS_AKG} -O2 -Werror) | |||||
| set(CMAKE_CXX_FLAGS_AKG ${CMAKE_CXX_FLAGS_AKG} -O2 -Werror) | |||||
| endif() | |||||
| if(CMAKE_CXX_COMPILER_ID MATCHES "GNU" AND CMAKE_CXX_COMPILER_VERSION | |||||
| VERSION_GREATER 7.0) | |||||
| set(CMAKE_CXX_FLAGS_AKG ${CMAKE_CXX_FLAGS_AKG} -faligned-new) | |||||
| endif() | |||||
| add_library(tvm SHARED ${COMPILER_SRCS} ${RUNTIME_SRCS} ${TOPI_SRCS}) | |||||
| target_link_libraries(tvm ${TVM_LINKER_LIBS} ${TVM_RUNTIME_LINKER_LIBS}) | |||||
| target_compile_options(tvm PRIVATE | |||||
| $<$<COMPILE_LANGUAGE:C>:${CMAKE_C_FLAGS_AKG}> | |||||
| $<$<COMPILE_LANGUAGE:CXX>:${CMAKE_CXX_FLAGS_AKG}>) | |||||
| target_include_directories(tvm PRIVATE "${TVM_DIR}/topi/include") | |||||
| install(TARGETS tvm) | |||||
| @@ -1,201 +0,0 @@ | |||||
| diff -Npur tvm/cmake/modules/ANTLR.cmake tvm_new/cmake/modules/ANTLR.cmake | |||||
| --- tvm/cmake/modules/ANTLR.cmake 2019-12-14 15:11:37.562418441 +0800 | |||||
| +++ tvm_new/cmake/modules/ANTLR.cmake 2019-12-14 11:28:49.161977599 +0800 | |||||
| @@ -14,12 +14,15 @@ | |||||
| # KIND, either express or implied. See the License for the | |||||
| # specific language governing permissions and limitations | |||||
| # under the License. | |||||
| + | |||||
| +# 2019.12.30 - Modify current directory of tvm. | |||||
| + | |||||
| if(USE_ANTLR) | |||||
| find_antlr(${USE_ANTLR}) | |||||
| if(ANTLR4) | |||||
| set(RELAY_PARSER_DIR | |||||
| - ${CMAKE_CURRENT_SOURCE_DIR}/python/tvm/relay/grammar) | |||||
| + ${TVM_DIR}/python/tvm/relay/grammar) | |||||
| set(RELAY_PARSER | |||||
| ${RELAY_PARSER_DIR}/py3/RelayVisitor.py | |||||
| diff -Npur tvm/cmake/modules/CUDA.cmake tvm_new/cmake/modules/CUDA.cmake | |||||
| --- tvm/cmake/modules/CUDA.cmake 2019-12-14 15:11:37.562418441 +0800 | |||||
| +++ tvm_new/cmake/modules/CUDA.cmake 2019-12-14 11:28:49.161977599 +0800 | |||||
| @@ -15,6 +15,8 @@ | |||||
| # specific language governing permissions and limitations | |||||
| # under the License. | |||||
| +# 2019.12.30 - Modify current directory of tvm. | |||||
| + | |||||
| # CUDA Module | |||||
| find_cuda(${USE_CUDA}) | |||||
| @@ -29,9 +31,9 @@ if(USE_CUDA) | |||||
| message(FATAL_ERROR "Cannot find CUDA, USE_CUDA=" ${USE_CUDA}) | |||||
| endif() | |||||
| message(STATUS "Build with CUDA support") | |||||
| - file(GLOB RUNTIME_CUDA_SRCS src/runtime/cuda/*.cc) | |||||
| + file(GLOB RUNTIME_CUDA_SRCS ${TVM_DIR}/src/runtime/cuda/*.cc) | |||||
| list(APPEND RUNTIME_SRCS ${RUNTIME_CUDA_SRCS}) | |||||
| - list(APPEND COMPILER_SRCS src/codegen/opt/build_cuda_on.cc) | |||||
| + list(APPEND COMPILER_SRCS ${TVM_DIR}/src/codegen/opt/build_cuda_on.cc) | |||||
| list(APPEND TVM_LINKER_LIBS ${CUDA_NVRTC_LIBRARY}) | |||||
| list(APPEND TVM_RUNTIME_LINKER_LIBS ${CUDA_CUDART_LIBRARY}) | |||||
| @@ -40,18 +42,18 @@ if(USE_CUDA) | |||||
| if(USE_CUDNN) | |||||
| message(STATUS "Build with cuDNN support") | |||||
| - file(GLOB CONTRIB_CUDNN_SRCS src/runtime/contrib/cudnn/*.cc) | |||||
| + file(GLOB CONTRIB_CUDNN_SRCS ${TVM_DIR}/src/runtime/contrib/cudnn/*.cc) | |||||
| list(APPEND RUNTIME_SRCS ${CONTRIB_CUDNN_SRCS}) | |||||
| list(APPEND TVM_RUNTIME_LINKER_LIBS ${CUDA_CUDNN_LIBRARY}) | |||||
| endif(USE_CUDNN) | |||||
| if(USE_CUBLAS) | |||||
| message(STATUS "Build with cuBLAS support") | |||||
| - file(GLOB CONTRIB_CUBLAS_SRCS src/runtime/contrib/cublas/*.cc) | |||||
| + file(GLOB CONTRIB_CUBLAS_SRCS ${TVM_DIR}/src/runtime/contrib/cublas/*.cc) | |||||
| list(APPEND RUNTIME_SRCS ${CONTRIB_CUBLAS_SRCS}) | |||||
| list(APPEND TVM_RUNTIME_LINKER_LIBS ${CUDA_CUBLAS_LIBRARY}) | |||||
| endif(USE_CUBLAS) | |||||
| else(USE_CUDA) | |||||
| - list(APPEND COMPILER_SRCS src/codegen/opt/build_cuda_off.cc) | |||||
| + list(APPEND COMPILER_SRCS ${TVM_DIR}/src/codegen/opt/build_cuda_off.cc) | |||||
| endif(USE_CUDA) | |||||
| diff -Npur tvm/cmake/modules/LLVM.cmake tvm_new/cmake/modules/LLVM.cmake | |||||
| --- tvm/cmake/modules/LLVM.cmake 2019-12-14 15:11:37.562418441 +0800 | |||||
| +++ tvm_new/cmake/modules/LLVM.cmake 2019-12-14 11:28:49.161977599 +0800 | |||||
| @@ -15,6 +15,8 @@ | |||||
| # specific language governing permissions and limitations | |||||
| # under the License. | |||||
| +# 2019.12.30 - Modify current directory of tvm. | |||||
| + | |||||
| # LLVM rules | |||||
| add_definitions(-DDMLC_USE_FOPEN64=0) | |||||
| @@ -26,7 +28,7 @@ if(NOT USE_LLVM STREQUAL "OFF") | |||||
| message(STATUS "Set TVM_LLVM_VERSION=" ${TVM_LLVM_VERSION}) | |||||
| # Set flags that are only needed for LLVM target | |||||
| add_definitions(-DTVM_LLVM_VERSION=${TVM_LLVM_VERSION}) | |||||
| - file(GLOB COMPILER_LLVM_SRCS src/codegen/llvm/*.cc) | |||||
| + file(GLOB COMPILER_LLVM_SRCS ${TVM_DIR}/src/codegen/llvm/*.cc) | |||||
| list(APPEND TVM_LINKER_LIBS ${LLVM_LIBS}) | |||||
| list(APPEND COMPILER_SRCS ${COMPILER_LLVM_SRCS}) | |||||
| if(NOT MSVC) | |||||
| diff -Npur tvm/cmake/modules/Micro.cmake tvm_new/cmake/modules/Micro.cmake | |||||
| --- tvm/cmake/modules/Micro.cmake 2019-12-14 15:11:37.562418441 +0800 | |||||
| +++ tvm_new/cmake/modules/Micro.cmake 2019-12-14 11:28:49.161977599 +0800 | |||||
| @@ -15,8 +15,10 @@ | |||||
| # specific language governing permissions and limitations | |||||
| # under the License. | |||||
| +# 2019.12.30 - Modify current directory of tvm. | |||||
| + | |||||
| if(USE_MICRO) | |||||
| message(STATUS "Build with Micro support") | |||||
| - file(GLOB RUNTIME_MICRO_SRCS src/runtime/micro/*.cc) | |||||
| + file(GLOB RUNTIME_MICRO_SRCS ${TVM_DIR}/src/runtime/micro/*.cc) | |||||
| list(APPEND RUNTIME_SRCS ${RUNTIME_MICRO_SRCS}) | |||||
| endif(USE_MICRO) | |||||
| diff -Npur tvm/cmake/modules/VTA.cmake tvm_new/cmake/modules/VTA.cmake | |||||
| --- tvm/cmake/modules/VTA.cmake 2019-12-14 15:11:37.562418441 +0800 | |||||
| +++ tvm_new/cmake/modules/VTA.cmake 2019-12-14 14:42:32.358381133 +0800 | |||||
| @@ -15,17 +15,19 @@ | |||||
| # specific language governing permissions and limitations | |||||
| # under the License. | |||||
| +# 2019.12.30 - Modify current directory of tvm. | |||||
| + | |||||
| # CMake Build rules for VTA | |||||
| find_program(PYTHON NAMES python python3 python3.6) | |||||
| if(MSVC) | |||||
| message(STATUS "VTA build is skipped in Windows..") | |||||
| elseif(PYTHON) | |||||
| - set(VTA_CONFIG ${PYTHON} ${CMAKE_CURRENT_SOURCE_DIR}/vta/config/vta_config.py) | |||||
| + set(VTA_CONFIG ${PYTHON} ${TVM_DIR}/vta/config/vta_config.py) | |||||
| if(EXISTS ${CMAKE_CURRENT_BINARY_DIR}/vta_config.json) | |||||
| message(STATUS "Use VTA config " ${CMAKE_CURRENT_BINARY_DIR}/vta_config.json) | |||||
| - set(VTA_CONFIG ${PYTHON} ${CMAKE_CURRENT_SOURCE_DIR}/vta/config/vta_config.py | |||||
| + set(VTA_CONFIG ${PYTHON} ${TVM_DIR}/vta/config/vta_config.py | |||||
| --use-cfg=${CMAKE_CURRENT_BINARY_DIR}/vta_config.json) | |||||
| endif() | |||||
| @@ -40,18 +42,18 @@ elseif(PYTHON) | |||||
| # Fast simulator driver build | |||||
| if(USE_VTA_FSIM) | |||||
| # Add fsim driver sources | |||||
| - file(GLOB FSIM_RUNTIME_SRCS vta/src/*.cc) | |||||
| - list(APPEND FSIM_RUNTIME_SRCS vta/src/sim/sim_driver.cc) | |||||
| - list(APPEND FSIM_RUNTIME_SRCS vta/src/vmem/virtual_memory.cc vta/src/vmem/virtual_memory.h) | |||||
| - list(APPEND FSIM_RUNTIME_SRCS vta/src/sim/sim_tlpp.cc) | |||||
| + file(GLOB FSIM_RUNTIME_SRCS ${TVM_DIR}/vta/src/*.cc) | |||||
| + list(APPEND FSIM_RUNTIME_SRCS ${TVM_DIR}/vta/src/sim/sim_driver.cc) | |||||
| + list(APPEND FSIM_RUNTIME_SRCS ${TVM_DIR}/vta/src/vmem/virtual_memory.cc ${TVM_DIR}/vta/src/vmem/virtual_memory.h) | |||||
| + list(APPEND FSIM_RUNTIME_SRCS ${TVM_DIR}/vta/src/sim/sim_tlpp.cc) | |||||
| # Target lib: vta_fsim | |||||
| add_library(vta_fsim SHARED ${FSIM_RUNTIME_SRCS}) | |||||
| - target_include_directories(vta_fsim PUBLIC vta/include) | |||||
| + target_include_directories(vta_fsim PUBLIC ${TVM_DIR}/vta/include) | |||||
| foreach(__def ${VTA_DEFINITIONS}) | |||||
| string(SUBSTRING ${__def} 3 -1 __strip_def) | |||||
| target_compile_definitions(vta_fsim PUBLIC ${__strip_def}) | |||||
| endforeach() | |||||
| - include_directories("vta/include") | |||||
| + include_directories("${TVM_DIR}/vta/include") | |||||
| if(APPLE) | |||||
| set_target_properties(vta_fsim PROPERTIES LINK_FLAGS "-undefined dynamic_lookup") | |||||
| endif(APPLE) | |||||
| @@ -61,18 +63,18 @@ elseif(PYTHON) | |||||
| # Cycle accurate simulator driver build | |||||
| if(USE_VTA_TSIM) | |||||
| # Add tsim driver sources | |||||
| - file(GLOB TSIM_RUNTIME_SRCS vta/src/*.cc) | |||||
| - list(APPEND TSIM_RUNTIME_SRCS vta/src/tsim/tsim_driver.cc) | |||||
| - list(APPEND TSIM_RUNTIME_SRCS vta/src/dpi/module.cc) | |||||
| - list(APPEND TSIM_RUNTIME_SRCS vta/src/vmem/virtual_memory.cc vta/src/vmem/virtual_memory.h) | |||||
| + file(GLOB TSIM_RUNTIME_SRCS ${TVM_DIR}/vta/src/*.cc) | |||||
| + list(APPEND TSIM_RUNTIME_SRCS ${TVM_DIR}/vta/src/tsim/tsim_driver.cc) | |||||
| + list(APPEND TSIM_RUNTIME_SRCS ${TVM_DIR}/vta/src/dpi/module.cc) | |||||
| + list(APPEND TSIM_RUNTIME_SRCS ${TVM_DIR}/vta/src/vmem/virtual_memory.cc ${TVM_DIR}/vta/src/vmem/virtual_memory.h) | |||||
| # Target lib: vta_tsim | |||||
| add_library(vta_tsim SHARED ${TSIM_RUNTIME_SRCS}) | |||||
| - target_include_directories(vta_tsim PUBLIC vta/include) | |||||
| + target_include_directories(vta_tsim PUBLIC ${TVM_DIR}/vta/include) | |||||
| foreach(__def ${VTA_DEFINITIONS}) | |||||
| string(SUBSTRING ${__def} 3 -1 __strip_def) | |||||
| target_compile_definitions(vta_tsim PUBLIC ${__strip_def}) | |||||
| endforeach() | |||||
| - include_directories("vta/include") | |||||
| + include_directories("${TVM_DIR}/vta/include") | |||||
| if(APPLE) | |||||
| set_target_properties(vta_tsim PROPERTIES LINK_FLAGS "-undefined dynamic_lookup") | |||||
| endif(APPLE) | |||||
| @@ -80,19 +82,19 @@ elseif(PYTHON) | |||||
| # VTA FPGA driver sources | |||||
| if(USE_VTA_FPGA) | |||||
| - file(GLOB FPGA_RUNTIME_SRCS vta/src/*.cc) | |||||
| + file(GLOB FPGA_RUNTIME_SRCS ${TVM_DIR}/vta/src/*.cc) | |||||
| # Rules for Zynq-class FPGAs with pynq OS support (see pynq.io) | |||||
| if(${VTA_TARGET} STREQUAL "pynq" OR | |||||
| ${VTA_TARGET} STREQUAL "ultra96") | |||||
| - list(APPEND FPGA_RUNTIME_SRCS vta/src/pynq/pynq_driver.cc) | |||||
| + list(APPEND FPGA_RUNTIME_SRCS ${TVM_DIR}/vta/src/pynq/pynq_driver.cc) | |||||
| # Rules for Pynq v2.4 | |||||
| find_library(__cma_lib NAMES cma PATH /usr/lib) | |||||
| elseif(${VTA_TARGET} STREQUAL "de10nano") # DE10-Nano rules | |||||
| - file(GLOB FPGA_RUNTIME_SRCS vta/src/de10nano/*.cc vta/src/*.cc) | |||||
| + file(GLOB FPGA_RUNTIME_SRCS ${TVM_DIR}/vta/src/de10nano/*.cc ${TVM_DIR}/vta/src/*.cc) | |||||
| endif() | |||||
| # Target lib: vta | |||||
| add_library(vta SHARED ${FPGA_RUNTIME_SRCS}) | |||||
| - target_include_directories(vta PUBLIC vta/include) | |||||
| + target_include_directories(vta PUBLIC ${TVM_DIR}/vta/include) | |||||
| foreach(__def ${VTA_DEFINITIONS}) | |||||
| string(SUBSTRING ${__def} 3 -1 __strip_def) | |||||
| target_compile_definitions(vta PUBLIC ${__strip_def}) | |||||
| @@ -1,71 +0,0 @@ | |||||
| --- tvm/python/tvm/_ffi/base.py 2020-03-12 16:17:39.089828527 +0800 | |||||
| +++ tvm_new/python/tvm/_ffi/base.py 2020-03-12 16:17:16.829829558 +0800 | |||||
| @@ -16,6 +16,9 @@ | |||||
| # under the License. | |||||
| # coding: utf-8 | |||||
| # pylint: disable=invalid-name | |||||
| + | |||||
| +# 2019.12.30 - Modify _load_lib function. | |||||
| + | |||||
| """Base library for TVM FFI.""" | |||||
| from __future__ import absolute_import | |||||
| @@ -47,8 +50,18 @@ else: | |||||
| def _load_lib(): | |||||
| - """Load libary by searching possible path.""" | |||||
| - lib_path = libinfo.find_lib_path() | |||||
| + """Load library by searching possible path.""" | |||||
| + pwd = os.path.dirname(os.path.realpath(__file__)) | |||||
| + path = os.path.realpath(pwd+"/../../../mindspore/lib") | |||||
| + lib_path = [] | |||||
| + files = os.listdir(path) | |||||
| + for f in files: | |||||
| + if f.startswith("libtvm.") and f.endswith(".so"): | |||||
| + lib_path.append(path+"/"+f) | |||||
| + break | |||||
| + if not lib_path: | |||||
| + raise RuntimeError("mindspore library cannot find.") | |||||
| + | |||||
| lib = ctypes.CDLL(lib_path[0], ctypes.RTLD_GLOBAL) | |||||
| # DMatrix functions | |||||
| lib.TVMGetLastError.restype = ctypes.c_char_p | |||||
| diff -Npur tvm/topi/python/topi/cpp/impl.py tvm_new/topi/python/topi/cpp/impl.py | |||||
| --- tvm/topi/python/topi/cpp/impl.py 2020-03-12 16:17:39.129828525 +0800 | |||||
| +++ tvm_new/topi/python/topi/cpp/impl.py 2020-03-12 16:17:16.873829556 +0800 | |||||
| @@ -14,6 +14,9 @@ | |||||
| # KIND, either express or implied. See the License for the | |||||
| # specific language governing permissions and limitations | |||||
| # under the License. | |||||
| + | |||||
| +# 2019.12.30 - Modify _load_lib function. | |||||
| + | |||||
| """Load Lib for C++ TOPI ops and schedules""" | |||||
| import sys | |||||
| import os | |||||
| @@ -30,12 +33,18 @@ def _get_lib_names(): | |||||
| return ['libtvm_topi.so', 'tvm_topi.so'] | |||||
| def _load_lib(): | |||||
| - """Load libary by searching possible path.""" | |||||
| - curr_path = os.path.dirname(os.path.realpath(os.path.expanduser(__file__))) | |||||
| - lib_search = curr_path | |||||
| - lib_path = libinfo.find_lib_path(_get_lib_names(), lib_search, optional=True) | |||||
| - if lib_path is None: | |||||
| - return None, None | |||||
| + """Load library by searching possible path.""" | |||||
| + pwd = os.path.dirname(os.path.realpath(__file__)) | |||||
| + path = os.path.realpath(pwd+"/../../../mindspore/lib") | |||||
| + lib_path = [] | |||||
| + files = os.listdir(path) | |||||
| + for f in files: | |||||
| + if f.startswith("libtvm.") and f.endswith(".so"): | |||||
| + lib_path.append(path+"/"+f) | |||||
| + break | |||||
| + if not lib_path: | |||||
| + raise RuntimeError("mindspore library cannot find.") | |||||
| + | |||||
| lib = ctypes.CDLL(lib_path[0], ctypes.RTLD_GLOBAL) | |||||
| return lib, os.path.basename(lib_path[0]) | |||||
| @@ -1,55 +0,0 @@ | |||||
| diff -Npur tvm/include/tvm/expr_operator.h tvm_new/include/tvm/expr_operator.h | |||||
| --- tvm/include/tvm/expr_operator.h 2019-12-28 10:11:27.369814744 +0800 | |||||
| +++ tvm_new/include/tvm/expr_operator.h 2019-12-28 10:11:27.209812391 +0800 | |||||
| @@ -25,6 +25,11 @@ | |||||
| * when the type is int32 or int64 for simplifying the index expressions. | |||||
| */ | |||||
| // Acknowledgement: Most operator APIs originate from Halide. | |||||
| + | |||||
| +/* | |||||
| + * 2019.12.30 - Add new operator for expr. | |||||
| + */ | |||||
| + | |||||
| #ifndef TVM_EXPR_OPERATOR_H_ | |||||
| #define TVM_EXPR_OPERATOR_H_ | |||||
| @@ -217,6 +222,16 @@ TVM_DLL Expr operator*(Expr a, Expr b); | |||||
| */ | |||||
| TVM_DLL Expr operator/(Expr a, Expr b); | |||||
| /*! | |||||
| + * \brief mod operator | |||||
| + * | |||||
| + * \param a left operand | |||||
| + * \param b right operand | |||||
| + * \return The result expression. | |||||
| + * \note this function does eager constant folding for | |||||
| + * index types(int32, int64) when possible. | |||||
| + */ | |||||
| +TVM_DLL Expr operator%(Expr a, Expr b); | |||||
| +/*! | |||||
| * \brief left shift operator | |||||
| * | |||||
| * \param a left operand | |||||
| diff -Npur tvm/include/tvm/lowered_func.h tvm_new/include/tvm/lowered_func.h | |||||
| --- tvm/include/tvm/lowered_func.h 2019-12-28 10:11:27.369814744 +0800 | |||||
| +++ tvm_new/include/tvm/lowered_func.h 2019-12-28 10:11:27.209812391 +0800 | |||||
| @@ -22,6 +22,11 @@ | |||||
| * \brief Information about a lowered TVM function. | |||||
| * This data structure is final step toward codegen. | |||||
| */ | |||||
| + | |||||
| +/* | |||||
| + * 2019.12.30 - Add new var array for args_real. | |||||
| + */ | |||||
| + | |||||
| #ifndef TVM_LOWERED_FUNC_H_ | |||||
| #define TVM_LOWERED_FUNC_H_ | |||||
| @@ -74,6 +79,7 @@ class LoweredFuncNode : public ir::Funct | |||||
| * This function can only take pod type(int, float) and void* as arguments. | |||||
| */ | |||||
| Array<Var> args; | |||||
| + Array<Var> args_real; | |||||
| /*! | |||||
| * \brief The IterVar axis of threads | |||||
| * Each axis need host function to specify a size. | |||||
| @@ -1,120 +0,0 @@ | |||||
| diff -Npur tvm/src/pass/make_api.cc tvm_new/src/pass/make_api.cc | |||||
| --- tvm/src/pass/make_api.cc 2019-12-14 15:11:37.626419432 +0800 | |||||
| +++ tvm_new/src/pass/make_api.cc 2019-12-14 14:58:46.562493287 +0800 | |||||
| @@ -20,6 +20,11 @@ | |||||
| /*! | |||||
| * \file make_api.cc Build API function. | |||||
| */ | |||||
| + | |||||
| +/* | |||||
| + * 2019.12.30 - Define new function to push buffer node from api_args to args_real. | |||||
| + */ | |||||
| + | |||||
| #include <tvm/ir_pass.h> | |||||
| #include <tvm/ir.h> | |||||
| #include <tvm/ir_visitor.h> | |||||
| @@ -40,6 +45,17 @@ inline Stmt MakeAssertEQ(Expr lhs, Expr | |||||
| return AssertStmt::make(lhs == rhs, msg, Evaluate::make(0)); | |||||
| } | |||||
| +Array<Var> Param ( Array<NodeRef> api_args,Array<Var> args_real) { | |||||
| + int num_args = static_cast<int>(api_args.size()); | |||||
| + for (int i = 0; i < num_args; i++) { | |||||
| + const BufferNode *v = api_args[i].as<BufferNode>(); | |||||
| + if(v) { | |||||
| + args_real.push_back(v->data); | |||||
| + } | |||||
| + } | |||||
| + return args_real; | |||||
| +} | |||||
| + | |||||
| LoweredFunc MakeAPI(Stmt body, | |||||
| std::string name, | |||||
| Array<NodeRef> api_args, | |||||
| @@ -47,6 +63,8 @@ LoweredFunc MakeAPI(Stmt body, | |||||
| bool is_restricted) { | |||||
| const Stmt nop = Evaluate::make(0); | |||||
| int num_args = static_cast<int>(api_args.size()); | |||||
| + Array<Var> args_real; | |||||
| + args_real = Param (api_args, args_real); | |||||
| CHECK_LE(num_unpacked_args, num_args); | |||||
| int num_packed_args = num_args - num_unpacked_args; | |||||
| // Data field definitions | |||||
| @@ -170,6 +188,7 @@ LoweredFunc MakeAPI(Stmt body, | |||||
| NodePtr<LoweredFuncNode> n = make_node<LoweredFuncNode>(); | |||||
| n->name = name; | |||||
| n->args = args; | |||||
| + n->args_real = args_real; | |||||
| n->handle_data_type = binder.def_handle_dtype(); | |||||
| n->is_packed_func = num_unpacked_args == 0; | |||||
| n->is_restricted = is_restricted; | |||||
| diff -Npur tvm/src/pass/split_host_device.cc tvm_new/src/pass/split_host_device.cc | |||||
| --- tvm/src/pass/split_host_device.cc 2019-12-14 15:11:37.626419432 +0800 | |||||
| +++ tvm_new/src/pass/split_host_device.cc 2019-12-14 11:28:49.293979656 +0800 | |||||
| @@ -21,6 +21,11 @@ | |||||
| * \file split_host_device.cc | |||||
| * \brief Split device function from host. | |||||
| */ | |||||
| + | |||||
| +/* | |||||
| + * 2019.12.30 - Add new implements for host device splitter. | |||||
| + */ | |||||
| + | |||||
| #include <tvm/ir.h> | |||||
| #include <tvm/lowered_func.h> | |||||
| #include <tvm/channel.h> | |||||
| @@ -38,6 +43,7 @@ class IRUseDefAnalysis : public IRMutato | |||||
| Stmt Mutate_(const AttrStmt *op, const Stmt& s) final { | |||||
| if (op->attr_key == attr::thread_extent) { | |||||
| IterVar iv = Downcast<IterVar>(op->node); | |||||
| + iv = IterVarNode::make(Range(0, op->value), iv->var, iv->iter_type, iv->thread_tag); | |||||
| CHECK_NE(iv->thread_tag.length(), 0U); | |||||
| // thread_extent can appear multiple times | |||||
| // use the first appearance as def. | |||||
| @@ -186,6 +192,7 @@ class HostDeviceSplitter : public IRMuta | |||||
| name_ = f->name; | |||||
| NodePtr<LoweredFuncNode> n = | |||||
| make_node<LoweredFuncNode>(*f.operator->()); | |||||
| + args_real = n->args_real; | |||||
| n->body = this->Mutate(f->body); | |||||
| n->func_type = kHostFunc; | |||||
| Array<LoweredFunc> ret{LoweredFunc(n)}; | |||||
| @@ -196,6 +203,7 @@ class HostDeviceSplitter : public IRMuta | |||||
| } | |||||
| private: | |||||
| + Array<Var> args_real; | |||||
| Stmt SplitDeviceFunc(Stmt body) { | |||||
| std::ostringstream os; | |||||
| os << name_ << "_kernel" << device_funcs_.size(); | |||||
| @@ -223,6 +231,30 @@ class HostDeviceSplitter : public IRMuta | |||||
| n->args.push_back(v); | |||||
| } | |||||
| } | |||||
| +std::shared_ptr<LoweredFuncNode> na = std::make_shared<LoweredFuncNode>(); | |||||
| + for (unsigned i = 0; i < (unsigned)args_real.size(); i++) { | |||||
| + bool match = false; | |||||
| + for (unsigned j = 0; j < (unsigned)n->args.size(); j++) { | |||||
| + if (strcmp(args_real[i].get()->name_hint.c_str(), n->args[j].get()->name_hint.c_str()) == 0) { | |||||
| + na->args.push_back(n->args[j]); | |||||
| + match = true; | |||||
| + break; | |||||
| + } else { | |||||
| + continue; | |||||
| + } | |||||
| + } | |||||
| + | |||||
| + if (!match) { | |||||
| + na->args.push_back(args_real[i]); | |||||
| + // mark handle data type. | |||||
| + for (auto kv : handle_data_type_) { | |||||
| + if (strcmp(args_real[i].get()->name_hint.c_str(), kv.first->name_hint.c_str()) == 0) { | |||||
| + n->handle_data_type.Set(args_real[i], kv.second); | |||||
| + } | |||||
| + } | |||||
| + } | |||||
| + } | |||||
| + n->args = na->args; | |||||
| LoweredFunc f_device(n); | |||||
| Array<Expr> call_args; | |||||
| call_args.push_back(StringImm::make(f_device->name)); | |||||