diff --git a/PerfectNumbers.Core/Gpu/GpuContextPool.cs b/PerfectNumbers.Core/Gpu/GpuContextPool.cs index ae11bda..eb9d26c 100644 --- a/PerfectNumbers.Core/Gpu/GpuContextPool.cs +++ b/PerfectNumbers.Core/Gpu/GpuContextPool.cs @@ -13,13 +13,14 @@ public static class GpuContextPool { public readonly Context Context; public readonly Accelerator Accelerator; + public readonly KernelContainer Kernels; public PooledContext(KernelContainer kernels) { Context = SharedGpuContext.Context; Accelerator = SharedGpuContext.Accelerator; + Kernels = kernels; GpuStaticTableInitializer.EnsureStaticTables(kernels, Accelerator); - kernels.Dispose(); // 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,6 +35,7 @@ public static class GpuContextPool // Clear any per-accelerator cached resources to avoid releasing // after the accelerator is destroyed. PrimeTester.ClearGpuCaches(Accelerator); + Kernels.Dispose(); // These resources are shared between GPU leases // Accelerator.Dispose(); @@ -53,7 +55,9 @@ public static class GpuContextPool } // Create a new accelerator when the pool does not have one available. - return new GpuContextLease(new PooledContext(GpuKernelPool.GetKernels())); + KernelContainer kernels = GpuKernelPool.GetKernels(); + var context = new PooledContext(kernels); + return new GpuContextLease(context); } @@ -111,6 +115,8 @@ public static class GpuContextPool public Context Context => _ctx!.Context; public Accelerator Accelerator => _ctx!.Accelerator; + public KernelContainer Kernels => _ctx!.Kernels; + public void Dispose() { if (_disposed) diff --git a/PerfectNumbers.Core/Gpu/GpuKernelLease.cs b/PerfectNumbers.Core/Gpu/GpuKernelLease.cs index 1db24b1..fb48461 100644 --- a/PerfectNumbers.Core/Gpu/GpuKernelLease.cs +++ b/PerfectNumbers.Core/Gpu/GpuKernelLease.cs @@ -12,23 +12,22 @@ public sealed class GpuKernelLease private static readonly ConcurrentQueue Pool = new(); private GpuContextLease? _gpu; - public KernelContainer Kernels; + public KernelContainer Kernels = null!; private AcceleratorStream? _stream; - private GpuKernelLease(KernelContainer kernels) + private GpuKernelLease() { - Kernels = kernels; } - internal static GpuKernelLease Rent(GpuContextLease gpu, KernelContainer kernels) + internal static GpuKernelLease Rent(GpuContextLease gpu) { if (!Pool.TryDequeue(out var lease)) { - lease = new GpuKernelLease(kernels); + lease = new GpuKernelLease(); } lease._gpu = gpu; - lease.Kernels = kernels; + lease.Kernels = gpu.Kernels; lease._stream = null; return lease; } @@ -156,9 +155,9 @@ public sealed class GpuKernelLease _gpu?.Dispose(); _gpu = null; + Kernels = null!; - Kernels?.Dispose(); - GpuPrimeWorkLimiter.Release(); + GpuPrimeWorkLimiter.Release(); Pool.Enqueue(this); } diff --git a/PerfectNumbers.Core/Gpu/GpuKernelPool.cs b/PerfectNumbers.Core/Gpu/GpuKernelPool.cs index 365b4d6..e445f6f 100644 --- a/PerfectNumbers.Core/Gpu/GpuKernelPool.cs +++ b/PerfectNumbers.Core/Gpu/GpuKernelPool.cs @@ -299,10 +299,11 @@ public class GpuKernelPool public static GpuKernelLease GetKernel(bool useGpuOrder) { + _ = useGpuOrder; + GpuPrimeWorkLimiter.Acquire(); var gpu = Rent(); - var kernels = GetKernels(); - return GpuKernelLease.Rent(gpu, kernels); + return GpuKernelLease.Rent(gpu); } ///