Skip to content
rajumarkPublic

About

Write GPU kernels in plain Kotlin. A K2 compiler plugin turns @kernel functions into WGSL, so they run on any GPU through WebGPU, and they still run on the CPU for unit tests.

Topics

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

46 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Kernelin: the same Kotlin code runs way faster on the GPU than on the CPU, up to 118 times faster

Kernelin

CI Live demo Docs Maven Central License

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]);

Status

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.

Real-world projects

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.

Use it in your project

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).

Run a kernel on the GPU from Kotlin

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")

Modules

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)

Build

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/demo

Contributing

See CONTRIBUTING.md, the compatibility policy in VERSIONING.md, and SECURITY.md for reporting vulnerabilities. AI agents: start with AGENTS.md.

About

Write GPU kernels in plain Kotlin. A K2 compiler plugin turns @kernel functions into WGSL, so they run on any GPU through WebGPU, and they still run on the CPU for unit tests.

Topics

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages