Allow test mode to seed by-divisor runs

This commit is contained in:
Marek Lemańczyk committed 2025-10-16 03:42:55 +02:00
1 parent 03751c27be
commit ff724732f8
1 file changed
+76 -16
+76 -16
View File
@@ -407,18 +407,17 @@ internal static class Program
}
}
int testPrimeCandidateLimit = 0;
if (_testMode)
{
currentP = 31UL;
remainder = currentP % 6UL;
useDivisor = false;
useByDivisor = false;
useResidue = false;
useLucas = false;
filterFile = string.Empty;
maxPrimeLimit = UInt128.MaxValue;
maxPrimeConfigured = false;
startPrimeProvided = true;
testPrimeCandidateLimit = Math.Max(1, threadCount) * 3;
}
if (useByDivisor)
@@ -430,7 +429,7 @@ internal static class Program
_byDivisorStartPrime = 0UL;
}
if (useByDivisor && string.IsNullOrEmpty(filterFile))
if (useByDivisor && !_testMode && string.IsNullOrEmpty(filterFile))
{
Console.WriteLine("--mersenne=bydivisor requires --filter-p=<path>.");
return;
@@ -654,11 +653,16 @@ internal static class Program
ulong maxP = 0UL;
ulong[] localFilter = Array.Empty<ulong>();
int filterCount = 0;
if (useFilter)
{
Console.WriteLine("Loading filter...");
if (_useByDivisorMode)
{
if (_testMode)
{
byDivisorCandidates = BuildTestPrimeCandidates(testPrimeCandidateLimit);
}
else
{
Console.WriteLine("Loading filter...");
int skippedByLimit = 0;
byDivisorCandidates = LoadByDivisorCandidates(filterFile, maxPrimeLimit, maxPrimeConfigured, out skippedByLimit);
if (maxPrimeConfigured)
@@ -675,8 +679,10 @@ internal static class Program
}
}
}
else
}
else if (useFilter)
{
Console.WriteLine("Loading filter...");
// TODO: Rent this filter buffer from ArrayPool<ulong> and reuse it across reload batches so
// we do not allocate fresh arrays while replaying large result filters.
localFilter = new ulong[1024];
@@ -730,6 +736,11 @@ internal static class Program
}
}
}
if (_testMode)
{
_testTargetPrimeCount = testPrimeCandidateLimit;
}
if (_primeCount >= 2)
@@ -744,6 +755,12 @@ internal static class Program
// Configure batch size for GPU primality sieve
PrimeTester.GpuBatchSize = gpuPrimeBatch;
Stopwatch? stopwatch = null;
if (_testMode)
{
stopwatch = Stopwatch.StartNew();
}
Console.WriteLine("Starting scan...");
if (_useByDivisorMode)
@@ -751,6 +768,12 @@ internal static class Program
RunByDivisorMode(byDivisorCandidates, threadCount);
FlushBuffer();
StringBuilderPool.Return(_outputBuilder!);
if (stopwatch is not null)
{
stopwatch.Stop();
ReportTestTime(stopwatch.Elapsed);
}
return;
}
@@ -767,17 +790,12 @@ internal static class Program
if (_testMode)
{
_testTargetPrimeCount = Math.Max(1, threadCount) * 3;
testPrimeCandidateLimit = Math.Max(1, threadCount) * 3;
_testTargetPrimeCount = testPrimeCandidateLimit;
}
_state = ((long)currentP << 3) | (long)remainder;
Stopwatch? stopwatch = null;
if (_testMode)
{
stopwatch = Stopwatch.StartNew();
}
Task[] tasks = new Task[threadCount];
int taskIndex = 0;
@@ -866,6 +884,48 @@ internal static class Program
}
}
private static List<ulong> BuildTestPrimeCandidates(int targetCount)
{
if (targetCount <= 0)
{
return [];
}
List<ulong> candidates = new(targetCount);
ulong previous = 29UL;
int remaining = targetCount;
ulong nextPrime = 0UL;
while (remaining > 0)
{
try
{
nextPrime = PrimeIterator.Next(in previous);
}
catch (InvalidOperationException)
{
break;
}
if (nextPrime < 31UL)
{
previous = nextPrime;
continue;
}
candidates.Add(nextPrime);
remaining--;
previous = nextPrime;
}
if (remaining > 0)
{
Console.WriteLine("Unable to populate the requested number of test primes before reaching the 64-bit limit.");
}
return candidates;
}
private static List<ulong> LoadByDivisorCandidates(string candidateFile, UInt128 maxPrimeLimit, bool maxPrimeConfigured, out int skippedByLimit)
{
List<ulong> candidates = [];