Consolidate multiply helpers and guard GPU fallbacks

This commit is contained in:
Marek Lemańczyk committed 2025-10-04 21:20:29 +02:00
1 parent 84ebbed98b
commit 6adac6b7a7
10 files changed
+227 -70

No files matched your search

@@ -1,5 +1,7 @@
using System;
using System.Collections.Concurrent;
using System.Numerics;
using System.Threading;
namespace PerfectNumbers.Core.Gpu;
@@ -13,6 +15,22 @@ internal enum GpuPow2ModStatus
internal static class PrimeOrderGpuHeuristics
{
private static readonly ConcurrentDictionary<ulong, byte> OverflowedPrimes = new();
private static int s_modulusBitLimit = PrimeOrderGpuCapability.Default.ModulusBits;
private static int s_exponentBitLimit = PrimeOrderGpuCapability.Default.ExponentBits;
internal static void OverrideCapabilitiesForTesting(PrimeOrderGpuCapability capability)
{
Volatile.Write(ref s_modulusBitLimit, capability.ModulusBits);
Volatile.Write(ref s_exponentBitLimit, capability.ExponentBits);
}
internal static void ResetCapabilitiesForTesting()
{
OverrideCapabilitiesForTesting(PrimeOrderGpuCapability.Default);
}
private static PrimeOrderGpuCapability Capabilities
=> new(Volatile.Read(ref s_modulusBitLimit), Volatile.Read(ref s_exponentBitLimit));
internal static void MarkOverflow(ulong prime) => OverflowedPrimes[prime] = 0;
@@ -33,6 +51,19 @@ internal static class PrimeOrderGpuHeuristics
return GpuPow2ModStatus.Overflow;
}
PrimeOrderGpuCapability capability = Capabilities;
if (!SupportsPrime(prime, capability))
{
MarkOverflow(prime);
return GpuPow2ModStatus.Overflow;
}
if (!SupportsExponent(exponent, capability))
{
return GpuPow2ModStatus.Overflow;
}
// TODO: Implement the GPU heuristic order calculator so this path mirrors PrimeOrderCalculator before enabling device execution.
return GpuPow2ModStatus.Unavailable;
}
@@ -61,7 +92,49 @@ internal static class PrimeOrderGpuHeuristics
return GpuPow2ModStatus.Overflow;
}
PrimeOrderGpuCapability capability = Capabilities;
if (!SupportsPrime(prime, capability))
{
MarkOverflow(prime);
return GpuPow2ModStatus.Overflow;
}
for (int i = 0; i < exponents.Length; i++)
{
if (!SupportsExponent(exponents[i], capability))
{
return GpuPow2ModStatus.Overflow;
}
}
// TODO: Implement the GPU heuristic order calculator so this path mirrors PrimeOrderCalculator before enabling device execution.
return GpuPow2ModStatus.Unavailable;
}
}
private static bool SupportsPrime(ulong prime, PrimeOrderGpuCapability capability)
{
return GetBitLength(prime) <= capability.ModulusBits;
}
private static bool SupportsExponent(ulong exponent, PrimeOrderGpuCapability capability)
{
return GetBitLength(exponent) <= capability.ExponentBits;
}
private static int GetBitLength(ulong value)
{
if (value == 0UL)
{
return 0;
}
return 64 - BitOperations.LeadingZeroCount(value);
}
internal readonly record struct PrimeOrderGpuCapability(int ModulusBits, int ExponentBits)
{
public static PrimeOrderGpuCapability Default => new(128, 64);
}
}