neural-doom / app.py
Quazim0t0's picture
Stability: cap per-tick work at a wall-time budget < timer interval (prevents HF worker backup/freeze on slow CPU)
ff17f40 verified
Raw
History Blame Contribute Delete
23.4 kB
"""
Neural DOOM -- ZeroGPU Gradio Space, chromatic dark UI.
DOOM runs on an i386 core whose every datapath unit (decode, ALU slices,
shifts, multiplier slices) is a neural network verified bit-exact over its
COMPLETE input domain. A full frame (5,952,699 instructions) was replayed
fully neurally and came out bit-identical to the golden run -- framebuffer
and all 128 MB of machine state.
Interactives:
* ZeroGPU: re-verify ALL 13 units exhaustively on the H200, live
* run a live neural execution segment from the title-frame snapshot,
bit-checked against the golden reference hash
* instruction microscope: single-step real DOOM code and watch every
neural unit fire, slice by slice
Assets (unit weights, DOOM binary, WAD, snapshot) come from a private HF
repo via the HF_TOKEN Space secret.
"""
import os, json, time, hashlib
import numpy as np
import gradio as gr
import spaces
import torch
from huggingface_hub import snapshot_download
ASSETS_REPO = "Quazim0t0/neural-x86-doom"
ASSETS = snapshot_download(ASSETS_REPO, token=os.environ.get("HF_TOKEN"))
os.environ["CORE386_PATH"] = os.path.join(ASSETS, "core386.so" if os.name != "nt"
else "core386.dll")
import x86_units
x86_units.CACHE = os.path.join(ASSETS, "models")
from x86_units import build_all, NeuralUnits, GoldenUnits, ALU, BitMLP
from x86_units import (u_ADC8, u_SBB8, u_logic, u_SHL1, u_SHR1, u_MASK8,
u_NOT8, u_FLAGS8, u_prefix, u_modrm, u_sib)
from x86_linux import Linux386
SNAP = np.load(os.path.join(ASSETS, "doom_snapshot.npz"))
GOLDEN_REFS = json.load(open(os.path.join(ASSETS, "doom_golden_refs.json")))
ELF = open(os.path.join(ASSETS, "doom_i386"), "rb").read()
WAD = open(os.path.join(ASSETS, "doom1.wad"), "rb").read()
def title_frame_image():
from PIL import Image
fb = SNAP["title_fb"].reshape(400, 640, 4)
return Image.fromarray(fb[:, :, [2, 1, 0]])
def fresh_machine():
m = Linux386(ELF, argv=("doom", "-iwad", "doom1.wad"),
fs={"doom1.wad": WAD, "./doom1.wad": WAD})
m.mem[:] = SNAP["mem"].tobytes()
r = SNAP["regs"]
m.cpu.r = [int(x) for x in r[:8]]
(m.cpu.eip, m.cpu.gs_base, m.cpu.instr_count,
m.clock_ns, m.brk, m.mmap_ptr, m.next_fd) = (int(x) for x in r[8:15])
m.cpu.f = {str(k): int(v) for k, v in zip(SNAP["fkeys"], SNAP["fvals"])}
m.frames = []
return m
def state_hash(m):
h = hashlib.sha256()
h.update(m.mem)
h.update(repr((m.cpu.r, m.cpu.eip, sorted(m.cpu.f.items()), m.clock_ns)).encode())
return h.hexdigest()
# ================= ZeroGPU: exhaustive unit re-verification =================
UNIT_SPECS = [
("ADC8", u_ADC8, "8-bit add w/ carry + CFΒ·OFΒ·SFΒ·ZFΒ·AF"),
("SBB8", u_SBB8, "8-bit subtract w/ borrow + flags"),
("AND8", lambda: u_logic(lambda a, b: a & b), "bitwise AND + SFΒ·ZF"),
("OR8", lambda: u_logic(lambda a, b: a | b), "bitwise OR + SFΒ·ZF"),
("XOR8", lambda: u_logic(lambda a, b: a ^ b), "bitwise XOR + SFΒ·ZF"),
("SHL1", u_SHL1, "shift-left-1 slice w/ carry chain"),
("SHR1", u_SHR1, "shift-right-1 slice w/ carry chain"),
("MASK8", u_MASK8, "multiplier partial-product slice"),
("NOT8", u_NOT8, "bitwise NOT"),
("FLAGS8", u_FLAGS8, "SFΒ·ZFΒ·parity extractor"),
("PREFIX", u_prefix, "instruction prefix classifier"),
("MODRM", u_modrm, "ModRM field decoder"),
("SIB", u_sib, "SIB field decoder"),
]
@spaces.GPU(duration=60)
def verify_all_units_gpu():
dev = "cuda" if torch.cuda.is_available() else "cpu"
gpu = torch.cuda.get_device_name(0) if dev == "cuda" else "CPU fallback"
rows = []
total_cases = 0
t_all = time.time()
for name, builder, desc in UNIT_SPECS:
X, Y = builder()
X = torch.tensor(X, device=dev); Y = torch.tensor(Y, device=dev)
net = BitMLP(X.shape[1], Y.shape[1]).to(dev)
net.load_state_dict(torch.load(
os.path.join(ASSETS, "models", f"{name}.pt"),
weights_only=True, map_location=dev))
t0 = time.time()
with torch.no_grad():
ok = int((((net(X) > 0).float() == Y).all(1)).sum())
total_cases += X.shape[0]
verdict = "βœ… EXACT" if ok == X.shape[0] else "❌ FAIL"
rows.append(f"| `{name}` | {desc} | {ok:,} / {X.shape[0]:,} | {verdict} | "
f"{(time.time()-t0)*1000:.0f} ms |")
dt = time.time() - t_all
return (f"### {total_cases:,} cases β€” every possible input of every unit β€” "
f"re-verified on **{gpu}** in **{dt:.1f}s**\n\n"
"| unit | role | cases exact | verdict | GPU time |\n"
"|---|---|---|---|---|\n" + "\n".join(rows) +
"\n\n*This is the entire mathematical foundation of the machine, "
"re-proven from the shipped weights, live, just now.*")
# ================= live neural execution segment =================
_neural = None
def neural_units():
global _neural
if _neural is None:
_neural = NeuralUnits(build_all())
return _neural
def run_neural_segment(seg_choice, progress=gr.Progress()):
seg = int(seg_choice.split()[0].replace(",", ""))
ref = GOLDEN_REFS.get(str(seg))
units = neural_units()
m = fresh_machine()
m.cpu.u = units
m.cpu.alu = ALU(units)
t0 = time.time()
for i in range(seg):
m.cpu.step()
if i % 250 == 0:
progress(i / seg, desc=f"⚑ {i:,} / {seg:,} instructions through the neural nets")
dt = time.time() - t0
h = state_hash(m)
same = (h == ref)
badge = ("<div class='verdict-pass'>BIT-IDENTICAL βœ…</div>" if same
else "<div class='verdict-fail'>MISMATCH ❌</div>")
return (f"{badge}\n\n**{seg:,} instructions of id Software's actual machine code** "
f"executed with every decode, ALU op, shift and multiply a neural "
f"network β€” {dt:.0f}s ({seg/dt:,.0f} instr/s).\n\n"
f"Resulting machine state (128 MB memory + registers + flags) hashed and "
f"compared against the golden reference:\n\n"
f"`neural {h[:40]}…`\n`golden {(ref or '?')[:40]}…`")
# ================= playable DOOM (C orchestrator, 77M instr/s) =================
from x86_cfast import FastLinux
from PIL import Image as PILImage
DOOMKEY = {"fwd": 0xAD, "back": 0xAF, "left": 0xAC, "right": 0xAE,
"fire": 0xA3, "use": 0xA2, "enter": 13, "esc": 27,
"strafel": 0xA0, "strafer": 0xA1}
def _fb_img(fb):
a = np.frombuffer(fb, np.uint8).reshape(400, 640, 4)
return PILImage.fromarray(a[:, :, [2, 1, 0]])
def _stream(mach, n_frames, hold_key=None, hold_frames=8):
if hold_key:
mach.keys.extend([1, DOOMKEY[hold_key]])
got = 0
while got < n_frames:
mach.frames = []
r = mach.run(max_instr=30_000_000)
if r in (2, 4):
yield None, "machine stopped"
return
for fb in mach.frames:
got += 1
if hold_key and got == hold_frames:
mach.keys.extend([0, DOOMKEY[hold_key]])
yield _fb_img(fb), f"frame {got}/{n_frames}"
if got >= n_frames:
break
if hold_key and got < hold_frames:
mach.keys.extend([0, DOOMKEY[hold_key]])
# Continuous play: a gr.Timer is the game loop. It runs the machine in small
# bursts every tick (so the world is always alive -- attract demo, monsters,
# animation), applying whatever input was queued by the buttons/keyboard since
# the last tick. Input handlers only enqueue (instant); the timer does the work.
TICK_INSTR = 6_000_000 # ~one tick's worth of emulation (a few frames)
TICK_CHUNK = 1_500_000 # run the burst in chunks so the time guard can fire
TICK_BUDGET = 0.12 # wall seconds/tick, strictly under the 0.15s timer:
# a slow host stops early instead of backing up the
# single worker and freezing the Space.
DEFAULT_HOLD = 3 # ticks a tapped key stays held (move/fire/use/menu)
HOLD_TICKS = {"left": 2, "right": 2} # turning: shorter hold -> less turn per tap
def doom_power(state):
mach = FastLinux(ELF, argv=("doom", "-iwad", "doom1.wad"),
fs={"doom1.wad": WAD, "./doom1.wad": WAD})
# boot to the first rendered frame
img = None
for _ in range(8):
mach.frames = []
if mach.run(max_instr=20_000_000) in (2, 4):
break
if mach.frames:
img = _fb_img(mach.frames[-1]); break
state = {"mach": mach, "down": {}} # down: key -> ticks remaining held
return (state, img,
"⏻ ON β€” running live & continuous. Use the keyboard / mouse / buttons; "
"press ⏎ twice for a new game.", gr.Timer(active=True))
def doom_enqueue(state, key):
"""Instant: press the key now and arm its hold for a few ticks."""
if state and state.get("mach"):
down = state["down"]
if key not in down:
state["mach"].keys.extend([1, DOOMKEY[key]]) # press now
down[key] = HOLD_TICKS.get(key, DEFAULT_HOLD) # (re)arm hold length
return state
def doom_pause(state):
if not state or not state.get("mach"):
return state, "Power on first."
state["paused"] = not state.get("paused", False)
return state, ("⏸ paused" if state["paused"] else "β–Ά running live")
def doom_tick(state):
"""The game loop: apply held keys, advance a burst, render the new frame."""
if not state or not state.get("mach") or state.get("paused"):
return state, gr.update(), gr.update()
mach = state["mach"]; down = state["down"]
# keys were pressed on enqueue; run a burst, then release any whose hold ran out.
# Run in chunks up to TICK_INSTR but bail at TICK_BUDGET so a slow host can't
# overrun the timer interval and freeze the worker (game just paces a bit slower).
mach.frames = []
t0 = time.time(); ran = 0; r = 0
while ran < TICK_INSTR and time.time() - t0 < TICK_BUDGET:
r = mach.run(max_instr=TICK_CHUNK); ran += TICK_CHUNK
if r in (2, 4):
break
for k in list(down.keys()):
down[k] -= 1
if down[k] <= 0:
mach.keys.extend([0, DOOMKEY[k]]); del down[k]
if r in (2, 4):
return {"mach": None, "down": {}}, gr.update(), "machine halted β€” press Power On"
img = _fb_img(mach.frames[-1]) if mach.frames else gr.update()
return state, img, gr.update()
# ================= instruction microscope =================
class TracingUnits:
"""Proxy around NeuralUnits that records every unit invocation."""
def __init__(self, inner):
self._inner = inner
self.calls = []
def __getattr__(self, name):
fn = getattr(self._inner, name)
def wrap(*a):
r = fn(*a)
self.calls.append((name, a, r))
return r
return wrap
MICRO = {"m": None, "tr": None}
def micro_reset():
MICRO["m"] = None
return micro_step()
def micro_step():
if MICRO["m"] is None:
m = fresh_machine()
tr = TracingUnits(neural_units())
m.cpu.u = tr
m.cpu.alu = ALU(tr)
MICRO["m"], MICRO["tr"] = m, tr
m, tr = MICRO["m"], MICRO["tr"]
tr.calls = []
eip0 = m.cpu.eip
code = bytes(m.mem[eip0:eip0 + 12]).hex(" ")
m.cpu.step()
nbytes = (m.cpu.eip - eip0) if 0 < m.cpu.eip - eip0 <= 12 else 12
shown = code[:nbytes * 3 - 1] if nbytes else code
rows = []
for name, args, res in tr.calls[:40]:
a = ", ".join(f"{x:02x}" if isinstance(x, int) else str(x) for x in args)
if isinstance(res, tuple):
r = " ".join(f"{x:02x}" if isinstance(x, int) else str(x) for x in res)
elif isinstance(res, int):
r = f"{res:02x}"
else:
r = str(res)
rows.append(f"| `{name}` | `{a}` | `{r}` |")
more = f"\n*…plus {len(tr.calls)-40} more unit calls*" if len(tr.calls) > 40 else ""
regs = m.cpu.r
f = m.cpu.f
return (f"### instruction @ `eip {eip0:08x}` β€” bytes `{shown}`\n"
f"**{len(tr.calls)} neural unit calls** computed this instruction:\n\n"
"| unit | inputs | outputs |\n|---|---|---|\n" + "\n".join(rows) + more +
f"\n\n**after:** `eax {regs[0]:08x}` `ecx {regs[1]:08x}` `edx {regs[2]:08x}` "
f"`ebx {regs[3]:08x}` `esp {regs[4]:08x}` `ebp {regs[5]:08x}` "
f"`esi {regs[6]:08x}` `edi {regs[7]:08x}` β†’ `eip {m.cpu.eip:08x}`\n\n"
f"flags: CF={f['CF']} ZF={f['ZF']} SF={f['SF']} OF={f['OF']} "
f"PF={f['PF']} AF={f['AF']}")
# ================= UI =================
WRITEUP = open(os.path.join(os.path.dirname(os.path.abspath(__file__)), "WRITEUP.md"),
encoding="utf-8").read()
CSS = """
:root { color-scheme: dark; }
body, .gradio-container {
background: radial-gradient(ellipse at 20% -10%, #1a0a2e 0%, #0a0a14 45%, #050508 100%) !important;
}
#hero h1 {
font-size: 2.6em; font-weight: 900; letter-spacing: -0.02em;
background: linear-gradient(90deg, #ff3b3b, #ff9d00, #ffe600, #3bff8f, #00e0ff, #b03bff, #ff3b8f);
background-size: 300% 100%;
-webkit-background-clip: text; background-clip: text; color: transparent;
animation: chroma 8s linear infinite;
}
@keyframes chroma { 0% {background-position: 0% 50%;} 100% {background-position: 300% 50%;} }
#hero p, #hero li { color: #c8c8de; }
.panel {
border: 1px solid transparent; border-radius: 14px; padding: 4px;
background:
linear-gradient(#0e0e1a, #0e0e1a) padding-box,
linear-gradient(135deg, #ff3b3b66, #00e0ff66, #b03bff66) border-box;
box-shadow: 0 0 24px #00e0ff14, 0 0 48px #b03bff0f;
}
#doomframe { position: relative; border-radius: 10px; overflow: hidden;
box-shadow: 0 0 30px #ff3b3b33, 0 0 60px #ff3b3b1a; }
#doomframe::after {
content: ""; position: absolute; inset: 0; pointer-events: none;
background: repeating-linear-gradient(0deg, transparent 0 2px, #00000022 2px 4px);
}
/* ---- CRT / monitor bezel around the live DOOM screen ---- */
#crt {
position: relative; border-radius: 22px; padding: 26px 26px 40px;
background: linear-gradient(160deg, #34343e 0%, #20202a 55%, #14141b 100%);
box-shadow: 0 18px 50px #000b, 0 2px 0 #ffffff10 inset,
0 0 0 2px #000 inset, 0 0 0 3px #ffffff0c;
}
#crt::before { /* power LED */
content: ""; position: absolute; bottom: 14px; right: 30px; width: 9px; height: 9px;
border-radius: 50%; background: #3bff8f; box-shadow: 0 0 10px #3bff8f, 0 0 3px #fff;
}
#crt::after { /* brand plate */
content: "NEURAL-VISION ⟐ 640Γ—400"; position: absolute; bottom: 12px; left: 30px;
font: 700 10px/1 ui-monospace, monospace; letter-spacing: 2px; color: #6a6a7e;
}
#crt #doomplay {
position: relative; border-radius: 10px; overflow: hidden; background: #000;
box-shadow: inset 0 0 70px #000c, 0 0 26px #ff3b3b22;
}
#crt #doomplay::after { /* scanlines + glass curvature glare */
content: ""; position: absolute; inset: 0; pointer-events: none;
background:
repeating-linear-gradient(0deg, #0000 0 2px, #00000030 2px 3px),
radial-gradient(120% 90% at 50% -10%, #ffffff1c, #0000 55%);
}
#crt #doomplay img { display: block; width: 100%; image-rendering: pixelated; }
button.primary, .primary {
background: linear-gradient(90deg, #ff3b3b, #b03bff) !important;
border: none !important; color: white !important; font-weight: 700 !important;
box-shadow: 0 0 18px #b03bff55 !important; transition: box-shadow .2s !important;
}
button.primary:hover { box-shadow: 0 0 30px #ff3b3b88 !important; }
.verdict-pass {
display: inline-block; padding: 10px 22px; border-radius: 10px; font-size: 1.3em;
font-weight: 900; color: #06140a;
background: linear-gradient(90deg, #3bff8f, #00e0ff);
box-shadow: 0 0 28px #3bff8f66; letter-spacing: .04em;
}
.verdict-fail {
display: inline-block; padding: 10px 22px; border-radius: 10px; font-size: 1.3em;
font-weight: 900; color: #fff; background: linear-gradient(90deg, #ff3b3b, #ff9d00);
}
.prooflog {
font-family: ui-monospace, monospace; color: #3bff8f; background: #050a07;
border: 1px solid #3bff8f44; border-radius: 10px; padding: 14px;
box-shadow: inset 0 0 24px #3bff8f11;
}
table { border-color: #2a2a44 !important; }
"""
FORCE_DARK = """
function refresh() {
const url = new URL(window.location);
if (url.searchParams.get('__theme') !== 'dark') {
url.searchParams.set('__theme', 'dark');
window.location.href = url.href;
}
}
"""
theme = gr.themes.Base(
primary_hue="purple", neutral_hue="slate",
font=[gr.themes.GoogleFont("Inter"), "system-ui", "sans-serif"],
font_mono=[gr.themes.GoogleFont("JetBrains Mono"), "ui-monospace", "monospace"],
)
with gr.Blocks(title="Neural DOOM") as demo:
with gr.Column(elem_id="hero"):
gr.Markdown(
"# NEURAL DOOM\n"
"### id Software's 1993 code, executed by neural networks β€” bit-exact\n"
"Every datapath unit of this i386 β€” instruction decode, every ALU slice, "
"every shift, every multiply β€” is a neural network verified over its "
"**complete input domain**. A full frame (**5,952,699 instructions**) was "
"replayed with every unit neural and came out **bit-identical** to the "
"conventional run: every pixel, every byte of all 128 MB of machine state.")
with gr.Row():
with gr.Column(scale=3):
gr.Image(value=title_frame_image(), elem_id="doomframe", show_label=False,
interactive=False)
with gr.Column(scale=2):
gr.HTML("<div class='prooflog'>instructions golden = 5,952,699<br>"
"instructions neural = 5,952,699<br>"
"framebuffer 640Γ—400 ........ BIT-IDENTICAL<br>"
"machine state (128 MB) ..... IDENTICAL<br><br>"
">>> DOOM FRAME EXACT THROUGH THE FULLY NEURAL x86</div>")
gr.Markdown("_102 minutes of compute at ~970 instructions/second β€” every "
"one decoded and computed by neural nets, one verified 8-bit "
"slice at a time. This page lets you re-run the proofs yourself._")
gr.Markdown("---")
with gr.Column(elem_classes="panel"):
gr.Markdown("## πŸ’€ PLAY DOOM β€” live, in your browser, on this machine\n"
"The C orchestrator (lockstep-validated against the QEMU-validated "
"core; **57,110/57,110 live neural audits exact**) runs at 77M "
"instructions/second β€” fast enough to stream playable frames. "
"Power on, press **⏎ Enter** twice to start a new game, then fight.\n\n"
"_The game runs **continuously** β€” the world keeps moving on its own. "
"Use the on-screen buttons to play; tap a button repeatedly to keep "
"moving or turning. ⏸ pauses._")
play_state = gr.State(None)
play_timer = gr.Timer(0.15, active=False) # the continuous game loop
with gr.Row():
with gr.Column(scale=3):
with gr.Group(elem_id="crt"): # TV / CRT monitor bezel
play_scr = gr.Image(elem_id="doomplay", show_label=False,
interactive=False)
play_status = gr.Markdown("Power is OFF.")
with gr.Column(scale=1):
p_on = gr.Button("⏻ Power On", variant="primary", elem_id="k_on")
with gr.Row():
p_enter = gr.Button("⏎ Enter", elem_id="k_enter")
p_esc = gr.Button("Esc", elem_id="k_esc")
with gr.Row():
p_fwd = gr.Button("β–² forward", elem_id="k_fwd")
with gr.Row():
p_left = gr.Button("β—€ turn", elem_id="k_left")
p_right = gr.Button("turn β–Ά", elem_id="k_right")
with gr.Row():
p_back = gr.Button("β–Ό back", elem_id="k_back")
with gr.Row():
p_fire = gr.Button("πŸ”« FIRE", variant="primary", elem_id="k_fire")
p_use = gr.Button("βœ‹ use", elem_id="k_use")
with gr.Row():
p_sl = gr.Button("⇀ strafe", elem_id="k_strafel")
p_sr = gr.Button("strafe β‡₯", elem_id="k_strafer")
p_wait = gr.Button("⏸ pause / resume", elem_id="k_wait")
p_on.click(doom_power, play_state,
[play_state, play_scr, play_status, play_timer])
for btn, key in [(p_enter, "enter"), (p_esc, "esc"), (p_fwd, "fwd"),
(p_back, "back"), (p_left, "left"), (p_right, "right"),
(p_fire, "fire"), (p_use, "use"),
(p_sl, "strafel"), (p_sr, "strafer")]:
btn.click(doom_enqueue, [play_state, gr.State(key)], play_state)
# the timer drives continuous play; pause/resume toggles a flag it honors
play_timer.tick(doom_tick, play_state, [play_state, play_scr, play_status])
p_wait.click(doom_pause, play_state, [play_state, play_status])
with gr.Row(equal_height=False):
with gr.Column(elem_classes="panel"):
gr.Markdown("## πŸ”¬ Re-prove the foundation &nbsp;Β·&nbsp; ZeroGPU\n"
"One click re-verifies **all 13 units exhaustively** β€” every "
"possible input of every unit, 525k+ cases β€” on an H200 slice.")
v_btn = gr.Button("⚑ Re-verify all 13 units on GPU", variant="primary")
v_out = gr.Markdown()
with gr.Column(elem_classes="panel"):
gr.Markdown("## βš™οΈ Run DOOM neurally, live\n"
"Executes real DOOM machine code from the title-frame snapshot "
"with **every unit neural**, then bit-checks the resulting "
"machine state against the golden reference hash.")
seg = gr.Dropdown(["10,000 instructions", "25,000 instructions",
"50,000 instructions"], value="10,000 instructions",
label="segment length", filterable=False)
r_btn = gr.Button("⚑ Execute neurally + verify", variant="primary")
r_out = gr.Markdown()
with gr.Column(elem_classes="panel"):
gr.Markdown("## 🧬 Instruction microscope\n"
"Single-step DOOM and watch the neural units fire. Each row is one "
"net computing one verified slice of the instruction β€” carry chains, "
"flag wiring, decode fields, all of it.")
with gr.Row():
s_btn = gr.Button("⏭ Step one instruction", variant="primary")
x_btn = gr.Button("β†Ί Reset to title frame")
s_out = gr.Markdown()
v_btn.click(verify_all_units_gpu, None, v_out)
r_btn.click(run_neural_segment, seg, r_out)
s_btn.click(micro_step, None, s_out)
x_btn.click(micro_reset, None, s_out)
gr.Markdown("---")
with gr.Accordion("πŸ“œ The full story β€” what this is, how we got here, and why it matters", open=True):
gr.Markdown(WRITEUP)
demo.launch(theme=theme, css=CSS, js=FORCE_DARK)