tinygrad 0.10.0__py3-none-any.whl → 0.10.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. tinygrad/codegen/devectorizer.py +247 -0
  2. tinygrad/codegen/expander.py +121 -0
  3. tinygrad/codegen/kernel.py +141 -201
  4. tinygrad/codegen/linearize.py +223 -84
  5. tinygrad/codegen/lowerer.py +60 -42
  6. tinygrad/codegen/symbolic.py +476 -0
  7. tinygrad/codegen/transcendental.py +22 -13
  8. tinygrad/device.py +187 -47
  9. tinygrad/dtype.py +39 -28
  10. tinygrad/engine/jit.py +83 -65
  11. tinygrad/engine/memory.py +4 -5
  12. tinygrad/engine/multi.py +161 -0
  13. tinygrad/engine/realize.py +62 -108
  14. tinygrad/engine/schedule.py +396 -357
  15. tinygrad/engine/search.py +55 -66
  16. tinygrad/gradient.py +73 -0
  17. tinygrad/helpers.py +81 -59
  18. tinygrad/nn/__init__.py +30 -32
  19. tinygrad/nn/datasets.py +1 -2
  20. tinygrad/nn/optim.py +22 -26
  21. tinygrad/nn/state.py +91 -66
  22. tinygrad/ops.py +492 -641
  23. tinygrad/renderer/__init__.py +95 -36
  24. tinygrad/renderer/cstyle.py +99 -92
  25. tinygrad/renderer/llvmir.py +83 -34
  26. tinygrad/renderer/ptx.py +83 -99
  27. tinygrad/renderer/wgsl.py +95 -0
  28. tinygrad/runtime/autogen/amd_gpu.py +39507 -12
  29. tinygrad/runtime/autogen/comgr.py +2 -0
  30. tinygrad/runtime/autogen/kfd.py +4 -3
  31. tinygrad/runtime/autogen/kgsl.py +1 -1
  32. tinygrad/runtime/autogen/libc.py +404 -71
  33. tinygrad/runtime/autogen/llvm.py +11379 -0
  34. tinygrad/runtime/autogen/pci.py +1333 -0
  35. tinygrad/runtime/autogen/vfio.py +891 -0
  36. tinygrad/runtime/autogen/webgpu.py +6985 -0
  37. tinygrad/runtime/graph/cuda.py +8 -9
  38. tinygrad/runtime/graph/hcq.py +84 -79
  39. tinygrad/runtime/graph/metal.py +40 -43
  40. tinygrad/runtime/ops_amd.py +498 -334
  41. tinygrad/runtime/ops_cloud.py +34 -34
  42. tinygrad/runtime/ops_cpu.py +24 -0
  43. tinygrad/runtime/ops_cuda.py +30 -27
  44. tinygrad/runtime/ops_disk.py +62 -63
  45. tinygrad/runtime/ops_dsp.py +159 -42
  46. tinygrad/runtime/ops_gpu.py +30 -30
  47. tinygrad/runtime/ops_hip.py +29 -31
  48. tinygrad/runtime/ops_llvm.py +48 -41
  49. tinygrad/runtime/ops_metal.py +149 -113
  50. tinygrad/runtime/ops_npy.py +2 -2
  51. tinygrad/runtime/ops_nv.py +238 -273
  52. tinygrad/runtime/ops_python.py +55 -50
  53. tinygrad/runtime/ops_qcom.py +129 -157
  54. tinygrad/runtime/ops_webgpu.py +225 -0
  55. tinygrad/runtime/support/allocator.py +94 -0
  56. tinygrad/runtime/support/am/__init__.py +0 -0
  57. tinygrad/runtime/support/am/amdev.py +396 -0
  58. tinygrad/runtime/support/am/ip.py +463 -0
  59. tinygrad/runtime/support/compiler_cuda.py +4 -2
  60. tinygrad/runtime/support/elf.py +28 -4
  61. tinygrad/runtime/support/hcq.py +256 -324
  62. tinygrad/runtime/support/llvm.py +26 -0
  63. tinygrad/shape/shapetracker.py +85 -53
  64. tinygrad/shape/view.py +104 -140
  65. tinygrad/spec.py +155 -0
  66. tinygrad/tensor.py +835 -527
  67. tinygrad/viz/assets/cdnjs.cloudflare.com/ajax/libs/highlight.js/11.10.0/highlight.min.js +1232 -0
  68. tinygrad/viz/assets/cdnjs.cloudflare.com/ajax/libs/highlight.js/11.10.0/languages/cpp.min.js +47 -0
  69. tinygrad/viz/assets/cdnjs.cloudflare.com/ajax/libs/highlight.js/11.10.0/languages/python.min.js +42 -0
  70. tinygrad/viz/assets/cdnjs.cloudflare.com/ajax/libs/highlight.js/11.10.0/styles/default.min.css +9 -0
  71. tinygrad/viz/assets/d3js.org/d3.v5.min.js +2 -0
  72. tinygrad/viz/assets/dagrejs.github.io/project/dagre-d3/latest/dagre-d3.min.js +4816 -0
  73. tinygrad/viz/assets/unpkg.com/@highlightjs/cdn-assets@11.10.0/styles/tokyo-night-dark.min.css +8 -0
  74. tinygrad/viz/index.html +544 -0
  75. tinygrad/viz/perfetto.html +178 -0
  76. tinygrad/viz/serve.py +205 -0
  77. {tinygrad-0.10.0.dist-info → tinygrad-0.10.2.dist-info}/METADATA +48 -25
  78. tinygrad-0.10.2.dist-info/RECORD +99 -0
  79. {tinygrad-0.10.0.dist-info → tinygrad-0.10.2.dist-info}/WHEEL +1 -1
  80. tinygrad/codegen/uopgraph.py +0 -506
  81. tinygrad/engine/lazy.py +0 -228
  82. tinygrad/function.py +0 -212
  83. tinygrad/multi.py +0 -177
  84. tinygrad/runtime/graph/clang.py +0 -39
  85. tinygrad/runtime/ops_clang.py +0 -35
  86. tinygrad-0.10.0.dist-info/RECORD +0 -77
  87. {tinygrad-0.10.0.dist-info → tinygrad-0.10.2.dist-info}/LICENSE +0 -0
  88. {tinygrad-0.10.0.dist-info → tinygrad-0.10.2.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,178 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en-us">
3
+ <head>
4
+ <style>
5
+ * {
6
+ margin: 0;
7
+ padding: 0;
8
+ box-sizing: border-box;
9
+ }
10
+
11
+ body, html {
12
+ width: 100%;
13
+ height: 100%;
14
+ overflow: hidden;
15
+ font-family: "Noto Sans", sans-serif;
16
+ font-optical-sizing: auto;
17
+ font-weight: 400;
18
+ font-style: normal;
19
+ font-variation-settings: "wdth" 100;
20
+ font-size: 14px;
21
+ }
22
+
23
+ header {
24
+ width: 100%;
25
+ height: 48px;
26
+ background: #0f1018;
27
+ }
28
+
29
+ #perfetto_frame {
30
+ width: 100vw;
31
+ height: calc(100vh - 40px);
32
+ border: none;
33
+ }
34
+
35
+ #loading_screen {
36
+ position: fixed;
37
+ top: 0;
38
+ left: 0;
39
+ width: 100vw;
40
+ height: 100vh;
41
+ background: #0f1018;
42
+ display: flex;
43
+ flex-direction: column;
44
+ justify-content: center;
45
+ align-items: center;
46
+ color: white;
47
+ font-family: Arial, sans-serif;
48
+ z-index: 1;
49
+ }
50
+
51
+ .loader {
52
+ width: 48px;
53
+ height: 48px;
54
+ border: 5px solid #FFF;
55
+ border-bottom-color: transparent;
56
+ border-radius: 50%;
57
+ margin-bottom: 20px;
58
+ animation: rotation 1s linear infinite;
59
+ }
60
+
61
+ @keyframes rotation {
62
+ 0% { transform: rotate(0deg); }
63
+ 100% { transform: rotate(360deg); }
64
+ }
65
+
66
+ #loading_text {
67
+ font-size: 18px;
68
+ }
69
+
70
+ .floating-container {
71
+ position: fixed;
72
+ top: 8px;
73
+ left: 16px;
74
+ z-index: 4;
75
+ display: flex;
76
+ flex-direction: row;
77
+ gap: 8px;
78
+ }
79
+ .nav-btn {
80
+ background-color: #1a1b26;
81
+ border: 1px solid #4a4b56;
82
+ color: #f0f0f5;
83
+ height: 32px;
84
+ border-radius: 8px;
85
+ cursor: pointer;
86
+ text-decoration: none;
87
+ display: flex;
88
+ align-items: center;
89
+ padding: 0 6px;
90
+ font-weight: bold;
91
+ }
92
+ .btn {
93
+ height: 32px;
94
+ background-color: #1a1b26;
95
+ border: 1px solid #4a4b56;
96
+ color: #f0f0f5;
97
+ border-radius: 8px;
98
+ cursor: pointer;
99
+ transition-duration: .5s;
100
+ }
101
+ .btn:hover {
102
+ background-color: #2a2b36;
103
+ border-color: #5a5b66;
104
+ color: #ffffff;
105
+ transform: translateY(-1px);
106
+ }
107
+ </style>
108
+ </head>
109
+ <body>
110
+ <header></header>
111
+ <div class="floating-container">
112
+ <a class="btn nav-btn" href="/">UOps</a>
113
+ </div>
114
+
115
+ <div id="loading_screen">
116
+ <div class="loader" id="spinner"></div>
117
+ <div id="loading_text">Loading trace data...</div>
118
+ </div>
119
+
120
+ <iframe id="perfetto_frame" src="https://ui.perfetto.dev" allow="clipboard-write"></iframe>
121
+
122
+ <script type="text/javascript">
123
+ const ORIGIN = 'https://ui.perfetto.dev';
124
+ const API_ENDPOINT = '/get_profile';
125
+ const iframe = document.getElementById('perfetto_frame');
126
+ const loadingScreen = document.getElementById('loading_screen');
127
+
128
+ async function fetchFromApi() {
129
+ try {
130
+ const response = await fetch(API_ENDPOINT);
131
+ if (!response.ok) {
132
+ throw new Error(`HTTP error! status: ${response.status}`);
133
+ }
134
+ const jsonData = await response.json();
135
+
136
+ // Convert JSON to string and then to blob
137
+ const jsonString = JSON.stringify(jsonData);
138
+ const blob = new Blob([jsonString], { type: 'application/json' });
139
+ const arrayBuffer = await blob.arrayBuffer();
140
+
141
+ openTrace(arrayBuffer);
142
+ } catch (error) {
143
+ document.getElementById('spinner').remove();
144
+ document.getElementById('loading_text').innerHTML = 'Error loading trace data.<br>Please ensure PROFILE=1 is set and the VIZ server is running.';
145
+ console.error('Error loading trace:', error);
146
+ }
147
+ }
148
+
149
+ function openTrace(arrayBuffer) {
150
+ const timer = setInterval(() => iframe.contentWindow.postMessage('PING', ORIGIN), 50);
151
+
152
+ const onMessageHandler = (evt) => {
153
+ if (evt.data !== 'PONG') return;
154
+ loadingScreen.style.transition = 'opacity 0.5s';
155
+ loadingScreen.style.opacity = '0';
156
+ setTimeout(() => {
157
+ loadingScreen.style.display = 'none';
158
+ }, 500);
159
+
160
+ window.clearInterval(timer);
161
+ window.removeEventListener('message', onMessageHandler);
162
+
163
+ iframe.contentWindow.postMessage({
164
+ perfetto: {
165
+ buffer: arrayBuffer,
166
+ title: 'Profile Viewer',
167
+ url: location.href,
168
+ }
169
+ }, ORIGIN);
170
+ };
171
+
172
+ window.addEventListener('message', onMessageHandler);
173
+ }
174
+
175
+ window.onload = fetchFromApi;
176
+ </script>
177
+ </body>
178
+ </html>
tinygrad/viz/serve.py ADDED
@@ -0,0 +1,205 @@
1
+ #!/usr/bin/env python3
2
+ import multiprocessing, pickle, functools, difflib, os, threading, json, time, sys, webbrowser, socket, argparse, decimal
3
+ from http.server import HTTPServer, BaseHTTPRequestHandler
4
+ from urllib.parse import parse_qs, urlparse
5
+ from typing import Any, Callable, TypedDict, Generator
6
+ from tinygrad.helpers import colored, getenv, tqdm, unwrap, word_wrap
7
+ from tinygrad.ops import TrackedGraphRewrite, UOp, Ops, lines, GroupOp
8
+ from tinygrad.codegen.kernel import Kernel
9
+ from tinygrad.device import ProfileEvent, ProfileDeviceEvent, ProfileRangeEvent, ProfileGraphEvent
10
+ from tinygrad.dtype import dtypes
11
+
12
+ uops_colors = {Ops.LOAD: "#ffc0c0", Ops.STORE: "#87CEEB", Ops.CONST: "#e0e0e0", Ops.VCONST: "#e0e0e0",
13
+ Ops.DEFINE_GLOBAL: "#ffe0b0", Ops.DEFINE_LOCAL: "#ffe0d0", Ops.DEFINE_ACC: "#f0ffe0", Ops.REDUCE_AXIS: "#FF6B6B",
14
+ Ops.RANGE: "#c8a0e0", Ops.ASSIGN: "#e0ffc0", Ops.BARRIER: "#ff8080", Ops.IF: "#c8b0c0", Ops.SPECIAL: "#c0c0ff",
15
+ Ops.INDEX: "#e8ffa0", Ops.WMMA: "#efefc0", Ops.VIEW: "#C8F9D4", Ops.MULTI: "#f6ccff", Ops.KERNEL: "#3e7f55",
16
+ **{x:"#D8F9E4" for x in GroupOp.Movement}, **{x:"#ffffc0" for x in GroupOp.ALU}, Ops.THREEFRY:"#ffff80",
17
+ Ops.BLOCK: "#C4A484", Ops.BLOCKEND: "#C4A4A4", Ops.BUFFER: "#B0BDFF", Ops.COPY: "#a040a0", Ops.NAME:"#808080"}
18
+
19
+ # VIZ API
20
+
21
+ # NOTE: if any extra rendering in VIZ fails, we don't crash
22
+ def pcall(fxn:Callable[..., str], *args, **kwargs) -> str:
23
+ try: return fxn(*args, **kwargs)
24
+ except Exception as e: return f"ERROR: {e}"
25
+
26
+ # ** Metadata for a track_rewrites scope
27
+
28
+ class GraphRewriteMetadata(TypedDict):
29
+ loc: tuple[str, int] # [path, lineno] calling graph_rewrite
30
+ match_count: int # total match count in this context
31
+ code_line: str # source code calling graph_rewrite
32
+ kernel_code: str|None # optionally render the final kernel code
33
+ name: str|None # optional name of the rewrite
34
+
35
+ @functools.lru_cache(None)
36
+ def _prg(k:Kernel): return k.to_program().src
37
+ def to_metadata(k:Any, v:TrackedGraphRewrite) -> GraphRewriteMetadata:
38
+ return {"loc":v.loc, "match_count":len(v.matches), "code_line":lines(v.loc[0])[v.loc[1]-1].strip(),
39
+ "kernel_code":pcall(_prg, k) if isinstance(k, Kernel) else None, "name":v.name}
40
+ def get_metadata(keys:list[Any], contexts:list[list[TrackedGraphRewrite]]) -> list[tuple[str, list[GraphRewriteMetadata]]]:
41
+ return [(k.name if isinstance(k, Kernel) else str(k), [to_metadata(k, v) for v in vals]) for k,vals in zip(keys, contexts)]
42
+
43
+ # ** Complete rewrite details for a graph_rewrite call
44
+
45
+ class GraphRewriteDetails(TypedDict):
46
+ graph: dict # JSON serialized UOp for this rewrite step
47
+ uop: str # strigified UOp for this rewrite step
48
+ diff: list[str]|None # string diff of the single UOp that changed
49
+ changed_nodes: list[int]|None # the changed UOp id + all its parents ids
50
+ upat: tuple[tuple[str, int], str]|None # [loc, source_code] of the matched UPat
51
+
52
+ def uop_to_json(x:UOp) -> dict[int, tuple[str, list[int], str]]:
53
+ assert isinstance(x, UOp)
54
+ # NOTE: this is [id, [label, src_ids, color]]
55
+ graph: dict[int, tuple[str, list[int], str]] = {}
56
+ excluded: set[UOp] = set()
57
+ for u in (toposort:=x.toposort):
58
+ # always exclude DEVICE/CONST/UNIQUE
59
+ if u.op in {Ops.DEVICE, Ops.CONST, Ops.UNIQUE}: excluded.add(u)
60
+ # only exclude CONST VIEW source if it has no other children in the graph
61
+ if u.op is Ops.CONST and len(u.src) != 0 and all(cr.op is Ops.CONST for c in u.src[0].children if (cr:=c()) is not None and cr in toposort):
62
+ excluded.update(u.src)
63
+ for u in toposort:
64
+ if u in excluded: continue
65
+ argst = str(u.arg)
66
+ if u.op is Ops.VIEW:
67
+ argst = ("\n".join([f"{v.shape} / {v.strides}"+(f"\nMASK {v.mask}" if v.mask is not None else "")+
68
+ ("" if v.offset == 0 else f" / {v.offset}") for v in unwrap(u.st).views]))
69
+ label = f"{str(u.op).split('.')[1]}{(chr(10)+word_wrap(argst.replace(':', ''))) if u.arg is not None else ''}"
70
+ if u.dtype != dtypes.void: label += f"\n{u.dtype}"
71
+ for idx,x in enumerate(u.src):
72
+ if x in excluded:
73
+ if x.op is Ops.CONST and dtypes.is_float(u.dtype): label += f"\nCONST{idx} {x.arg:g}"
74
+ else: label += f"\n{x.op.name}{idx} {x.arg}"
75
+ graph[id(u)] = (label, [id(x) for x in u.src if x not in excluded], uops_colors.get(u.op, "#ffffff"))
76
+ return graph
77
+
78
+ def get_details(k:Any, ctx:TrackedGraphRewrite) -> Generator[GraphRewriteDetails, None, None]:
79
+ yield {"graph":uop_to_json(next_sink:=ctx.sink), "uop":str(ctx.sink), "changed_nodes":None, "diff":None, "upat":None}
80
+ replaces: dict[UOp, UOp] = {}
81
+ for u0,u1,upat in tqdm(ctx.matches):
82
+ replaces[u0] = u1
83
+ new_sink = next_sink.substitute(replaces)
84
+ yield {"graph": (sink_json:=uop_to_json(new_sink)), "uop":str(new_sink), "changed_nodes":[id(x) for x in u1.toposort if id(x) in sink_json],
85
+ "diff":list(difflib.unified_diff(pcall(str, u0).splitlines(), pcall(str, u1).splitlines())), "upat":(upat.location, upat.printable())}
86
+ if not ctx.bottom_up: next_sink = new_sink
87
+
88
+ # Profiler API
89
+ devices:dict[str, tuple[decimal.Decimal, decimal.Decimal, int]] = {}
90
+ def prep_ts(device:str, ts:decimal.Decimal, is_copy): return int(decimal.Decimal(ts) + devices[device][is_copy])
91
+ def dev_to_pid(device:str, is_copy=False): return {"pid": devices[device][2], "tid": int(is_copy)}
92
+ def dev_ev_to_perfetto_json(ev:ProfileDeviceEvent):
93
+ devices[ev.device] = (ev.comp_tdiff, ev.copy_tdiff if ev.copy_tdiff is not None else ev.comp_tdiff, len(devices))
94
+ return [{"name": "process_name", "ph": "M", "pid": dev_to_pid(ev.device)['pid'], "args": {"name": ev.device}},
95
+ {"name": "thread_name", "ph": "M", "pid": dev_to_pid(ev.device)['pid'], "tid": 0, "args": {"name": "COMPUTE"}},
96
+ {"name": "thread_name", "ph": "M", "pid": dev_to_pid(ev.device)['pid'], "tid": 1, "args": {"name": "COPY"}}]
97
+ def range_ev_to_perfetto_json(ev:ProfileRangeEvent):
98
+ return [{"name": ev.name, "ph": "X", "ts": prep_ts(ev.device, ev.st, ev.is_copy), "dur": float(ev.en-ev.st), **dev_to_pid(ev.device, ev.is_copy)}]
99
+ def graph_ev_to_perfetto_json(ev:ProfileGraphEvent, reccnt):
100
+ ret = []
101
+ for i,e in enumerate(ev.ents):
102
+ st, en = ev.sigs[e.st_id], ev.sigs[e.en_id]
103
+ ret += [{"name": e.name, "ph": "X", "ts": prep_ts(e.device, st, e.is_copy), "dur": float(en-st), **dev_to_pid(e.device, e.is_copy)}]
104
+ for dep in ev.deps[i]:
105
+ d = ev.ents[dep]
106
+ ret += [{"ph": "s", **dev_to_pid(d.device, d.is_copy), "id": reccnt+len(ret), "ts": prep_ts(d.device, ev.sigs[d.en_id], d.is_copy), "bp": "e"}]
107
+ ret += [{"ph": "f", **dev_to_pid(e.device, e.is_copy), "id": reccnt+len(ret)-1, "ts": prep_ts(e.device, st, e.is_copy), "bp": "e"}]
108
+ return ret
109
+ def to_perfetto(profile:list[ProfileEvent]):
110
+ # Start json with devices.
111
+ prof_json = [x for ev in profile if isinstance(ev, ProfileDeviceEvent) for x in dev_ev_to_perfetto_json(ev)]
112
+ for ev in tqdm(profile, desc="preparing profile"):
113
+ if isinstance(ev, ProfileRangeEvent): prof_json += range_ev_to_perfetto_json(ev)
114
+ elif isinstance(ev, ProfileGraphEvent): prof_json += graph_ev_to_perfetto_json(ev, reccnt=len(prof_json))
115
+ return json.dumps({"traceEvents": prof_json}).encode() if len(prof_json) > 0 else None
116
+
117
+ # ** HTTP server
118
+
119
+ class Handler(BaseHTTPRequestHandler):
120
+ def do_GET(self):
121
+ ret, status_code, content_type = b"", 200, "text/html"
122
+
123
+ if (url:=urlparse(self.path)).path == "/":
124
+ with open(os.path.join(os.path.dirname(__file__), "index.html"), "rb") as f: ret = f.read()
125
+ elif (url:=urlparse(self.path)).path == "/profiler":
126
+ with open(os.path.join(os.path.dirname(__file__), "perfetto.html"), "rb") as f: ret = f.read()
127
+ elif self.path.startswith("/assets/") and '/..' not in self.path:
128
+ try:
129
+ with open(os.path.join(os.path.dirname(__file__), self.path.strip('/')), "rb") as f: ret = f.read()
130
+ if url.path.endswith(".js"): content_type = "application/javascript"
131
+ if url.path.endswith(".css"): content_type = "text/css"
132
+ except FileNotFoundError: status_code = 404
133
+ elif url.path == "/kernels":
134
+ if "kernel" in (query:=parse_qs(url.query)):
135
+ def getarg(k:str,default=0): return int(query[k][0]) if k in query else default
136
+ kidx, ridx = getarg("kernel"), getarg("idx")
137
+ try:
138
+ # stream details
139
+ self.send_response(200)
140
+ self.send_header("Content-Type", "text/event-stream")
141
+ self.send_header("Cache-Control", "no-cache")
142
+ self.end_headers()
143
+ for r in get_details(contexts[0][kidx], contexts[1][kidx][ridx]):
144
+ self.wfile.write(f"data: {json.dumps(r)}\n\n".encode("utf-8"))
145
+ self.wfile.flush()
146
+ self.wfile.write("data: END\n\n".encode("utf-8"))
147
+ return self.wfile.flush()
148
+ # pass if client closed connection
149
+ except (BrokenPipeError, ConnectionResetError): return
150
+ ret, content_type = json.dumps(kernels).encode(), "application/json"
151
+ elif url.path == "/get_profile" and perfetto_profile is not None: ret, content_type = perfetto_profile, "application/json"
152
+ else: status_code = 404
153
+
154
+ # send response
155
+ self.send_response(status_code)
156
+ self.send_header('Content-Type', content_type)
157
+ self.send_header('Content-Length', str(len(ret)))
158
+ self.end_headers()
159
+ return self.wfile.write(ret)
160
+
161
+ # ** main loop
162
+
163
+ def reloader():
164
+ mtime = os.stat(__file__).st_mtime
165
+ while not stop_reloader.is_set():
166
+ if mtime != os.stat(__file__).st_mtime:
167
+ print("reloading server...")
168
+ os.execv(sys.executable, [sys.executable] + sys.argv)
169
+ time.sleep(0.1)
170
+
171
+ def load_pickle(path:str):
172
+ if path is None or not os.path.exists(path): return None
173
+ with open(path, "rb") as f: return pickle.load(f)
174
+
175
+ if __name__ == "__main__":
176
+ parser = argparse.ArgumentParser()
177
+ parser.add_argument('--kernels', type=str, help='Path to kernels', default=None)
178
+ parser.add_argument('--profile', type=str, help='Path profile', default=None)
179
+ args = parser.parse_args()
180
+
181
+ with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
182
+ if s.connect_ex(((HOST:="http://127.0.0.1").replace("http://", ""), PORT:=getenv("PORT", 8000))) == 0:
183
+ raise RuntimeError(f"{HOST}:{PORT} is occupied! use PORT= to change.")
184
+ stop_reloader = threading.Event()
185
+ multiprocessing.current_process().name = "VizProcess" # disallow opening of devices
186
+ st = time.perf_counter()
187
+ print("*** viz is starting")
188
+
189
+ contexts, profile = load_pickle(args.kernels), load_pickle(args.profile)
190
+
191
+ # NOTE: this context is a tuple of list[keys] and list[values]
192
+ kernels = get_metadata(*contexts) if contexts is not None else []
193
+
194
+ perfetto_profile = to_perfetto(profile) if profile is not None else None
195
+
196
+ server = HTTPServer(('', PORT), Handler)
197
+ reloader_thread = threading.Thread(target=reloader)
198
+ reloader_thread.start()
199
+ print(f"*** started viz on {HOST}:{PORT}")
200
+ print(colored(f"*** ready in {(time.perf_counter()-st)*1e3:4.2f}ms", "green"))
201
+ if len(getenv("BROWSER", "")) > 0: webbrowser.open(f"{HOST}:{PORT}{'/profiler' if contexts is None else ''}")
202
+ try: server.serve_forever()
203
+ except KeyboardInterrupt:
204
+ print("*** viz is shutting down...")
205
+ stop_reloader.set()
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: tinygrad
3
- Version: 0.10.0
3
+ Version: 0.10.2
4
4
  Summary: You like pytorch? You like micrograd? You love tinygrad! <3
