diamond-in commited on
Commit
7e374b6
ยท
verified ยท
1 Parent(s): 8013ee4

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +172 -117
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 DNA (NEURAL PHYSICS ENGINE)
9
  # ==========================================
10
- class NeuralPhysics(nn.Module):
11
- def __init__(self, channel_n=16):
12
- super().__init__()
13
- self.channel_n = channel_n
14
-
15
- # Input: 48 channels (16 channels * 3 filters)
16
- # Output: 128 hidden features
17
- self.w1 = nn.Conv2d(channel_n * 3, 128, 1, 1)
18
- self.w2 = nn.Conv2d(128, channel_n, 1, 1)
19
-
20
- # Initialize weights with slightly higher variance so life explodes faster
21
- with torch.no_grad():
22
- self.w1.weight.normal_(0.0, 0.05) # Increased variance
23
- self.w1.bias.normal_(0.0, 0.05)
24
- self.w2.weight.zero_() # Output layer starts at 0 (stable)
25
-
26
- def forward(self, x):
27
- # 1. PERCEPTION
28
- ident = torch.tensor([[0,0,0],[0,1,0],[0,0,0]]).float()
29
- sobel_x = torch.tensor([[-1,0,1],[-2,0,2],[-1,0,1]]).float() / 8.0
30
- sobel_y = torch.tensor([[-1,-2,-1],[0,0,0],[1,2,1]]).float() / 8.0
31
-
32
- kernel = torch.stack([ident, sobel_x, sobel_y]).unsqueeze(1)
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
- # 2. COGNITION
38
- y = F.relu(self.w1(y))
39
- y = self.w2(y)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
 
41
- # 3. UPDATE
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 LIVING GRID
48
  # ==========================================
49
- class LivingCPU:
50
- def __init__(self, size=64):
51
- self.size = size
52
- self.channels = 16
53
-
54
- # The Grid: [Batch, Channels, Height, Width]
55
- self.grid = torch.zeros(1, self.channels, size, size)
56
-
57
- # FIX: Seed the VISIBLE channels (RGB) too, not just hidden ones
58
- # Set the center 3x3 pixels to 1.0 (White Square)
59
- mid = size // 2
60
- self.grid[:, :, mid-1:mid+1, mid-1:mid+1] = 1.0
61
-
62
- self.model = NeuralPhysics(self.channels)
63
- self.step_count = 0
64
-
65
- def step(self, loops=20):
66
- # Run multiple steps per call so the user sees changes
67
- with torch.no_grad():
68
- for _ in range(loops):
69
- self.grid = self.model(self.grid)
70
- self.grid.clamp_(0.0, 1.0)
71
- self.step_count += 1
72
- return self.render()
73
-
74
- def damage(self):
75
- # Destroy a random chunk
76
- cx = np.random.randint(10, self.size-10)
77
- cy = np.random.randint(10, self.size-10)
78
- # Set all channels to 0 in that square
79
- self.grid[:, :, cx:cx+16, cy:cy+16] = 0.0
80
- return "โš ๏ธ DAMAGE DETECTED! REGENERATING..."
81
-
82
- def render(self):
83
- # Take first 3 channels (RGB)
84
- # [1, 3, H, W] -> [H, W, 3]
85
- img_tensor = self.grid[0, :3, :, :].permute(1, 2, 0)
86
-
87
- # Scale to 0-255
88
- img_np = (img_tensor.clamp(0, 1).numpy() * 255).astype(np.uint8)
89
- return img_np
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
90
 
91
  # ==========================================
92
  # GRADIO APP
93
  # ==========================================
94
 
95
- cpu_life = LivingCPU()
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 reset_fn():
108
- cpu_life.__init__()
109
- img = cpu_life.render()
110
- return img, "โ™ป๏ธ SYSTEM REBORN."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
111
 
112
- with gr.Blocks() as demo:
113
- gr.Markdown("# ๐Ÿงฌ The Self-Healing Neural CPU")
114
- gr.Markdown("### Artificial Life Simulation")
 
115
 
116
  with gr.Row():
117
  with gr.Column():
118
- # Display the grid
119
- screen = gr.Image(label="Living Logic Grid", height=400, image_mode="RGB", type="numpy")
120
- status = gr.Textbox(label="System Status", value="Ready. Seed Planted.")
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
- gr.Markdown("""
128
- **Instructions:**
129
- 1. Click **Evolve**. You will see the white seed explode into colors.
130
- 2. Keep clicking **Evolve** to watch the pattern stabilize.
131
- 3. Click **Inflict Damage** to delete a chunk.
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(theme=gr.themes.Glass())
 
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()