This is an automated email from the ASF dual-hosted git repository.

junrushao pushed a commit to branch unity
in repository https://gitbox.apache.org/repos/asf/tvm.git


The following commit(s) were added to refs/heads/unity by this push:
     new 51d7128326 [Unity][DLight] Fix Reduction Rule (#15412)
51d7128326 is described below

commit 51d712832600d17dff392de9cf41428c7094e333
Author: Siyuan Feng <[email protected]>
AuthorDate: Thu Jul 27 04:11:56 2023 +0800

    [Unity][DLight] Fix Reduction Rule (#15412)
    
    This PR fixes a correctness issue when the epilogue length is different
    with the `len_tx`.
---
 python/tvm/dlight/gpu/reduction.py        |  3 +-
 tests/python/dlight/test_gpu_reduction.py | 96 +++++++++++++++++++++++++++++--
 2 files changed, 92 insertions(+), 7 deletions(-)

diff --git a/python/tvm/dlight/gpu/reduction.py 
b/python/tvm/dlight/gpu/reduction.py
index 4730d61072..ddc0be3861 100644
--- a/python/tvm/dlight/gpu/reduction.py
+++ b/python/tvm/dlight/gpu/reduction.py
@@ -239,5 +239,6 @@ class Reduction(ScheduleRule):
                 # Thus the remaining spatial part should be bind to tx.
                 sch.set_scope(block, 0, "local")
                 _, *s = sch.get_loops(epilogue)  # pylint: disable=invalid-name
-                sch.bind(sch.fuse(*s), "threadIdx.x")
+                tx, _ = sch.split(sch.fuse(*s), factors=[len_tx, None])
+                sch.bind(tx, "threadIdx.x")
         # pylint: enable=invalid-name
diff --git a/tests/python/dlight/test_gpu_reduction.py 
b/tests/python/dlight/test_gpu_reduction.py
index 35af44a471..6f4c6df25e 100644
--- a/tests/python/dlight/test_gpu_reduction.py
+++ b/tests/python/dlight/test_gpu_reduction.py
@@ -555,12 +555,13 @@ def test_spatial_inner_no_broadcasting():
                             with T.init():
                                 var_matmul_intermediate_local[0, 0, v0] = 
T.float16(0)
                             var_matmul_intermediate_local[0, 0, v0] = 
var_matmul_intermediate_local[0, 0, v0] + 
var_matmul_intermediate_rf_local[vax1_0_fused_1, 0, 0, v0]
-                for ax0_fused in T.thread_binding(16, thread="threadIdx.x"):
-                    with T.block("T_add"):
-                        v0 = T.axis.spatial(4096, ax0_fused_0 * 16 + ax0_fused)
-                        T.reads(lv570[0, 0, v0], 
var_matmul_intermediate_local[0, 0, v0])
-                        T.writes(p_output0_intermediate[0, 0, v0])
-                        p_output0_intermediate[0, 0, v0] = lv570[0, 0, v0] + 
var_matmul_intermediate_local[0, 0, v0]
+                for ax0_fused_0_1 in T.thread_binding(16, 
thread="threadIdx.x"):
+                    for ax0_fused_1 in range(1):
+                        with T.block("T_add"):
+                            v0 = T.axis.spatial(4096, ax0_fused_0 * 16 + 
ax0_fused_0_1 + ax0_fused_1)
+                            T.reads(lv570[0, 0, v0], 
var_matmul_intermediate_local[0, 0, v0])
+                            T.writes(p_output0_intermediate[0, 0, v0])
+                            p_output0_intermediate[0, 0, v0] = lv570[0, 0, v0] 
+ var_matmul_intermediate_local[0, 0, v0]
     # fmt: on
 
     target = Target("nvidia/geforce-rtx-3090-ti")
@@ -711,5 +712,88 @@ def test_reduction_inner_no_broadcasting():
     assert_structural_equal(mod, Expected)
 
 
+def test_reduction_inner_no_broadcasting2():
+
+    # fmt: off
+    @I.ir_module
+    class Module:
+        @T.prim_func
+        def main(lv9: T.Buffer((2560, 320), "uint32"), lv10: T.Buffer((2560, 
80), "float16"), lv1: T.Buffer((1, 2560), "float16"), p_output0_intermediate: 
T.Buffer((1, 2560), "float32")):
+            T.func_attr({"tir.noalias": T.bool(True)})
+            # with T.block("root"):
+            p_output0_intermediate_1 = T.alloc_buffer((2560, 2560), "float16")
+            var_matmul_intermediate = T.alloc_buffer((1, 2560), "float16")
+            for i, j in T.grid(2560, 2560):
+                with T.block("decode"):
+                    v_i, v_j = T.axis.remap("SS", [i, j])
+                    T.reads(lv9[v_i, v_j // 8], lv10[v_i, v_j // 32])
+                    T.writes(p_output0_intermediate_1[v_i, v_j])
+                    p_output0_intermediate_1[v_i, v_j] = (T.Cast("float16", 
T.bitwise_and(T.shift_right(lv9[v_i, v_j // 8], T.Cast("uint32", v_j % 8) * 
T.uint32(4)), T.uint32(15))) - T.float16(7)) * lv10[v_i, v_j // 32]
+            for i0, i1, k in T.grid(1, 2560, 2560):
+                with T.block("matmul"):
+                    v_i0, v_i1, v_k = T.axis.remap("SSR", [i0, i1, k])
+                    T.reads(lv1[v_i0, v_k], p_output0_intermediate_1[v_k, 
v_i1])
+                    T.writes(var_matmul_intermediate[v_i0, v_i1])
+                    with T.init():
+                        var_matmul_intermediate[v_i0, v_i1] = T.float16(0)
+                    var_matmul_intermediate[v_i0, v_i1] = 
var_matmul_intermediate[v_i0, v_i1] + lv1[v_i0, v_k] * 
p_output0_intermediate_1[v_k, v_i1]
+            for i0, i1 in T.grid(1, 2560):
+                with T.block("compute"):
+                    v_i0, v_i1 = T.axis.remap("SS", [i0, i1])
+                    T.reads(var_matmul_intermediate[v_i0, v_i1])
+                    T.writes(p_output0_intermediate[v_i0, v_i1])
+                    p_output0_intermediate[v_i0, v_i1] = T.Cast("float32", 
var_matmul_intermediate[v_i0, v_i1])
+
+    @I.ir_module
+    class Expected:
+        @T.prim_func
+        def main(lv9: T.Buffer((2560, 320), "uint32"), lv10: T.Buffer((2560, 
80), "float16"), lv1: T.Buffer((1, 2560), "float16"), p_output0_intermediate: 
T.Buffer((1, 2560), "float32")):
+            T.func_attr({"tir.is_scheduled": 1, "tir.noalias": T.bool(True)})
+            # with T.block("root"):
+            var_matmul_intermediate_local = T.alloc_buffer((1, 2560), 
"float16", scope="local")
+            var_matmul_intermediate_rf_local = T.alloc_buffer((16, 1, 2560), 
"float16", scope="local")
+            for ax0_0_fused_0 in T.thread_binding(20, thread="blockIdx.x"):
+                for ax0_0_fused_1 in T.thread_binding(16, 
thread="threadIdx.x"):
+                    for ax1_fused_1 in T.thread_binding(16, 
thread="threadIdx.y"):
+                        for ax0_1_init in range(8):
+                            with T.block("matmul_rf_init"):
+                                vax1_fused_1 = T.axis.spatial(16, ax1_fused_1)
+                                v0 = T.axis.spatial(2560, ax0_0_fused_0 * 128 
+ ax0_0_fused_1 * 8 + ax0_1_init)
+                                T.reads()
+                                
T.writes(var_matmul_intermediate_rf_local[vax1_fused_1, 0, v0])
+                                var_matmul_intermediate_rf_local[vax1_fused_1, 
0, v0] = T.float16(0)
+                        for ax1_fused_0, ax0_1 in T.grid(160, 8):
+                            with T.block("matmul_rf_update"):
+                                vax1_fused_1 = T.axis.spatial(16, ax1_fused_1)
+                                v0 = T.axis.spatial(2560, ax0_0_fused_0 * 128 
+ ax0_0_fused_1 * 8 + ax0_1)
+                                vax1_fused_0 = T.axis.reduce(160, ax1_fused_0)
+                                
T.reads(var_matmul_intermediate_rf_local[vax1_fused_1, 0, v0], lv1[0, 
vax1_fused_0 * 16 + vax1_fused_1], lv9[vax1_fused_0 * 16 + vax1_fused_1, v0 // 
8], lv10[vax1_fused_0 * 16 + vax1_fused_1, v0 // 32])
+                                
T.writes(var_matmul_intermediate_rf_local[vax1_fused_1, 0, v0])
+                                var_matmul_intermediate_rf_local[vax1_fused_1, 
0, v0] = var_matmul_intermediate_rf_local[vax1_fused_1, 0, v0] + lv1[0, 
vax1_fused_0 * 16 + vax1_fused_1] * ((T.Cast("float16", 
T.bitwise_and(T.shift_right(lv9[vax1_fused_0 * 16 + vax1_fused_1, v0 // 8], 
T.Cast("uint32", v0 % 8) * T.uint32(4)), T.uint32(15))) - T.float16(7)) * 
lv10[vax1_fused_0 * 16 + vax1_fused_1, v0 // 32])
+                for ax1_fused_0 in T.thread_binding(16, thread="threadIdx.x"):
+                    for ax1_fused_1 in range(8):
+                        for ax0 in T.thread_binding(16, thread="threadIdx.y"):
+                            with T.block("matmul"):
+                                vax1_fused_1 = T.axis.reduce(16, ax0)
+                                v0 = T.axis.spatial(2560, ax0_0_fused_0 * 128 
+ ax1_fused_0 * 8 + ax1_fused_1)
+                                
T.reads(var_matmul_intermediate_rf_local[vax1_fused_1, 0, v0])
+                                T.writes(var_matmul_intermediate_local[0, v0])
+                                with T.init():
+                                    var_matmul_intermediate_local[0, v0] = 
T.float16(0)
+                                var_matmul_intermediate_local[0, v0] = 
var_matmul_intermediate_local[0, v0] + 
var_matmul_intermediate_rf_local[vax1_fused_1, 0, v0]
+                for ax0_fused_0 in T.thread_binding(16, thread="threadIdx.x"):
+                    for ax0_fused_1 in range(8):
+                        with T.block("compute"):
+                            v0 = T.axis.spatial(2560, ax0_0_fused_0 * 128 + 
ax0_fused_0 * 8 + ax0_fused_1)
+                            T.reads(var_matmul_intermediate_local[0, v0])
+                            T.writes(p_output0_intermediate[0, v0])
+                            p_output0_intermediate[0, v0] = T.Cast("float32", 
var_matmul_intermediate_local[0, v0])
+    # fmt: on
+
+    with Target("nvidia/geforce-rtx-3090-ti"):
+        mod = dl.ApplyDefaultSchedule(dl.gpu.Reduction())(Module)  # pylint: 
disable=not-callable
+    assert_structural_equal(mod, Expected)
+
+
 if __name__ == "__main__":
     tvm.testing.main()

Reply via email to