5
5
  Author: George Hotz
6
6
  License: MIT
@@ -11,29 +11,37 @@ Description-Content-Type: text/markdown
11
11
  License-File: LICENSE
12
12
  Provides-Extra: arm
13
13
  Requires-Dist: unicorn; extra == "arm"
14
- Provides-Extra: docs
15
- Requires-Dist: mkdocs; extra == "docs"
16
- Requires-Dist: mkdocs-material; extra == "docs"
17
- Requires-Dist: mkdocstrings[python]; extra == "docs"
18
- Requires-Dist: markdown-callouts; extra == "docs"
19
- Requires-Dist: markdown-exec[ansi]; extra == "docs"
20
- Requires-Dist: black; extra == "docs"
21
- Requires-Dist: numpy; extra == "docs"
14
+ Provides-Extra: triton
15
+ Requires-Dist: triton-nightly>=2.1.0.dev20231014192330; extra == "triton"
22
16
  Provides-Extra: linting
23
17
  Requires-Dist: pylint; extra == "linting"
24
- Requires-Dist: mypy==1.11.2; extra == "linting"
18
+ Requires-Dist: mypy==1.13.0; extra == "linting"
25
19
  Requires-Dist: typing-extensions; extra == "linting"
26
20
  Requires-Dist: pre-commit; extra == "linting"
