Built on MLIR & LLVM

Marlin

Write it once. Run it on every CPU core and the GPU.

A fast, compiled language with a calm, readable syntax. Tasks, parallel loops and GPU functions are part of the language, so the same source runs on your CPU and your graphics card.

$ curl -fsSL https://github.com/MehmetEminKaymaz/marlin/releases/latest/download/install.sh | sh
1 sourcefor CPU and GPU
Nativeon Linux, macOS & Windows
MLIR 19under the hood
0 data racesin accepted parallel loops
Why Marlin

Speed you can read

Marlin keeps the syntax small and moves the hard parts into the compiler: scheduling, GPU kernels, memory and safety checks.

GPU with one word

Put @GPU above a function. Matrix maths and parallel loops inside it become GPU kernels for NVIDIA, AMD, Intel and Apple graphics; without a GPU the same code runs on the CPU.

@GPU func relax(...) -> matrix<float64>

Lightweight tasks

marl f(x) starts a task, await(t) takes its result. Waiting never blocks a thread, so thousands of tasks can be in flight.

task<int64> t = marl fib(32);

Parallel loops, checked

parallel for spreads iterations over every core. The compiler rejects loops that could race, so the ones it accepts are correct.

parallel for i in 0 .. n { v[i] = f(i); }

Web server included

std.http ships an HTTP/1.1 server with routing, query and form helpers. One call serves every request in its own task.

http.serve_concurrent(8080, routes);

PostgreSQL & SQLite

Parameterised queries, transactions and connection pools. scan fills a list of structs straight from the result rows.

list<User> users = scan(r.rows);

Matrices built in

matrix<T, N> is a first-class type. a + b * 2 - c runs as one fused loop and matmul is tiled for speed.

matrix<float> d = matmul(a, b);
Examples

Real programs, real output

Every example below was compiled with marlin -O2 and run. The output is exactly what it printed.

basics.marl

struct Point {
    float64 x;
    float64 y;
}

func length(Point p) -> float64 {
    return sqrt(p.x * p.x + p.y * p.y);
}

func main() -> void {
    list<Point> points = [Point(3, 4), Point(6, 8)];
    let square = (int n) -> int | n * n;
    for p in points {
        print("length:", length(p));
    }
    print("square(7) =", square(7));
    free(points);
}
Output
length: 5.0
length: 10.0
square(7) = 49
How it works

From .marl to machine code

Marlin is a front end for MLIR, the compiler framework behind many modern ML and HPC tools. Each step can be inspected with --emit.

.marl

Source

Small, typed syntax. Modules with import.

AST

Checks

Types, race-freedom of parallel loops, task and GPU rules.

MLIR

Dialects

Loops, tensors and tasks as high-level IR.

scftensorasyncgpu
LLVM

Lowering

CPU code through LLVM IR. GPU kernels as PTX for CUDA and SPIR-V for Vulkan.

nvvmspirv
EXE

Native binary

One file for Linux, macOS or Windows. No VM, no interpreter.

Performance

Same code, more hardware

When a GPU is there, the same source uses it. Without one, it runs on every CPU core.

CPU or GPU, one source

2048 × 2048 float matmul, five times

CPU, all 20 threads350 ms
RTX 4060 Laptop (CUDA)30 ms
11.7× faster

Built-in kernel

4096 × 4096 float on the GPU

hand-written parallel for270 ms
built-in tiled matmul35 ms
7.7× faster

The first card is one @GPU program, run once with MARLIN_GPU=cpu and once on the graphics card (copies to and from the GPU included). Measured on the same laptop; your numbers will differ.

Quick start

Install in one line

  1. Install

    Run the command for your system. It downloads the compiler, verifies it, puts it in your home folder and adds marlin to your PATH. Run it again to update.

  2. Check your setup

    marlin doctor compiles a few small programs and tells you exactly what is missing, with the command that installs it.

  3. Write and run

    Save a .marl file and compile it. You get a native executable; add -O2 for speed.

# needs a C compiler, e.g. sudo apt install build-essential
$ curl -fsSL https://github.com/MehmetEminKaymaz/marlin/releases/latest/download/install.sh | sh
$ marlin doctor

# hello.marl:  func main() -> void { print("hello, ocean"); }
$ marlin hello.marl -O2 -o hello
$ ./hello
hello, ocean

Write in comfort with VS Code

The Marlin extension adds syntax colouring, snippets, live errors from the real compiler (through its built-in language server) and a one-key Compile & Run.