Document GPU kernel audit progress

This commit is contained in:
Marek Lemańczyk committed 2025-10-18 17:42:33 +02:00
1 parent 1e25ea0ccf
commit 6217ea7888
31 files changed
+3496 -3246

No files matched your search

@@ -0,0 +1,69 @@
using ILGPU;
namespace PerfectNumbers.Core.Gpu;
internal static class NttTransformKernels
{
public static void ForwardKernel(Index1D index, ArrayView<GpuUInt128> input, ArrayView<GpuUInt128> output, int length, GpuUInt128 modulus, GpuUInt128 root)
{
// TODO(NTT-OPT): Replace this reference O(n^2) kernel with a stage-wise
// Cooley–Tukey butterfly kernel (O(n log n)). This version uses a per-
// element ModPow in the hot loop which is far too slow and causes long
// single-kernel runtimes. After twiddle precomputation, each butterfly
// should perform: (u, v) -> (u+v*w, u-v*w) with a single MulMod.
var sum = new GpuUInt128(0UL, 0UL);
for (int i = 0; i < length; i++)
{
var term = input[i];
var power = new GpuUInt128(root);
power.ModPow((ulong)index.X * (ulong)i, modulus);
term.MulMod(power, modulus);
sum.AddMod(term, modulus);
}
output[index] = sum;
}
public static void InverseKernel(Index1D index, ArrayView<GpuUInt128> input, ArrayView<GpuUInt128> output, int length, GpuUInt128 modulus, GpuUInt128 rootInv, GpuUInt128 nInv)
{
// TODO(NTT-OPT): Replace this O(n^2) inverse with stage-wise butterflies
// using precomputed inverse twiddles. Apply final scaling by nInv after
// all stages, preferably in a small dedicated kernel.
var sum = new GpuUInt128(0UL, 0UL);
for (int i = 0; i < length; i++)
{
var term = input[i];
var power = new GpuUInt128(rootInv);
power.ModPow((ulong)index.X * (ulong)i, modulus);
term.MulMod(power, modulus);
sum.AddMod(term, modulus);
}
sum.MulMod(nInv, modulus);
output[index] = sum;
}
public static void BitReverseKernel(Index1D index, ArrayView<GpuUInt128> data, int bits)
{
int i = index.X;
int j = ReverseBits(i, bits);
if (i < j)
{
var tmp = data[i];
data[i] = data[j];
data[j] = tmp;
}
}
internal static int ReverseBits(int value, int bits)
{
int result = 0;
for (int i = 0; i < bits; i++)
{
result = (result << 1) | (value & 1);
value >>= 1;
}
return result;
}
}