diff --git a/EvenPerfectBitScanner.Benchmarks/Pow2MontgomeryModCycleComputationBenchmarks.cs b/EvenPerfectBitScanner.Benchmarks/Pow2MontgomeryModCycleComputationBenchmarks.cs index 8c773fb..2ae2a6e 100644 --- a/EvenPerfectBitScanner.Benchmarks/Pow2MontgomeryModCycleComputationBenchmarks.cs +++ b/EvenPerfectBitScanner.Benchmarks/Pow2MontgomeryModCycleComputationBenchmarks.cs @@ -280,10 +280,11 @@ public class Pow2MontgomeryModCycleComputationBenchmarks Console.WriteLine("Trying heuristic. Prime order calculation"); #endif PrimeOrderCalculator.PrimeOrderResult orderResult = PrimeOrderCalculator.Calculate( - modulus, - _previousPrimeOrder, - divisorData, - PrimeOrderCalculator.PrimeOrderSearchConfig.HeuristicDefault); + modulus, + _previousPrimeOrder, + divisorData, + PrimeOrderCalculator.PrimeOrderSearchConfig.HeuristicDefault, + PrimeOrderCalculator.PrimeOrderHeuristicDevice.Gpu); if (orderResult.Order != 0UL) { diff --git a/PerfectNumbers.Core.Tests/Gpu/PrimeOrderGpuHeuristicsTests.cs b/PerfectNumbers.Core.Tests/Gpu/PrimeOrderGpuHeuristicsTests.cs index 3338cd0..6f77ade 100644 --- a/PerfectNumbers.Core.Tests/Gpu/PrimeOrderGpuHeuristicsTests.cs +++ b/PerfectNumbers.Core.Tests/Gpu/PrimeOrderGpuHeuristicsTests.cs @@ -359,7 +359,7 @@ public class PrimeOrderGpuHeuristicsTests PrimeOrderGpuHeuristics.OverflowRegistry[prime] = 0; MontgomeryDivisorData divisorData = MontgomeryDivisorData.FromModulus(prime); - PrimeOrderCalculator.PrimeOrderResult result = PrimeOrderCalculator.Calculate(prime, null, divisorData, PrimeOrderCalculator.PrimeOrderSearchConfig.HeuristicDefault); + PrimeOrderCalculator.PrimeOrderResult result = PrimeOrderCalculator.Calculate(prime, null, divisorData, PrimeOrderCalculator.PrimeOrderSearchConfig.HeuristicDefault, PrimeOrderCalculator.PrimeOrderHeuristicDevice.Gpu); result.Status.Should().Be(PrimeOrderCalculator.PrimeOrderStatus.Found); result.Order.Should().Be(3UL); diff --git a/PerfectNumbers.Core.Tests/PrimeOrderCalculatorTests.cs b/PerfectNumbers.Core.Tests/PrimeOrderCalculatorTests.cs index d7dd522..9d3968e 100644 --- a/PerfectNumbers.Core.Tests/PrimeOrderCalculatorTests.cs +++ b/PerfectNumbers.Core.Tests/PrimeOrderCalculatorTests.cs @@ -46,10 +46,11 @@ public class PrimeOrderCalculatorTests ulong expected = ComputeOrderByDoubling(prime); PrimeOrderCalculator.PrimeOrderResult result = PrimeOrderCalculator.Calculate( - prime, - previousOrder: null, - MontgomeryDivisorData.FromModulus(prime), - PrimeOrderCalculator.PrimeOrderSearchConfig.HeuristicDefault); + prime, + previousOrder: null, + MontgomeryDivisorData.FromModulus(prime), + PrimeOrderCalculator.PrimeOrderSearchConfig.HeuristicDefault, + PrimeOrderCalculator.PrimeOrderHeuristicDevice.Gpu); result.Status.Should().Be(PrimeOrderCalculator.PrimeOrderStatus.Found); result.Order.Should().Be(expected); @@ -63,16 +64,18 @@ public class PrimeOrderCalculatorTests ulong previousOrder = ComputeOrderByDoubling(previousPrime); PrimeOrderCalculator.PrimeOrderResult heuristic = PrimeOrderCalculator.Calculate( - prime, - previousOrder, - MontgomeryDivisorData.FromModulus(prime), - PrimeOrderCalculator.PrimeOrderSearchConfig.HeuristicDefault); + prime, + previousOrder, + MontgomeryDivisorData.FromModulus(prime), + PrimeOrderCalculator.PrimeOrderSearchConfig.HeuristicDefault, + PrimeOrderCalculator.PrimeOrderHeuristicDevice.Gpu); PrimeOrderCalculator.PrimeOrderResult strict = PrimeOrderCalculator.Calculate( - prime, - previousOrder: null, - MontgomeryDivisorData.FromModulus(prime), - PrimeOrderCalculator.PrimeOrderSearchConfig.StrictDefault); + prime, + previousOrder: null, + MontgomeryDivisorData.FromModulus(prime), + PrimeOrderCalculator.PrimeOrderSearchConfig.StrictDefault, + PrimeOrderCalculator.PrimeOrderHeuristicDevice.Gpu); heuristic.Status.Should().Be(PrimeOrderCalculator.PrimeOrderStatus.Found); strict.Status.Should().Be(PrimeOrderCalculator.PrimeOrderStatus.Found); @@ -86,10 +89,11 @@ public class PrimeOrderCalculatorTests public void Calculate_handles_trivial_primes(ulong prime, ulong expectedOrder) { PrimeOrderCalculator.PrimeOrderResult result = PrimeOrderCalculator.Calculate( - prime, - previousOrder: null, - MontgomeryDivisorData.FromModulus(prime), - PrimeOrderCalculator.PrimeOrderSearchConfig.HeuristicDefault); + prime, + previousOrder: null, + MontgomeryDivisorData.FromModulus(prime), + PrimeOrderCalculator.PrimeOrderSearchConfig.HeuristicDefault, + PrimeOrderCalculator.PrimeOrderHeuristicDevice.Gpu); result.Status.Should().Be(PrimeOrderCalculator.PrimeOrderStatus.Found); result.Order.Should().Be(expectedOrder); @@ -106,10 +110,11 @@ public class PrimeOrderCalculatorTests mode: PrimeOrderCalculator.PrimeOrderMode.Heuristic); PrimeOrderCalculator.PrimeOrderResult result = PrimeOrderCalculator.Calculate( - prime: 13UL, - previousOrder: null, - MontgomeryDivisorData.FromModulus(13UL), - config); + prime: 13UL, + previousOrder: null, + MontgomeryDivisorData.FromModulus(13UL), + config, + PrimeOrderCalculator.PrimeOrderHeuristicDevice.Gpu); result.Status.Should().Be(PrimeOrderCalculator.PrimeOrderStatus.HeuristicUnresolved); result.Order.Should().Be(ComputeOrderByDoubling(13UL)); @@ -127,10 +132,11 @@ public class PrimeOrderCalculatorTests MontgomeryDivisorData divisorData = MontgomeryDivisorData.FromModulus(239UL); PrimeOrderCalculator.PrimeOrderResult heuristic = PrimeOrderCalculator.Calculate( - prime: 239UL, - previousOrder: null, - divisorData, - heuristicConfig); + prime: 239UL, + previousOrder: null, + divisorData, + heuristicConfig, + PrimeOrderCalculator.PrimeOrderHeuristicDevice.Gpu); heuristic.Status.Should().Be(PrimeOrderCalculator.PrimeOrderStatus.HeuristicUnresolved); heuristic.Order.Should().Be(ComputeOrderByDoubling(239UL)); @@ -142,10 +148,11 @@ public class PrimeOrderCalculatorTests mode: PrimeOrderCalculator.PrimeOrderMode.Strict); PrimeOrderCalculator.PrimeOrderResult strict = PrimeOrderCalculator.Calculate( - prime: 239UL, - previousOrder: null, - divisorData, - strictConfig); + prime: 239UL, + previousOrder: null, + divisorData, + strictConfig, + PrimeOrderCalculator.PrimeOrderHeuristicDevice.Gpu); strict.Status.Should().Be(PrimeOrderCalculator.PrimeOrderStatus.Found); strict.Order.Should().Be(heuristic.Order); diff --git a/PerfectNumbers.Core/PrimeOrderCalculator.Wide.cs b/PerfectNumbers.Core/PrimeOrderCalculator.Wide.cs index 7c2c6ef..072f5ab 100644 --- a/PerfectNumbers.Core/PrimeOrderCalculator.Wide.cs +++ b/PerfectNumbers.Core/PrimeOrderCalculator.Wide.cs @@ -31,7 +31,7 @@ internal static partial class PrimeOrderCalculator PrimeOrderSearchConfig config, PrimeOrderHeuristicDevice device) { - using var scope = UsePow2Mode(device); + var scope = UsePow2Mode(device); MontgomeryDivisorData divisorData; if (prime <= ulong.MaxValue) { @@ -51,7 +51,8 @@ internal static partial class PrimeOrderCalculator ulong prime64 = (ulong)prime; divisorData = MontgomeryDivisorData.FromModulus(prime64); - PrimeOrderResult result = Calculate(prime64, previous, divisorData, config, device); + PrimeOrderResult result = Calculate(prime64, previous, divisorData, config, device); + scope.Dispose(); return new PrimeOrderResultWide(result.Status, result.Order); } else @@ -59,7 +60,9 @@ internal static partial class PrimeOrderCalculator divisorData = default; } - return CalculateWideInternal(prime, previousOrder, divisorData, config); + PrimeOrderResultWide resultWide = CalculateWideInternal(prime, previousOrder, divisorData, config); + scope.Dispose(); + return resultWide; } private static PrimeOrderResultWide CalculateWideInternal(UInt128 prime, UInt128? previousOrder, in MontgomeryDivisorData divisorData, PrimeOrderSearchConfig config) @@ -75,15 +78,20 @@ internal static partial class PrimeOrderCalculator } UInt128 phi = prime - UInt128.One; - using var debugScope = UseDebugLogging(!IsGpuHeuristicDevice); - PartialFactorResult128 phiFactors = PartialFactorWide(phi, config); + var debugScope = UseDebugLogging(!IsGpuHeuristicDevice); + PartialFactorResult128 phiFactors = PartialFactorWide(phi, config); + PrimeOrderResultWide result; if (phiFactors.Factors is null) { - // HeuristicFailureLog.Record(prime, null, HeuristicFailureReason.PhiPartialFactorizationFailed); - return FinishStrictlyWide(prime, divisorData, config.Mode); + // HeuristicFailureLog.Record(prime, null, HeuristicFailureReason.PhiPartialFactorizationFailed); + result = FinishStrictlyWide(prime, divisorData, config.Mode); + debugScope.Dispose(); + return result; } - return RunHeuristicPipelineWide(prime, previousOrder, divisorData, config, phi, phiFactors); + result = RunHeuristicPipelineWide(prime, previousOrder, divisorData, config, phi, phiFactors); + debugScope.Dispose(); + return result; } private static PrimeOrderResultWide RunHeuristicPipelineWide(