Skip to content

Math

Arithmetic the built-ins leave out. Every function here is an expression function: on a tile it fuses into the sweep of the statement that calls it, on a scalar it is plain arithmetic.

@autotune(T in [1024])
kernel blend(A: tensor<f32>[N], B: tensor<f32>[N], Y: tensor<f32>[N], w: f32) {
let i = ctx.block.x * T
Y[i :+ T] = lerp(A[i :+ T], B[i :+ T], clamp(w, 0.0, 1.0))
}

clamp(w, 0.0, 1.0) is scalar arithmetic on the parameter; lerp is computed per element in the one sweep that reads A and B and writes Y.

fn cdiv(a, b)expression

The number of b-sized pieces that cover a: ceil(a / b) for positive integers. The grid of a kernel tiling N by T is cdiv(N, T).

Source, std/math.ph:8
fn cdiv(a, b) = (a + b - 1) / b
fn round_up(a, b)expression

a rounded up to a multiple of b, for positive integers.

Source, std/math.ph:11
fn round_up(a, b) = cdiv(a, b) * b
fn square(x)expression

x * x.

Source, std/math.ph:14
fn square(x) = x * x
fn rcp(x)expression

1 / x.

Source, std/math.ph:17
fn rcp(x) = 1.0 / x
fn clamp(x, lo, hi)expression

x limited to [lo, hi], for lo <= hi.

Source, std/math.ph:20
fn clamp(x, lo, hi) = min(max(x, lo), hi)
fn lerp(a, b, w)expression

The point w of the way from a to b: a at 0, b at 1.

Source, std/math.ph:23
fn lerp(a, b, w) = a + w * (b - a)
fn exp2(x)fn log2(x)expression

2^x and log2(x), as approximate as exp and log.

Source, std/math.ph:26
fn exp2(x) = exp(x * 0.6931471805599453)
fn log2(x) = log(x) * 1.4426950408889634
fn sign(x)expression

-1 for a negative x, 1 for a positive one. Within 1e-30 of zero the result runs linearly through 0, so it is 0 at 0.

Source, std/math.ph:31
fn sign(x) = clamp(x * 1.0e30, -1.0, 1.0)
fn erf(x)expression

The error function, by Abramowitz and Stegun's 7.1.26: within 1.5e-7 of erf on every input, before the rounding of exp.

Source, std/math.ph:35
fn erf(x) = sign(x) * (1.0 - _erf_tail(1.0 / (1.0 + 0.3275911 * abs(x))) * exp(-x * x))

The built-ins have no erf, since its CUDA form is a libdevice call the compiler does not link. The polynomial is the library’s own helper, _erf_tail. The site’s tests check this definition against the series of erf over [-3, 3], where it stays within the stated 1.5e-7.