Ignore zero factors in TrySpecialMaxCpu
This commit is contained in:
1 parent
fddec17b3f
commit
fada9ff098
3 files changed
+70
-43
No files matched your search
@@ -1,3 +1,4 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.Runtime.CompilerServices;
|
||||
using ILGPU;
|
||||
using ILGPU.Runtime;
|
||||
@@ -5,16 +6,38 @@ using static PerfectNumbers.Core.Gpu.GpuContextPool;
|
||||
|
||||
namespace PerfectNumbers.Core.Gpu;
|
||||
|
||||
public ref struct GpuKernelLease(IDisposable limiter, GpuContextLease gpu, KernelContainer kernels)
|
||||
public sealed class GpuKernelLease : IDisposable
|
||||
{
|
||||
private bool disposedValue;
|
||||
private IDisposable? _limiter = limiter;
|
||||
private GpuContextLease? _gpu = gpu;
|
||||
private KernelContainer _kernels = kernels;
|
||||
private AcceleratorStream? _stream;
|
||||
private object? _executionLock = gpu.ExecutionLock;
|
||||
private static readonly ConcurrentQueue<GpuKernelLease> Pool = new();
|
||||
|
||||
public readonly Accelerator Accelerator => _gpu?.Accelerator ?? throw new NullReferenceException("GPU context is already released");
|
||||
private IDisposable? _limiter;
|
||||
private GpuContextLease? _gpu;
|
||||
private KernelContainer? _kernels;
|
||||
private AcceleratorStream? _stream;
|
||||
private object? _executionLock;
|
||||
private bool _disposed;
|
||||
|
||||
private GpuKernelLease()
|
||||
{
|
||||
}
|
||||
|
||||
internal static GpuKernelLease Rent(IDisposable limiter, GpuContextLease gpu, KernelContainer kernels)
|
||||
{
|
||||
if (!Pool.TryDequeue(out var lease))
|
||||
{
|
||||
lease = new GpuKernelLease();
|
||||
}
|
||||
|
||||
lease._limiter = limiter;
|
||||
lease._gpu = gpu;
|
||||
lease._kernels = kernels;
|
||||
lease._stream = null;
|
||||
lease._executionLock = gpu.ExecutionLock;
|
||||
lease._disposed = false;
|
||||
return lease;
|
||||
}
|
||||
|
||||
public Accelerator Accelerator => _gpu?.Accelerator ?? throw new NullReferenceException("GPU context is already released");
|
||||
|
||||
public AcceleratorStream Stream
|
||||
{
|
||||
@@ -32,16 +55,16 @@ public ref struct GpuKernelLease(IDisposable limiter, GpuContextLease gpu, Kerne
|
||||
}
|
||||
}
|
||||
|
||||
public readonly ExecutionScope EnterExecutionScope() => new ExecutionScope(_executionLock);
|
||||
public ExecutionScope EnterExecutionScope() => new ExecutionScope(_executionLock);
|
||||
|
||||
public readonly Action<AcceleratorStream, Index1D, ulong, ulong, ArrayView<GpuUInt128>, ArrayView<ulong>> OrderKernel
|
||||
public Action<AcceleratorStream, Index1D, ulong, ulong, ArrayView<GpuUInt128>, ArrayView<ulong>> OrderKernel
|
||||
{
|
||||
get
|
||||
{
|
||||
var accel = Accelerator; // avoid capturing 'this' in lambda
|
||||
lock (_gpu!.Value.KernelInitLock)
|
||||
{
|
||||
return KernelContainer.InitOnce(ref _kernels.Order, () =>
|
||||
return KernelContainer.InitOnce(ref _kernels!.Order, () =>
|
||||
{
|
||||
var loaded = accel.LoadAutoGroupedStreamKernel<Index1D, ulong, ulong, ArrayView<GpuUInt128>, ArrayView<ulong>>(OrderKernelScan);
|
||||
var kernel = KernelUtil.GetKernel(loaded);
|
||||
@@ -51,14 +74,14 @@ public ref struct GpuKernelLease(IDisposable limiter, GpuContextLease gpu, Kerne
|
||||
}
|
||||
}
|
||||
|
||||
public 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
|
||||
public 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
|
||||
{
|
||||
get
|
||||
{
|
||||
var accel = Accelerator;
|
||||
lock (_gpu!.Value.KernelInitLock)
|
||||
{
|
||||
return KernelContainer.InitOnce(ref _kernels.Pow2Mod, () =>
|
||||
return KernelContainer.InitOnce(ref _kernels!.Pow2Mod, () =>
|
||||
{
|
||||
var loaded = accel.LoadAutoGroupedStreamKernel<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>>(Pow2ModKernelScan);
|
||||
var kernel = KernelUtil.GetKernel(loaded);
|
||||
@@ -68,14 +91,14 @@ public ref struct GpuKernelLease(IDisposable limiter, GpuContextLease gpu, Kerne
|
||||
}
|
||||
}
|
||||
|
||||
public readonly Action<AcceleratorStream, Index1D, ulong, GpuUInt128, GpuUInt128, byte, ulong, ulong, ulong, ulong, ulong, ArrayView<ulong>, ArrayView1D<ulong, Stride1D.Dense>> IncrementalKernel
|
||||
public Action<AcceleratorStream, Index1D, ulong, GpuUInt128, GpuUInt128, byte, ulong, ulong, ulong, ulong, ulong, ArrayView<ulong>, ArrayView1D<ulong, Stride1D.Dense>> IncrementalKernel
|
||||
{
|
||||
get
|
||||
{
|
||||
var accel = Accelerator;
|
||||
lock (_gpu!.Value.KernelInitLock)
|
||||
{
|
||||
return KernelContainer.InitOnce(ref _kernels.Incremental, () =>
|
||||
return KernelContainer.InitOnce(ref _kernels!.Incremental, () =>
|
||||
{
|
||||
var loaded = accel.LoadAutoGroupedStreamKernel<Index1D, ulong, GpuUInt128, GpuUInt128, byte, ulong, ulong, ulong, ulong, ulong, ArrayView<ulong>, ArrayView1D<ulong, Stride1D.Dense>>(IncrementalKernelScan);
|
||||
var kernel = KernelUtil.GetKernel(loaded);
|
||||
@@ -85,14 +108,14 @@ public ref struct GpuKernelLease(IDisposable limiter, GpuContextLease gpu, Kerne
|
||||
}
|
||||
}
|
||||
|
||||
public readonly Action<AcceleratorStream, Index1D, ulong, GpuUInt128, GpuUInt128, byte, ulong, ResidueAutomatonArgs, ArrayView<int>, ArrayView1D<ulong, Stride1D.Dense>> IncrementalOrderKernel
|
||||
public Action<AcceleratorStream, Index1D, ulong, GpuUInt128, GpuUInt128, byte, ulong, ResidueAutomatonArgs, ArrayView<int>, ArrayView1D<ulong, Stride1D.Dense>> IncrementalOrderKernel
|
||||
{
|
||||
get
|
||||
{
|
||||
var accel = Accelerator;
|
||||
lock (_gpu!.Value.KernelInitLock)
|
||||
{
|
||||
return KernelContainer.InitOnce(ref _kernels.IncrementalOrder, () =>
|
||||
return KernelContainer.InitOnce(ref _kernels!.IncrementalOrder, () =>
|
||||
{
|
||||
var loaded = accel.LoadAutoGroupedStreamKernel<Index1D, ulong, GpuUInt128, GpuUInt128, byte, ulong, ResidueAutomatonArgs, ArrayView<int>, ArrayView1D<ulong, Stride1D.Dense>>(IncrementalOrderKernelScan);
|
||||
var kernel = KernelUtil.GetKernel(loaded);
|
||||
@@ -102,14 +125,14 @@ public ref struct GpuKernelLease(IDisposable limiter, GpuContextLease gpu, Kerne
|
||||
}
|
||||
}
|
||||
|
||||
public readonly Action<AcceleratorStream, Index1D, ulong, GpuUInt128, GpuUInt128, byte, ulong, ResidueAutomatonArgs, ArrayView<int>, ArrayView1D<ulong, Stride1D.Dense>> Pow2ModOrderKernel
|
||||
public Action<AcceleratorStream, Index1D, ulong, GpuUInt128, GpuUInt128, byte, ulong, ResidueAutomatonArgs, ArrayView<int>, ArrayView1D<ulong, Stride1D.Dense>> Pow2ModOrderKernel
|
||||
{
|
||||
get
|
||||
{
|
||||
var accel = Accelerator;
|
||||
lock (_gpu!.Value.KernelInitLock)
|
||||
{
|
||||
return KernelContainer.InitOnce(ref _kernels.Pow2ModOrder, () =>
|
||||
return KernelContainer.InitOnce(ref _kernels!.Pow2ModOrder, () =>
|
||||
{
|
||||
var loaded = accel.LoadAutoGroupedStreamKernel<Index1D, ulong, GpuUInt128, GpuUInt128, byte, ulong, ResidueAutomatonArgs, ArrayView<int>, ArrayView1D<ulong, Stride1D.Dense>>(Pow2ModOrderKernelScan);
|
||||
var kernel = KernelUtil.GetKernel(loaded);
|
||||
@@ -119,14 +142,14 @@ public ref struct GpuKernelLease(IDisposable limiter, GpuContextLease gpu, Kerne
|
||||
}
|
||||
}
|
||||
|
||||
public 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
|
||||
public 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
|
||||
{
|
||||
get
|
||||
{
|
||||
var accel = Accelerator;
|
||||
lock (_gpu!.Value.KernelInitLock)
|
||||
{
|
||||
return KernelContainer.InitOnce(ref _kernels.SmallPrimeFactor, () =>
|
||||
return KernelContainer.InitOnce(ref _kernels!.SmallPrimeFactor, () =>
|
||||
{
|
||||
var loaded = accel.LoadAutoGroupedStreamKernel<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>>(SmallPrimeFactorKernelScan);
|
||||
var kernel = KernelUtil.GetKernel(loaded);
|
||||
@@ -343,26 +366,28 @@ public ref struct GpuKernelLease(IDisposable limiter, GpuContextLease gpu, Kerne
|
||||
|
||||
private void Dispose(bool disposing)
|
||||
{
|
||||
if (!disposedValue)
|
||||
if (_disposed)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
_stream?.Dispose();
|
||||
_stream = null;
|
||||
|
||||
_gpu?.Dispose();
|
||||
_gpu = null;
|
||||
|
||||
_executionLock = null;
|
||||
|
||||
_limiter?.Dispose();
|
||||
_limiter = null;
|
||||
}
|
||||
|
||||
// free unmanaged resources (unmanaged objects) and override finalizer
|
||||
// set large fields to null
|
||||
disposedValue = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (disposing)
|
||||
{
|
||||
_stream?.Dispose();
|
||||
_stream = null;
|
||||
|
||||
_gpu?.Dispose();
|
||||
_gpu = null;
|
||||
|
||||
_executionLock = null;
|
||||
|
||||
_limiter?.Dispose();
|
||||
_limiter = null;
|
||||
}
|
||||
|
||||
_kernels = null;
|
||||
_disposed = true;
|
||||
Pool.Enqueue(this);
|
||||
}
|
||||
|
||||
private static void Pow2ModKernelScan(Index1D index, ulong exponent, GpuUInt128 twoP, GpuUInt128 kStart, byte lastIsSeven, ulong _,
|
||||
@@ -677,10 +702,8 @@ public ref struct GpuKernelLease(IDisposable limiter, GpuContextLease gpu, Kerne
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
|
||||
Dispose(disposing: true);
|
||||
// Enabled this when the struct is converted to a class
|
||||
// GC.SuppressFinalize(this);
|
||||
System.GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
public readonly struct ExecutionScope
|
||||
|
||||
@@ -283,7 +283,7 @@ public class GpuKernelPool
|
||||
var gpu = RentPreferred(preferCpu: !useGpuOrder);
|
||||
var accelerator = gpu.Accelerator;
|
||||
var kernels = GetKernels(accelerator);
|
||||
return new(limiter, gpu, kernels);
|
||||
return GpuKernelLease.Rent(limiter, gpu, kernels);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
Reference in new issue
Block a user