Remove IDisposable usage and using declarations

This commit is contained in:
Marek Lemańczyk committed 2025-10-13 21:55:16 +02:00
1 parent 305a489d6c
commit 0b43880959
26 files changed
+136 -113

No files matched your search

+2 -2
View File
@@ -76,10 +76,10 @@ public readonly struct ResiduePrimeViews(
public readonly ArrayView1D<ulong, Stride1D.Dense> LastSevenPow2 = lastSevenPow2;
}
public ref struct GpuKernelLease(IDisposable limiter, GpuContextLease gpu, KernelContainer kernels)
public ref struct GpuKernelLease(GpuPrimeWorkLimiter.Lease limiter, GpuContextLease gpu, KernelContainer kernels)
{
private bool disposedValue;
private IDisposable? _limiter = limiter;
private GpuPrimeWorkLimiter.Lease? _limiter = limiter;
private GpuContextLease? _gpu = gpu;
private KernelContainer _kernels = kernels;
private AcceleratorStream? _stream;
@@ -6,13 +6,13 @@ public static class GpuPrimeWorkLimiter
private static readonly object _lock = new();
private static int _currentLimit = 1;
public static IDisposable Acquire()
public static Lease Acquire()
{
// TODO: Inline the pooled limiter guard from the GpuLimiterThroughputBenchmarks so prime-sieve
// GPU jobs stop allocating Releaser instances on every acquisition.
var sem = _semaphore;
sem.Wait();
return new Releaser(sem);
return new Lease(sem);
}
public static void SetLimit(int value)
@@ -36,12 +36,12 @@ public static class GpuPrimeWorkLimiter
}
}
private sealed class Releaser : IDisposable
public sealed class Lease
{
private readonly SemaphoreSlim _sem;
private bool _disposed;
public Releaser(SemaphoreSlim sem)
public Lease(SemaphoreSlim sem)
{
_sem = sem;
}
+4 -4
View File
@@ -6,14 +6,14 @@ public static class GpuWorkLimiter
private static readonly object _lock = new();
private static int _currentLimit = 1;
public static IDisposable Acquire()
public static Lease Acquire()
{
// TODO: Replace the per-call Releaser allocation with the pooled struct-based guard from the
// GpuLimiterThroughputBenchmarks so limiter acquisition does not allocate when we enter the
// GPU scanning hot path.
var sem = _semaphore;
sem.Wait();
return new Releaser(sem);
return new Lease(sem);
}
public static void SetLimit(int value)
@@ -40,12 +40,12 @@ public static class GpuWorkLimiter
}
}
private sealed class Releaser : IDisposable
public sealed class Lease
{
private readonly SemaphoreSlim _sem;
private bool _disposed;
public Releaser(SemaphoreSlim sem)
public Lease(SemaphoreSlim sem)
{
_sem = sem;
}
@@ -844,7 +844,7 @@ public sealed class MersenneNumberDivisorByDivisorGpuTester : IMersenneNumberDiv
private void ReturnBatchResources(Accelerator accelerator, BatchResources resources) => _resourcePools.GetOrAdd(accelerator, static _ => []).Add(resources);
private sealed class BatchResources : IDisposable
private sealed class BatchResources
{
internal BatchResources(MersenneNumberDivisorByDivisorGpuTester owner, Accelerator accelerator, int capacity)
{
@@ -948,7 +948,7 @@ public sealed class MersenneNumberDivisorByDivisorGpuTester : IMersenneNumberDiv
return ComputeAllowedMaxDivisor(prime, _divisorLimit);
}
public DivisorScanSession CreateDivisorSession()
public IMersenneNumberDivisorByDivisorTester.IDivisorScanSession CreateDivisorSession()
{
// Divisor sessions are handed out only after configuration, so this guard would never trigger on the
// production path.
@@ -965,8 +965,6 @@ public sealed class MersenneNumberDivisorByDivisorGpuTester : IMersenneNumberDiv
return new DivisorScanSession(this);
}
IMersenneNumberDivisorByDivisorTester.IDivisorScanSession IMersenneNumberDivisorByDivisorTester.CreateDivisorSession() => CreateDivisorSession();
}
@@ -6,7 +6,7 @@ using ILGPU.Runtime;
namespace PerfectNumbers.Core.Gpu;
internal sealed class MersenneNumberDivisorCandidateGpuEvaluator : IDisposable
internal sealed class MersenneNumberDivisorCandidateGpuEvaluator
{
private const int RemainderCount = 6;
@@ -7,7 +7,7 @@ using ILGPU.Runtime;
namespace PerfectNumbers.Core.Gpu;
internal sealed class MersenneNumberDivisorMontgomeryGpuBuilder : IDisposable
internal sealed class MersenneNumberDivisorMontgomeryGpuBuilder
{
private readonly GpuContextPool.GpuContextLease _lease;
private readonly Accelerator _accelerator;
@@ -6,7 +6,7 @@ using ILGPU.Runtime;
namespace PerfectNumbers.Core.Gpu;
internal sealed class MersenneNumberDivisorRemainderGpuStepper : IDisposable
internal sealed class MersenneNumberDivisorRemainderGpuStepper
{
private const int RemainderCount = 6;
@@ -7,7 +7,7 @@ using ILGPU.Runtime;
namespace PerfectNumbers.Core.Gpu;
internal sealed class MersenneNumberDivisorResidueGpuEvaluator : IDisposable
internal sealed class MersenneNumberDivisorResidueGpuEvaluator
{
private readonly GpuContextPool.GpuContextLease _lease;
private readonly Accelerator _accelerator;
@@ -327,8 +327,9 @@ public class MersenneNumberLucasLehmerGpuTester
// TODO: Replace StreamWriter with the pooled TextFileWriter pipeline so persisting NTT
// parameters reuses the zero-allocation buffered writes highlighted in the scanner I/O
// benchmarks instead of allocating a new encoder per append.
using var writer = new StreamWriter(ParameterFilePath, append: true);
var writer = new StreamWriter(ParameterFilePath, append: true);
writer.WriteLine($"{length} {modulus.High} {modulus.Low} {primitiveRoot.High} {primitiveRoot.Low}");
writer.Dispose();
}
}
@@ -338,7 +339,7 @@ public class MersenneNumberLucasLehmerGpuTester
ulong foundRoot = 0UL;
bool success = false;
var processorCount = Environment.ProcessorCount;
using var cts = new System.Threading.CancellationTokenSource();
var cts = new System.Threading.CancellationTokenSource();
object sync = new();
// TODO: Move this Parallel.For to the shared low-overhead work scheduler once the NTT parameter
@@ -381,11 +382,13 @@ public class MersenneNumberLucasLehmerGpuTester
{
modulus = new GpuUInt128(0UL, foundCandidate);
primitiveRoot = new GpuUInt128(0UL, foundRoot);
cts.Dispose();
return true;
}
modulus = new GpuUInt128(0UL, 18446744069414584321UL);
primitiveRoot = new GpuUInt128(0UL, 7UL);
cts.Dispose();
return false;
}
@@ -64,31 +64,25 @@ internal static class MontgomeryOddPowerGpu
var accelerator = lease.Accelerator;
var stream = lease.Stream;
using var divisorBuffer = accelerator.Allocate1D<MontgomeryDivisorData>(divisorCount);
using var countBuffer = accelerator.Allocate1D<int>(divisorCount);
using var resultBuffer = accelerator.Allocate1D<ulong>(divisorCount * stride);
var divisorBuffer = accelerator.Allocate1D<MontgomeryDivisorData>(divisorCount);
var countBuffer = accelerator.Allocate1D<int>(divisorCount);
var resultBuffer = accelerator.Allocate1D<ulong>(divisorCount * stride);
try
{
divisorBuffer.View.CopyFromCPU(ref MemoryMarshal.GetReference(divisors), divisorCount);
countBuffer.View.CopyFromCPU(ref MemoryMarshal.GetReference(oddPowerCounts), divisorCount);
resultBuffer.MemSetToZero();
divisorBuffer.View.CopyFromCPU(ref MemoryMarshal.GetReference(divisors), divisorCount);
countBuffer.View.CopyFromCPU(ref MemoryMarshal.GetReference(oddPowerCounts), divisorCount);
resultBuffer.MemSetToZero();
var kernel = lease.MontgomeryOddPowerKernel;
kernel(stream, divisorCount, divisorBuffer.View, countBuffer.View, resultBuffer.View, stride);
stream.Synchronize();
var kernel = lease.MontgomeryOddPowerKernel;
kernel(stream, divisorCount, divisorBuffer.View, countBuffer.View, resultBuffer.View, stride);
stream.Synchronize();
resultBuffer.View.CopyToCPU(ref MemoryMarshal.GetReference(results), divisorCount * stride);
return true;
}
catch
{
return false;
}
finally
{
execution.Dispose();
lease.Dispose();
}
resultBuffer.View.CopyToCPU(ref MemoryMarshal.GetReference(results), divisorCount * stride);
resultBuffer.Dispose();
countBuffer.Dispose();
divisorBuffer.Dispose();
execution.Dispose();
lease.Dispose();
return true;
}
}
+1 -1
View File
@@ -47,7 +47,7 @@ public static class NttGpuMath
private static readonly ConcurrentDictionary<Accelerator, Action<Index1D, ArrayView<GpuUInt128>, int>> BitReverseKernelCache = new(); // TODO: Precompute bit-reversal kernels during boot so we can remove the concurrent lookup overhead flagged in the benchmarks.
private sealed class SquareCacheEntry : IDisposable
private sealed class SquareCacheEntry
{
public MemoryBuffer1D<GpuUInt128, Stride1D.Dense> Buffer { get; }
public GpuUInt128 Root { get; }
@@ -18,8 +18,10 @@ public interface IMersenneNumberDivisorByDivisorTester
void PrepareCandidates(ReadOnlySpan<ulong> primes, Span<ulong> allowedMaxValues);
public interface IDivisorScanSession : IDisposable
public interface IDivisorScanSession
{
void CheckDivisor(ulong divisor, in MontgomeryDivisorData divisorData, ulong divisorCycle, ReadOnlySpan<ulong> primes, Span<byte> hits);
void Dispose();
}
}
+6 -3
View File
@@ -196,7 +196,7 @@ public class MersenneDivisorCycles
public static IEnumerable<(ulong divisor, ulong cycleLength)> EnumerateStream(Stream compressor)
{
// Binary pairs: (ulong divisor, ulong cycle)
using var reader = new BinaryReader(compressor, Encoding.UTF8, leaveOpen: true);
var reader = new BinaryReader(compressor, Encoding.UTF8, leaveOpen: true);
while (true)
{
ulong d, c;
@@ -207,6 +207,7 @@ public class MersenneDivisorCycles
}
catch (EndOfStreamException)
{
reader.Dispose();
yield break;
}
@@ -829,7 +830,7 @@ public class MersenneDivisorCycles
// Start fresh to avoid mixing formats
outputStream.SetLength(0L);
outputStream.Position = 0L;
using var writer = new BinaryWriter(outputStream, Encoding.UTF8, leaveOpen: false);
var writer = new BinaryWriter(outputStream, Encoding.UTF8, leaveOpen: false);
for (var taskIndex = 0; taskIndex < threads; taskIndex++)
{
ulong threadStart = start + (ulong)taskIndex * blockSize;
@@ -911,6 +912,7 @@ public class MersenneDivisorCycles
}
Task.WaitAll(tasks);
writer.Dispose();
}
public static void GenerateGpu(string path, ulong maxDivisor, int batchSize = 1_000_000, long skipCount = 0L, long nextPosition = 0L)
@@ -947,7 +949,7 @@ public class MersenneDivisorCycles
outputStream.Position = 0L;
}
using var writer = new BinaryWriter(outputStream, Encoding.UTF8, leaveOpen: false);
var writer = new BinaryWriter(outputStream, Encoding.UTF8, leaveOpen: false);
try
{
while (skipCount > 0L && start <= maxDivisor)
@@ -1022,6 +1024,7 @@ public class MersenneDivisorCycles
pool.Return(outCycles, clearArray: false);
}
writer.Dispose();
stream.Dispose();
lease.Dispose();
@@ -3,7 +3,7 @@ using System.Buffers;
namespace PerfectNumbers.Core
{
internal sealed class PrimeFactorPartialResult : IDisposable
internal sealed class PrimeFactorPartialResult
{
[ThreadStatic]
private static PrimeFactorPartialResult? s_poolHead;
+1 -1
View File
@@ -176,7 +176,7 @@ public sealed class PrimeTester(bool useInternal = false)
DevicePrimes.View.CopyFromCPU(primes);
}
internal sealed class ScratchBuffers : IDisposable
internal sealed class ScratchBuffers
{
public MemoryBuffer1D<ulong, Stride1D.Dense> Input { get; private set; }
public MemoryBuffer1D<byte, Stride1D.Dense> Output { get; private set; }
+1 -1
View File
@@ -3,7 +3,7 @@ namespace PerfectNumbers.Core;
/// <summary>
/// Provides thread-safe file writing for both text and binary data.
/// </summary>
public sealed class TextFileWriter : IDisposable
public sealed class TextFileWriter
{
private readonly FileStream _stream;
private StreamWriter? _textWriter;