Restored outputting of candidates which failed some tests
This commit is contained in:
1 parent
afcc8d87f9
commit
5420523a0a
1 file changed
+127
-143
+127
-143
@@ -40,8 +40,8 @@ internal static class Program
|
|||||||
private static string? _resultsPrefix;
|
private static string? _resultsPrefix;
|
||||||
private static readonly Optimized PrimeIterator = new();
|
private static readonly Optimized PrimeIterator = new();
|
||||||
|
|
||||||
[ThreadStatic]
|
[ThreadStatic]
|
||||||
private static bool _lastCompositeP;
|
private static bool _lastCompositeP;
|
||||||
|
|
||||||
// RLE/bit-pattern filtering options
|
// RLE/bit-pattern filtering options
|
||||||
private static string? _rleBlacklistPath;
|
private static string? _rleBlacklistPath;
|
||||||
@@ -74,15 +74,15 @@ internal static class Program
|
|||||||
bool mersenneOnGpu = true; // controls Lucas/incremental/pow2mod device
|
bool mersenneOnGpu = true; // controls Lucas/incremental/pow2mod device
|
||||||
bool orderOnGpu = true; // controls order computations device
|
bool orderOnGpu = true; // controls order computations device
|
||||||
int scanBatchSize = 2_097_152, sliceSize = 32;
|
int scanBatchSize = 2_097_152, sliceSize = 32;
|
||||||
UInt128 residueKMax = 5_000_000UL;
|
UInt128 residueKMax = 5_000_000UL;
|
||||||
bool residueKMaxExplicit = false;
|
bool residueKMaxExplicit = false;
|
||||||
string filterFile = string.Empty;
|
string filterFile = string.Empty;
|
||||||
string cyclesPath = DefaultCyclesPath;
|
string cyclesPath = DefaultCyclesPath;
|
||||||
int cyclesBatchSize = 512;
|
int cyclesBatchSize = 512;
|
||||||
bool continueCyclesGeneration = false;
|
bool continueCyclesGeneration = false;
|
||||||
UInt128 divisorCyclesSearchLimit128 = PerfectNumberConstants.ExtraDivisorCycleSearchLimit;
|
UInt128 divisorCyclesSearchLimit128 = PerfectNumberConstants.ExtraDivisorCycleSearchLimit;
|
||||||
ulong divisorCyclesSearchLimit = PerfectNumberConstants.ExtraDivisorCycleSearchLimit;
|
ulong divisorCyclesSearchLimit = PerfectNumberConstants.ExtraDivisorCycleSearchLimit;
|
||||||
bool divisorCyclesLimitExplicit = false;
|
bool divisorCyclesLimitExplicit = false;
|
||||||
|
|
||||||
// NTT backend selection (GPU): reference vs staged
|
// NTT backend selection (GPU): reference vs staged
|
||||||
for (int i = 0; i < args.Length; i++)
|
for (int i = 0; i < args.Length; i++)
|
||||||
@@ -144,25 +144,25 @@ internal static class Program
|
|||||||
int eq = arg.IndexOf('=');
|
int eq = arg.IndexOf('=');
|
||||||
divisor = UInt128.Parse(arg.AsSpan(eq + 1));
|
divisor = UInt128.Parse(arg.AsSpan(eq + 1));
|
||||||
}
|
}
|
||||||
else if (arg.StartsWith("--divisor-cycles-limit=", StringComparison.OrdinalIgnoreCase))
|
else if (arg.StartsWith("--divisor-cycles-limit=", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
int eq = arg.IndexOf('=');
|
int eq = arg.IndexOf('=');
|
||||||
if (UInt128.TryParse(arg.AsSpan(eq + 1), NumberStyles.Integer, provider: null, out var limit))
|
if (UInt128.TryParse(arg.AsSpan(eq + 1), NumberStyles.Integer, provider: null, out var limit))
|
||||||
{
|
{
|
||||||
divisorCyclesSearchLimit128 = limit;
|
divisorCyclesSearchLimit128 = limit;
|
||||||
divisorCyclesSearchLimit = limit > (UInt128)ulong.MaxValue ? ulong.MaxValue : (ulong)limit;
|
divisorCyclesSearchLimit = limit > (UInt128)ulong.MaxValue ? ulong.MaxValue : (ulong)limit;
|
||||||
divisorCyclesLimitExplicit = true;
|
divisorCyclesLimitExplicit = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (arg.StartsWith("--residue-max-k=", StringComparison.OrdinalIgnoreCase))
|
else if (arg.StartsWith("--residue-max-k=", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
int eq = arg.IndexOf('=');
|
int eq = arg.IndexOf('=');
|
||||||
if (UInt128.TryParse(arg.AsSpan(eq + 1), NumberStyles.Integer, provider: null, out var kmax))
|
if (UInt128.TryParse(arg.AsSpan(eq + 1), NumberStyles.Integer, provider: null, out var kmax))
|
||||||
{
|
{
|
||||||
residueKMax = kmax;
|
residueKMax = kmax;
|
||||||
residueKMaxExplicit = true;
|
residueKMaxExplicit = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Replaces --lucas=cpu|gpu; controls device for Lucas and for
|
// Replaces --lucas=cpu|gpu; controls device for Lucas and for
|
||||||
// incremental/pow2mod scanning
|
// incremental/pow2mod scanning
|
||||||
else if (arg.StartsWith("--mersenne-device=", StringComparison.OrdinalIgnoreCase))
|
else if (arg.StartsWith("--mersenne-device=", StringComparison.OrdinalIgnoreCase))
|
||||||
@@ -372,13 +372,13 @@ internal static class Program
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
residueKMax = ResolveResidueMaxK(useResidue, residueKMaxExplicit, divisorCyclesLimitExplicit, residueKMax, divisorCyclesSearchLimit128);
|
residueKMax = ResolveResidueMaxK(useResidue, residueKMaxExplicit, divisorCyclesLimitExplicit, residueKMax, divisorCyclesSearchLimit128);
|
||||||
|
|
||||||
if (showHelp)
|
if (showHelp)
|
||||||
{
|
{
|
||||||
PrintHelp();
|
PrintHelp();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply GPU prime sieve runtime configuration
|
// Apply GPU prime sieve runtime configuration
|
||||||
GpuPrimeWorkLimiter.SetLimit(gpuPrimeThreads);
|
GpuPrimeWorkLimiter.SetLimit(gpuPrimeThreads);
|
||||||
@@ -460,8 +460,8 @@ internal static class Program
|
|||||||
useGpuScan: mersenneOnGpu,
|
useGpuScan: mersenneOnGpu,
|
||||||
useGpuOrder: orderOnGpu,
|
useGpuOrder: orderOnGpu,
|
||||||
useResidue: useResidue,
|
useResidue: useResidue,
|
||||||
maxK: residueKMax,
|
maxK: residueKMax,
|
||||||
residueDivisorSets: divisorCyclesSearchLimit128);
|
residueDivisorSets: divisorCyclesSearchLimit128);
|
||||||
if (!useLucas)
|
if (!useLucas)
|
||||||
{
|
{
|
||||||
tester.WarmUpOrders(currentP, _orderWarmupLimitOverride ?? 5_000_000UL);
|
tester.WarmUpOrders(currentP, _orderWarmupLimitOverride ?? 5_000_000UL);
|
||||||
@@ -773,7 +773,7 @@ internal static class Program
|
|||||||
Console.WriteLine(" --divisor-cycles-device=cpu|gpu device for cycles generation (default gpu)");
|
Console.WriteLine(" --divisor-cycles-device=cpu|gpu device for cycles generation (default gpu)");
|
||||||
Console.WriteLine(" --divisor-cycles-batch-size=<value> batch size for cycles generation (default 512)");
|
Console.WriteLine(" --divisor-cycles-batch-size=<value> batch size for cycles generation (default 512)");
|
||||||
Console.WriteLine(" --divisor-cycles-continue continue divisor cycles generation");
|
Console.WriteLine(" --divisor-cycles-continue continue divisor cycles generation");
|
||||||
Console.WriteLine(" --divisor-cycles-limit=<value> cycle search iterations when --mersenne=divisor or residue (UInt128 supported; residue path honors full range)");
|
Console.WriteLine(" --divisor-cycles-limit=<value> cycle search iterations when --mersenne=divisor or residue (UInt128 supported; residue path honors full range)");
|
||||||
|
|
||||||
Console.WriteLine(" --use-order test primality via q order");
|
Console.WriteLine(" --use-order test primality via q order");
|
||||||
Console.WriteLine(" --workaround-mod avoid '%' operator on the GPU");
|
Console.WriteLine(" --workaround-mod avoid '%' operator on the GPU");
|
||||||
@@ -842,70 +842,54 @@ internal static class Program
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool lastWasComposite = _lastCompositeP;
|
bool lastWasComposite = _lastCompositeP;
|
||||||
bool primeFlag = false, printToConsole = false;
|
bool primeFlag = false, printToConsole = false;
|
||||||
|
|
||||||
StringBuilder? localBuilder = passedAllTests ? StringBuilderPool.Rent() : null;
|
StringBuilder localBuilder = StringBuilderPool.Rent();
|
||||||
if (localBuilder is not null)
|
_ = localBuilder
|
||||||
{
|
.Append(currentP).Append(',')
|
||||||
_ = localBuilder
|
.Append(searchedMersenne).Append(',')
|
||||||
.Append(currentP).Append(',')
|
.Append(detailedCheck).Append(',')
|
||||||
.Append(searchedMersenne).Append(',')
|
.Append(passedAllTests).Append('\n');
|
||||||
.Append(detailedCheck).Append(',')
|
|
||||||
.Append(passedAllTests).Append('\n');
|
|
||||||
}
|
|
||||||
|
|
||||||
lock (Sync)
|
lock (Sync)
|
||||||
{
|
{
|
||||||
if (_consoleCounter >= ConsoleInterval)
|
if (_consoleCounter >= ConsoleInterval)
|
||||||
{
|
{
|
||||||
printToConsole = true;
|
printToConsole = true;
|
||||||
primeFlag = passedAllTests && !lastWasComposite && _primeFoundAfterInit;
|
primeFlag = passedAllTests && !lastWasComposite && _primeFoundAfterInit;
|
||||||
_consoleCounter = 0;
|
_consoleCounter = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_consoleCounter++;
|
_consoleCounter++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (localBuilder is not null)
|
_ = _outputBuilder!.Append(localBuilder);
|
||||||
{
|
|
||||||
_ = _outputBuilder!.Append(localBuilder);
|
|
||||||
|
|
||||||
_writeIndex++;
|
_writeIndex++;
|
||||||
if (_writeIndex >= _writeBatchSize)
|
if (_writeIndex >= _writeBatchSize)
|
||||||
{
|
{
|
||||||
FlushBuffer();
|
FlushBuffer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (printToConsole)
|
if (printToConsole)
|
||||||
{
|
{
|
||||||
if (localBuilder is not null)
|
if (primeFlag)
|
||||||
{
|
{
|
||||||
if (primeFlag)
|
_ = localBuilder
|
||||||
{
|
.Remove(localBuilder.Length - 1, 1)
|
||||||
_ = localBuilder
|
.Append(PrimeFoundSuffix)
|
||||||
.Remove(localBuilder.Length - 1, 1)
|
.Append('\n');
|
||||||
.Append(PrimeFoundSuffix)
|
}
|
||||||
.Append('\n');
|
|
||||||
}
|
|
||||||
|
|
||||||
Console.WriteLine(localBuilder.Remove(localBuilder.Length - 1, 1).ToString());
|
Console.WriteLine(localBuilder.Remove(localBuilder.Length - 1, 1).ToString());
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
Console.WriteLine($"{currentP},{searchedMersenne},{detailedCheck},{passedAllTests}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (localBuilder is not null)
|
localBuilder.Clear();
|
||||||
{
|
StringBuilderPool.Return(localBuilder);
|
||||||
localBuilder.Clear();
|
}
|
||||||
StringBuilderPool.Return(localBuilder);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
private static void FlushBuffer()
|
private static void FlushBuffer()
|
||||||
@@ -956,11 +940,11 @@ internal static class Program
|
|||||||
}
|
}
|
||||||
|
|
||||||
ulong next = (value << 1) | 1UL;
|
ulong next = (value << 1) | 1UL;
|
||||||
remainder = (remainder << 1) + 1UL;
|
remainder = (remainder << 1) + 1UL;
|
||||||
while (remainder >= 6UL)
|
while (remainder >= 6UL)
|
||||||
{
|
{
|
||||||
remainder -= 6UL;
|
remainder -= 6UL;
|
||||||
}
|
}
|
||||||
|
|
||||||
value = remainder switch
|
value = remainder switch
|
||||||
{
|
{
|
||||||
@@ -978,11 +962,11 @@ internal static class Program
|
|||||||
return original;
|
return original;
|
||||||
}
|
}
|
||||||
|
|
||||||
remainder += value;
|
remainder += value;
|
||||||
while (remainder >= 6UL)
|
while (remainder >= 6UL)
|
||||||
{
|
{
|
||||||
remainder -= 6UL;
|
remainder -= 6UL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return next + value;
|
return next + value;
|
||||||
}
|
}
|
||||||
@@ -999,11 +983,11 @@ internal static class Program
|
|||||||
return next;
|
return next;
|
||||||
}
|
}
|
||||||
|
|
||||||
remainder += diff;
|
remainder += diff;
|
||||||
while (remainder >= 6UL)
|
while (remainder >= 6UL)
|
||||||
{
|
{
|
||||||
remainder -= 6UL;
|
remainder -= 6UL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return next + diff;
|
return next + diff;
|
||||||
}
|
}
|
||||||
@@ -1031,11 +1015,11 @@ internal static class Program
|
|||||||
}
|
}
|
||||||
|
|
||||||
candidate += diff;
|
candidate += diff;
|
||||||
addRemainder += diff;
|
addRemainder += diff;
|
||||||
while (addRemainder >= 6UL)
|
while (addRemainder >= 6UL)
|
||||||
{
|
{
|
||||||
addRemainder -= 6UL;
|
addRemainder -= 6UL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (advancePrime)
|
if (advancePrime)
|
||||||
@@ -1149,37 +1133,37 @@ internal static class Program
|
|||||||
return _divisorTester!.IsPrime(p, _divisor, divisorCyclesSearchLimit, out detailedCheck);
|
return _divisorTester!.IsPrime(p, _divisor, divisorCyclesSearchLimit, out detailedCheck);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool mersennePrime = MersenneTesters.Value!.IsMersennePrime(p, out bool residueExhausted);
|
bool mersennePrime = MersenneTesters.Value!.IsMersennePrime(p, out bool residueExhausted);
|
||||||
detailedCheck = residueExhausted;
|
detailedCheck = residueExhausted;
|
||||||
return mersennePrime;
|
return mersennePrime;
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
internal static UInt128 ResolveResidueMaxK(
|
internal static UInt128 ResolveResidueMaxK(
|
||||||
bool useResidue,
|
bool useResidue,
|
||||||
bool residueMaxExplicit,
|
bool residueMaxExplicit,
|
||||||
bool divisorLimitExplicit,
|
bool divisorLimitExplicit,
|
||||||
UInt128 residueMaxK,
|
UInt128 residueMaxK,
|
||||||
UInt128 divisorLimit)
|
UInt128 divisorLimit)
|
||||||
{
|
{
|
||||||
if (!useResidue)
|
if (!useResidue)
|
||||||
{
|
{
|
||||||
return residueMaxK;
|
return residueMaxK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (residueMaxExplicit || !divisorLimitExplicit)
|
if (residueMaxExplicit || !divisorLimitExplicit)
|
||||||
{
|
{
|
||||||
return residueMaxK;
|
return residueMaxK;
|
||||||
}
|
}
|
||||||
|
|
||||||
return divisorLimit;
|
return divisorLimit;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use ModResidueTracker with a small set of primes to pre-filter composite p.
|
// Use ModResidueTracker with a small set of primes to pre-filter composite p.
|
||||||
private static bool IsCompositeByResidues(ulong p)
|
private static bool IsCompositeByResidues(ulong p)
|
||||||
{
|
{
|
||||||
var tracker = PResidue.Value!;
|
var tracker = PResidue.Value!;
|
||||||
tracker.BeginMerge(p);
|
tracker.BeginMerge(p);
|
||||||
// Use the small prime list from PerfectNumbers.Core to the extent of sqrt(p)
|
// Use the small prime list from PerfectNumbers.Core to the extent of sqrt(p)
|
||||||
var primes = PrimesGenerator.SmallPrimes;
|
var primes = PrimesGenerator.SmallPrimes;
|
||||||
var primesPow2 = PrimesGenerator.SmallPrimesPow2;
|
var primesPow2 = PrimesGenerator.SmallPrimesPow2;
|
||||||
|
|||||||
Reference in new issue
Block a user