code: def __init__(self, cl_cache=[], inputs={}):
      self.cl_cache, self.inputs = cl_cache[:], inputs
      self.gobj = 0
  
      # build graph
      # NOTE: if CLCACHE=1, this is wrong!
      nodes = defaultdict(lambda: {"in_edges": [], "out_edges": []})
      for _, args in self.cl_cache:
          # output is always the first parameter
          for a in args[3:]:
              nodes[a]["out_edges"].append(args[2])
              nodes[args[2]]["in_edges"].append(a)
  
      # get buffers to save
      self.buffers_to_save = set()
      self.outputs = []
      for n in nodes.keys():
          if len(nodes[n]["in_edges"]) == 0:
              self.buffers_to_save.add(n)
          if len(nodes[n]["out_edges"]) == 0:
              self.outputs.append(n)
  
      fake_inputs = []
      for k, n in self.inputs.items():
          if n in self.buffers_to_save:
              self.buffers_to_save.remove(n)
          else:
              print(f"WARNING: {k} was not a used input, removing it")
              fake_inputs.append(k)
      for k in fake_inputs:
          del self.inputs[k]
  
file_path: tinygrad/extra/thneed.py
imports: import time
  import struct
  import json
  import traceback
  import numpy
  from tinygrad.runtime.ops_gpu import CLProgram, compile_gpu
  from tinygrad.device import Device
  from tinygrad.helpers import DEBUG, getenv
  from collections import defaultdict
  import pyopencl
  from tinygrad.runtime.ops_gpu import OSX_TIMING_RATIO
label_desc: Use image node_id 1 to create a new Thneed object  with example: obj = Thneed(cl_cache, inputs)