makepad/libs/ai/cuda/kernels/paint_extras.cu
Admin 7f59912916 libs/ai: one AI stack, replacing libs/ggml, llama, mlx, cuda, tts, voice2 and pbr_paint
The model code was spread across eight crates that had grown into each other:
ggml and cuda and mlx each owned part of a tensor runtime, llama and tts and
voice2 each owned part of a model, and libs/diffusion owned everything else.
They are now one tree with an explicit shape:

  libs/ai/cuda     — kernels and launch surface
  libs/ai/metal    — Metal shaders and the shim
  libs/ai/llm      — the language-model runtime (sessions, lanes, contexts,
                     the CUDA and Metal executors, the compiled Metal path)
  libs/ai/models/  — common, flux, h3, music, paint, speech, stems, vision

libs/diffusion is not deleted but demoted: what remains is the VALIDATOR
crate — several dozen `*_validate.rs` oracles that check a native
implementation against a reference, which is where they belong now that the
implementations live next door.

The functional work inside the move is mostly in the LLM runtime: N lanes that
draft while one verify batch serves all of them, per-slot prefill over a shared
folded attention arena, speculation that survives batching, and a scheduler
that reports rather than publishes. And in the CUDA build: a machine without
usable CUDA must still LINK (and say so), the default kernel arch is the
building machine's GPU, `NO_CUDA` forces the stub even where the toolkit
exists, and kernels compile in parallel with progress.

libs/video_flow is new here: classical optical flow estimation and the `mkfl`
motion-field payload — a flow field measured from a clip without a model,
which is what drives free-rate bounce-looping playback and the uprez/tween
enhance pipe.
2026-08-23 01:34:35 +02:00

550 lines
18 KiB
Text

