From a84445ef2a9710df9cbbe132db180decbbf0392f Mon Sep 17 00:00:00 2001 From: mlemanczyk Date: Sun, 16 Nov 2025 15:01:51 +0100 Subject: [PATCH] Stream handling simplified to avoid dictionary lookups in favor of array lookups with known indexes. --- .../Gpu/GpuKernelCompilationTests.cs | 4 +-- PerfectNumbers.Core/DivisorCycleCache.cs | 2 +- .../Gpu/Accelerators/AcceleratorStreamPool.cs | 20 ++++++------ .../Gpu/Accelerators/HeuristicGpuTables.cs | 32 +++++++++---------- .../HeuristicPrimeTesterAccelerator.cs | 4 +-- PerfectNumbers.Core/Gpu/GpuKernelPool.cs | 2 +- .../Gpu/Kernels/PrimeTesterKernels.cs | 14 ++------ .../Gpu/Pow2MontgomeryGpuCalculator.cs | 6 ++-- .../Gpu/PrimeOrderGpuHeuristics.cs | 10 +++--- PerfectNumbers.Core/HeuristicPrimeTester.cs | 22 +++++++------ PerfectNumbers.Core/MersenneDivisorCycles.cs | 4 +-- PerfectNumbers.Core/MersenneNumberTester.cs | 2 +- PerfectNumbers.Core/PerfectNumberConstants.cs | 2 +- .../PrimeOrderCalculator.Gpu.cs | 8 ++--- PerfectNumbers.Core/PrimeTester.cs | 8 ++--- 15 files changed, 67 insertions(+), 73 deletions(-) diff --git a/PerfectNumbers.Core.Tests/Gpu/GpuKernelCompilationTests.cs b/PerfectNumbers.Core.Tests/Gpu/GpuKernelCompilationTests.cs index b40333b..e60bc24 100644 --- a/PerfectNumbers.Core.Tests/Gpu/GpuKernelCompilationTests.cs +++ b/PerfectNumbers.Core.Tests/Gpu/GpuKernelCompilationTests.cs @@ -363,7 +363,7 @@ public class GpuKernelCompilationTests finally { stream.Synchronize(); - AcceleratorStreamPool.Return(acceleratorIndex, stream); + AcceleratorStreamPool.Return(acceleratorIndex); // GpuPrimeWorkLimiter.Release(); } @@ -381,7 +381,7 @@ public class GpuKernelCompilationTests finally { stream.Synchronize(); - AcceleratorStreamPool.Return(acceleratorIndex, stream); + AcceleratorStreamPool.Return(acceleratorIndex); // GpuPrimeWorkLimiter.Release(); } } diff --git a/PerfectNumbers.Core/DivisorCycleCache.cs b/PerfectNumbers.Core/DivisorCycleCache.cs index 26e7a6b..5e11b31 100644 --- a/PerfectNumbers.Core/DivisorCycleCache.cs +++ b/PerfectNumbers.Core/DivisorCycleCache.cs @@ -345,7 +345,7 @@ public sealed class DivisorCycleCache resultBuffer.View.CopyToCPU(stream, resultSpan); stream.Synchronize(); - AcceleratorStreamPool.Return(acceleratorIndex, stream); + AcceleratorStreamPool.Return(acceleratorIndex); resultSpan.CopyTo(destination); if (rentedPow is not null) diff --git a/PerfectNumbers.Core/Gpu/Accelerators/AcceleratorStreamPool.cs b/PerfectNumbers.Core/Gpu/Accelerators/AcceleratorStreamPool.cs index c6a5317..9c9ba17 100644 --- a/PerfectNumbers.Core/Gpu/Accelerators/AcceleratorStreamPool.cs +++ b/PerfectNumbers.Core/Gpu/Accelerators/AcceleratorStreamPool.cs @@ -7,8 +7,7 @@ public static class AcceleratorStreamPool { private static readonly Accelerator[] _accelerators = AcceleratorPool.Shared.Accelerators; private static readonly SemaphoreSlim[] _locks = new SemaphoreSlim[PerfectNumberConstants.RollingAccelerators]; - private static readonly ConcurrentQueue[] _streams = new ConcurrentQueue [PerfectNumberConstants.RollingAccelerators]; - + private static readonly AcceleratorStream[] _streams = new AcceleratorStream[PerfectNumberConstants.RollingAccelerators]; private static SemaphoreSlim CreateLock() => new(PerfectNumberConstants.ThreadsByAccelerator); @@ -17,26 +16,27 @@ public static class AcceleratorStreamPool public static AcceleratorStream Rent(int acceleratorIndex) { var streamLock = _locks[acceleratorIndex]; - var queue = _streams[acceleratorIndex]; streamLock.Wait(); + var queue = _streams[acceleratorIndex]; + if (queue != null) + { + return queue; + } - return queue.TryDequeue(out var stream) - ? stream - : _accelerators[acceleratorIndex].CreateStream(); + queue = _accelerators[acceleratorIndex].CreateStream(); + _streams[acceleratorIndex] = queue; + return queue; } - public static void Return(int acceleratorIndex, AcceleratorStream stream) + public static void Return(int acceleratorIndex) { var streamLock = _locks[acceleratorIndex]; - var queue = _streams[acceleratorIndex]; - queue.Enqueue(stream); streamLock.Release(); } public static void WarmUp(int acceleratorIndex) { - _streams[acceleratorIndex] = new(); _locks[acceleratorIndex] = CreateLock(); } } diff --git a/PerfectNumbers.Core/Gpu/Accelerators/HeuristicGpuTables.cs b/PerfectNumbers.Core/Gpu/Accelerators/HeuristicGpuTables.cs index 36e3ff2..93ae15a 100644 --- a/PerfectNumbers.Core/Gpu/Accelerators/HeuristicGpuTables.cs +++ b/PerfectNumbers.Core/Gpu/Accelerators/HeuristicGpuTables.cs @@ -45,25 +45,25 @@ internal sealed class HeuristicGpuTables HeuristicGroupBDivisorsEnding9 = CopyUintSpanToDevice(accelerator, stream, DivisorGenerator.SmallPrimesLastNineWithoutLastThree); HeuristicGroupBDivisorSquaresEnding9 = CopySpanToDevice(accelerator, stream, DivisorGenerator.SmallPrimesPow2LastNineWithoutLastThree); - var combinedEnding1 = HeuristicCombinedPrimeTester.CombinedDivisorsEnding1; - HeuristicCombinedDivisorsEnding1 = CopySpanToDevice(accelerator, stream, combinedEnding1); - var combinedSquaresEnding1 = HeuristicCombinedPrimeTester.CombinedDivisorsEnding1Squares; - HeuristicCombinedDivisorSquaresEnding1 = CopySpanToDevice(accelerator, stream, combinedSquaresEnding1); + // var combinedEnding1 = HeuristicCombinedPrimeTester.CombinedDivisorsEnding1; + // HeuristicCombinedDivisorsEnding1 = CopySpanToDevice(accelerator, stream, combinedEnding1); + // var combinedSquaresEnding1 = HeuristicCombinedPrimeTester.CombinedDivisorsEnding1Squares; + // HeuristicCombinedDivisorSquaresEnding1 = CopySpanToDevice(accelerator, stream, combinedSquaresEnding1); - var combinedEnding3 = HeuristicCombinedPrimeTester.CombinedDivisorsEnding3; - HeuristicCombinedDivisorsEnding3 = CopySpanToDevice(accelerator, stream, combinedEnding3); - var combinedSquaresEnding3 = HeuristicCombinedPrimeTester.CombinedDivisorsEnding3Squares; - HeuristicCombinedDivisorSquaresEnding3 = CopySpanToDevice(accelerator, stream, combinedSquaresEnding3); + // var combinedEnding3 = HeuristicCombinedPrimeTester.CombinedDivisorsEnding3; + // HeuristicCombinedDivisorsEnding3 = CopySpanToDevice(accelerator, stream, combinedEnding3); + // var combinedSquaresEnding3 = HeuristicCombinedPrimeTester.CombinedDivisorsEnding3Squares; + // HeuristicCombinedDivisorSquaresEnding3 = CopySpanToDevice(accelerator, stream, combinedSquaresEnding3); - var combinedEnding7 = HeuristicCombinedPrimeTester.CombinedDivisorsEnding7; - HeuristicCombinedDivisorsEnding7 = CopySpanToDevice(accelerator, stream, combinedEnding7); - var combinedSquaresEnding7 = HeuristicCombinedPrimeTester.CombinedDivisorsEnding7Squares; - HeuristicCombinedDivisorSquaresEnding7 = CopySpanToDevice(accelerator, stream, combinedSquaresEnding7); + // var combinedEnding7 = HeuristicCombinedPrimeTester.CombinedDivisorsEnding7; + // HeuristicCombinedDivisorsEnding7 = CopySpanToDevice(accelerator, stream, combinedEnding7); + // var combinedSquaresEnding7 = HeuristicCombinedPrimeTester.CombinedDivisorsEnding7Squares; + // HeuristicCombinedDivisorSquaresEnding7 = CopySpanToDevice(accelerator, stream, combinedSquaresEnding7); - var combinedEnding9 = HeuristicCombinedPrimeTester.CombinedDivisorsEnding9; - HeuristicCombinedDivisorsEnding9 = CopySpanToDevice(accelerator, stream, combinedEnding9); - var combinedSquaresEnding9 = HeuristicCombinedPrimeTester.CombinedDivisorsEnding9Squares; - HeuristicCombinedDivisorSquaresEnding9 = CopySpanToDevice(accelerator, stream, combinedSquaresEnding9); + // var combinedEnding9 = HeuristicCombinedPrimeTester.CombinedDivisorsEnding9; + // HeuristicCombinedDivisorsEnding9 = CopySpanToDevice(accelerator, stream, combinedEnding9); + // var combinedSquaresEnding9 = HeuristicCombinedPrimeTester.CombinedDivisorsEnding9Squares; + // HeuristicCombinedDivisorSquaresEnding9 = CopySpanToDevice(accelerator, stream, combinedSquaresEnding9); } internal readonly MemoryBuffer1D HeuristicGroupADivisors; diff --git a/PerfectNumbers.Core/Gpu/Accelerators/HeuristicPrimeTesterAccelerator.cs b/PerfectNumbers.Core/Gpu/Accelerators/HeuristicPrimeTesterAccelerator.cs index de9e4b4..d30e2ad 100644 --- a/PerfectNumbers.Core/Gpu/Accelerators/HeuristicPrimeTesterAccelerator.cs +++ b/PerfectNumbers.Core/Gpu/Accelerators/HeuristicPrimeTesterAccelerator.cs @@ -136,7 +136,7 @@ internal sealed class HeuristicPrimeTesterAccelerator Accelerator = accelerator; EnsureCapacity(minBufferCapacity); - HeuristicTrialDivisionKernel = KernelUtil.GetKernel(accelerator.LoadAutoGroupedStreamKernel, ulong, ulong, HeuristicGpuDivisorTableKind, HeuristicGpuDivisorTables>(PrimeTesterKernels.HeuristicTrialDivisionKernel)); + HeuristicTrialDivisionKernel = KernelUtil.GetKernel(accelerator.LoadAutoGroupedStreamKernel, ulong, ulong, ArrayView1D, ArrayView1D>(PrimeTesterKernels.HeuristicTrialDivisionKernel)); AcceleratorStream stream = AcceleratorStreamPool.Rent(acceleratorIndex); @@ -146,7 +146,7 @@ internal sealed class HeuristicPrimeTesterAccelerator _heuristicDivisorTables = _sharedTables.CreateHeuristicDivisorTables(); stream.Synchronize(); - AcceleratorStreamPool.Return(acceleratorIndex, stream); + AcceleratorStreamPool.Return(acceleratorIndex); } public void EnsureCapacity(int minCapacity) diff --git a/PerfectNumbers.Core/Gpu/GpuKernelPool.cs b/PerfectNumbers.Core/Gpu/GpuKernelPool.cs index fae25c4..c6e8085 100644 --- a/PerfectNumbers.Core/Gpu/GpuKernelPool.cs +++ b/PerfectNumbers.Core/Gpu/GpuKernelPool.cs @@ -25,7 +25,7 @@ public class GpuKernelPool internal static KernelContainer GetOrAddKernels(int acceleratorIndex, AcceleratorStream stream, KernelType kernelType) { - var pool = _pool ??= []; + var pool = _pool ??= new KernelContainer[PerfectNumberConstants.RollingAccelerators]; if (pool[acceleratorIndex] is not {} kernels) { kernels = new(); diff --git a/PerfectNumbers.Core/Gpu/Kernels/PrimeTesterKernels.cs b/PerfectNumbers.Core/Gpu/Kernels/PrimeTesterKernels.cs index efe1b82..5b00b78 100644 --- a/PerfectNumbers.Core/Gpu/Kernels/PrimeTesterKernels.cs +++ b/PerfectNumbers.Core/Gpu/Kernels/PrimeTesterKernels.cs @@ -83,20 +83,10 @@ internal static class PrimeTesterKernels ArrayView resultFlag, ulong n, ulong maxDivisorSquare, - HeuristicGpuDivisorTableKind tableKind, - HeuristicGpuDivisorTables tables) + ArrayView1D divisors, + ArrayView1D divisorSquares) { - byte nMod10 = (byte)(n % 10UL); - ArrayView1D divisors = tables.SelectDivisors(tableKind, nMod10); - ArrayView1D divisorSquares = tables.SelectDivisorSquares(tableKind, nMod10); - - int divisorLength = (int)divisorSquares.Length; int threadIndex = index; - if (threadIndex >= divisorLength) - { - return; - } - ulong divisorSquare = divisorSquares[threadIndex]; if (divisorSquare > maxDivisorSquare) { diff --git a/PerfectNumbers.Core/Gpu/Pow2MontgomeryGpuCalculator.cs b/PerfectNumbers.Core/Gpu/Pow2MontgomeryGpuCalculator.cs index 9ecc739..ea3c568 100644 --- a/PerfectNumbers.Core/Gpu/Pow2MontgomeryGpuCalculator.cs +++ b/PerfectNumbers.Core/Gpu/Pow2MontgomeryGpuCalculator.cs @@ -32,7 +32,7 @@ public static class Pow2MontgomeryGpuCalculator resultBuffer.View.CopyToCPU(stream, ref result, 1); stream.Synchronize(); - AcceleratorStreamPool.Return(acceleratorIndex, stream); + AcceleratorStreamPool.Return(acceleratorIndex); // GpuPrimeWorkLimiter.Release(); PrimeOrderCalculatorAccelerator.Return(gpu); @@ -60,7 +60,7 @@ public static class Pow2MontgomeryGpuCalculator resultBuffer.View.CopyToCPU(stream, ref result, 1); stream.Synchronize(); - AcceleratorStreamPool.Return(acceleratorIndex, stream); + AcceleratorStreamPool.Return(acceleratorIndex); // GpuPrimeWorkLimiter.Release(); PrimeOrderCalculatorAccelerator.Return(gpu); @@ -86,7 +86,7 @@ public static class Pow2MontgomeryGpuCalculator resultBuffer.View.CopyToCPU(stream, ref result, 1); stream.Synchronize(); - AcceleratorStreamPool.Return(acceleratorIndex, stream); + AcceleratorStreamPool.Return(acceleratorIndex); return result; } diff --git a/PerfectNumbers.Core/Gpu/PrimeOrderGpuHeuristics.cs b/PerfectNumbers.Core/Gpu/PrimeOrderGpuHeuristics.cs index 671d3cf..40d628d 100644 --- a/PerfectNumbers.Core/Gpu/PrimeOrderGpuHeuristics.cs +++ b/PerfectNumbers.Core/Gpu/PrimeOrderGpuHeuristics.cs @@ -102,7 +102,7 @@ internal static partial class PrimeOrderGpuHeuristics private static SmallPrimeDeviceCache GetSmallPrimeDeviceCache(int acceleratorIndex, AcceleratorStream stream) { - var pool = _smallPrimeDeviceCache ??= []; + var pool = _smallPrimeDeviceCache ??= new SmallPrimeDeviceCache[PerfectNumberConstants.RollingAccelerators]; if (pool[acceleratorIndex] is {} cached) { return cached; @@ -132,7 +132,7 @@ internal static partial class PrimeOrderGpuHeuristics private static Kernel GetPartialFactorKernel(int acceleratorIndex) { - var pool = _partialFactorKernel ??= []; + var pool = _partialFactorKernel ??= new Kernel[PerfectNumberConstants.RollingAccelerators]; if (pool[acceleratorIndex] is {} cached) { return cached; @@ -487,7 +487,7 @@ internal static partial class PrimeOrderGpuHeuristics private static Kernel GetOrderKernel(int acceleratorIndex) { - var pool = _orderKernel ??= []; + var pool = _orderKernel ??= new Kernel[PerfectNumberConstants.RollingAccelerators]; if (pool[acceleratorIndex] is {} cached) { return cached; @@ -637,7 +637,7 @@ internal static partial class PrimeOrderGpuHeuristics remainderBuffer.View.CopyToCPU(stream, ref MemoryMarshal.GetReference(resultSpan), length); stream.Synchronize(); - AcceleratorStreamPool.Return(acceleratorIndex, stream); + AcceleratorStreamPool.Return(acceleratorIndex); for (int i = 0; i < length; i++) { results[i] = (UInt128)resultSpan[i]; @@ -675,7 +675,7 @@ internal static partial class PrimeOrderGpuHeuristics private static Kernel GetPow2ModKernel(int acceleratorIndex) { - var pool = _pow2ModKernel ??= []; + var pool = _pow2ModKernel ??= new Kernel[PerfectNumberConstants.RollingAccelerators]; if (pool[acceleratorIndex] is {} cached) { return cached; diff --git a/PerfectNumbers.Core/HeuristicPrimeTester.cs b/PerfectNumbers.Core/HeuristicPrimeTester.cs index 29865e1..27fbed8 100644 --- a/PerfectNumbers.Core/HeuristicPrimeTester.cs +++ b/PerfectNumbers.Core/HeuristicPrimeTester.cs @@ -3,6 +3,7 @@ using System.Runtime.CompilerServices; using ILGPU.Runtime; using PerfectNumbers.Core.Gpu; using PerfectNumbers.Core.Gpu.Accelerators; +using ILGPU; namespace PerfectNumbers.Core; @@ -239,33 +240,36 @@ public sealed class HeuristicPrimeTester } - private bool HeuristicTrialDivisionGpuDetectsDivisor(ulong n, ulong maxDivisorSquare, byte nMod10) + private static bool HeuristicTrialDivisionGpuDetectsDivisor(ulong n, ulong maxDivisorSquare, byte nMod10) { // GpuPrimeWorkLimiter.Acquire(); var gpu = HeuristicPrimeTesterAccelerator.Rent(1); - var stream = gpu.Stream; + var stream = gpu.Stream!; var kernel = gpu.HeuristicTrialDivisionKernel; var flagView1D = gpu.HeuristicFlag.View; - var flagView = flagView1D.AsContiguous(); - bool compositeDetected = false; + bool compositeDetected; int compositeFlag = 0; int groupALength = HeuristicPrimeSieves.GroupADivisors.Length; flagView1D.CopyFromCPU(stream, ref compositeFlag, 1); + var tables = gpu.HeuristicGpuTables; + ArrayView1D divisors = tables.GroupADivisors; + ArrayView1D divisorSquares = tables.GroupADivisorSquares; + kernel.Launch( stream!, 1, groupALength, - flagView, + flagView1D, n, maxDivisorSquare, - HeuristicGpuDivisorTableKind.GroupA, - gpu.HeuristicGpuTables); + divisors, + divisorSquares); flagView1D.CopyToCPU(stream, ref compositeFlag, 1); - stream!.Synchronize(); + stream.Synchronize(); compositeDetected = compositeFlag != 0; @@ -296,7 +300,7 @@ public sealed class HeuristicPrimeTester stream, 1, divisorLength, - flagView, + flagView1D, n, maxDivisorSquare, tableKind, diff --git a/PerfectNumbers.Core/MersenneDivisorCycles.cs b/PerfectNumbers.Core/MersenneDivisorCycles.cs index 271b56f..eb73f54 100644 --- a/PerfectNumbers.Core/MersenneDivisorCycles.cs +++ b/PerfectNumbers.Core/MersenneDivisorCycles.cs @@ -898,7 +898,7 @@ public class MersenneDivisorCycles start = end + 1UL; } - AcceleratorStreamPool.Return(acceleratorIndex, stream); + AcceleratorStreamPool.Return(acceleratorIndex); pool.Return(divisors, clearArray: false); pool.Return(outCycles, clearArray: false); @@ -907,7 +907,7 @@ public class MersenneDivisorCycles private static Kernel GetDivisorCycleKernel(int acceleratorIndex) { - var pool = _divisorCycleKernel ??= []; + var pool = _divisorCycleKernel ??= new Kernel[PerfectNumberConstants.RollingAccelerators]; if (pool[acceleratorIndex] is {} cached) { return cached; diff --git a/PerfectNumbers.Core/MersenneNumberTester.cs b/PerfectNumbers.Core/MersenneNumberTester.cs index 2719d3e..5d30a59 100644 --- a/PerfectNumbers.Core/MersenneNumberTester.cs +++ b/PerfectNumbers.Core/MersenneNumberTester.cs @@ -204,7 +204,7 @@ public sealed class MersenneNumberTester( qBuffer.Dispose(); } - AcceleratorStreamPool.Return(acceleratorIndex,stream); + AcceleratorStreamPool.Return(acceleratorIndex); // GpuPrimeWorkLimiter.Release(); uInt128Pool.Return(qs); } diff --git a/PerfectNumbers.Core/PerfectNumberConstants.cs b/PerfectNumbers.Core/PerfectNumberConstants.cs index ef99aff..18bab29 100644 --- a/PerfectNumbers.Core/PerfectNumberConstants.cs +++ b/PerfectNumbers.Core/PerfectNumberConstants.cs @@ -15,7 +15,7 @@ public static class PerfectNumberConstants public const int MaxOddPowersCount = 128; public const int PooledArrayThreshold = 64; public static readonly int RollingAccelerators = 298; //SharedGpuContext.Device.MaxNumThreadsPerGroup; - public const int ThreadsByAccelerator = 4096; + public const int ThreadsByAccelerator = 2; // TODO: Load these limits from the benchmark-driven configuration so CPU and GPU scans stay aligned with the optimal // divisor-cycle datasets we generate offline. // TODO: Promote these magic numbers into a runtime profile derived from EvenPerfectBitScanner.Benchmarks so we can retune diff --git a/PerfectNumbers.Core/PrimeOrderCalculator.Gpu.cs b/PerfectNumbers.Core/PrimeOrderCalculator.Gpu.cs index 38d45f0..cc43e8c 100644 --- a/PerfectNumbers.Core/PrimeOrderCalculator.Gpu.cs +++ b/PerfectNumbers.Core/PrimeOrderCalculator.Gpu.cs @@ -50,7 +50,7 @@ internal static partial class PrimeOrderCalculator gpu.OutputUlong.View.CopyToCPU(stream, ref order, 1); stream.Synchronize(); - AcceleratorStreamPool.Return(acceleratorIndex, stream); + AcceleratorStreamPool.Return(acceleratorIndex); // GpuPrimeWorkLimiter.Release(); return order; @@ -114,7 +114,7 @@ internal static partial class PrimeOrderCalculator smallPrimeFactorRemainingSlotView.CopyToCPU(stream, ref remaining, 1); stream.Synchronize(); - AcceleratorStreamPool.Return(acceleratorIndex, stream); + AcceleratorStreamPool.Return(acceleratorIndex); // GpuPrimeWorkLimiter.Release(); for (int i = 0; i < factorCount; i++) @@ -164,7 +164,7 @@ internal static partial class PrimeOrderCalculator specialMaxResultView.CopyToCPU(stream, ref result, 1); stream.Synchronize(); - AcceleratorStreamPool.Return(acceleratorIndex, stream); + AcceleratorStreamPool.Return(acceleratorIndex); // GpuPrimeWorkLimiter.Release(); return result != 0; } @@ -190,7 +190,7 @@ internal static partial class PrimeOrderCalculator gpu.Input.View.CopyToCPU(stream, randomStateSpan); stream.Synchronize(); - AcceleratorStreamPool.Return(acceleratorIndex, stream); + AcceleratorStreamPool.Return(acceleratorIndex); ThreadStaticDeterministicRandomGpu.Exclusive.SetState(randomStateSpan[0]); bool factored = factoredSpan[0] != 0; diff --git a/PerfectNumbers.Core/PrimeTester.cs b/PerfectNumbers.Core/PrimeTester.cs index 574319b..33ba0c8 100644 --- a/PerfectNumbers.Core/PrimeTester.cs +++ b/PerfectNumbers.Core/PrimeTester.cs @@ -123,7 +123,7 @@ public sealed class PrimeTester outputView.CopyToCPU(stream, ref flag, 1); stream.Synchronize(); - AcceleratorStreamPool.Return(acceleratorIndex, stream); + AcceleratorStreamPool.Return(acceleratorIndex); PrimeOrderCalculatorAccelerator.Return(gpu); // GpuPrimeWorkLimiter.Release(); @@ -162,7 +162,7 @@ public sealed class PrimeTester outputView.CopyToCPU(stream, ref flag, 1); stream.Synchronize(); - AcceleratorStreamPool.Return(acceleratorIndex, stream); + AcceleratorStreamPool.Return(acceleratorIndex); return flag != 0; } @@ -239,7 +239,7 @@ public sealed class PrimeTester } stream.Synchronize(); - AcceleratorStreamPool.Return(acceleratorIndex, stream); + AcceleratorStreamPool.Return(acceleratorIndex); PrimeOrderCalculatorAccelerator.Return(gpu); // GpuPrimeWorkLimiter.Release(); } @@ -295,7 +295,7 @@ public sealed class PrimeTester resultBuffer.View.CopyToCPU(stream, in results); stream.Synchronize(); - AcceleratorStreamPool.Return(acceleratorIndex, stream); + AcceleratorStreamPool.Return(acceleratorIndex); PrimeOrderCalculatorAccelerator.Return(gpu); }