HeuristicCombinedPrimeTesterAccelerator integrated with PrimeOrderCalculatorAccelerator.
This commit is contained in:
1 parent
183b147135
commit
f630bfb598
9 files changed
+67
-215
No files matched your search
@@ -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.
|
||||
AcceleratorStream stream = accelerator.CreateStream();
|
||||
LastDigitGpuTables.WarmUp(i, stream);
|
||||
HeuristicCombinedPrimeTesterAccelerator.WarmUp(i, stream);
|
||||
HeuristicGpuCombinedTables.WarmUp(i, stream);
|
||||
// SharedHeuristicGpuTables.EnsureStaticTables(accelerator, stream);
|
||||
// _ = GpuKernelPool.GetOrAddKernels(accelerator, stream, KernelType.None);
|
||||
// KernelContainer kernels = GpuKernelPool.GetOrAddKernels(accelerator, stream);
|
||||
@@ -109,12 +109,16 @@ public sealed class PrimeOrderCalculatorAccelerator
|
||||
public MemoryBuffer1D<ulong, Stride1D.Dense> SpecialMaxFactors;
|
||||
public readonly MemoryBuffer1D<ulong, Stride1D.Dense> SpecialMaxResult;
|
||||
|
||||
public readonly HeuristicGpuCombinedDivisorTables DivisorTables;
|
||||
|
||||
public readonly Kernel SmallPrimeSieveKernel;
|
||||
public readonly Kernel CheckFactorsKernel;
|
||||
public readonly Kernel ConvertToStandardKernel;
|
||||
public readonly Kernel HeuristicCombinedTrialDivisionKernel;
|
||||
public readonly Kernel KeepMontgomeryKernel;
|
||||
public readonly Kernel PollardRhoKernel;
|
||||
public readonly Kernel Pow2ModWideKernel;
|
||||
|
||||
public Kernel SharesFactorKernel;
|
||||
|
||||
|
||||
@@ -186,16 +190,19 @@ public sealed class PrimeOrderCalculatorAccelerator
|
||||
SpecialMaxCandidates = accelerator.Allocate1D<ulong>(specialMaxFactorCapacity);
|
||||
SpecialMaxResult = accelerator.Allocate1D<ulong>(1);
|
||||
|
||||
var sharedTables = LastDigitGpuTables.EnsureStaticTables(acceleratorIndex);
|
||||
var lastDigitSharedTables = LastDigitGpuTables.EnsureStaticTables(acceleratorIndex);
|
||||
|
||||
DevicePrimesLastOne = sharedTables.DevicePrimesLastOne;
|
||||
DevicePrimesLastSeven = sharedTables.DevicePrimesLastSeven;
|
||||
DevicePrimesLastThree = sharedTables.DevicePrimesLastThree;
|
||||
DevicePrimesLastNine = sharedTables.DevicePrimesLastNine;
|
||||
DevicePrimesPow2LastOne = sharedTables.DevicePrimesPow2LastOne;
|
||||
DevicePrimesPow2LastSeven = sharedTables.DevicePrimesPow2LastSeven;
|
||||
DevicePrimesPow2LastThree = sharedTables.DevicePrimesPow2LastThree;
|
||||
DevicePrimesPow2LastNine = sharedTables.DevicePrimesPow2LastNine;
|
||||
DevicePrimesLastOne = lastDigitSharedTables.DevicePrimesLastOne;
|
||||
DevicePrimesLastSeven = lastDigitSharedTables.DevicePrimesLastSeven;
|
||||
DevicePrimesLastThree = lastDigitSharedTables.DevicePrimesLastThree;
|
||||
DevicePrimesLastNine = lastDigitSharedTables.DevicePrimesLastNine;
|
||||
DevicePrimesPow2LastOne = lastDigitSharedTables.DevicePrimesPow2LastOne;
|
||||
DevicePrimesPow2LastSeven = lastDigitSharedTables.DevicePrimesPow2LastSeven;
|
||||
DevicePrimesPow2LastThree = lastDigitSharedTables.DevicePrimesPow2LastThree;
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
KeepMontgomeryKernel = KernelUtil.GetKernel(keepKernel);
|
||||
|
||||
|
||||
@@ -109,7 +109,7 @@ public sealed class MersenneNumberDivisorByDivisorGpuTester : IMersenneNumberDiv
|
||||
// GpuPrimeWorkLimiter();
|
||||
// int acceleratorIndex = AcceleratorPool.Shared.Rent();
|
||||
// var accelerator = _accelerators[acceleratorIndex];
|
||||
var gpu = HeuristicCombinedPrimeTesterAccelerator.Rent(batchCapacity);
|
||||
var gpu = PrimeOrderCalculatorAccelerator.Rent(batchCapacity);
|
||||
var acceleratorIndex = gpu.AcceleratorIndex;
|
||||
var accelerator = gpu.Accelerator;
|
||||
var stream = AcceleratorStreamPool.Rent(acceleratorIndex);
|
||||
@@ -144,7 +144,7 @@ public sealed class MersenneNumberDivisorByDivisorGpuTester : IMersenneNumberDiv
|
||||
|
||||
AcceleratorStreamPool.Return(acceleratorIndex, stream);
|
||||
ReturnBatchResources(resources);
|
||||
HeuristicCombinedPrimeTesterAccelerator.Return(gpu);
|
||||
PrimeOrderCalculatorAccelerator.Return(gpu);
|
||||
// Monitor.Exit(gpuLease.ExecutionLock);
|
||||
// GpuPrimeWorkLimiter.Release();
|
||||
|
||||
@@ -188,7 +188,7 @@ public sealed class MersenneNumberDivisorByDivisorGpuTester : IMersenneNumberDiv
|
||||
}
|
||||
|
||||
private static bool CheckDivisors(
|
||||
HeuristicCombinedPrimeTesterAccelerator gpu,
|
||||
PrimeOrderCalculatorAccelerator gpu,
|
||||
ulong prime,
|
||||
ulong allowedMax,
|
||||
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)]
|
||||
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)
|
||||
{
|
||||
@@ -505,7 +505,7 @@ public sealed class MersenneNumberDivisorByDivisorGpuTester : IMersenneNumberDiv
|
||||
private static readonly Accelerator[] _accelerators = AcceleratorPool.Shared.Accelerators;
|
||||
|
||||
private readonly MersenneNumberDivisorByDivisorGpuTester _owner;
|
||||
private readonly HeuristicCombinedPrimeTesterAccelerator _primeTesterAccelerator;
|
||||
private readonly PrimeOrderCalculatorAccelerator _primeTesterAccelerator;
|
||||
private readonly Accelerator _accelerator;
|
||||
private readonly AcceleratorStream _stream;
|
||||
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;
|
||||
// GpuPrimeWorkLimiter.Acquire();
|
||||
_primeTesterAccelerator = HeuristicCombinedPrimeTesterAccelerator.Rent();
|
||||
_primeTesterAccelerator = PrimeOrderCalculatorAccelerator.Rent(1);
|
||||
Accelerator accelerator = _primeTesterAccelerator.Accelerator;
|
||||
_accelerator = accelerator;
|
||||
_stream = accelerator.CreateStream();
|
||||
|
||||
Reference in new issue
Block a user