tests/common/denoiser_reference.cs
using HumanoidMocapX.Inference;

/// <summary>Allocation-heavy, double-precision equations independent of production operators.</summary>
static class DenoiserReference
{
    const int Width = DenoiserTests.Width, Heads = DenoiserTests.Heads, HeadWidth = Width / Heads;

    internal static double[] Predict(Dictionary<string, Tensor> weights, double[] state, float[] body, float[] camera, float time)
    {
        double[] Linear(double[] x, string name) => RefinerTests.Linear(weights, x, name);
        double[] Mlp(double[] x, string name) => Linear(Linear(x, name + ".0").Select(Silu).ToArray(), name + ".2");
        var context = Add(Linear(body.Select(v => (double)v).ToArray(), "ctxt_encoder.feature"),
            Linear(camera.Select(v => (double)v).ToArray(), "ctxt_encoder.camera_R"));
        var frequencies = Enumerable.Range(0, Width / 2).Select(i => (double)time * 1000 * Math.Pow(10000, -2d * i / Width)).ToArray();
        var embeddedTime = frequencies.Select(Math.Cos).Concat(frequencies.Select(Math.Sin)).ToArray();
        var adapter = Add(Mlp(embeddedTime, "timestep_encoder.blocks"), Mlp(new double[FlowDenoiser.TextChannels], "vtxt_encoder.linears"));
        var streams = new[] { Linear(state, "input_encoder"), RefinerTests.Reference(weights, context, time) };
        var frames = streams[0].Length / Width;
        for (var index = 0; index < FlowDenoiser.DoubleBlocks; index++)
        {
            var q = new double[2 * frames * Width]; var k = new double[q.Length]; var v = new double[q.Length];
            var gates = new double[2][];
            for (var branch = 0; branch < 2; branch++)
            {
                var name = "double_blocks." + index + (branch == 0 ? ".motion" : ".text");
                gates[branch] = Linear(adapter.Select(Silu).ToArray(), name + "_mod.linear");
                var modulated = Modulate(Normalize(streams[branch], Width, false, 1e-6), gates[branch], 0, 1);
                var qkv = Linear(modulated, name + "_qkv");
                SplitQkv(weights, qkv, frames, 3 * Width, name + "_q_norm.weight", name + "_k_norm.weight",
                    q, k, v, branch * frames * Width);
            }
            var attended = Attention(q, k, v, frames);
            for (var branch = 0; branch < 2; branch++)
            {
                var name = "double_blocks." + index + (branch == 0 ? ".motion" : ".text");
                var projected = Linear(attended.Skip(branch * frames * Width).Take(frames * Width).ToArray(), name + "_out_proj");
                streams[branch] = AddGate(streams[branch], projected, gates[branch], 2);
                var normalized = Modulate(Normalize(streams[branch], Width, false, 1e-6), gates[branch], 3, 4);
                projected = Linear(Linear(normalized, name + "_mlp.fc1").Select(Gelu).ToArray(), name + "_mlp.fc2");
                streams[branch] = AddGate(streams[branch], projected, gates[branch], 5);
            }
        }
        var features = streams[0].Concat(streams[1]).ToArray();
        for (var index = 0; index < FlowDenoiser.SingleBlocks; index++)
        {
            var name = "single_blocks." + index;
            var gates = Linear(adapter.Select(Silu).ToArray(), name + ".modulation.linear");
            var modulated = Modulate(Normalize(features, Width, false, 1e-6), gates, 0, 1);
            var packed = Linear(modulated, name + ".linear1");
            var q = new double[features.Length]; var k = new double[q.Length]; var v = new double[q.Length];
            SplitQkv(weights, packed, 2 * frames, 7 * Width, name + ".q_norm.weight", name + ".k_norm.weight", q, k, v, 0);
            var attended = Attention(q, k, v, frames);
            var joined = new double[2 * frames * 5 * Width];
            for (var row = 0; row < 2 * frames; row++)
            {
                Array.Copy(attended, row * Width, joined, row * 5 * Width, Width);
                for (var c = 0; c < 4 * Width; c++) joined[row * 5 * Width + Width + c] = Gelu(packed[row * 7 * Width + 3 * Width + c]);
            }
            features = AddGate(features, Linear(joined, name + ".linear2"), gates, 2);
        }
        var finalGates = Linear(adapter.Select(Silu).ToArray(), "final_layer.adaLN_modulation.linear");
        var final = Modulate(Normalize(features.Take(frames * Width).ToArray(), Width, false, 1e-5), finalGates, 0, 1);
        return Linear(final, "final_layer.linear");
    }

