don't create linearizer if we are in the method cache (#1969)

* don't create linearizer if we are in the method cache

* remove unchecked properties

* that key isn't used

* fix default type is sticky
This commit is contained in:
George Hotz
2023-10-04 12:42:58 -07:00
committed by GitHub
parent de5d603ec1
commit 3d5127038c
6 changed files with 18 additions and 73 deletions
-48
View File
@@ -1,48 +0,0 @@
#!/usr/bin/env python
import unittest
import numpy as np
from tinygrad.ops import LazyOp, BinaryOps, ReduceOps
from tinygrad.runtime.ops_llvm import LLVMBuffer
class TestLLVM(unittest.TestCase):
def test_add(self):
a = LLVMBuffer.fromCPU(np.ones((4,4)))
b = LLVMBuffer.fromCPU(np.ones((4,4)))
ast = LazyOp(BinaryOps.ADD, (a,b))
ret = LLVMBuffer((4,4)).exec_ast(ast)
print(ret.toCPU())
def test_sum(self):
a = LLVMBuffer.fromCPU(np.ones((4,4)))
ast = LazyOp(ReduceOps.SUM, (a,), (1,1))
ret = LLVMBuffer((1,1)).exec_ast(ast)
print(ret.toCPU())
def test_sum_add(self):
a = LLVMBuffer.fromCPU(np.ones((4,4)))
b = LLVMBuffer.fromCPU(np.ones((1,1)))
ast = LazyOp(ReduceOps.SUM, (a,), (1,1))
ast = LazyOp(BinaryOps.ADD, (ast,b))
ret = LLVMBuffer((1,1)).exec_ast(ast)
print(ret.toCPU())
def test_add_sum(self):
a = LLVMBuffer.fromCPU(np.ones((4,4)))
b = LLVMBuffer.fromCPU(np.ones((4,4)))
ast = LazyOp(BinaryOps.ADD, (a,b))
ast = LazyOp(ReduceOps.SUM, (ast,), (1,1))
ret = LLVMBuffer((1,1)).exec_ast(ast)
print(ret.toCPU())
def test_add_sum_add(self):
a = LLVMBuffer.fromCPU(np.ones((4,4)))
b = LLVMBuffer.fromCPU(np.ones((4,4)))
c = LLVMBuffer.fromCPU(np.ones((1,1)))
ast = LazyOp(BinaryOps.ADD, (a,b))
ast = LazyOp(ReduceOps.SUM, (ast,), (1,1))
ast = LazyOp(BinaryOps.ADD, (ast,c))
ret = LLVMBuffer((1,1)).exec_ast(ast)
print(ret.toCPU())
if __name__ == "__main__":
unittest.main()
+2 -6
View File
@@ -67,12 +67,14 @@ def derandomize_model(model):
class TestRealWorld(unittest.TestCase):
def setUp(self):
self.old_type = Tensor.default_type
np.random.seed(2002)
if getenv("KOPT"):
self.oldfunc = getattr(__import__("tinygrad.codegen.search", fromlist=["kernel_optimize_search"]), "kernel_optimize_search")
setattr(__import__("tinygrad.codegen.search", fromlist=["kernel_optimize_search"]), "kernel_optimize_search", kopt_search_hook)
def tearDown(self):
Tensor.default_type = self.old_type
if getenv("KOPT"):
setattr(__import__("tinygrad.codegen.search", fromlist=["kernel_optimize_search"]), "kernel_optimize_search", self.oldfunc)
@@ -86,7 +88,6 @@ class TestRealWorld(unittest.TestCase):
@unittest.skipUnless(Device.DEFAULT in JIT_SUPPORTED_DEVICE and Device.DEFAULT not in ["LLVM"], "needs JIT, too long on CI LLVM")
def test_llama(self):
old_type = Tensor.default_type
Tensor.default_type = dtypes.float16
args_tiny = {"dim": 1024, "multiple_of": 256, "n_heads": 8, "n_layers": 8, "norm_eps": 1e-05, "vocab_size": 1000}
@@ -97,11 +98,8 @@ class TestRealWorld(unittest.TestCase):
# NOTE: only test one pass, not testing the dynamic shape autoregressive part
helper_test("test_llama", lambda: (Tensor([[1,]]),), test, 0.22 if CI else 13.5, 126 if CI else 486)
Tensor.default_type = old_type
@unittest.skipUnless(Device.DEFAULT in JIT_SUPPORTED_DEVICE and Device.DEFAULT not in ["LLVM"], "needs JIT, too long on CI LLVM")
def test_gpt2(self):
old_type = Tensor.default_type
Tensor.default_type = dtypes.float16
args_tiny = {"dim": 1024, "n_heads": 8, "n_layers": 8, "norm_eps": 1e-5, "vocab_size": 1000}
@@ -111,8 +109,6 @@ class TestRealWorld(unittest.TestCase):
def test(t): return model(t, 0).realize()
helper_test("test_gpt2", lambda: (Tensor([[1,]]),), test, 0.21 if CI else 0.9, 129 if CI else 369)
Tensor.default_type = old_type
@unittest.skipIf(getenv("KOPT"), "cifar hangs with KOPT")
@unittest.skipUnless(Device.DEFAULT in JIT_SUPPORTED_DEVICE and Device.DEFAULT not in ["LLVM"], "needs JIT, too long on CI LLVM")
def test_train_cifar(self):
-1
View File
@@ -53,7 +53,6 @@ class Kernel:
self.opts = opts if opts else (cast(Compiled, Device[Device.DEFAULT]).linearizer_opts if isinstance(Device[Device.DEFAULT], Compiled) else LinearizerOptions())
self.ast = ast
self.var_vals = var_vals
self.key = (ast, tuple(var_vals.keys())) if var_vals else ast
# fetch lazyop info
self.info: FlopCounter = get_lazyop_info(cast(LazyOp, self.ast))
+2 -2
View File
@@ -50,10 +50,10 @@ def kernel_optimize_search(k:Linearizer, create_k:Callable[[], Linearizer], to_p
# optimization
global_db = None
def kernel_optimize(k:Linearizer, create_k:Callable[[], Linearizer], to_prg, bufs):
def kernel_optimize(k:Linearizer, create_k:Callable[[], Linearizer], to_prg, bufs, key):
global global_db
skey = str(k.key)
skey = str(key)
if getenv("KOPT") == 2 and global_db is None:
import shelve
+13 -15
View File
@@ -67,14 +67,9 @@ class LazyOp:
@property
def st(self): raise NotImplementedError
@property
def children(self): raise NotImplementedError
@property
def shape(self): raise NotImplementedError
@property
def realized(self): raise NotImplementedError
@property
def optype(self): raise NotImplementedError
def realize(self): raise NotImplementedError
def children(self): raise NotImplementedError
# movement ops
def reshape(self, _): raise NotImplementedError
@@ -117,7 +112,7 @@ class Interpreted:
if ast.op in BufferOps and ast.op not in self.fxn_for_op:
if ast.op == BufferOps.MEM:
assert inputs[ast.arg.idx-1].dtype == ast.arg.dtype, "dtype mismatch"
buf = self.to_underlying(inputs[ast.arg.idx-1])
buf = self.to_underlying(inputs[ast.arg.idx-1].realized)
elif ast.op == BufferOps.CONST:
buf = self.to_underlying(self.buffer.fromCPU(np.array(ast.arg.val, dtype=ast.arg.dtype.np)))
for mop,arg in ast.arg.st.to_movement_ops(): buf = self.fxn_for_op[mop](buf, arg)
@@ -226,7 +221,7 @@ class Compiled:
if output.realized:
for i,a in enumerate(inputs):
# TODO: if this is contiguous it's fine
if a == output.realized:
if a.realized == output.realized:
if any(not x.arg.st.contiguous for x in ast.get_lazyops() if x.op == BufferOps.MEM and x.arg.idx == i+1):
output.realized = None
break
@@ -238,23 +233,26 @@ class Compiled:
from tinygrad.jit import CacheCollector
CacheCollector._mark_output_buffer(output.output_buffer)
from tinygrad.codegen.linearizer import Linearizer
k = Linearizer(ast, self.linearizer_opts, var_vals)
# all the rawbuffers
rawbuffers = [output.realized] + [x.realized for x in inputs]
key = (ast, tuple(var_vals.keys())) if var_vals else ast # TODO: remove var_vals so the key can just be the AST
# compilation time
def get_program():
from tinygrad.codegen.linearizer import Linearizer
k = Linearizer(ast, self.linearizer_opts, var_vals)
from tinygrad.codegen.search import kernel_optimize
if getenv("KOPT"): kernel_optimize(k, lambda: Linearizer(ast, self.linearizer_opts, var_vals), self.to_program, [output.realized]+inputs)
if getenv("KOPT"): kernel_optimize(k, lambda: Linearizer(ast, self.linearizer_opts, var_vals), self.to_program, rawbuffers, key)
elif not getenv("NOOPT"): k.hand_coded_optimizations()
return self.to_program(k)
if hasattr(k, 'key') and getenv("ENABLE_METHOD_CACHE", 1):
if k.key not in self.method_cache: self.method_cache[k.key] = get_program()
prg = self.method_cache[k.key]
if getenv("ENABLE_METHOD_CACHE", 1):
if key not in self.method_cache: self.method_cache[key] = get_program()
prg = self.method_cache[key]
else:
prg = get_program()
if prg.name == getenv("PRINT_PRG", ''): print(prg.prg)
prg.exec([output.realized]+inputs, var_vals=var_vals)
prg.exec(rawbuffers, var_vals=var_vals)
return output.realized
+1 -1
View File
@@ -23,7 +23,7 @@ def run_schedule(schedule:List[Tuple[LazyOp, LazyBuffer, Tuple[LazyBuffer, ...]]
for i,s in enumerate(op.src): assert isinstance(s, LazyOp) and s.op == BufferOps.MEM and s.arg.idx == i+1 and s.arg.st.contiguous, f"bad LoadOps src {i}: {s}"
LOAD_OPS_DISPATCHER[cast(LoadOps, op.op)](out, *buffers)
else:
out.realized = Device[out.device].exec_ast(op, output=out, inputs=[x.realized for x in buffers], var_vals=out.var_vals, **out._device_extra_args())
out.realized = Device[out.device].exec_ast(op, output=out, inputs=buffers, var_vals=out.var_vals, **out._device_extra_args())
del out.op
for v in out.views: del v.op
assert out.realized and isinstance(out.realized, Device[out.device].buffer), f"device mismatch on realized got {type(out.realized)} expected {out.device}"