code: def __init__(self, device: CLDevice, name: str, lib: bytes):
      self.device, self.name, self.lib = device, name, lib
      self.program = checked(
          cl.clCreateProgramWithBinary(
              device.context,
              1,
              ctypes.byref(device.device_id),
              (ctypes.c_size_t * 1)(len(lib)),
              to_char_p_p([lib], ctypes.c_ubyte),
              ctypes.byref(binary_status := ctypes.c_int32()),
              ctypes.byref(errcode_ret := ctypes.c_int32()),
          ),
          errcode_ret,
      )
      check(binary_status.value)
      check(
          cl.clBuildProgram(
              self.program,
              1,
              ctypes.byref(device.device_id),
              None,
              cl.clBuildProgram.argtypes[4](),
              None,
          )
      )  # NOTE: OSX requires this
      self.kernel = checked(
          cl.clCreateKernel(
              self.program,
              name.encode(),
              ctypes.byref(status := ctypes.c_int32()),
          ),
          status,
      )
  
imports: from __future__ import annotations
  from typing import Tuple, Optional, List
  import ctypes, functools, hashlib
  import gpuctypes.opencl
  from tinygrad.helpers import init_c_var, to_char_p_p, from_mv, OSX, DEBUG
  from tinygrad.dtype import ImageDType
  from tinygrad.codegen.kernel import LinearizerOptions
  from tinygrad.renderer.cstyle import OpenCLRenderer
  from tinygrad.device import Compiled, LRUAllocator
label_desc: Use image node_id 1 to create a new CLProgram object  with example: obj = CLProgram(device, name, lib)