    static void SplitQkv(Dictionary<string, Tensor> weights, double[] packed, int rows, int stride, string qName, string kName,
        double[] query, double[] key, double[] value, int destination)
    {
        var q = new double[rows * Width]; var k = new double[q.Length];
        for (var row = 0; row < rows; row++)
            for (var c = 0; c < Width; c++)
            { q[row * Width + c] = packed[row * stride + c]; k[row * Width + c] = packed[row * stride + Width + c]; value[destination + row * Width + c] = packed[row * stride + 2 * Width + c]; }
        q = Normalize(q, HeadWidth, true, 1e-6); k = Normalize(k, HeadWidth, true, 1e-6);
        for (var i = 0; i < q.Length; i++)
        { query[destination + i] = q[i] * weights[qName].Data[i % HeadWidth]; key[destination + i] = k[i] * weights[kName].Data[i % HeadWidth]; }
    }

    static double[] Attention(double[] q, double[] k, double[] v, int frames)
    {
        var tokens = frames * 2;
        foreach (var values in new[] { q, k })
            for (var token = 0; token < tokens; token++)
                for (var c = 0; c < Width; c += 2)
                {
                    var angle = (token % frames) * Math.Pow(10000, -(double)(c % HeadWidth) / HeadWidth);
                    var at = token * Width + c;
                    var rotated = new System.Numerics.Complex(values[at], values[at + 1]) * System.Numerics.Complex.FromPolarCoordinates(1, angle);
                    values[at] = rotated.Real; values[at + 1] = rotated.Imaginary;
                }
        var result = new double[q.Length];
        for (var row = 0; row < tokens; row++)
            for (var head = 0; head < Heads; head++)
            {
                var probabilities = new double[tokens];
                for (var column = 0; column < tokens; column++)
                {
                    var allowed = row < frames && column < frames && Math.Abs(row - column) <= 60
                        || column >= frames && Math.Abs(row % frames - column % frames) <= 3;
                    if (!allowed) continue;
                    double dot = 0;
                    for (var c = 0; c < HeadWidth; c++) dot += q[row * Width + head * HeadWidth + c] * k[column * Width + head * HeadWidth + c];
                    probabilities[column] = Math.Exp(dot / Math.Sqrt(HeadWidth));
                }
                var sum = probabilities.Sum();
                for (var c = 0; c < HeadWidth; c++)
                    for (var column = 0; column < tokens; column++) result[row * Width + head * HeadWidth + c] += probabilities[column] / sum * v[column * Width + head * HeadWidth + c];
            }
        return result;
    }

    static double[] Normalize(double[] x, int width, bool rms, double epsilon)
    {
        var result = new double[x.Length];
        for (var row = 0; row < x.Length / width; row++)
        {
            var values = x.Skip(row * width).Take(width).ToArray(); var mean = rms ? 0 : values.Average();
            var inverse = 1 / Math.Sqrt(values.Average(v => (v - mean) * (v - mean)) + epsilon);
            for (var c = 0; c < width; c++) result[row * width + c] = (values[c] - mean) * inverse;
        }
        return result;
    }

    static double Silu(double x) => x / (1 + Math.Exp(-x));
    static double Gelu(double x) => .5 * x * (1 + Math.Tanh(Math.Sqrt(2 / Math.PI) * (x + .044715 * x * x * x)));
    static double[] Add(double[] x, double[] y) => x.Zip(y, (a, b) => a + b).ToArray();
    static double[] AddGate(double[] x, double[] delta, double[] gates, int group)
        => x.Select((value, i) => value + delta[i] * gates[group * Width + i % Width]).ToArray();
    static double[] Modulate(double[] x, double[] gates, int shift, int scale)
        => x.Select((value, i) => value * (1 + gates[scale * Width + i % Width]) + gates[shift * Width + i % Width]).ToArray();
}