debugging while we compile
MODIFY
accel/opencl/ops_opencl.py
accel/opencl/ops_opencl.py
from __future__ import annotations
+import os
from tinygrad.llops.ops_gpu import GPUBuffer, CL, CLProgram, code_for_op
from tinygrad.ops import ProcessingOps
from tinygrad.helpers import prod, ConvArgs
@@ -16,10 +17,11 @@ CONV_SRC = load(pathlib.Path(__file__).parent.parent.parent / 'accel/opencl/conv
class ECL(CL):
@staticmethod
def image(shape):
- if CL.DEBUG >= 2: print(f"cl: create image({shape})")
- fmt = cl.ImageFormat(cl.channel_order.RGBA, cl.channel_type.FLOAT)
+ if int(os.getenv("FLOAT16", 0)):
# HALF_FLOAT breaks tests
- #fmt = cl.ImageFormat(cl.channel_order.RGBA, cl.channel_type.HALF_FLOAT)
+ fmt = cl.ImageFormat(cl.channel_order.RGBA, cl.channel_type.HALF_FLOAT)
+ else:
+ fmt = cl.ImageFormat(cl.channel_order.RGBA, cl.channel_type.FLOAT)
return cl.Image(CL().cl_ctx, cl.mem_flags.READ_WRITE, fmt, shape=shape)
def get_replacements(prg_src:str, opencl_type:List[str]) -> Dict[str, str]:

MODIFY
openpilot/compile.py
openpilot/compile.py
@@ -6,11 +6,16 @@ import os
import time
import io
os.environ['LAZY'] = '1'
+if int(os.getenv("NOIMAGE", 0)):
+ pass
+else:
os.environ['LAZY_OPENCL'] = '1'
import onnx
import numpy as np
+import tinygrad.ops as ops
+
from tinygrad.llops.ops_gpu import CL
from extra.utils import fetch
from extra.onnx import get_run_onnx
@@ -36,6 +41,8 @@ def get_random_input_tensors():
return inputs, np_inputs
if __name__ == "__main__":
+ ops.GRAPH = False
+
dat = fetch(OPENPILOT_MODEL)
onnx_model = onnx.load(io.BytesIO(dat))
run_onnx = get_run_onnx(onnx_model)
@@ -57,18 +64,22 @@ if __name__ == "__main__":
tinygrad_out = run_onnx(inputs)['outputs']
CL.CACHE = []
+ ops.GRAPH = True
tinygrad_out.realize()
+ ops.GRAPH = False
print("kernel count:", len(CL.CACHE))
# real CL ish
st = time.monotonic()
- for prg, args in CL.CACHE:
- prg(CL().cl_queue, *args)
+ for i, (prg, args) in enumerate(CL.CACHE):
+ print(f"{i:3d} running {prg.name:20s} with {str(args[0]):15s} {str(args[1]):15s} count {len(args)-2:2d}")
+ prg.clprg(CL().cl_queue, *args)
mt = time.monotonic()
CL().cl_queue.finish()
et = time.monotonic()
print(f"submit in {(mt-st)*1000.0:.2f} ms, total runtime is {(et-st)*1000.0:.2f} ms")
+ CL.CACHE = None
tinygrad_out = tinygrad_out.numpy()
# float32

MODIFY
tinygrad/llops/ops_gpu.py
tinygrad/llops/ops_gpu.py
@@ -9,7 +9,6 @@ from tinygrad.ops import UnaryOps, BinaryOps, ReduceOps, MovementOps, Processing
from tinygrad.shapetracker import ShapeTracker, View, strides_for_shape
class CL:
- DEBUG = int(os.getenv("DEBUGCL", "0"))
CACHE = None
def __init__(self):
if getattr(CL, "cl_queue", None) is not None: return
@@ -21,25 +20,21 @@ class CL:
@staticmethod
def enqueue_copy(a, b, is_blocking=False):
- if CL.DEBUG: print(f"cl: copy into {type(a)} sz {a.size} block {is_blocking}")
+ if CL.CACHE is not None: assert False, "can't copy while caching"
cl.enqueue_copy(CL().cl_queue, a, b, is_blocking=is_blocking)
@staticmethod
- def malloc(sz):
- if CL.DEBUG >= 2: print(f"cl: malloc({sz})")
- return cl.Buffer(CL().cl_ctx, cl.mem_flags.READ_WRITE, sz)
+ def malloc(sz): return cl.Buffer(CL().cl_ctx, cl.mem_flags.READ_WRITE, sz)
@functools.lru_cache(maxsize=None)
class CLProgram:
def __init__(self, name, prg, options=tuple(), argdtypes=None):
self.name = name
- if CL.DEBUG >= 2: print(f"cl: building {self.name:20s} with {options}")
self.built = cl.Program(CL().cl_ctx, prg).build(options=options)
self.clprg = self.built.__getattr__(name)
if argdtypes is not None: self.clprg.set_scalar_arg_dtypes(argdtypes)
def __call__(self, *args):
- if CL.DEBUG: print(f"cl: running {self.name:20s} with {str(args[0]):15s} {str(args[1]):15s} count {len(args)-2:2d}")
- if CL.CACHE is not None: CL.CACHE.append((self.clprg, args))
+ if CL.CACHE is not None: CL.CACHE.append((self, args))
else: self.clprg(CL().cl_queue, *args)
# **** end CL wrappers ****

debugging while we compile