27
21
  Requires-Dist: ruff; extra == "linting"
28
22
  Requires-Dist: types-tqdm; extra == "linting"
29
- Provides-Extra: llvm
30
- Requires-Dist: llvmlite; extra == "llvm"
23
+ Provides-Extra: testing-minimal
24
+ Requires-Dist: numpy; extra == "testing-minimal"
25
+ Requires-Dist: torch; extra == "testing-minimal"
26
+ Requires-Dist: pytest; extra == "testing-minimal"
27
+ Requires-Dist: pytest-xdist; extra == "testing-minimal"
28
+ Requires-Dist: hypothesis; extra == "testing-minimal"
29
+ Provides-Extra: testing-unit
30
+ Requires-Dist: numpy; extra == "testing-unit"
31
+ Requires-Dist: torch; extra == "testing-unit"
32
+ Requires-Dist: pytest; extra == "testing-unit"
33
+ Requires-Dist: pytest-xdist; extra == "testing-unit"
34
+ Requires-Dist: hypothesis; extra == "testing-unit"
35
+ Requires-Dist: tqdm; extra == "testing-unit"
36
+ Requires-Dist: safetensors; extra == "testing-unit"
37
+ Requires-Dist: tabulate; extra == "testing-unit"
31
38
  Provides-Extra: testing
