| import gradio as gr |
| import os |
| import subprocess |
| import shutil |
| import numpy as np |
| from PIL import Image |
| import pywasm |
|
|
| |
| SAVE_DIR = "/data" |
| EMCC_DIR = os.path.join(SAVE_DIR, "emsdk") |
| if not os.path.exists(SAVE_DIR): |
| os.makedirs(SAVE_DIR, exist_ok=True) |
|
|
| def get_wasm_files(): |
| """Helper to list current WASM files in the bucket""" |
| if not os.path.exists(SAVE_DIR): |
| return [] |
| files = [f for f in os.listdir(SAVE_DIR) if f.endswith('.wasm')] |
| return files if files else [] |
|
|
| |
| def ensure_compiler(): |
| """Checks for Emscripten in the bucket, installs if missing""" |
| emcc_path = os.path.join(EMCC_DIR, "upstream/emscripten/emcc") |
| if os.path.exists(emcc_path): |
| return emcc_path |
| try: |
| subprocess.run(["git", "clone", "https://github.com/emscripten-core/emsdk.git", EMCC_DIR], |
| check=True, capture_output=True) |
| subprocess.run([os.path.join(EMCC_DIR, "emsdk"), "install", "latest"], |
| check=True, capture_output=True) |
| subprocess.run([os.path.join(EMCC_DIR, "emsdk"), "activate", "latest"], |
| check=True, capture_output=True) |
| return emcc_path |
| except Exception as e: |
| return f"Error: {str(e)}" |
|
|
| def compile_c(c_code, filename): |
| if not filename: |
| return "β Error: Please provide a filename." |
|
|
| emcc_path = ensure_compiler() |
| if "Error" in emcc_path: |
| return emcc_path |
|
|
| |
| base = filename.split('.')[0] |
| if not base: |
| return "β Error: Invalid filename." |
|
|
| c_f = f"/tmp/{base}.c" |
| out_wasm = f"/tmp/{base}.wasm" |
| dest_wasm = os.path.join(SAVE_DIR, f"{base}.wasm") |
|
|
| with open(c_f, "w") as f: |
| f.write(c_code) |
|
|
| try: |
| |
| res = subprocess.run([ |
| emcc_path, c_f, |
| "-O3", |
| "-s", "WASM=1", |
| "-s", "SIDE_MODULE=1", |
| "-o", out_wasm |
| ], capture_output=True, text=True, timeout=120) |
|
|
| if res.returncode != 0: |
| stderr = res.stderr[-2000:] if len(res.stderr) > 2000 else res.stderr |
| return f"β Compiler Error:\n{stderr}" |
|
|
| if os.path.exists(out_wasm): |
| if os.path.exists(dest_wasm): |
| os.remove(dest_wasm) |
| shutil.move(out_wasm, dest_wasm) |
| return f"β
Successfully Forged: {base}.wasm" |
| return "β Error: WASM file generation failed." |
| except subprocess.TimeoutExpired: |
| return "β Error: Compilation timed out (>120s)." |
| except Exception as e: |
| return f"β System Error: {str(e)}" |
|
|
| |
|
|
| def run_wasm_func(wasm_file, func_name, args_str): |
| if not wasm_file: |
| return "β Select a WASM file." |
| if not func_name: |
| return "β Provide a function name." |
|
|
| path = os.path.join(SAVE_DIR, wasm_file) |
| if not os.path.exists(path): |
| return f"β WASM file not found: {wasm_file}" |
|
|
| try: |
| |
| arg_list = [] |
| if args_str and args_str.strip(): |
| for x in args_str.split(","): |
| x = x.strip() |
| if x: |
| arg_list.append(int(x)) |
|
|
| |
| runtime = pywasm.Runtime() |
| module_instance = runtime.instance_from_file(path) |
|
|
| |
| |
| errors = [] |
| for name in [func_name, f"_{func_name}"]: |
| try: |
| result = runtime.invocate(module_instance, name, arg_list) |
| return f"β
Execution Successful!\nFunction: {name}\nResult: {result}" |
| except AssertionError as e: |
| |
| errors.append(f"'{name}': Wrong argument count or assertion failed") |
| except Exception as e: |
| errors.append(f"'{name}': {str(e)}") |
|
|
| return f"β Runner Error:\n" + "\n".join(errors) |
|
|
| except Exception as e: |
| return f"β Runner Error: {str(e)}" |
|
|
| |
|
|
| def render_wasm(wasm_file): |
| if not wasm_file: |
| return None, "β Select a file." |
|
|
| path = os.path.join(SAVE_DIR, wasm_file) |
| if not os.path.exists(path): |
| return None, f"β File not found: {wasm_file}" |
|
|
| try: |
| with open(path, "rb") as f: |
| data = f.read() |
|
|
| if len(data) == 0: |
| return None, "β Empty WASM file." |
|
|
| arr = np.frombuffer(data, dtype=np.uint8).copy() |
|
|
| |
| min_val = arr.min() |
| max_val = arr.max() |
| if max_val > min_val: |
| arr = ((arr - min_val) * (255.0 / (max_val - min_val))).astype(np.uint8) |
|
|
| |
| canvas_size = 1920 * 1080 |
| if len(arr) > 0: |
| repeats = (canvas_size // len(arr)) + 1 |
| tiled = np.tile(arr, repeats) |
| canvas = tiled[:canvas_size] |
| else: |
| canvas = np.zeros(canvas_size, dtype=np.uint8) |
|
|
| img = Image.fromarray(canvas.reshape((1080, 1920)), mode='L') |
| return img, f"β
Visualizing {len(data)} bytes β 1920Γ1080 grayscale" |
|
|
| except Exception as e: |
| return None, f"β Visualizer Error: {str(e)}" |
|
|
| |
| with gr.Blocks() as demo: |
| gr.Markdown("# π οΈ LCPU: Advanced Arithmetic Engine") |
|
|
| with gr.Tab("1. The Forge"): |
| wasm_name = gr.Textbox(label="Output Filename", value="logic_core", |
| placeholder="e.g. math_engine (no extension)") |
| c_code_input = gr.TextArea( |
| label="C Code Source", |
| value='int add(int a, int b) {\n return a + b;\n}\n\nint mul(int a, int b) {\n return a * b;\n}', |
| lines=10 |
| ) |
| compile_btn = gr.Button("π Build Binary", variant="primary") |
| forge_status = gr.Textbox(label="Forge Output", interactive=False) |
|
|
| with gr.Tab("2. The Runner"): |
| with gr.Row(): |
| run_select = gr.Dropdown(label="Select Binary", choices=get_wasm_files()) |
| refresh_run = gr.Button("π Refresh", variant="secondary") |
| f_name = gr.Textbox(label="Function Name", value="add") |
| args_in = gr.Textbox(label="Arguments (comma separated)", placeholder="10, 20") |
| run_btn = gr.Button("β‘ Run Logic", variant="primary") |
| run_output = gr.Textbox(label="Output Result", interactive=False) |
|
|
| with gr.Tab("3. The Visualizer"): |
| with gr.Row(): |
| vis_select = gr.Dropdown(label="Select Binary", choices=get_wasm_files()) |
| refresh_vis = gr.Button("π Refresh", variant="secondary") |
| render_btn = gr.Button("π¨ Map to 1080p", variant="primary") |
| canvas_img = gr.Image(label="Logic Texture") |
| vis_status = gr.Textbox(label="Visualizer Status", interactive=False) |
|
|
| |
| compile_btn.click(compile_c, inputs=[c_code_input, wasm_name], outputs=forge_status) |
|
|
| |
| refresh_run.click(lambda: gr.Dropdown(choices=get_wasm_files()), outputs=run_select) |
| refresh_vis.click(lambda: gr.Dropdown(choices=get_wasm_files()), outputs=vis_select) |
|
|
| run_btn.click(run_wasm_func, inputs=[run_select, f_name, args_in], outputs=run_output) |
| render_btn.click(render_wasm, inputs=vis_select, outputs=[canvas_img, vis_status]) |
|
|
| if __name__ == "__main__": |
| demo.launch(theme=gr.themes.Monochrome()) |