more symbolic correctness
MODIFY
test/test_symbolic.py
test/test_symbolic.py
@@ -51,6 +51,13 @@ class TestSymbolic(unittest.TestCase):
def test_mod_remove(self):
self.helper_test_variable(Variable("a", 0, 6)%100, 0, 6, "a")
+ def test_big_mod(self):
+ self.helper_test_variable(Variable("a", -20, 20)%10, -9, 9, "(a%10)")
+ self.helper_test_variable(Variable("a", -20, 0)%10, -9, 0, "(a%10)")
+ self.helper_test_variable(Variable("a", -20, 1)%10, -9, 1, "(a%10)")
+ self.helper_test_variable(Variable("a", 0, 20)%10, 0, 9, "(a%10)")
+ self.helper_test_variable(Variable("a", -1, 20)%10, -1, 9, "(a%10)")
+
def test_gt_remove(self):
self.helper_test_variable(Variable("a", 0, 6) >= 25, 0, 0, "0")
@@ -67,7 +74,8 @@ class TestSymbolic(unittest.TestCase):
def test_mod_factor(self):
# this is technically wrong, if b is 0 the output will be negative
- self.helper_test_variable(Variable.sum([Variable.num(-29), Variable("a", 0, 10), Variable("b", 0, 10)*28]) % 28, -1, 27, "((-1+a)%28)")
+ self.helper_test_variable(Variable.sum([Variable.num(-29), Variable("a", 0, 10), Variable("b", 0, 10)*28]) % 28, -1, 9, "((-1+a)%28)")
+ self.helper_test_variable(Variable.sum([Variable.num(-29), Variable("a", 0, 100), Variable("b", 0, 10)*28]) % 28, -1, 27, "((-1+a)%28)")
def test_div_factor(self):
# TODO: this isn't right

MODIFY
tinygrad/llops/ops_gpu.py
tinygrad/llops/ops_gpu.py
@@ -44,7 +44,7 @@ class CLASTKernel(ASTKernel):
assert self.buftokens[buf_index].typ == Types.FLOAT4, f"image must be FLOAT4 {self.buftokens[buf_index]} {self.bufs[buf_index].st}"
idx = (idxy//4)%self.bufs[buf_index]._base_shape[1]
idy = (idxy//(4*self.bufs[buf_index]._base_shape[1]))%self.bufs[buf_index]._base_shape[0]
- if validhacks: idx, idy = [x.a if isinstance(x, ModNode) and x.max < x.b*2 else x for x in (idx, idy)]
+ if validhacks: idx, idy = [x.a if isinstance(x, ModNode) and x.a.max < x.b*2 else x for x in (idx, idy)]
return f"(int2)({idx.cl}, {idy.cl})"
def store(self, buf_index, value:List[Token]):

MODIFY
tinygrad/shape/symbolic.py
tinygrad/shape/symbolic.py
@@ -117,9 +117,8 @@ class RedNode(Node):
class MulNode(OpNode): op, minmax = "*", staticmethod(lambda a,b: (a.min*b, a.max*b))
class DivNode(OpNode): op, minmax = "//", staticmethod(lambda a,b: (int(a.min/b), int(a.max/b)))
-# TODO: this is wrong! should be flipped or something!
-# though if you change it to (0,b-1) it breaks VALIDHACKS=1
-class ModNode(OpNode): op, minmax = "%", staticmethod(lambda a,b: (min(a.min, 0), max(a.max, b-1)))
+# TODO: next three could be better
+class ModNode(OpNode): op, minmax = "%", staticmethod(lambda a,b: (min(max(a.min,-b+1),0),max(min(a.max,b-1),0)))
class GeNode(OpNode): op, minmax = ">=", staticmethod(lambda a,b: (0,1))
class LtNode(OpNode): op, minmax = "<", staticmethod(lambda a,b: (0,1))

more symbolic correctness