diff --git a/auto_tuning.py b/auto_tuning.py index 1e3b459..2c0a17a 100644 --- a/auto_tuning.py +++ b/auto_tuning.py @@ -1,25 +1,25 @@ import tempfile import tvm -from tvm import meta_schedule as ms -from tvm import tir -from tvm.meta_schedule.space_generator import ScheduleFn +from tvm import s_tir +from tvm.s_tir import meta_schedule as ms +from tvm.s_tir.meta_schedule.space_generator import ScheduleFn from evaluate import test_numerical_correctness from gemm_relu_add import gemm_relu_add -def auto_tuning_schedule(sch: tir.Schedule) -> tir.Schedule: +def auto_tuning_schedule(sch: s_tir.Schedule) -> s_tir.Schedule: """The function that defines the schedule space for automatic tuning. Parameters ---------- - sch : tir.Schedule + sch : s_tir.Schedule An empty schedule of the GeMM + ReLU + add workload. Returns ------- - sch : tir.Schedule + sch : s_tir.Schedule The updated schedule of the GeMM + ReLU + add workload. """ diff --git a/evaluate.py b/evaluate.py index 634311d..828ef2e 100644 --- a/evaluate.py +++ b/evaluate.py @@ -2,8 +2,8 @@ import numpy as np import tvm -import tvm.testing -from tvm import tir +from tvm import s_tir +from tvm.runtime import cuda, empty, tensor from gemm_relu_add import K, M, N, manual_schedule from trace_submission import apply_trace @@ -11,11 +11,11 @@ np.random.seed(0) -def build_sch(sch: tir.Schedule) -> tvm.runtime.Module: +def build_sch(sch: s_tir.Schedule) -> tvm.runtime.Module: return tvm.build(sch.mod, target="cuda") -def test_numerical_correctness(sch: tir.Schedule, num_rounds: int = 5): +def test_numerical_correctness(sch: s_tir.Schedule, num_rounds: int = 5): f = build_sch(sch) for i in range(num_rounds): @@ -25,25 +25,25 @@ def test_numerical_correctness(sch: tir.Schedule, num_rounds: int = 5): D_std = np.maximum(A_np @ B_np, 0) + C_np - device = tvm.cuda() - A_tvm = tvm.nd.array(A_np, device) - B_tvm = tvm.nd.array(B_np, device) - C_tvm = tvm.nd.array(C_np, device) - D_tvm = tvm.nd.array(np.zeros((M, N), dtype="float32"), device) + device = cuda() + A_tvm = tensor(A_np, device=device) + B_tvm = tensor(B_np, device=device) + C_tvm = tensor(C_np, device=device) + D_tvm = tensor(np.zeros((M, N), dtype="float32"), device=device) f(A_tvm, B_tvm, C_tvm, D_tvm) - tvm.testing.assert_allclose(D_tvm.numpy(), D_std, rtol=1e-4, atol=1e-4) + np.testing.assert_allclose(D_tvm.numpy(), D_std, rtol=1e-4, atol=1e-4) print(f"Passing test round {i}...") - print(f"Passed all tests.") + print("Passed all tests.") -def evaluate_execution_time(sch: tir.Schedule): +def evaluate_execution_time(sch: s_tir.Schedule): f = build_sch(sch) - device = tvm.cuda() - A_tvm = tvm.nd.empty((M, K), "float32", device) - B_tvm = tvm.nd.empty((K, N), "float32", device) - C_tvm = tvm.nd.empty((M, N), "float32", device) - D_tvm = tvm.nd.empty((M, N), "float32", device) + device = cuda() + A_tvm = empty((M, K), "float32", device) + B_tvm = empty((K, N), "float32", device) + C_tvm = empty((M, N), "float32", device) + D_tvm = empty((M, N), "float32", device) t = f.time_evaluator(f.entry_name, device, number=3, repeat=10, min_repeat_ms=100)( A_tvm, B_tvm, C_tvm, D_tvm @@ -54,27 +54,30 @@ def evaluate_execution_time(sch: tir.Schedule): def evaluate_naive_func_execution_time(): from gemm_relu_add import gemm_relu_add - sch = tir.Schedule(gemm_relu_add) - i, j, _ = sch.get_loops("gemm") + sch = s_tir.Schedule(gemm_relu_add) + gemm_block = sch.get_sblock("gemm") + i, j, _ = sch.get_loops(gemm_block) io, ii = sch.split(i, [None, 32]) jo, ji = sch.split(j, [None, 32]) sch.bind(io, "blockIdx.x") sch.bind(jo, "blockIdx.y") sch.bind(ii, "threadIdx.x") sch.bind(ji, "threadIdx.y") - sch.reverse_compute_at("relu", ji) - sch.reverse_compute_inline("add") - sch.set_scope("gemm", 0, "local") + relu_block = sch.get_sblock("relu") + sch.reverse_compute_at(relu_block, ji) + add_block = sch.get_sblock("add") + sch.reverse_compute_inline(add_block) + sch.set_scope(gemm_block, 0, "local") # Uncomment the line below to check the naive function. # sch.show() f = build_sch(sch) - device = tvm.cuda() - A_tvm = tvm.nd.empty((M, K), "float32", device) - B_tvm = tvm.nd.empty((K, N), "float32", device) - C_tvm = tvm.nd.empty((M, N), "float32", device) - D_tvm = tvm.nd.empty((M, N), "float32", device) + device = cuda() + A_tvm = empty((M, K), "float32", device) + B_tvm = empty((K, N), "float32", device) + C_tvm = empty((M, N), "float32", device) + D_tvm = empty((M, N), "float32", device) t = f.time_evaluator(f.entry_name, device, number=3, repeat=10, min_repeat_ms=100)( A_tvm, B_tvm, C_tvm, D_tvm @@ -82,9 +85,9 @@ def evaluate_naive_func_execution_time(): print("Naive function execution time: %.2f ms" % (t * 1e3)) -def show_cuda(sch: tir.Schedule): +def show_cuda(sch: s_tir.Schedule): f = build_sch(sch) - print(f.imported_modules[0].get_source()) + print(f.imports[0].inspect_source()) if __name__ == "__main__": @@ -105,7 +108,7 @@ def show_cuda(sch: tir.Schedule): if parsed.evaluate_tuned: from gemm_relu_add import gemm_relu_add - sch = tir.Schedule(gemm_relu_add) + sch = s_tir.Schedule(gemm_relu_add) apply_trace(sch) evaluate_execution_time(sch) if parsed.evaluate_naive: diff --git a/gemm_relu_add.py b/gemm_relu_add.py index 17be930..f62b3bb 100644 --- a/gemm_relu_add.py +++ b/gemm_relu_add.py @@ -1,26 +1,26 @@ from typing import Tuple -from tvm import tir -from tvm.script import tir as T -from tvm.tir.schedule import BlockRV +from tvm import s_tir +from tvm.s_tir.schedule import SBlockRV +from tvm.script import tirx as T M = 2048 N = 2048 K = 2048 -@T.prim_func +@T.prim_func(s_tir=True) def gemm_relu_add( A: T.Buffer((M, K), "float32"), B: T.Buffer((K, N), "float32"), C: T.Buffer((M, N), "float32"), D: T.Buffer((M, N), "float32"), ) -> None: - matmul = T.alloc_buffer((M, N), "float32", scope="global") - relu = T.alloc_buffer((M, N), "float32", scope="global") + matmul = T.sblock_alloc_buffer((M, N), "float32", scope="global") + relu = T.sblock_alloc_buffer((M, N), "float32", scope="global") # Compute GeMM for i, j, k in T.grid(M, N, K): - with T.block("gemm"): + with T.sblock("gemm"): vi = T.axis.spatial(M, i) vj = T.axis.spatial(N, j) vk = T.axis.reduce(K, k) @@ -29,25 +29,25 @@ def gemm_relu_add( matmul[vi, vj] += A[vi, vk] * B[vk, vj] # Compute ReLU for i, j in T.grid(M, N): - with T.block("relu"): + with T.sblock("relu"): vi = T.axis.spatial(M, i) vj = T.axis.spatial(N, j) relu[vi, vj] = T.max(matmul[vi, vj], T.float32(0)) # Compute add for i, j in T.grid(M, N): - with T.block("add"): + with T.sblock("add"): vi = T.axis.spatial(M, i) vj = T.axis.spatial(N, j) D[vi, vj] = relu[vi, vj] + C[vi, vj] -def manual_schedule() -> tir.Schedule: +def manual_schedule() -> s_tir.Schedule: """The function that manually schedules and optimizes the GeMM + ReLU + add workload. Returns ------- - sch : tir.Schedule + sch : s_tir.Schedule The schedule of the GeMM + ReLU + add workload. Note @@ -56,7 +56,7 @@ def manual_schedule() -> tir.Schedule: scheduling so far at any time. """ # Create a schedule from the workload. - sch = tir.Schedule(gemm_relu_add) + sch = s_tir.Schedule(gemm_relu_add) # Define the shared memory tile sizes and register tile sizes. tile_x, tile_y, tile_k = 64, 64, 64 thread_tile_x, thread_tile_y, thread_tile_k = 4, 4, 1 @@ -78,13 +78,13 @@ def manual_schedule() -> tir.Schedule: def shared_memory_tiling( - sch: tir.Schedule, tile_x: int, tile_y: int, tile_k: int -) -> Tuple[BlockRV, BlockRV]: + sch: s_tir.Schedule, tile_x: int, tile_y: int, tile_k: int +) -> Tuple[SBlockRV, SBlockRV]: """The implementation of shared memory tiling. Parameters ---------- - sch : tir.Schedule + sch : s_tir.Schedule The schedule instance. tile_x : int @@ -98,11 +98,11 @@ def shared_memory_tiling( Returns ------- - A_shared : tir.schedule.BlockRV + A_shared : SBlockRV The generated shared memory read stage of `A`. It is returned for the cooperative fetching in later tasks. - B_shared : tir.schedule.BlockRV + B_shared : SBlockRV The generated shared memory read stage of `B`. It is returned for the cooperative fetching in later tasks. @@ -112,7 +112,7 @@ def shared_memory_tiling( scheduling so far at any time. - We do not return `sch`, because it is in-place updated during scheduling. """ - block_gemm = sch.get_block("gemm") + block_gemm = sch.get_sblock("gemm") # Fetch the loops outside the "gemm" block. i, j, k = sch.get_loops(block_gemm) @@ -157,7 +157,7 @@ def shared_memory_tiling( def register_tiling( - sch: tir.Schedule, + sch: s_tir.Schedule, thread_tile_x: int, thread_tile_y: int, thread_tile_k: int, @@ -166,7 +166,7 @@ def register_tiling( Parameters ---------- - sch : tir.Schedule + sch : s_tir.Schedule The schedule instance. thread_tile_x : int @@ -184,7 +184,7 @@ def register_tiling( scheduling so far at any time. - We do not return `sch`, because it is in-place updated during scheduling. """ - block_gemm = sch.get_block("gemm") + block_gemm = sch.get_sblock("gemm") # Fetch the last three loops of the "gemm" block, # which are exactly the `i_inner`, `j_inner` and `k_inner` you get # in the last task. @@ -203,9 +203,9 @@ def register_tiling( def cooperative_fetching( - sch: tir.Schedule, - A_shared: BlockRV, - B_shared: BlockRV, + sch: s_tir.Schedule, + A_shared: SBlockRV, + B_shared: SBlockRV, thread_extent_x: int, thread_extent_y: int, ) -> None: @@ -213,13 +213,13 @@ def cooperative_fetching( Parameters ---------- - sch : tir.Schedule + sch : s_tir.Schedule The schedule instance. - A_shared : tir.schedule.BlockRV + A_shared : SBlockRV The shared memory read stage of `A` generated by shared memory tiling. - B_shared : tir.schedule.BlockRV + B_shared : SBlockRV The shared memory read stage of `B` generated by shared memory tiling. thread_extent_x : int @@ -237,7 +237,7 @@ def cooperative_fetching( - We do not return `sch`, because it is in-place updated during scheduling. """ - def _cooperative_fetching_impl(block: BlockRV): + def _cooperative_fetching_impl(block: SBlockRV): # TODO: Fetch the loops of the read stage with `get_loops`. # Think about what loops and how many we want to fetch here? ... @@ -254,12 +254,12 @@ def _cooperative_fetching_impl(block: BlockRV): _cooperative_fetching_impl(B_shared) -def write_cache(sch: tir.Schedule) -> None: +def write_cache(sch: s_tir.Schedule) -> None: """The implementation of write cache. Parameters ---------- - sch : tir.Schedule + sch : s_tir.Schedule The schedule instance. Note @@ -268,7 +268,7 @@ def write_cache(sch: tir.Schedule) -> None: scheduling so far at any time. - We do not return `sch`, because it is in-place updated during scheduling. """ - block_gemm = sch.get_block("gemm") + block_gemm = sch.get_sblock("gemm") # TODO: Use `sch.get_loops` to find out the location of inserting write cache. loop_index = ... write_cache_loc = sch.get_loops(block_gemm)[loop_index] @@ -279,12 +279,12 @@ def write_cache(sch: tir.Schedule) -> None: ... -def epilogue_fusion(sch: tir.Schedule) -> None: +def epilogue_fusion(sch: s_tir.Schedule) -> None: """The implementation of epilogue_fusion. Parameters ---------- - sch : tir.Schedule + sch : s_tir.Schedule The schedule instance. Note @@ -293,7 +293,7 @@ def epilogue_fusion(sch: tir.Schedule) -> None: scheduling so far at any time. - We do not return `sch`, because it is in-place updated during scheduling. """ - # TODO: Use `get_block` to retrieve the addition computation and ReLU computation. + # TODO: Use `get_sblock` to retrieve the addition computation and ReLU computation. ... # TODO: Use `reverse_compute_inline` to fuse addition into ReLU, and fuse ReLU into GeMM. ... diff --git a/mlsys_hw2.ipynb b/mlsys_hw2.ipynb index 4d5eddb..6a6974b 100644 --- a/mlsys_hw2.ipynb +++ b/mlsys_hw2.ipynb @@ -183,26 +183,26 @@ "metadata": {}, "source": [ "```python\n", - "from tvm import tir\n", - "from tvm.script import tir as T\n", + "from tvm import s_tir\n", + "from tvm.script import tirx as T\n", "\n", "M = 2048\n", "N = 2048\n", "K = 2048\n", "\n", "\n", - "@T.prim_func\n", + "@T.prim_func(s_tir=True)\n", "def gemm_relu_add(\n", " A: T.Buffer((M, K), \"float32\"),\n", " B: T.Buffer((K, N), \"float32\"),\n", " C: T.Buffer((M, N), \"float32\"),\n", " D: T.Buffer((M, N), \"float32\"),\n", ") -> None:\n", - " matmul = T.alloc_buffer((M, N), \"float32\", scope=\"global\")\n", - " relu = T.alloc_buffer((M, N), \"float32\", scope=\"global\")\n", + " matmul = T.sblock_alloc_buffer((M, N), \"float32\", scope=\"global\")\n", + " relu = T.sblock_alloc_buffer((M, N), \"float32\", scope=\"global\")\n", " # Compute GeMM\n", " for i, j, k in T.grid(M, N, K):\n", - " with T.block(\"gemm\"):\n", + " with T.sblock(\"gemm\"):\n", " vi = T.axis.spatial(M, i)\n", " vj = T.axis.spatial(N, j)\n", " vk = T.axis.reduce(K, k)\n", @@ -211,19 +211,19 @@ " matmul[vi, vj] += A[vi, vk] * B[vk, vj]\n", " # Compute ReLU\n", " for i, j in T.grid(M, N):\n", - " with T.block(\"relu\"):\n", + " with T.sblock(\"relu\"):\n", " vi = T.axis.spatial(M, i)\n", " vj = T.axis.spatial(N, j)\n", " relu[vi, vj] = T.max(matmul[vi, vj], T.float32(0))\n", " # Compute add\n", " for i, j in T.grid(M, N):\n", - " with T.block(\"add\"):\n", + " with T.sblock(\"add\"):\n", " vi = T.axis.spatial(M, i)\n", " vj = T.axis.spatial(N, j)\n", " D[vi, vj] = relu[vi, vj] + C[vi, vj]\n", "\n", "\n", - "sch = tir.Schedule(gemm_relu_add)\n", + "sch = s_tir.Schedule(gemm_relu_add)\n", "```" ] }, @@ -250,9 +250,9 @@ " * The second one defines the ReLU computation, which element-wisely takes the maximum\n", " of `matmul` and zero.\n", " * The third one describes the element-wise addition of the ReLU result and the input tensor `C`.\n", - "* After defining the function, we create a `tir.Schedule` instance with regard to this function.\n", - "`tir.Schedule` is the core tool in this assignment you will use to optimize this function.\n", - "`tir.Schedule` provides the a set of function transformations (which we call \"schedule primitives\")\n", + "* After defining the function, we create a `s_tir.Schedule` instance with regard to this function.\n", + "`s_tir.Schedule` is the core tool in this assignment you will use to optimize this function.\n", + "`s_tir.Schedule` provides the a set of function transformations (which we call \"schedule primitives\")\n", "that help accelerate the function execution on hardware.\n", "We will introduce these schedule primitives later." ] @@ -391,19 +391,19 @@ "which contain a basic example on how to use the primitive.\n", "We also provide instructions in your TODO area in `gemm_relu_add.py`.\n", "\n", - "- `split` [(docs)](https://tvm.apache.org/docs/reference/api/python/tir/schedule.html#tvm.tir.schedule.Schedule.split)\n", + "- `split` [(docs)](https://tvm.apache.org/docs/reference/api/python/s_tir/schedule.html#tvm.s_tir.schedule.Schedule.split)\n", " - It splits one loop into multiple loops that collectively iterate the iteration space of the original loop.\n", " We use `split` for tiling.\n", - "- `reorder` [(docs)](https://tvm.apache.org/docs/reference/api/python/tir/schedule.html#tvm.tir.schedule.Schedule.reorder)\n", + "- `reorder` [(docs)](https://tvm.apache.org/docs/reference/api/python/s_tir/schedule.html#tvm.s_tir.schedule.Schedule.reorder)\n", " - It reorders the specified contiguous loops into a new order.\n", " We apply `reorder` for loops after splitting for tiling.\n", - "- `bind` [(docs)](https://tvm.apache.org/docs/reference/api/python/tir/schedule.html#tvm.tir.schedule.Schedule.bind)\n", + "- `bind` [(docs)](https://tvm.apache.org/docs/reference/api/python/s_tir/schedule.html#tvm.s_tir.schedule.Schedule.bind)\n", " - It binds a loop to `blockIdx.x/y/z` or `threadIdx.x/y/z` on GPU,\n", " so that we can specify the area to compute of a thread block or a single thread.\n", - "- `cache_read` [(docs)](https://tvm.apache.org/docs/reference/api/python/tir/schedule.html#tvm.tir.schedule.Schedule.cache_read)\n", + "- `cache_read` [(docs)](https://tvm.apache.org/docs/reference/api/python/s_tir/schedule.html#tvm.s_tir.schedule.Schedule.cache_read)\n", " - It generates a cache stage for the specified region in the specified memory scope.\n", " We use `cache_read` to generate the read stages from global memory to shared memory.\n", - "- `compute_at` [(docs)](https://tvm.apache.org/docs/reference/api/python/tir/schedule.html#tvm.tir.schedule.Schedule.compute_at)\n", + "- `compute_at` [(docs)](https://tvm.apache.org/docs/reference/api/python/s_tir/schedule.html#tvm.s_tir.schedule.Schedule.compute_at)\n", " - It moves a computation (e.g., the shared memory read stage) to the location under the specified loop.\n", " We use `compute_at` to move the shared memory read stages to the right location.\n", "\n", @@ -539,7 +539,7 @@ "we can write a common schedule function and apply it to the shared memory read stages\n", "of both `A` and `B`.\n", "The new schedule primitive you will use in this task is\n", - "`fuse` [(docs)](https://tvm.apache.org/docs/reference/api/python/tir/schedule.html#tvm.tir.schedule.Schedule.fuse),\n", + "`fuse` [(docs)](https://tvm.apache.org/docs/reference/api/python/s_tir/schedule.html#tvm.s_tir.schedule.Schedule.fuse),\n", "which, on the contrary to `split`, fuses multiple loops into a single loop." ] }, @@ -574,9 +574,9 @@ "source": [ "You need to implement the write cache in the `write_cache` function in `gemm_relu_add.py`.\n", "In this task, you will use the schedule primitive\n", - "`cache_write` [(docs)](https://tvm.apache.org/docs/reference/api/python/tir/schedule.html#tvm.tir.schedule.Schedule.cache_write)\n", + "`cache_write` [(docs)](https://tvm.apache.org/docs/reference/api/python/s_tir/schedule.html#tvm.s_tir.schedule.Schedule.cache_write)\n", "and\n", - "`reverse_compute_at` [(docs)](https://tvm.apache.org/docs/reference/api/python/tir/schedule.html#tvm.tir.schedule.Schedule.reverse_compute_at)\n", + "`reverse_compute_at` [(docs)](https://tvm.apache.org/docs/reference/api/python/s_tir/schedule.html#tvm.s_tir.schedule.Schedule.reverse_compute_at)\n", "to put the write cache stage at the right location.\n", "Similar to `cache_read` which generates a read cache stage for a computation,\n", "`cache_write` generates a write cache stage for a computation at the specified scope.\n", @@ -618,8 +618,8 @@ "metadata": {}, "source": [ "You need to implement the epilogue fusion in the `epilogue_fusion` function in `gemm_relu_add.py`,\n", - "where you will use `get_block` to retrieve the computation of addition and ReLU,\n", - "and use `reverse_compute_inline` [(docs)](https://tvm.apache.org/docs/reference/api/python/tir/schedule.html#tvm.tir.schedule.Schedule.reverse_compute_inline)\n", + "where you will use `get_sblock` to retrieve the computation of addition and ReLU,\n", + "and use `reverse_compute_inline` [(docs)](https://tvm.apache.org/docs/reference/api/python/s_tir/schedule.html#tvm.s_tir.schedule.Schedule.reverse_compute_inline)\n", "to inline the addition and ReLU into the write-back stage of GeMM." ] }, @@ -843,8 +843,8 @@ "offer better performance.\n", "\n", "If you want to define a search space that goes beyond a single schedule,\n", - "the primitive [`Schedule.sample_perfect_tile`](https://tvm.apache.org/docs/reference/api/python/tir/schedule.html#tvm.tir.schedule.Schedule.sample_perfect_tile)\n", - "in `tir.Schedule` helps you to sample the tile sizes from the specified loop.\n", + "the primitive [`Schedule.sample_perfect_tile`](https://tvm.apache.org/docs/reference/api/python/s_tir/schedule.html#tvm.s_tir.schedule.Schedule.sample_perfect_tile)\n", + "in `s_tir.Schedule` helps you to sample the tile sizes from the specified loop.\n", "For example, for a given schedule `sch`, a given loop `i` with loop length `length`,\n", "```python\n", "tile0, tile1, tile2, tile3 = sch.sample_perfect_tile(i, n=4)\n", @@ -923,9 +923,9 @@ "```\n", "in the end, and a function `apply_trace` printed out:\n", "```python\n", - "# from tvm import tir\n", - "def apply_trace(sch: tir.Schedule) -> None:\n", - " b0 = sch.get_block(name=\"gemm\", func_name=\"main\")\n", + "# from tvm import s_tir\n", + "def apply_trace(sch: s_tir.Schedule) -> None:\n", + " b0 = sch.get_sblock(name=\"gemm\", func_name=\"main\")\n", " # ...\n", "```\n", "\n", @@ -1070,4 +1070,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/schedule_example.ipynb b/schedule_example.ipynb index fe5cde7..692e00c 100644 --- a/schedule_example.ipynb +++ b/schedule_example.ipynb @@ -39,24 +39,25 @@ "outputs": [], "source": [ "import tvm\n", - "from tvm import tir\n", - "from tvm.script import tir as T\n", + "from tvm import s_tir\n", + "from tvm.script import tirx as T\n", + "from tvm.runtime import cuda, empty, tensor\n", "\n", "\n", - "@T.prim_func\n", + "@T.prim_func(s_tir=True)\n", "def sum_broadcast(\n", " A: T.Buffer((256,), \"float32\"),\n", " B: T.Buffer((256,), \"float32\"),\n", ") -> None:\n", " for i, k in T.grid(256, 256):\n", - " with T.block(\"sum_broadcast\"):\n", + " with T.sblock(\"sum_broadcast\"):\n", " vi = T.axis.spatial(256, i)\n", " vk = T.axis.reduce(256, k)\n", " with T.init():\n", " B[vi] = T.float32(0)\n", " B[vi] += A[vk]\n", "\n", - "sch = tir.Schedule(sum_broadcast)" + "sch = s_tir.Schedule(sum_broadcast)" ] }, { @@ -99,7 +100,7 @@ "outputs": [], "source": [ "# Fetch the computation block of \"sum_broadcast\".\n", - "block = sch.get_block(\"sum_broadcast\")\n", + "block = sch.get_sblock(\"sum_broadcast\")\n", "# Fetch the i, j loops of the computation.\n", "i, j = sch.get_loops(block)\n", "# Split i into two loops.\n", @@ -124,23 +125,24 @@ "data": { "text/html": [ "
# from tvm.script import ir as I\n",
-                            "# from tvm.script import tir as T\n",
+                            "# from tvm.script import tirx as T\n",
+                            "# from tvm.tirx.layout import Axis\n",
                             "\n",
-                            "@I.ir_module\n",
-                            "class Module:\n",
-                            "    @T.prim_func\n",
-                            "    def main(A: T.Buffer((256,), "float32"), B: T.Buffer((256,), "float32")):\n",
-                            "        T.func_attr({"global_symbol": "sum_broadcast"})\n",
-                            "        # with T.block("root"):\n",
-                            "        for i_0, i_1, k in T.grid(2, 128, 256):\n",
-                            "            with T.block("sum_broadcast"):\n",
-                            "                vi = T.axis.spatial(256, i_0 * 128 + i_1)\n",
-                            "                vk = T.axis.reduce(256, k)\n",
-                            "                T.reads(A[vk])\n",
-                            "                T.writes(B[vi])\n",
-                            "                with T.init():\n",
-                            "                    B[vi] = T.float32(0)\n",
-                            "                B[vi] = B[vi] + A[vk]\n",
+                            "@I.ir_module\n",
+                            "class Module:\n",
+                            "    @T.prim_func(s_tir=True)\n",
+                            "    def main(A: T.Buffer((256,), "float32"), B: T.Buffer((256,), "float32")):\n",
+                            "        T.func_attr({"global_symbol": "sum_broadcast"})\n",
+                            "        # with T.sblock("root"):\n",
+                            "        for i_0, i_1, k in T.grid(2, 128, 256):\n",
+                            "            with T.sblock("sum_broadcast"):\n",
+                            "                vi = T.axis.spatial(256, i_0 * 128 + i_1)\n",
+                            "                vk = T.axis.reduce(256, k)\n",
+                            "                T.reads(A[vk])\n",
+                            "                T.writes(B[vi])\n",
+                            "                with T.init():\n",
+                            "                    B[vi] = T.float32(0.0)\n",
+                            "                B[vi] = B[vi] + A[vk]\n",
                             "
\n" ], "text/plain": [ @@ -153,11 +155,11 @@ { "data": { "text/html": [ - "
# from tvm import tir\n",
-                            "def apply_trace(sch: tir.Schedule) -> None:\n",
-                            "  b0 = sch.get_block(name="sum_broadcast", func_name="main")\n",
-                            "  l1, l2 = sch.get_loops(block=b0)\n",
-                            "  l3, l4 = sch.split(loop=l1, factors=[2, 128], preserve_unit_iters=True)\n",
+                            "
# from tvm import s_tir\n",
+                            "def apply_trace(sch: s_tir.Schedule) -> None:\n",
+                            "  b0 = sch.get_sblock(name="sum_broadcast", func_name="main")\n",
+                            "  l1, l2 = sch.get_loops(block=b0)\n",
+                            "  l3, l4 = sch.split(loop=l1, factors=[2, 128], preserve_unit_iters=True, disable_predication=False)\n",
                             "
\n" ], "text/plain": [ @@ -188,25 +190,26 @@ "data": { "text/html": [ "
# from tvm.script import ir as I\n",
-                            "# from tvm.script import tir as T\n",
+                            "# from tvm.script import tirx as T\n",
+                            "# from tvm.tirx.layout import Axis\n",
                             "\n",
-                            "@I.ir_module\n",
-                            "class Module:\n",
-                            "    @T.prim_func\n",
-                            "    def main(A: T.Buffer((256,), "float32"), B: T.Buffer((256,), "float32")):\n",
-                            "        T.func_attr({"global_symbol": "sum_broadcast"})\n",
-                            "        # with T.block("root"):\n",
-                            "        for i_0 in T.thread_binding(2, thread="blockIdx.x"):\n",
-                            "            for i_1 in T.thread_binding(128, thread="threadIdx.x"):\n",
+                            "@I.ir_module\n",
+                            "class Module:\n",
+                            "    @T.prim_func(s_tir=True)\n",
+                            "    def main(A: T.Buffer((256,), "float32"), B: T.Buffer((256,), "float32")):\n",
+                            "        T.func_attr({"global_symbol": "sum_broadcast"})\n",
+                            "        # with T.sblock("root"):\n",
+                            "        for i_0 in T.thread_binding(2, thread="blockIdx.x"):\n",
+                            "            for i_1 in T.thread_binding(128, thread="threadIdx.x"):\n",
                             "                for k in range(256):\n",
-                            "                    with T.block("sum_broadcast"):\n",
-                            "                        vi = T.axis.spatial(256, i_0 * 128 + i_1)\n",
-                            "                        vk = T.axis.reduce(256, k)\n",
-                            "                        T.reads(A[vk])\n",
-                            "                        T.writes(B[vi])\n",
-                            "                        with T.init():\n",
-                            "                            B[vi] = T.float32(0)\n",
-                            "                        B[vi] = B[vi] + A[vk]\n",
+                            "                    with T.sblock("sum_broadcast"):\n",
+                            "                        vi = T.axis.spatial(256, i_0 * 128 + i_1)\n",
+                            "                        vk = T.axis.reduce(256, k)\n",
+                            "                        T.reads(A[vk])\n",
+                            "                        T.writes(B[vi])\n",
+                            "                        with T.init():\n",
+                            "                            B[vi] = T.float32(0.0)\n",
+                            "                        B[vi] = B[vi] + A[vk]\n",
                             "
\n" ], "text/plain": [ @@ -219,13 +222,13 @@ { "data": { "text/html": [ - "
# from tvm import tir\n",
-                            "def apply_trace(sch: tir.Schedule) -> None:\n",
-                            "  b0 = sch.get_block(name="sum_broadcast", func_name="main")\n",
-                            "  l1, l2 = sch.get_loops(block=b0)\n",
-                            "  l3, l4 = sch.split(loop=l1, factors=[2, 128], preserve_unit_iters=True)\n",
-                            "  sch.bind(loop=l3, thread_axis="blockIdx.x")\n",
-                            "  sch.bind(loop=l4, thread_axis="threadIdx.x")\n",
+                            "
# from tvm import s_tir\n",
+                            "def apply_trace(sch: s_tir.Schedule) -> None:\n",
+                            "  b0 = sch.get_sblock(name="sum_broadcast", func_name="main")\n",
+                            "  l1, l2 = sch.get_loops(block=b0)\n",
+                            "  l3, l4 = sch.split(loop=l1, factors=[2, 128], preserve_unit_iters=True, disable_predication=False)\n",
+                            "  sch.bind(loop=l3, thread_axis="blockIdx.x")\n",
+                            "  sch.bind(loop=l4, thread_axis="threadIdx.x")\n",
                             "
\n" ], "text/plain": [ @@ -262,6 +265,42 @@ "Test passed.\n", "CUDA source code:\n", "\n", + "#ifdef __CUDACC_RTC__\n", + " #include \n", + " using cuda::std::uint8_t;\n", + " using cuda::std::uint16_t;\n", + " using cuda::std::uint32_t;\n", + " using cuda::std::uint64_t;\n", + " using cuda::std::int8_t;\n", + " using cuda::std::int16_t;\n", + " using cuda::std::int32_t;\n", + " using cuda::std::int64_t;\n", + "\n", + " #include \n", + " namespace std {\n", + " using cuda::std::is_same;\n", + " using cuda::std::is_same_v;\n", + " using cuda::std::is_integral;\n", + " using cuda::std::is_signed;\n", + " using cuda::std::is_unsigned;\n", + " using cuda::std::is_floating_point;\n", + " using cuda::std::enable_if;\n", + " using cuda::std::conditional;\n", + " }\n", + "\n", + " // NVRTC uses asm/volatile instead of __asm__/__volatile__ (gcc extension).\n", + " #ifndef __asm__\n", + " #define __asm__ asm\n", + " #endif\n", + " #ifndef __volatile__\n", + " #define __volatile__ volatile\n", + " #endif\n", + "#else\n", + " #include \n", + " #include \n", + " #include \n", + "#endif\n", + "\n", "#if (((__CUDACC_VER_MAJOR__ == 11) && (__CUDACC_VER_MINOR__ >= 4)) || \\\n", " (__CUDACC_VER_MAJOR__ > 11))\n", "#define TVM_ENABLE_L2_PREFETCH 1\n", @@ -279,16 +318,15 @@ " #define uint unsigned int\n", " #define uchar unsigned char\n", " #define ushort unsigned short\n", - " #define int64_t long long\n", - " #define uint64_t unsigned long long\n", "#endif\n", - "extern \"C\" __global__ void __launch_bounds__(128) sum_broadcast_kernel(float* __restrict__ A, float* __restrict__ B);\n", - "extern \"C\" __global__ void __launch_bounds__(128) sum_broadcast_kernel(float* __restrict__ A, float* __restrict__ B) {\n", + "extern \"C\" __global__ void __launch_bounds__(128) sum_broadcast_kernel(float* __restrict__ A_ptr, float* __restrict__ B_ptr);\n", + "extern \"C\" __global__ void __launch_bounds__(128) sum_broadcast_kernel(float* __restrict__ A_ptr, float* __restrict__ B_ptr) {\n", " for (int k = 0; k < 256; ++k) {\n", + " int cse_v1 = ((((int)blockIdx.x) * 128) + ((int)threadIdx.x));\n", " if (k == 0) {\n", - " B[((((int)blockIdx.x) * 128) + ((int)threadIdx.x))] = 0.000000e+00f;\n", + " B_ptr[((((int)blockIdx.x) * 128) + ((int)threadIdx.x))] = 0x0p+0f/*0.000000e+00*/;\n", " }\n", - " B[((((int)blockIdx.x) * 128) + ((int)threadIdx.x))] = (B[((((int)blockIdx.x) * 128) + ((int)threadIdx.x))] + A[k]);\n", + " B_ptr[((((int)blockIdx.x) * 128) + ((int)threadIdx.x))] = (B_ptr[((((int)blockIdx.x) * 128) + ((int)threadIdx.x))] + A_ptr[k]);\n", " }\n", "}\n", "\n", @@ -297,7 +335,7 @@ } ], "source": [ - "def build_and_test(sch: tir.Schedule) -> None:\n", + "def build_and_test(sch: s_tir.Schedule) -> None:\n", " import numpy as np\n", "\n", " # Build the scheduled function.\n", @@ -308,9 +346,9 @@ " b_np = np.broadcast_to(a_np.sum(keepdims=True), shape=(256,))\n", "\n", " # Run the function we scheduled and built.\n", - " device = tvm.cuda()\n", - " a_tvm = tvm.nd.array(a_np, device=device)\n", - " b_tvm = tvm.nd.empty((256,), \"float32\", device=device)\n", + " device = cuda()\n", + " a_tvm = tensor(a_np, device=device)\n", + " b_tvm = empty((256,), \"float32\", device=device)\n", " f(a_tvm, b_tvm)\n", "\n", " # Validate the result correctness.\n", @@ -318,7 +356,7 @@ " print(\"Test passed.\")\n", "\n", " # Print out the CUDA source code of the function we scheduled.\n", - " print(f\"CUDA source code:\\n{f.imported_modules[0].get_source()}\")\n", + " print(f\"CUDA source code:\\n{f.imports[0].inspect_source()}\")\n", "\n", "\n", "# Run building and testing.\n", @@ -353,32 +391,33 @@ "data": { "text/html": [ "
# from tvm.script import ir as I\n",
-                            "# from tvm.script import tir as T\n",
+                            "# from tvm.script import tirx as T\n",
+                            "# from tvm.tirx.layout import Axis\n",
                             "\n",
-                            "@I.ir_module\n",
-                            "class Module:\n",
-                            "    @T.prim_func\n",
-                            "    def main(A: T.Buffer((256,), "float32"), B: T.Buffer((256,), "float32")):\n",
-                            "        T.func_attr({"global_symbol": "sum_broadcast"})\n",
-                            "        # with T.block("root"):\n",
-                            "        A_shared = T.alloc_buffer((256,), scope="shared")\n",
+                            "@I.ir_module\n",
+                            "class Module:\n",
+                            "    @T.prim_func(s_tir=True)\n",
+                            "    def main(A: T.Buffer((256,), "float32"), B: T.Buffer((256,), "float32")):\n",
+                            "        T.func_attr({"global_symbol": "sum_broadcast"})\n",
+                            "        # with T.sblock("root"):\n",
+                            "        A_shared = T.sblock_alloc_buffer((256,), scope="shared")\n",
                             "        for ax0 in range(256):\n",
-                            "            with T.block("A_shared"):\n",
-                            "                v0 = T.axis.spatial(256, ax0)\n",
-                            "                T.reads(A[v0])\n",
-                            "                T.writes(A_shared[v0])\n",
-                            "                A_shared[v0] = A[v0]\n",
-                            "        for i_0 in T.thread_binding(2, thread="blockIdx.x"):\n",
-                            "            for i_1 in T.thread_binding(128, thread="threadIdx.x"):\n",
+                            "            with T.sblock("A_shared"):\n",
+                            "                v0 = T.axis.spatial(256, ax0)\n",
+                            "                T.reads(A[v0])\n",
+                            "                T.writes(A_shared[v0])\n",
+                            "                A_shared[v0] = A[v0]\n",
+                            "        for i_0 in T.thread_binding(2, thread="blockIdx.x"):\n",
+                            "            for i_1 in T.thread_binding(128, thread="threadIdx.x"):\n",
                             "                for k in range(256):\n",
-                            "                    with T.block("sum_broadcast"):\n",
-                            "                        vi = T.axis.spatial(256, i_0 * 128 + i_1)\n",
-                            "                        vk = T.axis.reduce(256, k)\n",
-                            "                        T.reads(A_shared[vk])\n",
-                            "                        T.writes(B[vi])\n",
-                            "                        with T.init():\n",
-                            "                            B[vi] = T.float32(0)\n",
-                            "                        B[vi] = B[vi] + A_shared[vk]\n",
+                            "                    with T.sblock("sum_broadcast"):\n",
+                            "                        vi = T.axis.spatial(256, i_0 * 128 + i_1)\n",
+                            "                        vk = T.axis.reduce(256, k)\n",
+                            "                        T.reads(A_shared[vk])\n",
+                            "                        T.writes(B[vi])\n",
+                            "                        with T.init():\n",
+                            "                            B[vi] = T.float32(0.0)\n",
+                            "                        B[vi] = B[vi] + A_shared[vk]\n",
                             "
\n" ], "text/plain": [ @@ -391,14 +430,14 @@ { "data": { "text/html": [ - "
# from tvm import tir\n",
-                            "def apply_trace(sch: tir.Schedule) -> None:\n",
-                            "  b0 = sch.get_block(name="sum_broadcast", func_name="main")\n",
-                            "  l1, l2 = sch.get_loops(block=b0)\n",
-                            "  l3, l4 = sch.split(loop=l1, factors=[2, 128], preserve_unit_iters=True)\n",
-                            "  sch.bind(loop=l3, thread_axis="blockIdx.x")\n",
-                            "  sch.bind(loop=l4, thread_axis="threadIdx.x")\n",
-                            "  b5 = sch.cache_read(block=b0, read_buffer_index=0, storage_scope="shared")\n",
+                            "
# from tvm import s_tir\n",
+                            "def apply_trace(sch: s_tir.Schedule) -> None:\n",
+                            "  b0 = sch.get_sblock(name="sum_broadcast", func_name="main")\n",
+                            "  l1, l2 = sch.get_loops(block=b0)\n",
+                            "  l3, l4 = sch.split(loop=l1, factors=[2, 128], preserve_unit_iters=True, disable_predication=False)\n",
+                            "  sch.bind(loop=l3, thread_axis="blockIdx.x")\n",
+                            "  sch.bind(loop=l4, thread_axis="threadIdx.x")\n",
+                            "  b5 = sch.cache_read(block=b0, read_buffer_index=0, storage_scope="shared")\n",
                             "
\n" ], "text/plain": [ @@ -442,32 +481,33 @@ "data": { "text/html": [ "
# from tvm.script import ir as I\n",
-                            "# from tvm.script import tir as T\n",
+                            "# from tvm.script import tirx as T\n",
+                            "# from tvm.tirx.layout import Axis\n",
                             "\n",
-                            "@I.ir_module\n",
-                            "class Module:\n",
-                            "    @T.prim_func\n",
-                            "    def main(A: T.Buffer((256,), "float32"), B: T.Buffer((256,), "float32")):\n",
-                            "        T.func_attr({"global_symbol": "sum_broadcast"})\n",
-                            "        # with T.block("root"):\n",
-                            "        A_shared = T.alloc_buffer((256,), scope="shared")\n",
-                            "        for i_0 in T.thread_binding(2, thread="blockIdx.x"):\n",
-                            "            for i_1 in T.thread_binding(128, thread="threadIdx.x"):\n",
+                            "@I.ir_module\n",
+                            "class Module:\n",
+                            "    @T.prim_func(s_tir=True)\n",
+                            "    def main(A: T.Buffer((256,), "float32"), B: T.Buffer((256,), "float32")):\n",
+                            "        T.func_attr({"global_symbol": "sum_broadcast"})\n",
+                            "        # with T.sblock("root"):\n",
+                            "        A_shared = T.sblock_alloc_buffer((256,), scope="shared")\n",
+                            "        for i_0 in T.thread_binding(2, thread="blockIdx.x"):\n",
+                            "            for i_1 in T.thread_binding(128, thread="threadIdx.x"):\n",
                             "                for ax0 in range(256):\n",
-                            "                    with T.block("A_shared"):\n",
-                            "                        v0 = T.axis.spatial(256, ax0)\n",
-                            "                        T.reads(A[v0])\n",
-                            "                        T.writes(A_shared[v0])\n",
-                            "                        A_shared[v0] = A[v0]\n",
+                            "                    with T.sblock("A_shared"):\n",
+                            "                        v0 = T.axis.spatial(256, ax0)\n",
+                            "                        T.reads(A[v0])\n",
+                            "                        T.writes(A_shared[v0])\n",
+                            "                        A_shared[v0] = A[v0]\n",
                             "                for k in range(256):\n",
-                            "                    with T.block("sum_broadcast"):\n",
-                            "                        vi = T.axis.spatial(256, i_0 * 128 + i_1)\n",
-                            "                        vk = T.axis.reduce(256, k)\n",
-                            "                        T.reads(A_shared[vk])\n",
-                            "                        T.writes(B[vi])\n",
-                            "                        with T.init():\n",
-                            "                            B[vi] = T.float32(0)\n",
-                            "                        B[vi] = B[vi] + A_shared[vk]\n",
+                            "                    with T.sblock("sum_broadcast"):\n",
+                            "                        vi = T.axis.spatial(256, i_0 * 128 + i_1)\n",
+                            "                        vk = T.axis.reduce(256, k)\n",
+                            "                        T.reads(A_shared[vk])\n",
+                            "                        T.writes(B[vi])\n",
+                            "                        with T.init():\n",
+                            "                            B[vi] = T.float32(0.0)\n",
+                            "                        B[vi] = B[vi] + A_shared[vk]\n",
                             "
\n" ], "text/plain": [ @@ -480,15 +520,15 @@ { "data": { "text/html": [ - "
# from tvm import tir\n",
-                            "def apply_trace(sch: tir.Schedule) -> None:\n",
-                            "  b0 = sch.get_block(name="sum_broadcast", func_name="main")\n",
-                            "  l1, l2 = sch.get_loops(block=b0)\n",
-                            "  l3, l4 = sch.split(loop=l1, factors=[2, 128], preserve_unit_iters=True)\n",
-                            "  sch.bind(loop=l3, thread_axis="blockIdx.x")\n",
-                            "  sch.bind(loop=l4, thread_axis="threadIdx.x")\n",
-                            "  b5 = sch.cache_read(block=b0, read_buffer_index=0, storage_scope="shared")\n",
-                            "  sch.compute_at(block=b5, loop=l4, preserve_unit_loops=False, index=-1)\n",
+                            "
# from tvm import s_tir\n",
+                            "def apply_trace(sch: s_tir.Schedule) -> None:\n",
+                            "  b0 = sch.get_sblock(name="sum_broadcast", func_name="main")\n",
+                            "  l1, l2 = sch.get_loops(block=b0)\n",
+                            "  l3, l4 = sch.split(loop=l1, factors=[2, 128], preserve_unit_iters=True, disable_predication=False)\n",
+                            "  sch.bind(loop=l3, thread_axis="blockIdx.x")\n",
+                            "  sch.bind(loop=l4, thread_axis="threadIdx.x")\n",
+                            "  b5 = sch.cache_read(block=b0, read_buffer_index=0, storage_scope="shared")\n",
+                            "  sch.compute_at(block=b5, loop=l4, preserve_unit_loops=False, index=-1)\n",
                             "
\n" ], "text/plain": [ @@ -529,33 +569,34 @@ "data": { "text/html": [ "
# from tvm.script import ir as I\n",
-                            "# from tvm.script import tir as T\n",
+                            "# from tvm.script import tirx as T\n",
+                            "# from tvm.tirx.layout import Axis\n",
                             "\n",
-                            "@I.ir_module\n",
-                            "class Module:\n",
-                            "    @T.prim_func\n",
-                            "    def main(A: T.Buffer((256,), "float32"), B: T.Buffer((256,), "float32")):\n",
-                            "        T.func_attr({"global_symbol": "sum_broadcast"})\n",
-                            "        # with T.block("root"):\n",
-                            "        A_shared = T.alloc_buffer((256,), scope="shared")\n",
-                            "        for i_0 in T.thread_binding(2, thread="blockIdx.x"):\n",
-                            "            for i_1 in T.thread_binding(128, thread="threadIdx.x"):\n",
+                            "@I.ir_module\n",
+                            "class Module:\n",
+                            "    @T.prim_func(s_tir=True)\n",
+                            "    def main(A: T.Buffer((256,), "float32"), B: T.Buffer((256,), "float32")):\n",
+                            "        T.func_attr({"global_symbol": "sum_broadcast"})\n",
+                            "        # with T.sblock("root"):\n",
+                            "        A_shared = T.sblock_alloc_buffer((256,), scope="shared")\n",
+                            "        for i_0 in T.thread_binding(2, thread="blockIdx.x"):\n",
+                            "            for i_1 in T.thread_binding(128, thread="threadIdx.x"):\n",
                             "                for ax0_0 in range(2):\n",
-                            "                    for ax0_1 in T.thread_binding(128, thread="threadIdx.x"):\n",
-                            "                        with T.block("A_shared"):\n",
-                            "                            v0 = T.axis.spatial(256, ax0_0 * 128 + ax0_1)\n",
-                            "                            T.reads(A[v0])\n",
-                            "                            T.writes(A_shared[v0])\n",
-                            "                            A_shared[v0] = A[v0]\n",
+                            "                    for ax0_1 in T.thread_binding(128, thread="threadIdx.x"):\n",
+                            "                        with T.sblock("A_shared"):\n",
+                            "                            v0 = T.axis.spatial(256, ax0_0 * 128 + ax0_1)\n",
+                            "                            T.reads(A[v0])\n",
+                            "                            T.writes(A_shared[v0])\n",
+                            "                            A_shared[v0] = A[v0]\n",
                             "                for k in range(256):\n",
-                            "                    with T.block("sum_broadcast"):\n",
-                            "                        vi = T.axis.spatial(256, i_0 * 128 + i_1)\n",
-                            "                        vk = T.axis.reduce(256, k)\n",
-                            "                        T.reads(A_shared[vk])\n",
-                            "                        T.writes(B[vi])\n",
-                            "                        with T.init():\n",
-                            "                            B[vi] = T.float32(0)\n",
-                            "                        B[vi] = B[vi] + A_shared[vk]\n",
+                            "                    with T.sblock("sum_broadcast"):\n",
+                            "                        vi = T.axis.spatial(256, i_0 * 128 + i_1)\n",
+                            "                        vk = T.axis.reduce(256, k)\n",
+                            "                        T.reads(A_shared[vk])\n",
+                            "                        T.writes(B[vi])\n",
+                            "                        with T.init():\n",
+                            "                            B[vi] = T.float32(0.0)\n",
+                            "                        B[vi] = B[vi] + A_shared[vk]\n",
                             "
\n" ], "text/plain": [ @@ -568,18 +609,18 @@ { "data": { "text/html": [ - "
# from tvm import tir\n",
-                            "def apply_trace(sch: tir.Schedule) -> None:\n",
-                            "  b0 = sch.get_block(name="sum_broadcast", func_name="main")\n",
-                            "  l1, l2 = sch.get_loops(block=b0)\n",
-                            "  l3, l4 = sch.split(loop=l1, factors=[2, 128], preserve_unit_iters=True)\n",
-                            "  sch.bind(loop=l3, thread_axis="blockIdx.x")\n",
-                            "  sch.bind(loop=l4, thread_axis="threadIdx.x")\n",
-                            "  b5 = sch.cache_read(block=b0, read_buffer_index=0, storage_scope="shared")\n",
-                            "  sch.compute_at(block=b5, loop=l4, preserve_unit_loops=False, index=-1)\n",
-                            "  l6, l7, l8 = sch.get_loops(block=b5)\n",
-                            "  l9, l10 = sch.split(loop=l8, factors=[None, 128], preserve_unit_iters=True)\n",
-                            "  sch.bind(loop=l10, thread_axis="threadIdx.x")\n",
+                            "
# from tvm import s_tir\n",
+                            "def apply_trace(sch: s_tir.Schedule) -> None:\n",
+                            "  b0 = sch.get_sblock(name="sum_broadcast", func_name="main")\n",
+                            "  l1, l2 = sch.get_loops(block=b0)\n",
+                            "  l3, l4 = sch.split(loop=l1, factors=[2, 128], preserve_unit_iters=True, disable_predication=False)\n",
+                            "  sch.bind(loop=l3, thread_axis="blockIdx.x")\n",
+                            "  sch.bind(loop=l4, thread_axis="threadIdx.x")\n",
+                            "  b5 = sch.cache_read(block=b0, read_buffer_index=0, storage_scope="shared")\n",
+                            "  sch.compute_at(block=b5, loop=l4, preserve_unit_loops=False, index=-1)\n",
+                            "  l6, l7, l8 = sch.get_loops(block=b5)\n",
+                            "  l9, l10 = sch.split(loop=l8, factors=[None, 128], preserve_unit_iters=True, disable_predication=False)\n",
+                            "  sch.bind(loop=l10, thread_axis="threadIdx.x")\n",
                             "
\n" ], "text/plain": [ @@ -619,6 +660,42 @@ "Test passed.\n", "CUDA source code:\n", "\n", + "#ifdef __CUDACC_RTC__\n", + " #include \n", + " using cuda::std::uint8_t;\n", + " using cuda::std::uint16_t;\n", + " using cuda::std::uint32_t;\n", + " using cuda::std::uint64_t;\n", + " using cuda::std::int8_t;\n", + " using cuda::std::int16_t;\n", + " using cuda::std::int32_t;\n", + " using cuda::std::int64_t;\n", + "\n", + " #include \n", + " namespace std {\n", + " using cuda::std::is_same;\n", + " using cuda::std::is_same_v;\n", + " using cuda::std::is_integral;\n", + " using cuda::std::is_signed;\n", + " using cuda::std::is_unsigned;\n", + " using cuda::std::is_floating_point;\n", + " using cuda::std::enable_if;\n", + " using cuda::std::conditional;\n", + " }\n", + "\n", + " // NVRTC uses asm/volatile instead of __asm__/__volatile__ (gcc extension).\n", + " #ifndef __asm__\n", + " #define __asm__ asm\n", + " #endif\n", + " #ifndef __volatile__\n", + " #define __volatile__ volatile\n", + " #endif\n", + "#else\n", + " #include \n", + " #include \n", + " #include \n", + "#endif\n", + "\n", "#if (((__CUDACC_VER_MAJOR__ == 11) && (__CUDACC_VER_MINOR__ >= 4)) || \\\n", " (__CUDACC_VER_MAJOR__ > 11))\n", "#define TVM_ENABLE_L2_PREFETCH 1\n", @@ -636,21 +713,21 @@ " #define uint unsigned int\n", " #define uchar unsigned char\n", " #define ushort unsigned short\n", - " #define int64_t long long\n", - " #define uint64_t unsigned long long\n", "#endif\n", - "extern \"C\" __global__ void __launch_bounds__(128) sum_broadcast_kernel(float* __restrict__ A, float* __restrict__ B);\n", - "extern \"C\" __global__ void __launch_bounds__(128) sum_broadcast_kernel(float* __restrict__ A, float* __restrict__ B) {\n", - " __shared__ float A_shared[256];\n", + "extern \"C\" __global__ void __launch_bounds__(128) sum_broadcast_kernel(float* __restrict__ A_ptr, float* __restrict__ B_ptr);\n", + "extern \"C\" __global__ void __launch_bounds__(128) sum_broadcast_kernel(float* __restrict__ A_ptr, float* __restrict__ B_ptr) {\n", + " __shared__ alignas(64) float A_ptr_shared[256];\n", " for (int ax0_0 = 0; ax0_0 < 2; ++ax0_0) {\n", - " A_shared[((ax0_0 * 128) + ((int)threadIdx.x))] = A[((ax0_0 * 128) + ((int)threadIdx.x))];\n", + " int cse_v1 = ((ax0_0 * 128) + ((int)threadIdx.x));\n", + " A_ptr_shared[((ax0_0 * 128) + ((int)threadIdx.x))] = A_ptr[((ax0_0 * 128) + ((int)threadIdx.x))];\n", " }\n", " __syncthreads();\n", " for (int k = 0; k < 256; ++k) {\n", + " int cse_v2 = ((((int)blockIdx.x) * 128) + ((int)threadIdx.x));\n", " if (k == 0) {\n", - " B[((((int)blockIdx.x) * 128) + ((int)threadIdx.x))] = 0.000000e+00f;\n", + " B_ptr[((((int)blockIdx.x) * 128) + ((int)threadIdx.x))] = 0x0p+0f/*0.000000e+00*/;\n", " }\n", - " B[((((int)blockIdx.x) * 128) + ((int)threadIdx.x))] = (B[((((int)blockIdx.x) * 128) + ((int)threadIdx.x))] + A_shared[k]);\n", + " B_ptr[((((int)blockIdx.x) * 128) + ((int)threadIdx.x))] = (B_ptr[((((int)blockIdx.x) * 128) + ((int)threadIdx.x))] + A_ptr_shared[k]);\n", " }\n", "}\n", "\n", diff --git a/trace_submission.py b/trace_submission.py index ee1b42f..435f7f8 100644 --- a/trace_submission.py +++ b/trace_submission.py @@ -1,5 +1,5 @@ -from tvm import tir +from tvm import s_tir -def apply_trace(sch: tir.Schedule) -> None: +def apply_trace(sch: s_tir.Schedule) -> None: # Paste your `apply_trace` function here... ...