--min-k command-line argument added. Partial factoring switched back to CPU.
This commit is contained in:
1 parent
13498dc460
commit
a296e62d4d
10 files changed
+485
-160
No files matched your search
@@ -50,6 +50,7 @@ internal readonly struct CliArguments
|
|||||||
internal readonly double ZeroFractionHard;
|
internal readonly double ZeroFractionHard;
|
||||||
internal readonly double ZeroFractionConjecture;
|
internal readonly double ZeroFractionConjecture;
|
||||||
internal readonly int MaxZeroConjecture;
|
internal readonly int MaxZeroConjecture;
|
||||||
|
internal readonly ulong MinK;
|
||||||
|
|
||||||
private CliArguments(
|
private CliArguments(
|
||||||
ulong startPrime,
|
ulong startPrime,
|
||||||
@@ -93,7 +94,8 @@ internal readonly struct CliArguments
|
|||||||
bool rleOnlyLast7,
|
bool rleOnlyLast7,
|
||||||
double zeroFractionHard,
|
double zeroFractionHard,
|
||||||
double zeroFractionConjecture,
|
double zeroFractionConjecture,
|
||||||
int maxZeroConjecture)
|
int maxZeroConjecture,
|
||||||
|
ulong minK)
|
||||||
{
|
{
|
||||||
StartPrime = startPrime;
|
StartPrime = startPrime;
|
||||||
StartPrimeProvided = startPrimeProvided;
|
StartPrimeProvided = startPrimeProvided;
|
||||||
@@ -137,6 +139,7 @@ internal readonly struct CliArguments
|
|||||||
ZeroFractionHard = zeroFractionHard;
|
ZeroFractionHard = zeroFractionHard;
|
||||||
ZeroFractionConjecture = zeroFractionConjecture;
|
ZeroFractionConjecture = zeroFractionConjecture;
|
||||||
MaxZeroConjecture = maxZeroConjecture;
|
MaxZeroConjecture = maxZeroConjecture;
|
||||||
|
MinK = minK;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal bool UseFilter => !TestMode && !string.IsNullOrEmpty(FilterFile);
|
internal bool UseFilter => !TestMode && !string.IsNullOrEmpty(FilterFile);
|
||||||
@@ -185,6 +188,7 @@ internal readonly struct CliArguments
|
|||||||
double zeroFractionHard = -1.0;
|
double zeroFractionHard = -1.0;
|
||||||
double zeroFractionConjecture = -1.0;
|
double zeroFractionConjecture = -1.0;
|
||||||
int maxZeroConjecture = -1;
|
int maxZeroConjecture = -1;
|
||||||
|
ulong minK = 1UL;
|
||||||
|
|
||||||
foreach (string argument in args)
|
foreach (string argument in args)
|
||||||
{
|
{
|
||||||
@@ -298,6 +302,21 @@ internal readonly struct CliArguments
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (argument.StartsWith("--min-k=", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
if (Utf8CliParser.TryParseUInt64(argument.AsSpan("--min-k=".Length), out ulong parsedMinK) && parsedMinK > 0UL)
|
||||||
|
{
|
||||||
|
minK = parsedMinK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Console.WriteLine("Invalid value for --min-k.");
|
||||||
|
return default;
|
||||||
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (argument.StartsWith("--mersenne-device=", StringComparison.OrdinalIgnoreCase))
|
if (argument.StartsWith("--mersenne-device=", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
useMersenneOnGpu = !argument.AsSpan("--mersenne-device=".Length).Equals("cpu", StringComparison.OrdinalIgnoreCase);
|
useMersenneOnGpu = !argument.AsSpan("--mersenne-device=".Length).Equals("cpu", StringComparison.OrdinalIgnoreCase);
|
||||||
@@ -568,7 +587,8 @@ internal readonly struct CliArguments
|
|||||||
rleOnlyLast7,
|
rleOnlyLast7,
|
||||||
zeroFractionHard,
|
zeroFractionHard,
|
||||||
zeroFractionConjecture,
|
zeroFractionConjecture,
|
||||||
maxZeroConjecture);
|
maxZeroConjecture,
|
||||||
|
minK);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void PrintHelp()
|
internal static void PrintHelp()
|
||||||
@@ -609,6 +629,7 @@ internal readonly struct CliArguments
|
|||||||
Console.WriteLine(" --filter-p=<path> process only p from previous run results (required for --mersenne=bydivisor)");
|
Console.WriteLine(" --filter-p=<path> process only p from previous run results (required for --mersenne=bydivisor)");
|
||||||
Console.WriteLine(" --write-batch-size=<value> overwrite frequency of disk writes (default 100 lines)");
|
Console.WriteLine(" --write-batch-size=<value> overwrite frequency of disk writes (default 100 lines)");
|
||||||
Console.WriteLine(" --gcd-filter enable early sieve based on GCD");
|
Console.WriteLine(" --gcd-filter enable early sieve based on GCD");
|
||||||
|
Console.WriteLine(" --min-k=<value> starting k for --mersenne=bydivisor divisor scan (default 1)");
|
||||||
Console.WriteLine(" --help, -help, --?, -?, /? show this help message");
|
Console.WriteLine(" --help, -help, --?, -?, /? show this help message");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -217,6 +217,7 @@ internal static class Program
|
|||||||
_byDivisorTester = mersenneOnGpu
|
_byDivisorTester = mersenneOnGpu
|
||||||
? new MersenneNumberDivisorByDivisorGpuTester()
|
? new MersenneNumberDivisorByDivisorGpuTester()
|
||||||
: new MersenneNumberDivisorByDivisorCpuTester();
|
: new MersenneNumberDivisorByDivisorCpuTester();
|
||||||
|
_byDivisorTester.MinK = _cliArguments.MinK;
|
||||||
_byDivisorTester.BatchSize = scanBatchSize;
|
_byDivisorTester.BatchSize = scanBatchSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -46,6 +46,8 @@ public class MersenneNumberDivisorByDivisorTesterTests
|
|||||||
|
|
||||||
public int BatchSize { get; set; }
|
public int BatchSize { get; set; }
|
||||||
|
|
||||||
|
public ulong MinK { get; set; }
|
||||||
|
|
||||||
public ulong DivisorLimit => ConfiguredMaxPrime + 100UL;
|
public ulong DivisorLimit => ConfiguredMaxPrime + 100UL;
|
||||||
|
|
||||||
public void ConfigureFromMaxPrime(ulong maxPrime)
|
public void ConfigureFromMaxPrime(ulong maxPrime)
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ public sealed class MersenneNumberDivisorByDivisorCpuTester() : IMersenneNumberD
|
|||||||
{
|
{
|
||||||
private ulong _divisorLimit;
|
private ulong _divisorLimit;
|
||||||
private int _batchSize = 1_024;
|
private int _batchSize = 1_024;
|
||||||
|
private ulong _minK = 1UL;
|
||||||
|
|
||||||
[ThreadStatic]
|
[ThreadStatic]
|
||||||
private static GpuUInt128WorkSet _divisorScanGpuWorkSet;
|
private static GpuUInt128WorkSet _divisorScanGpuWorkSet;
|
||||||
@@ -25,6 +26,12 @@ public sealed class MersenneNumberDivisorByDivisorCpuTester() : IMersenneNumberD
|
|||||||
set => _batchSize = Math.Max(1, value);
|
set => _batchSize = Math.Max(1, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ulong MinK
|
||||||
|
{
|
||||||
|
get => _minK;
|
||||||
|
set => _minK = value < 1UL ? 1UL : value;
|
||||||
|
}
|
||||||
|
|
||||||
public void ConfigureFromMaxPrime(ulong maxPrime)
|
public void ConfigureFromMaxPrime(ulong maxPrime)
|
||||||
{
|
{
|
||||||
_divisorLimit = ComputeDivisorLimitFromMaxPrime(maxPrime);
|
_divisorLimit = ComputeDivisorLimitFromMaxPrime(maxPrime);
|
||||||
@@ -61,6 +68,7 @@ public sealed class MersenneNumberDivisorByDivisorCpuTester() : IMersenneNumberD
|
|||||||
gpu,
|
gpu,
|
||||||
prime,
|
prime,
|
||||||
allowedMax,
|
allowedMax,
|
||||||
|
_minK,
|
||||||
out processedAll,
|
out processedAll,
|
||||||
out divisor);
|
out divisor);
|
||||||
|
|
||||||
@@ -100,9 +108,13 @@ public sealed class MersenneNumberDivisorByDivisorCpuTester() : IMersenneNumberD
|
|||||||
PrimeOrderCalculatorAccelerator gpu,
|
PrimeOrderCalculatorAccelerator gpu,
|
||||||
ulong prime,
|
ulong prime,
|
||||||
ulong allowedMax,
|
ulong allowedMax,
|
||||||
|
ulong minK,
|
||||||
out bool processedAll,
|
out bool processedAll,
|
||||||
out ulong foundDivisor)
|
out ulong foundDivisor)
|
||||||
{
|
{
|
||||||
|
foundDivisor = 0UL;
|
||||||
|
processedAll = true;
|
||||||
|
|
||||||
// The EvenPerfectBitScanner feeds primes >= 138,000,000 here, so allowedMax >= 3 in production runs.
|
// The EvenPerfectBitScanner feeds primes >= 138,000,000 here, so allowedMax >= 3 in production runs.
|
||||||
// Keeping the guard commented out documents the reasoning for benchmarks and tests.
|
// Keeping the guard commented out documents the reasoning for benchmarks and tests.
|
||||||
// if (allowedMax < 3UL)
|
// if (allowedMax < 3UL)
|
||||||
@@ -125,6 +137,13 @@ public sealed class MersenneNumberDivisorByDivisorCpuTester() : IMersenneNumberD
|
|||||||
divisor.High = step.High;
|
divisor.High = step.High;
|
||||||
divisor.Low = step.Low;
|
divisor.Low = step.Low;
|
||||||
divisor.Add(1UL);
|
divisor.Add(1UL);
|
||||||
|
if (minK > 1UL)
|
||||||
|
{
|
||||||
|
GpuUInt128 offset = new(minK - 1UL);
|
||||||
|
divisor = step * offset;
|
||||||
|
divisor.Add(1UL);
|
||||||
|
}
|
||||||
|
|
||||||
if (divisor.CompareTo(limit) > 0)
|
if (divisor.CompareTo(limit) > 0)
|
||||||
{
|
{
|
||||||
processedAll = true;
|
processedAll = true;
|
||||||
@@ -165,31 +184,66 @@ public sealed class MersenneNumberDivisorByDivisorCpuTester() : IMersenneNumberD
|
|||||||
step7 = (byte)(stepLow % 7UL);
|
step7 = (byte)(stepLow % 7UL);
|
||||||
step11 = (byte)(stepLow % 11UL);
|
step11 = (byte)(stepLow % 11UL);
|
||||||
|
|
||||||
remainder10 = (byte)(divisorLow % 10UL);
|
ulong maxK = allowedMax > 0UL ? (allowedMax - 1UL) / stepLow : 0UL;
|
||||||
remainder8 = (byte)(divisorLow & 7UL);
|
if (maxK == 0UL)
|
||||||
remainder3 = (byte)(divisorLow % 3UL);
|
{
|
||||||
remainder7 = (byte)(divisorLow % 7UL);
|
processedAll = true;
|
||||||
remainder11 = (byte)(divisorLow % 11UL);
|
foundDivisor = 0UL;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return CheckDivisors64(
|
ulong startK = minK < 1UL ? 1UL : minK;
|
||||||
gpu,
|
bool processedTop = true;
|
||||||
prime,
|
bool processedBottom = true;
|
||||||
stepLow,
|
bool composite = false;
|
||||||
limit.Low,
|
|
||||||
divisorLow,
|
if (startK <= maxK)
|
||||||
decimalMask,
|
{
|
||||||
step10,
|
composite = CheckDivisors64Range(
|
||||||
step8,
|
gpu,
|
||||||
step3,
|
prime,
|
||||||
step7,
|
stepLow,
|
||||||
step11,
|
allowedMax,
|
||||||
remainder10,
|
startK,
|
||||||
remainder8,
|
maxK,
|
||||||
remainder3,
|
decimalMask,
|
||||||
remainder7,
|
step10,
|
||||||
remainder11,
|
step8,
|
||||||
out processedAll,
|
step3,
|
||||||
out foundDivisor);
|
step7,
|
||||||
|
step11,
|
||||||
|
out processedTop,
|
||||||
|
out foundDivisor);
|
||||||
|
if (composite)
|
||||||
|
{
|
||||||
|
processedAll = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ulong lowerEnd = startK > 1UL ? startK - 1UL : 0UL;
|
||||||
|
if (lowerEnd >= 1UL)
|
||||||
|
{
|
||||||
|
lowerEnd = Math.Min(lowerEnd, maxK);
|
||||||
|
composite = CheckDivisors64Range(
|
||||||
|
gpu,
|
||||||
|
prime,
|
||||||
|
stepLow,
|
||||||
|
allowedMax,
|
||||||
|
1UL,
|
||||||
|
lowerEnd,
|
||||||
|
decimalMask,
|
||||||
|
step10,
|
||||||
|
step8,
|
||||||
|
step3,
|
||||||
|
step7,
|
||||||
|
step11,
|
||||||
|
out processedBottom,
|
||||||
|
out foundDivisor);
|
||||||
|
}
|
||||||
|
|
||||||
|
processedAll = processedTop && processedBottom;
|
||||||
|
return composite;
|
||||||
}
|
}
|
||||||
|
|
||||||
ulong divisorHigh = divisor.High;
|
ulong divisorHigh = divisor.High;
|
||||||
@@ -265,6 +319,75 @@ public sealed class MersenneNumberDivisorByDivisorCpuTester() : IMersenneNumberD
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static bool CheckDivisors64Range(
|
||||||
|
PrimeOrderCalculatorAccelerator gpu,
|
||||||
|
ulong prime,
|
||||||
|
ulong step,
|
||||||
|
ulong allowedMax,
|
||||||
|
ulong startK,
|
||||||
|
ulong endK,
|
||||||
|
ushort decimalMask,
|
||||||
|
byte step10,
|
||||||
|
byte step8,
|
||||||
|
byte step3,
|
||||||
|
byte step7,
|
||||||
|
byte step11,
|
||||||
|
out bool processedAll,
|
||||||
|
out ulong foundDivisor)
|
||||||
|
{
|
||||||
|
if (startK < 1UL || endK < startK)
|
||||||
|
{
|
||||||
|
processedAll = true;
|
||||||
|
foundDivisor = 0UL;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
UInt128 step128 = step;
|
||||||
|
UInt128 allowedMax128 = allowedMax;
|
||||||
|
UInt128 startDivisor128 = (step128 * startK) + UInt128.One;
|
||||||
|
if (startDivisor128 > allowedMax128)
|
||||||
|
{
|
||||||
|
processedAll = true;
|
||||||
|
foundDivisor = 0UL;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
UInt128 rangeLimit128 = (step128 * endK) + UInt128.One;
|
||||||
|
if (rangeLimit128 > allowedMax128)
|
||||||
|
{
|
||||||
|
rangeLimit128 = allowedMax128;
|
||||||
|
}
|
||||||
|
|
||||||
|
ulong startDivisor = (ulong)startDivisor128;
|
||||||
|
ulong rangeLimit = (ulong)rangeLimit128;
|
||||||
|
|
||||||
|
byte remainder10 = (byte)(startDivisor % 10UL);
|
||||||
|
byte remainder8 = (byte)(startDivisor & 7UL);
|
||||||
|
byte remainder3 = (byte)(startDivisor % 3UL);
|
||||||
|
byte remainder7 = (byte)(startDivisor % 7UL);
|
||||||
|
byte remainder11 = (byte)(startDivisor % 11UL);
|
||||||
|
|
||||||
|
return CheckDivisors64(
|
||||||
|
gpu,
|
||||||
|
prime,
|
||||||
|
step,
|
||||||
|
rangeLimit,
|
||||||
|
startDivisor,
|
||||||
|
decimalMask,
|
||||||
|
step10,
|
||||||
|
step8,
|
||||||
|
step3,
|
||||||
|
step7,
|
||||||
|
step11,
|
||||||
|
remainder10,
|
||||||
|
remainder8,
|
||||||
|
remainder3,
|
||||||
|
remainder7,
|
||||||
|
remainder11,
|
||||||
|
out processedAll,
|
||||||
|
out foundDivisor);
|
||||||
|
}
|
||||||
|
|
||||||
private static bool CheckDivisors64(
|
private static bool CheckDivisors64(
|
||||||
PrimeOrderCalculatorAccelerator gpu,
|
PrimeOrderCalculatorAccelerator gpu,
|
||||||
ulong prime,
|
ulong prime,
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
using ILGPU;
|
using ILGPU;
|
||||||
using ILGPU.Runtime;
|
using ILGPU.Runtime;
|
||||||
|
using Open.Collections;
|
||||||
|
|
||||||
namespace PerfectNumbers.Core.Gpu
|
namespace PerfectNumbers.Core.Gpu
|
||||||
{
|
{
|
||||||
public struct AcceleratorPool
|
public struct AcceleratorPool : IDisposable
|
||||||
{
|
{
|
||||||
internal readonly Context Context;
|
internal readonly Context Context;
|
||||||
internal readonly Device Device;
|
internal readonly Device Device;
|
||||||
@@ -28,6 +29,23 @@ namespace PerfectNumbers.Core.Gpu
|
|||||||
// Intentionally left empty - there's nothing to do here. We're not really renting anything.
|
// Intentionally left empty - there's nothing to do here. We're not really renting anything.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public readonly void Dispose()
|
||||||
|
{
|
||||||
|
Accelerator[] accelerators = Accelerators;
|
||||||
|
HashSet<Context> contexts = new(accelerators.Length);
|
||||||
|
foreach (var accelerator in accelerators)
|
||||||
|
{
|
||||||
|
contexts.Add(accelerator.Context);
|
||||||
|
accelerator.Synchronize();
|
||||||
|
accelerator.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var context in contexts)
|
||||||
|
{
|
||||||
|
context.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static readonly AcceleratorPool Shared = new(PerfectNumberConstants.RollingAccelerators);
|
public static readonly AcceleratorPool Shared = new(PerfectNumberConstants.RollingAccelerators);
|
||||||
|
|
||||||
private readonly int Capacity;
|
private readonly int Capacity;
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using System.Collections.Concurrent;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using ILGPU;
|
using ILGPU;
|
||||||
using ILGPU.Runtime;
|
using ILGPU.Runtime;
|
||||||
@@ -9,8 +10,8 @@ public sealed class PrimeOrderCalculatorAccelerator
|
|||||||
{
|
{
|
||||||
#region Pool
|
#region Pool
|
||||||
|
|
||||||
[ThreadStatic]
|
// [ThreadStatic]
|
||||||
private static Queue<PrimeOrderCalculatorAccelerator>? _pool;
|
private static ConcurrentQueue<PrimeOrderCalculatorAccelerator>? _pool;
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static PrimeOrderCalculatorAccelerator Rent(int primeTesterCapacity)
|
public static PrimeOrderCalculatorAccelerator Rent(int primeTesterCapacity)
|
||||||
@@ -34,7 +35,7 @@ public sealed class PrimeOrderCalculatorAccelerator
|
|||||||
|
|
||||||
internal static void Clear()
|
internal static void Clear()
|
||||||
{
|
{
|
||||||
Queue<PrimeOrderCalculatorAccelerator>? pool = _pool;
|
var pool = _pool;
|
||||||
if (pool != null)
|
if (pool != null)
|
||||||
{
|
{
|
||||||
while (pool.TryDequeue(out var gpu))
|
while (pool.TryDequeue(out var gpu))
|
||||||
@@ -46,7 +47,7 @@ public sealed class PrimeOrderCalculatorAccelerator
|
|||||||
|
|
||||||
internal static void DisposeAll()
|
internal static void DisposeAll()
|
||||||
{
|
{
|
||||||
Queue<PrimeOrderCalculatorAccelerator>? pool = _pool;
|
var pool = _pool;
|
||||||
if (pool != null)
|
if (pool != null)
|
||||||
{
|
{
|
||||||
while (pool.TryDequeue(out var gpu))
|
while (pool.TryDequeue(out var gpu))
|
||||||
@@ -152,7 +153,7 @@ public sealed class PrimeOrderCalculatorAccelerator
|
|||||||
|
|
||||||
private sealed class CalculatorKernels(Accelerator accelerator)
|
private sealed class CalculatorKernels(Accelerator accelerator)
|
||||||
{
|
{
|
||||||
public readonly Action<AcceleratorStream, Index1D, ulong, CalculateOrderKernelConfig, ulong, ulong, ulong, ulong, ulong, ArrayView1D<uint, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>, int, OrderKernelBuffers> CalculateOrderKernelLauncher = KernelUtil.GetKernel(accelerator.LoadAutoGroupedStreamKernel<Index1D, ulong, CalculateOrderKernelConfig, ulong, ulong, ulong, ulong, ulong, ArrayView1D<uint, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>, int, OrderKernelBuffers>(PrimeOrderKernels.CalculateOrderKernel)).CreateLauncherDelegate<Action<AcceleratorStream, Index1D, ulong, CalculateOrderKernelConfig, ulong, ulong, ulong, ulong, ulong, ArrayView1D<uint, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>, int, OrderKernelBuffers>>();
|
// public readonly Action<AcceleratorStream, Index1D, ulong, CalculateOrderKernelConfig, ulong, ulong, ulong, ulong, ulong, ArrayView1D<uint, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>, int, OrderKernelBuffers> CalculateOrderKernelLauncher = KernelUtil.GetKernel(accelerator.LoadAutoGroupedStreamKernel<Index1D, ulong, CalculateOrderKernelConfig, ulong, ulong, ulong, ulong, ulong, ArrayView1D<uint, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>, int, OrderKernelBuffers>(PrimeOrderKernels.CalculateOrderKernel)).CreateLauncherDelegate<Action<AcceleratorStream, Index1D, ulong, CalculateOrderKernelConfig, ulong, ulong, ulong, ulong, ulong, ArrayView1D<uint, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>, int, OrderKernelBuffers>>();
|
||||||
|
|
||||||
public readonly Kernel CheckFactorsKernel = KernelUtil.GetKernel(accelerator.LoadStreamKernel<int, ulong, ArrayView1D<KeyValuePair<ulong, int>, Stride1D.Dense>, ulong, ulong, ulong, ulong, ulong, ArrayView1D<ulong, Stride1D.Dense>>(PrimeOrderKernels.CheckFactorsKernel));
|
public readonly Kernel CheckFactorsKernel = KernelUtil.GetKernel(accelerator.LoadStreamKernel<int, ulong, ArrayView1D<KeyValuePair<ulong, int>, Stride1D.Dense>, ulong, ulong, ulong, ulong, ulong, ArrayView1D<ulong, Stride1D.Dense>>(PrimeOrderKernels.CheckFactorsKernel));
|
||||||
|
|
||||||
@@ -162,15 +163,15 @@ public sealed class PrimeOrderCalculatorAccelerator
|
|||||||
|
|
||||||
public readonly Action<AcceleratorStream, Index1D, ArrayView1D<ulong, Stride1D.Dense>, ulong, ulong, ulong, ulong, ulong, ArrayView1D<ulong, Stride1D.Dense>> KeepMontgomeryKernelLauncher = KernelUtil.GetKernel(accelerator.LoadAutoGroupedStreamKernel<Index1D, ArrayView1D<ulong, Stride1D.Dense>, ulong, ulong, ulong, ulong, ulong, ArrayView1D<ulong, Stride1D.Dense>>(Pow2MontgomeryKernels.Pow2MontgomeryKernelKeepMontgomery)).CreateLauncherDelegate<Action<AcceleratorStream, Index1D, ArrayView1D<ulong, Stride1D.Dense>, ulong, ulong, ulong, ulong, ulong, ArrayView1D<ulong, Stride1D.Dense>>>();
|
public readonly Action<AcceleratorStream, Index1D, ArrayView1D<ulong, Stride1D.Dense>, ulong, ulong, ulong, ulong, ulong, ArrayView1D<ulong, Stride1D.Dense>> KeepMontgomeryKernelLauncher = KernelUtil.GetKernel(accelerator.LoadAutoGroupedStreamKernel<Index1D, ArrayView1D<ulong, Stride1D.Dense>, ulong, ulong, ulong, ulong, ulong, ArrayView1D<ulong, Stride1D.Dense>>(Pow2MontgomeryKernels.Pow2MontgomeryKernelKeepMontgomery)).CreateLauncherDelegate<Action<AcceleratorStream, Index1D, ArrayView1D<ulong, Stride1D.Dense>, ulong, ulong, ulong, ulong, ulong, ArrayView1D<ulong, Stride1D.Dense>>>();
|
||||||
|
|
||||||
public readonly Action<AcceleratorStream, Index1D, ArrayView1D<uint, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>, int, int, ulong, uint, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<int, Stride1D.Dense>, ArrayView1D<int, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<byte, Stride1D.Dense>> PartialFactorKernelLauncher = KernelUtil.GetKernel(accelerator.LoadAutoGroupedStreamKernel<Index1D, ArrayView1D<uint, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>, int, int, ulong, uint, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<int, Stride1D.Dense>, ArrayView1D<int, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<byte, Stride1D.Dense>>(PrimeOrderKernels.PartialFactorKernel)).CreateLauncherDelegate<Action<AcceleratorStream, Index1D, ArrayView1D<uint, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>, int, int, ulong, uint, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<int, Stride1D.Dense>, ArrayView1D<int, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<byte, Stride1D.Dense>>>();
|
// public readonly Action<AcceleratorStream, Index1D, ArrayView1D<uint, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>, int, int, ulong, uint, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<int, Stride1D.Dense>, ArrayView1D<int, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<byte, Stride1D.Dense>> PartialFactorKernelLauncher = KernelUtil.GetKernel(accelerator.LoadAutoGroupedStreamKernel<Index1D, ArrayView1D<uint, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>, int, int, ulong, uint, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<int, Stride1D.Dense>, ArrayView1D<int, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<byte, Stride1D.Dense>>(PrimeOrderKernels.PartialFactorKernel)).CreateLauncherDelegate<Action<AcceleratorStream, Index1D, ArrayView1D<uint, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>, int, int, ulong, uint, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<int, Stride1D.Dense>, ArrayView1D<int, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<byte, Stride1D.Dense>>>();
|
||||||
|
|
||||||
public readonly Kernel PollardRhoKernel = KernelUtil.GetKernel(accelerator.LoadStreamKernel<ulong, int, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<byte, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>>(Pow2MontgomeryKernels.TryPollardRhoKernel));
|
// public readonly Kernel PollardRhoKernel = KernelUtil.GetKernel(accelerator.LoadStreamKernel<ulong, int, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<byte, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>>(Pow2MontgomeryKernels.TryPollardRhoKernel));
|
||||||
|
|
||||||
public readonly Action<AcceleratorStream, Index1D, ArrayView1D<ulong, Stride1D.Dense>, ulong, ulong, ulong, ulong, ulong, ArrayView1D<ulong, Stride1D.Dense>> Pow2ModKernelLauncher = KernelUtil.GetKernel(accelerator.LoadAutoGroupedStreamKernel<Index1D, ArrayView1D<ulong, Stride1D.Dense>, ulong, ulong, ulong, ulong, ulong, ArrayView1D<ulong, Stride1D.Dense>>(PrimeOrderKernels.Pow2ModKernel)).CreateLauncherDelegate<Action<AcceleratorStream, Index1D, ArrayView1D<ulong, Stride1D.Dense>, ulong, ulong, ulong, ulong, ulong, ArrayView1D<ulong, Stride1D.Dense>>>();
|
public readonly Action<AcceleratorStream, Index1D, ArrayView1D<ulong, Stride1D.Dense>, ulong, ulong, ulong, ulong, ulong, ArrayView1D<ulong, Stride1D.Dense>> Pow2ModKernelLauncher = KernelUtil.GetKernel(accelerator.LoadAutoGroupedStreamKernel<Index1D, ArrayView1D<ulong, Stride1D.Dense>, ulong, ulong, ulong, ulong, ulong, ArrayView1D<ulong, Stride1D.Dense>>(PrimeOrderKernels.Pow2ModKernel)).CreateLauncherDelegate<Action<AcceleratorStream, Index1D, ArrayView1D<ulong, Stride1D.Dense>, ulong, ulong, ulong, ulong, ulong, ArrayView1D<ulong, Stride1D.Dense>>>();
|
||||||
|
|
||||||
public readonly Action<AcceleratorStream, Index1D, ArrayView1D<GpuUInt128, Stride1D.Dense>, GpuUInt128, ArrayView1D<GpuUInt128, Stride1D.Dense>> Pow2ModWideKernelLauncher = KernelUtil.GetKernel(accelerator.LoadAutoGroupedStreamKernel<Index1D, ArrayView1D<GpuUInt128, Stride1D.Dense>, GpuUInt128, ArrayView1D<GpuUInt128, Stride1D.Dense>>(PrimeOrderKernels.Pow2ModKernelWide)).CreateLauncherDelegate<Action<AcceleratorStream, Index1D, ArrayView1D<GpuUInt128, Stride1D.Dense>, GpuUInt128, ArrayView1D<GpuUInt128, Stride1D.Dense>>>();
|
public readonly Action<AcceleratorStream, Index1D, ArrayView1D<GpuUInt128, Stride1D.Dense>, GpuUInt128, ArrayView1D<GpuUInt128, Stride1D.Dense>> Pow2ModWideKernelLauncher = KernelUtil.GetKernel(accelerator.LoadAutoGroupedStreamKernel<Index1D, ArrayView1D<GpuUInt128, Stride1D.Dense>, GpuUInt128, ArrayView1D<GpuUInt128, Stride1D.Dense>>(PrimeOrderKernels.Pow2ModKernelWide)).CreateLauncherDelegate<Action<AcceleratorStream, Index1D, ArrayView1D<GpuUInt128, Stride1D.Dense>, GpuUInt128, ArrayView1D<GpuUInt128, Stride1D.Dense>>>();
|
||||||
|
|
||||||
public readonly Action<AcceleratorStream, Index1D, ArrayView<ulong>, ArrayView<byte>> SharesFactorKernelLauncher = KernelUtil.GetKernel(accelerator.LoadAutoGroupedStreamKernel<Index1D, ArrayView<ulong>, ArrayView<byte>>(PrimeTesterKernels.SharesFactorKernel)).CreateLauncherDelegate<Action<AcceleratorStream, Index1D, ArrayView<ulong>, ArrayView<byte>>>();
|
// public readonly Action<AcceleratorStream, Index1D, ArrayView<ulong>, ArrayView<byte>> SharesFactorKernelLauncher = KernelUtil.GetKernel(accelerator.LoadAutoGroupedStreamKernel<Index1D, ArrayView<ulong>, ArrayView<byte>>(PrimeTesterKernels.SharesFactorKernel)).CreateLauncherDelegate<Action<AcceleratorStream, Index1D, ArrayView<ulong>, ArrayView<byte>>>();
|
||||||
|
|
||||||
public readonly Action<AcceleratorStream, Index1D, ulong, uint, ArrayView1D<uint, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>, int, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<int, Stride1D.Dense>, ArrayView1D<int, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>> SmallPrimeFactorKernelLauncher = KernelUtil.GetKernel(accelerator.LoadAutoGroupedStreamKernel<Index1D, ulong, uint, ArrayView1D<uint, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>, int, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<int, Stride1D.Dense>, ArrayView1D<int, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>>(SmallPrimeFactorKernels.SmallPrimeFactorKernelScan)).CreateLauncherDelegate<Action<AcceleratorStream, Index1D, ulong, uint, ArrayView1D<uint, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>, int, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<int, Stride1D.Dense>, ArrayView1D<int, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>>>();
|
public readonly Action<AcceleratorStream, Index1D, ulong, uint, ArrayView1D<uint, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>, int, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<int, Stride1D.Dense>, ArrayView1D<int, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>> SmallPrimeFactorKernelLauncher = KernelUtil.GetKernel(accelerator.LoadAutoGroupedStreamKernel<Index1D, ulong, uint, ArrayView1D<uint, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>, int, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<int, Stride1D.Dense>, ArrayView1D<int, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>>(SmallPrimeFactorKernels.SmallPrimeFactorKernelScan)).CreateLauncherDelegate<Action<AcceleratorStream, Index1D, ulong, uint, ArrayView1D<uint, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>, int, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<int, Stride1D.Dense>, ArrayView1D<int, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>>>();
|
||||||
|
|
||||||
@@ -437,16 +438,16 @@ public sealed class PrimeOrderCalculatorAccelerator
|
|||||||
|
|
||||||
var kernels = _kernels[acceleratorIndex];
|
var kernels = _kernels[acceleratorIndex];
|
||||||
|
|
||||||
CalculateOrderKernelLauncher = kernels.CalculateOrderKernelLauncher;
|
// CalculateOrderKernelLauncher = kernels.CalculateOrderKernelLauncher;
|
||||||
CheckFactorsKernel = kernels.CheckFactorsKernel;
|
CheckFactorsKernel = kernels.CheckFactorsKernel;
|
||||||
ConvertToStandardKernelLauncher = kernels.ConvertToStandardKernelLauncher;
|
ConvertToStandardKernelLauncher = kernels.ConvertToStandardKernelLauncher;
|
||||||
HeuristicCombinedTrialDivisionKernelLauncher = kernels.HeuristicCombinedTrialDivisionKernelLauncher;
|
HeuristicCombinedTrialDivisionKernelLauncher = kernels.HeuristicCombinedTrialDivisionKernelLauncher;
|
||||||
KeepMontgomeryKernelLauncher = kernels.KeepMontgomeryKernelLauncher;
|
KeepMontgomeryKernelLauncher = kernels.KeepMontgomeryKernelLauncher;
|
||||||
PartialFactorKernelLauncher = kernels.PartialFactorKernelLauncher;
|
// PartialFactorKernelLauncher = kernels.PartialFactorKernelLauncher;
|
||||||
PollardRhoKernel = kernels.PollardRhoKernel;
|
// PollardRhoKernel = kernels.PollardRhoKernel;
|
||||||
Pow2ModKernelLauncher = kernels.Pow2ModKernelLauncher;
|
Pow2ModKernelLauncher = kernels.Pow2ModKernelLauncher;
|
||||||
Pow2ModWideKernelLauncher = kernels.Pow2ModWideKernelLauncher;
|
Pow2ModWideKernelLauncher = kernels.Pow2ModWideKernelLauncher;
|
||||||
SharesFactorKernelLauncher = kernels.SharesFactorKernelLauncher;
|
// SharesFactorKernelLauncher = kernels.SharesFactorKernelLauncher;
|
||||||
SmallPrimeFactorKernelLauncher = kernels.SmallPrimeFactorKernelLauncher;
|
SmallPrimeFactorKernelLauncher = kernels.SmallPrimeFactorKernelLauncher;
|
||||||
SmallPrimeSieveKernelLauncher = kernels.SmallPrimeSieveKernelLauncher;
|
SmallPrimeSieveKernelLauncher = kernels.SmallPrimeSieveKernelLauncher;
|
||||||
SpecialMaxKernelLauncher = kernels.SpecialMaxKernelLauncher;
|
SpecialMaxKernelLauncher = kernels.SpecialMaxKernelLauncher;
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ public sealed partial class MersenneNumberDivisorByDivisorGpuTester : IMersenneN
|
|||||||
// so the synchronization fields from the previous implementation remain commented out here.
|
// so the synchronization fields from the previous implementation remain commented out here.
|
||||||
// private readonly object _sync = new();
|
// private readonly object _sync = new();
|
||||||
private ulong _divisorLimit;
|
private ulong _divisorLimit;
|
||||||
|
private ulong _minK = 1UL;
|
||||||
// private bool _isConfigured;
|
// private bool _isConfigured;
|
||||||
|
|
||||||
private readonly ConcurrentBag<MersenneNumberDivisorByDivisorAccelerator>[] _resourcePool = [.. AcceleratorPool.Shared.Accelerators.Select(x => new ConcurrentBag<MersenneNumberDivisorByDivisorAccelerator>())];
|
private readonly ConcurrentBag<MersenneNumberDivisorByDivisorAccelerator>[] _resourcePool = [.. AcceleratorPool.Shared.Accelerators.Select(x => new ConcurrentBag<MersenneNumberDivisorByDivisorAccelerator>())];
|
||||||
@@ -36,6 +37,12 @@ public sealed partial class MersenneNumberDivisorByDivisorGpuTester : IMersenneN
|
|||||||
set => GpuBatchSize = value;
|
set => GpuBatchSize = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ulong MinK
|
||||||
|
{
|
||||||
|
get => _minK;
|
||||||
|
set => _minK = value < 1UL ? 1UL : value;
|
||||||
|
}
|
||||||
|
|
||||||
public void ConfigureFromMaxPrime(ulong maxPrime)
|
public void ConfigureFromMaxPrime(ulong maxPrime)
|
||||||
{
|
{
|
||||||
// EvenPerfectBitScanner configures the GPU tester once before scanning and never mutates the configuration afterwards,
|
// EvenPerfectBitScanner configures the GPU tester once before scanning and never mutates the configuration afterwards,
|
||||||
@@ -95,6 +102,7 @@ public sealed partial class MersenneNumberDivisorByDivisorGpuTester : IMersenneN
|
|||||||
gpu,
|
gpu,
|
||||||
prime,
|
prime,
|
||||||
allowedMax,
|
allowedMax,
|
||||||
|
_minK,
|
||||||
resources.CheckDivisorKernel,
|
resources.CheckDivisorKernel,
|
||||||
resources.DivisorDataBuffer,
|
resources.DivisorDataBuffer,
|
||||||
resources.OffsetBuffer,
|
resources.OffsetBuffer,
|
||||||
@@ -162,6 +170,7 @@ public sealed partial class MersenneNumberDivisorByDivisorGpuTester : IMersenneN
|
|||||||
PrimeOrderCalculatorAccelerator gpu,
|
PrimeOrderCalculatorAccelerator gpu,
|
||||||
ulong prime,
|
ulong prime,
|
||||||
ulong allowedMax,
|
ulong allowedMax,
|
||||||
|
ulong minK,
|
||||||
Kernel kernel,
|
Kernel kernel,
|
||||||
MemoryBuffer1D<GpuDivisorPartialData, Stride1D.Dense> divisorDataBuffer,
|
MemoryBuffer1D<GpuDivisorPartialData, Stride1D.Dense> divisorDataBuffer,
|
||||||
MemoryBuffer1D<int, Stride1D.Dense> offsetBuffer,
|
MemoryBuffer1D<int, Stride1D.Dense> offsetBuffer,
|
||||||
@@ -183,8 +192,8 @@ public sealed partial class MersenneNumberDivisorByDivisorGpuTester : IMersenneN
|
|||||||
int batchCapacity = (int)divisorDataBuffer.Length;
|
int batchCapacity = (int)divisorDataBuffer.Length;
|
||||||
bool composite = false;
|
bool composite = false;
|
||||||
bool processedAll;
|
bool processedAll;
|
||||||
processedCount = 0UL;
|
ulong processedCountLocal = 0UL;
|
||||||
lastProcessed = 0UL;
|
ulong lastProcessedLocal = 0UL;
|
||||||
var acceleratorIndex = gpu.AcceleratorIndex;
|
var acceleratorIndex = gpu.AcceleratorIndex;
|
||||||
|
|
||||||
// EvenPerfectBitScanner always configures non-empty GPU divisor buffers, so the defensive guard stays
|
// EvenPerfectBitScanner always configures non-empty GPU divisor buffers, so the defensive guard stays
|
||||||
@@ -208,11 +217,13 @@ public sealed partial class MersenneNumberDivisorByDivisorGpuTester : IMersenneN
|
|||||||
if (!hasCandidates)
|
if (!hasCandidates)
|
||||||
{
|
{
|
||||||
coveredRange = true;
|
coveredRange = true;
|
||||||
|
processedCount = processedCountLocal;
|
||||||
|
lastProcessed = lastProcessedLocal;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ulong maxK = maxK128 > ulong.MaxValue ? ulong.MaxValue : (ulong)maxK128;
|
ulong maxK = maxK128 > ulong.MaxValue ? ulong.MaxValue : (ulong)maxK128;
|
||||||
ulong remainingCount = maxK;
|
ulong startK = minK < 1UL ? 1UL : minK;
|
||||||
|
|
||||||
ulong stepValue = (ulong)twoP128;
|
ulong stepValue = (ulong)twoP128;
|
||||||
byte step10 = (byte)(stepValue % 10UL);
|
byte step10 = (byte)(stepValue % 10UL);
|
||||||
@@ -221,13 +232,6 @@ public sealed partial class MersenneNumberDivisorByDivisorGpuTester : IMersenneN
|
|||||||
byte step7 = (byte)(stepValue % 7UL);
|
byte step7 = (byte)(stepValue % 7UL);
|
||||||
byte step11 = (byte)(stepValue % 11UL);
|
byte step11 = (byte)(stepValue % 11UL);
|
||||||
|
|
||||||
UInt128 currentDivisor128 = firstDivisor128;
|
|
||||||
ulong currentDivisorValue = (ulong)currentDivisor128;
|
|
||||||
byte remainder10 = (byte)(currentDivisorValue % 10UL);
|
|
||||||
byte remainder8 = (byte)(currentDivisorValue & 7UL);
|
|
||||||
byte remainder3 = (byte)(currentDivisorValue % 3UL);
|
|
||||||
byte remainder7 = (byte)(currentDivisorValue % 7UL);
|
|
||||||
byte remainder11 = (byte)(currentDivisorValue % 11UL);
|
|
||||||
LastDigit lastDigit = (prime & 3UL) == 3UL ? LastDigit.Seven : LastDigit.One;
|
LastDigit lastDigit = (prime & 3UL) == 3UL ? LastDigit.Seven : LastDigit.One;
|
||||||
ushort decimalMask = DivisorGenerator.GetDecimalMask(lastDigit);
|
ushort decimalMask = DivisorGenerator.GetDecimalMask(lastDigit);
|
||||||
|
|
||||||
@@ -243,11 +247,6 @@ public sealed partial class MersenneNumberDivisorByDivisorGpuTester : IMersenneN
|
|||||||
Span<int> offsetSpan = offsetStorage;
|
Span<int> offsetSpan = offsetStorage;
|
||||||
Span<int> countSpan = countStorage;
|
Span<int> countSpan = countStorage;
|
||||||
Span<ulong> cycleSpan = cycleStorage;
|
Span<ulong> cycleSpan = cycleStorage;
|
||||||
ref GpuDivisorPartialData divisorDataRef = ref MemoryMarshal.GetReference(divisorDataSpan);
|
|
||||||
ref int offsetRef = ref MemoryMarshal.GetReference(offsetSpan);
|
|
||||||
ref int countRef = ref MemoryMarshal.GetReference(countSpan);
|
|
||||||
ref ulong cycleRef = ref MemoryMarshal.GetReference(cycleSpan);
|
|
||||||
ref ulong exponentRef = ref MemoryMarshal.GetReference(exponentSpan);
|
|
||||||
|
|
||||||
ArrayView1D<GpuDivisorPartialData, Stride1D.Dense> divisorDataView = divisorDataBuffer.View;
|
ArrayView1D<GpuDivisorPartialData, Stride1D.Dense> divisorDataView = divisorDataBuffer.View;
|
||||||
ArrayView1D<int, Stride1D.Dense> offsetView = offsetBuffer.View;
|
ArrayView1D<int, Stride1D.Dense> offsetView = offsetBuffer.View;
|
||||||
@@ -257,100 +256,258 @@ public sealed partial class MersenneNumberDivisorByDivisorGpuTester : IMersenneN
|
|||||||
ArrayView1D<byte, Stride1D.Dense> hitsView = hitsBuffer.View;
|
ArrayView1D<byte, Stride1D.Dense> hitsView = hitsBuffer.View;
|
||||||
ArrayView1D<int, Stride1D.Dense> hitIndexView = hitIndexBuffer.View;
|
ArrayView1D<int, Stride1D.Dense> hitIndexView = hitIndexBuffer.View;
|
||||||
Queue<MontgomeryDivisorData> divisorPool = MontgomeryDivisorDataPool.Shared;
|
Queue<MontgomeryDivisorData> divisorPool = MontgomeryDivisorDataPool.Shared;
|
||||||
while (remainingCount > 0UL && !composite)
|
static bool ProcessRange(
|
||||||
|
PrimeOrderCalculatorAccelerator gpu,
|
||||||
|
ulong prime,
|
||||||
|
UInt128 twoP128,
|
||||||
|
UInt128 allowedMax128,
|
||||||
|
byte step10,
|
||||||
|
byte step8,
|
||||||
|
byte step3,
|
||||||
|
byte step7,
|
||||||
|
byte step11,
|
||||||
|
ushort decimalMask,
|
||||||
|
ArrayView1D<GpuDivisorPartialData, Stride1D.Dense> divisorDataView,
|
||||||
|
ArrayView1D<int, Stride1D.Dense> offsetView,
|
||||||
|
ArrayView1D<int, Stride1D.Dense> countView,
|
||||||
|
ArrayView1D<ulong, Stride1D.Dense> cycleView,
|
||||||
|
ArrayView1D<ulong, Stride1D.Dense> exponentViewDevice,
|
||||||
|
ArrayView1D<byte, Stride1D.Dense> hitsView,
|
||||||
|
ArrayView1D<int, Stride1D.Dense> hitIndexView,
|
||||||
|
Span<ulong> divisorSpan,
|
||||||
|
Span<ulong> exponentSpan,
|
||||||
|
Span<GpuDivisorPartialData> divisorDataSpan,
|
||||||
|
Span<int> offsetSpan,
|
||||||
|
Span<int> countSpan,
|
||||||
|
Span<ulong> cycleSpan,
|
||||||
|
Queue<MontgomeryDivisorData> divisorPool,
|
||||||
|
int chunkCountBaseline,
|
||||||
|
int acceleratorIndex,
|
||||||
|
ref bool composite,
|
||||||
|
ref ulong processedCountLocal,
|
||||||
|
ref ulong lastProcessedLocal,
|
||||||
|
ulong rangeStartK,
|
||||||
|
ulong rangeEndK,
|
||||||
|
Kernel kernel)
|
||||||
{
|
{
|
||||||
int chunkCount = chunkCountBaseline;
|
if (rangeStartK < 1UL || rangeEndK < rangeStartK)
|
||||||
if ((ulong)chunkCount > remainingCount)
|
|
||||||
{
|
{
|
||||||
chunkCount = (int)remainingCount;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
UInt128 nextDivisor128 = currentDivisor128;
|
UInt128 startDivisor128 = (twoP128 * rangeStartK) + UInt128.One;
|
||||||
int admissibleCount = 0;
|
if (startDivisor128 > allowedMax128)
|
||||||
|
|
||||||
byte localRemainder10 = remainder10;
|
|
||||||
byte localRemainder8 = remainder8;
|
|
||||||
byte localRemainder3 = remainder3;
|
|
||||||
byte localRemainder7 = remainder7;
|
|
||||||
byte localRemainder11 = remainder11;
|
|
||||||
|
|
||||||
for (int i = 0; i < chunkCount; i++)
|
|
||||||
{
|
{
|
||||||
bool passesSmallModuli = localRemainder3 != 0 && localRemainder7 != 0 && localRemainder11 != 0;
|
return true;
|
||||||
if (passesSmallModuli && (localRemainder8 == 1 || localRemainder8 == 7) && ((decimalMask >> localRemainder10) & 1) != 0)
|
}
|
||||||
{
|
|
||||||
ulong divisorValue = (ulong)nextDivisor128;
|
|
||||||
MontgomeryDivisorData montgomeryData = divisorPool.FromModulus(divisorValue);
|
|
||||||
ulong divisorCycle = ResolveDivisorCycle(gpu, divisorValue, prime, in montgomeryData);
|
|
||||||
if (divisorCycle == prime)
|
|
||||||
{
|
|
||||||
processedCount += (ulong)(i + 1);
|
|
||||||
lastProcessed = divisorValue;
|
|
||||||
coveredRange = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
divisorPool.Return(montgomeryData);
|
UInt128 rangeLimit128 = (twoP128 * rangeEndK) + UInt128.One;
|
||||||
divisorSpan[admissibleCount] = divisorValue;
|
if (rangeLimit128 > allowedMax128)
|
||||||
divisorDataSpan[admissibleCount] = new GpuDivisorPartialData(divisorValue);
|
{
|
||||||
offsetSpan[admissibleCount] = admissibleCount;
|
rangeLimit128 = allowedMax128;
|
||||||
countSpan[admissibleCount] = 1;
|
}
|
||||||
cycleSpan[admissibleCount] = divisorCycle;
|
|
||||||
exponentSpan[admissibleCount] = prime;
|
UInt128 rangeCount128 = ((rangeLimit128 - startDivisor128) / twoP128) + UInt128.One;
|
||||||
admissibleCount++;
|
ulong rangeRemaining = rangeCount128 > ulong.MaxValue ? ulong.MaxValue : (ulong)rangeCount128;
|
||||||
|
UInt128 currentRangeDivisor128 = startDivisor128;
|
||||||
|
ulong currentRangeDivisorValue = (ulong)currentRangeDivisor128;
|
||||||
|
byte rangeRemainder10 = (byte)(currentRangeDivisorValue % 10UL);
|
||||||
|
byte rangeRemainder8 = (byte)(currentRangeDivisorValue & 7UL);
|
||||||
|
byte rangeRemainder3 = (byte)(currentRangeDivisorValue % 3UL);
|
||||||
|
byte rangeRemainder7 = (byte)(currentRangeDivisorValue % 7UL);
|
||||||
|
byte rangeRemainder11 = (byte)(currentRangeDivisorValue % 11UL);
|
||||||
|
|
||||||
|
while (rangeRemaining > 0UL && !composite)
|
||||||
|
{
|
||||||
|
int chunkCount = chunkCountBaseline;
|
||||||
|
if ((ulong)chunkCount > rangeRemaining)
|
||||||
|
{
|
||||||
|
chunkCount = (int)rangeRemaining;
|
||||||
}
|
}
|
||||||
|
|
||||||
nextDivisor128 += twoP128;
|
UInt128 nextDivisor128 = currentRangeDivisor128;
|
||||||
localRemainder10 = AddMod10(localRemainder10, step10);
|
int admissibleCount = 0;
|
||||||
localRemainder8 = AddMod8(localRemainder8, step8);
|
|
||||||
localRemainder3 = AddMod3(localRemainder3, step3);
|
byte localRemainder10 = rangeRemainder10;
|
||||||
localRemainder7 = AddMod7(localRemainder7, step7);
|
byte localRemainder8 = rangeRemainder8;
|
||||||
localRemainder11 = AddMod11(localRemainder11, step11);
|
byte localRemainder3 = rangeRemainder3;
|
||||||
|
byte localRemainder7 = rangeRemainder7;
|
||||||
|
byte localRemainder11 = rangeRemainder11;
|
||||||
|
|
||||||
|
for (int i = 0; i < chunkCount; i++)
|
||||||
|
{
|
||||||
|
bool passesSmallModuli = localRemainder3 != 0 && localRemainder7 != 0 && localRemainder11 != 0;
|
||||||
|
if (passesSmallModuli && (localRemainder8 == 1 || localRemainder8 == 7) && ((decimalMask >> localRemainder10) & 1) != 0)
|
||||||
|
{
|
||||||
|
ulong divisorValue = (ulong)nextDivisor128;
|
||||||
|
MontgomeryDivisorData montgomeryData = divisorPool.FromModulus(divisorValue);
|
||||||
|
ulong divisorCycle = ResolveDivisorCycle(gpu, divisorValue, prime, in montgomeryData);
|
||||||
|
if (divisorCycle == prime)
|
||||||
|
{
|
||||||
|
processedCountLocal += (ulong)(i + 1);
|
||||||
|
lastProcessedLocal = divisorValue;
|
||||||
|
composite = true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
divisorPool.Return(montgomeryData);
|
||||||
|
divisorSpan[admissibleCount] = divisorValue;
|
||||||
|
divisorDataSpan[admissibleCount] = new GpuDivisorPartialData(divisorValue);
|
||||||
|
offsetSpan[admissibleCount] = admissibleCount;
|
||||||
|
countSpan[admissibleCount] = 1;
|
||||||
|
cycleSpan[admissibleCount] = divisorCycle;
|
||||||
|
exponentSpan[admissibleCount] = prime;
|
||||||
|
admissibleCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
nextDivisor128 += twoP128;
|
||||||
|
localRemainder10 = AddMod10(localRemainder10, step10);
|
||||||
|
localRemainder8 = AddMod8(localRemainder8, step8);
|
||||||
|
localRemainder3 = AddMod3(localRemainder3, step3);
|
||||||
|
localRemainder7 = AddMod7(localRemainder7, step7);
|
||||||
|
localRemainder11 = AddMod11(localRemainder11, step11);
|
||||||
|
}
|
||||||
|
|
||||||
|
rangeRemainder10 = localRemainder10;
|
||||||
|
rangeRemainder8 = localRemainder8;
|
||||||
|
rangeRemainder3 = localRemainder3;
|
||||||
|
rangeRemainder7 = localRemainder7;
|
||||||
|
rangeRemainder11 = localRemainder11;
|
||||||
|
|
||||||
|
processedCountLocal += (ulong)chunkCount;
|
||||||
|
|
||||||
|
UInt128 lastDivisor128 = nextDivisor128 - twoP128;
|
||||||
|
lastProcessedLocal = (ulong)lastDivisor128;
|
||||||
|
currentRangeDivisor128 = nextDivisor128;
|
||||||
|
rangeRemaining -= (ulong)chunkCount;
|
||||||
|
|
||||||
|
if (admissibleCount == 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ref GpuDivisorPartialData divisorDataRef = ref MemoryMarshal.GetReference(divisorDataSpan);
|
||||||
|
ref int offsetRef = ref MemoryMarshal.GetReference(offsetSpan);
|
||||||
|
ref int countRef = ref MemoryMarshal.GetReference(countSpan);
|
||||||
|
ref ulong cycleRef = ref MemoryMarshal.GetReference(cycleSpan);
|
||||||
|
ref ulong exponentRef = ref MemoryMarshal.GetReference(exponentSpan);
|
||||||
|
|
||||||
|
var stream = AcceleratorStreamPool.Rent(acceleratorIndex);
|
||||||
|
divisorDataView.CopyFromCPU(stream, ref divisorDataRef, admissibleCount);
|
||||||
|
offsetView.CopyFromCPU(stream, ref offsetRef, admissibleCount);
|
||||||
|
countView.CopyFromCPU(stream, ref countRef, admissibleCount);
|
||||||
|
cycleView.CopyFromCPU(stream, ref cycleRef, admissibleCount);
|
||||||
|
exponentViewDevice.CopyFromCPU(stream, ref exponentRef, admissibleCount);
|
||||||
|
|
||||||
|
int sentinel = int.MaxValue;
|
||||||
|
hitIndexView.CopyFromCPU(stream, ref sentinel, 1);
|
||||||
|
|
||||||
|
kernel.Launch(stream, 1, new Index1D(admissibleCount), divisorDataView, offsetView, countView, exponentViewDevice, cycleView, hitsView, hitIndexView);
|
||||||
|
|
||||||
|
int firstHit = sentinel;
|
||||||
|
hitIndexView.CopyToCPU(stream, ref firstHit, 1);
|
||||||
|
stream.Synchronize();
|
||||||
|
AcceleratorStreamPool.Return(acceleratorIndex, stream);
|
||||||
|
int hitIndex = firstHit >= admissibleCount ? -1 : firstHit;
|
||||||
|
bool hitFound = hitIndex >= 0;
|
||||||
|
composite = hitFound;
|
||||||
|
int lastIndex = admissibleCount - 1;
|
||||||
|
lastProcessedLocal = hitFound ? divisorSpan[hitIndex] : divisorSpan[lastIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
remainder10 = localRemainder10;
|
return rangeRemaining == 0UL;
|
||||||
remainder8 = localRemainder8;
|
|
||||||
remainder3 = localRemainder3;
|
|
||||||
remainder7 = localRemainder7;
|
|
||||||
remainder11 = localRemainder11;
|
|
||||||
|
|
||||||
processedCount += (ulong)chunkCount;
|
|
||||||
|
|
||||||
UInt128 lastDivisor128 = nextDivisor128 - twoP128;
|
|
||||||
lastProcessed = (ulong)lastDivisor128;
|
|
||||||
currentDivisor128 = nextDivisor128;
|
|
||||||
remainingCount -= (ulong)chunkCount;
|
|
||||||
|
|
||||||
if (admissibleCount == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
var stream = AcceleratorStreamPool.Rent(acceleratorIndex);
|
|
||||||
divisorDataView.CopyFromCPU(stream, ref divisorDataRef, admissibleCount);
|
|
||||||
offsetView.CopyFromCPU(stream, ref offsetRef, admissibleCount);
|
|
||||||
countView.CopyFromCPU(stream, ref countRef, admissibleCount);
|
|
||||||
cycleView.CopyFromCPU(stream, ref cycleRef, admissibleCount);
|
|
||||||
exponentViewDevice.CopyFromCPU(stream, ref exponentRef, admissibleCount);
|
|
||||||
|
|
||||||
int sentinel = int.MaxValue;
|
|
||||||
hitIndexView.CopyFromCPU(stream, ref sentinel, 1);
|
|
||||||
|
|
||||||
kernel.Launch(stream, 1, new Index1D(admissibleCount), divisorDataView, offsetView, countView, exponentViewDevice, cycleView, hitsView, hitIndexView);
|
|
||||||
|
|
||||||
int firstHit = sentinel;
|
|
||||||
hitIndexView.CopyToCPU(stream, ref firstHit, 1);
|
|
||||||
stream.Synchronize();
|
|
||||||
AcceleratorStreamPool.Return(acceleratorIndex, stream);
|
|
||||||
int hitIndex = firstHit >= admissibleCount ? -1 : firstHit;
|
|
||||||
bool hitFound = hitIndex >= 0;
|
|
||||||
composite = hitFound;
|
|
||||||
int lastIndex = admissibleCount - 1;
|
|
||||||
lastProcessed = hitFound ? divisorSpan[hitIndex] : divisorSpan[lastIndex];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
processedAll = remainingCount == 0UL;
|
bool processedTop = true;
|
||||||
coveredRange = composite || processedAll || (currentDivisor128 > allowedMax128);
|
bool processedBottom = true;
|
||||||
|
|
||||||
|
if (startK <= maxK)
|
||||||
|
{
|
||||||
|
processedTop = ProcessRange(
|
||||||
|
gpu,
|
||||||
|
prime,
|
||||||
|
twoP128,
|
||||||
|
allowedMax128,
|
||||||
|
step10,
|
||||||
|
step8,
|
||||||
|
step3,
|
||||||
|
step7,
|
||||||
|
step11,
|
||||||
|
decimalMask,
|
||||||
|
divisorDataView,
|
||||||
|
offsetView,
|
||||||
|
countView,
|
||||||
|
cycleView,
|
||||||
|
exponentViewDevice,
|
||||||
|
hitsView,
|
||||||
|
hitIndexView,
|
||||||
|
divisorSpan,
|
||||||
|
exponentSpan,
|
||||||
|
divisorDataSpan,
|
||||||
|
offsetSpan,
|
||||||
|
countSpan,
|
||||||
|
cycleSpan,
|
||||||
|
divisorPool,
|
||||||
|
chunkCountBaseline,
|
||||||
|
acceleratorIndex,
|
||||||
|
ref composite,
|
||||||
|
ref processedCountLocal,
|
||||||
|
ref lastProcessedLocal,
|
||||||
|
startK,
|
||||||
|
maxK,
|
||||||
|
kernel);
|
||||||
|
if (composite)
|
||||||
|
{
|
||||||
|
coveredRange = true;
|
||||||
|
processedCount = processedCountLocal;
|
||||||
|
lastProcessed = lastProcessedLocal;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ulong lowerEnd = startK > 1UL ? startK - 1UL : 0UL;
|
||||||
|
if (!composite && lowerEnd >= 1UL)
|
||||||
|
{
|
||||||
|
lowerEnd = Math.Min(lowerEnd, maxK);
|
||||||
|
processedBottom = ProcessRange(
|
||||||
|
gpu,
|
||||||
|
prime,
|
||||||
|
twoP128,
|
||||||
|
allowedMax128,
|
||||||
|
step10,
|
||||||
|
step8,
|
||||||
|
step3,
|
||||||
|
step7,
|
||||||
|
step11,
|
||||||
|
decimalMask,
|
||||||
|
divisorDataView,
|
||||||
|
offsetView,
|
||||||
|
countView,
|
||||||
|
cycleView,
|
||||||
|
exponentViewDevice,
|
||||||
|
hitsView,
|
||||||
|
hitIndexView,
|
||||||
|
divisorSpan,
|
||||||
|
exponentSpan,
|
||||||
|
divisorDataSpan,
|
||||||
|
offsetSpan,
|
||||||
|
countSpan,
|
||||||
|
cycleSpan,
|
||||||
|
divisorPool,
|
||||||
|
chunkCountBaseline,
|
||||||
|
acceleratorIndex,
|
||||||
|
ref composite,
|
||||||
|
ref processedCountLocal,
|
||||||
|
ref lastProcessedLocal,
|
||||||
|
1UL,
|
||||||
|
lowerEnd,
|
||||||
|
kernel);
|
||||||
|
}
|
||||||
|
|
||||||
|
processedAll = processedTop && processedBottom;
|
||||||
|
coveredRange = composite || processedAll;
|
||||||
|
processedCount = processedCountLocal;
|
||||||
|
lastProcessed = lastProcessedLocal;
|
||||||
return composite;
|
return composite;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ public interface IMersenneNumberDivisorByDivisorTester
|
|||||||
{
|
{
|
||||||
int BatchSize { get; set; }
|
int BatchSize { get; set; }
|
||||||
|
|
||||||
|
ulong MinK { get; set; }
|
||||||
|
|
||||||
void ConfigureFromMaxPrime(ulong maxPrime);
|
void ConfigureFromMaxPrime(ulong maxPrime);
|
||||||
|
|
||||||
ulong DivisorLimit { get; }
|
ulong DivisorLimit { get; }
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ public static class PerfectNumberConstants
|
|||||||
public const int DefaultSmallPrimeFactorSlotCount = 64;
|
public const int DefaultSmallPrimeFactorSlotCount = 64;
|
||||||
public const int DefaultSpecialMaxFactorCapacity = 1024;
|
public const int DefaultSpecialMaxFactorCapacity = 1024;
|
||||||
public const ulong ExtraDivisorCycleSearchLimit = 64UL;
|
public const ulong ExtraDivisorCycleSearchLimit = 64UL;
|
||||||
public const int GpuFrequency = 4 - 1;
|
public const int GpuFrequency = 256 - 1;
|
||||||
public const int MaxQForDivisorCycles = 4_000_000;
|
public const int MaxQForDivisorCycles = 4_000_000;
|
||||||
public static readonly uint PrimesLimit = 1_000_000; //(ulong)Array.MaxLength;// 1_000_000;
|
public static readonly uint PrimesLimit = 1_000_000; //(ulong)Array.MaxLength;// 1_000_000;
|
||||||
public const int MaxOddPowersCount = 128;
|
public const int MaxOddPowersCount = 128;
|
||||||
|
|||||||
@@ -54,11 +54,11 @@ internal static partial class PrimeOrderCalculator
|
|||||||
|
|
||||||
ulong phi = prime - 1UL;
|
ulong phi = prime - 1UL;
|
||||||
|
|
||||||
if (PrimeOrderGpuHeuristics.TryCalculateOrder(gpu, prime, previousOrder, config, divisorData, out ulong gpuOrder))
|
// if (PrimeOrderGpuHeuristics.TryCalculateOrder(gpu, prime, previousOrder, config, divisorData, out ulong gpuOrder))
|
||||||
// if (IsGpuHeuristicDevice && PrimeOrderGpuHeuristics.TryCalculateOrder(gpu, prime, previousOrder, config, divisorData, out ulong gpuOrder))
|
// if (IsGpuHeuristicDevice && PrimeOrderGpuHeuristics.TryCalculateOrder(gpu, prime, previousOrder, config, divisorData, out ulong gpuOrder))
|
||||||
{
|
// {
|
||||||
return gpuOrder;
|
// return gpuOrder;
|
||||||
}
|
// }
|
||||||
|
|
||||||
PartialFactorResult phiFactors = PartialFactor(gpu, phi, config);
|
PartialFactorResult phiFactors = PartialFactor(gpu, phi, config);
|
||||||
|
|
||||||
@@ -137,7 +137,7 @@ internal static partial class PrimeOrderCalculator
|
|||||||
|
|
||||||
Span<ulong> stackBuffer = stackalloc ulong[length];
|
Span<ulong> stackBuffer = stackalloc ulong[length];
|
||||||
|
|
||||||
if (length <= 8)
|
if (length <= 7)
|
||||||
{
|
{
|
||||||
return EvaluateSpecialMaxCandidates(stackBuffer, factorSpan, phi, prime, divisorData);
|
return EvaluateSpecialMaxCandidates(stackBuffer, factorSpan, phi, prime, divisorData);
|
||||||
}
|
}
|
||||||
@@ -1106,19 +1106,19 @@ internal static partial class PrimeOrderCalculator
|
|||||||
uint limit = config.SmallFactorLimit == 0 ? uint.MaxValue : config.SmallFactorLimit;
|
uint limit = config.SmallFactorLimit == 0 ? uint.MaxValue : config.SmallFactorLimit;
|
||||||
ulong remaining = value;
|
ulong remaining = value;
|
||||||
|
|
||||||
bool gpuFactored = false;
|
// bool gpuFactored = false;
|
||||||
if (IsGpuHeuristicDevice)
|
// if (IsGpuHeuristicDevice)
|
||||||
{
|
// {
|
||||||
gpuFactored = PrimeOrderGpuHeuristics.TryPartialFactor(gpu, value, limit, primeSlots, exponentSlots, out factorCount, out remaining);
|
// gpuFactored = PrimeOrderGpuHeuristics.TryPartialFactor(gpu, value, limit, primeSlots, exponentSlots, out factorCount, out remaining);
|
||||||
}
|
// }
|
||||||
|
|
||||||
List<PendingEntry> pending = ThreadStaticPools.RentPrimeOrderPendingEntryList(2);
|
List<PendingEntry> pending = ThreadStaticPools.RentPrimeOrderPendingEntryList(2);
|
||||||
Stack<ulong>? compositeStack = null;
|
Stack<ulong>? compositeStack = null;
|
||||||
PrimeTester primeTester = PrimeTester.Exclusive;
|
PrimeTester primeTester = PrimeTester.Exclusive;
|
||||||
// HeuristicPrimeTester? tester = _tester ??= new();
|
// HeuristicPrimeTester? tester = _tester ??= new();
|
||||||
|
|
||||||
if (!gpuFactored)
|
// if (!gpuFactored)
|
||||||
{
|
// {
|
||||||
PopulateSmallPrimeFactorsCpu(
|
PopulateSmallPrimeFactorsCpu(
|
||||||
value,
|
value,
|
||||||
limit,
|
limit,
|
||||||
@@ -1128,7 +1128,7 @@ internal static partial class PrimeOrderCalculator
|
|||||||
ref exponentSlotArray,
|
ref exponentSlotArray,
|
||||||
out factorCount,
|
out factorCount,
|
||||||
out remaining);
|
out remaining);
|
||||||
}
|
// }
|
||||||
|
|
||||||
|
|
||||||
if (remaining > 1UL)
|
if (remaining > 1UL)
|
||||||
@@ -1176,7 +1176,7 @@ internal static partial class PrimeOrderCalculator
|
|||||||
// bool isPrime = HeuristicCombinedPrimeTester.IsPrimeCpu(composite);
|
// bool isPrime = HeuristicCombinedPrimeTester.IsPrimeCpu(composite);
|
||||||
// bool isPrime = HeuristicCombinedPrimeTester.IsPrimeGpu(gpu, composite);
|
// bool isPrime = HeuristicCombinedPrimeTester.IsPrimeGpu(gpu, composite);
|
||||||
bool runOnGpu = RunOnGpu();
|
bool runOnGpu = RunOnGpu();
|
||||||
bool isPrime = !runOnGpu ? HeuristicCombinedPrimeTester.IsPrimeCpu(composite) : HeuristicCombinedPrimeTester.IsPrimeGpu(gpu, composite);
|
bool isPrime = !runOnGpu ? PrimeTester.IsPrime(composite) : HeuristicCombinedPrimeTester.IsPrimeGpu(gpu, composite);
|
||||||
// bool isPrime = PrimeTester.IsPrime(composite);
|
// bool isPrime = PrimeTester.IsPrime(composite);
|
||||||
// bool isPrime = Open.Numeric.Primes.Prime.Numbers.IsPrime(composite);
|
// bool isPrime = Open.Numeric.Primes.Prime.Numbers.IsPrime(composite);
|
||||||
|
|
||||||
@@ -1244,15 +1244,15 @@ internal static partial class PrimeOrderCalculator
|
|||||||
{
|
{
|
||||||
// bool isPrime = HeuristicCombinedPrimeTester.IsPrimeCpu(composite);
|
// bool isPrime = HeuristicCombinedPrimeTester.IsPrimeCpu(composite);
|
||||||
// bool isPrime = PrimeTester.IsPrime(composite);
|
// bool isPrime = PrimeTester.IsPrime(composite);
|
||||||
// bool isPrime = HeuristicCombinedPrimeTester.IsPrimeGpu(composite);
|
bool isPrime = HeuristicCombinedPrimeTester.IsPrimeGpu(gpu, composite);
|
||||||
// bool isPrime = PrimeTester.IsPrimeInternal(composite, CancellationToken.None);
|
// bool isPrime = PrimeTester.IsPrimeInternal(composite, CancellationToken.None);
|
||||||
|
|
||||||
// Atomic.Add(ref _partialFactorPendingHits, 1UL);
|
// Atomic.Add(ref _partialFactorPendingHits, 1UL);
|
||||||
// Console.WriteLine($"Partial factor pending hits {Volatile.Read(ref _partialFactorPendingHits)}");
|
// Console.WriteLine($"Partial factor pending hits {Volatile.Read(ref _partialFactorPendingHits)}");
|
||||||
|
|
||||||
bool isPrime = RunOnGpu()
|
// bool isPrime = RunOnGpu()
|
||||||
? HeuristicCombinedPrimeTester.IsPrimeGpu(gpu, composite)
|
// ? HeuristicCombinedPrimeTester.IsPrimeGpu(gpu, composite)
|
||||||
: HeuristicCombinedPrimeTester.IsPrimeCpu(composite);
|
// : PrimeTester.IsPrime(composite);
|
||||||
// bool isPrime = PrimeTester.IsPrime(composite);
|
// bool isPrime = PrimeTester.IsPrime(composite);
|
||||||
// bool isPrime = HeuristicCombinedPrimeTester.IsPrimeGpu(gpu, composite);
|
// bool isPrime = HeuristicCombinedPrimeTester.IsPrimeGpu(gpu, composite);
|
||||||
// bool isPrime = Open.Numeric.Primes.Prime.Numbers.IsPrime(composite);
|
// bool isPrime = Open.Numeric.Primes.Prime.Numbers.IsPrime(composite);
|
||||||
@@ -1287,7 +1287,7 @@ internal static partial class PrimeOrderCalculator
|
|||||||
{
|
{
|
||||||
// cofactorIsPrime = PrimeTester.IsPrime(cofactor);
|
// cofactorIsPrime = PrimeTester.IsPrime(cofactor);
|
||||||
// cofactorIsPrime = HeuristicCombinedPrimeTester.IsPrimeCpu(cofactor);
|
// cofactorIsPrime = HeuristicCombinedPrimeTester.IsPrimeCpu(cofactor);
|
||||||
// cofactorIsPrime = HeuristicCombinedPrimeTester.IsPrimeGpu(cofactor);
|
cofactorIsPrime = HeuristicCombinedPrimeTester.IsPrimeGpu(gpu, cofactor);
|
||||||
// cofactorIsPrime = PrimeTester.IsPrimeInternal(cofactor, CancellationToken.None);
|
// cofactorIsPrime = PrimeTester.IsPrimeInternal(cofactor, CancellationToken.None);
|
||||||
|
|
||||||
// Atomic.Add(ref _partialFactorCofactorHits, 1UL);
|
// Atomic.Add(ref _partialFactorCofactorHits, 1UL);
|
||||||
@@ -1295,9 +1295,9 @@ internal static partial class PrimeOrderCalculator
|
|||||||
|
|
||||||
// cofactorIsPrime = HeuristicCombinedPrimeTester.IsPrimeGpu(gpu, cofactor);
|
// cofactorIsPrime = HeuristicCombinedPrimeTester.IsPrimeGpu(gpu, cofactor);
|
||||||
// cofactorIsPrime = PrimeTester.IsPrimeGpu(gpu, cofactor);
|
// cofactorIsPrime = PrimeTester.IsPrimeGpu(gpu, cofactor);
|
||||||
cofactorIsPrime = RunOnGpu()
|
// cofactorIsPrime = RunOnGpu()
|
||||||
? HeuristicCombinedPrimeTester.IsPrimeGpu(gpu, cofactor)
|
// ? HeuristicCombinedPrimeTester.IsPrimeGpu(gpu, cofactor)
|
||||||
: HeuristicCombinedPrimeTester.IsPrimeCpu(cofactor);
|
// : PrimeTester.IsPrime(cofactor);
|
||||||
// cofactorIsPrime = PrimeTester.IsPrime(cofactor);
|
// cofactorIsPrime = PrimeTester.IsPrime(cofactor);
|
||||||
// cofactorIsPrime = Open.Numeric.Primes.Prime.Numbers.IsPrime(cofactor);
|
// cofactorIsPrime = Open.Numeric.Primes.Prime.Numbers.IsPrime(cofactor);
|
||||||
}
|
}
|
||||||
@@ -1385,7 +1385,7 @@ internal static partial class PrimeOrderCalculator
|
|||||||
private static bool RunOnGpu()
|
private static bool RunOnGpu()
|
||||||
{
|
{
|
||||||
// return false;
|
// return false;
|
||||||
return true;
|
// return true;
|
||||||
// int cpuCount;
|
// int cpuCount;
|
||||||
|
|
||||||
// lock(_sync)
|
// lock(_sync)
|
||||||
|
|||||||
Reference in new issue
Block a user