Factoring switched to PrimeTester.IsPrime for the best performance. PrimeOrderCalculator.PartialFactor switched to GPU factorization. Every so often it will send work to GPU instead of CPU. BatchedResources renamed to MersenneNumberDivisorByDivisorAccelerator for consistency and moved to its own file. It now uses array instead of dictionary for lookup free performance.
This commit is contained in:
1 parent
7b09c1fd3b
commit
6d1ff1372e
7 files changed
+202
-240
No files matched your search
@@ -0,0 +1,119 @@
|
||||
using System.Buffers;
|
||||
using ILGPU;
|
||||
using ILGPU.Runtime;
|
||||
|
||||
namespace PerfectNumbers.Core.Gpu;
|
||||
|
||||
public sealed class MersenneNumberDivisorByDivisorAccelerator
|
||||
{
|
||||
internal MersenneNumberDivisorByDivisorAccelerator(Accelerator accelerator, int capacity)
|
||||
{
|
||||
ArrayPool<ulong> ulongPool = ThreadStaticPools.UlongPool;
|
||||
ArrayPool<int> intPool = ThreadStaticPools.IntPool;
|
||||
ArrayPool<GpuDivisorPartialData> partialPool = ThreadStaticPools.GpuDivisorPartialDataPool;
|
||||
|
||||
Divisors = ulongPool.Rent(capacity);
|
||||
Exponents = ulongPool.Rent(capacity);
|
||||
DivisorData = partialPool.Rent(capacity);
|
||||
Offsets = intPool.Rent(capacity);
|
||||
Counts = intPool.Rent(capacity);
|
||||
Cycles = ulongPool.Rent(capacity);
|
||||
|
||||
lock (accelerator)
|
||||
{
|
||||
DivisorDataBuffer = accelerator.Allocate1D<GpuDivisorPartialData>(capacity);
|
||||
OffsetBuffer = accelerator.Allocate1D<int>(capacity);
|
||||
CountBuffer = accelerator.Allocate1D<int>(capacity);
|
||||
CycleBuffer = accelerator.Allocate1D<ulong>(capacity);
|
||||
ExponentBuffer = accelerator.Allocate1D<ulong>(capacity);
|
||||
HitsBuffer = accelerator.Allocate1D<byte>(capacity);
|
||||
HitIndexBuffer = accelerator.Allocate1D<int>(1);
|
||||
|
||||
CheckDivisorKernel = KernelUtil.GetKernel(accelerator.LoadAutoGroupedStreamKernel<Index1D, ArrayView<GpuDivisorPartialData>, ArrayView<int>, ArrayView<int>, ArrayView<ulong>, ArrayView<ulong>, ArrayView<byte>, ArrayView<int>>(DivisorByDivisorKernels.CheckKernel));
|
||||
}
|
||||
}
|
||||
|
||||
internal MemoryBuffer1D<GpuDivisorPartialData, Stride1D.Dense> DivisorDataBuffer;
|
||||
internal MemoryBuffer1D<int, Stride1D.Dense> OffsetBuffer;
|
||||
internal MemoryBuffer1D<int, Stride1D.Dense> CountBuffer;
|
||||
internal MemoryBuffer1D<ulong, Stride1D.Dense> CycleBuffer;
|
||||
internal MemoryBuffer1D<ulong, Stride1D.Dense> ExponentBuffer;
|
||||
internal MemoryBuffer1D<byte, Stride1D.Dense> HitsBuffer;
|
||||
internal MemoryBuffer1D<int, Stride1D.Dense> HitIndexBuffer;
|
||||
|
||||
internal ulong[] Divisors;
|
||||
internal ulong[] Exponents;
|
||||
internal GpuDivisorPartialData[] DivisorData;
|
||||
internal int[] Offsets;
|
||||
internal int[] Counts;
|
||||
internal ulong[] Cycles;
|
||||
internal readonly Kernel CheckDivisorKernel;
|
||||
|
||||
public void EnsureCapacity(Accelerator accelerator, int requiredCapacity)
|
||||
{
|
||||
if (DivisorDataBuffer.Length < requiredCapacity)
|
||||
{
|
||||
ReallocateBuffers(accelerator, requiredCapacity);
|
||||
}
|
||||
}
|
||||
|
||||
private void ReallocateBuffers(Accelerator accelerator, int capacity)
|
||||
{
|
||||
DivisorDataBuffer.Dispose();
|
||||
OffsetBuffer.Dispose();
|
||||
CountBuffer.Dispose();
|
||||
CycleBuffer.Dispose();
|
||||
ExponentBuffer.Dispose();
|
||||
HitsBuffer.Dispose();
|
||||
HitIndexBuffer.Dispose();
|
||||
|
||||
lock (accelerator)
|
||||
{
|
||||
DivisorDataBuffer = accelerator.Allocate1D<GpuDivisorPartialData>(capacity);
|
||||
OffsetBuffer = accelerator.Allocate1D<int>(capacity);
|
||||
CountBuffer = accelerator.Allocate1D<int>(capacity);
|
||||
CycleBuffer = accelerator.Allocate1D<ulong>(capacity);
|
||||
ExponentBuffer = accelerator.Allocate1D<ulong>(capacity);
|
||||
HitsBuffer = accelerator.Allocate1D<byte>(capacity);
|
||||
HitIndexBuffer = accelerator.Allocate1D<int>(1);
|
||||
}
|
||||
|
||||
ArrayPool<ulong> ulongPool = ThreadStaticPools.UlongPool;
|
||||
ArrayPool<int> intPool = ThreadStaticPools.IntPool;
|
||||
ArrayPool<GpuDivisorPartialData> partialPool = ThreadStaticPools.GpuDivisorPartialDataPool;
|
||||
ulongPool.Return(Divisors, clearArray: false);
|
||||
ulongPool.Return(Exponents, clearArray: false);
|
||||
partialPool.Return(DivisorData, clearArray: false);
|
||||
intPool.Return(Offsets, clearArray: false);
|
||||
intPool.Return(Counts, clearArray: false);
|
||||
ulongPool.Return(Cycles, clearArray: false);
|
||||
|
||||
Divisors = ulongPool.Rent(capacity);
|
||||
Exponents = ulongPool.Rent(capacity);
|
||||
DivisorData = partialPool.Rent(capacity);
|
||||
Offsets = intPool.Rent(capacity);
|
||||
Counts = intPool.Rent(capacity);
|
||||
Cycles = ulongPool.Rent(capacity);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
DivisorDataBuffer.Dispose();
|
||||
OffsetBuffer.Dispose();
|
||||
CountBuffer.Dispose();
|
||||
CycleBuffer.Dispose();
|
||||
ExponentBuffer.Dispose();
|
||||
HitsBuffer.Dispose();
|
||||
HitIndexBuffer.Dispose();
|
||||
|
||||
ArrayPool<ulong> ulongPool = ThreadStaticPools.UlongPool;
|
||||
ArrayPool<int> intPool = ThreadStaticPools.IntPool;
|
||||
ArrayPool<GpuDivisorPartialData> partialPool = ThreadStaticPools.GpuDivisorPartialDataPool;
|
||||
ulongPool.Return(Divisors, clearArray: false);
|
||||
ulongPool.Return(Exponents, clearArray: false);
|
||||
partialPool.Return(DivisorData, clearArray: false);
|
||||
intPool.Return(Offsets, clearArray: false);
|
||||
intPool.Return(Counts, clearArray: false);
|
||||
ulongPool.Return(Cycles, clearArray: false);
|
||||
}
|
||||
}
|
||||
@@ -69,7 +69,7 @@ public sealed class PrimeOrderCalculatorAccelerator
|
||||
AcceleratorStream stream = accelerator.CreateStream();
|
||||
// TODO: Review which tables are needed when final execution path is defined.
|
||||
LastDigitGpuTables.WarmUp(i, stream);
|
||||
HeuristicCombinedGpuTables.WarmUp(i, stream);
|
||||
// HeuristicCombinedGpuTables.WarmUp(i, stream);
|
||||
// SmallPrimeFactorGpuTables.WarmUp(i, stream);
|
||||
// SharedHeuristicGpuTables.EnsureStaticTables(accelerator, stream);
|
||||
// _ = GpuKernelPool.GetOrAddKernels(accelerator, stream, KernelType.None);
|
||||
@@ -115,13 +115,13 @@ public sealed class PrimeOrderCalculatorAccelerator
|
||||
|
||||
public Dictionary<ulong, int> Pow2ModEntriesToTestOnHost = [];
|
||||
|
||||
public readonly Action<AcceleratorStream, int, ulong, ArrayView1D<KeyValuePair<ulong, int>, Stride1D.Dense>, MontgomeryDivisorData, ArrayView1D<ulong, Stride1D.Dense>> CheckFactorsKernelLauncher;
|
||||
public readonly Kernel CheckFactorsKernel;
|
||||
|
||||
public readonly Action<AcceleratorStream, Index1D, ArrayView1D<ulong, Stride1D.Dense>, MontgomeryDivisorData, ArrayView1D<ulong, Stride1D.Dense>> ConvertToStandardKernelLauncher;
|
||||
|
||||
public readonly Action<AcceleratorStream, Index1D, byte, ArrayView<int>, ulong, ulong, HeuristicCombinedGpuViews> HeuristicCombinedTrialDivisionKernelLauncher;
|
||||
public readonly Action<AcceleratorStream, Index1D, ArrayView1D<ulong, Stride1D.Dense>, MontgomeryDivisorData, ArrayView1D<ulong, Stride1D.Dense>> KeepMontgomeryKernelLauncher;
|
||||
public readonly Action<AcceleratorStream, ulong, int, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<byte, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>> PollardRhoKernelLauncher;
|
||||
public readonly Kernel PollardRhoKernel;
|
||||
public readonly Action<AcceleratorStream, Index1D, ArrayView1D<GpuUInt128, Stride1D.Dense>, GpuUInt128, ArrayView1D<GpuUInt128, Stride1D.Dense>> Pow2ModWideKernelLauncher;
|
||||
public readonly Action<AcceleratorStream, Index1D, ArrayView<ulong>, ArrayView<byte>> SharesFactorKernelLauncher;
|
||||
public readonly Action<AcceleratorStream, Index1D, ulong, uint, ArrayView1D<uint, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>, int, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<int, Stride1D.Dense>, ArrayView1D<int, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>> SmallPrimeFactorKernelLauncher;
|
||||
@@ -247,9 +247,9 @@ public sealed class PrimeOrderCalculatorAccelerator
|
||||
DevicePrimesPow2LastThree = lastDigitSharedTables.DevicePrimesPow2LastThree.View;
|
||||
DevicePrimesPow2LastNine = lastDigitSharedTables.DevicePrimesPow2LastNine.View;
|
||||
|
||||
DivisorTables = HeuristicCombinedGpuTables
|
||||
.GetStaticTables(acceleratorIndex)
|
||||
.CreateViews();
|
||||
// DivisorTables = HeuristicCombinedGpuTables
|
||||
// .GetStaticTables(acceleratorIndex)
|
||||
// .CreateViews();
|
||||
|
||||
var smallPrimeFactorTables = SmallPrimeFactorGpuTables.GetStaticTables(acceleratorIndex);
|
||||
|
||||
@@ -260,7 +260,7 @@ public sealed class PrimeOrderCalculatorAccelerator
|
||||
SmallPrimeFactorSquares = tables.Squares.View;
|
||||
}
|
||||
|
||||
CheckFactorsKernelLauncher = KernelUtil.GetKernel(accelerator.LoadStreamKernel<int, ulong, ArrayView1D<KeyValuePair<ulong, int>, Stride1D.Dense>, MontgomeryDivisorData, ArrayView1D<ulong, Stride1D.Dense>>(PrimeOrderGpuHeuristics.CheckFactorsKernel)).CreateLauncherDelegate<Action<AcceleratorStream, int, ulong, ArrayView1D<KeyValuePair<ulong, int>, Stride1D.Dense>, MontgomeryDivisorData, ArrayView1D<ulong, Stride1D.Dense>>>();
|
||||
CheckFactorsKernel = KernelUtil.GetKernel(accelerator.LoadStreamKernel<int, ulong, ArrayView1D<KeyValuePair<ulong, int>, Stride1D.Dense>, MontgomeryDivisorData, ArrayView1D<ulong, Stride1D.Dense>>(PrimeOrderGpuHeuristics.CheckFactorsKernel));
|
||||
|
||||
ConvertToStandardKernelLauncher = KernelUtil.GetKernel(accelerator.LoadAutoGroupedStreamKernel<Index1D, ArrayView1D<ulong, Stride1D.Dense>, MontgomeryDivisorData, ArrayView1D<ulong, Stride1D.Dense>>(Pow2MontgomeryKernels.Pow2MontgomeryKernelConvertToStandard)).CreateLauncherDelegate<Action<AcceleratorStream, Index1D, ArrayView1D<ulong, Stride1D.Dense>, MontgomeryDivisorData, ArrayView1D<ulong, Stride1D.Dense>>>();
|
||||
|
||||
@@ -268,7 +268,7 @@ public sealed class PrimeOrderCalculatorAccelerator
|
||||
|
||||
KeepMontgomeryKernelLauncher = KernelUtil.GetKernel(accelerator.LoadAutoGroupedStreamKernel<Index1D, ArrayView1D<ulong, Stride1D.Dense>, MontgomeryDivisorData, ArrayView1D<ulong, Stride1D.Dense>>(Pow2MontgomeryKernels.Pow2MontgomeryKernelKeepMontgomery)).CreateLauncherDelegate<Action<AcceleratorStream, Index1D, ArrayView1D<ulong, Stride1D.Dense>, MontgomeryDivisorData, ArrayView1D<ulong, Stride1D.Dense>>>();
|
||||
|
||||
PollardRhoKernelLauncher = KernelUtil.GetKernel(accelerator.LoadStreamKernel<ulong, int, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<byte, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>>(Pow2MontgomeryKernels.TryPollardRhoKernel)).CreateLauncherDelegate<Action<AcceleratorStream, ulong, int, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<byte, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>>>();
|
||||
PollardRhoKernel = KernelUtil.GetKernel(accelerator.LoadStreamKernel<ulong, int, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<byte, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>>(Pow2MontgomeryKernels.TryPollardRhoKernel));
|
||||
|
||||
Pow2ModWideKernelLauncher = KernelUtil.GetKernel(accelerator.LoadAutoGroupedStreamKernel<Index1D, ArrayView1D<GpuUInt128, Stride1D.Dense>, GpuUInt128, ArrayView1D<GpuUInt128, Stride1D.Dense>>(PrimeOrderGpuHeuristics.Pow2ModKernelWide)).CreateLauncherDelegate<Action<AcceleratorStream, Index1D, ArrayView1D<GpuUInt128, Stride1D.Dense>, GpuUInt128, ArrayView1D<GpuUInt128, Stride1D.Dense>>>();
|
||||
|
||||
|
||||
Reference in new issue
Block a user