32
39
  Requires-Dist: numpy; extra == "testing"
33
40
  Requires-Dist: torch; extra == "testing"
34
- Requires-Dist: pillow; extra == "testing"
35
41
  Requires-Dist: pytest; extra == "testing"
36
42
  Requires-Dist: pytest-xdist; extra == "testing"
43
+ Requires-Dist: hypothesis; extra == "testing"
44
+ Requires-Dist: pillow; extra == "testing"
37
45
  Requires-Dist: onnx==1.16.0; extra == "testing"
38
46
  Requires-Dist: onnx2torch; extra == "testing"
39
47
  Requires-Dist: opencv-python; extra == "testing"
@@ -46,15 +54,29 @@ Requires-Dist: tiktoken; extra == "testing"
46
54
  Requires-Dist: blobfile; extra == "testing"
47
55
  Requires-Dist: librosa; extra == "testing"
48
56
  Requires-Dist: networkx; extra == "testing"
49
- Requires-Dist: hypothesis; extra == "testing"
50
57
  Requires-Dist: nibabel; extra == "testing"
51
58
  Requires-Dist: bottle; extra == "testing"
52
59
  Requires-Dist: ggml-python; extra == "testing"
53
- Provides-Extra: testing_tf
60
+ Requires-Dist: capstone; extra == "testing"
61
+ Provides-Extra: docs
62
+ Requires-Dist: mkdocs; extra == "docs"
63
+ Requires-Dist: mkdocs-material; extra == "docs"
64
+ Requires-Dist: mkdocstrings[python]; extra == "docs"
65
+ Requires-Dist: markdown-callouts; extra == "docs"
66
+ Requires-Dist: markdown-exec[ansi]; extra == "docs"
67
+ Requires-Dist: black; extra == "docs"
68
+ Requires-Dist: numpy; extra == "docs"
69
+ Provides-Extra: testing-tf
54
70
  Requires-Dist: tensorflow==2.15.1; extra == "testing-tf"
