Document GPU kernel audit progress
This commit is contained in:
1 parent
1e25ea0ccf
commit
6217ea7888
31 files changed
+3496
-3246
No files matched your search
@@ -169,7 +169,7 @@ public sealed class PrimeTester(bool useInternal = false)
|
||||
{
|
||||
_accel = accelerator;
|
||||
// Compile once per accelerator and upload primes once.
|
||||
Kernel = accelerator.LoadAutoGroupedStreamKernel<Index1D, ArrayView<ulong>, ArrayView<uint>, ArrayView<byte>>(SmallPrimeSieveKernel);
|
||||
Kernel = accelerator.LoadAutoGroupedStreamKernel<Index1D, ArrayView<ulong>, ArrayView<uint>, ArrayView<byte>>(PrimeTesterKernels.SmallPrimeSieveKernel);
|
||||
|
||||
var primes = PrimesGenerator.SmallPrimes;
|
||||
DevicePrimes = accelerator.Allocate1D<uint>(primes.Length);
|
||||
@@ -266,56 +266,6 @@ public sealed class PrimeTester(bool useInternal = false)
|
||||
GpuKernelState.Clear(accelerator);
|
||||
}
|
||||
|
||||
// GPU kernel: small-prime sieve only. Returns 1 if passes sieve (probable prime), 0 otherwise.
|
||||
private static void SmallPrimeSieveKernel(Index1D index, ArrayView<ulong> numbers, ArrayView<uint> smallPrimes, ArrayView<byte> results)
|
||||
{
|
||||
ulong n = numbers[index];
|
||||
if (n <= 3UL)
|
||||
{
|
||||
results[index] = (byte)(n >= 2UL ? 1 : 0);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((n & 1UL) == 0UL || (n > 5UL && (n % 5UL) == 0UL))
|
||||
{
|
||||
// TODO: Replace the `% 5` branch with the GPU Mod5 helper once the sieve kernel can
|
||||
// reuse the benchmarked bitmask reduction instead of modulo on every candidate.
|
||||
results[index] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (n.Mod10() == 1UL)
|
||||
{
|
||||
// Early reject special GCD heuristic with floor(log2 n)
|
||||
ulong m = 63UL - (ulong)ILGPU.Algorithms.XMath.LeadingZeroCount(n);
|
||||
if (BinaryGcdGpu(n, m) != 1UL)
|
||||
{
|
||||
results[index] = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
long len = smallPrimes.Length;
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
ulong p = smallPrimes[i];
|
||||
if (p * p > n)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if ((n % p) == 0UL)
|
||||
{
|
||||
// TODO: Route this modulo through the shared divisor-cycle cache once exposed to GPU kernels
|
||||
// so batched sieves avoid per-prime `%` operations that profiling showed expensive.
|
||||
results[index] = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
results[index] = 1;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
internal static bool SharesFactorWithMaxExponent(ulong n)
|
||||
{
|
||||
@@ -333,7 +283,7 @@ public sealed class PrimeTester(bool useInternal = false)
|
||||
// and divisor-cycle staging instead of allocating new device buffers per call.
|
||||
var gpu = GpuContextPool.Rent();
|
||||
var accelerator = gpu.Accelerator;
|
||||
var kernel = accelerator.LoadAutoGroupedStreamKernel<Index1D, ArrayView<ulong>, ArrayView<byte>>(SharesFactorKernel);
|
||||
var kernel = accelerator.LoadAutoGroupedStreamKernel<Index1D, ArrayView<ulong>, ArrayView<byte>>(PrimeTesterKernels.SharesFactorKernel);
|
||||
|
||||
int length = values.Length;
|
||||
var inputBuffer = accelerator.Allocate1D<ulong>(length);
|
||||
@@ -384,45 +334,5 @@ public sealed class PrimeTester(bool useInternal = false)
|
||||
|
||||
return u << shift;
|
||||
}
|
||||
|
||||
private static void SharesFactorKernel(Index1D index, ArrayView<ulong> numbers, ArrayView<byte> results)
|
||||
{
|
||||
ulong n = numbers[index];
|
||||
ulong m = 63UL - (ulong)XMath.LeadingZeroCount(n);
|
||||
ulong gcd = BinaryGcdGpu(n, m);
|
||||
results[index] = gcd == 1UL ? (byte)0 : (byte)1;
|
||||
}
|
||||
|
||||
private static ulong BinaryGcdGpu(ulong u, ulong v)
|
||||
{
|
||||
// TODO: Replace this inline GPU binary GCD with the kernel extracted from
|
||||
// GpuUInt128BinaryGcdBenchmarks via GpuKernelPool so device callers reuse the
|
||||
// fully unrolled ladder instead of this branchy fallback.
|
||||
if (u == 0UL)
|
||||
{
|
||||
return v;
|
||||
}
|
||||
|
||||
if (v == 0UL)
|
||||
{
|
||||
return u;
|
||||
}
|
||||
|
||||
int shift = XMath.TrailingZeroCount(u | v);
|
||||
u >>= XMath.TrailingZeroCount(u);
|
||||
|
||||
do
|
||||
{
|
||||
v >>= XMath.TrailingZeroCount(v);
|
||||
if (u > v)
|
||||
{
|
||||
(u, v) = (v, u);
|
||||
}
|
||||
|
||||
v -= u;
|
||||
}
|
||||
while (v != 0UL);
|
||||
|
||||
return u << shift;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user