// Focused Hunyuan3D-Paint extras kernels: wide-V reference attention and
// batched independent self-attention. Do not fold these into diffusion_ops.cu.
#include <cuda_runtime.h>
#include <math.h>
#include <stdint.h>
static constexpr int kPaintMaxHeadDim = 128;
// Matrix transpose: [rows, cols] -> [cols, rows]. Planar [C, HW] ↔ tokens [HW, C].
static __global__ void makepad_cuda_paint_transpose_f32_kernel(
const float * __restrict__ input,
float * __restrict__ output,
uint32_t rows,
uint32_t cols
) {
const size_t i = static_cast<size_t>(blockIdx.x) * blockDim.x + threadIdx.x;
const size_t n = static_cast<size_t>(rows) * cols;
if (i >= n) {
return;
}
const uint32_t r = static_cast<uint32_t>(i / cols);
const uint32_t c = static_cast<uint32_t>(i - static_cast<size_t>(r) * cols);
output[static_cast<size_t>(c) * rows + r] = input[i];
}
extern "C" cudaError_t makepad_cuda_paint_transpose_f32(
const float * input,
float * output,
uint32_t rows,
uint32_t cols,
cudaStream_t stream
) {
const size_t n = static_cast<size_t>(rows) * cols;
if (n == 0) {
return cudaSuccess;
}
const dim3 block(256, 1, 1);
const dim3 grid(static_cast<unsigned int>((n + block.x - 1) / block.x), 1, 1);
makepad_cuda_paint_transpose_f32_kernel<<<grid, block, 0, stream>>>(
input, output, rows, cols);
return cudaGetLastError();
}
static __device__ __forceinline__ float paint_dot(
const float * __restrict__ a,
const float * __restrict__ b,
uint32_t n
) {
float acc = 0.0f;
for (uint32_t i = 0; i < n; ++i) {
acc += a[i] * b[i];
}
return acc;
}
// Official RA: V is cat(v_alb, v_mr) on the last dim, then viewed as
// [heads, 2*head_dim]. Matches libs/pbr_paint/src/unet_extras.rs.
static __global__ void makepad_cuda_paint_ref_attn_wide_v_f32_kernel(
const float * __restrict__ q,
const float * __restrict__ k,
const float * __restrict__ v_alb,
const float * __restrict__ v_mr,
float * __restrict__ o_alb,
float * __restrict__ o_mr,
uint32_t q_len,
uint32_t kv_len,
uint32_t hidden,
uint32_t heads,
float scale
) {
const uint32_t qi = blockIdx.x * blockDim.x + threadIdx.x;
const uint32_t h = blockIdx.y;
if (qi >= q_len || h >= heads) {
return;
}
const uint32_t head_dim = hidden / heads;
const uint32_t v_head = head_dim * 2;
if (head_dim == 0 || head_dim > kPaintMaxHeadDim) {
return;
}
const float * qh = q + static_cast<size_t>(qi) * hidden + static_cast<size_t>(h) * head_dim;
float m = -INFINITY;
float l = 0.0f;
float acc[kPaintMaxHeadDim * 2];
for (uint32_t d = 0; d < v_head; ++d) {
acc[d] = 0.0f;
}
for (uint32_t ki = 0; ki < kv_len; ++ki) {
const float * kh = k + static_cast<size_t>(ki) * hidden + static_cast<size_t>(h) * head_dim;
const float s = paint_dot(qh, kh, head_dim) * scale;
const float m2 = fmaxf(m, s);
const float alpha = __expf(m - m2);
const float p = __expf(s - m2);
for (uint32_t d = 0; d < v_head; ++d) {
acc[d] *= alpha;
}
const uint32_t pack0 = h * v_head;
for (uint32_t d = 0; d < v_head; ++d) {
const uint32_t pack = pack0 + d;
const float * src = pack < hidden ? v_alb : v_mr;
const uint32_t off = pack < hidden ? pack : pack - hidden;
acc[d] += p * src[static_cast<size_t>(ki) * hidden + off];
}
l = l * alpha + p;
m = m2;
}
const float inv = 1.0f / fmaxf(l, 1e-12f);
float * oa = o_alb + static_cast<size_t>(qi) * hidden + static_cast<size_t>(h) * head_dim;
float * om = o_mr + static_cast<size_t>(qi) * hidden + static_cast<size_t>(h) * head_dim;
for (uint32_t d = 0; d < head_dim; ++d) {
oa[d] = acc[d] * inv;
om[d] = acc[head_dim + d] * inv;
}
}
extern "C" cudaError_t makepad_cuda_paint_ref_attn_wide_v_f32(
const float * q,
const float * k,
const float * v_alb,
const float * v_mr,
float * o_alb,
float * o_mr,
uint32_t q_len,
uint32_t kv_len,
uint32_t hidden,
uint32_t heads,
float scale,
cudaStream_t stream
) {
if (q_len == 0 || kv_len == 0 || heads == 0 || hidden == 0) {
return cudaSuccess;
}
if (hidden % heads != 0 || (hidden / heads) > kPaintMaxHeadDim) {
return cudaErrorInvalidValue;
}
const dim3 block(128, 1, 1);
const dim3 grid((q_len + block.x - 1) / block.x, heads, 1);
makepad_cuda_paint_ref_attn_wide_v_f32_kernel<<<grid, block, 0, stream>>>(
q, k, v_alb, v_mr, o_alb, o_mr, q_len, kv_len, hidden, heads, scale);
return cudaGetLastError();
}
// Independent self-attn over `batch` sequences packed as [batch * seq, hidden].
static __global__ void makepad_cuda_paint_attn_batched_self_f32_kernel(
const float * __restrict__ q,
const float * __restrict__ k,
const float * __restrict__ v,
float * __restrict__ out,
uint32_t batch,
uint32_t seq,
uint32_t hidden,
uint32_t heads,
float scale
) {
const uint32_t qi = blockIdx.x * blockDim.x + threadIdx.x;
const uint32_t bh = blockIdx.y;
const uint32_t b = bh / heads;
const uint32_t h = bh - b * heads;
if (qi >= seq || b >= batch || h >= heads) {
return;
}
const uint32_t head_dim = hidden / heads;
if (head_dim == 0 || head_dim > kPaintMaxHeadDim) {
return;
}
const size_t row0 = (static_cast<size_t>(b) * seq + qi) * hidden + static_cast<size_t>(h) * head_dim;
const float * qh = q + row0;
float m = -INFINITY;
float l = 0.0f;
float acc[kPaintMaxHeadDim];
for (uint32_t d = 0; d < head_dim; ++d) {
acc[d] = 0.0f;
}
const size_t batch_off = static_cast<size_t>(b) * seq * hidden;
for (uint32_t ki = 0; ki < seq; ++ki) {
const float * kh = k + batch_off + (static_cast<size_t>(ki) * hidden + static_cast<size_t>(h) * head_dim);
const float s = paint_dot(qh, kh, head_dim) * scale;
const float m2 = fmaxf(m, s);
const float alpha = __expf(m - m2);
const float p = __expf(s - m2);
const float * vh = v + batch_off + (static_cast<size_t>(ki) * hidden + static_cast<size_t>(h) * head_dim);
for (uint32_t d = 0; d < head_dim; ++d) {
acc[d] = acc[d] * alpha + p * vh[d];
}
l = l * alpha + p;
m = m2;
}
const float inv = 1.0f / fmaxf(l, 1e-12f);
float * oh = out + row0;
for (uint32_t d = 0; d < head_dim; ++d) {
oh[d] = acc[d] * inv;
}
}
static __global__ void makepad_cuda_paint_scale_f32_kernel(
const float * __restrict__ input,
float * __restrict__ output,
float scale,
uint32_t n
) {
const uint32_t i = blockIdx.x * blockDim.x + threadIdx.x;
if (i < n) {
output[i] = input[i] * scale;
}
}
extern "C" cudaError_t makepad_cuda_paint_scale_f32(
const float * input,
float * output,
float scale,
uint32_t n,
cudaStream_t stream
) {
if (n == 0) {
return cudaSuccess;
}
const dim3 block(256, 1, 1);
const dim3 grid((n + block.x - 1) / block.x, 1, 1);
makepad_cuda_paint_scale_f32_kernel<<<grid, block, 0, stream>>>(input, output, scale, n);
return cudaGetLastError();
}
// 3D PoseRoPE matching libs/pbr_paint apply_pose_rope: per-head rotary with
// xy dim = head_dim/8*3 and z dim = head_dim/8*2, theta=10000.
static __global__ void makepad_cuda_paint_pose_rope_f32_kernel(
const float * __restrict__ x,
const uint32_t * __restrict__ xyz,
float * __restrict__ out,
uint32_t seq,
uint32_t hidden,
uint32_t heads,
uint32_t voxel_res
) {
const uint32_t s = blockIdx.x;
const uint32_t h = blockIdx.y;
const uint32_t pair = threadIdx.x;
if (s >= seq || h >= heads) {
return;
}
const uint32_t head_dim = hidden / heads;
const uint32_t pairs = head_dim / 2;
if (pair >= pairs) {
return;
}
const uint32_t dim_xy = (head_dim / 8) * 3;
const uint32_t dim_z = (head_dim / 8) * 2;
const uint32_t pairs_xy = dim_xy / 2;
const uint32_t pairs_z = dim_z / 2;
uint32_t axis_dim = dim_xy;
uint32_t axis = 0;
uint32_t local = pair;
if (pair < pairs_xy) {
axis = 0;
local = pair;
axis_dim = dim_xy;
} else if (pair < pairs_xy * 2) {
axis = 1;
local = pair - pairs_xy;
axis_dim = dim_xy;
} else {
axis = 2;
local = pair - pairs_xy * 2;
axis_dim = dim_z;
if (local >= pairs_z) {
return;
}
}
uint32_t pos = xyz[s * 3 + axis];
if (voxel_res > 0 && pos >= voxel_res) {
pos = voxel_res - 1;
}
const float freq = expf(-logf(10000.0f) * (2.0f * static_cast<float>(local)) / static_cast<float>(axis_dim));
const float a = static_cast<float>(pos) * freq;
const float c = cosf(a);
const float si = sinf(a);
const size_t base = (static_cast<size_t>(s) * hidden + static_cast<size_t>(h) * head_dim) + static_cast<size_t>(pair) * 2;
const float re = x[base];
const float im = x[base + 1];
out[base] = re * c - im * si;
out[base + 1] = im * c + re * si;
}
extern "C" cudaError_t makepad_cuda_paint_pose_rope_f32(
const float * x,
const uint32_t * xyz,
float * out,
uint32_t seq,
uint32_t hidden,
uint32_t heads,
uint32_t voxel_res,
cudaStream_t stream
) {
if (seq == 0 || hidden == 0 || heads == 0) {
return cudaSuccess;
}
if (hidden % heads != 0 || (hidden / heads) % 2 != 0) {
return cudaErrorInvalidValue;
}
const uint32_t pairs = (hidden / heads) / 2;
const dim3 block(pairs < 128 ? pairs : 128, 1, 1);
const dim3 grid(seq, heads, 1);
makepad_cuda_paint_pose_rope_f32_kernel<<<grid, block, 0, stream>>>(
x, xyz, out, seq, hidden, heads, voxel_res);
return cudaGetLastError();
}
// [batch * seq, heads * hd] token-major -> [batch * heads * seq, hd]
// so one strided-batched GEMM can run over batch*heads.
static __global__ void makepad_cuda_paint_pack_heads_f32_kernel(
const float * __restrict__ input,
float * __restrict__ output,
uint32_t batch,
uint32_t seq,
uint32_t heads,
uint32_t head_dim
) {
const size_t n = static_cast<size_t>(batch) * seq * heads * head_dim;
const size_t i = static_cast<size_t>(blockIdx.x) * blockDim.x + threadIdx.x;
if (i >= n) {
return;
}
const uint32_t hidden = heads * head_dim;
const uint32_t d = static_cast<uint32_t>(i % head_dim);
const size_t t = i / head_dim;
const uint32_t h = static_cast<uint32_t>(t % heads);
const size_t bs = t / heads;
const uint32_t s = static_cast<uint32_t>(bs % seq);
const uint32_t b = static_cast<uint32_t>(bs / seq);
const size_t src = (static_cast<size_t>(b) * seq + s) * hidden + static_cast<size_t>(h) * head_dim + d;
const size_t dst = ((static_cast<size_t>(b) * heads + h) * seq + s) * head_dim + d;
output[dst] = input[src];
}
extern "C" cudaError_t makepad_cuda_paint_pack_heads_f32(
const float * input,
float * output,
uint32_t batch,
uint32_t seq,
uint32_t heads,
uint32_t head_dim,
cudaStream_t stream
) {
const size_t n = static_cast<size_t>(batch) * seq * heads * head_dim;
if (n == 0) {
return cudaSuccess;
}
const dim3 block(256, 1, 1);
const dim3 grid(static_cast<unsigned int>((n + block.x - 1) / block.x), 1, 1);
makepad_cuda_paint_pack_heads_f32_kernel<<<grid, block, 0, stream>>>(
input, output, batch, seq, heads, head_dim);
return cudaGetLastError();
}
static __global__ void makepad_cuda_paint_unpack_heads_f32_kernel(
const float * __restrict__ input,
float * __restrict__ output,
uint32_t batch,
uint32_t seq,
uint32_t heads,
uint32_t head_dim
) {
const size_t n = static_cast<size_t>(batch) * seq * heads * head_dim;
const size_t i = static_cast<size_t>(blockIdx.x) * blockDim.x + threadIdx.x;
if (i >= n) {
return;
}
const uint32_t hidden = heads * head_dim;
const uint32_t d = static_cast<uint32_t>(i % head_dim);
const size_t t = i / head_dim;
const uint32_t s = static_cast<uint32_t>(t % seq);
const size_t bh = t / seq;
const uint32_t h = static_cast<uint32_t>(bh % heads);
const uint32_t b = static_cast<uint32_t>(bh / heads);
const size_t src = ((static_cast<size_t>(b) * heads + h) * seq + s) * head_dim + d;
const size_t dst = (static_cast<size_t>(b) * seq + s) * hidden + static_cast<size_t>(h) * head_dim + d;
output[dst] = input[src];
}
extern "C" cudaError_t makepad_cuda_paint_unpack_heads_f32(
const float * input,
float * output,
uint32_t batch,
uint32_t seq,
uint32_t heads,
uint32_t head_dim,
cudaStream_t stream
) {
const size_t n = static_cast<size_t>(batch) * seq * heads * head_dim;
if (n == 0) {
return cudaSuccess;
}
const dim3 block(256, 1, 1);
const dim3 grid(static_cast<unsigned int>((n + block.x - 1) / block.x), 1, 1);
makepad_cuda_paint_unpack_heads_f32_kernel<<<grid, block, 0, stream>>>(
input, output, batch, seq, heads, head_dim);
return cudaGetLastError();
}
// Independent GroupNorm over N planar images packed as [C, N * H * W].
static __global__ void makepad_cuda_paint_gn_batched_stats_f32_kernel(
const float * __restrict__ input,
float * __restrict__ stats,
uint32_t width,
uint32_t height,
uint32_t channels,
uint32_t groups,
uint32_t batch,
float eps
) {
const uint32_t g = blockIdx.x;
const uint32_t b = blockIdx.y;
if (g >= groups || b >= batch) {
return;
}
const uint32_t cpg = channels / groups;
const uint32_t plane = width * height;
const uint32_t c0 = g * cpg;
const size_t col0 = static_cast<size_t>(b) * plane;
const size_t count = static_cast<size_t>(cpg) * plane;
double sum = 0.0;
double sumsq = 0.0;
for (uint32_t c = 0; c < cpg; ++c) {
const float * row = input + static_cast<size_t>(c0 + c) * (static_cast<size_t>(batch) * plane) + col0;
for (uint32_t i = threadIdx.x; i < plane; i += blockDim.x) {
const double v = static_cast<double>(row[i]);
sum += v;
sumsq += v * v;
}
}
for (int offset = 16; offset > 0; offset >>= 1) {
sum += __shfl_down_sync(0xffffffffu, sum, offset);
sumsq += __shfl_down_sync(0xffffffffu, sumsq, offset);
}
__shared__ double sh_sum[8];
__shared__ double sh_sumsq[8];
const int warp = threadIdx.x >> 5;
const int lane = threadIdx.x & 31;
if (lane == 0) {
sh_sum[warp] = sum;
sh_sumsq[warp] = sumsq;
}
__syncthreads();
if (threadIdx.x == 0) {
double t = 0.0;
double t2 = 0.0;
const int warps = (blockDim.x + 31) >> 5;
for (int w = 0; w < warps; ++w) {
t += sh_sum[w];
t2 += sh_sumsq[w];
}
const double mean = t / static_cast<double>(count);
const double var = fmax(t2 / static_cast<double>(count) - mean * mean, 0.0);
const uint32_t idx = b * groups + g;
stats[idx * 2] = static_cast<float>(mean);
stats[idx * 2 + 1] = static_cast<float>(rsqrt(var + static_cast<double>(eps)));
}
}
static __global__ void makepad_cuda_paint_gn_batched_apply_f32_kernel(
const float * __restrict__ input,
const float * __restrict__ gamma,
const float * __restrict__ beta,
const float * __restrict__ stats,
float * __restrict__ output,
uint32_t width,
uint32_t height,
uint32_t channels,
uint32_t groups,
uint32_t batch
) {
const size_t n = static_cast<size_t>(channels) * batch * width * height;
const size_t i = static_cast<size_t>(blockIdx.x) * blockDim.x + threadIdx.x;
if (i >= n) {
return;
}
const uint32_t plane = width * height;
const uint32_t cols = batch * plane;
const uint32_t col = static_cast<uint32_t>(i % cols);
const uint32_t c = static_cast<uint32_t>(i / cols);
const uint32_t b = col / plane;
const uint32_t cpg = channels / groups;
const uint32_t g = c / cpg;
const uint32_t idx = b * groups + g;
const float mean = stats[idx * 2];
const float inv = stats[idx * 2 + 1];
const float x = input[i];
output[i] = (x - mean) * inv * gamma[c] + beta[c];
}
extern "C" cudaError_t makepad_cuda_paint_gn_batched_f32(
const float * input,
const float * gamma,
const float * beta,
float * stats,
float * output,
uint32_t width,
uint32_t height,
uint32_t channels,
uint32_t groups,
uint32_t batch,
float eps,
cudaStream_t stream
) {
if (batch == 0 || width == 0 || height == 0 || channels == 0 || groups == 0) {
return cudaSuccess;
}
if (channels % groups != 0) {
return cudaErrorInvalidValue;
}
const dim3 sblock(256, 1, 1);
const dim3 sgrid(groups, batch, 1);
makepad_cuda_paint_gn_batched_stats_f32_kernel<<<sgrid, sblock, 0, stream>>>(
input, stats, width, height, channels, groups, batch, eps);
cudaError_t err = cudaGetLastError();
if (err != cudaSuccess) {
return err;
}
const size_t n = static_cast<size_t>(channels) * batch * width * height;
const dim3 ablock(256, 1, 1);
const dim3 agrid(static_cast<unsigned int>((n + ablock.x - 1) / ablock.x), 1, 1);
makepad_cuda_paint_gn_batched_apply_f32_kernel<<<agrid, ablock, 0, stream>>>(
input, gamma, beta, stats, output, width, height, channels, groups, batch);
return cudaGetLastError();
}
extern "C" cudaError_t makepad_cuda_paint_attn_batched_self_f32(
const float * q,
const float * k,
const float * v,
float * out,
uint32_t batch,
uint32_t seq,
uint32_t hidden,
uint32_t heads,
float scale,
cudaStream_t stream
) {
if (batch == 0 || seq == 0 || heads == 0 || hidden == 0) {
return cudaSuccess;
}
if (hidden % heads != 0 || (hidden / heads) > kPaintMaxHeadDim) {
return cudaErrorInvalidValue;
}
const dim3 block(128, 1, 1);
const dim3 grid((seq + block.x - 1) / block.x, batch * heads, 1);
makepad_cuda_paint_attn_batched_self_f32_kernel<<<grid, block, 0, stream>>>(
q, k, v, out, batch, seq, hidden, heads, scale);
return cudaGetLastError();
}