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.