55
- Requires-Dist: tensorflow-addons; extra == "testing-tf"
56
- Provides-Extra: triton
57
- Requires-Dist: triton-nightly>=2.1.0.dev20231014192330; extra == "triton"
71
+ Requires-Dist: tensorflow_addons; extra == "testing-tf"
72
+ Dynamic: author
73
+ Dynamic: classifier
74
+ Dynamic: description
75
+ Dynamic: description-content-type
76
+ Dynamic: license
77
+ Dynamic: provides-extra
78
+ Dynamic: requires-python
79
+ Dynamic: summary
58
80
 
59
81
  <div align="center">
60
82
 
@@ -139,13 +161,14 @@ See [examples/beautiful_mnist.py](examples/beautiful_mnist.py) for the full vers
139
161
  tinygrad already supports numerous accelerators, including:
140
162
 
141
163
  - [x] [GPU (OpenCL)](tinygrad/runtime/ops_gpu.py)
142
- - [x] [CLANG (C Code)](tinygrad/runtime/ops_clang.py)
164
+ - [x] [CPU (C Code)](tinygrad/runtime/ops_cpu.py)
143
165
  - [x] [LLVM](tinygrad/runtime/ops_llvm.py)
144
166
  - [x] [METAL](tinygrad/runtime/ops_metal.py)
