yum/vfft

git clone https://git.yummers.dev/yum/vfft

yumImplement fft v3 using groupshared memoryaedb649

master
1.9 KiB69 linesraw
1import lib.util;
2
3[[vk::binding(0, 0)]]
4RWStructuredBuffer<float2> input;
5
6[[vk::binding(1, 0)]]
7RWStructuredBuffer<float2> output;
8
9[[vk::binding(2, 0)]]
10StructuredBuffer<float2> twiddles;
11
12[[vk::binding(3, 0)]]
13cbuffer Uniforms {
14  uint input_len;
15  uint n_iter;
16};
17
18void fft_v2_stage(uint which_fft, uint id, uint stride, uint big_n, RWStructuredBuffer<float2> in, RWStructuredBuffer<float2> out) {
19    const uint k = id / stride;
20    const uint start_idx = which_fft * Uniforms.input_len + id % stride;
21
22    // Collect inputs.
23    let i0 = in[start_idx + 4 * k * stride];
24    let i1 = in[start_idx + (4 * k + 1) * stride];
25    let i2 = in[start_idx + (4 * k + 2) * stride];
26    let i3 = in[start_idx + (4 * k + 3) * stride];
27    // Collect relevant twiddles.
28    let ot1 = twiddles[1 * k * stride];
29    let ot2 = twiddles[2 * k * stride];
30    let ot3 = twiddles[3 * k * stride];
31
32    let a = i0;
33    let b = cmul(ot1, i1);
34    let c = cmul(ot2, i2);
35    let d = cmul(ot3, i3);
36
37    // To derive this, write the output assignments in terms of
38    // a/b/c/d, then factor out!
39    let ac_sum = a + c;
40    let ac_diff = a - c;
41    let bd_sum = b + d;
42    let bd_diff_ni = mul_ni(b - d);
43
44    out[start_idx + k * stride] = ac_sum + bd_sum;
45    out[start_idx + (k + big_n / 4) * stride] = ac_diff + bd_diff_ni;
46    out[start_idx + (k + big_n / 2) * stride] = ac_sum - bd_sum;
47    out[start_idx + (k + 3 * big_n / 4) * stride] = ac_diff - bd_diff_ni;
48}
49
50[shader("compute")]
51[numthreads(64, 16, 1)]
52void fft_v2_barrier(uint3 globalId : SV_DispatchThreadID, uint id: SV_GroupIndex)
53{
54    const uint which_fft = globalId.z;
55
56    uint stride = Uniforms.input_len;
57    uint big_n = 1;
58
59    for (uint i = 0; i < Uniforms.n_iter; i++) {
60      stride /= 4;
61      big_n *= 4;
62      if (i % 2 == 0) {
63        fft_v2_stage(which_fft, id, stride, big_n, input, output);
64      } else {
65        fft_v2_stage(which_fft, id, stride, big_n, output, input);
66      }
67      AllMemoryBarrierWithGroupSync();
68    }
69}