-
Notifications
You must be signed in to change notification settings - Fork 3.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[TensorIR][Schedule] New primitive reorder_block_itervar
#14448
Conversation
Thanks for contributing to TVM! Please refer to the contributing guidelines https://tvm.apache.org/docs/contribute/ for useful information and tips. Please request code reviews from Reviewers by @-ing them in a comment.
Generated by tvm-bot |
Is it safe to relax the single subtree constraint of |
transform_block_layout not only change orders of iter vars but also rewrite the outer loops to make sure the evaluation order is consistent with the iter vars, it is okay to relax a bit the constraint but will make analysis for rewriting more difficult |
@wrongtest-intellif Actually, I have tried to change the behavior of |
Thanks! then it looks quite good to me.
Thanks, then it looks quite good to me! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the discussion here! I believe this PR is ready to be merged!
) # Motivation Currently the `reorder` primitive only changes the loops, and block iterable variables order would not be changed. `transform_block_layout` can change the block iterable variables, but it requires the loops outside the given block to have no branches, which limited its usage. This schedule primitive changes the block iterable variable order directly, with API like: ```python def reorder_block_iter_var(self, block: BlockRV, new_order: List[int]) -> None: """Reorder the itervars inside a given block. Parameters ---------- block : BlockRV The block to be transformed. new_order : List[int] The new block itervar order. """ ``` where the `new_order` is a permutation of [0, 1, ..., n-1] if n is the number of itervars in the block. # Example Suppose we need to change the block itervar order in block "C": ```python @T.prim_func def matmul(A: T.Buffer[(128, 128), "float32"], B: T.Buffer[(128, 128), "float32"], C: T.Buffer[(128, 128), "float32"]) -> None: for i, j, k in T.grid(128, 128, 128): with T.block("C"): vi, vj, vk = T.axis.remap("SSR", [i, j, k]) with T.init(): C[vi, vj] = 0.0 C[vi, vj] = C[vi, vj] + A[vi, vk] * B[vj, vk] ``` after applying: ```python sch = tir.Schedule(matmul, debug_mask="all") C = sch.get_block("C") sch.reorder_block_iter_var(C, [2, 1, 0]) ``` the block itervar order would be changed to `vk, vj, vi`. ```python @T.prim_func def matmul_after_reorder_block_iter_var(A: T.Buffer[(128, 128), "float32"], B: T.Buffer[(128, 128), "float32"], C: T.Buffer[(128, 128), "float32"]): for i, j, k in T.grid(128, 128, 128): with T.block("C"): vk, vj, vi = T.axis.remap("RSS", [k, j, i]) T.reads(A[vi, vk], B[vj, vk]) T.writes(C[vi, vj]) with T.init(): C[vi, vj] = T.float32(0) C[vi, vj] = C[vi, vj] + A[vi, vk] * B[vj, vk] ```
) # Motivation Currently the `reorder` primitive only changes the loops, and block iterable variables order would not be changed. `transform_block_layout` can change the block iterable variables, but it requires the loops outside the given block to have no branches, which limited its usage. This schedule primitive changes the block iterable variable order directly, with API like: ```python def reorder_block_iter_var(self, block: BlockRV, new_order: List[int]) -> None: """Reorder the itervars inside a given block. Parameters ---------- block : BlockRV The block to be transformed. new_order : List[int] The new block itervar order. """ ``` where the `new_order` is a permutation of [0, 1, ..., n-1] if n is the number of itervars in the block. # Example Suppose we need to change the block itervar order in block "C": ```python @T.prim_func def matmul(A: T.Buffer[(128, 128), "float32"], B: T.Buffer[(128, 128), "float32"], C: T.Buffer[(128, 128), "float32"]) -> None: for i, j, k in T.grid(128, 128, 128): with T.block("C"): vi, vj, vk = T.axis.remap("SSR", [i, j, k]) with T.init(): C[vi, vj] = 0.0 C[vi, vj] = C[vi, vj] + A[vi, vk] * B[vj, vk] ``` after applying: ```python sch = tir.Schedule(matmul, debug_mask="all") C = sch.get_block("C") sch.reorder_block_iter_var(C, [2, 1, 0]) ``` the block itervar order would be changed to `vk, vj, vi`. ```python @T.prim_func def matmul_after_reorder_block_iter_var(A: T.Buffer[(128, 128), "float32"], B: T.Buffer[(128, 128), "float32"], C: T.Buffer[(128, 128), "float32"]): for i, j, k in T.grid(128, 128, 128): with T.block("C"): vk, vj, vi = T.axis.remap("RSS", [k, j, i]) T.reads(A[vi, vk], B[vj, vk]) T.writes(C[vi, vj]) with T.init(): C[vi, vj] = T.float32(0) C[vi, vj] = C[vi, vj] + A[vi, vk] * B[vj, vk] ```
Motivation
Currently the
reorder
primitive only changes the loops, and block iterable variables order would not be changed.transform_block_layout
can change the block iterable variables, but it requires the loops outside the given block to have no branches, which limited its usage.This schedule primitive changes the block iterable variable order directly, with API like:
where the
new_order
is a permutation of [0, 1, ..., n-1] if n is the number of itervars in the block.Example
Suppose we need to change the block itervar order in block "C":
after applying:
the block itervar order would be changed to
vk, vj, vi
.cc @junrushao @vinx13 @Hzfengsy