HeuristicCombinedPrimeTesterAccelerator integrated with PrimeOrderCalculatorAccelerator.
This commit is contained in:
1 parent
183b147135
commit
f630bfb598
9 files changed
+67
-215
No files matched your search
@@ -202,7 +202,7 @@ public sealed class MersenneNumberDivisorByDivisorCpuTester : IMersenneNumberDiv
|
|||||||
remainder7 = (byte)((((divisorHigh % 7UL) * 2UL) + (divisorLow % 7UL)) % 7UL);
|
remainder7 = (byte)((((divisorHigh % 7UL) * 2UL) + (divisorLow % 7UL)) % 7UL);
|
||||||
remainder11 = (byte)((((divisorHigh % 11UL) * 5UL) + (divisorLow % 11UL)) % 11UL);
|
remainder11 = (byte)((((divisorHigh % 11UL) * 5UL) + (divisorLow % 11UL)) % 11UL);
|
||||||
|
|
||||||
var gpu = HeuristicCombinedPrimeTesterAccelerator.Rent(1);
|
var gpu = PrimeOrderCalculatorAccelerator.Rent(1);
|
||||||
|
|
||||||
while (divisor.CompareTo(limit) <= 0)
|
while (divisor.CompareTo(limit) <= 0)
|
||||||
{
|
{
|
||||||
@@ -245,7 +245,7 @@ public sealed class MersenneNumberDivisorByDivisorCpuTester : IMersenneNumberDiv
|
|||||||
// A cycle equal to the tested exponent (which is prime in this path) guarantees that the candidate divides
|
// A cycle equal to the tested exponent (which is prime in this path) guarantees that the candidate divides
|
||||||
// the corresponding Mersenne number because the order of 2 modulo the divisor is exactly p.
|
// the corresponding Mersenne number because the order of 2 modulo the divisor is exactly p.
|
||||||
processedAll = true;
|
processedAll = true;
|
||||||
HeuristicCombinedPrimeTesterAccelerator.Return(gpu);
|
PrimeOrderCalculatorAccelerator.Return(gpu);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -263,7 +263,7 @@ public sealed class MersenneNumberDivisorByDivisorCpuTester : IMersenneNumberDiv
|
|||||||
remainder11 = AddMod11(remainder11, step11);
|
remainder11 = AddMod11(remainder11, step11);
|
||||||
}
|
}
|
||||||
|
|
||||||
HeuristicCombinedPrimeTesterAccelerator.Return(gpu);
|
PrimeOrderCalculatorAccelerator.Return(gpu);
|
||||||
processedAll = true;
|
processedAll = true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -289,7 +289,7 @@ public sealed class MersenneNumberDivisorByDivisorCpuTester : IMersenneNumberDiv
|
|||||||
processedAll = false;
|
processedAll = false;
|
||||||
|
|
||||||
bool canAdvance = step <= limit;
|
bool canAdvance = step <= limit;
|
||||||
var gpu = HeuristicCombinedPrimeTesterAccelerator.Rent(1);
|
var gpu = PrimeOrderCalculatorAccelerator.Rent(1);
|
||||||
if (!canAdvance)
|
if (!canAdvance)
|
||||||
{
|
{
|
||||||
if (divisor <= limit)
|
if (divisor <= limit)
|
||||||
@@ -319,7 +319,7 @@ public sealed class MersenneNumberDivisorByDivisorCpuTester : IMersenneNumberDiv
|
|||||||
if (divisorCycle == prime)
|
if (divisorCycle == prime)
|
||||||
{
|
{
|
||||||
processedAll = true;
|
processedAll = true;
|
||||||
HeuristicCombinedPrimeTesterAccelerator.Return(gpu);
|
PrimeOrderCalculatorAccelerator.Return(gpu);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -370,7 +370,7 @@ public sealed class MersenneNumberDivisorByDivisorCpuTester : IMersenneNumberDiv
|
|||||||
if (divisorCycle == prime)
|
if (divisorCycle == prime)
|
||||||
{
|
{
|
||||||
processedAll = true;
|
processedAll = true;
|
||||||
HeuristicCombinedPrimeTesterAccelerator.Return(gpu);
|
PrimeOrderCalculatorAccelerator.Return(gpu);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,147 +0,0 @@
|
|||||||
using System.Runtime.CompilerServices;
|
|
||||||
using ILGPU;
|
|
||||||
using ILGPU.Runtime;
|
|
||||||
|
|
||||||
namespace PerfectNumbers.Core.Gpu.Accelerators;
|
|
||||||
|
|
||||||
public sealed class HeuristicCombinedPrimeTesterAccelerator
|
|
||||||
{
|
|
||||||
#region Pool
|
|
||||||
|
|
||||||
[ThreadStatic]
|
|
||||||
private static Queue<HeuristicCombinedPrimeTesterAccelerator>? Pool;
|
|
||||||
|
|
||||||
public static void WarmUp(int acceleratorIndex, AcceleratorStream stream)
|
|
||||||
{
|
|
||||||
Console.WriteLine($"Preparing heuristic accelerator {acceleratorIndex}...");
|
|
||||||
HeuristicGpuCombinedTables.WarmUp(acceleratorIndex, stream);
|
|
||||||
// _ = GpuKernelPool.GetOrAddKernels(accelerator, stream, KernelType.None);
|
|
||||||
// KernelContainer kernels = GpuKernelPool.GetOrAddKernels(accelerator, stream);
|
|
||||||
// GpuStaticTableInitializer.EnsureStaticTables(accelerator, kernels, stream);
|
|
||||||
Console.WriteLine($"Heuristic accelerator {acceleratorIndex} is ready");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static HeuristicCombinedPrimeTesterAccelerator Rent(int minBufferCapacity = 1)
|
|
||||||
{
|
|
||||||
var pool = Pool ??= new();
|
|
||||||
if (!pool.TryDequeue(out var lease))
|
|
||||||
{
|
|
||||||
lease = new HeuristicCombinedPrimeTesterAccelerator(minBufferCapacity);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
lease.EnsureCapacity(minBufferCapacity);
|
|
||||||
}
|
|
||||||
|
|
||||||
return lease;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void Return(HeuristicCombinedPrimeTesterAccelerator lease)
|
|
||||||
{
|
|
||||||
var pool = Pool ??= new();
|
|
||||||
pool.Enqueue(lease);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void DisposeAll()
|
|
||||||
{
|
|
||||||
if (Pool != null)
|
|
||||||
{
|
|
||||||
while (Pool.TryDequeue(out var lease))
|
|
||||||
{
|
|
||||||
lease.DisposeResources();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void Clear()
|
|
||||||
{
|
|
||||||
if (Pool != null)
|
|
||||||
{
|
|
||||||
var retained = new List<HeuristicCombinedPrimeTesterAccelerator>();
|
|
||||||
while (Pool.TryDequeue(out var lease))
|
|
||||||
{
|
|
||||||
lease.DisposeResources();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
public readonly HeuristicGpuCombinedDivisorTables DivisorTables;
|
|
||||||
internal readonly Context Context;
|
|
||||||
public readonly Accelerator Accelerator;
|
|
||||||
public readonly Kernel HeuristicCombinedTrialDivisionKernel;
|
|
||||||
|
|
||||||
public MemoryBuffer1D<ulong, Stride1D.Dense>? Input = null;
|
|
||||||
public MemoryBuffer1D<byte, Stride1D.Dense>? Output = null;
|
|
||||||
public MemoryBuffer1D<int, Stride1D.Dense>? HeuristicFlag = null!;
|
|
||||||
public int BufferCapacity;
|
|
||||||
|
|
||||||
private HeuristicGpuCombinedTables _sharedTables;
|
|
||||||
public MemoryBuffer1D<ulong, Stride1D.Dense> HeuristicCombinedDivisorsEnding1 => _sharedTables.HeuristicCombinedDivisorsEnding1;
|
|
||||||
public MemoryBuffer1D<ulong, Stride1D.Dense> HeuristicCombinedDivisorSquaresEnding1 => _sharedTables.HeuristicCombinedDivisorSquaresEnding1;
|
|
||||||
public MemoryBuffer1D<ulong, Stride1D.Dense> HeuristicCombinedDivisorsEnding3 => _sharedTables.HeuristicCombinedDivisorsEnding3;
|
|
||||||
public MemoryBuffer1D<ulong, Stride1D.Dense> HeuristicCombinedDivisorSquaresEnding3 => _sharedTables.HeuristicCombinedDivisorSquaresEnding3;
|
|
||||||
public MemoryBuffer1D<ulong, Stride1D.Dense> HeuristicCombinedDivisorsEnding7 => _sharedTables.HeuristicCombinedDivisorsEnding7;
|
|
||||||
public MemoryBuffer1D<ulong, Stride1D.Dense> HeuristicCombinedDivisorSquaresEnding7 => _sharedTables.HeuristicCombinedDivisorSquaresEnding7;
|
|
||||||
public MemoryBuffer1D<ulong, Stride1D.Dense> HeuristicCombinedDivisorsEnding9 => _sharedTables.HeuristicCombinedDivisorsEnding9;
|
|
||||||
public MemoryBuffer1D<ulong, Stride1D.Dense> HeuristicCombinedDivisorSquaresEnding9 => _sharedTables.HeuristicCombinedDivisorSquaresEnding9;
|
|
||||||
|
|
||||||
private static readonly Accelerator[] _accelerators = AcceleratorPool.Shared.Accelerators;
|
|
||||||
internal readonly int AcceleratorIndex;
|
|
||||||
|
|
||||||
public HeuristicCombinedPrimeTesterAccelerator(int minBufferCapacity)
|
|
||||||
{
|
|
||||||
var acceleratorIndex = AcceleratorPool.Shared.Rent();
|
|
||||||
AcceleratorIndex = acceleratorIndex;
|
|
||||||
Accelerator accelerator = _accelerators[acceleratorIndex];
|
|
||||||
Context = accelerator.Context;
|
|
||||||
|
|
||||||
Accelerator = accelerator;
|
|
||||||
EnsureCapacity(minBufferCapacity);
|
|
||||||
|
|
||||||
HeuristicCombinedTrialDivisionKernel = KernelUtil.GetKernel(accelerator.LoadAutoGroupedStreamKernel<Index1D, byte, ArrayView<int>, ulong, ulong, HeuristicGpuCombinedDivisorTables>(PrimeTesterKernels.HeuristicTrialCombinedDivisionKernel));
|
|
||||||
|
|
||||||
AcceleratorStream stream = AcceleratorStreamPool.Rent(acceleratorIndex);
|
|
||||||
|
|
||||||
// GpuStaticTableInitializer.EnsureStaticTables(accelerator, kernels, stream);
|
|
||||||
|
|
||||||
_sharedTables = HeuristicGpuCombinedTables.GetStaticTables(acceleratorIndex);
|
|
||||||
DivisorTables = _sharedTables.CreateHeuristicDivisorTables();
|
|
||||||
|
|
||||||
stream.Synchronize();
|
|
||||||
AcceleratorStreamPool.Return(acceleratorIndex, stream);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void EnsureCapacity(int minCapacity)
|
|
||||||
{
|
|
||||||
if (minCapacity <= BufferCapacity)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Input?.Dispose();
|
|
||||||
Output?.Dispose();
|
|
||||||
HeuristicFlag?.Dispose();
|
|
||||||
|
|
||||||
Input = Accelerator.Allocate1D<ulong>(minCapacity);
|
|
||||||
Output = Accelerator.Allocate1D<byte>(minCapacity);
|
|
||||||
HeuristicFlag = Accelerator.Allocate1D<int>(minCapacity);
|
|
||||||
|
|
||||||
BufferCapacity = minCapacity;
|
|
||||||
}
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public void Return() => Return(this);
|
|
||||||
|
|
||||||
public void DisposeResources()
|
|
||||||
{
|
|
||||||
Input?.Dispose();
|
|
||||||
Output?.Dispose();
|
|
||||||
HeuristicFlag?.Dispose();
|
|
||||||
// ReleaseSharedTables(_sharedTables);
|
|
||||||
// These resources are shared between GPU leases
|
|
||||||
// Accelerator.Dispose();
|
|
||||||
// AcceleratorContext.Dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -68,7 +68,7 @@ public sealed class PrimeOrderCalculatorAccelerator
|
|||||||
// Don't take this from the pool as quick uploads of data to the accelerator consumes much of GPU's memory and throws.
|
// Don't take this from the pool as quick uploads of data to the accelerator consumes much of GPU's memory and throws.
|
||||||
AcceleratorStream stream = accelerator.CreateStream();
|
AcceleratorStream stream = accelerator.CreateStream();
|
||||||
LastDigitGpuTables.WarmUp(i, stream);
|
LastDigitGpuTables.WarmUp(i, stream);
|
||||||
HeuristicCombinedPrimeTesterAccelerator.WarmUp(i, stream);
|
HeuristicGpuCombinedTables.WarmUp(i, stream);
|
||||||
// SharedHeuristicGpuTables.EnsureStaticTables(accelerator, stream);
|
// SharedHeuristicGpuTables.EnsureStaticTables(accelerator, stream);
|
||||||
// _ = GpuKernelPool.GetOrAddKernels(accelerator, stream, KernelType.None);
|
// _ = GpuKernelPool.GetOrAddKernels(accelerator, stream, KernelType.None);
|
||||||
// KernelContainer kernels = GpuKernelPool.GetOrAddKernels(accelerator, stream);
|
// KernelContainer kernels = GpuKernelPool.GetOrAddKernels(accelerator, stream);
|
||||||
@@ -109,12 +109,16 @@ public sealed class PrimeOrderCalculatorAccelerator
|
|||||||
public MemoryBuffer1D<ulong, Stride1D.Dense> SpecialMaxFactors;
|
public MemoryBuffer1D<ulong, Stride1D.Dense> SpecialMaxFactors;
|
||||||
public readonly MemoryBuffer1D<ulong, Stride1D.Dense> SpecialMaxResult;
|
public readonly MemoryBuffer1D<ulong, Stride1D.Dense> SpecialMaxResult;
|
||||||
|
|
||||||
|
public readonly HeuristicGpuCombinedDivisorTables DivisorTables;
|
||||||
|
|
||||||
public readonly Kernel SmallPrimeSieveKernel;
|
public readonly Kernel SmallPrimeSieveKernel;
|
||||||
public readonly Kernel CheckFactorsKernel;
|
public readonly Kernel CheckFactorsKernel;
|
||||||
public readonly Kernel ConvertToStandardKernel;
|
public readonly Kernel ConvertToStandardKernel;
|
||||||
|
public readonly Kernel HeuristicCombinedTrialDivisionKernel;
|
||||||
public readonly Kernel KeepMontgomeryKernel;
|
public readonly Kernel KeepMontgomeryKernel;
|
||||||
public readonly Kernel PollardRhoKernel;
|
public readonly Kernel PollardRhoKernel;
|
||||||
public readonly Kernel Pow2ModWideKernel;
|
public readonly Kernel Pow2ModWideKernel;
|
||||||
|
|
||||||
public Kernel SharesFactorKernel;
|
public Kernel SharesFactorKernel;
|
||||||
|
|
||||||
|
|
||||||
@@ -186,16 +190,19 @@ public sealed class PrimeOrderCalculatorAccelerator
|
|||||||
SpecialMaxCandidates = accelerator.Allocate1D<ulong>(specialMaxFactorCapacity);
|
SpecialMaxCandidates = accelerator.Allocate1D<ulong>(specialMaxFactorCapacity);
|
||||||
SpecialMaxResult = accelerator.Allocate1D<ulong>(1);
|
SpecialMaxResult = accelerator.Allocate1D<ulong>(1);
|
||||||
|
|
||||||
var sharedTables = LastDigitGpuTables.EnsureStaticTables(acceleratorIndex);
|
var lastDigitSharedTables = LastDigitGpuTables.EnsureStaticTables(acceleratorIndex);
|
||||||
|
|
||||||
DevicePrimesLastOne = sharedTables.DevicePrimesLastOne;
|
DevicePrimesLastOne = lastDigitSharedTables.DevicePrimesLastOne;
|
||||||
DevicePrimesLastSeven = sharedTables.DevicePrimesLastSeven;
|
DevicePrimesLastSeven = lastDigitSharedTables.DevicePrimesLastSeven;
|
||||||
DevicePrimesLastThree = sharedTables.DevicePrimesLastThree;
|
DevicePrimesLastThree = lastDigitSharedTables.DevicePrimesLastThree;
|
||||||
DevicePrimesLastNine = sharedTables.DevicePrimesLastNine;
|
DevicePrimesLastNine = lastDigitSharedTables.DevicePrimesLastNine;
|
||||||
DevicePrimesPow2LastOne = sharedTables.DevicePrimesPow2LastOne;
|
DevicePrimesPow2LastOne = lastDigitSharedTables.DevicePrimesPow2LastOne;
|
||||||
DevicePrimesPow2LastSeven = sharedTables.DevicePrimesPow2LastSeven;
|
DevicePrimesPow2LastSeven = lastDigitSharedTables.DevicePrimesPow2LastSeven;
|
||||||
DevicePrimesPow2LastThree = sharedTables.DevicePrimesPow2LastThree;
|
DevicePrimesPow2LastThree = lastDigitSharedTables.DevicePrimesPow2LastThree;
|
||||||
DevicePrimesPow2LastNine = sharedTables.DevicePrimesPow2LastNine;
|
DevicePrimesPow2LastNine = lastDigitSharedTables.DevicePrimesPow2LastNine;
|
||||||
|
|
||||||
|
var heuristicSharedTables = HeuristicGpuCombinedTables.GetStaticTables(acceleratorIndex);
|
||||||
|
DivisorTables = heuristicSharedTables.CreateHeuristicDivisorTables();
|
||||||
|
|
||||||
var checkFactorsKernel = accelerator.LoadStreamKernel<int, ulong, ArrayView1D<KeyValuePair<ulong, int>, Stride1D.Dense>, MontgomeryDivisorData, ArrayView1D<ulong, Stride1D.Dense>>(PrimeOrderGpuHeuristics.CheckFactorsKernel);
|
var checkFactorsKernel = accelerator.LoadStreamKernel<int, ulong, ArrayView1D<KeyValuePair<ulong, int>, Stride1D.Dense>, MontgomeryDivisorData, ArrayView1D<ulong, Stride1D.Dense>>(PrimeOrderGpuHeuristics.CheckFactorsKernel);
|
||||||
CheckFactorsKernel = KernelUtil.GetKernel(checkFactorsKernel);
|
CheckFactorsKernel = KernelUtil.GetKernel(checkFactorsKernel);
|
||||||
@@ -203,6 +210,8 @@ public sealed class PrimeOrderCalculatorAccelerator
|
|||||||
var convertKernel = accelerator.LoadAutoGroupedStreamKernel<Index1D, ArrayView1D<ulong, Stride1D.Dense>, MontgomeryDivisorData, ArrayView1D<ulong, Stride1D.Dense>>(Pow2MontgomeryKernels.Pow2MontgomeryKernelConvertToStandard);
|
var convertKernel = accelerator.LoadAutoGroupedStreamKernel<Index1D, ArrayView1D<ulong, Stride1D.Dense>, MontgomeryDivisorData, ArrayView1D<ulong, Stride1D.Dense>>(Pow2MontgomeryKernels.Pow2MontgomeryKernelConvertToStandard);
|
||||||
ConvertToStandardKernel = KernelUtil.GetKernel(convertKernel);
|
ConvertToStandardKernel = KernelUtil.GetKernel(convertKernel);
|
||||||
|
|
||||||
|
HeuristicCombinedTrialDivisionKernel = KernelUtil.GetKernel(accelerator.LoadAutoGroupedStreamKernel<Index1D, byte, ArrayView<int>, ulong, ulong, HeuristicGpuCombinedDivisorTables>(PrimeTesterKernels.HeuristicTrialCombinedDivisionKernel));
|
||||||
|
|
||||||
var keepKernel = accelerator.LoadAutoGroupedStreamKernel<Index1D, ArrayView1D<ulong, Stride1D.Dense>, MontgomeryDivisorData, ArrayView1D<ulong, Stride1D.Dense>>(Pow2MontgomeryKernels.Pow2MontgomeryKernelKeepMontgomery);
|
var keepKernel = accelerator.LoadAutoGroupedStreamKernel<Index1D, ArrayView1D<ulong, Stride1D.Dense>, MontgomeryDivisorData, ArrayView1D<ulong, Stride1D.Dense>>(Pow2MontgomeryKernels.Pow2MontgomeryKernelKeepMontgomery);
|
||||||
KeepMontgomeryKernel = KernelUtil.GetKernel(keepKernel);
|
KeepMontgomeryKernel = KernelUtil.GetKernel(keepKernel);
|
||||||
|
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ public sealed class MersenneNumberDivisorByDivisorGpuTester : IMersenneNumberDiv
|
|||||||
// GpuPrimeWorkLimiter();
|
// GpuPrimeWorkLimiter();
|
||||||
// int acceleratorIndex = AcceleratorPool.Shared.Rent();
|
// int acceleratorIndex = AcceleratorPool.Shared.Rent();
|
||||||
// var accelerator = _accelerators[acceleratorIndex];
|
// var accelerator = _accelerators[acceleratorIndex];
|
||||||
var gpu = HeuristicCombinedPrimeTesterAccelerator.Rent(batchCapacity);
|
var gpu = PrimeOrderCalculatorAccelerator.Rent(batchCapacity);
|
||||||
var acceleratorIndex = gpu.AcceleratorIndex;
|
var acceleratorIndex = gpu.AcceleratorIndex;
|
||||||
var accelerator = gpu.Accelerator;
|
var accelerator = gpu.Accelerator;
|
||||||
var stream = AcceleratorStreamPool.Rent(acceleratorIndex);
|
var stream = AcceleratorStreamPool.Rent(acceleratorIndex);
|
||||||
@@ -144,7 +144,7 @@ public sealed class MersenneNumberDivisorByDivisorGpuTester : IMersenneNumberDiv
|
|||||||
|
|
||||||
AcceleratorStreamPool.Return(acceleratorIndex, stream);
|
AcceleratorStreamPool.Return(acceleratorIndex, stream);
|
||||||
ReturnBatchResources(resources);
|
ReturnBatchResources(resources);
|
||||||
HeuristicCombinedPrimeTesterAccelerator.Return(gpu);
|
PrimeOrderCalculatorAccelerator.Return(gpu);
|
||||||
// Monitor.Exit(gpuLease.ExecutionLock);
|
// Monitor.Exit(gpuLease.ExecutionLock);
|
||||||
// GpuPrimeWorkLimiter.Release();
|
// GpuPrimeWorkLimiter.Release();
|
||||||
|
|
||||||
@@ -188,7 +188,7 @@ public sealed class MersenneNumberDivisorByDivisorGpuTester : IMersenneNumberDiv
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static bool CheckDivisors(
|
private static bool CheckDivisors(
|
||||||
HeuristicCombinedPrimeTesterAccelerator gpu,
|
PrimeOrderCalculatorAccelerator gpu,
|
||||||
ulong prime,
|
ulong prime,
|
||||||
ulong allowedMax,
|
ulong allowedMax,
|
||||||
Action<AcceleratorStream, Index1D, ArrayView<GpuDivisorPartialData>, ArrayView<int>, ArrayView<int>, ArrayView<ulong>, ArrayView<ulong>, ArrayView<byte>, ArrayView<int>> kernel,
|
Action<AcceleratorStream, Index1D, ArrayView<GpuDivisorPartialData>, ArrayView<int>, ArrayView<int>, ArrayView<ulong>, ArrayView<ulong>, ArrayView<byte>, ArrayView<int>> kernel,
|
||||||
@@ -382,7 +382,7 @@ public sealed class MersenneNumberDivisorByDivisorGpuTester : IMersenneNumberDiv
|
|||||||
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
private static ulong ResolveDivisorCycle(HeuristicCombinedPrimeTesterAccelerator gpu, ulong divisor, ulong prime, in MontgomeryDivisorData divisorData)
|
private static ulong ResolveDivisorCycle(PrimeOrderCalculatorAccelerator gpu, ulong divisor, ulong prime, in MontgomeryDivisorData divisorData)
|
||||||
{
|
{
|
||||||
if (!MersenneDivisorCycles.TryCalculateCycleLengthForExponentCpu(gpu, divisor, prime, divisorData, out ulong computedCycle, out bool primeOrderFailed) || computedCycle == 0UL)
|
if (!MersenneDivisorCycles.TryCalculateCycleLengthForExponentCpu(gpu, divisor, prime, divisorData, out ulong computedCycle, out bool primeOrderFailed) || computedCycle == 0UL)
|
||||||
{
|
{
|
||||||
@@ -505,7 +505,7 @@ public sealed class MersenneNumberDivisorByDivisorGpuTester : IMersenneNumberDiv
|
|||||||
private static readonly Accelerator[] _accelerators = AcceleratorPool.Shared.Accelerators;
|
private static readonly Accelerator[] _accelerators = AcceleratorPool.Shared.Accelerators;
|
||||||
|
|
||||||
private readonly MersenneNumberDivisorByDivisorGpuTester _owner;
|
private readonly MersenneNumberDivisorByDivisorGpuTester _owner;
|
||||||
private readonly HeuristicCombinedPrimeTesterAccelerator _primeTesterAccelerator;
|
private readonly PrimeOrderCalculatorAccelerator _primeTesterAccelerator;
|
||||||
private readonly Accelerator _accelerator;
|
private readonly Accelerator _accelerator;
|
||||||
private readonly AcceleratorStream _stream;
|
private readonly AcceleratorStream _stream;
|
||||||
private Action<AcceleratorStream, Index1D, ArrayView<GpuDivisorPartialData>, ArrayView<int>, ArrayView<int>, ArrayView<ulong>, ArrayView<ulong>, ArrayView<byte>, ArrayView<int>> _kernel = null!;
|
private Action<AcceleratorStream, Index1D, ArrayView<GpuDivisorPartialData>, ArrayView<int>, ArrayView<int>, ArrayView<ulong>, ArrayView<ulong>, ArrayView<byte>, ArrayView<int>> _kernel = null!;
|
||||||
@@ -524,7 +524,7 @@ public sealed class MersenneNumberDivisorByDivisorGpuTester : IMersenneNumberDiv
|
|||||||
{
|
{
|
||||||
_owner = owner;
|
_owner = owner;
|
||||||
// GpuPrimeWorkLimiter.Acquire();
|
// GpuPrimeWorkLimiter.Acquire();
|
||||||
_primeTesterAccelerator = HeuristicCombinedPrimeTesterAccelerator.Rent();
|
_primeTesterAccelerator = PrimeOrderCalculatorAccelerator.Rent(1);
|
||||||
Accelerator accelerator = _primeTesterAccelerator.Accelerator;
|
Accelerator accelerator = _primeTesterAccelerator.Accelerator;
|
||||||
_accelerator = accelerator;
|
_accelerator = accelerator;
|
||||||
_stream = accelerator.CreateStream();
|
_stream = accelerator.CreateStream();
|
||||||
|
|||||||
@@ -173,20 +173,20 @@ public sealed class HeuristicCombinedPrimeTester
|
|||||||
{
|
{
|
||||||
byte nMod10 = (byte)n.Mod10();
|
byte nMod10 = (byte)n.Mod10();
|
||||||
ulong maxDivisorSquare = ComputeHeuristicDivisorSquareLimit(n);
|
ulong maxDivisorSquare = ComputeHeuristicDivisorSquareLimit(n);
|
||||||
var gpu = HeuristicCombinedPrimeTesterAccelerator.Rent(1);
|
var gpu = PrimeOrderCalculatorAccelerator.Rent(1);
|
||||||
bool isPrime = IsPrimeGpu(gpu, n, maxDivisorSquare, nMod10);
|
bool isPrime = IsPrimeGpu(gpu, n, maxDivisorSquare, nMod10);
|
||||||
HeuristicCombinedPrimeTesterAccelerator.Return(gpu);
|
PrimeOrderCalculatorAccelerator.Return(gpu);
|
||||||
return isPrime;
|
return isPrime;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool IsPrimeGpu(HeuristicCombinedPrimeTesterAccelerator gpu, ulong n)
|
public static bool IsPrimeGpu(PrimeOrderCalculatorAccelerator gpu, ulong n)
|
||||||
{
|
{
|
||||||
byte nMod10 = (byte)n.Mod10();
|
byte nMod10 = (byte)n.Mod10();
|
||||||
ulong maxDivisorSquare = ComputeHeuristicDivisorSquareLimit(n);
|
ulong maxDivisorSquare = ComputeHeuristicDivisorSquareLimit(n);
|
||||||
return IsPrimeGpu(gpu, n, maxDivisorSquare, nMod10);
|
return IsPrimeGpu(gpu, n, maxDivisorSquare, nMod10);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool IsPrimeGpu(HeuristicCombinedPrimeTesterAccelerator gpu, ulong n, ulong maxDivisorSquare, byte nMod10)
|
public static bool IsPrimeGpu(PrimeOrderCalculatorAccelerator gpu, ulong n, ulong maxDivisorSquare, byte nMod10)
|
||||||
{
|
{
|
||||||
// TODO: Is this condition ever met on the execution path in EvenPerfectBitScanner?
|
// TODO: Is this condition ever met on the execution path in EvenPerfectBitScanner?
|
||||||
if (maxDivisorSquare < 9UL)
|
if (maxDivisorSquare < 9UL)
|
||||||
@@ -233,10 +233,8 @@ public sealed class HeuristicCombinedPrimeTester
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
private static bool HeuristicTrialDivisionGpuDetectsDivisor(HeuristicCombinedPrimeTesterAccelerator gpu, ulong n, ulong maxDivisorSquare, byte nMod10)
|
private static bool HeuristicTrialDivisionGpuDetectsDivisor(PrimeOrderCalculatorAccelerator gpu, ulong n, ulong maxDivisorSquare, byte nMod10)
|
||||||
{
|
{
|
||||||
// GpuPrimeWorkLimiter.Acquire();
|
|
||||||
// var gpu = HeuristicCombinedPrimeTesterAccelerator.Rent(1);
|
|
||||||
var acceleratorIndex = gpu.AcceleratorIndex;
|
var acceleratorIndex = gpu.AcceleratorIndex;
|
||||||
var stream = AcceleratorStreamPool.Rent(acceleratorIndex);
|
var stream = AcceleratorStreamPool.Rent(acceleratorIndex);
|
||||||
var kernel = gpu.HeuristicCombinedTrialDivisionKernel;
|
var kernel = gpu.HeuristicCombinedTrialDivisionKernel;
|
||||||
@@ -264,7 +262,6 @@ public sealed class HeuristicCombinedPrimeTester
|
|||||||
// GpuPrimeWorkLimiter.Release();
|
// GpuPrimeWorkLimiter.Release();
|
||||||
|
|
||||||
compositeDetected = compositeFlag != 0;
|
compositeDetected = compositeFlag != 0;
|
||||||
HeuristicCombinedPrimeTesterAccelerator.Return(gpu);
|
|
||||||
return compositeDetected;
|
return compositeDetected;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -499,7 +496,7 @@ public sealed class HeuristicCombinedPrimeTester
|
|||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
internal static ulong ResolveHeuristicCycleLength(
|
internal static ulong ResolveHeuristicCycleLength(
|
||||||
HeuristicCombinedPrimeTesterAccelerator gpu,
|
PrimeOrderCalculatorAccelerator gpu,
|
||||||
ulong exponent,
|
ulong exponent,
|
||||||
in HeuristicDivisorPreparation preparation,
|
in HeuristicDivisorPreparation preparation,
|
||||||
out bool cycleFromHint,
|
out bool cycleFromHint,
|
||||||
|
|||||||
@@ -243,7 +243,7 @@ public sealed class HeuristicPrimeTester
|
|||||||
private bool HeuristicTrialDivisionGpuDetectsDivisor(ulong n, ulong maxDivisorSquare, byte nMod10)
|
private bool HeuristicTrialDivisionGpuDetectsDivisor(ulong n, ulong maxDivisorSquare, byte nMod10)
|
||||||
{
|
{
|
||||||
// GpuPrimeWorkLimiter.Acquire();
|
// GpuPrimeWorkLimiter.Acquire();
|
||||||
var gpu = HeuristicCombinedPrimeTesterAccelerator.Rent(1);
|
var gpu = PrimeOrderCalculatorAccelerator.Rent(1);
|
||||||
int acceleratorIndex = gpu.AcceleratorIndex;
|
int acceleratorIndex = gpu.AcceleratorIndex;
|
||||||
var stream = AcceleratorStreamPool.Rent(acceleratorIndex);
|
var stream = AcceleratorStreamPool.Rent(acceleratorIndex);
|
||||||
var kernel = gpu.HeuristicCombinedTrialDivisionKernel;
|
var kernel = gpu.HeuristicCombinedTrialDivisionKernel;
|
||||||
@@ -316,7 +316,7 @@ public sealed class HeuristicPrimeTester
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
AcceleratorStreamPool.Return(acceleratorIndex, stream);
|
AcceleratorStreamPool.Return(acceleratorIndex, stream);
|
||||||
gpu.Return();
|
PrimeOrderCalculatorAccelerator.Return(gpu);
|
||||||
// GpuPrimeWorkLimiter.Release();
|
// GpuPrimeWorkLimiter.Release();
|
||||||
return compositeDetected;
|
return compositeDetected;
|
||||||
}
|
}
|
||||||
@@ -466,7 +466,7 @@ public sealed class HeuristicPrimeTester
|
|||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
internal static ulong ResolveHeuristicCycleLength(
|
internal static ulong ResolveHeuristicCycleLength(
|
||||||
HeuristicCombinedPrimeTesterAccelerator gpu,
|
PrimeOrderCalculatorAccelerator gpu,
|
||||||
ulong exponent,
|
ulong exponent,
|
||||||
in HeuristicDivisorPreparation preparation,
|
in HeuristicDivisorPreparation preparation,
|
||||||
out bool cycleFromHint,
|
out bool cycleFromHint,
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ public class MersenneDivisorCycles
|
|||||||
return _smallCycles!;
|
return _smallCycles!;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool CycleEqualsExponent(HeuristicCombinedPrimeTesterAccelerator gpu, ulong divisor, in MontgomeryDivisorData divisorData, ulong exponent)
|
public static bool CycleEqualsExponent(PrimeOrderCalculatorAccelerator gpu, ulong divisor, in MontgomeryDivisorData divisorData, ulong exponent)
|
||||||
{
|
{
|
||||||
if (CycleEqualsExponentForMersenneCandidate(divisor, divisorData, exponent))
|
if (CycleEqualsExponentForMersenneCandidate(divisor, divisorData, exponent))
|
||||||
{
|
{
|
||||||
@@ -260,7 +260,7 @@ public class MersenneDivisorCycles
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static bool TryCalculateCycleLengthForExponentCpu(
|
public static bool TryCalculateCycleLengthForExponentCpu(
|
||||||
HeuristicCombinedPrimeTesterAccelerator gpu,
|
PrimeOrderCalculatorAccelerator gpu,
|
||||||
ulong divisor,
|
ulong divisor,
|
||||||
ulong exponent,
|
ulong exponent,
|
||||||
in MontgomeryDivisorData divisorData,
|
in MontgomeryDivisorData divisorData,
|
||||||
@@ -345,7 +345,7 @@ public class MersenneDivisorCycles
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static bool AccumulateFactors(
|
private static bool AccumulateFactors(
|
||||||
HeuristicCombinedPrimeTesterAccelerator gpu,
|
PrimeOrderCalculatorAccelerator gpu,
|
||||||
ulong value,
|
ulong value,
|
||||||
Dictionary<ulong, int> counts)
|
Dictionary<ulong, int> counts)
|
||||||
{
|
{
|
||||||
@@ -377,7 +377,7 @@ public class MersenneDivisorCycles
|
|||||||
// private static ulong _tryFactorIntoCountsInternalHits;
|
// private static ulong _tryFactorIntoCountsInternalHits;
|
||||||
// private static ulong _tryCalculateCycleLengthHeuristicHits;
|
// private static ulong _tryCalculateCycleLengthHeuristicHits;
|
||||||
|
|
||||||
private static bool TryFactorIntoCountsInternal(HeuristicCombinedPrimeTesterAccelerator gpu, ulong value, Dictionary<ulong, int> counts)
|
private static bool TryFactorIntoCountsInternal(PrimeOrderCalculatorAccelerator gpu, ulong value, Dictionary<ulong, int> counts)
|
||||||
{
|
{
|
||||||
// The EvenPerfectBitScanner only requests factors for values >= 2 here. Leave the guard documented without executing it.
|
// The EvenPerfectBitScanner only requests factors for values >= 2 here. Leave the guard documented without executing it.
|
||||||
// if (value <= 1UL)
|
// if (value <= 1UL)
|
||||||
|
|||||||
@@ -55,39 +55,34 @@ internal static partial class PrimeOrderCalculator
|
|||||||
ulong phi = prime - 1UL;
|
ulong phi = prime - 1UL;
|
||||||
|
|
||||||
PrimeOrderCalculatorAccelerator gpu = PrimeOrderCalculatorAccelerator.Rent(1);
|
PrimeOrderCalculatorAccelerator gpu = PrimeOrderCalculatorAccelerator.Rent(1);
|
||||||
HeuristicCombinedPrimeTesterAccelerator gpu2 = HeuristicCombinedPrimeTesterAccelerator.Rent(1);
|
|
||||||
if (IsGpuHeuristicDevice && PrimeOrderGpuHeuristics.TryCalculateOrder(prime, previousOrder, config, divisorData, out ulong gpuOrder))
|
if (IsGpuHeuristicDevice && PrimeOrderGpuHeuristics.TryCalculateOrder(prime, previousOrder, config, divisorData, out ulong gpuOrder))
|
||||||
{
|
{
|
||||||
PrimeOrderCalculatorAccelerator.Return(gpu);
|
PrimeOrderCalculatorAccelerator.Return(gpu);
|
||||||
HeuristicCombinedPrimeTesterAccelerator.Return(gpu2);
|
|
||||||
return gpuOrder;
|
return gpuOrder;
|
||||||
}
|
}
|
||||||
|
|
||||||
PartialFactorResult phiFactors = PartialFactor(gpu, gpu2, phi, config);
|
PartialFactorResult phiFactors = PartialFactor(gpu, phi, config);
|
||||||
|
|
||||||
ulong result;
|
ulong result;
|
||||||
if (phiFactors.Factors is null)
|
if (phiFactors.Factors is null)
|
||||||
{
|
{
|
||||||
result = prime <= PerfectNumberConstants.MaxQForDivisorCycles
|
result = prime <= PerfectNumberConstants.MaxQForDivisorCycles
|
||||||
? CalculateByFactorizationGpu(gpu, gpu2, prime, divisorData)
|
? CalculateByFactorizationGpu(gpu, prime, divisorData)
|
||||||
: CalculateByFactorizationCpu(gpu, gpu2, prime, divisorData);
|
: CalculateByFactorizationCpu(gpu, prime, divisorData);
|
||||||
|
|
||||||
phiFactors.Dispose();
|
phiFactors.Dispose();
|
||||||
PrimeOrderCalculatorAccelerator.Return(gpu);
|
PrimeOrderCalculatorAccelerator.Return(gpu);
|
||||||
HeuristicCombinedPrimeTesterAccelerator.Return(gpu2);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = RunHeuristicPipelineCpu(gpu, gpu2, prime, previousOrder, config, divisorData, phi, phiFactors);
|
result = RunHeuristicPipelineCpu(gpu, prime, previousOrder, config, divisorData, phi, phiFactors);
|
||||||
phiFactors.Dispose();
|
phiFactors.Dispose();
|
||||||
PrimeOrderCalculatorAccelerator.Return(gpu);
|
PrimeOrderCalculatorAccelerator.Return(gpu);
|
||||||
HeuristicCombinedPrimeTesterAccelerator.Return(gpu2);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ulong RunHeuristicPipelineCpu(
|
private static ulong RunHeuristicPipelineCpu(
|
||||||
PrimeOrderCalculatorAccelerator gpu,
|
PrimeOrderCalculatorAccelerator gpu,
|
||||||
HeuristicCombinedPrimeTesterAccelerator gpu2,
|
|
||||||
ulong prime,
|
ulong prime,
|
||||||
ulong? previousOrder,
|
ulong? previousOrder,
|
||||||
in PrimeOrderSearchConfig config,
|
in PrimeOrderSearchConfig config,
|
||||||
@@ -104,7 +99,7 @@ internal static partial class PrimeOrderCalculator
|
|||||||
ulong candidateOrder = InitializeStartingOrderCpu(gpu, prime, phi, divisorData);
|
ulong candidateOrder = InitializeStartingOrderCpu(gpu, prime, phi, divisorData);
|
||||||
candidateOrder = ExponentLoweringCpu(candidateOrder, prime, phiFactors, divisorData);
|
candidateOrder = ExponentLoweringCpu(candidateOrder, prime, phiFactors, divisorData);
|
||||||
|
|
||||||
if (TryConfirmOrderCpu(gpu, gpu2, prime, candidateOrder, divisorData, config, out PartialFactorResult? orderFactors))
|
if (TryConfirmOrderCpu(gpu, prime, candidateOrder, divisorData, config, out PartialFactorResult? orderFactors))
|
||||||
{
|
{
|
||||||
// GpuPrimeWorkLimiter.Release();
|
// GpuPrimeWorkLimiter.Release();
|
||||||
return candidateOrder;
|
return candidateOrder;
|
||||||
@@ -114,10 +109,10 @@ internal static partial class PrimeOrderCalculator
|
|||||||
{
|
{
|
||||||
orderFactors?.Dispose();
|
orderFactors?.Dispose();
|
||||||
// GpuPrimeWorkLimiter.Release();
|
// GpuPrimeWorkLimiter.Release();
|
||||||
return CalculateByFactorizationGpu(gpu, gpu2, prime, divisorData);
|
return CalculateByFactorizationGpu(gpu, prime, divisorData);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TryHeuristicFinishCpu(gpu, gpu2, prime, candidateOrder, previousOrder, divisorData, config, phiFactors, orderFactors, out ulong order))
|
if (TryHeuristicFinishCpu(gpu, prime, candidateOrder, previousOrder, divisorData, config, phiFactors, orderFactors, out ulong order))
|
||||||
{
|
{
|
||||||
// GpuPrimeWorkLimiter.Release();
|
// GpuPrimeWorkLimiter.Release();
|
||||||
return order;
|
return order;
|
||||||
@@ -346,7 +341,6 @@ internal static partial class PrimeOrderCalculator
|
|||||||
|
|
||||||
private static bool TryConfirmOrderCpu(
|
private static bool TryConfirmOrderCpu(
|
||||||
PrimeOrderCalculatorAccelerator gpu,
|
PrimeOrderCalculatorAccelerator gpu,
|
||||||
HeuristicCombinedPrimeTesterAccelerator gpu2,
|
|
||||||
ulong prime,
|
ulong prime,
|
||||||
ulong order,
|
ulong order,
|
||||||
in MontgomeryDivisorData divisorData,
|
in MontgomeryDivisorData divisorData,
|
||||||
@@ -365,7 +359,7 @@ internal static partial class PrimeOrderCalculator
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
PartialFactorResult factorization = PartialFactor(gpu, gpu2, order, config);
|
PartialFactorResult factorization = PartialFactor(gpu, order, config);
|
||||||
if (factorization.Factors is null)
|
if (factorization.Factors is null)
|
||||||
{
|
{
|
||||||
factorization.Dispose();
|
factorization.Dispose();
|
||||||
@@ -510,7 +504,6 @@ internal static partial class PrimeOrderCalculator
|
|||||||
|
|
||||||
private static bool TryHeuristicFinishCpu(
|
private static bool TryHeuristicFinishCpu(
|
||||||
PrimeOrderCalculatorAccelerator gpu,
|
PrimeOrderCalculatorAccelerator gpu,
|
||||||
HeuristicCombinedPrimeTesterAccelerator gpu2,
|
|
||||||
ulong prime,
|
ulong prime,
|
||||||
ulong order,
|
ulong order,
|
||||||
ulong? previousOrder,
|
ulong? previousOrder,
|
||||||
@@ -528,7 +521,7 @@ internal static partial class PrimeOrderCalculator
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Reuse the partial factorization from TryConfirmOrderCpu when available.
|
// Reuse the partial factorization from TryConfirmOrderCpu when available.
|
||||||
PartialFactorResult orderFactors = cachedOrderFactors ?? PartialFactor(gpu, gpu2, order, config);
|
PartialFactorResult orderFactors = cachedOrderFactors ?? PartialFactor(gpu, order, config);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (orderFactors.Factors is null)
|
if (orderFactors.Factors is null)
|
||||||
@@ -644,7 +637,7 @@ internal static partial class PrimeOrderCalculator
|
|||||||
|
|
||||||
bool equalsOne = powStepper.InitializeCpuIsUnity(candidate);
|
bool equalsOne = powStepper.InitializeCpuIsUnity(candidate);
|
||||||
powStepperInitialized = true;
|
powStepperInitialized = true;
|
||||||
if (equalsOne && TryConfirmCandidateCpu(gpu, gpu2, prime, candidate, divisorData, config, ref powUsed, powBudget))
|
if (equalsOne && TryConfirmCandidateCpu(gpu, prime, candidate, divisorData, config, ref powUsed, powBudget))
|
||||||
{
|
{
|
||||||
if (gpuPool is not null)
|
if (gpuPool is not null)
|
||||||
{
|
{
|
||||||
@@ -681,7 +674,7 @@ internal static partial class PrimeOrderCalculator
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!TryConfirmCandidateCpu(gpu, gpu2, prime, candidate, divisorData, config, ref powUsed, powBudget))
|
if (!TryConfirmCandidateCpu(gpu, prime, candidate, divisorData, config, ref powUsed, powBudget))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -892,9 +885,9 @@ internal static partial class PrimeOrderCalculator
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool TryConfirmCandidateCpu(PrimeOrderCalculatorAccelerator gpu, HeuristicCombinedPrimeTesterAccelerator gpu2, ulong prime, ulong candidate, in MontgomeryDivisorData divisorData, in PrimeOrderSearchConfig config, ref int powUsed, int powBudget)
|
private static bool TryConfirmCandidateCpu(PrimeOrderCalculatorAccelerator gpu, ulong prime, ulong candidate, in MontgomeryDivisorData divisorData, in PrimeOrderSearchConfig config, ref int powUsed, int powBudget)
|
||||||
{
|
{
|
||||||
PartialFactorResult factorization = PartialFactor(gpu, gpu2, candidate, config);
|
PartialFactorResult factorization = PartialFactor(gpu, candidate, config);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (factorization.Factors is null)
|
if (factorization.Factors is null)
|
||||||
@@ -1092,7 +1085,7 @@ internal static partial class PrimeOrderCalculator
|
|||||||
|
|
||||||
private static bool _goToGpu = true;
|
private static bool _goToGpu = true;
|
||||||
|
|
||||||
private static PartialFactorResult PartialFactor(PrimeOrderCalculatorAccelerator gpu, HeuristicCombinedPrimeTesterAccelerator gpu2, ulong value, in PrimeOrderSearchConfig config)
|
private static PartialFactorResult PartialFactor(PrimeOrderCalculatorAccelerator gpu, ulong value, in PrimeOrderSearchConfig config)
|
||||||
{
|
{
|
||||||
if (value <= 1UL)
|
if (value <= 1UL)
|
||||||
{
|
{
|
||||||
@@ -1182,7 +1175,7 @@ internal static partial class PrimeOrderCalculator
|
|||||||
bool goToGpu = Volatile.Read(ref _goToGpu);
|
bool goToGpu = Volatile.Read(ref _goToGpu);
|
||||||
Volatile.Write(ref _goToGpu, !goToGpu);
|
Volatile.Write(ref _goToGpu, !goToGpu);
|
||||||
bool isPrime = goToGpu
|
bool isPrime = goToGpu
|
||||||
? HeuristicCombinedPrimeTester.IsPrimeGpu(gpu2, composite)
|
? HeuristicCombinedPrimeTester.IsPrimeGpu(gpu, composite)
|
||||||
: PrimeTester.IsPrime(composite);
|
: PrimeTester.IsPrime(composite);
|
||||||
// bool isPrime = Open.Numeric.Primes.Prime.Numbers.IsPrime(composite);
|
// bool isPrime = Open.Numeric.Primes.Prime.Numbers.IsPrime(composite);
|
||||||
|
|
||||||
@@ -1255,7 +1248,7 @@ internal static partial class PrimeOrderCalculator
|
|||||||
// Console.WriteLine($"Partial factor pending hits {Volatile.Read(ref _partialFactorPendingHits)}");
|
// Console.WriteLine($"Partial factor pending hits {Volatile.Read(ref _partialFactorPendingHits)}");
|
||||||
|
|
||||||
// bool isPrime = PrimeTester.IsPrimeCpu(composite, CancellationToken.None);
|
// bool isPrime = PrimeTester.IsPrimeCpu(composite, CancellationToken.None);
|
||||||
bool isPrime = HeuristicCombinedPrimeTester.IsPrimeGpu(gpu2, 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);
|
||||||
|
|
||||||
entry = entry.WithPrimality(isPrime);
|
entry = entry.WithPrimality(isPrime);
|
||||||
@@ -1292,7 +1285,7 @@ internal static partial class PrimeOrderCalculator
|
|||||||
// Atomic.Add(ref _partialFactorCofactorHits, 1UL);
|
// Atomic.Add(ref _partialFactorCofactorHits, 1UL);
|
||||||
// Console.WriteLine($"Partial factor cofactor hits {Volatile.Read(ref _partialFactorCofactorHits)}");
|
// Console.WriteLine($"Partial factor cofactor hits {Volatile.Read(ref _partialFactorCofactorHits)}");
|
||||||
|
|
||||||
cofactorIsPrime = HeuristicCombinedPrimeTester.IsPrimeGpu(gpu2, cofactor);
|
cofactorIsPrime = HeuristicCombinedPrimeTester.IsPrimeGpu(gpu, cofactor);
|
||||||
// cofactorIsPrime = PrimeTester.IsPrimeGpu(gpu, cofactor);
|
// cofactorIsPrime = PrimeTester.IsPrimeGpu(gpu, cofactor);
|
||||||
// cofactorIsPrime = PrimeTester.IsPrimeGpu(cofactor);
|
// cofactorIsPrime = PrimeTester.IsPrimeGpu(cofactor);
|
||||||
// cofactorIsPrime = Open.Numeric.Primes.Prime.Numbers.IsPrime(cofactor);
|
// cofactorIsPrime = Open.Numeric.Primes.Prime.Numbers.IsPrime(cofactor);
|
||||||
@@ -1713,11 +1706,11 @@ internal static partial class PrimeOrderCalculator
|
|||||||
exponents = newExponentSpan;
|
exponents = newExponentSpan;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ulong CalculateByFactorizationCpu(PrimeOrderCalculatorAccelerator gpu, HeuristicCombinedPrimeTesterAccelerator gpu2, ulong prime, in MontgomeryDivisorData divisorData)
|
private static ulong CalculateByFactorizationCpu(PrimeOrderCalculatorAccelerator gpu, ulong prime, in MontgomeryDivisorData divisorData)
|
||||||
{
|
{
|
||||||
ulong phi = prime - 1UL;
|
ulong phi = prime - 1UL;
|
||||||
Dictionary<ulong, int> counts = new(capacity: 8);
|
Dictionary<ulong, int> counts = new(capacity: 8);
|
||||||
FactorCompletelyCpu(gpu2, phi, counts);
|
FactorCompletelyCpu(gpu, phi, counts);
|
||||||
if (counts.Count == 0)
|
if (counts.Count == 0)
|
||||||
{
|
{
|
||||||
return phi;
|
return phi;
|
||||||
@@ -1761,7 +1754,7 @@ internal static partial class PrimeOrderCalculator
|
|||||||
return order;
|
return order;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void FactorCompletelyCpu(HeuristicCombinedPrimeTesterAccelerator gpu, ulong value, Dictionary<ulong, int> counts)
|
private static void FactorCompletelyCpu(PrimeOrderCalculatorAccelerator gpu, ulong value, Dictionary<ulong, int> counts)
|
||||||
{
|
{
|
||||||
FactorCompletely(gpu, value, counts, knownComposite: false);
|
FactorCompletely(gpu, value, counts, knownComposite: false);
|
||||||
}
|
}
|
||||||
@@ -1771,7 +1764,7 @@ internal static partial class PrimeOrderCalculator
|
|||||||
// [ThreadStatic]
|
// [ThreadStatic]
|
||||||
// private static HeuristicPrimeTester? _tester;
|
// private static HeuristicPrimeTester? _tester;
|
||||||
|
|
||||||
private static void FactorCompletely(HeuristicCombinedPrimeTesterAccelerator gpu, ulong value, Dictionary<ulong, int> counts, bool knownComposite)
|
private static void FactorCompletely(PrimeOrderCalculatorAccelerator gpu, ulong value, Dictionary<ulong, int> counts, bool knownComposite)
|
||||||
{
|
{
|
||||||
if (value <= 1UL)
|
if (value <= 1UL)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -12,13 +12,13 @@ internal static partial class PrimeOrderCalculator
|
|||||||
|
|
||||||
private const int GpuSmallPrimeFactorSlots = 64;
|
private const int GpuSmallPrimeFactorSlots = 64;
|
||||||
|
|
||||||
private static ulong CalculateByFactorizationGpu(PrimeOrderCalculatorAccelerator gpu, HeuristicCombinedPrimeTesterAccelerator gpu2, ulong prime, in MontgomeryDivisorData divisorData)
|
private static ulong CalculateByFactorizationGpu(PrimeOrderCalculatorAccelerator gpu, ulong prime, in MontgomeryDivisorData divisorData)
|
||||||
{
|
{
|
||||||
ulong phi = prime - 1UL;
|
ulong phi = prime - 1UL;
|
||||||
Dictionary<ulong, int> counts = gpu.Pow2ModEntriesToTestOnHost;
|
Dictionary<ulong, int> counts = gpu.Pow2ModEntriesToTestOnHost;
|
||||||
counts.Clear();
|
counts.Clear();
|
||||||
|
|
||||||
FactorCompletelyCpu(gpu2, phi, counts);
|
FactorCompletelyCpu(gpu, phi, counts);
|
||||||
if (counts.Count == 0)
|
if (counts.Count == 0)
|
||||||
{
|
{
|
||||||
return phi;
|
return phi;
|
||||||
|
|||||||
Reference in new issue
Block a user