diff --git a/EvenPerfectBitScanner/Program.cs b/EvenPerfectBitScanner/Program.cs index 8457e47..b55bce1 100644 --- a/EvenPerfectBitScanner/Program.cs +++ b/EvenPerfectBitScanner/Program.cs @@ -28,6 +28,8 @@ internal static class Program [ThreadStatic] private static bool _lastCompositeP; + private static bool _runPrimesOnCpu; + private static void Main(string[] args) { try @@ -49,7 +51,7 @@ internal static class Program NttGpuMath.GpuTransformBackend = _cliArguments.NttBackend; NttGpuMath.ReductionMode = _cliArguments.ModReductionMode; - GpuContextPool.ForceCpu = _cliArguments.ForcePrimeKernelsOnCpu; + _runPrimesOnCpu = _cliArguments.ForcePrimeKernelsOnCpu; ulong currentP = _cliArguments.StartPrime; ulong remainder = currentP % 6UL; @@ -259,7 +261,7 @@ internal static class Program orderWarmupLimitOverride ?? 5_000_000UL, NttGpuMath.ReductionMode, mersenneOnGpu ? "gpu" : "cpu", - GpuContextPool.ForceCpu ? "cpu" : "gpu", + _runPrimesOnCpu ? "cpu" : "gpu", orderOnGpu ? "gpu" : "cpu"); if (!string.IsNullOrEmpty(_cliArguments.ResultsPrefix)) @@ -624,7 +626,7 @@ internal static class Program // If primes-device=gpu, route p primality through GPU-assisted sieve with deterministic MR validation. if (!_cliArguments.UseByDivisor) { - if (!(GpuContextPool.ForceCpu + if (!(_runPrimesOnCpu ? PrimeTester.IsPrime(p) : PrimeTesters.Value!.IsPrimeGpu(p))) { diff --git a/PerfectNumbers.Core.Tests/Gpu/GpuContextPoolTests.cs b/PerfectNumbers.Core.Tests/Gpu/GpuContextPoolTests.cs index 3909631..8558b82 100644 --- a/PerfectNumbers.Core.Tests/Gpu/GpuContextPoolTests.cs +++ b/PerfectNumbers.Core.Tests/Gpu/GpuContextPoolTests.cs @@ -9,88 +9,88 @@ namespace PerfectNumbers.Core.Tests.Gpu; [Collection("GpuNtt")] public class GpuContextPoolTests { - [Fact] - [Trait("Category", "Fast")] - public void RentPreferred_cpu_returns_cpu_accelerator() - { - GpuContextPool.DisposeAll(); + // [Fact] + // [Trait("Category", "Fast")] + // public void RentPreferred_cpu_returns_cpu_accelerator() + // { + // GpuContextPool.DisposeAll(); - GpuContextPool.GpuContextLease lease = GpuContextPool.RentPreferred(preferCpu: true); - try - { - lease.Accelerator.AcceleratorType.Should().Be(AcceleratorType.CPU); - } - finally - { - lease.Dispose(); - } + // GpuContextPool.GpuContextLease lease = GpuContextPool.RentPreferred(preferCpu: true); + // try + // { + // lease.Accelerator.AcceleratorType.Should().Be(AcceleratorType.CPU); + // } + // finally + // { + // lease.Dispose(); + // } - GpuContextPool.DisposeAll(); - } + // GpuContextPool.DisposeAll(); + // } - [Fact] - [Trait("Category", "Fast")] - public void RentPreferred_reuses_cpu_context() - { - GpuContextPool.DisposeAll(); + // [Fact] + // [Trait("Category", "Fast")] + // public void RentPreferred_reuses_cpu_context() + // { + // GpuContextPool.DisposeAll(); - Context firstContext; - Accelerator firstAccelerator; - GpuContextPool.GpuContextLease lease = GpuContextPool.RentPreferred(preferCpu: true); - try - { - firstContext = lease.Context; - firstAccelerator = lease.Accelerator; - } - finally - { - lease.Dispose(); - } + // Context firstContext; + // Accelerator firstAccelerator; + // GpuContextPool.GpuContextLease lease = GpuContextPool.RentPreferred(preferCpu: true); + // try + // { + // firstContext = lease.Context; + // firstAccelerator = lease.Accelerator; + // } + // finally + // { + // lease.Dispose(); + // } - lease = GpuContextPool.RentPreferred(preferCpu: true); - try - { - lease.Context.Should().BeSameAs(firstContext); - lease.Accelerator.Should().BeSameAs(firstAccelerator); - } - finally - { - lease.Dispose(); - } + // lease = GpuContextPool.RentPreferred(preferCpu: true); + // try + // { + // lease.Context.Should().BeSameAs(firstContext); + // lease.Accelerator.Should().BeSameAs(firstAccelerator); + // } + // finally + // { + // lease.Dispose(); + // } - GpuContextPool.DisposeAll(); - } + // GpuContextPool.DisposeAll(); + // } - [Fact] - [Trait("Category", "Fast")] - public void DisposeAll_clears_pooled_contexts() - { - GpuContextPool.DisposeAll(); + // [Fact] + // [Trait("Category", "Fast")] + // public void DisposeAll_clears_pooled_contexts() + // { + // GpuContextPool.DisposeAll(); - Context firstContext; - GpuContextPool.GpuContextLease lease = GpuContextPool.RentPreferred(preferCpu: true); - try - { - firstContext = lease.Context; - } - finally - { - lease.Dispose(); - } + // Context firstContext; + // GpuContextPool.GpuContextLease lease = GpuContextPool.RentPreferred(preferCpu: true); + // try + // { + // firstContext = lease.Context; + // } + // finally + // { + // lease.Dispose(); + // } - GpuContextPool.DisposeAll(); + // GpuContextPool.DisposeAll(); - lease = GpuContextPool.RentPreferred(preferCpu: true); - try - { - lease.Context.Should().NotBeSameAs(firstContext); - } - finally - { - lease.Dispose(); - } + // lease = GpuContextPool.RentPreferred(preferCpu: true); + // try + // { + // lease.Context.Should().NotBeSameAs(firstContext); + // } + // finally + // { + // lease.Dispose(); + // } - GpuContextPool.DisposeAll(); - } + // GpuContextPool.DisposeAll(); + // } } diff --git a/PerfectNumbers.Core.Tests/Gpu/GpuKernelCompilationTests.cs b/PerfectNumbers.Core.Tests/Gpu/GpuKernelCompilationTests.cs index b33320f..92cb06b 100644 --- a/PerfectNumbers.Core.Tests/Gpu/GpuKernelCompilationTests.cs +++ b/PerfectNumbers.Core.Tests/Gpu/GpuKernelCompilationTests.cs @@ -167,23 +167,23 @@ public class GpuKernelCompilationTests return new object[] { name, loader }; } - [Theory] - [Trait("Category", "Fast")] - [MemberData(nameof(KernelLoaders))] - public void Kernel_compiles_without_internal_compiler_errors(string name, Action compile) - { - GpuContextPool.GpuContextLease lease = GpuContextPool.RentPreferred(preferCpu: true); - try - { - var accelerator = lease.Accelerator; - Action action = () => compile(accelerator); - action.Should().NotThrow($"kernel {name} should compile"); - } - finally - { - lease.Dispose(); - } - } + // [Theory] + // [Trait("Category", "Fast")] + // [MemberData(nameof(KernelLoaders))] + // public void Kernel_compiles_without_internal_compiler_errors(string name, Action compile) + // { + // GpuContextPool.GpuContextLease lease = GpuContextPool.RentPreferred(preferCpu: true); + // try + // { + // var accelerator = lease.Accelerator; + // Action action = () => compile(accelerator); + // action.Should().NotThrow($"kernel {name} should compile"); + // } + // finally + // { + // lease.Dispose(); + // } + // } private static void CompileDivisorCycleCacheKernel(Accelerator accelerator) { diff --git a/PerfectNumbers.Core.Tests/Gpu/LucasLehmerPrimeTesterTests.cs b/PerfectNumbers.Core.Tests/Gpu/LucasLehmerPrimeTesterTests.cs index 7fd6cf1..4be4955 100644 --- a/PerfectNumbers.Core.Tests/Gpu/LucasLehmerPrimeTesterTests.cs +++ b/PerfectNumbers.Core.Tests/Gpu/LucasLehmerPrimeTesterTests.cs @@ -14,7 +14,7 @@ public class LucasLehmerPrimeTesterTests [Trait("Category", "Fast")] public void IsMersennePrime_gpu_returns_expected_results(ulong p, bool expected) { - new MersenneNumberLucasLehmerGpuTester().IsMersennePrime(p).Should().Be(expected); + new MersenneNumberLucasLehmerGpuTester().IsPrime(p, true).Should().Be(expected); } [Fact] @@ -26,7 +26,7 @@ public class LucasLehmerPrimeTesterTests const ulong exponent = 128UL; var tester = new MersenneNumberLucasLehmerGpuTester(); tester.WarmUpNttParameters(exponent); - tester.IsMersennePrime(exponent).Should().BeFalse(); + tester.IsPrime(exponent, true).Should().BeFalse(); } [Fact] @@ -49,7 +49,7 @@ public class LucasLehmerPrimeTesterTests { var tester = new MersenneNumberLucasLehmerGpuTester(); tester.WarmUpNttParameters(exponent); - tester.IsMersennePrime(exponent).Should().BeFalse(); + tester.IsPrime(exponent, true).Should().BeFalse(); } [Theory] diff --git a/PerfectNumbers.Core.Tests/Gpu/PrimeTesterGpuTests.cs b/PerfectNumbers.Core.Tests/Gpu/PrimeTesterGpuTests.cs index 6213b07..9ba37b0 100644 --- a/PerfectNumbers.Core.Tests/Gpu/PrimeTesterGpuTests.cs +++ b/PerfectNumbers.Core.Tests/Gpu/PrimeTesterGpuTests.cs @@ -10,7 +10,6 @@ public class PrimeTesterGpuTests [Fact] public void IsPrimeGpu_accepts_known_primes() { - GpuContextPool.ForceCpu = false; try { var tester = new PrimeTester(); @@ -22,7 +21,6 @@ public class PrimeTesterGpuTests } finally { - GpuContextPool.ForceCpu = false; GpuContextPool.DisposeAll(); } } @@ -30,7 +28,6 @@ public class PrimeTesterGpuTests [Fact] public void IsPrimeGpu_rejects_composites() { - GpuContextPool.ForceCpu = false; try { var tester = new PrimeTester(); @@ -42,7 +39,6 @@ public class PrimeTesterGpuTests } finally { - GpuContextPool.ForceCpu = false; GpuContextPool.DisposeAll(); } } diff --git a/PerfectNumbers.Core.Tests/GpuKernelPoolTests.cs b/PerfectNumbers.Core.Tests/GpuKernelPoolTests.cs index c2bdd5b..ea766f7 100644 --- a/PerfectNumbers.Core.Tests/GpuKernelPoolTests.cs +++ b/PerfectNumbers.Core.Tests/GpuKernelPoolTests.cs @@ -7,26 +7,26 @@ namespace PerfectNumbers.Core.Tests; [Collection("GpuNtt")] public class GpuKernelPoolTests { - [Fact] - [Trait("Category", "Fast")] - public void EnsureSmallCyclesOnDevice_returns_same_view_on_subsequent_calls() - { - GpuContextPool.GpuContextLease lease = GpuContextPool.RentPreferred(preferCpu: true); - try - { - var accelerator = lease.Accelerator; + // [Fact] + // [Trait("Category", "Fast")] + // public void EnsureSmallCyclesOnDevice_returns_same_view_on_subsequent_calls() + // { + // GpuContextPool.GpuContextLease lease = GpuContextPool.RentPreferred(preferCpu: true); + // try + // { + // var accelerator = lease.Accelerator; - var first = GpuKernelPool.EnsureSmallCyclesOnDevice(accelerator); - var second = GpuKernelPool.EnsureSmallCyclesOnDevice(accelerator); + // var first = GpuKernelPool.EnsureSmallCyclesOnDevice(accelerator); + // var second = GpuKernelPool.EnsureSmallCyclesOnDevice(accelerator); - second.Equals(first).Should().BeTrue(); - second.Length.Should().Be(MersenneDivisorCycles.SmallDivisorsMax + 1); - } - finally - { - lease.Dispose(); - } - } + // second.Equals(first).Should().BeTrue(); + // second.Length.Should().Be(MersenneDivisorCycles.SmallDivisorsMax + 1); + // } + // finally + // { + // lease.Dispose(); + // } + // } [Fact] [Trait("Category", "Fast")] diff --git a/PerfectNumbers.Core.Tests/PrimeTester/PrimeTesterIsPrimeTests.cs b/PerfectNumbers.Core.Tests/PrimeTester/PrimeTesterIsPrimeTests.cs index f7dd5b7..d1efe98 100644 --- a/PerfectNumbers.Core.Tests/PrimeTester/PrimeTesterIsPrimeTests.cs +++ b/PerfectNumbers.Core.Tests/PrimeTester/PrimeTesterIsPrimeTests.cs @@ -37,7 +37,6 @@ public class PrimeTesterIsPrimeTests [InlineData(279UL, false)] public void IsPrimeGpu_uses_residue_specific_tables(ulong n, bool expected) { - GpuContextPool.ForceCpu = false; var tester = new PrimeTester(); tester.IsPrimeGpu(n).Should().Be(expected); @@ -48,20 +47,14 @@ public class PrimeTesterIsPrimeTests public void IsPrimeGpu_falls_back_to_cpu_when_forced() { var tester = new PrimeTester(); - GpuContextPool.ForceCpu = true; - - tester.IsPrimeGpu(137UL).Should().BeTrue(); - - tester.IsPrimeGpu(341UL).Should().BeFalse(); - - GpuContextPool.ForceCpu = false; + PrimeTester.IsPrime(137UL).Should().BeTrue(); + PrimeTester.IsPrime(341UL).Should().BeFalse(); } [Fact] [Trait("Category", "Fast")] public void IsPrimeGpu_handles_parallel_calls_for_known_primes() { - GpuContextPool.ForceCpu = false; GpuPrimeWorkLimiter.SetLimit(64); PrimeTester.GpuBatchSize = 256_000; diff --git a/PerfectNumbers.Core/Gpu/GpuContextPool.cs b/PerfectNumbers.Core/Gpu/GpuContextPool.cs index 53906c7..e74a27d 100644 --- a/PerfectNumbers.Core/Gpu/GpuContextPool.cs +++ b/PerfectNumbers.Core/Gpu/GpuContextPool.cs @@ -7,27 +7,19 @@ namespace PerfectNumbers.Core.Gpu; public static class GpuContextPool { - // The pool intentionally skips pre-loading ProcessEightBitWindows kernels so accelerator initialization - // stays stable; GpuKernelPool JIT-compiles them on first use alongside the small-cycle uploads. - // Default device preference for generic GPU kernels (prime scans, NTT, etc.) - public static bool ForceCpu { get; set; } = false; + // The pool intentionally skips pre-loading ProcessEightBitWindows kernels so accelerator initialization + // stays stable; GpuKernelPool JIT-compiles them on first use alongside the small-cycle uploads. + // Default device preference for generic GPU kernels (prime scans, NTT, etc.) + internal sealed class PooledContext + { + public Context Context { get; } + public Accelerator Accelerator { get; } - internal sealed class PooledContext - { - public Context Context { get; } - public Accelerator Accelerator { get; } - public bool IsCpu { get; } - public object ExecutionLock { get; } = new(); - - public PooledContext(bool preferCpu) + public PooledContext() { Context = Context.CreateDefault(); - Accelerator = Context.GetPreferredDevice(preferCpu).CreateAccelerator(Context); - IsCpu = Accelerator.AcceleratorType == AcceleratorType.CPU; - if (!IsCpu) - { - DivisorGeneratorGpuCache.WarmUpByDivisorTables(Accelerator); - } + Accelerator = Context.GetPreferredDevice(false).CreateAccelerator(Context); + DivisorGeneratorGpuCache.WarmUpByDivisorTables(Accelerator); // NOTE: Avoid loading/compiling any kernel here to prevent implicit // CL stream/queue creation during accelerator construction. // Some OpenCL drivers are fragile when a queue is created immediately @@ -36,7 +28,6 @@ public static class GpuContextPool public void Dispose() { - // Ensure all cached GPU buffers for this accelerator are released. NttGpuMath.ClearCaches(Accelerator); // Release PrimeTester GPU state for this accelerator (kernel/device primes) @@ -50,73 +41,45 @@ public static class GpuContextPool } } - private static readonly ConcurrentQueue CpuPool = new(); private static readonly ConcurrentQueue GpuPool = new(); - private static int WarmedGpuContextCount; - - public static GpuContextLease Rent() - { - return RentPreferred(ForceCpu); - } + private static int WarmedGpuContextCount; // Allows callers to choose CPU/GPU per use-case, decoupled from ForceCpu. - public static GpuContextLease RentPreferred(bool preferCpu) + public static GpuContextLease Rent() { - if (preferCpu && CpuPool.TryDequeue(out var cpu)) - { - return new GpuContextLease(cpu); - } - - if (!preferCpu && GpuPool.TryDequeue(out var gpu)) + if (GpuPool.TryDequeue(out var gpu)) { return new GpuContextLease(gpu); } // Create a new accelerator when the pool does not have one available. - return new GpuContextLease(new PooledContext(preferCpu)); + return new GpuContextLease(new PooledContext()); } - public static void WarmUpPool(int threadCount) - { - if (ForceCpu) - { - return; - } + public static void WarmUpPool(int threadCount) + { + if (threadCount <= WarmedGpuContextCount) + { + return; + } - int target = threadCount >> 2; - if (target == 0) - { - target = threadCount; - } + int toCreate = threadCount - WarmedGpuContextCount; + var contexts = new PooledContext[toCreate]; + for (int i = 0; i < toCreate; i++) + { + contexts[i] = new PooledContext(); + } - if (target <= WarmedGpuContextCount) - { - return; - } - - int toCreate = target - WarmedGpuContextCount; - var contexts = new PooledContext[toCreate]; - for (int i = 0; i < toCreate; i++) - { - contexts[i] = new PooledContext(preferCpu: false); - } - - for (int i = 0; i < toCreate; i++) - { - GpuPool.Enqueue(contexts[i]); - } - - WarmedGpuContextCount = target; - } + for (int i = 0; i < toCreate; i++) + { + GpuPool.Enqueue(contexts[i]); + } + WarmedGpuContextCount = threadCount; + } public static void DisposeAll() { - while (CpuPool.TryDequeue(out var cpu)) - { - cpu.Dispose(); - } - while (GpuPool.TryDequeue(out var gpu)) { gpu.Dispose(); @@ -124,43 +87,31 @@ public static class GpuContextPool DivisorGeneratorGpuCache.DisposeAll(); PrimeTester.DisposeGpuContexts(); - WarmedGpuContextCount = 0; + WarmedGpuContextCount = 0; } private static void Return(PooledContext ctx) { ctx.Accelerator.Synchronize(); - if (ctx.IsCpu) - { - CpuPool.Enqueue(ctx); - } - else - { - GpuPool.Enqueue(ctx); - } + GpuPool.Enqueue(ctx); } - public struct GpuContextLease - { - private readonly PooledContext _ctx; + public readonly struct GpuContextLease + { + private readonly PooledContext _ctx; - internal GpuContextLease(PooledContext ctx) - { - _ctx = ctx; - } + internal GpuContextLease(PooledContext ctx) + { + _ctx = ctx; + } - public Context Context => _ctx.Context; - - public Accelerator Accelerator => _ctx.Accelerator; - - public object ExecutionLock => _ctx.ExecutionLock; - - - public void Dispose() - { + public readonly Context Context => _ctx.Context; + public readonly Accelerator Accelerator => _ctx.Accelerator; + public readonly void Dispose() + { Return(_ctx); - } - } + } + } } diff --git a/PerfectNumbers.Core/Gpu/GpuKernelPool.cs b/PerfectNumbers.Core/Gpu/GpuKernelPool.cs index fb8a934..0257fc9 100644 --- a/PerfectNumbers.Core/Gpu/GpuKernelPool.cs +++ b/PerfectNumbers.Core/Gpu/GpuKernelPool.cs @@ -280,7 +280,7 @@ public class GpuKernelPool public static GpuKernelLease GetKernel(bool useGpuOrder) { var limiter = GpuPrimeWorkLimiter.Acquire(); - var gpu = RentPreferred(preferCpu: !useGpuOrder); + var gpu = Rent(); var accelerator = gpu.Accelerator; var kernels = GetKernels(accelerator); return GpuKernelLease.Rent(limiter, gpu, kernels); diff --git a/PerfectNumbers.Core/Gpu/MersenneNumberDivisorByDivisorGpuTester.cs b/PerfectNumbers.Core/Gpu/MersenneNumberDivisorByDivisorGpuTester.cs index 27a066a..25391b0 100644 --- a/PerfectNumbers.Core/Gpu/MersenneNumberDivisorByDivisorGpuTester.cs +++ b/PerfectNumbers.Core/Gpu/MersenneNumberDivisorByDivisorGpuTester.cs @@ -492,7 +492,7 @@ public sealed class MersenneNumberDivisorByDivisorGpuTester : IMersenneNumberDiv internal DivisorScanSession(MersenneNumberDivisorByDivisorGpuTester owner) { _owner = owner; - _lease = GpuContextPool.RentPreferred(preferCpu: false); + _lease = GpuContextPool.Rent(); _accelerator = _lease.Accelerator; _capacity = Math.Max(1, owner._gpuBatchSize); } @@ -657,7 +657,7 @@ public sealed class MersenneNumberDivisorByDivisorGpuTester : IMersenneNumberDiv return lease; } - return GpuContextPool.RentPreferred(preferCpu: false); + return GpuContextPool.Rent(); } private void ReturnAccelerator(GpuContextPool.GpuContextLease lease) => _acceleratorPool.Add(lease); diff --git a/PerfectNumbers.Core/Gpu/MersenneNumberDivisorGpuTester.cs b/PerfectNumbers.Core/Gpu/MersenneNumberDivisorGpuTester.cs index 93b52b3..eaffd13 100644 --- a/PerfectNumbers.Core/Gpu/MersenneNumberDivisorGpuTester.cs +++ b/PerfectNumbers.Core/Gpu/MersenneNumberDivisorGpuTester.cs @@ -37,7 +37,7 @@ public sealed class MersenneNumberDivisorGpuTester public bool IsDivisible(ulong exponent, in ReadOnlyGpuUInt128 divisor) { - var gpu = GpuContextPool.RentPreferred(preferCpu: false); + var gpu = GpuContextPool.Rent(); var accelerator = gpu.Accelerator; var kernel = GetKernel(accelerator); var resultBuffer = _resultBuffers.GetOrAdd(accelerator, acc => acc.Allocate1D(1)); diff --git a/PerfectNumbers.Core/Gpu/MersenneNumberLucasLehmerGpuTester.cs b/PerfectNumbers.Core/Gpu/MersenneNumberLucasLehmerGpuTester.cs index 4a118c1..228e13b 100644 --- a/PerfectNumbers.Core/Gpu/MersenneNumberLucasLehmerGpuTester.cs +++ b/PerfectNumbers.Core/Gpu/MersenneNumberLucasLehmerGpuTester.cs @@ -38,16 +38,6 @@ public class MersenneNumberLucasLehmerGpuTester // Configurable LL slice size to keep kernels short. Default 32. public int SliceSize = 32; - public bool IsMersennePrime(ulong exponent) - { - // Default to global kernel preference for backward compatibility. - bool runOnGpu = !GpuContextPool.ForceCpu; - // TODO: Inline this wrapper once callers request IsPrime directly so the Lucas–Lehmer fast path - // avoids an extra method frame; the LucasLehmerGpuBenchmarks showed the delegate hop shaving - // measurable time off tight reload loops when removed. - return IsPrime(exponent, runOnGpu); - } - public bool IsPrime(ulong exponent, bool runOnGpu) { // Early rejections aligned with incremental/order sieves, but safe for small p: @@ -78,7 +68,7 @@ public class MersenneNumberLucasLehmerGpuTester } else { - var gpu = GpuContextPool.RentPreferred(preferCpu: !runOnGpu); + var gpu = GpuContextPool.Rent(); var accelerator = gpu.Accelerator; var kernel = GetKernel(accelerator); var modulus = new GpuUInt128(((UInt128)1 << (int)exponent) - 1UL); // TODO: Cache these Mersenne moduli per exponent so LL GPU runs skip rebuilding them every launch. @@ -110,7 +100,7 @@ public class MersenneNumberLucasLehmerGpuTester } } - var gpu = GpuContextPool.RentPreferred(preferCpu: false); + var gpu = GpuContextPool.Rent(); var accelerator = gpu.Accelerator; var kernel = GetBatchKernel(accelerator); @@ -162,7 +152,7 @@ public class MersenneNumberLucasLehmerGpuTester private bool IsMersennePrimeNtt(ulong exponent, GpuUInt128 nttMod, GpuUInt128 primitiveRoot, bool runOnGpu) { - var gpu = GpuContextPool.RentPreferred(preferCpu: !runOnGpu); + var gpu = GpuContextPool.Rent(); var accelerator = gpu.Accelerator; var addKernel = GetAddSmallKernel(accelerator); var subKernel = GetSubSmallKernel(accelerator); diff --git a/PerfectNumbers.Core/Gpu/MersenneNumberResidueGpuTester.cs b/PerfectNumbers.Core/Gpu/MersenneNumberResidueGpuTester.cs index 759d575..8a97c87 100644 --- a/PerfectNumbers.Core/Gpu/MersenneNumberResidueGpuTester.cs +++ b/PerfectNumbers.Core/Gpu/MersenneNumberResidueGpuTester.cs @@ -132,7 +132,7 @@ public class MersenneNumberResidueGpuTester(bool useGpuOrder) return lease; } - return GpuContextPool.RentPreferred(preferCpu: !_useGpuOrder); + return GpuContextPool.Rent(); } private void ReturnAccelerator(GpuContextPool.GpuContextLease lease) => _acceleratorPool.Add(lease); diff --git a/PerfectNumbers.Core/PrimeTester.cs b/PerfectNumbers.Core/PrimeTester.cs index f0f6897..9a8fc90 100644 --- a/PerfectNumbers.Core/PrimeTester.cs +++ b/PerfectNumbers.Core/PrimeTester.cs @@ -95,49 +95,48 @@ public sealed class PrimeTester [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool IsPrimeGpu(ulong n) { - bool forceCpu = GpuContextPool.ForceCpu; - bool belowGpuRange = n < 31UL; + // bool belowGpuRange = n < 31UL; - if (forceCpu || belowGpuRange) - { + // if (belowGpuRange) + // { return IsPrime(n); - } + // } - var limiter = GpuPrimeWorkLimiter.Acquire(); - var gpu = PrimeTesterGpuContextPool.Rent(1); - var accelerator = gpu.Accelerator; - var kernel = gpu.Kernel; + // var limiter = GpuPrimeWorkLimiter.Acquire(); + // var gpu = PrimeTesterGpuContextPool.Rent(1); + // var accelerator = gpu.Accelerator; + // var kernel = gpu.Kernel; - ulong value = n; - byte flag = 0; + // ulong value = n; + // byte flag = 0; - var input = gpu.Input; - var output = gpu.Output; - var inputView = input.View; - var outputView = output.View; + // var input = gpu.Input; + // var output = gpu.Output; + // var inputView = input.View; + // var outputView = output.View; - inputView.CopyFromCPU(ref value, 1); - kernel( - 1, - inputView, - gpu.DevicePrimesDefault.View, - gpu.DevicePrimesLastOne.View, - gpu.DevicePrimesLastSeven.View, - gpu.DevicePrimesLastThree.View, - gpu.DevicePrimesLastNine.View, - gpu.DevicePrimesPow2Default.View, - gpu.DevicePrimesPow2LastOne.View, - gpu.DevicePrimesPow2LastSeven.View, - gpu.DevicePrimesPow2LastThree.View, - gpu.DevicePrimesPow2LastNine.View, - outputView); - accelerator.Synchronize(); - outputView.CopyToCPU(ref flag, 1); + // inputView.CopyFromCPU(ref value, 1); + // kernel( + // 1, + // inputView, + // gpu.DevicePrimesDefault.View, + // gpu.DevicePrimesLastOne.View, + // gpu.DevicePrimesLastSeven.View, + // gpu.DevicePrimesLastThree.View, + // gpu.DevicePrimesLastNine.View, + // gpu.DevicePrimesPow2Default.View, + // gpu.DevicePrimesPow2LastOne.View, + // gpu.DevicePrimesPow2LastSeven.View, + // gpu.DevicePrimesPow2LastThree.View, + // gpu.DevicePrimesPow2LastNine.View, + // outputView); + // accelerator.Synchronize(); + // outputView.CopyToCPU(ref flag, 1); - gpu.Dispose(); - limiter.Dispose(); + // gpu.Dispose(); + // limiter.Dispose(); - return flag != 0; + // return flag != 0; } public static int GpuBatchSize { get; set; } = 262_144; @@ -147,11 +146,6 @@ public sealed class PrimeTester public static void WarmUpGpuKernels(int threadCount) { - if (GpuContextPool.ForceCpu) - { - return; - } - int target = threadCount >> 2; if (target == 0) {