mirror of
https://github.com/tile-ai/tilelang.git
synced 2026-10-27 07:32:58 +08:00
* refactor: merge test CI workflow files into one * chore: set `UV_INDEX_STRATEGY=unsafe-best-match` * feat: add AST test with Python 3.8 * feat: implement manual caching mechanism for self-hosted runners * refactor: simplify cache logic for self-hosted runners * chore: clear uv cache on failure * chore: print format.sh output to logs * chore: improve uv caching * chore: disable parallel test * chore: use `PYTHONDEVMODE=1` in CI * feat: enable coredump generation * fix: fix perfbench condition * Revert "feat: enable coredump generation" This reverts commitc52da65cb5. * chore: move example CI down * Revert "chore: move example CI down" This reverts commit9d8e65055e. * chore: skip example `test_example_mha_sink_bwd_bhsd` * chore: skip example `test_example_gqa_sink_bwd_bhsd` * fix: fix example argument passing * fix: loosen test criteria * chore: rename `CMAKE_CONFIGURE_OPTIONS` -> `CLANG_TIDY_CMAKE_OPTIONS` for clarity * feat: enable parallel testings * chore: update pytest options * remove skipped test as now been resolved * chore: empty commit to re-trigger ci * test for n 1 * chore: remove ` --numprocesses=1` option in example * chore: disable failfast * chore: update cibw selection * fix: fix git submodule clone * chore: update cibw commands * fix: fix yapf multiprocessing * chore: setup ccache for CIBW on macOS only * chore: update comments * chore: update artifact listing * fix: do not fail if not found nvcc in PATH * fix: fix flash-attn installation * chore: update dist workflow trigger * chore: remove outdated comments * chore(workflows/dist): simplify build matrix strategy * fix: fix CUDA path finding * fix: fix CUDA path finding * chore: imcrease CI timeout * ci: disable failfast * fix: hide path prefix * chore: more verbose * chore: disable PR trigger for dist workflow * fix: seed for tests * fix: use nightly torch for ROCm tests * chore: enable PR trigger for dist workflow * chore: stop uploading debug wheels as artifacts in PR * chore: do not run workflows in forks * chore: housekeep requirements * chore: use Nightly-ROCm-6.3 for CI * chore: use Nightly-ROCm-6.4 for CI * Update ROCm toolkit version to 7.0 * chore: restore previous rocm-ci.yml for test * fix: cleanup PYTHONPATH * chore: remove previous rocm-ci.yml * ci fix * chore: remove previous rocm-ci.yml * chore: enable parallel example run --------- Co-authored-by: LeiWang1999 <leiwang1999@outlook.com> Co-authored-by: alex_xiao <xinyuxiao2024@gmail.com>
98 lines
3.0 KiB
Python
98 lines
3.0 KiB
Python
import tilelang
|
|
import tilelang.language as T
|
|
import torch
|
|
import itertools
|
|
import argparse
|
|
|
|
|
|
def get_configs():
|
|
iter_params = dict(
|
|
blk_m=[64, 128, 256],
|
|
threads=[128, 256, 512],
|
|
)
|
|
return [dict(zip(iter_params, values)) for values in itertools.product(*iter_params.values())]
|
|
|
|
|
|
@tilelang.autotune(configs=get_configs())
|
|
@tilelang.jit(out_idx=[1, 2])
|
|
def tl_topk(
|
|
M,
|
|
N,
|
|
topk,
|
|
blk_m,
|
|
threads=128,
|
|
):
|
|
dtype = "float32"
|
|
|
|
@T.prim_func
|
|
def topk_kernel(
|
|
logits: T.Tensor([M, N], dtype),
|
|
topk_gates: T.Tensor([M, topk], dtype),
|
|
topk_indices: T.Tensor([M, topk], "int32"),
|
|
):
|
|
with T.Kernel(T.ceildiv(M, blk_m), threads=threads) as bx:
|
|
logits_frag = T.alloc_fragment([blk_m, N], dtype=dtype)
|
|
max_val = T.alloc_fragment([blk_m], dtype=dtype)
|
|
expand_max_idx = T.alloc_fragment([blk_m, N], "int32")
|
|
max_idx = T.alloc_fragment([blk_m], "int32")
|
|
|
|
T.copy(logits[bx * blk_m, 0], logits_frag)
|
|
|
|
for k in T.serial(topk):
|
|
T.fill(expand_max_idx, -1)
|
|
T.reduce_max(logits_frag, max_val, dim=1, clear=True)
|
|
|
|
for i, j in T.Parallel(blk_m, N):
|
|
expand_max_idx[i, j] = T.if_then_else(max_val[i] == logits_frag[i, j], j,
|
|
expand_max_idx[i, j])
|
|
|
|
T.reduce_max(expand_max_idx, max_idx, dim=1, clear=True)
|
|
|
|
for i, j in T.Parallel(blk_m, N):
|
|
|
|
logits_frag[i, j] = T.if_then_else(max_val[i] == logits_frag[i, j], -10000.0,
|
|
logits_frag[i, j])
|
|
|
|
for i in T.Parallel(blk_m):
|
|
topk_gates[bx * blk_m + i, k] = max_val[i]
|
|
topk_indices[bx * blk_m + i, k] = max_idx[i]
|
|
|
|
return topk_kernel
|
|
|
|
|
|
def ref_program(logits, top_k):
|
|
|
|
top_k_gates, top_k_indices = logits.topk(top_k, dim=1)
|
|
|
|
return top_k_gates, top_k_indices.to(torch.int32)
|
|
|
|
|
|
def main(argv=None):
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument("--M", type=int, default=320, help="num_tokens")
|
|
parser.add_argument("--N", type=int, default=128, help="num_experts")
|
|
parser.add_argument("--topk", type=int, default=6, help="topk")
|
|
parser.add_argument("--blk_m", type=int, default=64, help="blk_m")
|
|
args = parser.parse_args(argv)
|
|
M, N, topk, blk_m = args.M, args.N, args.topk, args.blk_m
|
|
|
|
logits = torch.rand((M, N), device="cuda", dtype=torch.float32)
|
|
|
|
kernel = tl_topk(M=M, N=N, topk=topk, blk_m=blk_m)
|
|
tl_gates, tl_indices = kernel(logits)
|
|
|
|
torch_gates, torch_indices = ref_program(logits, topk)
|
|
|
|
# test accuracy
|
|
torch.testing.assert_close(tl_gates, torch_gates)
|
|
torch.testing.assert_close(tl_indices, torch_indices)
|
|
|
|
# profile
|
|
profiler = kernel.get_profiler(tensor_supply_type=tilelang.TensorSupplyType.Auto)
|
|
tilelang_latency = profiler.do_bench()
|
|
print(f"Tilelang latency: {tilelang_latency}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|