Skip to content
Kavachकवच

GPU: gpu fn

● Advanced4 min

A gpu fn uses only what a GPU can do: 32-bit numbers and Bool, arithmetic, if, loops and other gpu fns. Anything else is a compile error that names it.

gpu fn brighten(x: Float32, gain: Float32) -> Float32 {
    const k = 1.5
    let v = x * k + gain
    if v > 1.0 {
        v = 1.0
    }
    v
}

fn main() {
    print(brighten(0.2, 0.1))
    const pixels: [Float32] = [0.1, 0.4, 0.9]
    print(pixels.map(p => brighten(p, 0.1)))
}

The program ran and printed:

kavach run rules.kav

0.4[0.25, 0.70000005, 1.0]
rules.kav: Kavach code, then what running it prints
AllowedNot allowedWhy
Float32, Int32, UInt32, BoolFloat, Int and other 64-bit typesGPUs compute 32-bit numbers fast: consumer NVIDIA GPUs run 64-bit floats at 1/64 of the speed, and WebGPU's shading language has none
those types, and records and tuples of 1 to 8 of them, as parameters and resulttext, lists, maps, pointerseach GPU thread holds a few fixed-size numbers; it can't make or grow a value in memory
const, let, =, if/else, while, for over 0..n, returnfor over a list, match, try, recursiona GPU has no call stack, and nothing a thread could loop over but its own numbers
+ - * / % and comparisons; ** on Float32print, debug, capabilities (files, network, AI)thousands of threads run at once, cut off from the outside world
Float32(n), Int32(x); abs, min, max, clamp; math.sqrt, floor, ceil, round, powa function that isn't a gpu fn, other std modulesthe compiler can only translate what it has checked follows these rules

Inside a gpu fn, a number with no other type is 32-bit: const k = 1.5 is a Float32. Called directly, as in brighten(0.2, 0.1), it runs on the CPU like any function. Each rule is checked when compiling:

gpu fn half(x: Float) -> Float {
    x / 2.0
}

The compiler refused the program:

kavach run float64.kav

error: `half` gives a `Float`, and a `gpu fn` works with `Float32`, `Int32`, `UInt32` and `Bool`, and records and tuples of 1 to 8 of them (spec 15.1)
float64.kav: Kavach code, then what running it prints
gpu fn twice(x: Float32) -> Float32 {
    print(x)
    x * 2.0
}

The compiler refused the program:

kavach run print.kav

error: a `gpu fn` can't use `print`: it reaches outside the program (files, the network, the terminal, time, AI), and on the GPU a `gpu fn` runs alone, item by item, with only its own values (spec 15.1)
print.kav: Kavach code, then what running it prints

Calling a plain function from a gpu fn is refused, and the message says whether that function could be one. This one could:

fn square(x: Float32) -> Float32 {
    x * x
}

gpu fn area(r: Float32) -> Float32 {
    3.14159 * square(r)
}

The compiler refused the program:

kavach run plain-call.kav

error: a `gpu fn` can't use `square`: it isn't a `gpu fn`, but it fits the GPU's rules. Mark it `gpu fn square`; it still runs on the CPU when called there (spec 15.1)
plain-call.kav: Kavach code, then what running it prints

This one can't, and the message says why:

fn loud(x: Float32) -> Float32 {
    print(x)
    x
}

gpu fn shout(x: Float32) -> Float32 {
    loud(x) * 2.0
}

The compiler refused the program:

kavach run plain-print.kav

error: a `gpu fn` can't use `loud`: it isn't a `gpu fn`, and can't be one, since it uses `print`: it reaches outside the program (files, the network, the terminal, time, AI), and on the GPU a `gpu fn` runs alone, item by item, with only its own values (spec 15.1)
plain-print.kav: Kavach code, then what running it prints
gpu fn total(xs: [Float32]) -> Float32 {
    let t: Float32 = 0.0
    for x in xs {
        t = t + x
    }
    t
}

The compiler refused the program:

kavach run list.kav

error: `xs` is a `[Float32]`, and a `gpu fn` works with `Float32`, `Int32`, `UInt32` and `Bool`, and records and tuples of 1 to 8 of them (spec 15.1)
list.kav: Kavach code, then what running it prints

So a gpu fn can never fail on the GPU in a way it couldn't on the CPU.

Limits and sizes

WhatLimit or sizeSource
Values in a gpu fnFloat32, Int32, UInt32 and Bool only15-gpu.md
A record or tuple item1 to 8 fields of those types15-gpu.md

Every limit in Kavach, on one page: Limits and Sizes.