Spaces:
Paused
Paused
Update app.py
Browse files
app.py
CHANGED
|
@@ -1,140 +1,195 @@
|
|
| 1 |
import gradio as gr
|
| 2 |
-
import torch
|
| 3 |
-
import torch.nn as nn
|
| 4 |
-
import torch.nn.functional as F
|
| 5 |
import numpy as np
|
|
|
|
| 6 |
|
| 7 |
# ==========================================
|
| 8 |
-
# THE
|
| 9 |
# ==========================================
|
| 10 |
-
class
|
| 11 |
-
def __init__(self
|
| 12 |
-
|
| 13 |
-
self.
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
self.
|
| 18 |
-
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
|
| 23 |
-
|
| 24 |
-
|
| 25 |
-
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
filters = kernel.repeat(self.channel_n, 1, 1, 1).to(x.device)
|
| 34 |
-
|
| 35 |
-
y = F.conv2d(x, filters, padding=1, groups=self.channel_n)
|
| 36 |
|
| 37 |
-
#
|
| 38 |
-
|
| 39 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 40 |
|
| 41 |
-
|
| 42 |
-
# Stochastic update (cells fire randomly)
|
| 43 |
-
stochastic = (torch.rand(x.shape[0], 1, x.shape[2], x.shape[3]) > 0.5).float().to(x.device)
|
| 44 |
-
return x + y * stochastic
|
| 45 |
|
| 46 |
# ==========================================
|
| 47 |
-
# THE
|
| 48 |
# ==========================================
|
| 49 |
-
|
| 50 |
-
|
| 51 |
-
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
|
| 56 |
-
|
| 57 |
-
|
| 58 |
-
|
| 59 |
-
|
| 60 |
-
|
| 61 |
-
|
| 62 |
-
|
| 63 |
-
|
| 64 |
-
|
| 65 |
-
|
| 66 |
-
|
| 67 |
-
|
| 68 |
-
|
| 69 |
-
|
| 70 |
-
|
| 71 |
-
|
| 72 |
-
|
| 73 |
-
|
| 74 |
-
|
| 75 |
-
|
| 76 |
-
|
| 77 |
-
|
| 78 |
-
|
| 79 |
-
|
| 80 |
-
|
| 81 |
-
|
| 82 |
-
|
| 83 |
-
|
| 84 |
-
|
| 85 |
-
|
| 86 |
-
|
| 87 |
-
|
| 88 |
-
|
| 89 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 90 |
|
| 91 |
# ==========================================
|
| 92 |
# GRADIO APP
|
| 93 |
# ==========================================
|
| 94 |
|
| 95 |
-
|
| 96 |
-
|
| 97 |
-
def step_fn():
|
| 98 |
-
# Run 50 generations per click
|
| 99 |
-
img = cpu_life.step(loops=50)
|
| 100 |
-
return img, f"Cycle: {cpu_life.step_count} | Status: Growing"
|
| 101 |
-
|
| 102 |
-
def damage_fn():
|
| 103 |
-
msg = cpu_life.damage()
|
| 104 |
-
img = cpu_life.render()
|
| 105 |
-
return img, msg
|
| 106 |
|
| 107 |
-
def
|
| 108 |
-
|
| 109 |
-
|
| 110 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 111 |
|
| 112 |
-
with gr.Blocks() as demo:
|
| 113 |
-
gr.Markdown("#
|
| 114 |
-
gr.Markdown("###
|
|
|
|
| 115 |
|
| 116 |
with gr.Row():
|
| 117 |
with gr.Column():
|
| 118 |
-
|
| 119 |
-
|
| 120 |
-
|
| 121 |
-
|
| 122 |
-
with gr.Column():
|
| 123 |
-
step_btn = gr.Button("๐งฌ Evolve (Fast Forward)", variant="primary")
|
| 124 |
-
damage_btn = gr.Button("๐ฅ Inflict Damage", variant="stop")
|
| 125 |
-
reset_btn = gr.Button("โป๏ธ Rebirth")
|
| 126 |
|
| 127 |
-
|
| 128 |
-
|
| 129 |
-
|
| 130 |
-
|
| 131 |
-
|
| 132 |
-
4. Click **Evolve** again to watch it heal.
|
| 133 |
-
""")
|
| 134 |
-
|
| 135 |
-
step_btn.click(step_fn, outputs=[screen, status])
|
| 136 |
-
damage_btn.click(damage_fn, outputs=[screen, status])
|
| 137 |
-
reset_btn.click(reset_fn, outputs=[screen, status])
|
| 138 |
|
| 139 |
if __name__ == "__main__":
|
| 140 |
-
demo.launch(
|
|
|
|
| 1 |
import gradio as gr
|
|
|
|
|
|
|
|
|
|
| 2 |
import numpy as np
|
| 3 |
+
import time
|
| 4 |
|
| 5 |
# ==========================================
|
| 6 |
+
# THE ARCHITECTURE (64-BIT RISC-V)
|
| 7 |
# ==========================================
|
| 8 |
+
class VisualRISCV:
|
| 9 |
+
def __init__(self):
|
| 10 |
+
# 64KB RAM (Small enough to visualize as a 256x256 image)
|
| 11 |
+
self.RAM_SIZE = 65536
|
| 12 |
+
self.ram = np.zeros(self.RAM_SIZE, dtype=np.int64)
|
| 13 |
+
self.registers = np.zeros(32, dtype=np.int64)
|
| 14 |
+
self.pc = 0
|
| 15 |
+
self.logs = []
|
| 16 |
+
|
| 17 |
+
def log(self, msg):
|
| 18 |
+
self.logs.append(msg)
|
| 19 |
+
|
| 20 |
+
def reset(self):
|
| 21 |
+
self.ram.fill(0)
|
| 22 |
+
self.registers.fill(0)
|
| 23 |
+
self.pc = 0
|
| 24 |
+
self.logs = []
|
| 25 |
+
self.log("โก SYSTEM RESET.")
|
| 26 |
+
|
| 27 |
+
def get_ram_image(self):
|
| 28 |
+
# Convert RAM (1D array) to 2D Image (256x256)
|
| 29 |
+
# We normalize values to be visible (0-255)
|
| 30 |
+
grid = self.ram.reshape((256, 256))
|
|
|
|
|
|
|
|
|
|
| 31 |
|
| 32 |
+
# Make it look cool: Any non-zero value lights up
|
| 33 |
+
# We use a modulo to make math patterns look like gradients
|
| 34 |
+
visual_grid = (grid % 255).astype(np.uint8)
|
| 35 |
+
return visual_grid
|
| 36 |
+
|
| 37 |
+
def execute(self, steps=1000):
|
| 38 |
+
start = time.time()
|
| 39 |
+
for _ in range(steps):
|
| 40 |
+
if self.pc >= self.RAM_SIZE: break
|
| 41 |
+
|
| 42 |
+
instr = self.ram[self.pc]
|
| 43 |
+
if instr == 0: break # End of code
|
| 44 |
+
|
| 45 |
+
# DECODE
|
| 46 |
+
opcode = instr & 0x7F
|
| 47 |
+
rd = (instr >> 7) & 0x1F
|
| 48 |
+
rs1 = (instr >> 15) & 0x1F
|
| 49 |
+
rs2 = (instr >> 20) & 0x1F
|
| 50 |
+
imm = (instr >> 20)
|
| 51 |
+
|
| 52 |
+
# EXECUTE
|
| 53 |
+
if opcode == 1: # ADDI
|
| 54 |
+
self.registers[rd] = self.registers[rs1] + imm
|
| 55 |
+
elif opcode == 2: # ADD
|
| 56 |
+
# Fix for register mapping
|
| 57 |
+
real_rs2 = (instr >> 20) & 0x1F
|
| 58 |
+
self.registers[rd] = self.registers[rs1] + self.registers[real_rs2]
|
| 59 |
+
elif opcode == 3: # STORE
|
| 60 |
+
addr = self.registers[rs1] + imm
|
| 61 |
+
if addr < self.RAM_SIZE:
|
| 62 |
+
self.ram[int(addr)] = self.registers[rd]
|
| 63 |
+
elif opcode == 4: # JUMP (BNE)
|
| 64 |
+
if self.registers[rd] != 0:
|
| 65 |
+
self.pc -= imm
|
| 66 |
+
continue
|
| 67 |
+
elif opcode == 99: # HALT
|
| 68 |
+
break
|
| 69 |
+
|
| 70 |
+
self.pc += 1
|
| 71 |
|
| 72 |
+
return time.time() - start
|
|
|
|
|
|
|
|
|
|
| 73 |
|
| 74 |
# ==========================================
|
| 75 |
+
# THE PROGRAMS (SOFTWARE)
|
| 76 |
# ==========================================
|
| 77 |
+
|
| 78 |
+
# 1. FIBONACCI VISUALIZER
|
| 79 |
+
# Calculates Fibonacci numbers and writes them to RAM sequentially.
|
| 80 |
+
# This creates a "Static" noise pattern that represents pure math.
|
| 81 |
+
fib_code = """[
|
| 82 |
+
# R1 = Address Pointer (Start at 256 to skip code area)
|
| 83 |
+
(256 << 20) | (0 << 15) | (1 << 7) | 1,
|
| 84 |
+
|
| 85 |
+
# R2 = Fib A (1)
|
| 86 |
+
(1 << 20) | (0 << 15) | (2 << 7) | 1,
|
| 87 |
+
|
| 88 |
+
# R3 = Fib B (1)
|
| 89 |
+
(1 << 20) | (0 << 15) | (3 << 7) | 1,
|
| 90 |
+
|
| 91 |
+
# R4 = Loop Counter (Run 10,000 times)
|
| 92 |
+
(10000 << 20) | (0 << 15) | (4 << 7) | 1,
|
| 93 |
+
|
| 94 |
+
# --- LOOP START ---
|
| 95 |
+
|
| 96 |
+
# STORE Fib A (R2) to RAM[R1]
|
| 97 |
+
(0 << 20) | (1 << 15) | (2 << 7) | 3,
|
| 98 |
+
|
| 99 |
+
# CALC NEXT FIB: R5 = R2 + R3
|
| 100 |
+
(3 << 20) | (2 << 15) | (5 << 7) | 2,
|
| 101 |
+
|
| 102 |
+
# SHIFT: R2 = R3
|
| 103 |
+
(0 << 20) | (3 << 15) | (2 << 7) | 2, # Add 0 to move
|
| 104 |
+
|
| 105 |
+
# SHIFT: R3 = R5
|
| 106 |
+
(0 << 20) | (5 << 15) | (3 << 7) | 2,
|
| 107 |
+
|
| 108 |
+
# INCREMENT POINTER: R1++
|
| 109 |
+
(1 << 20) | (1 << 15) | (1 << 7) | 1,
|
| 110 |
+
|
| 111 |
+
# DECREMENT COUNTER: R4--
|
| 112 |
+
(-1 << 20) | (4 << 15) | (4 << 7) | 1,
|
| 113 |
+
|
| 114 |
+
# JUMP BACK 6 STEPS IF R4 != 0
|
| 115 |
+
(6 << 20) | (0 << 15) | (4 << 7) | 4,
|
| 116 |
+
|
| 117 |
+
# HALT
|
| 118 |
+
99
|
| 119 |
+
]"""
|
| 120 |
+
|
| 121 |
+
# 2. MEMORY FILLER (Gradient)
|
| 122 |
+
# Fills RAM with a linear gradient.
|
| 123 |
+
grad_code = """[
|
| 124 |
+
# R1 = Address (Start 256)
|
| 125 |
+
(256 << 20) | (0 << 15) | (1 << 7) | 1,
|
| 126 |
+
# R2 = Value (0)
|
| 127 |
+
(0 << 20) | (0 << 15) | (2 << 7) | 1,
|
| 128 |
+
# R3 = Counter (60000)
|
| 129 |
+
(60000 << 20) | (0 << 15) | (3 << 7) | 1,
|
| 130 |
+
|
| 131 |
+
# STORE RAM[R1] = R2
|
| 132 |
+
(0 << 20) | (1 << 15) | (2 << 7) | 3,
|
| 133 |
+
# R1++
|
| 134 |
+
(1 << 20) | (1 << 15) | (1 << 7) | 1,
|
| 135 |
+
# R2++
|
| 136 |
+
(1 << 20) | (2 << 15) | (2 << 7) | 1,
|
| 137 |
+
# R3--
|
| 138 |
+
(-1 << 20) | (3 << 15) | (3 << 7) | 1,
|
| 139 |
+
# JUMP BACK 4
|
| 140 |
+
(4 << 20) | (0 << 15) | (3 << 7) | 4,
|
| 141 |
+
99
|
| 142 |
+
]"""
|
| 143 |
|
| 144 |
# ==========================================
|
| 145 |
# GRADIO APP
|
| 146 |
# ==========================================
|
| 147 |
|
| 148 |
+
cpu = VisualRISCV()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 149 |
|
| 150 |
+
def run_cpu(prog_name):
|
| 151 |
+
cpu.reset()
|
| 152 |
+
|
| 153 |
+
# Select Program
|
| 154 |
+
if prog_name == "Fibonacci Math":
|
| 155 |
+
code = eval(fib_code)
|
| 156 |
+
else:
|
| 157 |
+
code = eval(grad_code)
|
| 158 |
+
|
| 159 |
+
# Flash Code
|
| 160 |
+
for i, instr in enumerate(code):
|
| 161 |
+
cpu.ram[i] = int(instr)
|
| 162 |
+
|
| 163 |
+
cpu.log(f"๐พ LOADED {prog_name}")
|
| 164 |
+
|
| 165 |
+
# Run
|
| 166 |
+
cpu.log("๐ EXECUTING...")
|
| 167 |
+
# We run 60,000 cycles to ensure the image fills up
|
| 168 |
+
t = cpu.execute(steps=60000)
|
| 169 |
+
|
| 170 |
+
img = cpu.get_ram_image()
|
| 171 |
+
|
| 172 |
+
reg_str = f"R1 (Addr): {cpu.registers[1]}\nR2 (Val): {cpu.registers[2]}\nR3 (Val): {cpu.registers[3]}"
|
| 173 |
+
|
| 174 |
+
return img, "\n".join(cpu.logs), reg_str
|
| 175 |
|
| 176 |
+
with gr.Blocks(theme=gr.themes.Monochrome()) as demo:
|
| 177 |
+
gr.Markdown("# ๐ง Visual RISC-V Core")
|
| 178 |
+
gr.Markdown("### Seeing the Math")
|
| 179 |
+
gr.Markdown("This system runs real calculations. The image below is not a picture; it is a **Direct View of the RAM**. Every pixel is a number calculated by the CPU.")
|
| 180 |
|
| 181 |
with gr.Row():
|
| 182 |
with gr.Column():
|
| 183 |
+
prog_select = gr.Radio(["Fibonacci Math", "Linear Gradient"], label="Select Program", value="Fibonacci Math")
|
| 184 |
+
run_btn = gr.Button("Run Calculation", variant="primary")
|
| 185 |
+
logs = gr.Textbox(label="System Logs")
|
| 186 |
+
regs = gr.Textbox(label="CPU Registers")
|
|
|
|
|
|
|
|
|
|
|
|
|
| 187 |
|
| 188 |
+
with gr.Column():
|
| 189 |
+
# Visualizing RAM
|
| 190 |
+
ram_view = gr.Image(label="RAM Visualization (256x256)", height=400, image_mode="L", type="numpy")
|
| 191 |
+
|
| 192 |
+
run_btn.click(run_cpu, inputs=prog_select, outputs=[ram_view, logs, regs])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 193 |
|
| 194 |
if __name__ == "__main__":
|
| 195 |
+
demo.launch()
|