| # Licensed to the Apache Software Foundation (ASF) under one |
| # or more contributor license agreements. See the NOTICE file |
| # distributed with this work for additional information |
| # regarding copyright ownership. The ASF licenses this file |
| # to you 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. |
| |
| |
| import tvm |
| from .. import defop |
| from ..utils import reduce_axes, assign_by_req |
| |
| |
| def _compute_sum(itype, otype, ndim, reduce1st_dim, req): |
| axes = ([reduce1st_dim, 1 - reduce1st_dim] * ndim)[:ndim] |
| a = tvm.te.placeholder([tvm.te.size_var() for _ in range(ndim)], name='a', dtype=itype) |
| reduce_output = reduce_axes(a, axes, tvm.tir.sum, otype) |
| output_placeholder, final_output = assign_by_req(reduce_output, req) |
| s = tvm.te.create_schedule(final_output.op) |
| return s, a, output_placeholder, final_output, [reduce_output, final_output] |
| |
| |
| @defop(name='sum_cpu', target='cpu', itype=['bool'], |
| otype=['float32', 'float64', 'int32', 'int64'], |
| ndim=[5], req=['kWriteTo', 'kAddTo'], reduce1st_dim=[0, 1], |
| attrs=["reduce1st_dim", "req"]) |
| def _sum_cpu(itype, otype, ndim, reduce1st_dim, req): |
| s, a, output_placeholder, final_output, tensor_list = _compute_sum( |
| itype, otype, ndim, reduce1st_dim, req) |
| for t in tensor_list: |
| axes = [axis for axis in t.op.axis] |
| fused = s[t].fuse(*axes) |
| s[t].parallel(fused) |
| return s, [a, output_placeholder, final_output] |
| |
| |
| @defop(name='sum_gpu', target='gpu', itype=['bool'], |
| otype=['float32', 'float64', 'int32', 'int64'], |
| ndim=[5], req=['kWriteTo', 'kAddTo'], reduce1st_dim=[0, 1], |
| attrs=["reduce1st_dim", "req"]) |
| def _sum_gpu(itype, otype, ndim, reduce1st_dim, req): |
| s, a, output_placeholder, final_output, tensor_list = _compute_sum( |
| itype, otype, ndim, reduce1st_dim, req) |
| num_threads = 64 |
| for t in tensor_list: |
| block_x = tvm.te.thread_axis("blockIdx.x") |
| thread_x = tvm.te.thread_axis("threadIdx.x") |
| axes = [axis for axis in t.op.axis] |
| fused = s[t].fuse(*axes) |
| bx, tx = s[t].split(fused, factor=num_threads) |
| s[t].bind(bx, block_x) |
| s[t].bind(tx, thread_x) |
| return s, [a, output_placeholder, final_output] |