Handle zero-cycle GPU divisor sessions with heuristics

This commit is contained in:
Marek Lemańczyk committed 2025-10-24 06:40:33 +02:00
1 parent cf9d143ca2
commit fbd6235316
2 files changed
+34 -7

No files matched your search

@@ -142,6 +142,22 @@ public class MersenneNumberDivisorGpuTesterTests
divisorsExhausted.Should().BeTrue();
}
[Fact]
[Trait("Category", "Fast")]
public void ByDivisor_session_computes_cycle_when_zero_is_provided()
{
var tester = new MersenneNumberDivisorByDivisorGpuTester();
tester.ConfigureFromMaxPrime(43UL);
using var session = tester.CreateDivisorSession();
ulong[] primes = { 31UL, 37UL, 41UL };
byte[] hits = new byte[primes.Length];
session.CheckDivisor(223UL, MontgomeryDivisorData.FromModulus(223UL), 0UL, primes, hits);
hits.Should().ContainInOrder(new byte[] { 0, 1, 0 });
}
[Fact]
[Trait("Category", "Fast")]
public void ByDivisor_session_checks_divisors_across_primes()
@@ -471,15 +471,26 @@ public sealed class MersenneNumberDivisorByDivisorGpuTester : IMersenneNumberDiv
}
ulong cycle = divisorCycle;
// EvenPerfectBitScanner resolves divisor cycles before scheduling GPU work, so the zero-cycle fallback stays disabled.
// if (cycle == 0UL)
// {
// throw new InvalidOperationException("GPU divisor cycle length must be non-zero.");
// }
ulong firstPrime = primes[0];
if (cycle == 0UL)
{
if (!MersenneDivisorCycles.TryCalculateCycleLengthForExponent(divisor, firstPrime, cachedData, out ulong computedCycle, out bool primeOrderFailed) || computedCycle == 0UL)
{
cycle = MersenneDivisorCycles.CalculateCycleLength(divisor, cachedData, skipPrimeOrderHeuristic: primeOrderFailed);
}
else
{
cycle = computedCycle;
}
if (cycle == 0UL)
{
throw new InvalidOperationException("GPU divisor cycle length must be non-zero.");
}
}
// Precompute the initial cycle remainder on the host to keep the GPU kernel branch-free.
// EvenPerfectBitScanner resolves divisor cycles before scheduling GPU work, so cycle never equals zero here.
ulong firstRemainder = firstPrime % cycle;
Monitor.Enter(_lease.ExecutionLock);