arudradey commited on
Commit
71b3e56
Β·
verified Β·
1 Parent(s): 078db72

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +54 -41
app.py CHANGED
@@ -7,7 +7,8 @@ from PIL import Image
7
  import pywasm
8
 
9
  # 1. Configuration & Persistent Paths
10
- SAVE_DIR = "/data"
 
11
  EMCC_DIR = os.path.join(SAVE_DIR, "emsdk")
12
  if not os.path.exists(SAVE_DIR):
13
  os.makedirs(SAVE_DIR, exist_ok=True)
@@ -41,16 +42,17 @@ def compile_c(c_code, filename):
41
  out_wasm = f"/tmp/{base}.wasm"
42
  dest_wasm = os.path.join(SAVE_DIR, f"{base}.wasm")
43
 
 
44
  with open(c_f, "w") as f:
45
  f.write(c_code)
46
 
47
  try:
48
- # Optimized for Python Runtime execution
49
  res = subprocess.run([
50
  emcc_path, c_f,
51
  "-O3",
52
  "-s", "WASM=1",
53
- "-s", "SIDE_MODULE=1", # Creates a clean library without JS bloat
54
  "-o", out_wasm
55
  ], capture_output=True, text=True, timeout=60)
56
 
@@ -69,54 +71,64 @@ def run_wasm_func(wasm_file, func_name, args):
69
  if not wasm_file: return "❌ Select a WASM file."
70
  path = os.path.join(SAVE_DIR, wasm_file)
71
  try:
72
- # Use pywasm.load(path) which is the standard for most versions
73
- runtime = pywasm.load(path)
74
 
75
- # Parse comma-separated numbers
76
- arg_list = [int(x.strip()) for x in args.split(",")] if args else []
77
 
78
- # Check for function with and without underscore (C convention)
79
- result = None
 
 
 
 
 
 
 
80
  try:
81
- result = runtime.exec(func_name, arg_list)
82
- except:
83
- result = runtime.exec(f"_{func_name}", arg_list)
 
 
 
84
 
85
- return f"Execution Successful!\nResult: {result}"
86
  except Exception as e:
87
- return f"❌ Runner Error: {str(e)}\n(Try adding/removing '_' from function name)"
88
 
89
- # 4. Visualizer Logic (With Visibility Fix)
90
  def render_wasm(wasm_file):
91
  if not wasm_file: return None, "❌ Select a file."
92
  path = os.path.join(SAVE_DIR, wasm_file)
93
 
94
- with open(path, "rb") as f:
95
- data = f.read()
96
-
97
- # Map binary to 1080p Grid
98
- arr = np.frombuffer(data, dtype=np.uint8).copy()
99
-
100
- # Scale values so they aren't just "black"
101
- if len(arr) > 0 and (arr.max() - arr.min()) != 0:
102
- arr = ((arr - arr.min()) * (255 / (arr.max() - arr.min()))).astype(np.uint8)
103
 
