Write GPU kernels in plain Kotlin. A K2 compiler plugin translates @Kernel functions to WGSL,
so they run on any GPU through WebGPU, and they still run on the CPU for unit tests.
@Kernel
fun saxpy(alpha: Float, x: FloatArray, y: FloatArray) {
val i = globalId()
y[i] += alpha * x[i]
}becomes
@group(0) @binding(1) var<storage, read> x: array<f32>;
@group(0) @binding(2) var<storage, read_write> y: array<f32>;
...
let i: i32 = i32(kernelin_id);
y[i] += (kernelin_params.alpha * x[i]);0.4.0 is released on Maven Central. On an Apple M5, the generated shaders match the Kotlin CPU results and run
up to 118× faster than all 10 CPU cores; on a mid-range Android phone (Adreno GPU, Chrome) up to 33× faster than all
8 CPU cores (see the website and benchmarks/). Since 0.2.0,
IntelliJ IDEA and Android Studio underline code the GPU can't run while you type.
Live demo → a fractal computed on your GPU by Kernelin-generated code.
Documentation → guides, API reference and compiler internals. AI agents can read
docs.md or llms.txt; see also AGENTS.md.
kernelin-projects (live): three apps built with Kernelin from Maven Central, each checked against exact answers and benchmarked.
- Risk Engine (simulation): Monte Carlo options pricing + greeks, 1M paths × 252 days × 4 scenarios in 46 ms on an Apple M5 GPU, 53× faster than 10 JVM cores.
- Photo Studio (image): live photo editing with edge-preserving denoise, 3.8 MP in 48 ms, +11.3 dB PSNR.
- Motion Guard (video): traffic camera motion vectors and vehicle speeds, 720p in 19 ms (live 30 fps), precision 0.995 vs ground truth.
Kernelin is on Maven Central. Make sure mavenCentral() is in your plugin repositories:
// settings.gradle.kts
pluginManagement {
repositories {
mavenCentral()
gradlePluginPortal()
}
}// build.gradle.kts
plugins {
kotlin("jvm") version "2.4.21" // or kotlin("multiplatform"), or an Android plugin
id("io.github.rajumark.kernelin") version "0.4.0"
}The plugin runs the Kernelin compiler plugin on every compilation and adds
io.github.rajumark:kernelin-runtime in Kotlin JVM, Multiplatform and Android projects (plus kernelin-webgpu to
wasmJsMain in Multiplatform projects).
Kernelin 0.4.0 is built for Kotlin 2.4.21; the compiler plugin API changes between Kotlin versions.
| Artifact | What it is |
|---|---|
io.github.rajumark:kernelin-runtime:0.4.0 |
@Kernel, globalId(), kernelSource(), KernelinCpu (JVM, JS, Wasm, Native) |
io.github.rajumark:kernelin-webgpu:0.4.0 |
WebGPU host: Kotlin/Wasm (browser), Android and desktop JVM (native) |
io.github.rajumark:kernelin-compiler-plugin:0.4.0 |
the K2 compiler plugin (added by the Gradle plugin) |
io.github.rajumark:kernelin-gradle-plugin:0.4.0 |
Gradle plugin io.github.rajumark.kernelin |
See examples/ for complete projects (hello-jvm, hello-multiplatform).
val gpu = WebGpu.create() // Kotlin/Wasm, any WebGPU browser
gpu.dispatch(n) { saxpy(alpha = 2.5f, x = x, y = y) } // a normal call: names and types checked at compile time
// y now holds the result, just like after KernelinCpu.dispatch(n) { saxpy(2.5f, x, y) }On a device that may have no GPU, Compute.create() picks the GPU when there is one and the CPU when not, with the
same compute.dispatch(n) { saxpy(...) } call.
Typed dispatch and Compute are new in 0.4.0. For more control (data that stays on the GPU), load the kernel and
pass arguments by name:
val kernel = gpu.load(kernelSource(::saxpy)) // the compiler embeds the WGSL here
val result = kernel.run(
size = n,
scalars = mapOf("alpha" to 2.5f),
buffers = mapOf("x" to GpuData.of(x), "y" to GpuData.of(y)),
)
val y2 = result.floats("y")| Module | What it is |
|---|---|
kernelin-runtime |
Multiplatform (JVM, JS, Wasm, iOS, macOS, tvOS, watchOS, Linux, Windows): @Kernel, globalId(), KernelinCpu (CPU runner), kernelSource(::k) |
kernelin-compiler-plugin |
K2 compiler plugin; WgslKernelTranslator turns Kotlin IR into WGSL and embeds it where kernelSource(::k) is called |
kernelin-webgpu |
WebGPU host for Kotlin/Wasm (browser), and natively (since 0.4.0) for Android and desktop JVM apps (macOS, Linux, Windows; no browser): WebGpu.create(), gpu.dispatch(n) { k(...) }, gpu.load(kernelSource(::k)), kernel.run(...) |
kernelin-gradle-plugin |
id("io.github.rajumark.kernelin"): one-line setup for JVM, Multiplatform and Android projects; kernelin { enabled = false } |
samples |
Kernels in commonMain (JVM + Wasm), CPU tests and benchmark (JVM), live demo entry points (Wasm) |
Requires JDK 21. Tests validate every generated shader with naga
when it's installed (cargo install naga-cli).
gradle build
gradle :samples:bench -Pout=/path/to/folder # then serve the folder and open runner.html
gradle :samples:benchGpu # same kernels on this computer's GPU through the JVM GPU host
scripts/bench-android.sh /path/to/folder # same GPU benchmark in Chrome on a USB-connected Android phone
scripts/bench-android-cpu.sh # the CPU side on the phone (Kotlin on ART)
scripts/bench-android-app.sh # GPU (native WebGPU, no browser) and CPU benchmark in an Android app
gradle :samples:exportDemo # rebuild the Kotlin/Wasm live demo into docs/demoSee CONTRIBUTING.md, the compatibility policy in VERSIONING.md, and SECURITY.md for reporting vulnerabilities. AI agents: start with AGENTS.md.
