--mersenne=bydivisor testers and sessions integrated and converted to structs.

This commit is contained in:
mlemanczyk committed 2025-12-18 05:07:31 +01:00
1 parent 3c80221105
commit 2abc6aae49
32 files changed
+3814 -1505

No files matched your search

@@ -55,23 +55,13 @@ public class MersenneNumberDivisorByDivisorTesterTests
{
}
public void ResumeFromState(BigInteger lastSavedK)
public void ResumeFromState(in string stateFile, in BigInteger lastSavedK, in BigInteger minK)
{
}
public ulong DivisorLimit => ConfiguredMaxPrime + 100UL;
public void ConfigureFromMaxPrime(ulong maxPrime)
{
ConfiguredMaxPrime = maxPrime;
}
public ulong GetAllowedMaxDivisor(ulong prime)
{
return DivisorLimit;
}
public bool IsPrime(PrimeOrderCalculatorAccelerator gpu, ulong prime, out bool divisorsExhausted, out BigInteger divisor)
public bool IsPrime(ulong prime, out bool divisorsExhausted, out BigInteger divisor)
{
divisorsExhausted = true;
if (prime % 7UL == 0UL)
@@ -95,8 +85,9 @@ public class MersenneNumberDivisorByDivisorTesterTests
return new DummySession();
}
public void PrepareCandidates(in ReadOnlySpan<ulong> primes, Span<ulong> allowedMaxValues)
public void PrepareCandidates(ulong maxPrime, in ReadOnlySpan<ulong> primes, Span<ulong> allowedMaxValues)
{
ConfiguredMaxPrime = maxPrime;
for (int i = 0; i < primes.Length; i++)
{
allowedMaxValues[i] = 100UL;
@@ -1,125 +1,106 @@
using System.Numerics;
using FluentAssertions;
using PerfectNumbers.Core.Cpu;
using PerfectNumbers.Core.Gpu.Accelerators;
using Xunit;
namespace PerfectNumbers.Core.Tests;
public class MersenneNumberDivisorCpuTesterTests
{
[Fact]
[Trait("Category", "Fast")]
public void ByDivisor_tester_tracks_divisors_across_primes()
{
var tester = new MersenneNumberDivisorByDivisorCpuTester();
tester.ConfigureFromMaxPrime(11UL);
[Fact]
[Trait("Category", "Fast")]
public void ByDivisor_tester_tracks_divisors_across_primes()
{
var tester = new MersenneNumberDivisorByDivisorCpuTesterWithCpuOrder();
var gpu = PrimeOrderCalculatorAccelerator.Rent(1);
try
{
tester.IsPrime(gpu, 5UL, out bool divisorsExhausted, out BigInteger divisor).Should().BeTrue();
divisorsExhausted.Should().BeTrue();
divisor.Should().Be(BigInteger.Zero);
ulong[] primes = [5UL, 7UL, 11UL];
ulong[] allowedMax = new ulong[primes.Length];
tester.PrepareCandidates(maxPrime: 11UL, primes, allowedMax);
tester.IsPrime(gpu, 7UL, out divisorsExhausted, out divisor).Should().BeTrue();
divisorsExhausted.Should().BeTrue();
divisor.Should().Be(BigInteger.Zero);
tester.ResumeFromState(Path.Combine(Path.GetTempPath(), "bydivisor-cpu-tests.bin"), BigInteger.Zero, BigInteger.One);
tester.ResetStateTracking();
tester.IsPrime(gpu, 11UL, out divisorsExhausted, out divisor).Should().BeFalse();
divisorsExhausted.Should().BeTrue();
divisor.Should().BeGreaterThan(BigInteger.Zero);
}
finally
{
PrimeOrderCalculatorAccelerator.Return(gpu);
}
}
tester.IsPrime(5UL, out bool divisorsExhausted, out BigInteger divisor).Should().BeTrue();
divisorsExhausted.Should().BeTrue();
divisor.Should().Be(BigInteger.Zero);
[Fact]
[Trait("Category", "Fast")]
public void ByDivisor_session_checks_divisors_across_primes()
{
var tester = new MersenneNumberDivisorByDivisorCpuTester();
tester.ConfigureFromMaxPrime(13UL);
tester.IsPrime(7UL, out divisorsExhausted, out divisor).Should().BeTrue();
divisorsExhausted.Should().BeTrue();
divisor.Should().Be(BigInteger.Zero);
var gpu = PrimeOrderCalculatorAccelerator.Rent(1);
var session = tester.CreateDivisorSession(gpu);
try
{
ulong[] primes = [5UL, 7UL, 11UL, 13UL];
tester.IsPrime(11UL, out divisorsExhausted, out divisor).Should().BeFalse();
divisorsExhausted.Should().BeTrue();
divisor.Should().BeGreaterThan(BigInteger.Zero);
}
ulong cycle23 = MersenneDivisorCycles.CalculateCycleLengthCpu(23UL, MontgomeryDivisorData.FromModulus(23UL));
session.CheckDivisor(23UL, MontgomeryDivisorData.FromModulus(23UL), cycle23, primes).Should().BeTrue();
[Fact]
[Trait("Category", "Fast")]
public void ByDivisor_session_checks_divisors_across_primes()
{
var session = new MersenneCpuDivisorScanSessionWithCpuOrder();
ulong[] primesWithoutHit = [5UL, 7UL, 13UL];
session.CheckDivisor(23UL, MontgomeryDivisorData.FromModulus(23UL), cycle23, primesWithoutHit).Should().BeFalse();
ulong[] primes = [5UL, 7UL, 11UL, 13UL];
ulong cycle31 = MersenneDivisorCycles.CalculateCycleLengthCpu(31UL, MontgomeryDivisorData.FromModulus(31UL));
session.CheckDivisor(31UL, MontgomeryDivisorData.FromModulus(31UL), cycle31, primes).Should().BeTrue();
ulong cycle23 = MersenneDivisorCycles.CalculateCycleLengthCpu(23UL, MontgomeryDivisorData.FromModulus(23UL));
session.CheckDivisor(23UL, MontgomeryDivisorData.FromModulus(23UL), cycle23, primes).Should().BeTrue();
ulong[] primesBeforeHit = [7UL, 11UL, 13UL];
session.CheckDivisor(31UL, MontgomeryDivisorData.FromModulus(31UL), cycle31, primesBeforeHit).Should().BeFalse();
}
finally
{
session.Return();
PrimeOrderCalculatorAccelerator.Return(gpu);
}
}
ulong[] primesWithoutHit = [5UL, 7UL, 13UL];
session.CheckDivisor(23UL, MontgomeryDivisorData.FromModulus(23UL), cycle23, primesWithoutHit).Should().BeFalse();
[Fact]
[Trait("Category", "Fast")]
public void ByDivisor_session_marks_mersenne_numbers_divisible_by_seven_as_composite()
{
var tester = new MersenneNumberDivisorByDivisorCpuTester();
tester.ConfigureFromMaxPrime(43UL);
ulong cycle31 = MersenneDivisorCycles.CalculateCycleLengthCpu(31UL, MontgomeryDivisorData.FromModulus(31UL));
session.CheckDivisor(31UL, MontgomeryDivisorData.FromModulus(31UL), cycle31, primes).Should().BeTrue();
var gpu = PrimeOrderCalculatorAccelerator.Rent(1);
var session = tester.CreateDivisorSession(gpu);
try
{
ulong[] exponents = [6UL, 7UL, 9UL, 10UL, 12UL];
ulong[] primesBeforeHit = [7UL, 11UL, 13UL];
session.CheckDivisor(31UL, MontgomeryDivisorData.FromModulus(31UL), cycle31, primesBeforeHit).Should().BeFalse();
}
MontgomeryDivisorData divisorData = MontgomeryDivisorData.FromModulus(7UL);
ulong cycle = MersenneDivisorCycles.CalculateCycleLengthCpu(7UL, divisorData);
session.CheckDivisor(7UL, divisorData, cycle, exponents).Should().BeTrue();
[Fact]
[Trait("Category", "Fast")]
public void ByDivisor_session_marks_mersenne_numbers_divisible_by_seven_as_composite()
{
var session = new MersenneCpuDivisorScanSessionWithCpuOrder();
ulong[] nonDivisibleExponents = [5UL, 11UL];
session.CheckDivisor(7UL, divisorData, cycle, nonDivisibleExponents).Should().BeFalse();
}
finally
{
session.Return();
PrimeOrderCalculatorAccelerator.Return(gpu);
}
}
ulong[] exponents = [6UL, 7UL, 9UL, 10UL, 12UL];
[Fact]
[Trait("Category", "Fast")]
public void ByDivisor_session_marks_mersenne_numbers_divisible_by_eleven_as_composite()
{
var tester = new MersenneNumberDivisorByDivisorCpuTester();
tester.ConfigureFromMaxPrime(61UL);
MontgomeryDivisorData divisorData = MontgomeryDivisorData.FromModulus(7UL);
ulong cycle = MersenneDivisorCycles.CalculateCycleLengthCpu(7UL, divisorData);
session.CheckDivisor(7UL, divisorData, cycle, exponents).Should().BeTrue();
var gpu = PrimeOrderCalculatorAccelerator.Rent(1);
var session = tester.CreateDivisorSession(gpu);
try
{
ulong[] exponents = [10UL, 11UL, 20UL, 21UL, 30UL];
ulong[] nonDivisibleExponents = [5UL, 11UL];
session.CheckDivisor(7UL, divisorData, cycle, nonDivisibleExponents).Should().BeFalse();
}
MontgomeryDivisorData divisorData = MontgomeryDivisorData.FromModulus(11UL);
ulong cycle = MersenneDivisorCycles.CalculateCycleLengthCpu(11UL, divisorData);
session.CheckDivisor(11UL, divisorData, cycle, exponents).Should().BeTrue();
[Fact]
[Trait("Category", "Fast")]
public void ByDivisor_session_marks_mersenne_numbers_divisible_by_eleven_as_composite()
{
var session = new MersenneCpuDivisorScanSessionWithCpuOrder();
ulong[] exponents = [10UL, 11UL, 20UL, 21UL, 30UL];
MontgomeryDivisorData divisorData = MontgomeryDivisorData.FromModulus(11UL);
ulong cycle = MersenneDivisorCycles.CalculateCycleLengthCpu(11UL, divisorData);
session.CheckDivisor(11UL, divisorData, cycle, exponents).Should().BeTrue();
ulong[] nonDivisibleExponents = [5UL, 17UL];
session.CheckDivisor(11UL, divisorData, cycle, nonDivisibleExponents).Should().BeFalse();
}
[Fact]
[Trait("Category", "Fast")]
public void ByDivisor_does_not_mark_mersenne_prime_as_composite_via_self_divisor()
{
var tester = new MersenneNumberDivisorByDivisorCpuTesterWithCpuOrder();
tester.DivisorLimit = (BigInteger.One << 30) - BigInteger.One;
BigInteger kSelf = ((BigInteger.One << 31) - 2) / 62; // (2^p - 2) / (2p) for p=31.
tester.ResumeFromState(Path.Combine(Path.GetTempPath(), "bydivisor-selfdivisor.bin"), BigInteger.Zero, kSelf);
tester.ResetStateTracking();
tester.IsPrime(31UL, out bool divisorsExhausted, out BigInteger divisor).Should().BeTrue();
divisorsExhausted.Should().BeTrue();
divisor.Should().Be(BigInteger.Zero);
}
ulong[] nonDivisibleExponents = [5UL, 17UL];
session.CheckDivisor(11UL, divisorData, cycle, nonDivisibleExponents).Should().BeFalse();
}
finally
{
session.Return();
PrimeOrderCalculatorAccelerator.Return(gpu);
}
}
}
@@ -68,7 +68,6 @@ public class MersenneNumberDivisorGpuTesterTests
{
tester.IsPrime(gpu, 35UL, 31UL, 0UL, out bool divisorsExhausted).Should().BeFalse();
divisorsExhausted.Should().BeTrue();
}
finally
{
@@ -93,47 +92,46 @@ public class MersenneNumberDivisorGpuTesterTests
}
}
private static void ConfigureByDivisorTester(MersenneNumberDivisorByDivisorGpuTester tester, ulong maxPrime)
{
tester.PrepareCandidates(maxPrime, ReadOnlySpan<ulong>.Empty, Span<ulong>.Empty);
tester.ResumeFromState(Path.Combine(Path.GetTempPath(), "bydivisor-gpu-tests.bin"), BigInteger.Zero, BigInteger.One);
tester.ResetStateTracking();
}
[Fact]
[Trait("Category", "Fast")]
public void ByDivisor_tester_tracks_divisors_across_primes()
{
var tester = new MersenneNumberDivisorByDivisorGpuTester();
tester.ConfigureFromMaxPrime(43UL);
ConfigureByDivisorTester(tester, maxPrime: 43UL);
var gpu = PrimeOrderCalculatorAccelerator.Rent(1);
try
{
tester.IsPrime(gpu, 31UL, out bool exhausted, out BigInteger divisor).Should().BeTrue();
exhausted.Should().BeTrue();
divisor.Should().Be(BigInteger.Zero);
tester.IsPrime(31UL, out bool exhausted, out BigInteger divisor).Should().BeTrue();
exhausted.Should().BeTrue();
divisor.Should().Be(BigInteger.Zero);
tester.IsPrime(gpu, 37UL, out exhausted, out divisor).Should().BeFalse();
exhausted.Should().BeTrue();
divisor.Should().BeGreaterThan(BigInteger.Zero);
tester.IsPrime(37UL, out exhausted, out divisor).Should().BeFalse();
exhausted.Should().BeTrue();
divisor.Should().BeGreaterThan(BigInteger.Zero);
tester.IsPrime(gpu, 43UL, out exhausted, out divisor).Should().BeFalse();
exhausted.Should().BeTrue();
divisor.Should().BeGreaterThan(BigInteger.Zero);
}
finally
{
PrimeOrderCalculatorAccelerator.Return(gpu);
}
tester.IsPrime(43UL, out exhausted, out divisor).Should().BeFalse();
exhausted.Should().BeTrue();
divisor.Should().BeGreaterThan(BigInteger.Zero);
}
[Fact]
[Trait("Category", "Fast")]
public void ByDivisor_tester_defaults_to_zero_limit_before_configuration()
public void ByDivisor_tester_defaults_to_zero_limit_before_prepare_candidates()
{
var tester = new MersenneNumberDivisorByDivisorGpuTester();
tester.DivisorLimit.Should().Be(0UL);
ulong[] primes = [31UL, 37UL];
ulong[] allowed = new ulong[primes.Length];
tester.PrepareCandidates(maxPrime: 37UL, primes, allowed);
tester.PrepareCandidates(primes, allowed);
allowed.Should().OnlyContain(value => value == 0UL);
tester.DivisorLimit.Should().BeGreaterThan(0UL);
allowed.Should().OnlyContain(value => value > 0UL);
}
[Fact]
@@ -141,28 +139,20 @@ public class MersenneNumberDivisorGpuTesterTests
public void ByDivisor_tester_respects_filter_based_limit()
{
var tester = new MersenneNumberDivisorByDivisorGpuTester();
tester.ConfigureFromMaxPrime(41UL);
ConfigureByDivisorTester(tester, maxPrime: 41UL);
var gpu = PrimeOrderCalculatorAccelerator.Rent(1);
try
{
tester.IsPrime(gpu, 31UL, out _, out BigInteger divisor).Should().BeTrue();
divisor.Should().Be(BigInteger.Zero);
tester.IsPrime(gpu, 37UL, out bool exhausted, out divisor).Should().BeFalse();
exhausted.Should().BeTrue();
divisor.Should().BeGreaterThan(BigInteger.Zero);
tester.IsPrime(31UL, out _, out BigInteger divisor).Should().BeTrue();
divisor.Should().Be(BigInteger.Zero);
tester.IsPrime(gpu, 41UL, out bool divisorsExhausted, out divisor).Should().BeFalse();
divisorsExhausted.Should().BeTrue();
divisor.Should().BeGreaterThan(BigInteger.Zero);
}
finally
{
PrimeOrderCalculatorAccelerator.Return(gpu);
}
tester.IsPrime(37UL, out bool exhausted, out divisor).Should().BeFalse();
exhausted.Should().BeTrue();
divisor.Should().BeGreaterThan(BigInteger.Zero);
tester.IsPrime(41UL, out bool divisorsExhausted, out divisor).Should().BeFalse();
divisorsExhausted.Should().BeTrue();
divisor.Should().BeGreaterThan(BigInteger.Zero);
}
[Theory]
[InlineData(71UL, false)]
[InlineData(89UL, true)]
@@ -171,50 +161,39 @@ public class MersenneNumberDivisorGpuTesterTests
public void ByDivisor_tester_matches_incremental_expectations(ulong exponent, bool expectedPrime)
{
var tester = new MersenneNumberDivisorByDivisorGpuTester();
tester.ConfigureFromMaxPrime(exponent);
ConfigureByDivisorTester(tester, maxPrime: exponent);
var gpu = PrimeOrderCalculatorAccelerator.Rent(1);
try
tester.IsPrime(exponent, out bool exhausted, out BigInteger divisor).Should().Be(expectedPrime);
exhausted.Should().BeTrue();
if (expectedPrime)
{
tester.IsPrime(gpu, exponent, out bool exhausted, out BigInteger divisor).Should().Be(expectedPrime);
exhausted.Should().BeTrue();
if (expectedPrime)
{
divisor.Should().Be(BigInteger.Zero);
}
else
{
divisor.Should().BeGreaterThan(BigInteger.Zero);
}
divisor.Should().Be(BigInteger.Zero);
}
finally
else
{
PrimeOrderCalculatorAccelerator.Return(gpu);
divisor.Should().BeGreaterThan(BigInteger.Zero);
}
}
[Fact]
[Trait("Category", "Fast")]
public void ByDivisor_gpu_tester_uses_cycle_remainders_per_divisor()
{
var tester = new MersenneNumberDivisorByDivisorGpuTester
{
GpuBatchSize = 8,
};
tester.ConfigureFromMaxPrime(43UL);
var gpu = PrimeOrderCalculatorAccelerator.Rent(1);
int originalBatchSize = EnvironmentConfiguration.GpuBatchSize;
try
{
tester.IsPrime(gpu, 41UL, out bool divisorsExhausted, out BigInteger divisor).Should().BeFalse();
EnvironmentConfiguration.GpuBatchSize = 8;
var tester = new MersenneNumberDivisorByDivisorGpuTester();
ConfigureByDivisorTester(tester, maxPrime: 43UL);
tester.IsPrime(41UL, out bool divisorsExhausted, out BigInteger divisor).Should().BeFalse();
divisorsExhausted.Should().BeTrue();
divisor.Should().BeGreaterThan(BigInteger.Zero);
}
finally
{
PrimeOrderCalculatorAccelerator.Return(gpu);
EnvironmentConfiguration.GpuBatchSize = originalBatchSize;
}
}
@@ -223,14 +202,14 @@ public class MersenneNumberDivisorGpuTesterTests
public void ByDivisor_session_computes_cycle_when_zero_is_provided()
{
var tester = new MersenneNumberDivisorByDivisorGpuTester();
tester.ConfigureFromMaxPrime(43UL);
ConfigureByDivisorTester(tester, maxPrime: 43UL);
var gpu = PrimeOrderCalculatorAccelerator.Rent(1);
var session = tester.CreateDivisorSession(gpu);
try
{
ulong[] primes = [31UL, 37UL, 41UL];
var session = tester.CreateDivisorSession(gpu);
ulong[] primes = [31UL, 37UL, 41UL];
session.CheckDivisor(223UL, MontgomeryDivisorData.FromModulus(223UL), 0UL, primes).Should().BeTrue();
ulong[] primesWithoutHit = [31UL, 41UL];
@@ -238,7 +217,6 @@ public class MersenneNumberDivisorGpuTesterTests
}
finally
{
session.Return();
PrimeOrderCalculatorAccelerator.Return(gpu);
}
}
@@ -248,12 +226,13 @@ public class MersenneNumberDivisorGpuTesterTests
public void ByDivisor_session_checks_divisors_across_primes()
{
var tester = new MersenneNumberDivisorByDivisorGpuTester();
tester.ConfigureFromMaxPrime(43UL);
ConfigureByDivisorTester(tester, maxPrime: 43UL);
var gpu = PrimeOrderCalculatorAccelerator.Rent(1);
var session = tester.CreateDivisorSession(gpu);
try
{
var session = tester.CreateDivisorSession(gpu);
ulong[] primes = [31UL, 37UL, 41UL, 43UL];
ulong cycle223 = MersenneDivisorCycles.CalculateCycleLengthGpu(gpu, 223UL, MontgomeryDivisorData.FromModulus(223UL));
@@ -270,7 +249,6 @@ public class MersenneNumberDivisorGpuTesterTests
}
finally
{
session.Return();
PrimeOrderCalculatorAccelerator.Return(gpu);
}
}
@@ -279,29 +257,34 @@ public class MersenneNumberDivisorGpuTesterTests
[Trait("Category", "Fast")]
public void ByDivisor_gpu_session_reuses_cycle_remainders_across_batches()
{
var tester = new MersenneNumberDivisorByDivisorGpuTester
{
GpuBatchSize = 2,
};
tester.ConfigureFromMaxPrime(47UL);
var gpu = PrimeOrderCalculatorAccelerator.Rent(1);
var session = tester.CreateDivisorSession(gpu);
int originalBatchSize = EnvironmentConfiguration.GpuBatchSize;
try
{
ulong[] primes = [31UL, 37UL, 41UL, 43UL, 47UL];
EnvironmentConfiguration.GpuBatchSize = 2;
var tester = new MersenneNumberDivisorByDivisorGpuTester();
ConfigureByDivisorTester(tester, maxPrime: 47UL);
ulong cycle223 = MersenneDivisorCycles.CalculateCycleLengthGpu(gpu, 223UL, MontgomeryDivisorData.FromModulus(223UL));
session.CheckDivisor(223UL, MontgomeryDivisorData.FromModulus(223UL), cycle223, primes).Should().BeTrue();
var gpu = PrimeOrderCalculatorAccelerator.Rent(1);
try
{
var session = tester.CreateDivisorSession(gpu);
ulong[] primesBeforeHit = [31UL];
session.CheckDivisor(223UL, MontgomeryDivisorData.FromModulus(223UL), cycle223, primesBeforeHit).Should().BeFalse();
ulong[] primes = [31UL, 37UL, 41UL, 43UL, 47UL];
ulong cycle223 = MersenneDivisorCycles.CalculateCycleLengthGpu(gpu, 223UL, MontgomeryDivisorData.FromModulus(223UL));
session.CheckDivisor(223UL, MontgomeryDivisorData.FromModulus(223UL), cycle223, primes).Should().BeTrue();
ulong[] primesBeforeHit = [31UL];
session.CheckDivisor(223UL, MontgomeryDivisorData.FromModulus(223UL), cycle223, primesBeforeHit).Should().BeFalse();
}
finally
{
PrimeOrderCalculatorAccelerator.Return(gpu);
}
}
finally
{
session.Return();
PrimeOrderCalculatorAccelerator.Return(gpu);
EnvironmentConfiguration.GpuBatchSize = originalBatchSize;
}
}
@@ -309,16 +292,13 @@ public class MersenneNumberDivisorGpuTesterTests
[Trait("Category", "Fast")]
public void ByDivisor_session_marks_mersenne_numbers_divisible_by_seven_as_composite()
{
var tester = new MersenneNumberDivisorByDivisorGpuTester
{
GpuBatchSize = 5,
};
tester.ConfigureFromMaxPrime(43UL);
var tester = new MersenneNumberDivisorByDivisorGpuTester();
ConfigureByDivisorTester(tester, maxPrime: 43UL);
var gpu = PrimeOrderCalculatorAccelerator.Rent(1);
var session = tester.CreateDivisorSession(gpu);
try
{
var session = tester.CreateDivisorSession(gpu);
ulong[] exponents = [6UL, 7UL, 9UL, 10UL, 12UL];
MontgomeryDivisorData divisorData = MontgomeryDivisorData.FromModulus(7UL);
@@ -331,7 +311,6 @@ public class MersenneNumberDivisorGpuTesterTests
}
finally
{
session.Return();
PrimeOrderCalculatorAccelerator.Return(gpu);
}
}
@@ -340,16 +319,13 @@ public class MersenneNumberDivisorGpuTesterTests
[Trait("Category", "Fast")]
public void ByDivisor_session_marks_mersenne_numbers_divisible_by_eleven_as_composite()
{
var tester = new MersenneNumberDivisorByDivisorGpuTester
{
GpuBatchSize = 5,
};
tester.ConfigureFromMaxPrime(61UL);
var tester = new MersenneNumberDivisorByDivisorGpuTester();
ConfigureByDivisorTester(tester, maxPrime: 61UL);
var gpu = PrimeOrderCalculatorAccelerator.Rent(1);
var session = tester.CreateDivisorSession(gpu);
try
{
var session = tester.CreateDivisorSession(gpu);
ulong[] exponents = [10UL, 11UL, 20UL, 21UL, 30UL];
MontgomeryDivisorData divisorData = MontgomeryDivisorData.FromModulus(11UL);
@@ -362,7 +338,6 @@ public class MersenneNumberDivisorGpuTesterTests
}
finally
{
session.Return();
PrimeOrderCalculatorAccelerator.Return(gpu);
}
}
@@ -392,13 +367,13 @@ public class MersenneNumberDivisorGpuTesterTests
DivisorCycleCache.Shared.RefreshSnapshot();
var tester = new MersenneNumberDivisorByDivisorGpuTester();
tester.ConfigureFromMaxPrime(19UL);
ConfigureByDivisorTester(tester, maxPrime: 19UL);
typeof(MersenneNumberDivisorByDivisorGpuTester)
.GetField("_divisorLimit", BindingFlags.NonPublic | BindingFlags.Instance)!
.SetValue(tester, 200UL);
tester.IsPrime(gpu, 19UL, out bool divisorsExhausted, out BigInteger divisor).Should().BeTrue();
tester.IsPrime(19UL, out bool divisorsExhausted, out BigInteger divisor).Should().BeTrue();
divisorsExhausted.Should().BeTrue();
divisor.Should().Be(BigInteger.Zero);
}
@@ -413,32 +388,15 @@ public class MersenneNumberDivisorGpuTesterTests
[Fact]
[Trait("Category", "Fast")]
public void ByDivisor_cpu_session_reuses_cycle_remainders_across_primes()
public void ByDivisor_cpu_session_checks_divisors_across_primes()
{
var tester = new MersenneNumberDivisorByDivisorCpuTester
{
BatchSize = 2,
};
var session = new MersenneCpuDivisorScanSessionWithCpuOrder();
tester.ConfigureFromMaxPrime(47UL);
ulong[] primes = [31UL, 37UL, 41UL, 43UL, 47UL];
ulong cycle223 = MersenneDivisorCycles.CalculateCycleLengthCpu(223UL, MontgomeryDivisorData.FromModulus(223UL));
session.CheckDivisor(223UL, MontgomeryDivisorData.FromModulus(223UL), cycle223, primes).Should().BeTrue();
var gpu = PrimeOrderCalculatorAccelerator.Rent(1);
var session = tester.CreateDivisorSession(gpu);
try
{
ulong[] primes = [31UL, 37UL, 41UL, 43UL, 47UL];
ulong cycle223 = MersenneDivisorCycles.CalculateCycleLengthGpu(gpu, 223UL, MontgomeryDivisorData.FromModulus(223UL));
session.CheckDivisor(223UL, MontgomeryDivisorData.FromModulus(223UL), cycle223, primes).Should().BeTrue();
ulong[] primesBeforeHit = [31UL];
session.CheckDivisor(223UL, MontgomeryDivisorData.FromModulus(223UL), cycle223, primesBeforeHit).Should().BeFalse();
}
finally
{
session.Return();
PrimeOrderCalculatorAccelerator.Return(gpu);
}
ulong[] primesBeforeHit = [31UL];
session.CheckDivisor(223UL, MontgomeryDivisorData.FromModulus(223UL), cycle223, primesBeforeHit).Should().BeFalse();
}
}