cleanup lazy reduce (#3517)

* cleanup lazy reduce

removed useless assert now arg is axis and cleaned split logic

* stride can be symbolic with int shape
This commit is contained in:
chenyu
2024-02-28 08:15:01 -05:00
committed by GitHub
parent 2127c1c6c2
commit fa88e1d0d0
+2 -2
View File
@@ -131,11 +131,11 @@ class LazyBuffer:
new_shape = tuple(1 if i in axis else s for i,s in enumerate(self.shape))
# TODO: this logic should move to the scheduler
if self.size == 0 and 0 not in new_shape: return self.const({ReduceOps.SUM: 0.0, ReduceOps.MAX: -math.inf}[op], new_shape)
assert len(self.shape)==len(new_shape) and all(ns in (1,s) for s,ns in zip(self.shape,new_shape)), f"not a contraction {self.shape=} {new_shape=}"
# TODO: can we split symbolic shape if the reduce axis is not symbolic?
if not all_int(self.shape) or (0 in self.shape) or prod(self.shape) // prod(new_shape) < getenv("REDUCEOP_SPLIT_THRESHOLD", 32768):
return self._reduce_op(op, axis)
heuristic, divisor, dim_to_split = max(((divisor := math.gcd(256, old))/(stride or math.inf), divisor, i) for i, (old, new, stride) in enumerate(zip(self.shape, new_shape, self.st.real_strides())) if old != new) # type: ignore # noqa: E501
heuristic, divisor, dim_to_split = max(((divisor := math.gcd(256, s))/(st or math.inf), divisor, i) for i,(s,st) in \
enumerate(zip(self.shape, self.st.real_strides())) if i in axis and (st is None or isinstance(st, int)))
if divisor < 16 or heuristic < 0.1: return self._reduce_op(op, axis)
# choose largest divisor (>=16) to split on, penalize large strides
def splitted_shape(dim_aft_div):