104
- canvas = np.zeros(1920 * 1080, dtype=np.uint8)
105
-
106
- # Tiling: Repeat data so it fills the screen visually
107
- if len(arr) > 0:
108
- tiled_data = np.tile(arr, (1920 * 1080 // len(arr)) + 1)
109
- canvas = tiled_data[:1920 * 1080]
110
-
111
- img = Image.fromarray(canvas.reshape((1080, 1920)), mode='L')
112
- return img, f"Visualizing {len(data)} bytes of logic (Tiled/Normalized)."
 
113
 
114
- # 5. Gradio Interface Layout
115
- with gr.Blocks(theme=gr.themes.Monochrome()) as demo:
116
- gr.Markdown("# πŸ› οΈ LCPU: Spatial Arithmetic Forge")
117
 
118
  with gr.Tab("1. The Forge"):
119
- wasm_name = gr.Textbox(label="Output Filename", value="math_logic")
120
  c_code_input = gr.TextArea(label="C Code Source", value='int add(int a, int b) {\n return a + b;\n}', lines=8)
121
  compile_btn = gr.Button("πŸš€ Build Binary", variant="primary")
122
  forge_status = gr.Textbox(label="Forge Output")
@@ -126,7 +138,7 @@ with gr.Blocks(theme=gr.themes.Monochrome()) as demo:
126
  run_select = gr.Dropdown(label="Select Binary", choices=get_wasm_files())
127
  refresh_run = gr.Button("πŸ”„", variant="secondary")
128
  f_name = gr.Textbox(label="Function Name", value="add")
129
- args_in = gr.Textbox(label="Arguments (e.g. 10, 20)", placeholder="5, 5")
130
  run_btn = gr.Button("⚑ Run Logic", variant="primary")
131
  run_output = gr.Textbox(label="Output Result")
132
 
@@ -136,9 +148,9 @@ with gr.Blocks(theme=gr.themes.Monochrome()) as demo:
136
  refresh_vis = gr.Button("πŸ”„", variant="secondary")
137
  render_btn = gr.Button("🎨 Map to 1080p", variant="primary")
138
  canvas_img = gr.Image(label="Logic Texture")
139
- vis_status = gr.Textbox(label="Canvas Status")
140
 
141
- # Wire up the events
142
  compile_btn.click(compile_c, [c_code_input, wasm_name], forge_status)
143
  refresh_run.click(lambda: gr.Dropdown(choices=get_wasm_files()), outputs=run_select)
144
  refresh_vis.click(lambda: gr.Dropdown(choices=get_wasm_files()), outputs=vis_select)
@@ -146,4 +158,5 @@ with gr.Blocks(theme=gr.themes.Monochrome()) as demo:
146
  render_btn.click(render_wasm, vis_select, [canvas_img, vis_status])
147
 
148
  if __name__ == "__main__":
149
- demo.launch()
 
 
7
  import pywasm
8
 
9
  # 1. Configuration & Persistent Paths
10
+ # Note: Using /data for Hugging Face persistent storage; fallback to local /app/data
11
+ SAVE_DIR = "/data" if os.path.exists("/data") else "./data"
12
  EMCC_DIR = os.path.join(SAVE_DIR, "emsdk")
13
  if not os.path.exists(SAVE_DIR):
14
  os.makedirs(SAVE_DIR, exist_ok=True)
 
42
  out_wasm = f"/tmp/{base}.wasm"
43
  dest_wasm = os.path.join(SAVE_DIR, f"{base}.wasm")
44
 
45
+ # Removed extern "C" to ensure plain C compatibility
46
  with open(c_f, "w") as f:
47
  f.write(c_code)
48
 
49
  try:
50
+ # SIDE_MODULE=1 for clean WASM
51
  res = subprocess.run([
52
  emcc_path, c_f,
53
  "-O3",
54
  "-s", "WASM=1",
55
+ "-s", "SIDE_MODULE=1",
56
  "-o", out_wasm
57
  ], capture_output=True, text=True, timeout=60)
58
 
 
71
  if not wasm_file: return "❌ Select a WASM file."
72
  path = os.path.join(SAVE_DIR, wasm_file)
73
  try:
74
+ # 1. Create the runtime
75
+ runtime = pywasm.Runtime()
76
 
77
+ # 2. Load the instance
78
+ module_instance = runtime.instance_from_file(path)
79
 
80
+ # 3. Explicit Arg Parsing
81
+ arg_list = []
82
+ if args.strip():
83
+ try:
84
+ arg_list = [int(x.strip()) for x in args.split(",")]
85
+ except ValueError:
86
+ return "❌ Error: Arguments must be a comma-separated list of integers."
87
+
88
+ # 4. Invocate with fallback for C underscore naming
89
  try:
90
+ result = runtime.invocate(module_instance, func_name, arg_list)
91
+ except Exception:
92
+ try:
93
+ result = runtime.invocate(module_instance, f"_{func_name}", arg_list)
94
+ except Exception as e:
95
+ return f"❌ Function '{func_name}' not found or failed: {str(e)}"
96
 
97
+ return f"Result: {result}"
98
  except Exception as e:
99
+ return f"❌ Runner Error: {str(e)}"
100
 
101
+ # 4. Visualizer Logic
102
  def render_wasm(wasm_file):
103
  if not wasm_file: return None, "❌ Select a file."
104
  path = os.path.join(SAVE_DIR, wasm_file)
105
 
106
+ try:
107
+ with open(path, "rb") as f:
108
+ data = f.read()
109
+
110
+ arr = np.frombuffer(data, dtype=np.uint8).copy()
111
+
112
+ if len(arr) > 0 and (arr.max() - arr.min()) != 0:
113
+ arr = ((arr - arr.min()) * (255 / (arr.max() - arr.min()))).astype(np.uint8)
 
114
 
115
+ canvas = np.zeros(1920 * 1080, dtype=np.uint8)
116
+
117
+ if len(arr) > 0:
118
+ tiled_data = np.tile(arr, (1920 * 1080 // len(arr)) + 1)
119
+ canvas = tiled_data[:1920 * 1080]
120
+
121
+ img = Image.fromarray(canvas.reshape((1080, 1920)), mode='L')
122
+ return img, f"Visualizing {len(data)} bytes."
123
+ except Exception as e:
124
+ return None, f"❌ Visualizer Error: {str(e)}"
125
 
126
+ # 5. Gradio UI (Fixed wiring and theme)
127
+ with gr.Blocks() as demo:
128
+ gr.Markdown("# πŸ› οΈ LCPU: Arithmetic Engine Fix-Build")
129
 
130
  with gr.Tab("1. The Forge"):
131
+ wasm_name = gr.Textbox(label="Output Filename", value="logic_core")
132
  c_code_input = gr.TextArea(label="C Code Source", value='int add(int a, int b) {\n return a + b;\n}', lines=8)
133
  compile_btn = gr.Button("πŸš€ Build Binary", variant="primary")
134
  forge_status = gr.Textbox(label="Forge Output")
 
138
  run_select = gr.Dropdown(label="Select Binary", choices=get_wasm_files())
139
  refresh_run = gr.Button("πŸ”„", variant="secondary")
140
  f_name = gr.Textbox(label="Function Name", value="add")
141
+ args_in = gr.Textbox(label="Arguments (e.g. 5, 10)", placeholder="5, 10")
142
  run_btn = gr.Button("⚑ Run Logic", variant="primary")
143
  run_output = gr.Textbox(label="Output Result")
144
 
 
148
  refresh_vis = gr.Button("πŸ”„", variant="secondary")
149
  render_btn = gr.Button("🎨 Map to 1080p", variant="primary")
150
  canvas_img = gr.Image(label="Logic Texture")
151
+ vis_status = gr.Textbox(label="Visualizer Status") # Fixed output box
152
 
153
+ # Event Wiring
154
  compile_btn.click(compile_c, [c_code_input, wasm_name], forge_status)
155
  refresh_run.click(lambda: gr.Dropdown(choices=get_wasm_files()), outputs=run_select)
156
  refresh_vis.click(lambda: gr.Dropdown(choices=get_wasm_files()), outputs=vis_select)
 
158
  render_btn.click(render_wasm, vis_select, [canvas_img, vis_status])
159
 
160
  if __name__ == "__main__":
161
+ # Theme moved to launch to avoid Gradio 6 syntax issues
162
+ demo.launch(theme=gr.themes.Monochrome())