GPU contexts and accelerators made shared to prevent application crashes with high no. of threads.

This commit is contained in:
mlemanczyk committed 2025-11-02 12:51:31 +01:00
1 parent b33a3c8e75
commit 0e7bbae132
2 files changed
+29 -19

No files matched your search

+17 -12
View File
@@ -12,13 +12,17 @@ public static class GpuContextPool
// Default device preference for generic GPU kernels (prime scans, NTT, etc.)
internal sealed class PooledContext
{
public Context Context { get; }
public Accelerator Accelerator { get; }
public readonly Context Context;
public readonly Accelerator Accelerator;
private static readonly Context _sharedContext = Context.CreateDefault();
private static readonly Device _sharedDevice = _sharedContext.GetPreferredDevice(false);
private static readonly Accelerator _sharedAccelerator = _sharedDevice.CreateAccelerator(_sharedContext);
public PooledContext()
{
Context = Context.CreateDefault();
Accelerator = Context.GetPreferredDevice(false).CreateAccelerator(Context);
Context = _sharedContext;
Accelerator = _sharedAccelerator;
// NOTE: Avoid loading/compiling any kernel here to prevent implicit
// CL stream/queue creation during accelerator construction.
// Some OpenCL drivers are fragile when a queue is created immediately
@@ -34,8 +38,9 @@ public static class GpuContextPool
// after the accelerator is destroyed.
PrimeTester.ClearGpuCaches(Accelerator);
Accelerator.Dispose();
Context.Dispose();
// These resources are shared between GPU leases
// Accelerator.Dispose();
// Context.Dispose();
}
}
@@ -62,15 +67,15 @@ public static class GpuContextPool
}
int toCreate = threadCount - WarmedGpuContextCount;
Console.WriteLine($"Warming up GPU context pool to {toCreate} contexts...");
var contexts = new PooledContext[toCreate];
var pool = GpuPool;
PooledContext context;
for (int i = 0; i < toCreate; i++)
{
contexts[i] = new PooledContext();
}
for (int i = 0; i < toCreate; i++)
{
GpuPool.Enqueue(contexts[i]);
context = new PooledContext();
contexts[i] = context;
pool.Enqueue(context);
}
WarmedGpuContextCount = threadCount;
+12 -7
View File
@@ -99,7 +99,7 @@ public sealed class PrimeTester
// if (belowGpuRange)
// {
return IsPrime(n);
return IsPrime(n);
// }
// var limiter = GpuPrimeWorkLimiter.Acquire();
@@ -378,12 +378,16 @@ public sealed class PrimeTester
public HeuristicGpuDivisorTables HeuristicGpuTables => _heuristicDivisorTables;
private static readonly Context _sharedContext = Context.CreateDefault();
private static readonly Device _sharedDevice = _sharedContext.GetPreferredDevice(false);
private static readonly Accelerator _sharedAccelerator = _sharedDevice.CreateAccelerator(_sharedContext);
internal PrimeTesterGpuContextLease(int minBufferCapacity)
{
AcceleratorContext = Context.CreateDefault();
Accelerator = AcceleratorContext.GetPreferredDevice(false).CreateAccelerator(AcceleratorContext);
AcceleratorContext = _sharedContext;// Context.CreateDefault();
Accelerator = _sharedAccelerator; //AcceleratorContext.GetPreferredDevice(false).CreateAccelerator(AcceleratorContext);
Kernel = Accelerator.LoadAutoGroupedStreamKernel<Index1D, ArrayView<ulong>, ArrayView<uint>, ArrayView<uint>, ArrayView<uint>, ArrayView<uint>, ArrayView<uint>, ArrayView<ulong>, ArrayView<ulong>, ArrayView<ulong>, ArrayView<ulong>, ArrayView<ulong>, ArrayView<byte>>(PrimeTesterKernels.SmallPrimeSieveKernel);
HeuristicTrialDivisionKernel = Accelerator.LoadAutoGroupedStreamKernel<Index1D, ArrayView<int>, ulong, ulong, HeuristicGpuDivisorTableKind, HeuristicGpuDivisorTables>(PrimeTesterKernels.HeuristicTrialDivisionKernel);
HeuristicTrialDivisionKernel = Accelerator.LoadAutoGroupedStreamKernel<Index1D, ArrayView<int>, ulong, ulong, HeuristicGpuDivisorTableKind, HeuristicGpuDivisorTables>(PrimeTesterKernels.HeuristicTrialDivisionKernel);
_sharedTables = RentSharedTables(Accelerator);
@@ -439,7 +443,7 @@ public sealed class PrimeTester
}
_returned = true;
PrimeTesterGpuContextPool.Return(this);
Return(this);
}
internal void DisposeResources()
@@ -448,8 +452,9 @@ public sealed class PrimeTester
Output?.Dispose();
HeuristicFlag?.Dispose();
ReleaseSharedTables(_sharedTables);
Accelerator.Dispose();
AcceleratorContext.Dispose();
// These resources are shared between GPU leases
// Accelerator.Dispose();
// AcceleratorContext.Dispose();
}
}