Allow residue GPU scanning to cover UInt128 divisors

This commit is contained in:
Marek Lemańczyk committed 2025-09-20 02:49:20 +02:00
1 parent 0a9b11e957
commit bc1ec6a3aa
6 files changed
+62 -56

No files matched your search

+24 -18
View File
@@ -1,3 +1,4 @@
using System.Globalization;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Text;
@@ -73,12 +74,13 @@ internal static class Program
bool mersenneOnGpu = true; // controls Lucas/incremental/pow2mod device
bool orderOnGpu = true; // controls order computations device
int scanBatchSize = 2_097_152, sliceSize = 32;
ulong residueKMax = 5_000_000UL;
UInt128 residueKMax = 5_000_000UL;
string filterFile = string.Empty;
string cyclesPath = DefaultCyclesPath;
int cyclesBatchSize = 512;
bool continueCyclesGeneration = false;
ulong divisorCyclesSearchLimit = PerfectNumberConstants.ExtraDivisorCycleSearchLimit;
UInt128 divisorCyclesSearchLimit128 = PerfectNumberConstants.ExtraDivisorCycleSearchLimit;
ulong divisorCyclesSearchLimit = PerfectNumberConstants.ExtraDivisorCycleSearchLimit;
// NTT backend selection (GPU): reference vs staged
for (int i = 0; i < args.Length; i++)
@@ -140,19 +142,23 @@ internal static class Program
int eq = arg.IndexOf('=');
divisor = UInt128.Parse(arg.AsSpan(eq + 1));
}
else if (arg.StartsWith("--divisor-cycles-limit=", StringComparison.OrdinalIgnoreCase))
{
int eq = arg.IndexOf('=');
divisorCyclesSearchLimit = ulong.Parse(arg.AsSpan(eq + 1));
}
else if (arg.StartsWith("--residue-max-k=", StringComparison.OrdinalIgnoreCase))
{
int eq = arg.IndexOf('=');
if (ulong.TryParse(arg.AsSpan(eq + 1), out var kmax))
{
residueKMax = kmax;
}
}
else if (arg.StartsWith("--divisor-cycles-limit=", StringComparison.OrdinalIgnoreCase))
{
int eq = arg.IndexOf('=');
if (UInt128.TryParse(arg.AsSpan(eq + 1), NumberStyles.Integer, provider: null, out var limit))
{
divisorCyclesSearchLimit128 = limit;
divisorCyclesSearchLimit = limit > (UInt128)ulong.MaxValue ? ulong.MaxValue : (ulong)limit;
}
}
else if (arg.StartsWith("--residue-max-k=", StringComparison.OrdinalIgnoreCase))
{
int eq = arg.IndexOf('=');
if (UInt128.TryParse(arg.AsSpan(eq + 1), NumberStyles.Integer, provider: null, out var kmax))
{
residueKMax = kmax;
}
}
// Replaces --lucas=cpu|gpu; controls device for Lucas and for
// incremental/pow2mod scanning
else if (arg.StartsWith("--mersenne-device=", StringComparison.OrdinalIgnoreCase))
@@ -448,8 +454,8 @@ internal static class Program
useGpuScan: mersenneOnGpu,
useGpuOrder: orderOnGpu,
useResidue: useResidue,
maxK: residueKMax,
residueDivisorSets: divisorCyclesSearchLimit);
maxK: residueKMax,
residueDivisorSets: divisorCyclesSearchLimit128);
if (!useLucas)
{
tester.WarmUpOrders(currentP, _orderWarmupLimitOverride ?? 5_000_000UL);
@@ -741,7 +747,7 @@ internal static class Program
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-continue continue divisor cycles generation");
Console.WriteLine(" --divisor-cycles-limit=<value> cycle search iterations when --mersenne=divisor or residue");
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(" --workaround-mod avoid '%' operator on the GPU");