145
167
  - [x] [CUDA](tinygrad/runtime/ops_cuda.py)
146
168
  - [x] [AMD](tinygrad/runtime/ops_amd.py)
147
169
  - [x] [NV](tinygrad/runtime/ops_nv.py)
148
170
  - [x] [QCOM](tinygrad/runtime/ops_qcom.py)
171
+ - [x] [WEBGPU](tinygrad/runtime/ops_webgpu.py)
149
172
 
150
173
  And it is easy to add more! Your accelerator of choice only needs to support a total of ~25 low level ops.
151
174
 
@@ -183,8 +206,8 @@ y = Tensor([[2.0,0,-2.0]], requires_grad=True)
183
206
  z = y.matmul(x).sum()
184
207
  z.backward()
185
208
 
186
- print(x.grad.numpy()) # dz/dx
187
- print(y.grad.numpy()) # dz/dy
209
+ print(x.grad.tolist()) # dz/dx
210
+ print(y.grad.tolist()) # dz/dy
188
211
  ```
189
212
 
190
213
  The same thing but in PyTorch:
@@ -196,8 +219,8 @@ y = torch.tensor([[2.0,0,-2.0]], requires_grad=True)
196
219
  z = y.matmul(x).sum()
197
220
  z.backward()
198
221
 
199
- print(x.grad.numpy()) # dz/dx
200
- print(y.grad.numpy()) # dz/dy
222
+ print(x.grad.tolist()) # dz/dx
223
+ print(y.grad.tolist()) # dz/dy
201
224
  ```
202
225
 
203
226
  ## Contributing
@@ -208,7 +231,7 @@ We'll start with what will get your PR closed with a pointer to this section:
208
231
 
209
232
  - No code golf! While low line count is a guiding light of this project, anything that remotely looks like code golf will be closed. The true goal is reducing complexity and increasing readability, and deleting `\n`s does nothing to help with that.
210
233
  - All docs and whitespace changes will be closed unless you are a well-known contributor. The people writing the docs should be those who know the codebase the absolute best. People who have not demonstrated that shouldn't be messing with docs. Whitespace changes are both useless *and* carry a risk of introducing bugs.
211
- - Anything you claim is a "speedup" must be benchmarked. In general, the goal is simplicity, so even if your PR makes things marginally faster, you have to consider the tradeoff with maintainablity and readablity.
234
+ - Anything you claim is a "speedup" must be benchmarked. In general, the goal is simplicity, so even if your PR makes things marginally faster, you have to consider the tradeoff with maintainability and readability.
212
235
  - In general, the code outside the core `tinygrad/` folder is not well tested, so unless the current code there is broken, you shouldn't be changing it.
213
236
  - If your PR looks "complex", is a big diff, or adds lots of lines, it won't be reviewed or merged. Consider breaking it up into smaller PRs that are individually clear wins. A common pattern I see is prerequisite refactors before adding new functionality. If you can (cleanly) refactor to the point that the feature is a 3 line change, this is great, and something easy for us to review.
214
237
 
