Handle zero-cycle GPU divisor sessions with heuristics
This commit is contained in:
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();
|
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]
|
[Fact]
|
||||||
[Trait("Category", "Fast")]
|
[Trait("Category", "Fast")]
|
||||||
public void ByDivisor_session_checks_divisors_across_primes()
|
public void ByDivisor_session_checks_divisors_across_primes()
|
||||||
|
|||||||
@@ -471,15 +471,26 @@ public sealed class MersenneNumberDivisorByDivisorGpuTester : IMersenneNumberDiv
|
|||||||
}
|
}
|
||||||
|
|
||||||
ulong cycle = divisorCycle;
|
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];
|
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.
|
// 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;
|
ulong firstRemainder = firstPrime % cycle;
|
||||||
|
|
||||||
Monitor.Enter(_lease.ExecutionLock);
|
Monitor.Enter(_lease.ExecutionLock);
|
||||||
|
|||||||
Reference in new issue
Block a user