From 8e779c5c9ee5769e190c9175c29e3f8b48218756 Mon Sep 17 00:00:00 2001 From: mlemanczyk Date: Fri, 7 Nov 2025 15:18:17 +0100 Subject: [PATCH] GpuKernelLease removed --- .../Gpu/GpuKernelCompilationTests.cs | 30 +++++++------- PerfectNumbers.Core/DivisorCycleCache.cs | 4 +- PerfectNumbers.Core/Gpu/GpuKernelLease.cs | 40 ------------------- PerfectNumbers.Core/Gpu/GpuKernelPool.cs | 14 ++----- ...MersenneNumberDivisorByDivisorGpuTester.cs | 7 ++-- .../Gpu/MersenneNumberIncrementalGpuTester.cs | 9 +++-- .../Gpu/MersenneNumberOrderGpuTester.cs | 15 ++++--- .../Gpu/PrimeOrderGpuHeuristics.cs | 21 +++++----- PerfectNumbers.Core/MersenneDivisorCycles.cs | 5 +-- PerfectNumbers.Core/MersenneNumberTester.cs | 6 +-- .../PrimeOrderCalculator.Gpu.cs | 12 +++--- PerfectNumbers.Core/ULongExtensions.Gpu.cs | 4 +- 12 files changed, 60 insertions(+), 107 deletions(-) delete mode 100644 PerfectNumbers.Core/Gpu/GpuKernelLease.cs diff --git a/PerfectNumbers.Core.Tests/Gpu/GpuKernelCompilationTests.cs b/PerfectNumbers.Core.Tests/Gpu/GpuKernelCompilationTests.cs index 0f94715..839a0fb 100644 --- a/PerfectNumbers.Core.Tests/Gpu/GpuKernelCompilationTests.cs +++ b/PerfectNumbers.Core.Tests/Gpu/GpuKernelCompilationTests.cs @@ -330,7 +330,7 @@ public class GpuKernelCompilationTests private static void CompileMersenneDivisorCyclesKernel(Accelerator accelerator) { - var kernel = accelerator.LoadAutoGroupedStreamKernel(MersenneDivisorCyclesKernel); + var kernel = accelerator.LoadAutoGroupedStreamKernel(MersenneDivisorCyclesKernel); _ = kernel; } @@ -349,32 +349,32 @@ public class GpuKernelCompilationTests private static void CompileGpuKernelPoolKernels(Accelerator accelerator) { _ = accelerator; - var lease = GpuKernelPool.Rent(); + GpuPrimeWorkLimiter.Acquire(); try { - _ = GpuKernelLease.OrderKernel; - _ = GpuKernelLease.IncrementalKernel; - _ = GpuKernelLease.Pow2ModKernel; - _ = GpuKernelLease.IncrementalOrderKernel; - _ = GpuKernelLease.Pow2ModOrderKernel; + _ = GpuKernelPool.Kernels.Order; + _ = GpuKernelPool.Kernels.Incremental; + _ = GpuKernelPool.Kernels.Pow2Mod; + _ = GpuKernelPool.Kernels.IncrementalOrder; + _ = GpuKernelPool.Kernels.Pow2ModOrder; } finally { - lease.Dispose(); + GpuPrimeWorkLimiter.Release(); } - var orderLease = GpuKernelPool.Rent(); + GpuPrimeWorkLimiter.Acquire(); try { - _ = GpuKernelLease.OrderKernel; - _ = GpuKernelLease.IncrementalKernel; - _ = GpuKernelLease.Pow2ModKernel; - _ = GpuKernelLease.IncrementalOrderKernel; - _ = GpuKernelLease.Pow2ModOrderKernel; + _ = GpuKernelPool.Kernels.Order; + _ = GpuKernelPool.Kernels.Incremental; + _ = GpuKernelPool.Kernels.Pow2Mod; + _ = GpuKernelPool.Kernels.IncrementalOrder; + _ = GpuKernelPool.Kernels.Pow2ModOrder; } finally { - orderLease.Dispose(); + GpuPrimeWorkLimiter.Release(); } } } diff --git a/PerfectNumbers.Core/DivisorCycleCache.cs b/PerfectNumbers.Core/DivisorCycleCache.cs index 4b3abc4..bba7044 100644 --- a/PerfectNumbers.Core/DivisorCycleCache.cs +++ b/PerfectNumbers.Core/DivisorCycleCache.cs @@ -267,7 +267,7 @@ public sealed class DivisorCycleCache private void ComputeCyclesGpuCore(ReadOnlySpan divisors, Span destination) { int length = divisors.Length; - var gpuLease = GpuKernelPool.Rent(); + GpuPrimeWorkLimiter.Acquire(); Accelerator accelerator = SharedGpuContext.Accelerator; var stream = accelerator.CreateStream(); @@ -349,7 +349,7 @@ public sealed class DivisorCycleCache ThreadStaticPools.BytePool.Return(rentedStatus!, clearArray: false); } - gpuLease.Dispose(); + GpuPrimeWorkLimiter.Release(); } private static Action, ArrayView1D, ArrayView1D, ArrayView1D, ArrayView1D> LoadKernel(Accelerator accelerator) diff --git a/PerfectNumbers.Core/Gpu/GpuKernelLease.cs b/PerfectNumbers.Core/Gpu/GpuKernelLease.cs deleted file mode 100644 index a66dc5b..0000000 --- a/PerfectNumbers.Core/Gpu/GpuKernelLease.cs +++ /dev/null @@ -1,40 +0,0 @@ -using System.Collections.Concurrent; -using ILGPU; -using ILGPU.Runtime; - -namespace PerfectNumbers.Core.Gpu; - -public sealed class GpuKernelLease -{ - private static readonly ConcurrentQueue Pool = new(); - - internal static GpuKernelLease Rent() - { - if (!Pool.TryDequeue(out var lease)) - { - lease = new GpuKernelLease(); - } - - return lease; - } - - public static readonly Action, ArrayView> OrderKernel = GpuKernelPool.Kernels.Order!; - - public static readonly Action, ArrayView1D, ArrayView1D, ArrayView1D, ArrayView1D, ArrayView1D> Pow2ModKernel = GpuKernelPool.Kernels.Pow2Mod!; - - public static readonly Action, ArrayView1D> IncrementalKernel = GpuKernelPool.Kernels.Incremental!; - - public static readonly Action, ArrayView1D> IncrementalOrderKernel = GpuKernelPool.Kernels.IncrementalOrder!; - - public static readonly Action, ArrayView1D> Pow2ModOrderKernel = GpuKernelPool.Kernels.Pow2ModOrder!; - - public static readonly Action, int, MontgomeryDivisorData, ArrayView1D, ArrayView1D> SpecialMaxKernel = GpuKernelPool.Kernels.SpecialMax!; - - public static readonly Action, ArrayView1D, int, ArrayView1D, ArrayView1D, ArrayView1D, ArrayView1D> SmallPrimeFactorKernel = GpuKernelPool.Kernels.SmallPrimeFactor!; - - public void Dispose() - { - Pool.Enqueue(this); - GpuPrimeWorkLimiter.Release(); - } -} diff --git a/PerfectNumbers.Core/Gpu/GpuKernelPool.cs b/PerfectNumbers.Core/Gpu/GpuKernelPool.cs index 2ae5777..b70ae34 100644 --- a/PerfectNumbers.Core/Gpu/GpuKernelPool.cs +++ b/PerfectNumbers.Core/Gpu/GpuKernelPool.cs @@ -22,7 +22,6 @@ public class GpuKernelPool { var kernels = new KernelContainer(); var stream = SharedGpuContext.Accelerator.CreateStream(); - PreloadStaticTables(kernels, stream); InitOnce(ref kernels.Order, () => { @@ -88,6 +87,8 @@ public class GpuKernelPool return kernel.CreateLauncherDelegate, ArrayView1D, int, ArrayView1D, ArrayView1D, ArrayView1D, ArrayView1D>>(); }); + PreloadStaticTables(kernels, stream); + stream.Synchronize(); stream.Dispose(); return kernels; @@ -201,25 +202,18 @@ public class GpuKernelPool return new SmallPrimeFactorViews(devicePrimes, deviceSquares); } - public static GpuKernelLease Rent() - { - GpuPrimeWorkLimiter.Acquire(); - var stream = SharedGpuContext.Accelerator.CreateStream(); - return GpuKernelLease.Rent(); - } - /// /// Runs a GPU action with an acquired accelerator and stream. /// /// Action to run with (Accelerator, Stream). public static void Run(Action action) { - var lease = Rent(); + GpuPrimeWorkLimiter.Acquire(); var accelerator = SharedGpuContext.Accelerator; var stream = accelerator.CreateStream(); action(accelerator, stream); stream.Synchronize(); stream.Dispose(); - lease.Dispose(); + GpuPrimeWorkLimiter.Release(); } } diff --git a/PerfectNumbers.Core/Gpu/MersenneNumberDivisorByDivisorGpuTester.cs b/PerfectNumbers.Core/Gpu/MersenneNumberDivisorByDivisorGpuTester.cs index f682be8..176369f 100644 --- a/PerfectNumbers.Core/Gpu/MersenneNumberDivisorByDivisorGpuTester.cs +++ b/PerfectNumbers.Core/Gpu/MersenneNumberDivisorByDivisorGpuTester.cs @@ -95,7 +95,7 @@ public sealed class MersenneNumberDivisorByDivisorGpuTester : IMersenneNumberDiv ulong processedCount; ulong lastProcessed; - var gpuLease = GpuKernelPool.Rent(); + GpuPrimeWorkLimiter.Acquire(); var accelerator = SharedGpuContext.Accelerator; var stream = accelerator.CreateStream(); @@ -129,7 +129,7 @@ public sealed class MersenneNumberDivisorByDivisorGpuTester : IMersenneNumberDiv stream.Dispose(); ReturnBatchResources(resources); // Monitor.Exit(gpuLease.ExecutionLock); - gpuLease.Dispose(); + GpuPrimeWorkLimiter.Release(); if (composite) { @@ -485,7 +485,6 @@ public sealed class MersenneNumberDivisorByDivisorGpuTester : IMersenneNumberDiv public sealed class DivisorScanSession : IMersenneNumberDivisorByDivisorTester.IDivisorScanSession { private readonly MersenneNumberDivisorByDivisorGpuTester _owner; - private readonly GpuKernelLease _lease; private readonly Accelerator _accelerator; private readonly AcceleratorStream _stream; private Action, ArrayView, ArrayView, ArrayView, ArrayView, ArrayView, ArrayView> _kernel = null!; @@ -502,7 +501,7 @@ public sealed class MersenneNumberDivisorByDivisorGpuTester : IMersenneNumberDiv internal DivisorScanSession(MersenneNumberDivisorByDivisorGpuTester owner) { _owner = owner; - _lease = GpuKernelPool.Rent(); + GpuPrimeWorkLimiter.Acquire(); Accelerator accelerator = SharedGpuContext.Accelerator; _accelerator = accelerator; _stream = accelerator.CreateStream(); diff --git a/PerfectNumbers.Core/Gpu/MersenneNumberIncrementalGpuTester.cs b/PerfectNumbers.Core/Gpu/MersenneNumberIncrementalGpuTester.cs index f7570d7..09ca4ca 100644 --- a/PerfectNumbers.Core/Gpu/MersenneNumberIncrementalGpuTester.cs +++ b/PerfectNumbers.Core/Gpu/MersenneNumberIncrementalGpuTester.cs @@ -16,7 +16,7 @@ public class MersenneNumberIncrementalGpuTester(GpuKernelType kernelType, bool u { throw new NotImplementedException($"GPU incremental scanning requires the device cycle heuristics implementation (kernel: {_kernelType}, GPU order: {_useGpuOrder})."); - var gpuLease = GpuKernelPool.Rent(); + GpuPrimeWorkLimiter.Acquire(); var accelerator = SharedGpuContext.Accelerator; var stream = accelerator.CreateStream(); int batchSize = GpuConstants.ScanBatchSize; // large batch improves GPU occupancy @@ -24,8 +24,9 @@ public class MersenneNumberIncrementalGpuTester(GpuKernelType kernelType, bool u ulong divMul = (ulong)((((UInt128)1 << 64) - UInt128.One) / exponent) + 1UL; byte last = lastDigit == LastDigit.Seven ? (byte)1 : (byte)0; // ILGPU kernels do not support bool parameters - var pow2Kernel = GpuKernelLease.Pow2ModKernel; - var incKernel = GpuKernelLease.IncrementalKernel; + KernelContainer kernels = GpuKernelPool.Kernels; + var pow2Kernel = kernels.Pow2Mod!; + var incKernel = kernels.Incremental!; ulong step10 = (exponent.Mod10() << 1).Mod10(); ulong step8 = ((exponent & 7UL) << 1) & 7UL; ulong step3 = ((exponent % 3UL) << 1) % 3UL; @@ -124,6 +125,6 @@ public class MersenneNumberIncrementalGpuTester(GpuKernelType kernelType, bool u stream.Dispose(); ulongPool.Return(orderArray); orderBuffer.Dispose(); - gpuLease.Dispose(); + GpuPrimeWorkLimiter.Release(); } } diff --git a/PerfectNumbers.Core/Gpu/MersenneNumberOrderGpuTester.cs b/PerfectNumbers.Core/Gpu/MersenneNumberOrderGpuTester.cs index afe290b..372546d 100644 --- a/PerfectNumbers.Core/Gpu/MersenneNumberOrderGpuTester.cs +++ b/PerfectNumbers.Core/Gpu/MersenneNumberOrderGpuTester.cs @@ -9,7 +9,7 @@ public class MersenneNumberOrderGpuTester(GpuKernelType kernelType, bool useGpuO public void Scan(ulong exponent, UInt128 twoP, LastDigit lastDigit, UInt128 maxK, ref bool isPrime) { - var gpuLease = GpuKernelPool.Rent(); + GpuPrimeWorkLimiter.Acquire(); var accelerator = SharedGpuContext.Accelerator; var stream = accelerator.CreateStream(); int batchSize = GpuConstants.ScanBatchSize; // large batch improves GPU occupancy and avoids TDR @@ -17,10 +17,11 @@ public class MersenneNumberOrderGpuTester(GpuKernelType kernelType, bool useGpuO ulong divMul = (ulong)((((UInt128)1 << 64) - UInt128.One) / exponent) + 1UL; byte last = lastDigit == LastDigit.Seven ? (byte)1 : (byte)0; // ILGPU kernels do not support bool parameters + KernelContainer kernels = GpuKernelPool.Kernels; var kernel = _kernelType switch { - GpuKernelType.Pow2Mod => GpuKernelLease.Pow2ModOrderKernel, - _ => GpuKernelLease.IncrementalOrderKernel, + GpuKernelType.Pow2Mod => kernels.Pow2ModOrder!, + _ => kernels.IncrementalOrder!, }; var foundBuffer = accelerator.Allocate1D(1); // TODO: Replace this allocation with the pooled device buffer from GpuOrderKernelBenchmarks so repeated scans reuse the pinned staging memory instead of allocating per run. @@ -46,8 +47,10 @@ public class MersenneNumberOrderGpuTester(GpuKernelType kernelType, bool useGpuO var kernelArgs = new ResidueAutomatonArgs(q0m10, step10, q0m8, step8, q0m3, step3, q0m5, step5); // Ensure device has small cycles table for early rejections in order kernels - kernel(stream, currentSize, exponent, (GpuUInt128)twoP, (GpuUInt128)kStart, last, divMul, - kernelArgs, foundBuffer.View, smallCyclesView); + kernel( + stream, currentSize, exponent, (GpuUInt128)twoP, (GpuUInt128)kStart, + last, divMul, kernelArgs, foundBuffer.View, smallCyclesView + ); foundBuffer.View.CopyToCPU(stream, ref found, 1); stream.Synchronize(); @@ -62,6 +65,6 @@ public class MersenneNumberOrderGpuTester(GpuKernelType kernelType, bool useGpuO stream.Dispose(); foundBuffer.Dispose(); - gpuLease.Dispose(); + GpuPrimeWorkLimiter.Release(); } } diff --git a/PerfectNumbers.Core/Gpu/PrimeOrderGpuHeuristics.cs b/PerfectNumbers.Core/Gpu/PrimeOrderGpuHeuristics.cs index 3aad7a8..6052a19 100644 --- a/PerfectNumbers.Core/Gpu/PrimeOrderGpuHeuristics.cs +++ b/PerfectNumbers.Core/Gpu/PrimeOrderGpuHeuristics.cs @@ -2,10 +2,7 @@ using System.Buffers; using System.Collections.Concurrent; using ILGPU; using ILGPU.Runtime; -using System.Numerics; -using PerfectNumbers.Core; using System.Runtime.InteropServices; -using System.Runtime.CompilerServices; using ILGPU.Runtime.OpenCL; namespace PerfectNumbers.Core.Gpu; @@ -198,7 +195,7 @@ internal static partial class PrimeOrderGpuHeuristics try { - var lease = GpuKernelPool.Rent(); + GpuPrimeWorkLimiter.Acquire(); Accelerator accelerator = SharedGpuContext.Accelerator; AcceleratorStream stream = accelerator.CreateStream(); @@ -254,7 +251,7 @@ internal static partial class PrimeOrderGpuHeuristics countBuffer.Dispose(); remainingBuffer.Dispose(); fullyFactoredBuffer.Dispose(); - lease.Dispose(); + GpuPrimeWorkLimiter.Release(); return true; } catch (CLException ex) @@ -366,7 +363,7 @@ internal static partial class PrimeOrderGpuHeuristics { order = 0UL; - var lease = GpuKernelPool.Rent(); + GpuPrimeWorkLimiter.Acquire(); Accelerator accelerator = SharedGpuContext.Accelerator; AcceleratorStream stream = accelerator.CreateStream(); @@ -444,7 +441,7 @@ internal static partial class PrimeOrderGpuHeuristics stackProductBuffer.Dispose(); resultBuffer.Dispose(); statusBuffer.Dispose(); - lease.Dispose(); + GpuPrimeWorkLimiter.Release(); PrimeOrderKernelStatus kernelStatus = (PrimeOrderKernelStatus)status; if (kernelStatus == PrimeOrderKernelStatus.Fallback) @@ -519,7 +516,7 @@ internal static partial class PrimeOrderGpuHeuristics private static bool TryComputeOnGpu(ReadOnlySpan exponents, ulong prime, in MontgomeryDivisorData divisorData, Span results) { - var lease = GpuKernelPool.Rent(); + GpuPrimeWorkLimiter.Acquire(); Accelerator accelerator = SharedGpuContext.Accelerator; AcceleratorStream? stream = accelerator.CreateStream(); var kernel = GetPow2ModKernel(accelerator); @@ -544,7 +541,7 @@ internal static partial class PrimeOrderGpuHeuristics stream = null; exponentBuffer.Dispose(); remainderBuffer.Dispose(); - lease.Dispose(); + GpuPrimeWorkLimiter.Release(); } catch (Exception) { @@ -552,7 +549,7 @@ internal static partial class PrimeOrderGpuHeuristics stream?.Dispose(); exponentBuffer.Dispose(); remainderBuffer.Dispose(); - lease.Dispose(); + GpuPrimeWorkLimiter.Release(); throw; } @@ -578,7 +575,7 @@ internal static partial class PrimeOrderGpuHeuristics GpuUInt128[]? rentedExponents = null; GpuUInt128[]? rentedResults = null; - var lease = GpuKernelPool.Rent(); + GpuPrimeWorkLimiter.Acquire(); ArrayPool gpuUInt128Pool = ThreadStaticPools.GpuUInt128Pool; try @@ -639,7 +636,7 @@ internal static partial class PrimeOrderGpuHeuristics gpuUInt128Pool.Return(rentedResults!, clearArray: false); } - lease.Dispose(); + GpuPrimeWorkLimiter.Release(); } } diff --git a/PerfectNumbers.Core/MersenneDivisorCycles.cs b/PerfectNumbers.Core/MersenneDivisorCycles.cs index 1fc36d3..2ce1f14 100644 --- a/PerfectNumbers.Core/MersenneDivisorCycles.cs +++ b/PerfectNumbers.Core/MersenneDivisorCycles.cs @@ -795,7 +795,6 @@ public class MersenneDivisorCycles // Prepare output file with header ulong start = 3UL; - var locker = new object(); var pool = ThreadStaticPools.UlongPool; ulong batchSizeUL = (ulong)batchSize, d, end; @@ -804,7 +803,7 @@ public class MersenneDivisorCycles divisors = pool.Rent(count); outCycles = pool.Rent(count); - var lease = GpuKernelPool.Rent(); + GpuPrimeWorkLimiter.Acquire(); var accelerator = SharedGpuContext.Accelerator; var stream = accelerator.CreateStream(); var loaded = accelerator.LoadAutoGroupedStreamKernel< @@ -898,7 +897,7 @@ public class MersenneDivisorCycles pool.Return(divisors, clearArray: false); pool.Return(outCycles, clearArray: false); - lease.Dispose(); + GpuPrimeWorkLimiter.Release(); } diff --git a/PerfectNumbers.Core/MersenneNumberTester.cs b/PerfectNumbers.Core/MersenneNumberTester.cs index c42695c..17ade5e 100644 --- a/PerfectNumbers.Core/MersenneNumberTester.cs +++ b/PerfectNumbers.Core/MersenneNumberTester.cs @@ -147,10 +147,10 @@ public sealed class MersenneNumberTester( UInt128[] qs = qsBuffer; - var gpuLease = GpuKernelPool.Rent(); + GpuPrimeWorkLimiter.Acquire(); var accelerator = SharedGpuContext.Accelerator; var stream = accelerator.CreateStream(); - var orderKernel = GpuKernelLease.OrderKernel!; + var orderKernel = GpuKernelPool.Kernels.Order!; // Guard long-running kernels by chunking the warm-up across batches. // Reuse the same ScanBatchSize knob used for scanning. @@ -197,7 +197,7 @@ public sealed class MersenneNumberTester( } stream.Dispose(); - gpuLease.Dispose(); + GpuPrimeWorkLimiter.Release(); uInt128Pool.Return(qs); } diff --git a/PerfectNumbers.Core/PrimeOrderCalculator.Gpu.cs b/PerfectNumbers.Core/PrimeOrderCalculator.Gpu.cs index 4c5c504..19a9e90 100644 --- a/PerfectNumbers.Core/PrimeOrderCalculator.Gpu.cs +++ b/PerfectNumbers.Core/PrimeOrderCalculator.Gpu.cs @@ -19,7 +19,7 @@ internal static partial class PrimeOrderCalculator Span exponentBuffer = exponentBufferArray.AsSpan(0, GpuSmallPrimeFactorSlots); remaining = value; - var lease = GpuKernelPool.Rent(); + GpuPrimeWorkLimiter.Acquire(); Accelerator accelerator = SharedGpuContext.Accelerator; var stream = accelerator.CreateStream(); KernelContainer kernels = GpuKernelPool.Kernels; @@ -31,7 +31,7 @@ internal static partial class PrimeOrderCalculator if (kernels.SmallPrimeFactorsPrimes is null) throw new NullReferenceException($"{nameof(kernels.SmallPrimeFactorsPrimes)} is null"); if (kernels.SmallPrimeFactorsSquares is null) throw new NullReferenceException($"{nameof(kernels.SmallPrimeFactorsSquares)} is null"); - var kernel = GpuKernelLease.SmallPrimeFactorKernel; + var kernel = GpuKernelPool.Kernels.SmallPrimeFactor!; ArrayView1D smallPrimeFactorCountSlotView = scratch.SmallPrimeFactorCountSlot.View; ArrayView1D smallPrimeFactorRemainingSlotView = scratch.SmallPrimeFactorRemainingSlot.View; @@ -78,7 +78,7 @@ internal static partial class PrimeOrderCalculator } GpuScratchBufferPool.Return(scratch); - lease.Dispose(); + GpuPrimeWorkLimiter.Release(); return true; } @@ -101,7 +101,7 @@ internal static partial class PrimeOrderCalculator factorSpan[i] = factors[i].Value; } - GpuKernelLease lease = GpuKernelPool.Rent(); + GpuPrimeWorkLimiter.Acquire(); Accelerator accelerator = SharedGpuContext.Accelerator; var stream = accelerator.CreateStream(); @@ -111,7 +111,7 @@ internal static partial class PrimeOrderCalculator ArrayView1D specialMaxFactorsView = scratch.SpecialMaxFactors.View; specialMaxFactorsView.SubView(0, factorCount).CopyFromCPU(stream, ref MemoryMarshal.GetReference(factorSpan), factorCount); - var kernel = GpuKernelLease.SpecialMaxKernel; + var kernel = GpuKernelPool.Kernels.SpecialMax!; ArrayView1D specialMaxResultView = scratch.SpecialMaxResult.View; @@ -134,7 +134,7 @@ internal static partial class PrimeOrderCalculator // stream.Synchronize(); // return result != 0; GpuScratchBufferPool.Return(scratch); - lease.Dispose(); + GpuPrimeWorkLimiter.Release(); return result[0] != 0; } } diff --git a/PerfectNumbers.Core/ULongExtensions.Gpu.cs b/PerfectNumbers.Core/ULongExtensions.Gpu.cs index fc2ee8f..91e1564 100644 --- a/PerfectNumbers.Core/ULongExtensions.Gpu.cs +++ b/PerfectNumbers.Core/ULongExtensions.Gpu.cs @@ -461,7 +461,7 @@ public static partial class ULongExtensions { ulong result = 0UL; - GpuKernelLease lease = GpuKernelPool.Rent(); + GpuPrimeWorkLimiter.Acquire(); Accelerator accelerator = SharedGpuContext.Accelerator; AcceleratorStream stream = accelerator.CreateStream(); @@ -484,7 +484,7 @@ public static partial class ULongExtensions stream.Dispose(); resultBuffer.Dispose(); exponentBuffer.Dispose(); - lease.Dispose(); + GpuPrimeWorkLimiter.Release(); return result; }