GPU memory allocations protected with lock to prevent shared memory access issues. GPU usage limited for the best performance.
This commit is contained in:
1 parent
02d16bf05c
commit
5cac51479e
12 files changed
+236
-148
No files matched your search
@@ -260,11 +260,14 @@ public sealed class DivisorCycleCache
|
|||||||
}
|
}
|
||||||
|
|
||||||
Accelerator accelerator = _accelerator;
|
Accelerator accelerator = _accelerator;
|
||||||
divisorBuffer = accelerator.Allocate1D<ulong>(requiredCapacity);
|
lock(accelerator)
|
||||||
powBuffer = accelerator.Allocate1D<ulong>(requiredCapacity);
|
{
|
||||||
orderBuffer = accelerator.Allocate1D<ulong>(requiredCapacity);
|
divisorBuffer = accelerator.Allocate1D<ulong>(requiredCapacity);
|
||||||
resultBuffer = accelerator.Allocate1D<ulong>(requiredCapacity);
|
powBuffer = accelerator.Allocate1D<ulong>(requiredCapacity);
|
||||||
statusBuffer = accelerator.Allocate1D<byte>(requiredCapacity);
|
orderBuffer = accelerator.Allocate1D<ulong>(requiredCapacity);
|
||||||
|
resultBuffer = accelerator.Allocate1D<ulong>(requiredCapacity);
|
||||||
|
statusBuffer = accelerator.Allocate1D<byte>(requiredCapacity);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ComputeCyclesGpuCore(ReadOnlySpan<ulong> divisors, Span<ulong> destination)
|
private void ComputeCyclesGpuCore(ReadOnlySpan<ulong> divisors, Span<ulong> destination)
|
||||||
|
|||||||
@@ -117,7 +117,11 @@ public sealed class PrimeOrderCalculatorAccelerator
|
|||||||
|
|
||||||
public readonly Kernel CheckFactorsKernel;
|
public readonly Kernel CheckFactorsKernel;
|
||||||
public readonly Kernel ConvertToStandardKernel;
|
public readonly Kernel ConvertToStandardKernel;
|
||||||
|
|
||||||
|
public readonly Action<AcceleratorStream, Index1D, ArrayView1D<ulong, Stride1D.Dense>, MontgomeryDivisorData, ArrayView1D<ulong, Stride1D.Dense>> ConvertToStandardKernelLauncher;
|
||||||
|
|
||||||
public readonly Kernel HeuristicCombinedTrialDivisionKernel;
|
public readonly Kernel HeuristicCombinedTrialDivisionKernel;
|
||||||
|
public readonly Action<AcceleratorStream, Index1D, byte, ArrayView<int>, ulong, ulong, HeuristicCombinedGpuViews> HeuristicCombinedTrialDivisionKernelLauncher;
|
||||||
public readonly Kernel KeepMontgomeryKernel;
|
public readonly Kernel KeepMontgomeryKernel;
|
||||||
public readonly Kernel PollardRhoKernel;
|
public readonly Kernel PollardRhoKernel;
|
||||||
public readonly Kernel Pow2ModWideKernel;
|
public readonly Kernel Pow2ModWideKernel;
|
||||||
@@ -133,29 +137,41 @@ public sealed class PrimeOrderCalculatorAccelerator
|
|||||||
MemoryBuffer1D<KeyValuePair<ulong, int>, Stride1D.Dense> pow2ModEntriesToTestOnDevice = Pow2ModEntriesToTestOnDevice;
|
MemoryBuffer1D<KeyValuePair<ulong, int>, Stride1D.Dense> pow2ModEntriesToTestOnDevice = Pow2ModEntriesToTestOnDevice;
|
||||||
if (pow2ModEntriesToTestOnDevice.Length < factorsCount)
|
if (pow2ModEntriesToTestOnDevice.Length < factorsCount)
|
||||||
{
|
{
|
||||||
pow2ModEntriesToTestOnDevice.Dispose();
|
lock (accelerator)
|
||||||
Pow2ModEntriesToTestOnDevice = accelerator.Allocate1D<KeyValuePair<ulong, int>>(factorsCount);
|
{
|
||||||
|
pow2ModEntriesToTestOnDevice.Dispose();
|
||||||
|
Pow2ModEntriesToTestOnDevice = accelerator.Allocate1D<KeyValuePair<ulong, int>>(factorsCount);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MemoryBuffer1D<ulong, Stride1D.Dense> input = Input;
|
MemoryBuffer1D<ulong, Stride1D.Dense> input = Input;
|
||||||
if (input.Length < primeTesterCapacity)
|
if (input.Length < primeTesterCapacity)
|
||||||
{
|
{
|
||||||
input.Dispose();
|
lock (accelerator)
|
||||||
Input = accelerator.Allocate1D<ulong>(primeTesterCapacity);
|
{
|
||||||
|
input.Dispose();
|
||||||
|
Input = accelerator.Allocate1D<ulong>(primeTesterCapacity);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MemoryBuffer1D<byte, Stride1D.Dense> outputByte = OutputByte;
|
MemoryBuffer1D<byte, Stride1D.Dense> outputByte = OutputByte;
|
||||||
if (outputByte.Length < primeTesterCapacity)
|
if (outputByte.Length < primeTesterCapacity)
|
||||||
{
|
{
|
||||||
outputByte.Dispose();
|
lock (accelerator)
|
||||||
OutputByte = accelerator.Allocate1D<byte>(primeTesterCapacity);
|
{
|
||||||
|
outputByte.Dispose();
|
||||||
|
OutputByte = accelerator.Allocate1D<byte>(primeTesterCapacity);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MemoryBuffer1D<int, Stride1D.Dense> outputInt = OutputInt;
|
MemoryBuffer1D<int, Stride1D.Dense> outputInt = OutputInt;
|
||||||
if (outputInt.Length < primeTesterCapacity)
|
if (outputInt.Length < primeTesterCapacity)
|
||||||
{
|
{
|
||||||
outputInt.Dispose();
|
lock (accelerator)
|
||||||
OutputInt = accelerator.Allocate1D<int>(primeTesterCapacity);
|
{
|
||||||
|
outputInt.Dispose();
|
||||||
|
OutputInt = accelerator.Allocate1D<int>(primeTesterCapacity);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -166,15 +182,21 @@ public sealed class PrimeOrderCalculatorAccelerator
|
|||||||
MemoryBuffer1D<ulong, Stride1D.Dense> outputUlong = OutputUlong;
|
MemoryBuffer1D<ulong, Stride1D.Dense> outputUlong = OutputUlong;
|
||||||
if (outputUlong.Length < newSize)
|
if (outputUlong.Length < newSize)
|
||||||
{
|
{
|
||||||
outputUlong.Dispose();
|
lock (accelerator)
|
||||||
OutputUlong = accelerator.Allocate1D<ulong>(newSize);
|
{
|
||||||
|
outputUlong.Dispose();
|
||||||
|
OutputUlong = accelerator.Allocate1D<ulong>(newSize);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MemoryBuffer1D<int, Stride1D.Dense> outputInt = OutputInt;
|
MemoryBuffer1D<int, Stride1D.Dense> outputInt = OutputInt;
|
||||||
if (outputInt.Length < newSize)
|
if (outputInt.Length < newSize)
|
||||||
{
|
{
|
||||||
outputInt.Dispose();
|
lock (accelerator)
|
||||||
OutputInt = accelerator.Allocate1D<int>(newSize);
|
{
|
||||||
|
outputInt.Dispose();
|
||||||
|
OutputInt = accelerator.Allocate1D<int>(newSize);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -184,15 +206,21 @@ public sealed class PrimeOrderCalculatorAccelerator
|
|||||||
MemoryBuffer1D<ulong, Stride1D.Dense> input = Input;
|
MemoryBuffer1D<ulong, Stride1D.Dense> input = Input;
|
||||||
if (input.Length < newSize)
|
if (input.Length < newSize)
|
||||||
{
|
{
|
||||||
input.Dispose();
|
lock (accelerator)
|
||||||
Input = accelerator.Allocate1D<ulong>(newSize);
|
{
|
||||||
|
input.Dispose();
|
||||||
|
Input = accelerator.Allocate1D<ulong>(newSize);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MemoryBuffer1D<ulong, Stride1D.Dense> outputUlong = OutputUlong;
|
MemoryBuffer1D<ulong, Stride1D.Dense> outputUlong = OutputUlong;
|
||||||
if (outputUlong.Length < newSize)
|
if (outputUlong.Length < newSize)
|
||||||
{
|
{
|
||||||
outputUlong.Dispose();
|
lock (accelerator)
|
||||||
OutputUlong = accelerator.Allocate1D<ulong>(newSize);
|
{
|
||||||
|
outputUlong.Dispose();
|
||||||
|
OutputUlong = accelerator.Allocate1D<ulong>(newSize);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -201,57 +229,65 @@ public sealed class PrimeOrderCalculatorAccelerator
|
|||||||
var accelerator = _accelerators[acceleratorIndex];
|
var accelerator = _accelerators[acceleratorIndex];
|
||||||
Accelerator = accelerator;
|
Accelerator = accelerator;
|
||||||
AcceleratorIndex = acceleratorIndex;
|
AcceleratorIndex = acceleratorIndex;
|
||||||
Input = accelerator.Allocate1D<ulong>(Math.Max(specialMaxFactorCapacity, primeTesterCapacity));
|
lock (accelerator)
|
||||||
OutputByte = Accelerator.Allocate1D<byte>(primeTesterCapacity);
|
|
||||||
OutputInt = Accelerator.Allocate1D<int>(Math.Max(primeTesterCapacity, smallPrimeFactorSlotCount));
|
|
||||||
OutputUlong = accelerator.Allocate1D<ulong>(Math.Max(specialMaxFactorCapacity, smallPrimeFactorSlotCount));
|
|
||||||
Pow2ModEntriesToTestOnDevice = accelerator.Allocate1D<KeyValuePair<ulong, int>>(factorsCount);
|
|
||||||
SmallPrimeFactorCountSlot = accelerator.Allocate1D<int>(1);
|
|
||||||
SpecialMaxResult = accelerator.Allocate1D<ulong>(1);
|
|
||||||
|
|
||||||
LastDigitGpuTables lastDigitSharedTables = LastDigitGpuTables.GetStaticTables(acceleratorIndex);
|
|
||||||
|
|
||||||
DevicePrimesLastOne = lastDigitSharedTables.DevicePrimesLastOne.View;
|
|
||||||
DevicePrimesLastSeven = lastDigitSharedTables.DevicePrimesLastSeven.View;
|
|
||||||
DevicePrimesLastThree = lastDigitSharedTables.DevicePrimesLastThree.View;
|
|
||||||
DevicePrimesLastNine = lastDigitSharedTables.DevicePrimesLastNine.View;
|
|
||||||
DevicePrimesPow2LastOne = lastDigitSharedTables.DevicePrimesPow2LastOne.View;
|
|
||||||
DevicePrimesPow2LastSeven = lastDigitSharedTables.DevicePrimesPow2LastSeven.View;
|
|
||||||
DevicePrimesPow2LastThree = lastDigitSharedTables.DevicePrimesPow2LastThree.View;
|
|
||||||
DevicePrimesPow2LastNine = lastDigitSharedTables.DevicePrimesPow2LastNine.View;
|
|
||||||
|
|
||||||
DivisorTables = HeuristicCombinedGpuTables
|
|
||||||
.GetStaticTables(acceleratorIndex)
|
|
||||||
.CreateViews();
|
|
||||||
|
|
||||||
var smallPrimeFactorTables = SmallPrimeFactorGpuTables.GetStaticTables(acceleratorIndex);
|
|
||||||
|
|
||||||
if (smallPrimeFactorTables.HasValue)
|
|
||||||
{
|
{
|
||||||
SmallPrimeFactorGpuTables tables = smallPrimeFactorTables.Value;
|
Input = accelerator.Allocate1D<ulong>(Math.Max(specialMaxFactorCapacity, primeTesterCapacity));
|
||||||
SmallPrimeFactorPrimes = tables.Primes.View;
|
OutputByte = Accelerator.Allocate1D<byte>(primeTesterCapacity);
|
||||||
SmallPrimeFactorSquares = tables.Squares.View;
|
OutputInt = Accelerator.Allocate1D<int>(Math.Max(primeTesterCapacity, smallPrimeFactorSlotCount));
|
||||||
|
OutputUlong = accelerator.Allocate1D<ulong>(Math.Max(specialMaxFactorCapacity, smallPrimeFactorSlotCount));
|
||||||
|
Pow2ModEntriesToTestOnDevice = accelerator.Allocate1D<KeyValuePair<ulong, int>>(factorsCount);
|
||||||
|
SmallPrimeFactorCountSlot = accelerator.Allocate1D<int>(1);
|
||||||
|
SpecialMaxResult = accelerator.Allocate1D<ulong>(1);
|
||||||
|
|
||||||
|
LastDigitGpuTables lastDigitSharedTables = LastDigitGpuTables.GetStaticTables(acceleratorIndex);
|
||||||
|
DevicePrimesLastOne = lastDigitSharedTables.DevicePrimesLastOne.View;
|
||||||
|
DevicePrimesLastSeven = lastDigitSharedTables.DevicePrimesLastSeven.View;
|
||||||
|
DevicePrimesLastThree = lastDigitSharedTables.DevicePrimesLastThree.View;
|
||||||
|
DevicePrimesLastNine = lastDigitSharedTables.DevicePrimesLastNine.View;
|
||||||
|
DevicePrimesPow2LastOne = lastDigitSharedTables.DevicePrimesPow2LastOne.View;
|
||||||
|
DevicePrimesPow2LastSeven = lastDigitSharedTables.DevicePrimesPow2LastSeven.View;
|
||||||
|
DevicePrimesPow2LastThree = lastDigitSharedTables.DevicePrimesPow2LastThree.View;
|
||||||
|
DevicePrimesPow2LastNine = lastDigitSharedTables.DevicePrimesPow2LastNine.View;
|
||||||
|
|
||||||
|
DivisorTables = HeuristicCombinedGpuTables
|
||||||
|
.GetStaticTables(acceleratorIndex)
|
||||||
|
.CreateViews();
|
||||||
|
|
||||||
|
var smallPrimeFactorTables = SmallPrimeFactorGpuTables.GetStaticTables(acceleratorIndex);
|
||||||
|
|
||||||
|
if (smallPrimeFactorTables.HasValue)
|
||||||
|
{
|
||||||
|
SmallPrimeFactorGpuTables tables = smallPrimeFactorTables.Value;
|
||||||
|
SmallPrimeFactorPrimes = tables.Primes.View;
|
||||||
|
SmallPrimeFactorSquares = tables.Squares.View;
|
||||||
|
}
|
||||||
|
|
||||||
|
CheckFactorsKernel = KernelUtil.GetKernel(accelerator.LoadStreamKernel<int, ulong, ArrayView1D<KeyValuePair<ulong, int>, Stride1D.Dense>, MontgomeryDivisorData, ArrayView1D<ulong, Stride1D.Dense>>(PrimeOrderGpuHeuristics.CheckFactorsKernel));
|
||||||
|
|
||||||
|
Kernel convertToStandardKernel = KernelUtil.GetKernel(accelerator.LoadAutoGroupedStreamKernel<Index1D, ArrayView1D<ulong, Stride1D.Dense>, MontgomeryDivisorData, ArrayView1D<ulong, Stride1D.Dense>>(Pow2MontgomeryKernels.Pow2MontgomeryKernelConvertToStandard));
|
||||||
|
|
||||||
|
ConvertToStandardKernel = convertToStandardKernel;
|
||||||
|
ConvertToStandardKernelLauncher = convertToStandardKernel.CreateLauncherDelegate<Action<AcceleratorStream, Index1D, ArrayView1D<ulong, Stride1D.Dense>, MontgomeryDivisorData, ArrayView1D<ulong, Stride1D.Dense>>>();
|
||||||
|
|
||||||
|
var heuristicCombinedTrialDivisionKernel = KernelUtil.GetKernel(accelerator.LoadAutoGroupedStreamKernel<Index1D, byte, ArrayView<int>, ulong, ulong, HeuristicCombinedGpuViews>(PrimeTesterKernels.HeuristicTrialCombinedDivisionKernel));
|
||||||
|
|
||||||
|
HeuristicCombinedTrialDivisionKernel = heuristicCombinedTrialDivisionKernel;
|
||||||
|
HeuristicCombinedTrialDivisionKernelLauncher = heuristicCombinedTrialDivisionKernel.CreateLauncherDelegate<Action<AcceleratorStream, Index1D, byte, ArrayView<int>, ulong, ulong, HeuristicCombinedGpuViews>>();
|
||||||
|
|
||||||
|
KeepMontgomeryKernel = KernelUtil.GetKernel(accelerator.LoadAutoGroupedStreamKernel<Index1D, ArrayView1D<ulong, Stride1D.Dense>, MontgomeryDivisorData, ArrayView1D<ulong, Stride1D.Dense>>(Pow2MontgomeryKernels.Pow2MontgomeryKernelKeepMontgomery));
|
||||||
|
|
||||||
|
PollardRhoKernel = KernelUtil.GetKernel(accelerator.LoadStreamKernel<ulong, int, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<byte, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>>(Pow2MontgomeryKernels.TryPollardRhoKernel));
|
||||||
|
|
||||||
|
Pow2ModWideKernel = KernelUtil.GetKernel(accelerator.LoadAutoGroupedStreamKernel<Index1D, ArrayView1D<GpuUInt128, Stride1D.Dense>, GpuUInt128, ArrayView1D<GpuUInt128, Stride1D.Dense>>(PrimeOrderGpuHeuristics.Pow2ModKernelWide));
|
||||||
|
|
||||||
|
SharesFactorKernel = KernelUtil.GetKernel(accelerator.LoadAutoGroupedStreamKernel<Index1D, ArrayView<ulong>, ArrayView<byte>>(PrimeTesterKernels.SharesFactorKernel));
|
||||||
|
|
||||||
|
SmallPrimeFactorKernel = 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));
|
||||||
|
|
||||||
|
SmallPrimeSieveKernel = KernelUtil.GetKernel(accelerator.LoadAutoGroupedStreamKernel<Index1D, ArrayView<ulong>, ArrayView<uint>, ArrayView<uint>, ArrayView<uint>, ArrayView<uint>, ArrayView<ulong>, ArrayView<ulong>, ArrayView<ulong>, ArrayView<ulong>, ArrayView<byte>>(PrimeTesterKernels.SmallPrimeSieveKernel));
|
||||||
|
|
||||||
|
SpecialMaxKernel = KernelUtil.GetKernel(accelerator.LoadAutoGroupedStreamKernel<Index1D, ulong, ArrayView1D<ulong, Stride1D.Dense>, int, MontgomeryDivisorData, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>>(PrimeOrderGpuHeuristics.EvaluateSpecialMaxCandidatesKernel));
|
||||||
}
|
}
|
||||||
|
|
||||||
CheckFactorsKernel = KernelUtil.GetKernel(accelerator.LoadStreamKernel<int, ulong, ArrayView1D<KeyValuePair<ulong, int>, Stride1D.Dense>, MontgomeryDivisorData, ArrayView1D<ulong, Stride1D.Dense>>(PrimeOrderGpuHeuristics.CheckFactorsKernel));
|
|
||||||
|
|
||||||
ConvertToStandardKernel = KernelUtil.GetKernel(accelerator.LoadAutoGroupedStreamKernel<Index1D, ArrayView1D<ulong, Stride1D.Dense>, MontgomeryDivisorData, ArrayView1D<ulong, Stride1D.Dense>>(Pow2MontgomeryKernels.Pow2MontgomeryKernelConvertToStandard));
|
|
||||||
|
|
||||||
HeuristicCombinedTrialDivisionKernel = KernelUtil.GetKernel(accelerator.LoadAutoGroupedStreamKernel<Index1D, byte, ArrayView<int>, ulong, ulong, HeuristicCombinedGpuViews>(PrimeTesterKernels.HeuristicTrialCombinedDivisionKernel));
|
|
||||||
|
|
||||||
KeepMontgomeryKernel = KernelUtil.GetKernel(accelerator.LoadAutoGroupedStreamKernel<Index1D, ArrayView1D<ulong, Stride1D.Dense>, MontgomeryDivisorData, ArrayView1D<ulong, Stride1D.Dense>>(Pow2MontgomeryKernels.Pow2MontgomeryKernelKeepMontgomery));
|
|
||||||
|
|
||||||
PollardRhoKernel = KernelUtil.GetKernel(accelerator.LoadStreamKernel<ulong, int, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<byte, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>>(Pow2MontgomeryKernels.TryPollardRhoKernel));
|
|
||||||
|
|
||||||
Pow2ModWideKernel = KernelUtil.GetKernel(accelerator.LoadAutoGroupedStreamKernel<Index1D, ArrayView1D<GpuUInt128, Stride1D.Dense>, GpuUInt128, ArrayView1D<GpuUInt128, Stride1D.Dense>>(PrimeOrderGpuHeuristics.Pow2ModKernelWide));
|
|
||||||
|
|
||||||
SharesFactorKernel = KernelUtil.GetKernel(accelerator.LoadAutoGroupedStreamKernel<Index1D, ArrayView<ulong>, ArrayView<byte>>(PrimeTesterKernels.SharesFactorKernel));
|
|
||||||
|
|
||||||
SmallPrimeFactorKernel = 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));
|
|
||||||
|
|
||||||
SmallPrimeSieveKernel = KernelUtil.GetKernel(accelerator.LoadAutoGroupedStreamKernel<Index1D, ArrayView<ulong>, ArrayView<uint>, ArrayView<uint>, ArrayView<uint>, ArrayView<uint>, ArrayView<ulong>, ArrayView<ulong>, ArrayView<ulong>, ArrayView<ulong>, ArrayView<byte>>(PrimeTesterKernels.SmallPrimeSieveKernel));
|
|
||||||
|
|
||||||
SpecialMaxKernel = KernelUtil.GetKernel(accelerator.LoadAutoGroupedStreamKernel<Index1D, ulong, ArrayView1D<ulong, Stride1D.Dense>, int, MontgomeryDivisorData, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>>(PrimeOrderGpuHeuristics.EvaluateSpecialMaxCandidatesKernel));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ public class GpuKernelPool
|
|||||||
internal static KernelContainer GetOrAddKernels(int acceleratorIndex, AcceleratorStream stream, KernelType kernelType)
|
internal static KernelContainer GetOrAddKernels(int acceleratorIndex, AcceleratorStream stream, KernelType kernelType)
|
||||||
{
|
{
|
||||||
var pool = _pool ??= [];
|
var pool = _pool ??= [];
|
||||||
if (pool[acceleratorIndex] is not {} kernels)
|
if (pool[acceleratorIndex] is not { } kernels)
|
||||||
{
|
{
|
||||||
kernels = new();
|
kernels = new();
|
||||||
}
|
}
|
||||||
@@ -151,7 +151,7 @@ public class GpuKernelPool
|
|||||||
var host = MersenneDivisorCycles.Shared.ExportSmallCyclesSnapshot();
|
var host = MersenneDivisorCycles.Shared.ExportSmallCyclesSnapshot();
|
||||||
MemoryBuffer1D<ulong, Stride1D.Dense>? device;
|
MemoryBuffer1D<ulong, Stride1D.Dense>? device;
|
||||||
|
|
||||||
// lock (accelerator)
|
lock (accelerator)
|
||||||
{
|
{
|
||||||
device = accelerator.Allocate1D<ulong>(host.Length);
|
device = accelerator.Allocate1D<ulong>(host.Length);
|
||||||
}
|
}
|
||||||
@@ -195,13 +195,13 @@ public class GpuKernelPool
|
|||||||
MemoryBuffer1D<ulong, Stride1D.Dense>? deviceLastOnePow2;
|
MemoryBuffer1D<ulong, Stride1D.Dense>? deviceLastOnePow2;
|
||||||
MemoryBuffer1D<ulong, Stride1D.Dense>? deviceLastSevenPow2;
|
MemoryBuffer1D<ulong, Stride1D.Dense>? deviceLastSevenPow2;
|
||||||
|
|
||||||
// lock (accelerator)
|
lock (accelerator)
|
||||||
// {
|
{
|
||||||
deviceLastOne = accelerator.Allocate1D<uint>(hostLastOne.Length);
|
deviceLastOne = accelerator.Allocate1D<uint>(hostLastOne.Length);
|
||||||
deviceLastSeven = accelerator.Allocate1D<uint>(hostLastSeven.Length);
|
deviceLastSeven = accelerator.Allocate1D<uint>(hostLastSeven.Length);
|
||||||
deviceLastOnePow2 = accelerator.Allocate1D<ulong>(hostLastOnePow2.Length);
|
deviceLastOnePow2 = accelerator.Allocate1D<ulong>(hostLastOnePow2.Length);
|
||||||
deviceLastSevenPow2 = accelerator.Allocate1D<ulong>(hostLastSevenPow2.Length);
|
deviceLastSevenPow2 = accelerator.Allocate1D<ulong>(hostLastSevenPow2.Length);
|
||||||
// }
|
}
|
||||||
|
|
||||||
deviceLastOne.View.CopyFromCPU(stream, hostLastOne);
|
deviceLastOne.View.CopyFromCPU(stream, hostLastOne);
|
||||||
deviceLastSeven.View.CopyFromCPU(stream, hostLastSeven);
|
deviceLastSeven.View.CopyFromCPU(stream, hostLastSeven);
|
||||||
|
|||||||
@@ -540,7 +540,7 @@ public sealed class MersenneNumberDivisorByDivisorGpuTester : IMersenneNumberDiv
|
|||||||
|
|
||||||
if (_divisorBuffer == null)
|
if (_divisorBuffer == null)
|
||||||
{
|
{
|
||||||
// lock(accelerator)
|
lock(accelerator)
|
||||||
{
|
{
|
||||||
_divisorBuffer = accelerator.Allocate1D<GpuDivisorPartialData>(1);
|
_divisorBuffer = accelerator.Allocate1D<GpuDivisorPartialData>(1);
|
||||||
_offsetBuffer = accelerator.Allocate1D<int>(1);
|
_offsetBuffer = accelerator.Allocate1D<int>(1);
|
||||||
@@ -570,7 +570,7 @@ public sealed class MersenneNumberDivisorByDivisorGpuTester : IMersenneNumberDiv
|
|||||||
{
|
{
|
||||||
int desiredCapacity = requiredCapacity > _capacity ? requiredCapacity : _capacity;
|
int desiredCapacity = requiredCapacity > _capacity ? requiredCapacity : _capacity;
|
||||||
_capacity = desiredCapacity;
|
_capacity = desiredCapacity;
|
||||||
// lock (accelerator)
|
lock (accelerator)
|
||||||
{
|
{
|
||||||
_exponentsBuffer = accelerator.Allocate1D<ulong>(desiredCapacity);
|
_exponentsBuffer = accelerator.Allocate1D<ulong>(desiredCapacity);
|
||||||
_hitBuffer = accelerator.Allocate1D<byte>(desiredCapacity);
|
_hitBuffer = accelerator.Allocate1D<byte>(desiredCapacity);
|
||||||
@@ -798,7 +798,7 @@ public sealed class MersenneNumberDivisorByDivisorGpuTester : IMersenneNumberDiv
|
|||||||
|
|
||||||
private void AllocateDeviceBuffers(Accelerator accelerator, int capacity)
|
private void AllocateDeviceBuffers(Accelerator accelerator, int capacity)
|
||||||
{
|
{
|
||||||
// lock (accelerator)
|
lock (accelerator)
|
||||||
{
|
{
|
||||||
_divisorDataBuffer = accelerator.Allocate1D<GpuDivisorPartialData>(capacity);
|
_divisorDataBuffer = accelerator.Allocate1D<GpuDivisorPartialData>(capacity);
|
||||||
_offsetBuffer = accelerator.Allocate1D<int>(capacity);
|
_offsetBuffer = accelerator.Allocate1D<int>(capacity);
|
||||||
|
|||||||
@@ -55,8 +55,10 @@ public static class Pow2MontgomeryGpuCalculator
|
|||||||
// We don't need to worry about any left-overs here.
|
// We don't need to worry about any left-overs here.
|
||||||
// resultBuffer.MemSetToZero(stream);
|
// resultBuffer.MemSetToZero(stream);
|
||||||
|
|
||||||
var kernel = gpu.ConvertToStandardKernel;
|
var kernelLauncher = gpu.ConvertToStandardKernelLauncher!;
|
||||||
kernel.Launch(stream, 1, 1, exponentBuffer.View, divisor, resultBuffer.View);
|
|
||||||
|
kernelLauncher(stream, 1, exponentBuffer.View, divisor, resultBuffer.View);
|
||||||
|
|
||||||
resultBuffer.View.CopyToCPU(stream, ref result, 1);
|
resultBuffer.View.CopyToCPU(stream, ref result, 1);
|
||||||
stream.Synchronize();
|
stream.Synchronize();
|
||||||
|
|
||||||
@@ -73,7 +75,6 @@ public static class Pow2MontgomeryGpuCalculator
|
|||||||
ulong result = 0UL;
|
ulong result = 0UL;
|
||||||
MemoryBuffer1D<ulong, Stride1D.Dense> exponentBuffer = gpu.Input;
|
MemoryBuffer1D<ulong, Stride1D.Dense> exponentBuffer = gpu.Input;
|
||||||
MemoryBuffer1D<ulong, Stride1D.Dense> resultBuffer = gpu.OutputUlong;
|
MemoryBuffer1D<ulong, Stride1D.Dense> resultBuffer = gpu.OutputUlong;
|
||||||
var kernel = gpu.ConvertToStandardKernel;
|
|
||||||
|
|
||||||
int acceleratorIndex = gpu.AcceleratorIndex;
|
int acceleratorIndex = gpu.AcceleratorIndex;
|
||||||
AcceleratorStream stream = AcceleratorStreamPool.Rent(acceleratorIndex);
|
AcceleratorStream stream = AcceleratorStreamPool.Rent(acceleratorIndex);
|
||||||
@@ -81,8 +82,11 @@ public static class Pow2MontgomeryGpuCalculator
|
|||||||
// We don't need to worry about any left-overs here.
|
// We don't need to worry about any left-overs here.
|
||||||
// resultBuffer.MemSetToZero(stream);
|
// resultBuffer.MemSetToZero(stream);
|
||||||
|
|
||||||
var kernelLauncher = kernel.CreateLauncherDelegate<Action<AcceleratorStream, Index1D, ArrayView1D<ulong, Stride1D.Dense>, MontgomeryDivisorData, ArrayView1D<ulong, Stride1D.Dense>>>();
|
|
||||||
kernelLauncher(stream, 1,exponentBuffer.View, divisor, resultBuffer.View);
|
var accelerator = gpu.Accelerator;
|
||||||
|
var kernelLauncher = gpu.ConvertToStandardKernelLauncher;
|
||||||
|
kernelLauncher(stream, 1, exponentBuffer.View, divisor, resultBuffer.View);
|
||||||
|
|
||||||
resultBuffer.View.CopyToCPU(stream, ref result, 1);
|
resultBuffer.View.CopyToCPU(stream, ref result, 1);
|
||||||
stream.Synchronize();
|
stream.Synchronize();
|
||||||
|
|
||||||
|
|||||||
@@ -190,14 +190,14 @@ internal static partial class PrimeOrderGpuHeuristics
|
|||||||
// fullyFactoredBuffer.MemSetToZero(stream);
|
// fullyFactoredBuffer.MemSetToZero(stream);
|
||||||
|
|
||||||
var partialFactorKernel = GetPartialFactorKernel(acceleratorIndex);
|
var partialFactorKernel = GetPartialFactorKernel(acceleratorIndex);
|
||||||
|
var kernelLauncher = 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>>>();
|
||||||
|
|
||||||
partialFactorKernel.Launch(
|
kernelLauncher(
|
||||||
stream,
|
stream,
|
||||||
1,
|
1,
|
||||||
1,
|
|
||||||
smallPrimesView,
|
smallPrimesView,
|
||||||
smallSquaresView,
|
smallSquaresView,
|
||||||
smallPrimesView.Length,
|
(int)smallPrimesView.Length,
|
||||||
primeTargets.Length,
|
primeTargets.Length,
|
||||||
value,
|
value,
|
||||||
limit,
|
limit,
|
||||||
@@ -354,7 +354,7 @@ internal static partial class PrimeOrderGpuHeuristics
|
|||||||
MemoryBuffer1D<ulong, Stride1D.Dense>? resultBuffer;
|
MemoryBuffer1D<ulong, Stride1D.Dense>? resultBuffer;
|
||||||
MemoryBuffer1D<byte, Stride1D.Dense>? statusBuffer;
|
MemoryBuffer1D<byte, Stride1D.Dense>? statusBuffer;
|
||||||
|
|
||||||
// lock(accelerator)
|
lock(accelerator)
|
||||||
{
|
{
|
||||||
phiFactorBuffer = accelerator.Allocate1D<ulong>(GpuSmallPrimeFactorSlots);
|
phiFactorBuffer = accelerator.Allocate1D<ulong>(GpuSmallPrimeFactorSlots);
|
||||||
phiExponentBuffer = accelerator.Allocate1D<int>(GpuSmallPrimeFactorSlots);
|
phiExponentBuffer = accelerator.Allocate1D<int>(GpuSmallPrimeFactorSlots);
|
||||||
@@ -398,16 +398,17 @@ internal static partial class PrimeOrderGpuHeuristics
|
|||||||
statusBuffer.View);
|
statusBuffer.View);
|
||||||
|
|
||||||
var orderKernel = GetOrderKernel(acceleratorIndex);
|
var orderKernel = GetOrderKernel(acceleratorIndex);
|
||||||
orderKernel.Launch(
|
var kernelLauncher = orderKernel.CreateLauncherDelegate<Action<AcceleratorStream, Index1D, ulong, OrderKernelConfig, MontgomeryDivisorData, ArrayView1D<uint, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>, int, OrderKernelBuffers>>();
|
||||||
|
|
||||||
|
kernelLauncher(
|
||||||
stream,
|
stream,
|
||||||
1,
|
1,
|
||||||
1,
|
|
||||||
prime,
|
prime,
|
||||||
kernelConfig,
|
kernelConfig,
|
||||||
divisorData,
|
divisorData,
|
||||||
smallPrimesView,
|
smallPrimesView,
|
||||||
smallSquaresView,
|
smallSquaresView,
|
||||||
smallPrimesView.Length,
|
(int)smallPrimesView.Length,
|
||||||
buffers);
|
buffers);
|
||||||
|
|
||||||
|
|
||||||
@@ -517,7 +518,7 @@ internal static partial class PrimeOrderGpuHeuristics
|
|||||||
// with out preallocated buffers. Share the pool with Pow2ModWide kernel.
|
// with out preallocated buffers. Share the pool with Pow2ModWide kernel.
|
||||||
MemoryBuffer1D<ulong, Stride1D.Dense>? exponentBuffer;
|
MemoryBuffer1D<ulong, Stride1D.Dense>? exponentBuffer;
|
||||||
MemoryBuffer1D<ulong, Stride1D.Dense>? remainderBuffer;
|
MemoryBuffer1D<ulong, Stride1D.Dense>? remainderBuffer;
|
||||||
// lock(accelerator)
|
lock(accelerator)
|
||||||
{
|
{
|
||||||
exponentBuffer = accelerator.Allocate1D<ulong>(exponents.Length);
|
exponentBuffer = accelerator.Allocate1D<ulong>(exponents.Length);
|
||||||
remainderBuffer = accelerator.Allocate1D<ulong>(exponents.Length);
|
remainderBuffer = accelerator.Allocate1D<ulong>(exponents.Length);
|
||||||
@@ -529,9 +530,11 @@ internal static partial class PrimeOrderGpuHeuristics
|
|||||||
// remainderBuffer.MemSetToZero(stream);
|
// remainderBuffer.MemSetToZero(stream);
|
||||||
|
|
||||||
var pow2ModKernel = GetPow2ModKernel(acceleratorIndex);
|
var pow2ModKernel = GetPow2ModKernel(acceleratorIndex);
|
||||||
|
var kernelLauncher = pow2ModKernel.CreateLauncherDelegate<Action<AcceleratorStream, Index1D, ArrayView1D<ulong, Stride1D.Dense>, MontgomeryDivisorData, ArrayView1D<ulong, Stride1D.Dense>>>();
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
pow2ModKernel.Launch(stream, 1, exponents.Length, exponentBuffer.View, divisorData, remainderBuffer.View);
|
kernelLauncher(stream, exponents.Length, exponentBuffer.View, divisorData, remainderBuffer.View);
|
||||||
remainderBuffer.View.CopyToCPU(stream, ref MemoryMarshal.GetReference(results), exponents.Length);
|
remainderBuffer.View.CopyToCPU(stream, ref MemoryMarshal.GetReference(results), exponents.Length);
|
||||||
stream.Synchronize();
|
stream.Synchronize();
|
||||||
|
|
||||||
@@ -590,13 +593,20 @@ internal static partial class PrimeOrderGpuHeuristics
|
|||||||
int acceleratorIndex = gpu.AcceleratorIndex;
|
int acceleratorIndex = gpu.AcceleratorIndex;
|
||||||
Accelerator accelerator = gpu.Accelerator;
|
Accelerator accelerator = gpu.Accelerator;
|
||||||
|
|
||||||
MemoryBuffer1D<GpuUInt128, Stride1D.Dense> exponentBuffer = accelerator.Allocate1D<GpuUInt128>(length);
|
|
||||||
MemoryBuffer1D<GpuUInt128, Stride1D.Dense> remainderBuffer = accelerator.Allocate1D<GpuUInt128>(length);
|
|
||||||
|
|
||||||
AcceleratorStream? stream = AcceleratorStreamPool.Rent(acceleratorIndex);
|
AcceleratorStream? stream = AcceleratorStreamPool.Rent(acceleratorIndex);
|
||||||
exponentBuffer.View.CopyFromCPU(stream, exponentSpan);
|
MemoryBuffer1D<GpuUInt128, Stride1D.Dense> exponentBuffer;
|
||||||
|
MemoryBuffer1D<GpuUInt128, Stride1D.Dense> remainderBuffer;
|
||||||
|
|
||||||
gpu.Pow2ModWideKernel.Launch(stream, length, exponentBuffer.View, modulus, remainderBuffer.View);
|
lock(accelerator)
|
||||||
|
{
|
||||||
|
exponentBuffer = accelerator.Allocate1D<GpuUInt128>(length);
|
||||||
|
remainderBuffer = accelerator.Allocate1D<GpuUInt128>(length);
|
||||||
|
}
|
||||||
|
|
||||||
|
exponentBuffer.View.CopyFromCPU(stream, exponentSpan);
|
||||||
|
var kernelLauncher = gpu.Pow2ModWideKernel.CreateLauncherDelegate<Action<AcceleratorStream, Index1D, ArrayView1D<GpuUInt128, Stride1D.Dense>, GpuUInt128, ArrayView1D<GpuUInt128, Stride1D.Dense>>>();
|
||||||
|
|
||||||
|
kernelLauncher(stream, length, exponentBuffer.View, modulus, remainderBuffer.View);
|
||||||
remainderBuffer.View.CopyToCPU(stream, ref MemoryMarshal.GetReference(resultSpan), length);
|
remainderBuffer.View.CopyToCPU(stream, ref MemoryMarshal.GetReference(resultSpan), length);
|
||||||
stream.Synchronize();
|
stream.Synchronize();
|
||||||
|
|
||||||
|
|||||||
@@ -240,13 +240,12 @@ public sealed class HeuristicCombinedPrimeTester
|
|||||||
var kernel = gpu.HeuristicCombinedTrialDivisionKernel;
|
var kernel = gpu.HeuristicCombinedTrialDivisionKernel;
|
||||||
var flagView1D = gpu.OutputInt!.View;
|
var flagView1D = gpu.OutputInt!.View;
|
||||||
|
|
||||||
bool compositeDetected = false;
|
bool compositeDetected;
|
||||||
int divisorLength = GetCombinedDivisors(nMod10).Length;
|
// int compositeFlag = 0;
|
||||||
|
Span<int> compositeFlag = stackalloc int[1];
|
||||||
|
flagView1D.MemSetToZero(stream);
|
||||||
|
|
||||||
int compositeFlag = 0;
|
var kernelLauncher = gpu.HeuristicCombinedTrialDivisionKernelLauncher;
|
||||||
flagView1D.CopyFromCPU(stream, ref compositeFlag, 1);
|
|
||||||
|
|
||||||
var kernelLauncher = kernel.CreateLauncherDelegate<Action<AcceleratorStream, Index1D, byte, ArrayView<int>, ulong, ulong, HeuristicCombinedGpuViews>>();
|
|
||||||
kernelLauncher(
|
kernelLauncher(
|
||||||
stream,
|
stream,
|
||||||
1,
|
1,
|
||||||
@@ -255,13 +254,13 @@ public sealed class HeuristicCombinedPrimeTester
|
|||||||
n,
|
n,
|
||||||
maxDivisorSquare,
|
maxDivisorSquare,
|
||||||
gpu.DivisorTables);
|
gpu.DivisorTables);
|
||||||
flagView1D.CopyToCPU(stream, ref compositeFlag, 1);
|
flagView1D.CopyToCPU(stream, compositeFlag);
|
||||||
stream.Synchronize();
|
stream.Synchronize();
|
||||||
|
|
||||||
AcceleratorStreamPool.Return(acceleratorIndex, stream);
|
AcceleratorStreamPool.Return(acceleratorIndex, stream);
|
||||||
// GpuPrimeWorkLimiter.Release();
|
// GpuPrimeWorkLimiter.Release();
|
||||||
|
|
||||||
compositeDetected = compositeFlag != 0;
|
compositeDetected = compositeFlag[0] != 0;
|
||||||
return compositeDetected;
|
return compositeDetected;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -840,6 +840,8 @@ public class MersenneDivisorCycles
|
|||||||
}
|
}
|
||||||
|
|
||||||
var divisorCycleKernel = GetDivisorCycleKernel(acceleratorIndex);
|
var divisorCycleKernel = GetDivisorCycleKernel(acceleratorIndex);
|
||||||
|
var kernelLauncher = divisorCycleKernel.CreateLauncherDelegate<Action<AcceleratorStream, Index1D, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>>>();
|
||||||
|
|
||||||
while (start <= maxDivisor)
|
while (start <= maxDivisor)
|
||||||
{
|
{
|
||||||
end = Math.Min(start + batchSizeUL - 1UL, maxDivisor);
|
end = Math.Min(start + batchSizeUL - 1UL, maxDivisor);
|
||||||
@@ -860,15 +862,14 @@ public class MersenneDivisorCycles
|
|||||||
// GpuKernelPool.Run((accelerator, stream) =>
|
// GpuKernelPool.Run((accelerator, stream) =>
|
||||||
MemoryBuffer1D<ulong, Stride1D.Dense>? bufferDiv;
|
MemoryBuffer1D<ulong, Stride1D.Dense>? bufferDiv;
|
||||||
MemoryBuffer1D<ulong, Stride1D.Dense>? bufferCycle;
|
MemoryBuffer1D<ulong, Stride1D.Dense>? bufferCycle;
|
||||||
// lock(accelerator)
|
lock(accelerator)
|
||||||
{
|
{
|
||||||
bufferDiv = accelerator.Allocate1D(validDivisors);
|
bufferDiv = accelerator.Allocate1D(validDivisors);
|
||||||
bufferCycle = accelerator.Allocate1D<ulong>(idx);
|
bufferCycle = accelerator.Allocate1D<ulong>(idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
divisorCycleKernel.Launch(
|
kernelLauncher(
|
||||||
stream,
|
stream,
|
||||||
1,
|
|
||||||
idx,
|
idx,
|
||||||
bufferDiv.View,
|
bufferDiv.View,
|
||||||
bufferCycle.View);
|
bufferCycle.View);
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ public static class PerfectNumberConstants
|
|||||||
public const int MaxOddPowersCount = 128;
|
public const int MaxOddPowersCount = 128;
|
||||||
public const int PooledArrayThreshold = 64;
|
public const int PooledArrayThreshold = 64;
|
||||||
public static readonly int RollingAccelerators = 298; //SharedGpuContext.Device.MaxNumThreadsPerGroup;
|
public static readonly int RollingAccelerators = 298; //SharedGpuContext.Device.MaxNumThreadsPerGroup;
|
||||||
public const int ThreadsByAccelerator = 4096;
|
public const int ThreadsByAccelerator = 1;
|
||||||
// TODO: Load these limits from the benchmark-driven configuration so CPU and GPU scans stay aligned with the optimal
|
// TODO: Load these limits from the benchmark-driven configuration so CPU and GPU scans stay aligned with the optimal
|
||||||
// divisor-cycle datasets we generate offline.
|
// divisor-cycle datasets we generate offline.
|
||||||
// TODO: Promote these magic numbers into a runtime profile derived from EvenPerfectBitScanner.Benchmarks so we can retune
|
// TODO: Promote these magic numbers into a runtime profile derived from EvenPerfectBitScanner.Benchmarks so we can retune
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ using System.Diagnostics;
|
|||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
using ILGPU;
|
||||||
using PerfectNumbers.Core.Cpu;
|
using PerfectNumbers.Core.Cpu;
|
||||||
using PerfectNumbers.Core.Gpu;
|
using PerfectNumbers.Core.Gpu;
|
||||||
using PerfectNumbers.Core.Gpu.Accelerators;
|
using PerfectNumbers.Core.Gpu.Accelerators;
|
||||||
@@ -65,9 +66,9 @@ internal static partial class PrimeOrderCalculator
|
|||||||
ulong result;
|
ulong result;
|
||||||
if (phiFactors.Factors is null)
|
if (phiFactors.Factors is null)
|
||||||
{
|
{
|
||||||
result = prime <= PerfectNumberConstants.MaxQForDivisorCycles
|
result = /*prime <= PerfectNumberConstants.MaxQForDivisorCycles
|
||||||
? CalculateByFactorizationGpu(gpu, prime, divisorData)
|
? CalculateByFactorizationGpu(gpu, prime, divisorData)
|
||||||
: CalculateByFactorizationCpu(gpu, prime, divisorData);
|
: */CalculateByFactorizationCpu(gpu, prime, divisorData);
|
||||||
|
|
||||||
phiFactors.Dispose();
|
phiFactors.Dispose();
|
||||||
PrimeOrderCalculatorAccelerator.Return(gpu);
|
PrimeOrderCalculatorAccelerator.Return(gpu);
|
||||||
@@ -108,7 +109,8 @@ internal static partial class PrimeOrderCalculator
|
|||||||
{
|
{
|
||||||
orderFactors?.Dispose();
|
orderFactors?.Dispose();
|
||||||
// GpuPrimeWorkLimiter.Release();
|
// GpuPrimeWorkLimiter.Release();
|
||||||
return CalculateByFactorizationGpu(gpu, prime, divisorData);
|
return CalculateByFactorizationCpu(gpu, prime, divisorData);
|
||||||
|
// return CalculateByFactorizationGpu(gpu, prime, divisorData);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TryHeuristicFinishCpu(gpu, prime, candidateOrder, previousOrder, divisorData, config, phiFactors, orderFactors, out ulong order))
|
if (TryHeuristicFinishCpu(gpu, prime, candidateOrder, previousOrder, divisorData, config, phiFactors, orderFactors, out ulong order))
|
||||||
@@ -136,7 +138,7 @@ internal static partial class PrimeOrderCalculator
|
|||||||
|
|
||||||
Span<ulong> stackBuffer = stackalloc ulong[length];
|
Span<ulong> stackBuffer = stackalloc ulong[length];
|
||||||
|
|
||||||
if (length <= 7)
|
if (length <= 9)
|
||||||
{
|
{
|
||||||
return EvaluateSpecialMaxCandidates(stackBuffer, factorSpan, phi, prime, divisorData);
|
return EvaluateSpecialMaxCandidates(stackBuffer, factorSpan, phi, prime, divisorData);
|
||||||
}
|
}
|
||||||
@@ -1055,17 +1057,17 @@ internal static partial class PrimeOrderCalculator
|
|||||||
private static ulong _pow2CpuHits;
|
private static ulong _pow2CpuHits;
|
||||||
private static bool Pow2EqualsOneCpu(PrimeOrderCalculatorAccelerator gpu, ulong exponent, ulong prime, in MontgomeryDivisorData divisorData)
|
private static bool Pow2EqualsOneCpu(PrimeOrderCalculatorAccelerator gpu, ulong exponent, ulong prime, in MontgomeryDivisorData divisorData)
|
||||||
{
|
{
|
||||||
if (exponent <= (PerfectNumberConstants.MaxQForDivisorCycles) || prime <= (PerfectNumberConstants.MaxQForDivisorCycles))
|
// if (exponent >= PerfectNumberConstants.MaxQForDivisorCycles || prime >= PerfectNumberConstants.MaxQForDivisorCycles)
|
||||||
{
|
// {
|
||||||
// Atomic.Add(ref _pow2GpuHits, 1);
|
// // Atomic.Add(ref _pow2GpuHits, 1);
|
||||||
// Console.WriteLine($"pow2 GPU Hits {_pow2GpuHits}");
|
// // Console.WriteLine($"pow2 GPU Hits {_pow2GpuHits}");
|
||||||
ulong remainder = exponent.Pow2MontgomeryModWindowedConvertGpu(gpu, divisorData);
|
// ulong remainder = exponent.Pow2MontgomeryModWindowedConvertGpu(gpu, divisorData);
|
||||||
// GpuPow2ModStatus status = PrimeOrderGpuHeuristics.TryPow2Mod(exponent, prime, out ulong remainder, divisorData);
|
// // GpuPow2ModStatus status = PrimeOrderGpuHeuristics.TryPow2Mod(exponent, prime, out ulong remainder, divisorData);
|
||||||
// if (status == GpuPow2ModStatus.Success)
|
// // if (status == GpuPow2ModStatus.Success)
|
||||||
// {
|
// // {
|
||||||
return remainder == 1UL;
|
// return remainder == 1UL;
|
||||||
// }
|
// // }
|
||||||
}
|
// }
|
||||||
|
|
||||||
// Atomic.Add(ref _pow2CpuHits, 1);
|
// Atomic.Add(ref _pow2CpuHits, 1);
|
||||||
// Console.WriteLine($"pow2 CPU Hits {_pow2CpuHits}");
|
// Console.WriteLine($"pow2 CPU Hits {_pow2CpuHits}");
|
||||||
@@ -1077,6 +1079,7 @@ internal static partial class PrimeOrderCalculator
|
|||||||
// private static ulong _partialFactorCofactorHits;
|
// private static ulong _partialFactorCofactorHits;
|
||||||
|
|
||||||
private static bool _goToGpu = true;
|
private static bool _goToGpu = true;
|
||||||
|
private static int _cpuCount;
|
||||||
|
|
||||||
private static PartialFactorResult PartialFactor(PrimeOrderCalculatorAccelerator gpu, ulong value, in PrimeOrderSearchConfig config)
|
private static PartialFactorResult PartialFactor(PrimeOrderCalculatorAccelerator gpu, ulong value, in PrimeOrderSearchConfig config)
|
||||||
{
|
{
|
||||||
@@ -1163,11 +1166,19 @@ internal static partial class PrimeOrderCalculator
|
|||||||
// Console.WriteLine($"Partial factor hits {Volatile.Read(ref _partialFactorHits)}");
|
// Console.WriteLine($"Partial factor hits {Volatile.Read(ref _partialFactorHits)}");
|
||||||
|
|
||||||
// bool isPrime = PrimeTester.IsPrimeCpu(composite, CancellationToken.None);
|
// bool isPrime = PrimeTester.IsPrimeCpu(composite, CancellationToken.None);
|
||||||
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(gpu, composite)
|
// ? HeuristicCombinedPrimeTester.IsPrimeGpu(gpu, composite)
|
||||||
: PrimeTester.IsPrime(composite);
|
// : PrimeTester.IsPrime(composite);
|
||||||
|
// bool isPrime = composite > PerfectNumberConstants.MaxQForDivisorCycles
|
||||||
|
// ? HeuristicCombinedPrimeTester.IsPrimeGpu(gpu, composite)
|
||||||
|
// : PrimeTester.IsPrime(composite);
|
||||||
|
// bool isPrime = HeuristicCombinedPrimeTester.IsPrimeGpu(gpu, composite);
|
||||||
|
bool runOnGpu = RunOnGpu();
|
||||||
|
|
||||||
|
bool isPrime = runOnGpu ? PrimeTester.IsPrime(composite) : HeuristicCombinedPrimeTester.IsPrimeGpu(gpu, composite);
|
||||||
|
// bool isPrime = PrimeTester.IsPrime(composite);
|
||||||
// bool isPrime = Open.Numeric.Primes.Prime.Numbers.IsPrime(composite);
|
// bool isPrime = Open.Numeric.Primes.Prime.Numbers.IsPrime(composite);
|
||||||
|
|
||||||
if (isPrime)
|
if (isPrime)
|
||||||
@@ -1184,8 +1195,8 @@ internal static partial class PrimeOrderCalculator
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!TryPollardRhoGpu(gpu, composite, out ulong factor))
|
// if (!TryPollardRhoGpu(gpu, composite, out ulong factor))
|
||||||
// if (!TryPollardRhoCpu(composite, deadlineTimestamp, out ulong factor))
|
if (!TryPollardRhoCpu(composite, deadlineTimestamp, out ulong factor))
|
||||||
{
|
{
|
||||||
pending.Add(new PendingEntry(composite, knownComposite: true));
|
pending.Add(new PendingEntry(composite, knownComposite: true));
|
||||||
continue;
|
continue;
|
||||||
@@ -1238,8 +1249,8 @@ internal static partial class PrimeOrderCalculator
|
|||||||
// 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 = PrimeTester.IsPrimeCpu(composite, CancellationToken.None);
|
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);
|
||||||
|
|
||||||
entry = entry.WithPrimality(isPrime);
|
entry = entry.WithPrimality(isPrime);
|
||||||
@@ -1276,9 +1287,9 @@ 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(gpu, cofactor);
|
// cofactorIsPrime = HeuristicCombinedPrimeTester.IsPrimeGpu(gpu, cofactor);
|
||||||
// cofactorIsPrime = PrimeTester.IsPrimeGpu(gpu, cofactor);
|
// cofactorIsPrime = PrimeTester.IsPrimeGpu(gpu, cofactor);
|
||||||
// cofactorIsPrime = PrimeTester.IsPrimeGpu(cofactor);
|
cofactorIsPrime = PrimeTester.IsPrime(cofactor);
|
||||||
// cofactorIsPrime = Open.Numeric.Primes.Prime.Numbers.IsPrime(cofactor);
|
// cofactorIsPrime = Open.Numeric.Primes.Prime.Numbers.IsPrime(cofactor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1362,6 +1373,23 @@ internal static partial class PrimeOrderCalculator
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static bool RunOnGpu()
|
||||||
|
{
|
||||||
|
const int GpuFrequency = 1024 - 1;
|
||||||
|
|
||||||
|
int cpuCount = Atomic.Add(target: ref _cpuCount, 1);
|
||||||
|
if (cpuCount == GpuFrequency)
|
||||||
|
{
|
||||||
|
Atomic.Add(ref _cpuCount, -GpuFrequency);
|
||||||
|
}
|
||||||
|
else if (cpuCount > GpuFrequency)
|
||||||
|
{
|
||||||
|
cpuCount -= GpuFrequency;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cpuCount != GpuFrequency;
|
||||||
|
}
|
||||||
|
|
||||||
private static void PopulateSmallPrimeFactorsCpu(
|
private static void PopulateSmallPrimeFactorsCpu(
|
||||||
ulong value,
|
ulong value,
|
||||||
uint limit,
|
uint limit,
|
||||||
@@ -1731,7 +1759,8 @@ internal static partial class PrimeOrderCalculator
|
|||||||
// ulong candidate = order / primeFactor;
|
// ulong candidate = order / primeFactor;
|
||||||
|
|
||||||
// if (candidate.Pow2MontgomeryModWindowedCpu(divisorData, keepMontgomery: false) == 1UL)
|
// if (candidate.Pow2MontgomeryModWindowedCpu(divisorData, keepMontgomery: false) == 1UL)
|
||||||
if (candidate.Pow2MontgomeryModWindowedConvertGpu(gpu, divisorData) == 1UL)
|
if (candidate.Pow2MontgomeryModWindowedCpu(divisorData, keepMontgomery: false) == 1UL)
|
||||||
|
// if (candidate.Pow2MontgomeryModWindowedConvertGpu(gpu, divisorData) == 1UL)
|
||||||
// if (Pow2EqualsOneCpu(candidate, prime, divisorData))
|
// if (Pow2EqualsOneCpu(candidate, prime, divisorData))
|
||||||
{
|
{
|
||||||
order = candidate;
|
order = candidate;
|
||||||
@@ -1768,9 +1797,9 @@ internal static partial class PrimeOrderCalculator
|
|||||||
// HeuristicPrimeTester tester = _tester ??= new();
|
// HeuristicPrimeTester tester = _tester ??= new();
|
||||||
|
|
||||||
// bool isPrime = primeTester.HeuristicIsPrimeGpu(value);
|
// bool isPrime = primeTester.HeuristicIsPrimeGpu(value);
|
||||||
bool isPrime = HeuristicCombinedPrimeTester.IsPrimeGpu(gpu, value);
|
// bool isPrime = HeuristicCombinedPrimeTester.IsPrimeGpu(gpu, value);
|
||||||
// bool isPrime = PrimeTester.IsPrimeGpu(value);
|
|
||||||
// bool isPrime = PrimeTester.IsPrimeGpu(value);
|
// bool isPrime = PrimeTester.IsPrimeGpu(value);
|
||||||
|
bool isPrime = PrimeTester.IsPrime(value);
|
||||||
// bool isPrime = Open.Numeric.Primes.Prime.Numbers.IsPrime(value);
|
// bool isPrime = Open.Numeric.Primes.Prime.Numbers.IsPrime(value);
|
||||||
if (!knownComposite && isPrime)
|
if (!knownComposite && isPrime)
|
||||||
{
|
{
|
||||||
@@ -1785,8 +1814,9 @@ internal static partial class PrimeOrderCalculator
|
|||||||
// Console.WriteLine($"Factor completely after PollardRho hits {Volatile.Read(ref _factorCompletelyPollardRhoHits)}");
|
// Console.WriteLine($"Factor completely after PollardRho hits {Volatile.Read(ref _factorCompletelyPollardRhoHits)}");
|
||||||
|
|
||||||
// isPrime = primeTester.HeuristicIsPrimeGpu(factor);
|
// isPrime = primeTester.HeuristicIsPrimeGpu(factor);
|
||||||
isPrime = HeuristicCombinedPrimeTester.IsPrimeGpu(gpu, factor);
|
// isPrime = HeuristicCombinedPrimeTester.IsPrimeGpu(gpu, factor);
|
||||||
// isPrime = PrimeTester.IsPrimeGpu(factor);
|
// isPrime = PrimeTester.IsPrimeGpu(factor);
|
||||||
|
isPrime = PrimeTester.IsPrime(factor);
|
||||||
// isPrime = Open.Numeric.Primes.Prime.Numbers.IsPrime(factor);
|
// isPrime = Open.Numeric.Primes.Prime.Numbers.IsPrime(factor);
|
||||||
if (isPrime)
|
if (isPrime)
|
||||||
{
|
{
|
||||||
@@ -1822,7 +1852,8 @@ 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)}");
|
||||||
|
|
||||||
isPrime = HeuristicCombinedPrimeTester.IsPrimeGpu(gpu, quotient);
|
// isPrime = HeuristicCombinedPrimeTester.IsPrimeGpu(gpu, quotient);
|
||||||
|
isPrime = PrimeTester.IsPrime(quotient);
|
||||||
// isPrime = PrimeTester.IsPrimeGpu(quotient);
|
// isPrime = PrimeTester.IsPrimeGpu(quotient);
|
||||||
// isPrime = Open.Numeric.Primes.Prime.Numbers.IsPrime(quotient);
|
// isPrime = Open.Numeric.Primes.Prime.Numbers.IsPrime(quotient);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -145,10 +145,11 @@ internal static partial class PrimeOrderCalculator
|
|||||||
|
|
||||||
ArrayView1D<ulong, Stride1D.Dense> specialMaxResultView = gpu.SpecialMaxResult.View;
|
ArrayView1D<ulong, Stride1D.Dense> specialMaxResultView = gpu.SpecialMaxResult.View;
|
||||||
|
|
||||||
kernel.Launch(
|
var kernelLauncher = kernel.CreateLauncherDelegate<Action<AcceleratorStream, Index1D, ulong, ArrayView1D<ulong, Stride1D.Dense>, int, MontgomeryDivisorData, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>>>();
|
||||||
|
|
||||||
|
kernelLauncher(
|
||||||
stream,
|
stream,
|
||||||
1,
|
1,
|
||||||
1,
|
|
||||||
phi,
|
phi,
|
||||||
specialMaxFactorsView,
|
specialMaxFactorsView,
|
||||||
factorCount,
|
factorCount,
|
||||||
|
|||||||
@@ -207,6 +207,8 @@ public sealed class PrimeTester
|
|||||||
|
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
AcceleratorStream stream = AcceleratorStreamPool.Rent(acceleratorIndex);
|
AcceleratorStream stream = AcceleratorStreamPool.Rent(acceleratorIndex);
|
||||||
|
var kernelLauncher = kernel.CreateLauncherDelegate<Action<AcceleratorStream, Index1D, ArrayView<ulong>, ArrayView<uint>, ArrayView<uint>, ArrayView<uint>, ArrayView<uint>, ArrayView<ulong>, ArrayView<ulong>, ArrayView<ulong>, ArrayView<ulong>, ArrayView<byte>>>();
|
||||||
|
|
||||||
while (pos < totalLength)
|
while (pos < totalLength)
|
||||||
{
|
{
|
||||||
int remaining = totalLength - pos;
|
int remaining = totalLength - pos;
|
||||||
@@ -215,7 +217,7 @@ public sealed class PrimeTester
|
|||||||
var valueSlice = values.Slice(pos, count);
|
var valueSlice = values.Slice(pos, count);
|
||||||
inputView.CopyFromCPU(stream, valueSlice);
|
inputView.CopyFromCPU(stream, valueSlice);
|
||||||
|
|
||||||
kernel.Launch(
|
kernelLauncher(
|
||||||
stream,
|
stream,
|
||||||
count,
|
count,
|
||||||
inputView,
|
inputView,
|
||||||
@@ -285,8 +287,9 @@ public sealed class PrimeTester
|
|||||||
|
|
||||||
AcceleratorStream stream = AcceleratorStreamPool.Rent(acceleratorIndex);
|
AcceleratorStream stream = AcceleratorStreamPool.Rent(acceleratorIndex);
|
||||||
inputBuffer.View.CopyFromCPU(stream, values);
|
inputBuffer.View.CopyFromCPU(stream, values);
|
||||||
|
var kernelLauncher = kernel.CreateLauncherDelegate<Action<AcceleratorStream, Index1D, ArrayView<ulong>, ArrayView<byte>>>();
|
||||||
|
|
||||||
kernel.Launch(stream, length, inputBuffer.View, resultBuffer.View);
|
kernelLauncher(stream, length, inputBuffer.View, resultBuffer.View);
|
||||||
|
|
||||||
resultBuffer.View.CopyToCPU(stream, in results);
|
resultBuffer.View.CopyToCPU(stream, in results);
|
||||||
stream.Synchronize();
|
stream.Synchronize();
|
||||||
|
|||||||
Reference in new issue
Block a user