Revert "Merge pull request #251 from mlemanczyk/codex/refactor-prime-checking-on-gpu-n5t2pm"

This reverts commit 936ce239db, reversing
changes made to e14b77e504.
This commit is contained in:
mlemanczyk committed 2025-11-02 11:22:14 +01:00
1 parent 936ce239db
commit 2281d9535e
23 files changed
+880 -1187

No files matched your search

@@ -1,7 +1,6 @@
using Open.Numeric.Primes;
using System;
using ILGPU.Runtime;
using System.Runtime.CompilerServices;
using ILGPU.Runtime;
using PerfectNumbers.Core.Gpu;
namespace PerfectNumbers.Core;
@@ -41,48 +40,32 @@ public sealed class HeuristicCombinedPrimeTester
CombinedDivisorsEnding9Squares = CombinedDivisorsEnding9OneAOneBSquares;
}
public static void EnsureInitialized()
{
// Intentionally left blank. Accessing this method forces the static constructor to run.
}
internal static ReadOnlySpan<ulong> CombinedDivisorsEnding1Span => CombinedDivisorsEnding1;
internal static ReadOnlySpan<ulong> CombinedDivisorsEnding3Span => CombinedDivisorsEnding3;
internal static ReadOnlySpan<ulong> CombinedDivisorsEnding7Span => CombinedDivisorsEnding7;
internal static ReadOnlySpan<ulong> CombinedDivisorsEnding9Span => CombinedDivisorsEnding9;
internal static ReadOnlySpan<ulong> CombinedDivisorsEnding1SquaresSpan => CombinedDivisorsEnding1Squares;
internal static ReadOnlySpan<ulong> CombinedDivisorsEnding3SquaresSpan => CombinedDivisorsEnding3Squares;
internal static ReadOnlySpan<ulong> CombinedDivisorsEnding7SquaresSpan => CombinedDivisorsEnding7Squares;
internal static ReadOnlySpan<ulong> CombinedDivisorsEnding9SquaresSpan => CombinedDivisorsEnding9Squares;
private const ulong Wheel210 = 210UL;
private static readonly ulong[] CombinedDivisorsEnding1TwoAOneB;
private static readonly ulong[] CombinedDivisorsEnding3TwoAOneB;
private static readonly ulong[] CombinedDivisorsEnding7TwoAOneB;
private static readonly ulong[] CombinedDivisorsEnding9TwoAOneB;
private static readonly uint[] CombinedDivisorsEnding1TwoAOneB;
private static readonly uint[] CombinedDivisorsEnding3TwoAOneB;
private static readonly uint[] CombinedDivisorsEnding7TwoAOneB;
private static readonly uint[] CombinedDivisorsEnding9TwoAOneB;
private static readonly ulong[] CombinedDivisorsEnding1OneAOneB;
private static readonly ulong[] CombinedDivisorsEnding3OneAOneB;
private static readonly ulong[] CombinedDivisorsEnding7OneAOneB;
private static readonly ulong[] CombinedDivisorsEnding9OneAOneB;
private static readonly uint[] CombinedDivisorsEnding1OneAOneB;
private static readonly uint[] CombinedDivisorsEnding3OneAOneB;
private static readonly uint[] CombinedDivisorsEnding7OneAOneB;
private static readonly uint[] CombinedDivisorsEnding9OneAOneB;
private static readonly ulong[] CombinedDivisorsEnding1ThreeAOneB;
private static readonly ulong[] CombinedDivisorsEnding3ThreeAOneB;
private static readonly ulong[] CombinedDivisorsEnding7ThreeAOneB;
private static readonly ulong[] CombinedDivisorsEnding9ThreeAOneB;
private static readonly uint[] CombinedDivisorsEnding1ThreeAOneB;
private static readonly uint[] CombinedDivisorsEnding3ThreeAOneB;
private static readonly uint[] CombinedDivisorsEnding7ThreeAOneB;
private static readonly uint[] CombinedDivisorsEnding9ThreeAOneB;
private static readonly ulong[] CombinedDivisorsEnding1ThreeATwoB;
private static readonly ulong[] CombinedDivisorsEnding3ThreeATwoB;
private static readonly ulong[] CombinedDivisorsEnding7ThreeATwoB;
private static readonly ulong[] CombinedDivisorsEnding9ThreeATwoB;
private static readonly uint[] CombinedDivisorsEnding1ThreeATwoB;
private static readonly uint[] CombinedDivisorsEnding3ThreeATwoB;
private static readonly uint[] CombinedDivisorsEnding7ThreeATwoB;
private static readonly uint[] CombinedDivisorsEnding9ThreeATwoB;
private static readonly ulong[] CombinedDivisorsEnding1;
private static readonly ulong[] CombinedDivisorsEnding3;
private static readonly ulong[] CombinedDivisorsEnding7;
private static readonly ulong[] CombinedDivisorsEnding9;
private static readonly uint[] CombinedDivisorsEnding1;
private static readonly uint[] CombinedDivisorsEnding3;
private static readonly uint[] CombinedDivisorsEnding7;
private static readonly uint[] CombinedDivisorsEnding9;
private static readonly ulong[] CombinedDivisorsEnding1TwoAOneBSquares;
private static readonly ulong[] CombinedDivisorsEnding3TwoAOneBSquares;
@@ -190,7 +173,7 @@ public sealed class HeuristicCombinedPrimeTester
private static bool HeuristicTrialDivisionCpu(ulong n, ulong maxDivisorSquare, byte nMod10)
{
ReadOnlySpan<ulong> combinedDivisors = GetCombinedDivisors(nMod10);
ReadOnlySpan<uint> combinedDivisors = GetCombinedDivisors(nMod10);
ReadOnlySpan<ulong> combinedDivisorSquares = GetCombinedDivisorSquares(nMod10);
int length = combinedDivisors.Length;
@@ -222,40 +205,78 @@ public sealed class HeuristicCombinedPrimeTester
_ => 256,
};
private static bool HeuristicTrialDivisionGpuDetectsDivisor(ulong n, ulong maxDivisorSquare, byte nMod10)
{
var limiter = GpuPrimeWorkLimiter.Acquire();
var gpu = PrimeTester.PrimeTesterGpuContextPool.Rent(1);
var accelerator = gpu.Accelerator;
var kernel = gpu.HeuristicTrialDivisionKernel;
var flagView1D = gpu.HeuristicFlag.View;
var flagView = flagView1D.AsContiguous();
bool compositeDetected = false;
int divisorLength = GetCombinedDivisors(nMod10).Length;
int compositeFlag = 0;
flagView1D.CopyFromCPU(ref compositeFlag, 1);
kernel(
divisorLength,
flagView,
n,
maxDivisorSquare,
HeuristicGpuDivisorTableKind.Combined,
gpu.HeuristicGpuTables);
accelerator.Synchronize();
flagView1D.CopyToCPU(ref compositeFlag, 1);
compositeDetected = compositeFlag != 0;
gpu.Dispose();
limiter.Dispose();
return compositeDetected;
}
private static bool HeuristicTrialDivisionGpuDetectsDivisor(ulong n, ulong maxDivisorSquare, byte nMod10)
{
int batchCapacity = GetBatchSize(n);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static bool EvaluateWithOpenNumericFallback(ulong n)
var limiter = GpuPrimeWorkLimiter.Acquire();
var gpu = PrimeTester.PrimeTesterGpuContextPool.Rent(batchCapacity);
var accelerator = gpu.Accelerator;
var kernel = gpu.HeuristicTrialDivisionKernel;
bool compositeDetected = false;
int count = 0;
var inputView = gpu.Input.View;
var flagView = gpu.HeuristicFlag.View;
ulong[] divisorArray = gpu.DivisorArray;
bool ProcessBatch(int length)
{
inputView.CopyFromCPU(ref divisorArray[0], length);
int compositeFlag = 0;
flagView.CopyFromCPU(ref compositeFlag, 1);
kernel(length, inputView, n, flagView);
accelerator.Synchronize();
flagView.CopyToCPU(ref compositeFlag, 1);
return compositeFlag != 0;
}
ReadOnlySpan<uint> combinedDivisors = GetCombinedDivisors(nMod10);
ReadOnlySpan<ulong> combinedDivisorSquares = GetCombinedDivisorSquares(nMod10);
int length = combinedDivisors.Length;
for (int i = 0; i < length; i++)
{
ulong divisorSquare = combinedDivisorSquares[i];
if (divisorSquare > maxDivisorSquare)
{
break;
}
divisorArray[count] = combinedDivisors[i];
count++;
if (count == batchCapacity)
{
if (ProcessBatch(count))
{
compositeDetected = true;
goto Cleanup;
}
count = 0;
}
}
if (count > 0 && ProcessBatch(count))
{
compositeDetected = true;
goto Cleanup;
}
Cleanup:
gpu.Dispose();
limiter.Dispose();
return compositeDetected;
}
private static bool EvaluateWithOpenNumericFallback(ulong n)
{
return Prime.Numbers.IsPrime(n);
}
@@ -264,7 +285,7 @@ public sealed class HeuristicCombinedPrimeTester
return n;
}
private static ReadOnlySpan<ulong> GetCombinedDivisors(byte nMod10)
private static ReadOnlySpan<uint> GetCombinedDivisors(byte nMod10)
{
return nMod10 switch
{
@@ -288,7 +309,7 @@ public sealed class HeuristicCombinedPrimeTester
};
}
internal static ReadOnlySpan<ulong> GetCombinedDivisors(byte nMod10, CombinedDivisorPattern pattern)
internal static ReadOnlySpan<uint> GetCombinedDivisors(byte nMod10, CombinedDivisorPattern pattern)
{
return pattern switch
{
@@ -368,17 +389,17 @@ public sealed class HeuristicCombinedPrimeTester
};
}
private static ulong[] BuildCombinedDivisors(byte nMod10, CombinedDivisorPattern pattern, out ulong[] squares)
private static uint[] BuildCombinedDivisors(byte nMod10, CombinedDivisorPattern pattern, out ulong[] squares)
{
ReadOnlySpan<ulong> groupA = HeuristicPrimeSieves.GroupADivisors;
ReadOnlySpan<int> groupA = HeuristicPrimeSieves.GroupADivisors;
ReadOnlySpan<uint> groupB = GetGroupBDivisors(nMod10);
var combined = new List<ulong>(groupA.Length + groupB.Length);
var combined = new List<uint>(groupA.Length + groupB.Length);
int groupAIndex = 0;
while (groupAIndex < groupA.Length && groupA[groupAIndex] <= 19)
{
combined.Add(groupA[groupAIndex]);
combined.Add((uint)groupA[groupAIndex]);
groupAIndex++;
}
@@ -414,7 +435,7 @@ public sealed class HeuristicCombinedPrimeTester
int addedA = 0;
while (addedA < groupAInterleaveCount && groupAIndex < groupA.Length)
{
combined.Add(groupA[groupAIndex]);
combined.Add((uint)groupA[groupAIndex]);
groupAIndex++;
addedA++;
}
@@ -428,7 +449,7 @@ public sealed class HeuristicCombinedPrimeTester
}
}
ulong[] result = [.. combined];
uint[] result = [.. combined];
ulong[] resultSquares = new ulong[result.Length];
for (int i = 0; i < result.Length; i++)
{
@@ -453,12 +474,12 @@ public sealed class HeuristicCombinedPrimeTester
return index;
}
private static bool IsGroupAPrefixValue(ulong value) => value is 3UL or 7UL or 11UL or 13UL;
private static bool IsGroupAPrefixValue(uint value) => value is 3U or 7U or 11U or 13U;
private static HeuristicDivisorGroup ResolveGroup(ulong value) => value switch
private static HeuristicDivisorGroup ResolveGroup(uint value) => value switch
{
3UL or 7UL or 11UL or 13UL => HeuristicDivisorGroup.GroupAConstant,
_ when value % 10UL == 3UL => HeuristicDivisorGroup.GroupAWheel,
3U or 7U or 11U or 13U => HeuristicDivisorGroup.GroupAConstant,
_ when value % 10U == 3U => HeuristicDivisorGroup.GroupAWheel,
_ => HeuristicDivisorGroup.GroupB,
};
@@ -557,7 +578,7 @@ public sealed class HeuristicCombinedPrimeTester
internal ref struct HeuristicDivisorEnumerator
{
private readonly ulong maxDivisorSquare;
private readonly ReadOnlySpan<ulong> combinedDivisors;
private readonly ReadOnlySpan<uint> combinedDivisors;
private readonly ReadOnlySpan<ulong> combinedDivisorSquares;
private int index;
@@ -582,7 +603,7 @@ public sealed class HeuristicCombinedPrimeTester
break;
}
ulong entry = combinedDivisors[currentIndex];
uint entry = combinedDivisors[currentIndex];
index = currentIndex + 1;
HeuristicDivisorGroup group = ResolveGroup(entry);