One Language, Every Core

Vx is a systems programming language for heterogeneous computing. CPU, GPU, NPU and accelerator memory are part of the type system — so a host thread dereferencing a device pointer is a compile error, not a segfault at three in the morning.

curl -fsSL https://vxlang.org/install.sh | sh

macOS on Apple Silicon and Linux x86_64. Other install options.

Heterogeneity belongs in the type system, not in the runtime.

Where data lives is part of its type

Most languages treat the accelerator as infrastructure: you write math, and a large opaque runtime decides how to ship it. Vx treats it as semantics. A tensor pinned to NPU high-bandwidth memory has a different type from one in host DRAM, and crossing between them takes an explicit transfer()even when the hardware boundary is free.

On Apple's unified memory that transfer compiles to almost nothing. It is still written down, because data locality should be provable by reading the source rather than by profiling the binary.

// Two matrices already resident in NPU memory.
fn custom_matmul(
    a: Pinned<Tensor<f32, [4, 4]>, Topology::NPU[0]>,
    b: Pinned<Tensor<f32, [4, 4]>, Topology::NPU[0]>)
    -> Verified<Tensor<f32, [4, 4], Memory::NPU_HBM>> {

    let mut result =
        Tensor<f32, [4, 4], Memory::NPU_HBM>::uninit();

    // Dispatch the computation to the accelerator.
    spawn on(Topology::NPU[0]) {
        for i in 0..4 {
            for j in 0..4 {
                result[i][j] = 0.0;
                for k in 0..4 {
                    result[i][j] += a[i][k] * b[k][j];
                }
            }
        }
    }

    return Verified(result);
}

What the compiler rules out

Vx front-loads into type checking a class of bug that normally surfaces as a runtime crash, silent corruption, or an out-of-memory at training step 1200.

Address-space typing

Dereferencing a device pointer from the host. A Pinned<T, NPU_SRAM> escaping into a host expression.

Capacity admission

A placement whose working set cannot fit the memory space it targets — checked against the declared machine, before a binary exists.

Seam contracts

Reading a buffer whose asynchronous transfer has not been made visible. Discharged by an SMT prover.

Linear types

Use-after-move of a consumed buffer, alongside a borrow checker with variance and region tracking.

Topology reachability

A transfer between two memory spaces with no declared path between them.

Autodiff

Differentiating through a region whose adjoint is not defined.

The machine is declared, not assumed

Most compilers hard-code a cost model. Vx reads one. A machine file describes the memory hierarchy and interconnect of a real part, and the compiler admits or rejects placements against it.

Units are exact integer conversions, never floats: SI prefixes are decimal (GB = 109), IEC are binary (GiB = 230). A figure copied off a vendor sheet means what the sheet meant.

The repository ships machine files for H100, H200, B200, A100, MI300X, Apple M4 and multi-GPU nodes — each citing its sources, and marking unverified figures as unverified.

Memory HBM  { capacity: 80 GiB, bandwidth: 3.35 TB/s,
              managed: explicit, scope: device }

Memory L2   { within: Memory::HBM, capacity: 50 MiB,
              bandwidth: 12 TB/s, managed: cached }

Memory SMEM { within: Memory::L2, capacity: 228 KiB,
              bandwidth: 128 B/cyc, clock: 1.98 GHz,
              replicas: 132, granule: 1 KiB, scope: sm }

Topology Device {
    arch: nvptx64,
    memory: Memory::HBM,
    transfer Memory::CPU_DRAM -> Memory::HBM : 63 GB/s,
}

How it compiles

A data-oriented parallel frontend

Every symbol, nominal type and monomorphized variant is a flat 256-bit identifier. A nominal type system plus mandatory boxing for recursive types decouples modules, so the pipeline runs parallel across cores with no query engine and no lock contention. Compilation walks flat arrays rather than pointer-chased trees.

The same source compiles to byte-identical MLIR whether it is built serially or in parallel. That is asserted in the test suite rather than hoped for — at benchmark scale, at one thread, at four, and with the thread pool taken off the path entirely, plus a corpus recompiled in fresh processes so each run gets its own hash seed. The claim is about the MLIR the frontend emits; everything downstream of it belongs to LLVM.

Backends

CPU (x86-64, arm64)MLIR → LLVM IR → native, AOT or JIT
NVIDIA GPUMLIR → NVVM → PTX → SASS
Apple AMX / ANECoreML primitive dispatch via plugin
DistributedManifest-driven remote regions over a wire protocol

Vendors extend the compiler through MLIR pass plugins rather than by patching it.

Where Vx is the wrong tool

PyTorch users mutate architecture mid-loop, print a tensor shape, branch on it, and carry on. In Vx — ahead-of-time, data-oriented, statically regioned — that same dynamism takes real work.

Vx is the right language for the thing that must be correct and fast across ten kinds of silicon. It is not the right language for the thing you are still figuring out.

Start here