@@ -0,0 +1,99 @@
1
+ tinygrad/__init__.py,sha256=2Jhg7NSWlegCi4OAfGW0iHRVHeqMx09f7446rwAmc60,587
2
+ tinygrad/device.py,sha256=y40tIC5HWH0GJgoiE-BoL-R1wNtwn0k9AuWpQS2VH-w,19927
3
+ tinygrad/dtype.py,sha256=HkfFDmPFi2CFUJ3cXoN8hd8W0b6dtK8inRr_wNoBeBE,10245
4
+ tinygrad/gradient.py,sha256=4FbtPDt3lFFLthq-uZMS1UPHqx-ssgrI3tlNTRUJAAw,4582
5
+ tinygrad/helpers.py,sha256=14xmrdja59H3CyIchRe-IX61jCyuzxrT2nJ59SAbAZc,19523
6
+ tinygrad/ops.py,sha256=Pdr96zni5LS31nR7RcvxcW4czXTSKjtOi-Z0lruL0ok,54874
7
+ tinygrad/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
+ tinygrad/spec.py,sha256=5wIXRDSMwpQjnYE5kgplhTyo8yMSRdRFw5il8kpAMV0,8937
9
+ tinygrad/tensor.py,sha256=w3L_O41XHK_MzoTzIASB2MM0w4vLb3km_RrKYDR4hKk,185155
10
+ tinygrad/codegen/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
+ tinygrad/codegen/devectorizer.py,sha256=bp-9DYLoB8XIBGHIpMe9ok0W42riQbbseqiGXg1-MrE,13584
12
+ tinygrad/codegen/expander.py,sha256=U_cJVu4I65c2k4a8MjwKi16iSg0QD2oP1TajmVWB3Ls,5978
13
+ tinygrad/codegen/kernel.py,sha256=9_bFVibBpoGkqhRit6dVxitxBUIulmJpGf-LAG474og,42808
14
+ tinygrad/codegen/linearize.py,sha256=cs50ZG_AmeXvWOOV6ig7zUZhMcd2dxumsc0kjI6NyTY,10853
15
+ tinygrad/codegen/lowerer.py,sha256=Ap8TAxzx3pAOVAUIFndeSMXf79TZxd8HveZraOeK4Qo,8935
16
+ tinygrad/codegen/symbolic.py,sha256=VoZ1h3B5ewIjC-fNHpd2h2beyePfuBThgneWMfCJMI8,29831
17
+ tinygrad/codegen/transcendental.py,sha256=tlQvQ4xJ2tjWyB_0ZmmTUvvVj05qffsVvkBaAQnnvVU,13733
18
+ tinygrad/engine/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
+ tinygrad/engine/jit.py,sha256=Y1CRXauO-ySlpyO2FV0Igr8N4UCjpLOjuIqYSrVE4oc,16797
20
+ tinygrad/engine/memory.py,sha256=UyiNYIoUjtcJ1SX6ApoCnbrSKZpbBbhfwr13TIaiqEM,3231
21
+ tinygrad/engine/multi.py,sha256=5I_2qULp1L8K_je3OZoqSVeOpzjW6COhThlu_j09l58,10336
22
+ tinygrad/engine/realize.py,sha256=rGDUWqYKx6h00Q4l-6BpT4sbe4ifbetjdiyBTTow6sA,9821
23
+ tinygrad/engine/schedule.py,sha256=-tzKWF3MarUizLMiHiLT-ssyfI1Se8OkafLCGtvPHZY,24633
24
+ tinygrad/engine/search.py,sha256=Uk2sfRhXvbgpRDjK4hIDO7dJFd2jdAxVkUde2SlKRIk,11685
25
+ tinygrad/nn/__init__.py,sha256=BAxMz-g7v-v1A32KaBzmGiaEnvQ_dU9d3KoPdYYwLDQ,15156
26
+ tinygrad/nn/datasets.py,sha256=wcT0Qrlpw_RzM7uBy8uphzKAjGT-ZE48fiP-0g3WvI0,1042
27
+ tinygrad/nn/optim.py,sha256=qfdYKi_ssX5O_DU6h8GJ0WCzBzAZLyyS3p_946PJNsQ,6816
28
+ tinygrad/nn/state.py,sha256=D7Q6yjGtfOf0pacVWRqJnaexiOxzOXlumMQXhieC_U0,16018
29
+ tinygrad/renderer/__init__.py,sha256=X0BJ3h45w3qWP_fVMadpjTBhGJltFB2XxgxK8aHnwPc,7615
30
+ tinygrad/renderer/cstyle.py,sha256=xOTSEGIJ0Sg1qeAAR8olro5_HnAjJkIWzr12AEIuRQs,31105
31
+ tinygrad/renderer/llvmir.py,sha256=T-8I1dLGIkzMF5AZCqvEz8SnpkMWZQC3VkbFSf7JDFA,11290
32
+ tinygrad/renderer/ptx.py,sha256=n58_vVi7eO3I4UIisRKCaKtzEZ5BO4Dle0yqMbDaI5s,14992
33
+ tinygrad/renderer/wgsl.py,sha256=zLUI2AqSe0o_kRFuLeZg3a3Qbfzy685NeFT2v-2odxY,7467
34
+ tinygrad/runtime/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
35
+ tinygrad/runtime/ops_amd.py,sha256=S0RBcJrIogrp0c5TMAk3ANTBwG5UUZbk13Yxgs3aTXk,37723
36
+ tinygrad/runtime/ops_cloud.py,sha256=1umLappzYKg0ECC9C_EN1lzXquAQVqY7wj-mS0vTcSk,10362
37
+ tinygrad/runtime/ops_cpu.py,sha256=mRiplNgA3rAYasy8VJd2GfYhuUVLp_x8V0xfBvJ7xik,1356
38
+ tinygrad/runtime/ops_cuda.py,sha256=26ko2bTLT_jDmU2i8_xiL4BomD9krzvlz6wY5FE-e5c,7138
39
+ tinygrad/runtime/ops_disk.py,sha256=pLIpvzlCVN47qBJ99nVEuwzYB3V0kuDldqG0XZBAblo,6642
40
+ tinygrad/runtime/ops_dsp.py,sha256=m4hiegBFqEShmcJoBq3htaepivoFxbn1MWASqsR__jY,18737
41
+ tinygrad/runtime/ops_gpu.py,sha256=VrY9iM5i44OQwTJE8sgUavCtr1TOpE96I5-JmqUFz-E,8972
42
+ tinygrad/runtime/ops_hip.py,sha256=MbR4depxgHcaGpOJGvUCiLq5tdbpaDiqs-Xj41rY2xQ,3730
43
+ tinygrad/runtime/ops_llvm.py,sha256=eiJ_UVlm_uX39j4K0-x6QTszxHwwv67I2g4F1ZGSyDk,3446
44
+ tinygrad/runtime/ops_metal.py,sha256=zzZOhEhPfuK-_WIdX-ewuDq66KWtqnKEdVUCAa00XeU,14336
45
+ tinygrad/runtime/ops_npy.py,sha256=8VNf1S5M_MRk9d3GxSsTPbfEz7I_aOwl7QMZ1mUG3As,370
46
+ tinygrad/runtime/ops_nv.py,sha256=thiu7q_vDeJUvlnR6wYXtMni0OrRMXzrbwdf596Ilyc,34855
47
+ tinygrad/runtime/ops_python.py,sha256=OsFSI12f4tCrS3-pWtpyXMochbTfcOq4wX7BHQ1wdOM,11687
48
+ tinygrad/runtime/ops_qcom.py,sha256=Dt4hgAd6o13CxsOFRSt7lHY6bCOTLvtQpOr_jx_lYbc,22565
49
+ tinygrad/runtime/ops_webgpu.py,sha256=DgWHSckZybr6w52-YcODTheRyIolNQiQ6n4Lb4dcjNY,12852
50
+ tinygrad/runtime/autogen/adreno.py,sha256=u7VxIomPAlW3nFUs4gSTe-6ijam_ywkvDM9OuTLF-j8,897915
51
+ tinygrad/runtime/autogen/amd_gpu.py,sha256=Iasq-zYiv8bvT43dtvPO1W5jaLEQ3d6hP0CoFVhSsak,3977783
52
+ tinygrad/runtime/autogen/comgr.py,sha256=3pp3XyqEJDBLa9XtGx2-Gc1iJgBbbgIq4pdFEpYXT44,39874
53
+ tinygrad/runtime/autogen/cuda.py,sha256=N0QyaMvQumr_HZh7fusCHM1d4o4mYti3Wq1MN7JSKr8,243920
54
+ tinygrad/runtime/autogen/hip.py,sha256=1yUHDCwL3KkD15if2Q1Ud3GbJiR7DxsNorKZTCINw54,245532
55
+ tinygrad/runtime/autogen/hsa.py,sha256=7Hsrn17HmChyeFOSX_3Fnzl9c0COtq2Z2ExqGu5FNiU,277716
56
+ tinygrad/runtime/autogen/io_uring.py,sha256=ZIZ2YnQkLr8WIHMieBw9Dv-NZ1ar9TwdP4YBv3gJm28,59786
57
+ tinygrad/runtime/autogen/kfd.py,sha256=VdhuG4qec0EgM-jJmWcdTS-8WrmywNkcjSX7ibbmvdk,30866
58
+ tinygrad/runtime/autogen/kgsl.py,sha256=2EgJ5Kst4oRUv81hsV2srgwPvWpY-weaSB4E2lGMAyc,50656
59
+ tinygrad/runtime/autogen/libc.py,sha256=KYy7QfWKFJ6NEhGGmcNl7cWkbxl-_pfRADApGi1WQd0,209051
60
+ tinygrad/runtime/autogen/llvm.py,sha256=aeVd_ByohxbGRyqXzShPOupI2xtcdk34I6_OIBrMQHg,467606
61
+ tinygrad/runtime/autogen/nv_gpu.py,sha256=9X2tPdv2E5JmXGZeT8i9jL19YJ4ETTsYwfU_Wn9mTwc,1679326
62
+ tinygrad/runtime/autogen/nvrtc.py,sha256=19te2-TW5suFy85KnJox3CPOmeeml5YxqIDeL-Bx_m4,23132
63
+ tinygrad/runtime/autogen/opencl.py,sha256=NL6fa8P3KC_McNZ8g2babdr3b8vrY-bFK0qzNAtL-rE,82656
64
+ tinygrad/runtime/autogen/pci.py,sha256=XVo3T6F_7msIZO4uzqw4seWi0VNtHCx6gM8sZ5mdynE,56769
65
+ tinygrad/runtime/autogen/qcom_dsp.py,sha256=jx36-zC6reTuWgfbHCrKVjOZcF4Q9fBnq3CuTbxztQk,61848
66
+ tinygrad/runtime/autogen/vfio.py,sha256=IJV1eeWWllU6b9LAX_IH0bUW5NDzfhPQy_YzXGhD9-8,32431
67
+ tinygrad/runtime/autogen/webgpu.py,sha256=vVGL2l8_XPuC2Xis7gYseIwCmm9ZidEoXU3E34rtNIw,325072
68
+ tinygrad/runtime/graph/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
69
+ tinygrad/runtime/graph/cuda.py,sha256=vLjT_c93G6ia_1MsbYWP5Uq96Aeko0AOskRkwT5-MUI,4818
70
+ tinygrad/runtime/graph/hcq.py,sha256=kKu2YnjAZU40XMACSbbcxJSi2xdTg3OYLO2zcPLyAf0,12600
71
+ tinygrad/runtime/graph/metal.py,sha256=7xLmAUmNiV-QbcLohFZhAIQ_nWwQBbeNVZY8mp6Ou6o,5848
72
+ tinygrad/runtime/support/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
73
+ tinygrad/runtime/support/allocator.py,sha256=INW6TaJxMi4cwMEDtkta2wFH3kJ87wy3SyFFu3_jJ9w,4721
74
+ tinygrad/runtime/support/compiler_cuda.py,sha256=6cU1OMMW3aOUFNVALpDYWKXh-zFc5q81PSSQhRK9fLw,5471
75
+ tinygrad/runtime/support/compiler_hip.py,sha256=fbRP82UdG4T-KCRYH_H2hEXlMFeHIJntSnY35ZWE5JY,4398
76
+ tinygrad/runtime/support/elf.py,sha256=EEcH4giM149Tirzi_1ozpStWSCXh--hqHSkhNrLSgEQ,4045
77
+ tinygrad/runtime/support/hcq.py,sha256=IHZsThsCB1o_xW208fBQw9ztpM8pcPNK_kPSKcOD9mE,22022
78
+ tinygrad/runtime/support/llvm.py,sha256=zCg2WQjqYrNVf2XLUsud2BA41cndmAxC6MizR82OtPo,1500
79
+ tinygrad/runtime/support/am/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
80
+ tinygrad/runtime/support/am/amdev.py,sha256=GP24gjQ7DI__eEvT_w14CqJzWCG0GDIaK1XDXj84kys,21293
81
+ tinygrad/runtime/support/am/ip.py,sha256=8wIFEVdQghFe5bCSYx60gNpjrFCKhhrc6espW7KrCng,24430
82
+ tinygrad/shape/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
83
+ tinygrad/shape/shapetracker.py,sha256=Ts8u2tSqgxs1Do3y3jNIMCIbR0c-hoDTjyVIkxgHqI4,7671
84
+ tinygrad/shape/view.py,sha256=ciHPBhfn30iM0X0JCEQ_iyOihRgPdi9kFtIUj5QidNc,18074
85
+ tinygrad/viz/index.html,sha256=qwG7LCOf49wWR_VnyhQGWSHtx8i_YnoedyvoVmxR9uQ,18544
86
+ tinygrad/viz/perfetto.html,sha256=X5ouzfw20wbDdWCM7eEygCDhNPF7gKMRyNM7kyRjcIA,4458
87
+ tinygrad/viz/serve.py,sha256=djOJkZYY75sqzAQ6pYRsTgeMV0UwrZrJcbsEx7Eke4g,11395
88
+ tinygrad/viz/assets/cdnjs.cloudflare.com/ajax/libs/highlight.js/11.10.0/highlight.min.js,sha256=Rx75rpDEB69ED83Ejt_utWIQazJnvRLZkHHBYvtS7TI,124980
89
+ tinygrad/viz/assets/cdnjs.cloudflare.com/ajax/libs/highlight.js/11.10.0/languages/cpp.min.js,sha256=_PnmV6YOH2gDppRwZRZGvzbyuLOqfIXPKcOO7D_1dXM,6005
90
+ tinygrad/viz/assets/cdnjs.cloudflare.com/ajax/libs/highlight.js/11.10.0/languages/python.min.js,sha256=LD3MH9LYaIvzmcT-6MIg_poJtKvUOdifbSyyx2dzGlU,3590
91
+ tinygrad/viz/assets/cdnjs.cloudflare.com/ajax/libs/highlight.js/11.10.0/styles/default.min.css,sha256=-94KwJIdhsNWxBUy5zGciHojvRuP8ABgyrRHJJ8Dx88,1144
92
+ tinygrad/viz/assets/d3js.org/d3.v5.min.js,sha256=Xb6SSzhH3wEPC4Vy3W70Lqh9Y3Du_3KxPqI2JHQSpTw,248314
93
+ tinygrad/viz/assets/dagrejs.github.io/project/dagre-d3/latest/dagre-d3.min.js,sha256=dPm4TA8Y9PY5q5mmtWMkRGOCMHJDKy34ZrxdbBGA9cs,725181
94
+ tinygrad/viz/assets/unpkg.com/@highlightjs/cdn-assets@11.10.0/styles/tokyo-night-dark.min.css,sha256=PCTQRtLh4Cuei-tkH53GOcdv9ErYnw-6yeq5Bi1V9Rs,1234
95
+ tinygrad-0.10.2.dist-info/LICENSE,sha256=ABRhUPEILzINYIukgazD-_rPipkUNUwslrb0RxnV6Xc,1058
96
+ tinygrad-0.10.2.dist-info/METADATA,sha256=zxbkNx4Cxx28E19m8YnZzvLMzA6UrPtu8i1FchTAErc,11846
97
+ tinygrad-0.10.2.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
98
+ tinygrad-0.10.2.dist-info/top_level.txt,sha256=vDABMCWBFQnx2kn9Azueu88FP-1klQdePoHikQhHymc,9
99
+ tinygrad-0.10.2.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.5.0)
2
+ Generator: setuptools (75.8.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5