makepad/libs/ai/vulkan/kernels/elementwise.splash
Admin 74faf62ef1 ai: the AI hub gives way to the UI, smaller models, vision and speech
The AI hub serves local models on the LAN and now yields GPU memory to the
UI (shrinks the chat context, then unloads; grows back after; never loads
into the UI reserve), groups models by type, and reports each model's
memory split. LLM decode on Vulkan with Splash kernels, one shared GPU
device per process, vision on chat turns, an on-device text detector,
music models and stems.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-13 12:26:21 +02:00

77 lines
2.3 KiB
Text

// Elementwise and reduction kernels shared by every model (f32 activations).
{
// Extend each contiguous f32 row with zeroes to the requested stride.
pad_rows: {
workgroup_size: 256
src: shader.buffer(f32)
dst: shader.buffer_rw(f32)
cols: shader.uniform(u32)
stride: shader.uniform(u32)
len: shader.uniform(u32)
main: fn() {
let i = global_id().x
if i < self.len {
let col = i % self.stride
var v = 0.0
if col < self.cols { v = self.src[(i / self.stride) * self.cols + col] }
self.dst[i] = v
}
}
}
add_row_bias: {
workgroup_size: 256
dst: shader.buffer_rw(f32)
bias: shader.buffer(f32)
cols: shader.uniform(u32)
len: shader.uniform(u32)
main: fn() {
let i = global_id().x
if i < self.len { self.dst[i] += self.bias[i % self.cols] }
}
}
// dst[i] = src[i] * scale
scale: {
workgroup_size: 256
src: shader.buffer(f32)
dst: shader.buffer_rw(f32)
n: shader.uniform(u32)
scale: shader.uniform(f32)
main: fn() {
let i = global_id().x
if i < self.n {
self.dst[i] = self.src[i] * self.scale
}
}
}
// y[row] = sum(x[row, :]) over `cols` columns: one workgroup per row,
// strided partial sums, a subgroup reduction, then one per subgroup.
row_sum: {
workgroup_size: 256
x: shader.buffer(f32)
y: shader.buffer_rw(f32)
cols: shader.uniform(u32)
partial: shader.workgroup(f32, 32)
main: fn() {
let row = group_id().x
let t = local_id().x
var acc = 0.0
var c = t
while c < self.cols {
acc += self.x[row * self.cols + c]
c += self.workgroup_size
}
acc = subgroup_add(acc)
if subgroup_lane() == 0 {
self.partial[subgroup_id()] = acc
}
barrier()
if t == 0 {
var s = 0.0
for k in 0..self.workgroup_size / subgroup_size() {
s += self.partial[k]
}
self.y[row] = s
}
}
}
}