code: def test_predicate():
      x = tvm.tir.Var("x", "int32")
      y = tvm.tir.Var("y", "int32")
      z = tvm.tir.Var("z", "int32")
  
      # available contraints
      # upper bound only
      assert_iter_sum_pattern(
          {x * 10 + y: (128, 0)},
          var_dom([(x, 13), (y, 10)]),
          predicate=x * 10 + y < 128,
      )
  
      assert_iter_sum_pattern(
          {x * 10 + y: (128, 0)},
          var_dom([(x, 13), (y, 10)]),
          predicate=x * 10 + y <= 127,
      )
  
      # lower bound only
      assert_iter_sum_pattern(
          {x * 10 + y: (124, 6)},
          var_dom([(x, 13), (y, 10)]),
          predicate=x * 10 + y > 5,
      )
  
      assert_iter_sum_pattern(
          {x * 10 + y: (124, 6)},
          var_dom([(x, 13), (y, 10)]),
          predicate=x * 10 + y >= 6,
      )
  
      # lower bound + upper bound
      assert_iter_sum_pattern(
          {x * 10 + y: (122, 6)},
          var_dom([(x, 13), (y, 10)]),
          predicate=tvm.tir.And(x * 10 + y > 5, x * 10 + y < 128),
      )
  
      assert_iter_sum_pattern(
          {x * 10 + y: (122, 6)},
          var_dom([(x, 13), (y, 10)]),
          predicate=tvm.tir.And(x * 10 + y >= 6, x * 10 + y <= 127),
      )
  
      assert_iter_sum_pattern(
          {x * 64 + y * 4 + z: (16, 16)},
          var_dom([(x, 16), (y, 16), (z, 4)]),
          predicate=tvm.tir.And(
              x * 64 + y * 4 + z < 32, 4 <= x * 16 + y
          ),
      )
  
      # constraint on one fused iter
      i = tvm.tir.Var("i", "int32")
      j = tvm.tir.Var("j", "int32")
      k = tvm.tir.Var("k", "int32")
      assert_iter_sum_pattern(
          {i * 8 + j * 2 + k: (88, 1)},
          var_dom([(i, 11), (j, 5), (k, 2)]),
          predicate=tvm.tir.all(1 <= j * 2 + k, j * 2 + k < 9),
      )
  
      # constraint on single var
      assert_iter_sum_pattern(
          {i: (10, 0)}, var_dom([(i, 48)]), predicate=i < 10
      )
  
      # iterations are subparts of constraint, invalid case 1
      assert_iter_sum_failure(
          [i, j, k],
          var_dom([(i, 128), (j, 128), (k, 128)]),
          predicate=tvm.tir.all(i * 16384 + j * 128 + k < 100),
      )
  
      # iterations are subparts of constraint, invalid case 2
      assert_iter_sum_failure(
          [i * 128 + j, k],
          var_dom([(i, 128), (j, 128), (k, 128)]),
          predicate=i * 16384 + j * 128 + k < 100,
      )
  
      # irrelavant predicate
      assert_iter_sum_pattern(
          {i + j: (1, j)}, var_dom([(i, 1)]), predicate=j <= 24
      )
  
      # constraint on nested fused iters
      assert_iter_sum_pattern(
          {i * 8 + j * 2 + k: (22, 3)},
          var_dom([(i, 11), (j, 5), (k, 2)]),
          predicate=tvm.tir.all(
              1 <= j * 2 + k,
              j * 2 + k < 9,
              3 <= i * 8 + j * 2 + k,
              i * 8 + j * 2 + k < 25,
          ),
      )
  
      # duplicate constraint on one fused iter
      assert_iter_sum_pattern(
          {i * 6 + j * 2 + k: (66, 2)},
          var_dom([(i, 11), (j, 5), (k, 2)]),
          predicate=tvm.tir.all(
              1 <= j * 2 + k,
              2 <= j * 2 + k,
              j * 2 + k < 8,
              j * 2 + k < 9,
          ),
      )
  
      # duplicate constraint on nested fused iters
      assert_iter_sum_pattern(
          {i * 6 + j * 2 + k: (15, 3)},
          var_dom([(i, 11), (j, 5), (k, 2)]),
          predicate=tvm.tir.all(
              1 <= j * 2 + k,
              2 <= j * 2 + k,
              j * 2 + k < 8,
              j * 2 + k < 9,
              3 <= i * 6 + j * 2 + k,
              i * 6 + j * 2 + k < 25,
              1 <= i * 6 + j * 2 + k,
              i * 6 + j * 2 + k < 18,
          ),
      )
  
      # constraint on non-disjoint fused iters should fail
      assert_iter_sum_failure(
          [i * 8 + j * 2 + k],
          var_dom([(i, 11), (j, 5), (k, 2)]),
          predicate=tvm.tir.all(2 <= j * 2 + k, 0 <= i * 4 + j),
      )
  
      # constraint on many disjoint fused iters, case 1
      # i4 * 6 + i5 in [3, 9), extent=6 (= scale of i2)
      # i2 * 30 + i3 * 15 in [30, 90), extent=60 (= scale of i1)
      # i1 * 60 in [60, 240), extent=180 (= scale of i0)
      i0 = tvm.tir.Var("i0", "int32")
      i1 = tvm.tir.Var("i1", "int32")
      i2 = tvm.tir.Var("i2", "int32")
      i3 = tvm.tir.Var("i3", "int32")
      i4 = tvm.tir.Var("i4", "int32")
      i5 = tvm.tir.Var("i5", "int32")
      assert_iter_sum_pattern(
          {
              i0 * 180
              + i1 * 60
              + i2 * 30
              + i3 * 15
              + i4 * 6
              + i5: (540, 93)
          },
          var_dom(
              [(i0, 3), (i1, 4), (i2, 3), (i3, 2), (i4, 3), (i5, 6)]
          ),
          predicate=tvm.tir.all(
              1 <= i1, 2 <= i2 * 2 + i3, 3 <= i4 * 6 + i5
          ),
      )
  
      # constraint on many disjoint fused iters, case 2
      assert_iter_sum_pattern(
          {i0 * 45 + i1 * 45 + i2 * 9 + i3 * 4 + i4: (135, 28)},
          var_dom([(i0, 3), (i1, 2), (i2, 5), (i3, 3), (i4, 4)]),
          predicate=tvm.tir.all(
              3 <= i1 * 5 + i2,
              i1 * 5 + i2 < 8,
              1 <= i3 * 4 + i4,
              i3 * 4 + i4 < 10,
          ),
      )
  
      # constraint on split iters
      assert_iter_sum_pattern(
          {i % 16: (7, 3), i // 16: (8, 4)},
          var_dom([(i, 1024)]),
          predicate=tvm.tir.all(
              3 <= i % 16, i % 16 < 10, 4 <= i // 16, i // 16 < 12
          ),
          check_level="bijective",
      )
  
      # constraint on split iters, nested case 1
      assert_iter_sum_pattern(
          {(i * 32 + j) % 16: (7, 3)},
          var_dom([(i, 5), (j, 32)]),
          predicate=tvm.tir.all(
              3 <= (i * 32 + j) % 16, (i * 32 + j) % 16 < 10
          ),
      )
  
      # constraint on split iters, nested case 2
      assert_iter_sum_failure(
          [
              (i * 32 + j) % 16,
          ],
          var_dom([(i, 5), (j, 32)]),
          predicate=tvm.tir.all(1 <= i * 32 + j, i * 32 + j <= 32),
          check_level="bijective",
      )
      assert_iter_sum_pattern(
          {(i * 32 + j) % 16: (16, 0)},
          var_dom([(i, 5), (j, 32)]),
          predicate=tvm.tir.all(1 <= i * 32 + j, i * 32 + j <= 32),
      )
      assert_iter_sum_pattern(
          {
              (i * 32 + j - 1) % 16: (16, 0),
              (i * 32 + j - 1) // 16: (4, 0),
          },
          var_dom([(i, 5), (j, 32)]),
          predicate=tvm.tir.all(1 <= i * 32 + j, i * 32 + j <= 64),
      )
  
      # non-standard form of predicate
      assert_iter_sum_pattern(
          {x * 10 + y: (128, 0)},
          var_dom([(x, 13), (y, 10)]),
          predicate=x * 10 < 128 - y,
      )
  
      # duplicate constraint
      assert_iter_sum_pattern(
          {x * 10 + y: (64, 0)},
          var_dom([(x, 13), (y, 10)]),
          predicate=tvm.tir.all(x * 10 + y < 128, x * 10 + y < 64),
      )
  
      # useless constraint
      assert_iter_sum_pattern(
          {x * 10 + y: (130, 0)},
          var_dom([(x, 13), (y, 10)]),
          predicate=x * 10 + y < 140,
      )
  
      i1 = tvm.tir.Var("i1", "int32")
      i2 = tvm.tir.Var("i2", "int32")
      i3 = tvm.tir.Var("i3", "int32")
      i4 = tvm.tir.Var("i4", "int32")
      assert_iter_sum_pattern(
          {i1 * 20 + i2 * 10 + i3 * 3 + i4: (128, 0)},
          var_dom([(i1, 7), (i2, 2), (i3, 4), (i4, 3)]),
          predicate=(
              tvm.tir.all(
                  i1 * 2 + i2 < 13,
                  i1 * 20 + i2 * 10 + i3 * 3 + i4 < 128,
                  i3 * 3 + i4 < 10,
              )
          ),
      )
  
      # wrong constraint
      assert_iter_sum_failure(
          [i1 * 20 + i2 * 10 + i3 * 3 + i4],
          var_dom([(i1, 7), (i2, 2), (i3, 4), (i4, 3)]),
          predicate=(
              tvm.tir.all(
                  i1 * 2 + i2 < 13,
                  i1 * 20 + i2 * 10 + i3 * 3 + i4 < 128,
                  i3 * 3 + i4 < 7,
              )
          ),
      )
  
      # incompatible constraint
      assert_iter_sum_failure(
          [i1 * 20 + i2 * 10 + i3 * 3 + i4],
          var_dom([(i1, 7), (i2, 2), (i3, 4), (i4, 3)]),
          predicate=(
              tvm.tir.all(
                  i1 * 2 + i2 < 13,
                  i1 * 20 + i2 * 10 + i3 * 3 + i4 < 128,
                  i3 * 3 + i4 < 10,
                  i1 * 4 + i3 < 20,
              )
          ),
      )
      assert_iter_sum_failure(
          [i1 * 20 + i2 * 10 + i3 * 3 + i4],
          var_dom([(i1, 7), (i2, 2), (i3, 4), (i4, 3)]),
          predicate=(
              tvm.tir.all(
                  i1 * 2 + i2 < 13,
                  i1 * 20 + i2 * 10 + i3 * 3 + i4 < 128,
                  i1 * 4 + i3 < 20,
              )
          ),
      )
  
      # zero iter
      xo = tvm.tir.Var("xo", "int32")
      xi = tvm.tir.Var("xi", "int32")
      y = tvm.tir.Var("y", "int32")
      assert_iter_sum_pattern(
          {xo * 129 + xi: (128, 0), y: (128, 0)},
          var_dom([(xo, 1), (xi, 129), (y, 128)]),
          predicate=xo * 129 + xi < 128,
      )
  
      # strided iteration predicate
      assert_iter_sum_pattern(
          {xo * 16 + xi * 4: (10, 0, 4)},
          var_dom([(xo, 3), (xi, 4)]),
          predicate=xo * 4 + xi < 10,
      )
  
imports: import tvm
  import tvm.testing
  from tvm.tir import floordiv, floormod
label_desc: Use image node_id 13 for calling a global function with example usage: test_predicate() without return types