Hi All,
The following script depicts the problem
@T.prim_func
def func(data: T.handle) -> None:
X = T.match_buffer(data, [4, 4], dtype="int32")
for i, j in T.grid(4, 4):
with T.block("block"):
vi, vj = T.axis.remap("SS", [i, j])
with T.init():
X[vi, vj] = 0
X[vi, vj] = T.if_then_else(vi > 0 and vj > 0, X[vi-1, vj-1], 0, dtype="int32") + \
T.if_then_else(vi > 0 and vj < 3, X[vi-1, vj+1], 0, dtype="int32") + 1
# direct test
f1 = tvm.build(func, "llvm")
a = tvm.nd.array(np.ones([4, 4], "int32"))
f1(a)
# reorder (i,j) -> (j,i), which should not be valid
ai, aj = s.get_loops(s.get_block("block"))
s.reorder(aj, ai)
f2 = tvm.build(s.mod["main"], "llvm")
b = tvm.nd.array(np.ones([4, 4], "int32"))
f2(b)
# get incorrect results
tvm.testing.assert_allclose(a.numpy(), b.numpy())
For this example, since the precedence conditions (i, j) <- (i-1, j-1), (i, j) <- (i-1, j+1)
should be preserved, the reorder should not be allowed. However, current schedule primitives do not detect this invalid operation.
It should be ok for developers manually performing the schedule since they are assumed to “know what you are doing”. But it would be too hard to debug in applications of somewhat “auto” fashion, where transformations are automatically done during searching and tuning.