GpuKernelLease removed

This commit is contained in:
mlemanczyk committed 2025-11-07 15:18:17 +01:00
1 parent 0410fd2c91
commit da3093a9ba
12 files changed
+58 -105

No files matched your search

-40
View File
@@ -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<GpuKernelLease> Pool = new();
internal static GpuKernelLease Rent()
{
if (!Pool.TryDequeue(out var lease))
{
lease = new GpuKernelLease();
}
return lease;
}
public static readonly Action<AcceleratorStream, Index1D, ulong, ulong, ArrayView<GpuUInt128>, ArrayView<ulong>> OrderKernel = GpuKernelPool.Kernels.Order!;
public static readonly Action<AcceleratorStream, Index1D, ulong, GpuUInt128, GpuUInt128, byte, ulong, ResidueAutomatonArgs, ArrayView<ulong>, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<uint, Stride1D.Dense>, ArrayView1D<uint, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>> Pow2ModKernel = GpuKernelPool.Kernels.Pow2Mod!;
public static readonly Action<AcceleratorStream, Index1D, ulong, GpuUInt128, GpuUInt128, byte, ulong, ulong, ulong, ulong, ulong, ArrayView<ulong>, ArrayView1D<ulong, Stride1D.Dense>> IncrementalKernel = GpuKernelPool.Kernels.Incremental!;
public static readonly Action<AcceleratorStream, Index1D, ulong, GpuUInt128, GpuUInt128, byte, ulong, ResidueAutomatonArgs, ArrayView<int>, ArrayView1D<ulong, Stride1D.Dense>> IncrementalOrderKernel = GpuKernelPool.Kernels.IncrementalOrder!;
public static readonly Action<AcceleratorStream, Index1D, ulong, GpuUInt128, GpuUInt128, byte, ulong, ResidueAutomatonArgs, ArrayView<int>, ArrayView1D<ulong, Stride1D.Dense>> Pow2ModOrderKernel = GpuKernelPool.Kernels.Pow2ModOrder!;
public static readonly Action<AcceleratorStream, Index1D, ulong, ArrayView1D<ulong, Stride1D.Dense>, int, MontgomeryDivisorData, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>> SpecialMaxKernel = GpuKernelPool.Kernels.SpecialMax!;
public static readonly Action<AcceleratorStream, Index1D, ulong, uint, ArrayView1D<uint, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>, int, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<int, Stride1D.Dense>, ArrayView1D<int, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>> SmallPrimeFactorKernel = GpuKernelPool.Kernels.SmallPrimeFactor!;
public void Dispose()
{
Pool.Enqueue(this);
GpuPrimeWorkLimiter.Release();
}
}
+2 -9
View File
@@ -201,25 +201,18 @@ public class GpuKernelPool
return new SmallPrimeFactorViews(devicePrimes, deviceSquares);
}
public static GpuKernelLease Rent()
{
GpuPrimeWorkLimiter.Acquire();
var stream = SharedGpuContext.Accelerator.CreateStream();
return GpuKernelLease.Rent();
}
/// <summary>
/// Runs a GPU action with an acquired accelerator and stream.
/// </summary>
/// <param name="action">Action to run with (Accelerator, Stream).</param>
public static void Run(Action<Accelerator, AcceleratorStream> 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();
}
}
@@ -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<AcceleratorStream, Index1D, ArrayView<GpuDivisorPartialData>, ArrayView<int>, ArrayView<int>, ArrayView<ulong>, ArrayView<ulong>, ArrayView<byte>, ArrayView<int>> _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();
@@ -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();
}
}
@@ -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<int>(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();
}
}
@@ -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<ulong> exponents, ulong prime, in MontgomeryDivisorData divisorData, Span<ulong> 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<GpuUInt128> gpuUInt128Pool = ThreadStaticPools.GpuUInt128Pool;
try
@@ -639,7 +636,7 @@ internal static partial class PrimeOrderGpuHeuristics
gpuUInt128Pool.Return(rentedResults!, clearArray: false);
}
lease.Dispose();
GpuPrimeWorkLimiter.Release();
}
}