One language for AI, hashing, and graphics — running on your GPU today, built to target FPGAs and custom silicon next.
A shaded 3D cube, rasterized pixel-by-pixel by a clic kernel on the GPU.
CUDA is fast, but it only runs on NVIDIA. That lock-in is its biggest weakness.
clic keeps what's good about CUDA — the simple grid-of-threads kernel model — and drops what isn't: the vendor lock-in, the block/thread bookkeeping, the cryptic errors. One kernel, written once, is meant to run on many backends.
your kernel (.clic)
│ clicc.py (compiler)
▼
Metal Shading Language ──► Apple GPU ◄─ works today
(next) clic IR ──────────► FPGA over USB ◄─ our own board
(next) clic IR ──────────► custom silicon
The bet: you don't beat CUDA on raw speed — you beat it on openness, efficiency-per-watt, and sovereignty, and clic is the software layer that makes non-NVIDIA hardware usable.
| Workload | Kernel | Result | Verified against |
|---|---|---|---|
| 🧠 AI | gemm_tiled (1024³, shared memory) |
~864 GFLOP/s | CPU reference |
| 🧠 AI | linear_relu / linear (dense layer) |
~508 GFLOP/s | CPU reference |
| 🧠 AI | attention (scaled dot-product) |
verified | CPU reference |
| 🔐 Hash | sha256 (1M nonces) |
~889 MH/s | Apple CryptoKit |
| 🎮 Graphics | raster (512², shaded cube) |
~5,700 fps | (the GIF above) |
The tiled GEMM is 1.8× faster than the naive one — same language, real GPU optimization (shared memory + barriers). The SHA-256 runtime also scans its range for the "hardest" hash — a real mining primitive. Full, current table for all 15 kernels: docs/BENCHMARKS.md.
Requires macOS with Xcode command-line tools (Swift + the Metal compiler) and Python 3. Then:
git clone https://github.com/Lastoneparis/clic
cd clic
./run.sh # compiles every kernel and runs it on your GPUOr use the CLI:
bin/clic build examples/gemm.clic # compile a kernel to Metal
bin/clic run runs/gemm.json # build (if needed) + run on the GPU
bin/clic bench # run every example
bin/clic sim # run the RTL simulationsEach kernel prints its throughput and a correctness check. New here? Walk through docs/TUTORIAL.md — write and run your own kernel in a few minutes. See also clic vs CUDA (honest positioning).
Run a kernel on the GPU in a few lines — no Metal boilerplate (python/):
import clic
out = clic.run("examples/saxpy.clic", "saxpy", grid=[8, 1, 1],
values={"n": 8, "a": 3.0, "x": [0,1,2,3,4,5,6,7], "y": [10]*8},
read=["y"])
print(out["y"]) # [10.0, 13.0, 16.0, 19.0, 22.0, 25.0, 28.0, 31.0]Kernels compose into real inference — python/mlp_demo.py runs a 2-layer MLP,
python/transformer_demo.py runs a full transformer forward pass
(rmsnorm → attention → FFN → logits → argmax), and
python/mistral_block_demo.py runs a full Mistral-style decoder block
(rmsnorm → RoPE → attention → residual → rmsnorm → SwiGLU → down → residual)
on the GPU, each matching a CPU reference.
tid.x is the global thread index — no block math to get wrong:
// y = a*x + y
kernel saxpy(n: i32, a: f32, x: buffer<f32>, y: buffer<f32>) {
let i = tid.x;
if (i < n) {
y[i] = a * x[i] + y[i];
}
}It also has reusable device functions and a small standard library — a fused neural-net layer is just:
include "../lib/activations.clic" // relu, gelu, sigmoid, ...
kernel linear_relu(/* ... */) {
// ... matmul + bias ...
C[row * N + col] = relu(acc); // C = relu(A*B + bias)
}Plus threadgroup (shared) memory, barrier(), bitwise ops and rotr (for
crypto), local array<T,N>, and per-group ids ltid/bid. Full reference:
docs/LANGUAGE.md. Kernels in examples/, or
tour them in the gallery.
| Path | What |
|---|---|
clicc.py |
The compiler: clic → Metal (lexer, parser, codegen) |
examples/*.clic |
Kernels: saxpy, gemm, gemm_tiled, gemm_i8 (INT8), linear_relu, linear_gelu, reduce, scan, nn (softmax/layernorm/rmsnorm), attention, conv2d, argmax, quant (INT8), collatz, sha256, raster |
lib/*.clic |
Standard library (activation functions) |
host/clicrun.swift |
Metal runtime + benchmark & verification harness |
python/clic.py |
Python host API — run a kernel from Python |
raster_scene.py |
Host-side geometry (the "vertex stage") for the rasterizer |
runs/*.json |
Run manifests (sizes, grid, buffers) |
docs/LANGUAGE.md |
The language reference · tests/ |
- clic → Metal; GEMM, SAXPY, SHA-256 running and verified
- Shared memory,
barrier(),ltid/bid— tiled GEMM (1.8× over naive) - SHA-256 verified vs Apple CryptoKit, plus a mining scan
- Triangle rasterizer — a shaded 3D cube (graphics path started)
- Device functions +
include; a stdlib (activations) + a fused NN layer - Full control flow:
while,break/continue, compound assignment - Parallel reduction (tree sum) + a step-by-step TUTORIAL
- Ternary operator +
f16(half) type — verified on GPU -
i8/u8quantized types (INT8 quantize/dequantize) — verified on GPU - Scaled dot-product attention (transformer core) — verified on GPU
- AI library: softmax + layernorm (transformer building blocks)
- Python host API — run a clic kernel from Python in a few lines
- A dedicated clic IR (decouple the front-end from backends)
- The FPGA backend — target the Lattice ECP5 (ULX3S) over USB
- Textured / perspective-correct triangles; animation
- The long road: a graphics API + drivers (to run real games)
clic is an early prototype. It is not faster than CUDA in absolute terms — nothing is, by being a language; speed comes from silicon. What clic offers is portability, clean ergonomics, and a path to hardware you control. Contributions and ideas welcome — see CONTRIBUTING.md.
The bigger vision — a European fabless AI-inference accelerator built on this open stack — is in PITCH.md and docs/FUNDRAISING.md.
Toward silicon — OSHI-A1: the accelerator this stack compiles to (131 TOPS
INT8 / 262 TOPS INT4, 273 GB/s, ~52 W, ~125 mm² @12 nm — see the
silicon spec), with a de-risked path from FPGA
to an FD-SOI MPW tape-out:
architecture ·
ISA ·
MVP silicon ·
ASIC flow ·
MPW shuttle & process ·
hardware roadmap.
The compute core is real, not just specified: rtl/ has a
synthesizable systolic MAC array + a full GEMM accelerator block (SRAM +
control FSM + host port) in Verilog, verified in simulation (./rtl/sim.sh) and
synthesized to the ECP5 — it fits the ULX3S 85F (a 12×12 = 144-MAC cluster),
DSP-mapped (synthesis results).
MIT © 2026 Hugo Moriceau
If this direction interests you, a ⭐ helps it find contributors.