blob: a15bd3d9137be602147b59c2c18bac0768f67b8b [file]
# 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-function-docstring,missing-module-docstring
import pytest
import tvm
import tvm.testing
from tvm import te, tir, topi
from tvm.script import tir as T
from tvm.tir.schedule.testing import (
assert_structural_equal_ignore_global_symbol,
verify_trace_roundtrip,
)
# pylint: disable=no-member,invalid-name,unused-variable,unexpected-keyword-arg
@T.prim_func
def transformed_matmul(a: T.handle, b: T.handle, c: T.handle) -> None:
A = T.match_buffer(a, [128, 128], dtype="float32")
B = T.match_buffer(b, [128, 128], dtype="float32")
C = T.match_buffer(c, [128, 128], dtype="float32")
for i0, i1, i2_outer, i2_inner_outer, i2_inner_inner in T.grid(128, 128, 4, 8, 4):
with T.block("update"):
vi, vj = T.axis.remap("SS", [i0, i1])
vk = T.axis.R(128, i2_outer * 32 + i2_inner_outer * 4 + i2_inner_inner)
T.reads([A[vi, vk], B[vj, vk]])
T.writes([C[vi, vj]])
with T.init():
C[vi, vj] = 0.0
C[vi, vj] = C[vi, vj] + (A[vi, vk] * B[vj, vk])
@T.prim_func
def transformed_matmul_with_let(a: T.handle, b: T.handle, c: T.handle) -> None:
A = T.match_buffer(a, [128, 128], dtype="float32")
B = T.match_buffer(b, [128, 128], dtype="float32")
C = T.match_buffer(c, [128, 128], dtype="float32")
for i0, i1, i2_outer, i2_inner_outer, i2_inner_inner in T.grid(128, 128, 4, 8, 4):
with T.block("update"):
vi, vj = T.axis.remap("SS", [i0, i1])
vk = T.axis.R(128, i2_outer * 32 + i2_inner_outer * 4 + i2_inner_inner)
T.reads([A[vi, vk], B[vj, vk]])
T.writes([C[vi, vj]])
with T.init():
C[vi, vj] = 0.0
v_C: T.float32 = C[vi, vj] + (A[vi, vk] * B[vj, vk])
C[vi, vj] = v_C
@T.prim_func
def matmul_rfactor(a: T.handle, b: T.handle, c: T.handle) -> None:
A = T.match_buffer(a, [128, 128], dtype="float32")
B = T.match_buffer(b, [128, 128], dtype="float32")
C = T.match_buffer(c, [128, 128], dtype="float32")
C_rf = T.alloc_buffer([4, 128, 128], dtype="float32")
for i0, i1, i2_outer, i2_inner_outer, i2_inner_inner in T.grid(128, 128, 4, 8, 4):
with T.block("update_rf"):
vi2_inner_inner = T.axis.S(4, i2_inner_inner)
vi = T.axis.S(128, i0)
vj = T.axis.S(128, i1)
vi2_outer = T.axis.R(4, i2_outer)
vi2_inner_outer = T.axis.R(8, i2_inner_outer)
with T.init():
C_rf[vi2_inner_inner, vi, vj] = 0.0
C_rf[vi2_inner_inner, vi, vj] = C_rf[vi2_inner_inner, vi, vj] + (
A[vi, (((vi2_outer * 32) + (vi2_inner_outer * 4)) + vi2_inner_inner)]
* B[vj, (((vi2_outer * 32) + (vi2_inner_outer * 4)) + vi2_inner_inner)]
)
for i0_1, i1_1, i2_inner_inner_1 in T.grid(128, 128, 4):
with T.block("update"):
vi2_inner_inner_1, vi_1, vj_1 = T.axis.remap("RSS", [i2_inner_inner_1, i0_1, i1_1])
with T.init():
C[vi_1, vj_1] = 0.0
C[vi_1, vj_1] = C[vi_1, vj_1] + C_rf[vi2_inner_inner_1, vi_1, vj_1]
@T.prim_func
def matmul_not_stage_pipeline(a: T.handle, b: T.handle, d: T.handle) -> None:
A = T.match_buffer(a, [256, 256])
B = T.match_buffer(b, [256, 256])
D = T.match_buffer(d, [256, 256])
C = T.alloc_buffer([256, 256])
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[vk, vj]
for i, j in T.grid(256, 256):
with T.block("D"):
vi, vj = T.axis.remap("SS", [i, j])
D[vi, vj] = C[vi, vj]
@T.prim_func
def matmul_not_same_buffer_access(a: T.handle, b: T.handle, c: T.handle) -> None:
A = T.match_buffer(a, (128, 128))
B = T.match_buffer(b, (128, 128))
C = T.match_buffer(c, (128, 128))
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[vj, vi] = C[vj, vi] + A[vi, vk] * B[vk, vj]
@T.prim_func
def matmul_loop_multiple_children(a: T.handle, b: T.handle, c: T.handle, d: T.handle) -> None:
A = T.match_buffer(a, [128, 128])
B = T.match_buffer(b, [128, 128])
C = T.match_buffer(c, [128, 128])
D = T.match_buffer(d, [128, 128])
for k, i, j in T.grid(128, 128, 128):
with T.block("C"):
ck, ci, cj = T.axis.remap("RSS", [k, i, j])
with T.init():
C[ci, cj] = 0.0
C[ci, cj] = C[ci, cj] + A[ci, ck] * B[ck, cj]
with T.block("D"):
dk, di, dj = T.axis.remap("RSS", [k, i, j])
with T.init():
D[di, dj] = 0.0
D[di, dj] = D[di, dj] + B[di, dk] * A[dk, dj]
@T.prim_func
def square_sum(a: T.handle, c: T.handle) -> None:
A = T.match_buffer(a, [16, 256, 256])
C = T.match_buffer(c, [16])
for b0, i0, j0 in T.grid(16, 256, 256):
with T.block("C"):
b, i, j = T.axis.remap("SRR", [b0, i0, j0])
with T.init():
C[b] = 0.0
C[b] = C[b] + A[b, i, j] * A[b, i, j]
@T.prim_func
def square_sum_rfactor(a: T.handle, c: T.handle) -> None:
A = T.match_buffer(a, [16, 256, 256])
C = T.match_buffer(c, [16])
C_rf = T.alloc_buffer([16, 256])
for i0, i1, i2 in T.grid(16, 256, 256):
with T.block("C_rf"):
vi2, b, i = T.axis.remap("SSR", [i2, i0, i1])
with T.init():
C_rf[b, vi2] = 0.0
C_rf[b, vi2] = C_rf[b, vi2] + (A[b, i, vi2] * A[b, i, vi2])
for i0_1, i2_1 in T.grid(16, 256):
with T.block("C"):
vi2_1, b_1 = T.axis.remap("RS", [i2_1, i0_1])
with T.init():
C[b_1] = 0.0
C[b_1] = C[b_1] + C_rf[b_1, vi2_1]
@T.prim_func
def transformed_square_sum_square_root(a: T.handle, d: T.handle) -> None:
A = T.match_buffer(a, [16, 256, 256])
D = T.match_buffer(d, [16])
C = T.alloc_buffer([16])
for i0, i1_i2_fused_outer, i1_i2_fused_inner in T.grid(16, 65536, 1):
with T.block("C"):
b = T.axis.S(16, i0)
i = T.axis.R(256, T.floordiv(i1_i2_fused_outer, 256))
j = T.axis.R(256, T.floormod(i1_i2_fused_outer, 256))
T.reads([A[b, i, j]])
T.writes([C[b]])
with T.init():
C[b] = 0.0
C[b] = C[b] + (A[b, i, j] * A[b, i, j])
for i0_1 in T.serial(0, 16):
with T.block("D"):
b_1 = T.axis.S(16, i0_1)
T.reads([C[b_1]])
T.writes([D[b_1]])
D[b_1] = T.sqrt(C[b_1], dtype="float32")
@T.prim_func
def square_sum_square_root_rfactor(a: T.handle, d: T.handle) -> None:
A = T.match_buffer(a, [16, 256, 256])
D = T.match_buffer(d, [16])
C = T.alloc_buffer([16])
C_rf = T.alloc_buffer([1, 16])
for i0, i1_i2_fused_outer, i1_i2_fused_inner in T.grid(16, 65536, 1):
with T.block("C_rf"):
vi1_i2_fused_inner, b = T.axis.remap("SS", [i1_i2_fused_inner, i0])
i = T.axis.R(256, T.floordiv(i1_i2_fused_outer, 256))
j = T.axis.R(256, T.floormod(i1_i2_fused_outer, 256))
with T.init():
C_rf[vi1_i2_fused_inner, b] = 0.0
C_rf[vi1_i2_fused_inner, b] = C_rf[vi1_i2_fused_inner, b] + (A[b, i, j] * A[b, i, j])
for i0_1, i1_i2_fused_inner_1 in T.grid(16, 1):
with T.block("C"):
vi1_i2_fused_inner_1, b_1 = T.axis.remap("RS", [i1_i2_fused_inner_1, i0_1])
with T.init():
C[b_1] = 0.0
C[b_1] = C[b_1] + C_rf[vi1_i2_fused_inner_1, b_1]
for i0_2 in T.serial(0, 16):
with T.block("D"):
b_2 = T.axis.S(16, i0_2)
D[b_2] = T.sqrt(C[b_2], dtype="float32")
@T.prim_func
def transformed_square_sum_square_root_factor_one_1(a: T.handle, d: T.handle) -> None:
A = T.match_buffer(a, [16, 256, 256])
D = T.match_buffer(d, [16])
C = T.alloc_buffer([16])
for i0, i1_i2_fused_outer, i1_i2_fused_inner in T.grid(16, 65536, 1):
with T.block("C"):
b = T.axis.S(16, i0)
i = T.axis.R(256, T.floordiv(i1_i2_fused_outer, 256))
j = T.axis.R(256, T.floormod(i1_i2_fused_outer, 256))
with T.init():
C[b] = 0.0
C[b] = C[b] + (A[b, i, j] * A[b, i, j])
for i0_1 in T.serial(0, 16):
with T.block("D"):
b_1 = T.axis.S(16, i0_1)
D[b_1] = T.sqrt(C[b_1], dtype="float32")
@T.prim_func
def square_sum_square_root_factor_one_1_rfactor(
A: T.Buffer((16, 256, 256), "float32"), D: T.Buffer((16,), "float32")
) -> None:
C = T.alloc_buffer([16], dtype="float32")
C_rf = T.alloc_buffer([1, 16], dtype="float32")
for i0, i1_i2_fused_outer, i1_i2_fused_inner in T.grid(16, 65536, 1):
with T.block("C_rf"):
b = T.axis.spatial(16, i0)
i = T.axis.reduce(256, i1_i2_fused_outer // 256)
j = T.axis.reduce(256, i1_i2_fused_outer % 256)
vi1_i2_fused_inner = T.axis.spatial(1, i1_i2_fused_inner)
with T.init():
C_rf[vi1_i2_fused_inner, b] = T.float32(0)
C_rf[vi1_i2_fused_inner, b] = C_rf[vi1_i2_fused_inner, b] + A[b, i, j] * A[b, i, j]
for i0, i1_i2_fused_inner in T.grid(16, 1):
with T.block("C"):
b, vi1_i2_fused_inner = T.axis.remap("SR", [i0, i1_i2_fused_inner])
with T.init():
C[b] = T.float32(0)
C[b] = C[b] + C_rf[vi1_i2_fused_inner, b]
for i0_1 in T.serial(16):
with T.block("D"):
b_1 = T.axis.spatial(16, i0_1)
D[b_1] = T.sqrt(C[b_1], dtype="float32")
@T.prim_func
def transformed_square_sum_square_root_factor_one_2(a: T.handle, d: T.handle) -> None:
A = T.match_buffer(a, [16, 256, 256])
D = T.match_buffer(d, [16])
C = T.alloc_buffer([16])
for i0, i1_i2_fused_outer, i1_i2_fused_inner in T.grid(16, 1, 65536):
with T.block("C"):
b = T.axis.S(16, i0)
i = T.axis.R(256, T.floordiv(i1_i2_fused_inner, 256))
j = T.axis.R(256, T.floormod(i1_i2_fused_inner, 256))
with T.init():
C[b] = 0.0
C[b] = C[b] + (A[b, i, j] * A[b, i, j])
for i0_1 in T.serial(0, 16):
with T.block("D"):
b_1 = T.axis.S(16, i0_1)
D[b_1] = T.sqrt(C[b_1], dtype="float32")
@T.prim_func
def square_sum_square_root_factor_one_2_rfactor(
A: T.Buffer((16, 256, 256), "float32"), D: T.Buffer((16,), "float32")
) -> None:
C = T.alloc_buffer([16], dtype="float32")
C_rf = T.alloc_buffer([16, 1], dtype="float32")
for i0, i1_i2_fused_outer, i1_i2_fused_inner in T.grid(16, 1, 65536):
with T.block("C_rf"):
b = T.axis.spatial(16, i0)
i = T.axis.reduce(256, i1_i2_fused_inner // 256)
j = T.axis.reduce(256, i1_i2_fused_inner % 256)
vi1_i2_fused_outer = T.axis.spatial(1, i1_i2_fused_outer)
with T.init():
C_rf[b, vi1_i2_fused_outer] = T.float32(0)
C_rf[b, vi1_i2_fused_outer] = C_rf[b, vi1_i2_fused_outer] + A[b, i, j] * A[b, i, j]
for i0, i1_i2_fused_outer in T.grid(16, 1):
with T.block("C"):
b, vi1_i2_fused_outer = T.axis.remap("SR", [i0, i1_i2_fused_outer])
with T.init():
C[b] = T.float32(0)
C[b] = C[b] + C_rf[b, vi1_i2_fused_outer]
for i0_1 in T.serial(16):
with T.block("D"):
b_1 = T.axis.spatial(16, i0_1)
D[b_1] = T.sqrt(C[b_1], dtype="float32")
@T.prim_func
def square_sum_with_annotation(a: T.handle, c: T.handle) -> None:
A = T.match_buffer(a, [16, 256, 256])
C = T.match_buffer(c, [16])
for b0, i0, j0 in T.grid(16, 256, 256):
with T.block("C"):
T.block_attr({"test_annotation": 1})
b, i, j = T.axis.remap("SRR", [b0, i0, j0])
with T.init():
C[b] = 0.0
C[b] = C[b] + A[b, i, j] * A[b, i, j]
@T.prim_func
def square_sum_with_annotation_rfactor(a: T.handle, c: T.handle) -> None:
A = T.match_buffer(a, [16, 256, 256])
C = T.match_buffer(c, [16])
C_rf = T.alloc_buffer([16, 256])
for i0, i1, i2 in T.grid(16, 256, 256):
with T.block("C_rf"):
T.block_attr({"test_annotation": 1})
vi2, b, i = T.axis.remap("SSR", [i2, i0, i1])
with T.init():
C_rf[b, vi2] = 0.0
C_rf[b, vi2] = C_rf[b, vi2] + (A[b, i, vi2] * A[b, i, vi2])
for i0_1, i2_1 in T.grid(16, 256):
with T.block("C"):
T.block_attr({"test_annotation": 1})
vi2_1, b_1 = T.axis.remap("RS", [i2_1, i0_1])
with T.init():
C[b_1] = 0.0
C[b_1] = C[b_1] + C_rf[b_1, vi2_1]
@T.prim_func
def element_wise(a: T.handle, b: T.handle) -> None:
A = T.match_buffer(a, (128, 128))
B = T.match_buffer(b, (128, 128))
for i, j in T.grid(128, 128):
with T.block("B"):
vi, vj = T.axis.remap("SS", [i, j])
B[vi, vj] = A[vi, vj] * 2.0
@T.prim_func
def rowsum(a: T.handle, b: T.handle) -> None:
A = T.match_buffer(a, (128, 128))
B = T.match_buffer(b, (128,))
for i, k in T.grid(128, 128):
with T.block("B"):
vi, vk = T.axis.remap("SR", [i, k])
with T.init():
B[vi] = 0.0
B[vi] = B[vi] + A[vi, vk]
@T.prim_func
def rowsum_not_quasi_affine(a: T.handle, b: T.handle) -> None:
A = T.match_buffer(a, (128, 128))
B = T.match_buffer(b, (128,))
for i, k in T.grid(128, 16):
with T.block("B"):
vi = T.axis.S(128, i)
vk = T.axis.R(128, T.floordiv(k * k, 2))
with T.init():
B[vi] = 0.0
B[vi] = B[vi] + A[vi, vk]
@T.prim_func
def rowsum_not_dominant(a: T.handle, b: T.handle) -> None:
A = T.match_buffer(a, (128, 128))
B = T.match_buffer(b, (128, 128))
for i, k in T.grid(128, 128):
with T.block("B"):
vi, vk = T.axis.remap("SR", [i, k])
with T.init():
B[vi, vk] = 0.0
B[vi, vk] = B[vi, vk] + A[vi, vk]
@T.prim_func
def rowsum_not_serial(a: T.handle, b: T.handle) -> None:
A = T.match_buffer(a, (128, 128))
B = T.match_buffer(b, (128,))
for i in T.serial(0, 128):
for k in T.parallel(0, 128):
with T.block("B"):
vi, vk = T.axis.remap("SR", [i, k])
with T.init():
B[vi] = 0.0
B[vi] = B[vi] + A[vi, vk]
@T.prim_func
def rowsum_wrong_reduce_pattern1(a: T.handle, b: T.handle) -> None:
A = T.match_buffer(a, (128, 128))
B = T.match_buffer(b, (128,))
for i, k in T.grid(128, 128):
with T.block("B"):
vi, vk = T.axis.remap("SR", [i, k])
with T.init():
B[vi] = 1.0
B[vi] = B[vi] + A[vi, vk]
@T.prim_func
def rowsum_wrong_reduce_pattern2(a: T.handle, b: T.handle) -> None:
A = T.match_buffer(a, (128, 128))
B = T.match_buffer(b, (128,))
for i, k in T.grid(128, 128):
with T.block("B"):
vi, vk = T.axis.remap("SR", [i, k])
with T.init():
B[vi] = 0.0
B[vi] = B[vi] - A[vi, vk]
@T.prim_func
def rowsum_init_not_bufferstore(a: T.handle, b: T.handle) -> None:
A = T.match_buffer(a, (128, 128))
B = T.match_buffer(b, (128,))
for i, k in T.grid(128, 128):
with T.block("B"):
vi, vk = T.axis.remap("SR", [i, k])
with T.init():
v_init: T.float32 = T.float32(0)
B[vi] = v_init
B[vi] = B[vi] + A[vi, vk]
@T.prim_func
def rowsum_transformed(a: T.handle, b: T.handle) -> None:
A = T.match_buffer(a, (128, 128))
B = T.match_buffer(b, (128,))
for io, ii_ko_fused, ki in T.grid(32, 128, 4):
with T.block("B"):
vi = T.axis.S(128, io * 4 + T.floordiv(ii_ko_fused, 32))
vk = T.axis.R(128, T.floormod(ii_ko_fused, 32) * 4 + ki)
with T.init():
B[vi] = 0.0
B[vi] = B[vi] + A[vi, vk]
@T.prim_func
def rowsum_zero_dim(a: T.handle, b: T.handle) -> None:
A = T.match_buffer(a, [128])
B = T.match_buffer(b, [])
for k0 in range(128):
with T.block("B"):
k = T.axis.R(128, k0)
with T.init():
B[()] = 0.0
B[()] = B[()] + A[k]
@T.prim_func
def rowsum_zero_dim_rfactor(a: T.handle, b: T.handle) -> None:
A = T.match_buffer(a, [128])
B = T.match_buffer(b, [])
B_rf = T.alloc_buffer([128], elem_offset=T.int64(0))
for i in range(128):
with T.block("B_rf"):
vi0 = T.axis.S(128, i)
B_rf[vi0] = A[vi0]
for i in range(128):
with T.block("B"):
vi0_1 = T.axis.R(128, i)
with T.init():
B[()] = 0.0
B[()] = B[()] + B_rf[vi0_1]
@T.prim_func
def rowsum_predicate(a: T.handle, b: T.handle) -> None:
A = T.match_buffer(a, [128, 128], dtype="float32")
B = T.match_buffer(b, [128], dtype="float32")
for i, k_0, k_1 in T.grid(128, 13, 10):
with T.block("B"):
T.where(k_0 * 10 + k_1 < 128)
vi = T.axis.S(128, i)
vk = T.axis.R(128, k_0 * 10 + k_1)
with T.init():
B[vi] = 0.0
B[vi] = B[vi] + A[vi, vk]
@T.prim_func
def rowsum_predicate_rfactor(a: T.handle, b: T.handle) -> None:
A = T.match_buffer(a, [128, 128], dtype="float32")
B = T.match_buffer(b, [128], dtype="float32")
B_rf = T.alloc_buffer([128, 13], dtype="float32")
for i, k_0, k_1 in T.grid(128, 13, 10):
with T.block("B_rf"):
vk_0, vi, vk_1 = T.axis.remap("SSR", [k_0, i, k_1])
T.where(k_0 * 10 + k_1 < 128)
with T.init():
B_rf[vi, vk_0] = T.float32(0)
B_rf[vi, vk_0] = B_rf[vi, vk_0] + A[vi, vk_0 * 10 + vk_1]
for i, k_0 in T.grid(128, 13):
with T.block("B"):
vk_0, vi = T.axis.remap("RS", [k_0, i])
with T.init():
B[vi] = T.float32(0)
B[vi] = B[vi] + B_rf[vi, vk_0]
@T.prim_func
def multiple_reduction_blocks(a: T.handle, f: T.handle) -> None:
A = T.match_buffer(a, (16, 16, 16))
C = T.alloc_buffer((16, 16))
D = T.alloc_buffer((16, 16))
E = T.alloc_buffer((16, 16))
F = T.match_buffer(f, (16, 16))
for i in T.serial(0, 16):
for j1 in T.serial(0, 16):
for k1o, k1i in T.grid(4, 4):
with T.block("C"):
ci, cj = T.axis.remap("SS", [i, j1])
ck = T.axis.R(16, k1o * 4 + k1i)
with T.init():
C[ci, cj] = 0.0
C[ci, cj] = C[ci, cj] + A[ci, cj, ck]
for k2o, k2i in T.grid(4, 4):
with T.block("D"):
di, dj = T.axis.remap("SS", [i, j1])
dk = T.axis.R(16, k2o * 4 + k2i)
with T.init():
D[di, dj] = 0.0
D[di, dj] = D[di, dj] + A[di, dj, dk] + C[di, dj]
for j2 in T.serial(0, 16):
for k3o, k3i in T.grid(4, 4):
with T.block("E"):
ei, ej = T.axis.remap("SS", [i, j2])
ek = T.axis.R(16, k3o * 4 + k3i)
with T.init():
E[ei, ej] = 0.0
E[ei, ej] = E[ei, ej] + A[ei, ej, ek] + D[ei, ej]
for k4o, k4i in T.grid(4, 4):
with T.block("F"):
fi, fj = T.axis.remap("SS", [i, j2])
fk = T.axis.R(16, k4o * 4 + k4i)
with T.init():
F[fi, fj] = 0.0
F[fi, fj] = F[fi, fj] + A[fi, fj, fk] + E[fi, fj]
@T.prim_func
def multiple_reduction_blocks_rfactor(a: T.handle, f: T.handle) -> None:
A = T.match_buffer(a, [16, 16, 16])
C = T.alloc_buffer([16, 16])
D = T.alloc_buffer([16, 16])
E = T.alloc_buffer([16, 16])
F = T.match_buffer(f, [16, 16])
C_rf = T.alloc_buffer([16, 16, 4])
for i, j1, k1o, k1i in T.grid(16, 16, 4, 4):
with T.block("C_rf"):
vk1o, ci, cj, vk1i = T.axis.remap("SSSR", [k1o, i, j1, k1i])
with T.init():
C_rf[ci, cj, vk1o] = 0.0
C_rf[ci, cj, vk1o] = C_rf[ci, cj, vk1o] + A[ci, cj, ((vk1o * 4) + vk1i)]
for i_1 in T.serial(0, 16):
for j1_1 in T.serial(0, 16):
for k1o_1 in T.serial(0, 4):
with T.block("C"):
vk1o_1, ci_1, cj_1 = T.axis.remap("RSS", [k1o_1, i_1, j1_1])
with T.init():
C[ci_1, cj_1] = 0.0
C[ci_1, cj_1] = C[ci_1, cj_1] + C_rf[ci_1, cj_1, vk1o_1]
for k2o, k2i in T.grid(4, 4):
with T.block("D"):
di, dj = T.axis.remap("SS", [i_1, j1_1])
dk = T.axis.R(16, k2o * 4 + k2i)
with T.init():
D[di, dj] = 0.0
D[di, dj] = (D[di, dj] + A[di, dj, dk]) + C[di, dj]
for j2 in T.serial(0, 16):
for k3o, k3i in T.grid(4, 4):
with T.block("E"):
ei, ej = T.axis.remap("SS", [i_1, j2])
ek = T.axis.R(16, k3o * 4 + k3i)
with T.init():
E[ei, ej] = 0.0
E[ei, ej] = (E[ei, ej] + A[ei, ej, ek]) + D[ei, ej]
for k4o, k4i in T.grid(4, 4):
with T.block("F"):
fi, fj = T.axis.remap("SS", [i_1, j2])
fk = T.axis.R(16, k4o * 4 + k4i)
with T.init():
F[fi, fj] = 0.0
F[fi, fj] = (F[fi, fj] + A[fi, fj, fk]) + E[fi, fj]
@T.prim_func
def rfactor_spatial_only(
A: T.Buffer((1, 512, 7, 7), "float32"),
B: T.Buffer((1, 512, 1, 1), "float32"),
) -> None:
for _i0, i1, _i2, _i3, i4, _i5 in T.grid(1, 512, 1, 1, 49, 1):
with T.block("acc"):
ax0 = T.axis.spatial(1, 0)
ax1 = T.axis.spatial(512, i1)
ax2 = T.axis.spatial(1, 0)
ax3 = T.axis.spatial(1, 0)
rv0 = T.axis.reduce(7, i4 // 7)
rv1 = T.axis.reduce(7, i4 % 7)
T.reads(A[ax0, ax1, ax2 * 7 + rv0, ax3 * 7 + rv1])
T.writes(B[ax0, ax1, ax2, ax3])
with T.init():
B[ax0, ax1, ax2, ax3] = T.float32(0)
B[ax0, ax1, ax2, ax3] = (
B[ax0, ax1, ax2, ax3] + A[ax0, ax1, ax2 * 7 + rv0, ax3 * 7 + rv1]
)
@T.prim_func
def rfactor_spatial_only_after(
A: T.Buffer((1, 512, 7, 7), "float32"),
B: T.Buffer((1, 512, 1, 1), "float32"),
) -> None:
# body
# with T.block("root")
B_rf = T.alloc_buffer([1, 512, 1, 1, 49], dtype="float32")
for _i0, i1, _i2, _i3, i4, _i5 in T.grid(1, 512, 1, 1, 49, 1):
with T.block("acc_rf"):
vi4 = T.axis.spatial(49, i4)
ax0 = T.axis.spatial(1, 0)
ax1 = T.axis.spatial(512, i1)
ax2 = T.axis.spatial(1, 0)
ax3 = T.axis.spatial(1, 0)
B_rf[ax0, ax1, ax2, ax3, vi4] = A[ax0, ax1, ax2 * 7 + vi4 // 7, ax3 * 7 + vi4 % 7]
for _i0, i1, _i2, _i3, i4, _i5 in T.grid(1, 512, 1, 1, 49, 1):
with T.block("acc"):
vi4 = T.axis.reduce(49, i4)
ax0 = T.axis.spatial(1, 0)
ax1 = T.axis.spatial(512, i1)
ax2 = T.axis.spatial(1, 0)
ax3 = T.axis.spatial(1, 0)
with T.init():
B[ax0, ax1, ax2, ax3] = T.float32(0)
B[ax0, ax1, ax2, ax3] = B[ax0, ax1, ax2, ax3] + B_rf[ax0, ax1, ax2, ax3, vi4]
@T.prim_func
def argmax_split(
idx: T.Buffer((128, 128), "int32"),
val: T.Buffer((128, 128), "float32"),
argmax_v0: T.Buffer((128,), "int32"),
argmax_v1: T.Buffer((128,), "float32"),
) -> None:
for i0, i1_0, i1_1 in T.grid(128, 4, 32):
with T.block("argmax"):
i = T.axis.spatial(128, i0)
k = T.axis.reduce(128, i1_0 * 32 + i1_1)
T.reads(idx[i, k], val[i, k])
T.writes(argmax_v0[i], argmax_v1[i])
with T.init():
argmax_v0[i] = -1
argmax_v1[i] = T.min_value("float32")
v_argmax_v0: T.int32 = T.Select(argmax_v1[i] >= val[i, k], argmax_v0[i], idx[i, k])
v_argmax_v1: T.float32 = T.Select(argmax_v1[i] >= val[i, k], argmax_v1[i], val[i, k])
argmax_v0[i] = v_argmax_v0
argmax_v1[i] = v_argmax_v1
@T.prim_func
def argmin_split_init_update_reordered(
idx: T.Buffer((128, 128), "int32"),
val: T.Buffer((128, 128), "float32"),
argmin_v0: T.Buffer((128,), "int32"),
argmin_v1: T.Buffer((128,), "float32"),
) -> None:
for i0, i1_0, i1_1 in T.grid(128, 4, 32):
with T.block("argmin"):
i = T.axis.spatial(128, i0)
k = T.axis.reduce(128, i1_0 * 32 + i1_1)
T.reads(idx[i, k], val[i, k])
T.writes(argmin_v0[i], argmin_v1[i])
with T.init():
argmin_v1[i] = T.max_value("float32")
argmin_v0[i] = -1
v_argmin_v0: T.int32 = T.Select(argmin_v1[i] <= val[i, k], argmin_v0[i], idx[i, k])
v_argmin_v1: T.float32 = T.Select(argmin_v1[i] <= val[i, k], argmin_v1[i], val[i, k])
argmin_v1[i] = v_argmin_v1
argmin_v0[i] = v_argmin_v0
@T.prim_func
def argmax_split_different_shape(
idx: T.Buffer((128, 128), "int32"),
val: T.Buffer((128, 128), "float32"),
argmax_v0: T.Buffer((256,), "int32"),
argmax_v1: T.Buffer((128,), "float32"),
) -> None:
for i0, i1_0, i1_1 in T.grid(128, 4, 32):
with T.block("argmax"):
i = T.axis.spatial(128, i0)
k = T.axis.reduce(128, i1_0 * 32 + i1_1)
T.reads(idx[i, k], val[i, k])
T.writes(argmax_v0[i], argmax_v1[i])
with T.init():
argmax_v0[i] = -1
argmax_v1[i] = T.min_value("float32")
v_argmax_v0: T.int32 = T.Select(argmax_v1[i] >= val[i, k], argmax_v0[i], idx[i, k])
v_argmax_v1: T.float32 = T.Select(argmax_v1[i] >= val[i, k], argmax_v1[i], val[i, k])
argmax_v0[i] = v_argmax_v0
argmax_v1[i] = v_argmax_v1
@T.prim_func
def argmax_split_different_indices(
idx: T.Buffer((128, 128), "int32"),
val: T.Buffer((128, 128), "float32"),
argmax_v0: T.Buffer((128,), "int32"),
argmax_v1: T.Buffer((128,), "float32"),
) -> None:
for i0, i1_0, i1_1 in T.grid(128, 4, 32):
with T.block("argmax"):
i = T.axis.spatial(128, i0)
k = T.axis.reduce(128, i1_0 * 32 + i1_1)
T.reads(idx[i, k], val[i, k])
T.writes(argmax_v0[i], argmax_v1[i])
with T.init():
argmax_v0[i] = -1
argmax_v1[i + 1] = T.min_value("float32")
v_argmax_v0: T.int32 = T.Select(argmax_v1[i] >= val[i, k], argmax_v0[i], idx[i, k])
v_argmax_v1: T.float32 = T.Select(argmax_v1[i] >= val[i, k], argmax_v1[i], val[i, k])
argmax_v0[i] = v_argmax_v0
argmax_v1[i + 1] = v_argmax_v1
@T.prim_func
def argmax_split_init_not_bufferstore(
idx: T.Buffer((128, 128), "int32"),
val: T.Buffer((128, 128), "float32"),
argmax_v0: T.Buffer((128,), "int32"),
argmax_v1: T.Buffer((128,), "float32"),
) -> None:
for i0, i1_0, i1_1 in T.grid(128, 4, 32):
with T.block("argmax"):
i = T.axis.spatial(128, i0)
k = T.axis.reduce(128, i1_0 * 32 + i1_1)
T.reads(idx[i, k], val[i, k])
T.writes(argmax_v0[i], argmax_v1[i])
with T.init():
argmax_v0[i] = -1
v1_init: T.float32 = T.min_value("float32")
argmax_v1[i] = v1_init
v_argmax_v0: T.int32 = T.Select(argmax_v1[i] >= val[i, k], argmax_v0[i], idx[i, k])
v_argmax_v1: T.float32 = T.Select(argmax_v1[i] >= val[i, k], argmax_v1[i], val[i, k])
argmax_v0[i] = v_argmax_v0
argmax_v1[i] = v_argmax_v1
@T.prim_func
def argmax_split_init_buffer_duplicate(
idx: T.Buffer((128, 128), "int32"),
val: T.Buffer((128, 128), "float32"),
argmax_v0: T.Buffer((128,), "int32"),
argmax_v1: T.Buffer((128,), "float32"),
) -> None:
for i0, i1_0, i1_1 in T.grid(128, 4, 32):
with T.block("argmax"):
i = T.axis.spatial(128, i0)
k = T.axis.reduce(128, i1_0 * 32 + i1_1)
T.reads(idx[i, k], val[i, k])
T.writes(argmax_v0[i], argmax_v1[i])
with T.init():
argmax_v0[i] = -1
argmax_v0[i] = -1
v_argmax_v0: T.int32 = T.Select(argmax_v1[i] >= val[i, k], argmax_v0[i], idx[i, k])
v_argmax_v1: T.float32 = T.Select(argmax_v1[i] >= val[i, k], argmax_v1[i], val[i, k])
argmax_v0[i] = v_argmax_v0
argmax_v1[i] = v_argmax_v1
@T.prim_func
def argmax_split_letstmt_fewer_than_init(
idx: T.Buffer((128, 128), "int32"),
val: T.Buffer((128, 128), "float32"),
argmax_v0: T.Buffer((128,), "int32"),
argmax_v1: T.Buffer((128,), "float32"),
) -> None:
for i0, i1_0, i1_1 in T.grid(128, 4, 32):
with T.block("argmax"):
i = T.axis.spatial(128, i0)
k = T.axis.reduce(128, i1_0 * 32 + i1_1)
T.reads(idx[i, k], val[i, k])
T.writes(argmax_v0[i], argmax_v1[i])
with T.init():
argmax_v0[i] = -1
argmax_v1[i] = T.min_value("float32")
v_argmax_v0: T.int32 = T.Select(argmax_v1[i] >= val[i, k], argmax_v0[i], idx[i, k])
argmax_v0[i] = v_argmax_v0
argmax_v1[i] = T.Select(argmax_v1[i] >= val[i, k], argmax_v1[i], val[i, k])
@T.prim_func
def argmax_split_letstmt_more_than_init(
idx: T.Buffer((128, 128), "int32"),
val: T.Buffer((128, 128), "float32"),
argmax_v0: T.Buffer((128,), "int32"),
argmax_v1: T.Buffer((128,), "float32"),
) -> None:
for i0, i1_0, i1_1 in T.grid(128, 4, 32):
with T.block("argmax"):
i = T.axis.spatial(128, i0)
k = T.axis.reduce(128, i1_0 * 32 + i1_1)
T.reads(idx[i, k], val[i, k])
T.writes(argmax_v0[i], argmax_v1[i])
with T.init():
argmax_v0[i] = -1
v_argmax_v0: T.int32 = T.Select(argmax_v1[i] >= val[i, k], argmax_v0[i], idx[i, k])
v_argmax_v1: T.float32 = T.Select(argmax_v1[i] >= val[i, k], argmax_v1[i], val[i, k])
argmax_v0[i] = v_argmax_v0
argmax_v1[i] = v_argmax_v1
@T.prim_func
def argmax_split_let_body_neither_seqstmt_nor_bufferstore(
idx: T.Buffer((128, 128), "int32"),
val: T.Buffer((128, 128), "float32"),
argmax_v0: T.Buffer((128,), "int32"),
argmax_v1: T.Buffer((128,), "float32"),
) -> None:
for i0, i1_0, i1_1 in T.grid(128, 4, 32):
with T.block("argmax"):
i = T.axis.spatial(128, i0)
k = T.axis.reduce(128, i1_0 * 32 + i1_1)
T.reads(idx[i, k], val[i, k])
T.writes(argmax_v0[i], argmax_v1[i])
with T.init():
argmax_v0[i] = -1
argmax_v1[i] = T.min_value("float32")
v_argmax_v0: T.int32 = T.Select(argmax_v1[i] >= val[i, k], argmax_v0[i], idx[i, k])
v_argmax_v1: T.float32 = T.Select(argmax_v1[i] >= val[i, k], argmax_v1[i], val[i, k])
T.evaluate(0)
@T.prim_func
def argmax_split_init_update_inconsistent_bufferstore_number(
idx: T.Buffer((128, 128), "int32"),
val: T.Buffer((128, 128), "float32"),
argmax_v0: T.Buffer((128,), "int32"),
argmax_v1: T.Buffer((128,), "float32"),
) -> None:
for i0, i1_0, i1_1 in T.grid(128, 4, 32):
with T.block("argmax"):
i = T.axis.spatial(128, i0)
k = T.axis.reduce(128, i1_0 * 32 + i1_1)
T.reads(idx[i, k], val[i, k])
T.writes(argmax_v0[i], argmax_v1[i])
with T.init():
argmax_v0[i] = -1
argmax_v1[i] = T.min_value("float32")
v_argmax_v0: T.int32 = T.Select(argmax_v1[i] >= val[i, k], argmax_v0[i], idx[i, k])
v_argmax_v1: T.float32 = T.Select(argmax_v1[i] >= val[i, k], argmax_v1[i], val[i, k])
argmax_v0[i] = v_argmax_v0
argmax_v1[i] = v_argmax_v1
argmax_v1[i] = v_argmax_v1
@T.prim_func
def argmax_split_body_seq_not_bufferstore(
idx: T.Buffer((128, 128), "int32"),
val: T.Buffer((128, 128), "float32"),
argmax_v0: T.Buffer((128,), "int32"),
argmax_v1: T.Buffer((128,), "float32"),
) -> None:
for i0, i1_0, i1_1 in T.grid(128, 4, 32):
with T.block("argmax"):
i = T.axis.spatial(128, i0)
k = T.axis.reduce(128, i1_0 * 32 + i1_1)
T.reads(idx[i, k], val[i, k])
T.writes(argmax_v0[i], argmax_v1[i])
with T.init():
argmax_v0[i] = -1
argmax_v1[i] = T.min_value("float32")
v_argmax_v0: T.int32 = T.Select(argmax_v1[i] >= val[i, k], argmax_v0[i], idx[i, k])
v_argmax_v1: T.float32 = T.Select(argmax_v1[i] >= val[i, k], argmax_v1[i], val[i, k])
argmax_v0[i] = v_argmax_v0
T.evaluate(0)
@T.prim_func
def argmax_split_body_bufferstore_value_not_var(
idx: T.Buffer((128, 128), "int32"),
val: T.Buffer((128, 128), "float32"),
argmax_v0: T.Buffer((128,), "int32"),
argmax_v1: T.Buffer((128,), "float32"),
) -> None:
for i0, i1_0, i1_1 in T.grid(128, 4, 32):
with T.block("argmax"):
i = T.axis.spatial(128, i0)
k = T.axis.reduce(128, i1_0 * 32 + i1_1)
T.reads(idx[i, k], val[i, k])
T.writes(argmax_v0[i], argmax_v1[i])
with T.init():
argmax_v0[i] = -1
argmax_v1[i] = T.min_value("float32")
v_argmax_v0: T.int32 = T.Select(argmax_v1[i] >= val[i, k], argmax_v0[i], idx[i, k])
v_argmax_v1: T.float32 = T.Select(argmax_v1[i] >= val[i, k], argmax_v1[i], val[i, k])
argmax_v0[i] = T.Select(argmax_v1[i] >= val[i, k], argmax_v0[i], idx[i, k])
argmax_v1[i] = v_argmax_v1
# v_unbound is unbound
@T.prim_func(check_well_formed=False)
def argmax_split_body_bufferstore_value_unbound_var(
idx: T.Buffer((128, 128), "int32"),
val: T.Buffer((128, 128), "float32"),
argmax_v0: T.Buffer((128,), "int32"),
argmax_v1: T.Buffer((128,), "float32"),
) -> None:
v_unbound = T.int32()
for i0, i1_0, i1_1 in T.grid(128, 4, 32):
with T.block("argmax"):
i = T.axis.spatial(128, i0)
k = T.axis.reduce(128, i1_0 * 32 + i1_1)
T.reads(idx[i, k], val[i, k])
T.writes(argmax_v0[i], argmax_v1[i])
with T.init():
argmax_v0[i] = -1
argmax_v1[i] = T.min_value("float32")
v_argmax_v0: T.int32 = T.Select(argmax_v1[i] >= val[i, k], argmax_v0[i], idx[i, k])
v_argmax_v1: T.float32 = T.Select(argmax_v1[i] >= val[i, k], argmax_v1[i], val[i, k])
argmax_v0[i] = v_unbound
argmax_v1[i] = v_argmax_v1
@T.prim_func
def argmax_split_one_let_var_used_multi_times(
idx: T.Buffer((128, 128), "int32"),
val: T.Buffer((128, 128), "int32"),
argmax_v0: T.Buffer((128,), "int32"),
argmax_v1: T.Buffer((128,), "int32"),
) -> None:
for i0, i1_0, i1_1 in T.grid(128, 4, 32):
with T.block("argmax"):
i = T.axis.spatial(128, i0)
k = T.axis.reduce(128, i1_0 * 32 + i1_1)
T.reads(idx[i, k], val[i, k])
T.writes(argmax_v0[i], argmax_v1[i])
with T.init():
argmax_v0[i] = -1
argmax_v1[i] = T.min_value("int32")
v_argmax_v0: T.int32 = T.Select(argmax_v1[i] >= val[i, k], argmax_v0[i], idx[i, k])
v_argmax_v1: T.int32 = T.Select(argmax_v1[i] >= val[i, k], argmax_v1[i], val[i, k])
argmax_v0[i] = v_argmax_v0
argmax_v1[i] = v_argmax_v0
@T.prim_func
def argmax_split_body_one_buffer_updated_multi_times(
idx: T.Buffer((128, 128), "int32"),
val: T.Buffer((128, 128), "int32"),
argmax_v0: T.Buffer((128,), "int32"),
argmax_v1: T.Buffer((128,), "int32"),
) -> None:
for i0, i1_0, i1_1 in T.grid(128, 4, 32):
with T.block("argmax"):
i = T.axis.spatial(128, i0)
k = T.axis.reduce(128, i1_0 * 32 + i1_1)
T.reads(idx[i, k], val[i, k])
T.writes(argmax_v0[i], argmax_v1[i])
with T.init():
argmax_v0[i] = -1
argmax_v1[i] = T.min_value("int32")
v_argmax_v0: T.int32 = T.Select(argmax_v1[i] >= val[i, k], argmax_v0[i], idx[i, k])
v_argmax_v1: T.int32 = T.Select(argmax_v1[i] >= val[i, k], argmax_v1[i], val[i, k])
argmax_v0[i] = v_argmax_v0
argmax_v0[i] = v_argmax_v1
@T.prim_func
def argmax_split_init_buffer_not_match(
idx: T.Buffer((128, 128), "int32"),
val: T.Buffer((128, 128), "float32"),
argmax_v0: T.Buffer((128,), "int32"),
argmax_v0_1: T.Buffer((128,), "int32"),
argmax_v1: T.Buffer((128,), "float32"),
) -> None:
for i0, i1_0, i1_1 in T.grid(128, 4, 32):
with T.block("argmax"):
i = T.axis.spatial(128, i0)
k = T.axis.reduce(128, i1_0 * 32 + i1_1)
T.reads(idx[i, k], val[i, k])
T.writes(argmax_v0[i], argmax_v0_1[i], argmax_v1[i])
with T.init():
argmax_v0_1[i] = -1
argmax_v1[i] = T.min_value("float32")
v_argmax_v0: T.int32 = T.Select(argmax_v1[i] >= val[i, k], argmax_v0[i], idx[i, k])
v_argmax_v1: T.float32 = T.Select(argmax_v1[i] >= val[i, k], argmax_v1[i], val[i, k])
argmax_v0[i] = v_argmax_v0
argmax_v1[i] = v_argmax_v1
@T.prim_func
def argmax_split_rfactor(
idx: T.Buffer((128, 128), "int32"),
val: T.Buffer((128, 128), "float32"),
argmax_v0: T.Buffer((128,), "int32"),
argmax_v1: T.Buffer((128,), "float32"),
) -> None:
argmax_v0_rf = T.alloc_buffer([128, 32], dtype="int32")
argmax_v1_rf = T.alloc_buffer([128, 32], dtype="float32")
for i0, i1_0, i1_1 in T.grid(128, 4, 32):
with T.block("argmax_rf"):
vi1_1, i, vi1_0 = T.axis.remap("SSR", [i1_1, i0, i1_0])
T.reads(idx[i, vi1_0 * 32 + vi1_1], val[i, vi1_0 * 32 + vi1_1])
T.writes(argmax_v0_rf[i, vi1_1], argmax_v1_rf[i, vi1_1])
with T.init():
argmax_v0_rf[i, vi1_1] = -1
argmax_v1_rf[i, vi1_1] = T.min_value("float32")
v_argmax_v0_rf: T.int32 = T.Select(
argmax_v1_rf[i, vi1_1] >= val[i, vi1_0 * 32 + vi1_1],
argmax_v0_rf[i, vi1_1],
idx[i, vi1_0 * 32 + vi1_1],
)
v_argmax_v1_rf: T.float32 = T.Select(
argmax_v1_rf[i, vi1_1] >= val[i, vi1_0 * 32 + vi1_1],
argmax_v1_rf[i, vi1_1],
val[i, vi1_0 * 32 + vi1_1],
)
argmax_v0_rf[i, vi1_1] = v_argmax_v0_rf
argmax_v1_rf[i, vi1_1] = v_argmax_v1_rf
for i0, i1_1 in T.grid(128, 32):
with T.block("argmax"):
vi1_1, i = T.axis.remap("RS", [i1_1, i0])
T.reads(argmax_v0_rf[i, vi1_1], argmax_v1_rf[i, vi1_1])
T.writes(argmax_v0[i], argmax_v1[i])
with T.init():
argmax_v0[i] = -1
argmax_v1[i] = T.min_value("float32")
v_argmax_v0: T.int32 = T.Select(
argmax_v1[i] >= argmax_v1_rf[i, vi1_1], argmax_v0[i], argmax_v0_rf[i, vi1_1]
)
v_argmax_v1: T.float32 = T.Select(
argmax_v1[i] >= argmax_v1_rf[i, vi1_1], argmax_v1[i], argmax_v1_rf[i, vi1_1]
)
argmax_v0[i] = v_argmax_v0
argmax_v1[i] = v_argmax_v1
@T.prim_func
def argmin_split_rfactor(
idx: T.Buffer((128, 128), "int32"),
val: T.Buffer((128, 128), "float32"),
argmin_v0: T.Buffer((128,), "int32"),
argmin_v1: T.Buffer((128,), "float32"),
) -> None:
argmin_v0_rf = T.alloc_buffer([128, 32], dtype="int32")
argmin_v1_rf = T.alloc_buffer([128, 32], dtype="float32")
for i0, i1_0, i1_1 in T.grid(128, 4, 32):
with T.block("argmin_rf"):
vi1_1, i, vi1_0 = T.axis.remap("SSR", [i1_1, i0, i1_0])
T.reads(idx[i, vi1_0 * 32 + vi1_1], val[i, vi1_0 * 32 + vi1_1])
T.writes(argmin_v0_rf[i, vi1_1], argmin_v1_rf[i, vi1_1])
with T.init():
argmin_v0_rf[i, vi1_1] = -1
argmin_v1_rf[i, vi1_1] = T.max_value("float32")
v_argmin_v0_rf: T.int32 = T.Select(
argmin_v1_rf[i, vi1_1] <= val[i, vi1_0 * 32 + vi1_1],
argmin_v0_rf[i, vi1_1],
idx[i, vi1_0 * 32 + vi1_1],
)
v_argmin_v1_rf: T.float32 = T.Select(
argmin_v1_rf[i, vi1_1] <= val[i, vi1_0 * 32 + vi1_1],
argmin_v1_rf[i, vi1_1],
val[i, vi1_0 * 32 + vi1_1],
)
argmin_v0_rf[i, vi1_1] = v_argmin_v0_rf
argmin_v1_rf[i, vi1_1] = v_argmin_v1_rf
for i0, i1_1 in T.grid(128, 32):
with T.block("argmin"):
vi1_1, i = T.axis.remap("RS", [i1_1, i0])
T.reads(argmin_v0_rf[i, vi1_1], argmin_v1_rf[i, vi1_1])
T.writes(argmin_v0[i], argmin_v1[i])
with T.init():
argmin_v0[i] = -1
argmin_v1[i] = T.max_value("float32")
v_argmin_v0: T.int32 = T.Select(
argmin_v1[i] <= argmin_v1_rf[i, vi1_1], argmin_v0[i], argmin_v0_rf[i, vi1_1]
)
v_argmin_v1: T.float32 = T.Select(
argmin_v1[i] <= argmin_v1_rf[i, vi1_1], argmin_v1[i], argmin_v1_rf[i, vi1_1]
)
argmin_v0[i] = v_argmin_v0
argmin_v1[i] = v_argmin_v1
@T.prim_func
def argmax_topi_rfactor(
placeholder: T.Buffer((1, 32), "int32"), placeholder_red: T.Buffer(1, "int32")
) -> None:
T.func_attr({"global_symbol": "main", "tir.noalias": True})
placeholder_red_temp_v0 = T.alloc_buffer([1], dtype="int32")
placeholder_red_temp_v1 = T.alloc_buffer([1], dtype="int32")
placeholder_red_temp_v0_rf = T.alloc_buffer([1, 8], dtype="int32")
placeholder_red_temp_v1_rf = T.alloc_buffer([1, 8], dtype="int32")
for i0, i1_0, i1_1 in T.grid(1, 4, 8):
with T.block("placeholder_red_temp_rf"):
vi1_1, ax0, vi1_0 = T.axis.remap("SSR", [i1_1, i0, i1_0])
T.reads(placeholder[ax0, vi1_0 * 8 + vi1_1])
T.writes(placeholder_red_temp_v0_rf[ax0, vi1_1], placeholder_red_temp_v1_rf[ax0, vi1_1])
with T.init():
placeholder_red_temp_v0_rf[ax0, vi1_1] = -1
placeholder_red_temp_v1_rf[ax0, vi1_1] = -2147483648
v_placeholder_red_temp_v0_rf: T.int32 = T.Select(
placeholder_red_temp_v1_rf[ax0, vi1_1] > placeholder[ax0, vi1_0 * 8 + vi1_1]
or placeholder_red_temp_v1_rf[ax0, vi1_1] == placeholder[ax0, vi1_0 * 8 + vi1_1]
and placeholder_red_temp_v0_rf[ax0, vi1_1] < vi1_0 * 8 + vi1_1,
placeholder_red_temp_v0_rf[ax0, vi1_1],
vi1_0 * 8 + vi1_1,
)
v_placeholder_red_temp_v1_rf: T.int32 = T.Select(
placeholder_red_temp_v1_rf[ax0, vi1_1] > placeholder[ax0, vi1_0 * 8 + vi1_1],
placeholder_red_temp_v1_rf[ax0, vi1_1],
placeholder[ax0, vi1_0 * 8 + vi1_1],
)
placeholder_red_temp_v0_rf[ax0, vi1_1] = v_placeholder_red_temp_v0_rf
placeholder_red_temp_v1_rf[ax0, vi1_1] = v_placeholder_red_temp_v1_rf
for i0, i1_1 in T.grid(1, 8):
with T.block("placeholder_red_temp"):
vi1_1, ax0 = T.axis.remap("RS", [i1_1, i0])
T.reads(placeholder_red_temp_v0_rf[ax0, vi1_1], placeholder_red_temp_v1_rf[ax0, vi1_1])
T.writes(placeholder_red_temp_v0[ax0], placeholder_red_temp_v1[ax0])
with T.init():
placeholder_red_temp_v0[ax0] = -1
placeholder_red_temp_v1[ax0] = -2147483648
v_placeholder_red_temp_v0: T.int32 = T.Select(
placeholder_red_temp_v1[ax0] > placeholder_red_temp_v1_rf[ax0, vi1_1]
or placeholder_red_temp_v1[ax0] == placeholder_red_temp_v1_rf[ax0, vi1_1]
and placeholder_red_temp_v0[ax0] < placeholder_red_temp_v0_rf[ax0, vi1_1],
placeholder_red_temp_v0[ax0],
placeholder_red_temp_v0_rf[ax0, vi1_1],
)
v_placeholder_red_temp_v1: T.int32 = T.Select(
placeholder_red_temp_v1[ax0] > placeholder_red_temp_v1_rf[ax0, vi1_1],
placeholder_red_temp_v1[ax0],
placeholder_red_temp_v1_rf[ax0, vi1_1],
)
placeholder_red_temp_v0[ax0] = v_placeholder_red_temp_v0
placeholder_red_temp_v1[ax0] = v_placeholder_red_temp_v1
for i0 in T.serial(1):
with T.block("placeholder_red"):
ax0 = T.axis.spatial(1, i0)
T.reads(placeholder_red_temp_v0[ax0])
T.writes(placeholder_red[ax0])
placeholder_red[ax0] = placeholder_red_temp_v0[ax0]
@T.prim_func
def argmin_topi_rfactor(
placeholder: T.Buffer((1, 32), "int32"), placeholder_red: T.Buffer(1, "int32")
) -> None:
T.func_attr({"global_symbol": "main", "tir.noalias": True})
placeholder_red_temp_v0 = T.alloc_buffer([1], dtype="int32")
placeholder_red_temp_v1 = T.alloc_buffer([1], dtype="int32")
placeholder_red_temp_v0_rf = T.alloc_buffer([1, 8], dtype="int32")
placeholder_red_temp_v1_rf = T.alloc_buffer([1, 8], dtype="int32")
for i0, i1_0, i1_1 in T.grid(1, 4, 8):
with T.block("placeholder_red_temp_rf"):
vi1_1, ax0, vi1_0 = T.axis.remap("SSR", [i1_1, i0, i1_0])
T.reads(placeholder[ax0, vi1_0 * 8 + vi1_1])
T.writes(placeholder_red_temp_v0_rf[ax0, vi1_1], placeholder_red_temp_v1_rf[ax0, vi1_1])
with T.init():
placeholder_red_temp_v0_rf[ax0, vi1_1] = -1
placeholder_red_temp_v1_rf[ax0, vi1_1] = 2147483647
v_placeholder_red_temp_v0_rf: T.int32 = T.Select(
placeholder_red_temp_v1_rf[ax0, vi1_1] < placeholder[ax0, vi1_0 * 8 + vi1_1]
or placeholder_red_temp_v1_rf[ax0, vi1_1] == placeholder[ax0, vi1_0 * 8 + vi1_1]
and placeholder_red_temp_v0_rf[ax0, vi1_1] < vi1_0 * 8 + vi1_1,
placeholder_red_temp_v0_rf[ax0, vi1_1],
vi1_0 * 8 + vi1_1,
)
v_placeholder_red_temp_v1_rf: T.int32 = T.Select(
placeholder_red_temp_v1_rf[ax0, vi1_1] < placeholder[ax0, vi1_0 * 8 + vi1_1],
placeholder_red_temp_v1_rf[ax0, vi1_1],
placeholder[ax0, vi1_0 * 8 + vi1_1],
)
placeholder_red_temp_v0_rf[ax0, vi1_1] = v_placeholder_red_temp_v0_rf
placeholder_red_temp_v1_rf[ax0, vi1_1] = v_placeholder_red_temp_v1_rf
for i0, i1_1 in T.grid(1, 8):
with T.block("placeholder_red_temp"):
vi1_1, ax0 = T.axis.remap("RS", [i1_1, i0])
T.reads(placeholder_red_temp_v0_rf[ax0, vi1_1], placeholder_red_temp_v1_rf[ax0, vi1_1])
T.writes(placeholder_red_temp_v0[ax0], placeholder_red_temp_v1[ax0])
with T.init():
placeholder_red_temp_v0[ax0] = -1
placeholder_red_temp_v1[ax0] = 2147483647
v_placeholder_red_temp_v0: T.int32 = T.Select(
placeholder_red_temp_v1[ax0] < placeholder_red_temp_v1_rf[ax0, vi1_1]
or placeholder_red_temp_v1[ax0] == placeholder_red_temp_v1_rf[ax0, vi1_1]
and placeholder_red_temp_v0[ax0] < placeholder_red_temp_v0_rf[ax0, vi1_1],
placeholder_red_temp_v0[ax0],
placeholder_red_temp_v0_rf[ax0, vi1_1],
)
v_placeholder_red_temp_v1: T.int32 = T.Select(
placeholder_red_temp_v1[ax0] < placeholder_red_temp_v1_rf[ax0, vi1_1],
placeholder_red_temp_v1[ax0],
placeholder_red_temp_v1_rf[ax0, vi1_1],
)
placeholder_red_temp_v0[ax0] = v_placeholder_red_temp_v0
placeholder_red_temp_v1[ax0] = v_placeholder_red_temp_v1
for i0 in T.serial(1):
with T.block("placeholder_red"):
ax0 = T.axis.spatial(1, i0)
T.reads(placeholder_red_temp_v0[ax0])
T.writes(placeholder_red[ax0])
placeholder_red[ax0] = placeholder_red_temp_v0[ax0]
# pylint: enable=no-member,invalid-name,unused-variable,unexpected-keyword-arg
def test_reduction_rfactor_matmul():
s = tir.Schedule(transformed_matmul, debug_mask="all")
update = s.get_block("update")
_, _, _, _, kii = s.get_loops(update)
rf_block = s.rfactor(kii, 0)
assert_structural_equal_ignore_global_symbol(s.mod["main"], matmul_rfactor)
assert s.get(rf_block).same_as(s.get(s.get_block("update_rf")))
assert s.get(update).same_as(s.get(s.get_block("update")))
verify_trace_roundtrip(s, mod=transformed_matmul)
def test_reduction_rfactor_matmul_with_let():
s = tir.Schedule(transformed_matmul_with_let, debug_mask="all")
update = s.get_block("update")
_, _, _, _, kii = s.get_loops(update)
rf_block = s.rfactor(kii, 0)
assert_structural_equal_ignore_global_symbol(s.mod["main"], matmul_rfactor)
assert s.get(rf_block).same_as(s.get(s.get_block("update_rf")))
assert s.get(update).same_as(s.get(s.get_block("update")))
verify_trace_roundtrip(s, mod=transformed_matmul_with_let)
def test_reduction_rfactor_square_sum():
s = tir.Schedule(square_sum, debug_mask="all")
C = s.get_block("C")
_, _, j = s.get_loops(C)
rf_block = s.rfactor(j, 1)
assert_structural_equal_ignore_global_symbol(s.mod["main"], square_sum_rfactor)
assert s.get(rf_block).same_as(s.get(s.get_block("C_rf")))
assert s.get(C).same_as(s.get(s.get_block("C")))
verify_trace_roundtrip(s, mod=square_sum)
def test_reduction_rfactor_square_sum_square_root():
s = tir.Schedule(transformed_square_sum_square_root, debug_mask="all")
C = s.get_block("C")
_, _, f_i = s.get_loops(C)
rf_block = s.rfactor(f_i, 0)
assert_structural_equal_ignore_global_symbol(s.mod["main"], square_sum_square_root_rfactor)
assert s.get(rf_block).same_as(s.get(s.get_block("C_rf")))
assert s.get(C).same_as(s.get(s.get_block("C")))
verify_trace_roundtrip(s, mod=transformed_square_sum_square_root)
def test_reduction_rfactor_loop_multiple_children():
s = tir.Schedule(matmul_loop_multiple_children, debug_mask="all")
k, _, _ = s.get_loops(s.get_block("C"))
with pytest.raises(tvm.tir.ScheduleError):
s.rfactor(k, 0)
def test_reduction_rfactor_not_stage_pipeline():
s = tir.Schedule(matmul_not_stage_pipeline, debug_mask="all")
_, _, k = s.get_loops(s.get_block("C"))
with pytest.raises(tvm.tir.ScheduleError):
s.rfactor(k, 0)
def test_reduction_rfactor_not_reduction_block1():
s = tir.Schedule(element_wise, debug_mask="all")
i, _ = s.get_loops(s.get_block("B"))
with pytest.raises(tvm.tir.ScheduleError):
s.rfactor(i, 0)
def test_reduction_rfactor_not_reduction_block2():
s = tir.Schedule(rowsum_not_quasi_affine, debug_mask="all")
_, k = s.get_loops(s.get_block("B"))
with pytest.raises(tvm.tir.ScheduleError):
s.rfactor(k, 0)
def test_reduction_rfactor_not_reduction_block3():
s = tir.Schedule(rowsum_not_dominant, debug_mask="all")
_, k = s.get_loops(s.get_block("B"))
with pytest.raises(tvm.tir.ScheduleError):
s.rfactor(k, 0)
def test_reduction_rfactor_not_serial_loop():
s = tir.Schedule(rowsum_not_serial, debug_mask="all")
_, k = s.get_loops(s.get_block("B"))
with pytest.raises(tvm.tir.ScheduleError):
s.rfactor(k, 0)
def test_reduction_rfactor_not_same_buffer_access():
s = tir.Schedule(matmul_not_same_buffer_access, debug_mask="all")
_, _, k = s.get_loops(s.get_block("C"))
with pytest.raises(tvm.tir.ScheduleError):
s.rfactor(k, 0)
def test_reduction_rfactor_factor_axis_range_fail():
s = tir.Schedule(transformed_matmul, debug_mask="all")
_, _, _, _, kii = s.get_loops(s.get_block("update"))
with pytest.raises(tvm.tir.ScheduleError):
s.rfactor(kii, 3)
with pytest.raises(tvm.tir.ScheduleError):
s.rfactor(kii, -4)
def test_reduction_rfactor_factor_axis_range():
s = tir.Schedule(transformed_matmul, debug_mask="all")
update = s.get_block("update")
_, _, _, _, kii = s.get_loops(update)
rf_block = s.rfactor(kii, -3)
assert_structural_equal_ignore_global_symbol(s.mod["main"], matmul_rfactor)
assert s.get(rf_block).same_as(s.get(s.get_block("update_rf")))
assert s.get(update).same_as(s.get(s.get_block("update")))
verify_trace_roundtrip(s, mod=transformed_matmul)
def test_reduction_rfactor_wrong_reduce_pattern1():
s = tir.Schedule(rowsum_wrong_reduce_pattern1, debug_mask="all")
_, k = s.get_loops(s.get_block("B"))
with pytest.raises(tvm.tir.ScheduleError):
s.rfactor(k, 0)
def test_reduction_rfactor_wrong_reduce_pattern2():
s = tir.Schedule(rowsum_wrong_reduce_pattern2, debug_mask="all")
_, k = s.get_loops(s.get_block("B"))
with pytest.raises(tvm.tir.ScheduleError):
s.rfactor(k, 0)
def test_reduction_rfactor_init_not_bufferstore():
s = tir.Schedule(rowsum_init_not_bufferstore, debug_mask="all")
_, k = s.get_loops(s.get_block("B"))
with pytest.raises(tvm.tir.ScheduleError):
s.rfactor(k, 0)
def test_reduction_rfactor_wrong_loops1():
s = tir.Schedule(rowsum, debug_mask="all")
i, _ = s.get_loops(s.get_block("B"))
with pytest.raises(tvm.tir.ScheduleError):
s.rfactor(i, 0)
def test_reduction_rfactor_wrong_loops2():
s = tir.Schedule(rowsum_transformed, debug_mask="all")
_, _, k_i = s.get_loops(s.get_block("B"))
with pytest.raises(tvm.tir.ScheduleError):
s.rfactor(k_i, 0)
def test_reduction_rfactor_zero_dim():
s = tir.Schedule(rowsum_zero_dim, debug_mask="all")
B = s.get_block("B")
(k,) = s.get_loops(B)
rf_block = s.rfactor(k, 0)
assert_structural_equal_ignore_global_symbol(s.mod["main"], rowsum_zero_dim_rfactor)
assert s.get(rf_block).same_as(s.get(s.get_block("B_rf")))
assert s.get(B).same_as(s.get(s.get_block("B")))
verify_trace_roundtrip(s, mod=rowsum_zero_dim)
def test_reduction_rfactor_outermost_loop_multiple_children_fail(): # pylint: disable=invalid-name
s = tir.Schedule(multiple_reduction_blocks, debug_mask="all")
_, _, k2o, k2i = s.get_loops(s.get_block("D"))
_, _, k3o, k3i = s.get_loops(s.get_block("E"))
_, _, k4o, k4i = s.get_loops(s.get_block("F"))
with pytest.raises(tvm.tir.ScheduleError):
s.rfactor(k2o, 0)
with pytest.raises(tvm.tir.ScheduleError):
s.rfactor(k2i, 0)
with pytest.raises(tvm.tir.ScheduleError):
s.rfactor(k3o, 0)
with pytest.raises(tvm.tir.ScheduleError):
s.rfactor(k3i, 0)
with pytest.raises(tvm.tir.ScheduleError):
s.rfactor(k4o, 0)
with pytest.raises(tvm.tir.ScheduleError):
s.rfactor(k4i, 0)
def test_reduction_rfactor_outermost_loop_multiple_children(): # pylint: disable=invalid-name
s = tir.Schedule(multiple_reduction_blocks, debug_mask="all")
C = s.get_block("C")
_, _, k1o, _ = s.get_loops(C)
rf_block = s.rfactor(k1o, 2)
assert_structural_equal_ignore_global_symbol(s.mod["main"], multiple_reduction_blocks_rfactor)
assert s.get(rf_block).same_as(s.get(s.get_block("C_rf")))
assert s.get(C).same_as(s.get(s.get_block("C")))
verify_trace_roundtrip(s, mod=multiple_reduction_blocks)
def test_reduction_rfactor_predicate(): # pylint: disable=invalid-name
s = tir.Schedule(rowsum_predicate, debug_mask="all")
B = s.get_block("B")
_, ko, _ = s.get_loops(B)
# TODO: should be a tvm.tir.ScheduleError
with pytest.raises(tvm.TVMError):
rf_block = s.rfactor(ko, 1)
def test_reduction_rfactor_with_annotation():
s = tir.Schedule(square_sum_with_annotation, debug_mask="all")
C = s.get_block("C")
_, _, j = s.get_loops(C)
rf_block = s.rfactor(j, 1)
assert_structural_equal_ignore_global_symbol(s.mod["main"], square_sum_with_annotation_rfactor)
assert s.get(rf_block).same_as(s.get(s.get_block("C_rf")))
assert s.get(C).same_as(s.get(s.get_block("C")))
verify_trace_roundtrip(s, mod=square_sum_with_annotation)
def test_reduction_rfactor_spatial_only():
s = tir.Schedule(rfactor_spatial_only, debug_mask="all")
block = s.get_block(name="acc", func_name="main")
_, _, _, _, loop, _ = s.get_loops(block)
rf_block = s.rfactor(loop=loop, factor_axis=4)
assert_structural_equal_ignore_global_symbol(s.mod["main"], rfactor_spatial_only_after)
assert s.get(rf_block).same_as(s.get(s.get_block("acc_rf")))
assert s.get(block).same_as(s.get(s.get_block("acc")))
verify_trace_roundtrip(s, mod=rfactor_spatial_only)
def test_reduction_rfactor_argmax():
s = tir.Schedule(argmax_split, debug_mask="all")
argmax = s.get_block("argmax")
_, _, ki = s.get_loops(argmax)
rf_block = s.rfactor(ki, 1)
assert_structural_equal_ignore_global_symbol(s.mod["main"], argmax_split_rfactor)
assert s.get(rf_block).same_as(s.get(s.get_block("argmax_rf")))
assert s.get(argmax).same_as(s.get(s.get_block("argmax")))
verify_trace_roundtrip(s, mod=argmax_split)
def test_reduction_rfactor_argmin_init_update_reordeded():
s = tir.Schedule(argmin_split_init_update_reordered, debug_mask="all")
argmin = s.get_block("argmin")
_, _, ki = s.get_loops(argmin)
rf_block = s.rfactor(ki, 1)
assert_structural_equal_ignore_global_symbol(s.mod["main"], argmin_split_rfactor)
assert s.get(rf_block).same_as(s.get(s.get_block("argmin_rf")))
assert s.get(argmin).same_as(s.get(s.get_block("argmin")))
verify_trace_roundtrip(s, mod=argmin_split_init_update_reordered)
def test_reduction_rfactor_argmax_reduction_buffer_different_shape():
s = tir.Schedule(argmax_split_different_shape, debug_mask="all")
argmax = s.get_block("argmax")
_, _, ki = s.get_loops(argmax)
with pytest.raises(tvm.tir.ScheduleError):
s.rfactor(ki, 1)
def test_reduction_rfactor_argmax_different_access_indices():
s = tir.Schedule(argmax_split_different_indices, debug_mask="all")
argmax = s.get_block("argmax")
_, _, ki = s.get_loops(argmax)
with pytest.raises(tvm.tir.ScheduleError):
s.rfactor(ki, 1)
def test_reduction_rfactor_argmax_init_not_bufferstore():
s = tir.Schedule(argmax_split_init_not_bufferstore, debug_mask="all")
argmax = s.get_block("argmax")
_, _, ki = s.get_loops(argmax)
with pytest.raises(tvm.tir.ScheduleError):
s.rfactor(ki, 1)
def test_reduction_rfactor_argmax_init_buffer_duplicate():
s = tir.Schedule(argmax_split_init_buffer_duplicate, debug_mask="all")
argmax = s.get_block("argmax")
_, _, ki = s.get_loops(argmax)
with pytest.raises(tvm.tir.ScheduleError):
s.rfactor(ki, 1)
def test_reduction_rfactor_argmax_letstmt_fewer_than_init():
s = tir.Schedule(argmax_split_letstmt_fewer_than_init, debug_mask="all")
argmax = s.get_block("argmax")
_, _, ki = s.get_loops(argmax)
with pytest.raises(tvm.tir.ScheduleError):
s.rfactor(ki, 1)
def test_reduction_rfactor_argmax_letstmt_more_than_init():
s = tir.Schedule(argmax_split_letstmt_more_than_init, debug_mask="all")
argmax = s.get_block("argmax")
_, _, ki = s.get_loops(argmax)
with pytest.raises(tvm.tir.ScheduleError):
s.rfactor(ki, 1)
def test_reduction_rfactor_argmax_let_body_neither_seqstmt_nor_bufferstore():
s = tir.Schedule(argmax_split_let_body_neither_seqstmt_nor_bufferstore, debug_mask="all")
argmax = s.get_block("argmax")
_, _, ki = s.get_loops(argmax)
with pytest.raises(tvm.tir.ScheduleError):
s.rfactor(ki, 1)
def test_reduction_rfactor_argmax_init_update_inconsistent_bufferstore_number():
s = tir.Schedule(argmax_split_init_update_inconsistent_bufferstore_number, debug_mask="all")
argmax = s.get_block("argmax")
_, _, ki = s.get_loops(argmax)
with pytest.raises(tvm.tir.ScheduleError):
s.rfactor(ki, 1)
def test_reduction_rfactor_argmax_body_seq_not_bufferstore():
s = tir.Schedule(argmax_split_body_seq_not_bufferstore, debug_mask="all")
argmax = s.get_block("argmax")
_, _, ki = s.get_loops(argmax)
with pytest.raises(tvm.tir.ScheduleError):
s.rfactor(ki, 1)
def test_reduction_rfactor_argmax_body_bufferstore_value_not_var():
s = tir.Schedule(argmax_split_body_bufferstore_value_not_var, debug_mask="all")
argmax = s.get_block("argmax")
_, _, ki = s.get_loops(argmax)
with pytest.raises(tvm.tir.ScheduleError):
s.rfactor(ki, 1)
@pytest.mark.xfail(reason="The input IR is not well-formed")
def test_reduction_rfactor_argmax_body_bufferstore_value_unbound_var():
s = tir.Schedule(argmax_split_body_bufferstore_value_unbound_var, debug_mask="all")
argmax = s.get_block("argmax")
_, _, ki = s.get_loops(argmax)
with pytest.raises(tvm.tir.ScheduleError):
s.rfactor(ki, 1)
def test_reduction_rfactor_argmax_one_let_var_used_multi_times():
s = tir.Schedule(argmax_split_one_let_var_used_multi_times, debug_mask="all")
argmax = s.get_block("argmax")
_, _, ki = s.get_loops(argmax)
with pytest.raises(tvm.tir.ScheduleError):
s.rfactor(ki, 1)
def test_reduction_rfactor_argmax_body_one_buffer_updated_multi_times():
s = tir.Schedule(argmax_split_body_one_buffer_updated_multi_times, debug_mask="all")
argmax = s.get_block("argmax")
_, _, ki = s.get_loops(argmax)
with pytest.raises(tvm.tir.ScheduleError):
s.rfactor(ki, 1)
def test_reduction_rfactor_argmax_init_buffer_not_match():
s = tir.Schedule(argmax_split_init_buffer_not_match, debug_mask="all")
argmax = s.get_block("argmax")
_, _, ki = s.get_loops(argmax)
with pytest.raises(tvm.tir.ScheduleError):
s.rfactor(ki, 1)
def test_reduction_rfactor_topi_argmax():
A = te.placeholder((1, 32), dtype="int32")
B = topi.argmax(A, axis=1)
argmax_topi = te.create_prim_func([A, B])
s = tir.Schedule(argmax_topi, debug_mask="all")
argmax = s.get_block("placeholder_red_temp")
_, k = s.get_loops(argmax)
_, ki = s.split(k, [None, 8])
rf_block = s.rfactor(ki, 1)
assert_structural_equal_ignore_global_symbol(s.mod["main"], argmax_topi_rfactor)
assert s.get(rf_block).same_as(s.get(s.get_block("placeholder_red_temp_rf")))
assert s.get(argmax).same_as(s.get(s.get_block("placeholder_red_temp")))
verify_trace_roundtrip(s, mod=argmax_topi)
def test_reduction_rfactor_topi_argmin():
A = te.placeholder((1, 32), dtype="int32")
B = topi.argmin(A, axis=1)
argmin_topi = te.create_prim_func([A, B])
s = tir.Schedule(argmin_topi, debug_mask="all")
argmin = s.get_block("placeholder_red_temp")
_, k = s.get_loops(argmin)
_, ki = s.split(k, [None, 8])
rf_block = s.rfactor(ki, 1)
assert_structural_equal_ignore_global_symbol(s.mod["main"], argmin_topi_rfactor)
assert s.get(rf_block).same_as(s.get(s.get_block("placeholder_red_temp_rf")))
assert s.get(argmin).same_as(s.get(s.get_block("placeholder_red_temp")))
verify_trace_roundtrip(s, mod=argmin_topi)
def test_reduction_rfactor_int64():
# fmt: off
@T.prim_func
def before(
A: T.Buffer((T.int64(128), T.int64(128)), "float32"),
B: T.Buffer((T.int64(128), T.int64(128)), "float32"),
C: T.Buffer((T.int64(128), T.int64(128)), "float32"),
):
for i0, i1, i2_outer, i2_inner_outer, i2_inner_inner in T.grid(
T.int64(128), T.int64(128), T.int64(4), T.int64(8), T.int64(4)
):
with T.block("update"):
vi, vj = T.axis.remap("SS", [i0, i1])
vk = T.axis.R(
T.int64(128),
i2_outer * T.int64(32) + i2_inner_outer * T.int64(4) + i2_inner_inner,
)
with T.init():
C[vi, vj] = 0.0
C[vi, vj] = C[vi, vj] + (A[vi, vk] * B[vj, vk])
@T.prim_func
def expected(A: T.Buffer((T.int64(128), T.int64(128)), "float32"),
B: T.Buffer((T.int64(128), T.int64(128)), "float32"),
C: T.Buffer((T.int64(128), T.int64(128)), "float32"),
):
C_rf = T.alloc_buffer((T.int64(4), T.int64(128), T.int64(128)), "float32")
for i0, i1, i2_outer, i2_inner_outer, i2_inner_inner in T.grid(T.int64(128), T.int64(128), T.int64(4), T.int64(8), T.int64(4)):
with T.block("update_rf"):
vi2_inner_inner, vi, vj, vi2_outer, vi2_inner_outer= T.axis.remap("SSSRR", [i2_inner_inner, i0, i1, i2_outer, i2_inner_outer])
with T.init():
C_rf[vi2_inner_inner, vi, vj] = 0.0
C_rf[vi2_inner_inner, vi, vj] = C_rf[vi2_inner_inner, vi, vj] + (
A[vi, (((vi2_outer * T.int64(32)) + (vi2_inner_outer * T.int64(4))) + vi2_inner_inner)]
* B[vj, (((vi2_outer * T.int64(32)) + (vi2_inner_outer * T.int64(4))) + vi2_inner_inner)]
)
for i0_1, i1_1, i2_inner_inner_1 in T.grid(T.int64(128), T.int64(128), T.int64(4)):
with T.block("update"):
vi2_inner_inner_1, vi_1, vj_1 = T.axis.remap("RSS", [i2_inner_inner_1, i0_1, i1_1])
with T.init():
C[vi_1, vj_1] = 0.0
C[vi_1, vj_1] = C[vi_1, vj_1] + C_rf[vi2_inner_inner_1, vi_1, vj_1]
# fmt: on
s = tir.Schedule(before, debug_mask="all")
update = s.get_block("update")
_, _, _, _, kii = s.get_loops(update)
rf_block = s.rfactor(kii, 0)
assert_structural_equal_ignore_global_symbol(s.mod["main"], expected)
assert s.get(rf_block).same_as(s.get(s.get_block("update_rf")))
assert s.get(update).same_as(s.get(s.get_block("update")))
verify_trace_roundtrip(s, mod=before)
if __name__ == "__main__":
tvm.testing.main()