Accelerator index added for dictionary-less use-cases
This commit is contained in:
1 parent
6cb63b6e73
commit
0540411cad
21 files changed
+855
-778
No files matched your search
@@ -5,38 +5,38 @@ namespace PerfectNumbers.Core.Gpu.Accelerators;
|
||||
|
||||
public static class AcceleratorStreamPool
|
||||
{
|
||||
private static readonly Dictionary<Accelerator, ConcurrentQueue<AcceleratorStream>> _streams = new(PerfectNumberConstants .RollingAccelerators << 1);
|
||||
private static readonly Accelerator[] _accelerators = AcceleratorPool.Shared.Accelerators;
|
||||
private static readonly SemaphoreSlim[] _locks = new SemaphoreSlim[PerfectNumberConstants.RollingAccelerators];
|
||||
private static readonly ConcurrentQueue<AcceleratorStream>[] _streams = new ConcurrentQueue<AcceleratorStream> [PerfectNumberConstants.RollingAccelerators];
|
||||
|
||||
private static SemaphoreSlim CreateLock() => new(PerfectNumberConstants.ThreadsByStream);
|
||||
private static SemaphoreSlim CreateLock() => new(PerfectNumberConstants.ThreadsByAccelerator);
|
||||
|
||||
private static readonly Dictionary<Accelerator, SemaphoreSlim> _locks = new(PerfectNumberConstants.RollingAccelerators << 1);
|
||||
|
||||
// private static int _rented;
|
||||
|
||||
public static AcceleratorStream Rent(Accelerator accelerator)
|
||||
public static AcceleratorStream Rent(int acceleratorIndex)
|
||||
{
|
||||
var streamLock = _locks[accelerator];
|
||||
var queue = _streams[accelerator];
|
||||
var streamLock = _locks[acceleratorIndex];
|
||||
var queue = _streams[acceleratorIndex];
|
||||
|
||||
streamLock.Wait();
|
||||
|
||||
return queue.TryDequeue(out var stream)
|
||||
? stream
|
||||
: accelerator.CreateStream();
|
||||
: _accelerators[acceleratorIndex].CreateStream();
|
||||
}
|
||||
|
||||
public static void Return(AcceleratorStream stream)
|
||||
public static void Return(int acceleratorIndex, AcceleratorStream stream)
|
||||
{
|
||||
Accelerator accelerator = stream.Accelerator;
|
||||
var streamLock = _locks[accelerator];
|
||||
var queue = _streams[accelerator];
|
||||
var streamLock = _locks[acceleratorIndex];
|
||||
var queue = _streams[acceleratorIndex];
|
||||
queue.Enqueue(stream);
|
||||
streamLock.Release();
|
||||
}
|
||||
|
||||
public static void WarmUp(Accelerator accelerator)
|
||||
public static void WarmUp(int acceleratorIndex)
|
||||
{
|
||||
_streams.Add(accelerator, new());
|
||||
_ = _locks.TryAdd(accelerator, CreateLock());
|
||||
_streams[acceleratorIndex] = new();
|
||||
_locks[acceleratorIndex] = CreateLock();
|
||||
}
|
||||
}
|
||||
@@ -131,9 +131,12 @@ internal sealed class HeuristicPrimeTesterAccelerator
|
||||
|
||||
public HeuristicGpuDivisorTables HeuristicGpuTables => _heuristicDivisorTables;
|
||||
|
||||
private static readonly Accelerator[] _accelerators = AcceleratorPool.Shared.Accelerators;
|
||||
|
||||
internal HeuristicPrimeTesterAccelerator(int minBufferCapacity)
|
||||
{
|
||||
Accelerator accelerator = AcceleratorPool.Shared.Rent();
|
||||
var acceleratorIndex = AcceleratorPool.Shared.Rent();
|
||||
Accelerator accelerator = _accelerators[acceleratorIndex];
|
||||
Context = accelerator.Context;
|
||||
|
||||
Accelerator = accelerator;
|
||||
@@ -141,7 +144,7 @@ internal sealed class HeuristicPrimeTesterAccelerator
|
||||
|
||||
HeuristicTrialDivisionKernel = KernelUtil.GetKernel(accelerator.LoadAutoGroupedStreamKernel<Index1D, ArrayView<int>, ulong, ulong, HeuristicGpuDivisorTableKind, HeuristicGpuDivisorTables>(PrimeTesterKernels.HeuristicTrialDivisionKernel));
|
||||
|
||||
AcceleratorStream stream = AcceleratorStreamPool.Rent(accelerator);
|
||||
AcceleratorStream stream = AcceleratorStreamPool.Rent(acceleratorIndex);
|
||||
|
||||
// GpuStaticTableInitializer.EnsureStaticTables(accelerator, kernels, stream);
|
||||
|
||||
@@ -149,7 +152,7 @@ internal sealed class HeuristicPrimeTesterAccelerator
|
||||
_heuristicDivisorTables = _sharedTables.CreateHeuristicDivisorTables();
|
||||
|
||||
stream.Synchronize();
|
||||
AcceleratorStreamPool.Return(stream);
|
||||
AcceleratorStreamPool.Return(acceleratorIndex, stream);
|
||||
}
|
||||
|
||||
public void EnsureCapacity(int minCapacity)
|
||||
|
||||
@@ -6,13 +6,14 @@ namespace PerfectNumbers.Core.Gpu.Accelerators;
|
||||
|
||||
internal sealed class LastDigitGpuTables
|
||||
{
|
||||
private static readonly Dictionary<Accelerator, LastDigitGpuTables> _sharedTables = new(PerfectNumberConstants.RollingAccelerators);
|
||||
private static readonly Accelerator[] _accelerators = AcceleratorPool.Shared.Accelerators;
|
||||
private static readonly LastDigitGpuTables[] _sharedTables = new LastDigitGpuTables[PerfectNumberConstants.RollingAccelerators];
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
internal static LastDigitGpuTables EnsureStaticTables(Accelerator accelerator) => _sharedTables[accelerator];
|
||||
internal static LastDigitGpuTables EnsureStaticTables(int acceleratorIndex) => _sharedTables[acceleratorIndex];
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
internal static void WarmUp(Accelerator accelerator, AcceleratorStream stream) => _sharedTables[accelerator] = new LastDigitGpuTables(accelerator, stream);
|
||||
internal static void WarmUp(int acceleratorIndex, AcceleratorStream stream) => _sharedTables[acceleratorIndex] = new LastDigitGpuTables(_accelerators[acceleratorIndex], stream);
|
||||
|
||||
internal LastDigitGpuTables(Accelerator accelerator, AcceleratorStream stream)
|
||||
{
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
using ILGPU;
|
||||
using ILGPU.Runtime;
|
||||
using PerfectNumbers.Core.Gpu;
|
||||
using PerfectNumbers.Core.Gpu.Kernels;
|
||||
|
||||
namespace PerfectNumbers.Core.Gpu.Accelerators;
|
||||
@@ -19,8 +18,8 @@ public sealed class PrimeOrderCalculatorAccelerator
|
||||
var pool = _pool ??= [];
|
||||
if (!pool.TryDequeue(out var gpu))
|
||||
{
|
||||
Accelerator accelerator = AcceleratorPool.Shared.Rent();
|
||||
gpu = new(accelerator, PerfectNumberConstants.DefaultFactorsBuffer, primeTesterCapacity, PerfectNumberConstants.DefaultSmallPrimeFactorSlotCount, PerfectNumberConstants.DefaultSpecialMaxFactorCapacity);
|
||||
int acceleratorIndex = AcceleratorPool.Shared.Rent();
|
||||
gpu = new(acceleratorIndex, PerfectNumberConstants.DefaultFactorsBuffer, primeTesterCapacity, PerfectNumberConstants.DefaultSmallPrimeFactorSlotCount, PerfectNumberConstants.DefaultSpecialMaxFactorCapacity);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -65,22 +64,26 @@ public sealed class PrimeOrderCalculatorAccelerator
|
||||
{
|
||||
Console.WriteLine($"Preparing accelerator {i}...");
|
||||
var accelerator = accelerators[i];
|
||||
AcceleratorStreamPool.WarmUp(accelerator);
|
||||
AcceleratorStreamPool.WarmUp(i);
|
||||
// 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(accelerator, stream);
|
||||
LastDigitGpuTables.WarmUp(i, stream);
|
||||
// SharedHeuristicGpuTables.EnsureStaticTables(accelerator, stream);
|
||||
// _ = GpuKernelPool.GetOrAddKernels(accelerator, stream, KernelType.None);
|
||||
// KernelContainer kernels = GpuKernelPool.GetOrAddKernels(accelerator, stream);
|
||||
// GpuStaticTableInitializer.EnsureStaticTables(accelerator, kernels, stream);
|
||||
stream.Synchronize();
|
||||
stream.Dispose();
|
||||
accelerator.Synchronize();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private static readonly Accelerator[] _accelerators = AcceleratorPool.Shared.Accelerators;
|
||||
|
||||
public readonly Accelerator Accelerator;
|
||||
public readonly int AcceleratorIndex;
|
||||
public readonly MemoryBuffer1D<ulong, Stride1D.Dense> Input;
|
||||
public readonly MemoryBuffer1D<ulong, Stride1D.Dense> OutputUlong;
|
||||
public MemoryBuffer1D<ulong, Stride1D.Dense> PrimeTestInput;
|
||||
@@ -161,9 +164,11 @@ public sealed class PrimeOrderCalculatorAccelerator
|
||||
}
|
||||
}
|
||||
|
||||
public PrimeOrderCalculatorAccelerator(Accelerator accelerator, int factorsCount, int primeTesterCapacity, int smallPrimeFactorSlotCount, int specialMaxFactorCapacity)
|
||||
public PrimeOrderCalculatorAccelerator(int acceleratorIndex, int factorsCount, int primeTesterCapacity, int smallPrimeFactorSlotCount, int specialMaxFactorCapacity)
|
||||
{
|
||||
var accelerator = _accelerators[acceleratorIndex];
|
||||
Accelerator = accelerator;
|
||||
AcceleratorIndex = acceleratorIndex;
|
||||
Input = accelerator.Allocate1D<ulong>(1);
|
||||
OutputUlong = accelerator.Allocate1D<ulong>(1);
|
||||
Pow2ModEntriesToTestOnDevice = accelerator.Allocate1D<KeyValuePair<ulong, int>>(factorsCount);
|
||||
@@ -179,7 +184,7 @@ public sealed class PrimeOrderCalculatorAccelerator
|
||||
SpecialMaxCandidates = accelerator.Allocate1D<ulong>(specialMaxFactorCapacity);
|
||||
SpecialMaxResult = accelerator.Allocate1D<ulong>(1);
|
||||
|
||||
var sharedTables = LastDigitGpuTables.EnsureStaticTables(accelerator);
|
||||
var sharedTables = LastDigitGpuTables.EnsureStaticTables(acceleratorIndex);
|
||||
|
||||
DevicePrimesLastOne = sharedTables.DevicePrimesLastOne;
|
||||
DevicePrimesLastSeven = sharedTables.DevicePrimesLastSeven;
|
||||
|
||||
Reference in new issue
Block a user