tinygrad 0.10.1__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.
- tinygrad/codegen/devectorizer.py +247 -0
- tinygrad/codegen/expander.py +121 -0
- tinygrad/codegen/kernel.py +35 -37
- tinygrad/codegen/linearize.py +19 -10
- tinygrad/codegen/lowerer.py +31 -8
- tinygrad/codegen/symbolic.py +476 -0
- tinygrad/codegen/transcendental.py +10 -0
- tinygrad/device.py +28 -11
- tinygrad/dtype.py +12 -3
- tinygrad/engine/jit.py +3 -2
- tinygrad/engine/multi.py +0 -1
- tinygrad/engine/realize.py +7 -4
- tinygrad/engine/schedule.py +227 -255
- tinygrad/engine/search.py +20 -27
- tinygrad/gradient.py +3 -0
- tinygrad/helpers.py +7 -4
- tinygrad/nn/state.py +2 -2
- tinygrad/ops.py +64 -329
- tinygrad/renderer/__init__.py +19 -3
- tinygrad/renderer/cstyle.py +39 -18
- tinygrad/renderer/llvmir.py +55 -18
- tinygrad/renderer/ptx.py +6 -2
- tinygrad/renderer/wgsl.py +20 -12
- tinygrad/runtime/autogen/libc.py +404 -71
- tinygrad/runtime/autogen/{libpciaccess.py → pci.py} +25 -715
- tinygrad/runtime/autogen/webgpu.py +6985 -0
- tinygrad/runtime/graph/metal.py +28 -29
- tinygrad/runtime/ops_amd.py +37 -34
- tinygrad/runtime/{ops_clang.py → ops_cpu.py} +4 -2
- tinygrad/runtime/ops_disk.py +1 -1
- tinygrad/runtime/ops_dsp.py +59 -33
- tinygrad/runtime/ops_llvm.py +14 -12
- tinygrad/runtime/ops_metal.py +78 -62
- tinygrad/runtime/ops_nv.py +9 -6
- tinygrad/runtime/ops_python.py +5 -5
- tinygrad/runtime/ops_webgpu.py +200 -38
- tinygrad/runtime/support/am/amdev.py +23 -11
- tinygrad/runtime/support/am/ip.py +10 -10
- tinygrad/runtime/support/elf.py +2 -0
- tinygrad/runtime/support/hcq.py +7 -5
- tinygrad/runtime/support/llvm.py +8 -14
- tinygrad/shape/shapetracker.py +3 -2
- tinygrad/shape/view.py +2 -3
- tinygrad/spec.py +21 -20
- tinygrad/tensor.py +150 -90
- tinygrad/viz/assets/cdnjs.cloudflare.com/ajax/libs/highlight.js/11.10.0/highlight.min.js +1232 -0
- tinygrad/viz/assets/cdnjs.cloudflare.com/ajax/libs/highlight.js/11.10.0/languages/cpp.min.js +47 -0
- tinygrad/viz/assets/cdnjs.cloudflare.com/ajax/libs/highlight.js/11.10.0/languages/python.min.js +42 -0
- tinygrad/viz/assets/cdnjs.cloudflare.com/ajax/libs/highlight.js/11.10.0/styles/default.min.css +9 -0
- tinygrad/viz/assets/d3js.org/d3.v5.min.js +2 -0
- tinygrad/viz/assets/dagrejs.github.io/project/dagre-d3/latest/dagre-d3.min.js +4816 -0
- tinygrad/viz/assets/unpkg.com/@highlightjs/cdn-assets@11.10.0/styles/tokyo-night-dark.min.css +8 -0
- tinygrad/viz/index.html +544 -0
- tinygrad/viz/perfetto.html +178 -0
- tinygrad/viz/serve.py +205 -0
- {tinygrad-0.10.1.dist-info → tinygrad-0.10.2.dist-info}/METADATA +20 -8
- tinygrad-0.10.2.dist-info/RECORD +99 -0
- tinygrad/codegen/rewriter.py +0 -516
- tinygrad-0.10.1.dist-info/RECORD +0 -86
- {tinygrad-0.10.1.dist-info → tinygrad-0.10.2.dist-info}/LICENSE +0 -0
- {tinygrad-0.10.1.dist-info → tinygrad-0.10.2.dist-info}/WHEEL +0 -0
- {tinygrad-0.10.1.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
1
|
Metadata-Version: 2.2
|
2
2
|
Name: tinygrad
|
3
|
-
Version: 0.10.
|
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
|
@@ -20,13 +20,28 @@ Requires-Dist: typing-extensions; extra == "linting"
|
|
20
20
|
Requires-Dist: pre-commit; extra == "linting"
|
21
21
|
Requires-Dist: ruff; extra == "linting"
|
22
22
|
Requires-Dist: types-tqdm; extra == "linting"
|
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"
|
23
38
|
Provides-Extra: testing
|
24
39
|
Requires-Dist: numpy; extra == "testing"
|
25
40
|
Requires-Dist: torch; extra == "testing"
|
26
|
-
Requires-Dist: jax; extra == "testing"
|
27
|
-
Requires-Dist: pillow; extra == "testing"
|
28
41
|
Requires-Dist: pytest; extra == "testing"
|
29
42
|
Requires-Dist: pytest-xdist; extra == "testing"
|
43
|
+
Requires-Dist: hypothesis; extra == "testing"
|
44
|
+
Requires-Dist: pillow; extra == "testing"
|
30
45
|
Requires-Dist: onnx==1.16.0; extra == "testing"
|
31
46
|
Requires-Dist: onnx2torch; extra == "testing"
|
32
47
|
Requires-Dist: opencv-python; extra == "testing"
|
@@ -39,13 +54,10 @@ Requires-Dist: tiktoken; extra == "testing"
|
|
39
54
|
Requires-Dist: blobfile; extra == "testing"
|
40
55
|
Requires-Dist: librosa; extra == "testing"
|
41
56
|
Requires-Dist: networkx; extra == "testing"
|
42
|
-
Requires-Dist: hypothesis; extra == "testing"
|
43
57
|
Requires-Dist: nibabel; extra == "testing"
|
44
58
|
Requires-Dist: bottle; extra == "testing"
|
45
59
|
Requires-Dist: ggml-python; extra == "testing"
|
46
60
|
Requires-Dist: capstone; extra == "testing"
|
47
|
-
Provides-Extra: webgpu
|
48
|
-
Requires-Dist: wgpu; extra == "webgpu"
|
49
61
|
Provides-Extra: docs
|
50
62
|
Requires-Dist: mkdocs; extra == "docs"
|
51
63
|
Requires-Dist: mkdocs-material; extra == "docs"
|
@@ -149,7 +161,7 @@ See [examples/beautiful_mnist.py](examples/beautiful_mnist.py) for the full vers
|
|
149
161
|
tinygrad already supports numerous accelerators, including:
|
150
162
|
|
151
163
|
- [x] [GPU (OpenCL)](tinygrad/runtime/ops_gpu.py)
|
152
|
-
- [x] [
|
164
|
+
- [x] [CPU (C Code)](tinygrad/runtime/ops_cpu.py)
|
153
165
|
- [x] [LLVM](tinygrad/runtime/ops_llvm.py)
|
154
166
|
- [x] [METAL](tinygrad/runtime/ops_metal.py)
|
155
167
|
- [x] [CUDA](tinygrad/runtime/ops_cuda.py)
|
@@ -219,7 +231,7 @@ We'll start with what will get your PR closed with a pointer to this section:
|
|
219
231
|
|
220
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.
|
221
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.
|
222
|
-
- 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
|
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.
|
223
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.
|
224
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.
|
225
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,,
|