Editor/Gpu/FlowGpuSingleBlock.cs
// C# adaptation of FlowHMR's MMSingleStreamBlock. See THIRD_PARTY_NOTICES.md.
using Sandbox;
using HumanoidMocapX.TensorInference;
namespace HumanoidMocapX.Inference;
internal sealed class FlowGpuSingleBlock
{
readonly FlowGpuLinear modulation, first, second;
readonly GpuBuffer<float> queryScale, keyScale;
internal FlowGpuSingleBlock(FlowGpuStorage storage, FlowWeights weights, int index, int width)
{
var name = "single_blocks." + index;
modulation = new(storage, weights, name + ".modulation.linear", width, 3 * width);
first = new(storage, weights, name + ".linear1", width, 7 * width);
second = new(storage, weights, name + ".linear2", 5 * width, width);
queryScale = storage.Weight(weights, name + ".q_norm.weight", FlowGpuWorkspace.HeadWidth);
keyScale = storage.Weight(weights, name + ".k_norm.weight", FlowGpuWorkspace.HeadWidth);
}
internal void Run(FlowGpuWorkspace w, GpuBuffer<float> features, GpuBuffer<float> adapter)
{
var k = w.Kernels; var rows = 2 * w.Frames; var width = w.Width;
modulation.Run(k, adapter, w.MotionGates);
k.Normalize(features, null, null, w.Normalized, rows, width, 1e-6f);
k.Modulate(w.Normalized, w.MotionGates, w.Modified, rows, width, 0, width);
first.Run(k, w.Modified, w.Packed, rows);
w.PrepareQkv(rows, 7 * width, 0, queryScale, keyScale);
w.Attend(true);
k.CopyColumns(w.Packed, w.Hidden, rows, 7 * width, 3 * width, 4 * width);
k.Activate(w.Hidden, w.Activated, rows * 4 * width, TensorActivation.Gelu);
k.ConcatColumns(w.Attended, w.Activated, w.Joined, rows, width, 4 * width);
second.Run(k, w.Joined, w.Projected, rows);
k.GatedAdd(features, w.Projected, w.MotionGates, w.Next, rows, width, 2 * width);
w.Next.CopyTo(features, rows * width);
}
}