Files
wehub-resource-sync 26446540fa
Lint / lint (push) Waiting to run
CI / MacOS (push) Waiting to run
CI / Windows (push) Waiting to run
chore: import upstream snapshot with attribution
2026-07-13 13:36:25 +08:00

94 lines
3.5 KiB
Python

# 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.
# pylint: disable=missing-docstring
# ruff: noqa: F841
"""Pool schedule rule for Adreno operators."""
from tvm import s_tir, tirx
from tvm.target import Target
from .. import analysis
from .base import AdrenoScheduleRule
# pylint: disable=invalid-name, unused-variable
class Pool2D(AdrenoScheduleRule):
def apply( # pylint: disable=too-many-locals,missing-docstring
self,
func: tirx.PrimFunc,
target: Target,
_: bool,
) -> s_tir.Schedule:
sch = s_tir.Schedule(func)
root = sch.get_sblock(name="root", func_name="main")
blocks = sch.get_child_blocks(root)
blocks_names = [sch.get(blk).name_hint for blk in blocks]
if "adaptive_pool_sum" not in blocks_names and "pool_max" not in blocks_names:
return None
def schedule_pad(blk: s_tir.schedule.SBlockRV):
lps, veclp = sch.get_loops(blk)[:-1], sch.get_loops(blk)[-1]
sch.vectorize(veclp)
b = sch.fuse(*lps)
tx_extent = min(int(sch.get(b).extent) & ~int(sch.get(b).extent - 1), 256)
bx, tx = sch.split(b, [None, tx_extent])
sch.bind(bx, "blockIdx.x")
sch.bind(tx, "threadIdx.x")
def schedule_max_pool(blk: s_tir.schedule.SBlockRV):
block_info = analysis.get_sblock_info(sch, blk)
iters_kind = "".join([_iter.kind for _iter in block_info.iters])
if iters_kind != "SSSSSRR":
return None
lps = sch.get_loops(blk)
block_lps, vec_lp, red_lps = lps[:4], lps[4], lps[5:]
write_blk = sch.cache_write(blk, 0, "local")
sch.reverse_compute_at(write_blk, vec_lp)
b = sch.fuse(*block_lps)
tx_extent = min(int(sch.get(b).extent) & ~int(sch.get(b).extent - 1), 256)
bx, tx = sch.split(b, [None, tx_extent])
sch.bind(bx, "blockIdx.x")
sch.bind(tx, "threadIdx.x")
sch.vectorize(vec_lp)
return True
passed_reduction = False
for blk in blocks:
if sch.get(blk).name_hint == "pad_temp":
schedule_pad(blk)
elif (
sch.get(blk).name_hint == "adaptive_pool_sum"
or sch.get(blk).name_hint == "pool_max"
):
ok = schedule_max_pool(blk)
if not ok:
return None
passed_reduction = True
else:
try:
if passed_reduction:
sch.reverse_compute_inline(blk)
else:
sch.compute_inline(blk)
except Exception: # pylint: disable=broad-except
pass
return sch