BitContradiction improvements.

This commit is contained in:
Marek Lemańczyk committed 2026-02-10 11:52:26 +01:00
1 parent b453d46c5f
commit 22cc8f368f
7 files changed
+5298 -4229

No files matched your search

@@ -1,3 +1,4 @@
using System.Numerics;
using FluentAssertions; using FluentAssertions;
using PerfectNumbers.Core.ByDivisor; using PerfectNumbers.Core.ByDivisor;
using Xunit; using Xunit;
@@ -22,7 +23,7 @@ public class BitContradictionSolverTests
[Fact] [Fact]
public void TryPropagateCarry_FailsWhenParityUnreachable() public void TryPropagateCarry_FailsWhenParityUnreachable()
{ {
CarryRange carry = CarryRange.Single(0); CarryRange carry = CarryRange.Single(0);
bool success = TryPropagateCarry( bool success = TryPropagateCarry(
currentCarry: ref carry, currentCarry: ref carry,
forcedOnes: 0, forcedOnes: 0,
@@ -34,10 +35,34 @@ public class BitContradictionSolverTests
carry.Max.Should().Be(0); carry.Max.Should().Be(0);
} }
[Fact]
[Trait("Category", "Fast")]
public void ShouldPruneWithFinalPow2Shift_ReturnsTrue_WhenShiftedResidueStaysBelowModulusAndResidueIsNotOne()
{
bool shouldPrune = ShouldPruneWithFinalPow2Shift(
prefixResidue: new BigInteger(3),
modulus: new BigInteger(1000),
tailShift: 8);
shouldPrune.Should().BeTrue();
}
[Fact]
[Trait("Category", "Fast")]
public void ShouldPruneWithFinalPow2Shift_ReturnsFalse_WhenResidueIsOne()
{
bool shouldPrune = ShouldPruneWithFinalPow2Shift(
prefixResidue: BigInteger.One,
modulus: new BigInteger(1000),
tailShift: 8);
shouldPrune.Should().BeFalse();
}
[Fact] [Fact]
public void TryPropagateCarry_ComputesNextCarryRange() public void TryPropagateCarry_ComputesNextCarryRange()
{ {
CarryRange carry = new(0, 1); CarryRange carry = new(0, 1);
bool success = TryPropagateCarry( bool success = TryPropagateCarry(
currentCarry: ref carry, currentCarry: ref carry,
forcedOnes: 1, forcedOnes: 1,
File diff suppressed because it is too large. Load diff
@@ -1,4 +1,4 @@
// #define DivisorSet_BitContradiction // #define DivisorSet_BitContradiction
// #define DivisorSet_BitTree // #define DivisorSet_BitTree
// #define DEVICE_GPU // #define DEVICE_GPU
@@ -5108,8 +5108,10 @@ public struct MersenneNumberDivisorByDivisorCpuTesterWithTemplate() : IMersenneN
while (true) while (true)
{ {
int remainder8 = (stepMod8 * kRem8 + 1) & 7; int remainder8 = (stepMod8 * kRem8 + 1) & 7;
#if DETAILED_LOG
if (prime == 138000001UL && divisor == 1209708008767) if (prime == 138000001UL && divisor == 1209708008767)
Console.WriteLine("[HIT] enumerated target q before remainder8 check"); Console.WriteLine("[HIT] enumerated target q before remainder8 check");
#endif
if (remainder8 != 1 && remainder8 != 7) if (remainder8 != 1 && remainder8 != 7)
{ {
@@ -5152,17 +5154,20 @@ public struct MersenneNumberDivisorByDivisorCpuTesterWithTemplate() : IMersenneN
} }
} }
#if DETAILED_LOG
if (prime == 138000001UL && divisor == 1209708008767) if (prime == 138000001UL && divisor == 1209708008767)
{ {
Console.WriteLine("[HIT] processed target q. Stopping."); Console.WriteLine("[HIT] processed target q. Stopping.");
Environment.Exit(1); Environment.Exit(1);
} }
#endif
RecordState(currentK);
MOVE_NEXT: MOVE_NEXT:
ContinueOuter: ContinueOuter:
RecordState(currentK);
if (hasLimit && currentK >= maxK) if (hasLimit && currentK >= maxK)
{ {
RecordState(currentK);
break; break;
} }
@@ -5357,9 +5362,9 @@ public struct MersenneNumberDivisorByDivisorCpuTesterWithTemplate() : IMersenneN
ReadOnlySpan<int> oneOffsetsSlice = oneOffsets[..oneCount]; ReadOnlySpan<int> oneOffsetsSlice = oneOffsets[..oneCount];
// BitContradictionSolverWithQMultiplier.SetDebugEnabled(true); // BitContradictionSolverWithQMultiplier.SetDebugEnabled(true);
#if DETAILED_LOG #if DETAILED_LOG
bool decided = BitContradictionSolverWithAMultiplier.TryCheckDivisibilityFromOneOffsets(oneOffsetsSlice, prime, currentK, isPowerOfTwo, out divides, out var reason); bool decided = BitContradictionSolverWithAMultiplier.TryCheckDivisibilityFromOneOffsets(oneOffsetsSlice, prime, divisor, currentK, isPowerOfTwo, out divides, out var reason);
#else #else
bool decided = BitContradictionSolverWithAMultiplier.TryCheckDivisibilityFromOneOffsets(oneOffsetsSlice, prime, currentK, isPowerOfTwo, out divides); bool decided = BitContradictionSolverWithAMultiplier.TryCheckDivisibilityFromOneOffsets(oneOffsetsSlice, prime, divisor, currentK, isPowerOfTwo, out divides);
#endif #endif
// BitContradictionSolverWithQMultiplier.SetDebugEnabled(false); // BitContradictionSolverWithQMultiplier.SetDebugEnabled(false);
if (decided && divides) if (decided && divides)
@@ -21,12 +21,14 @@ public static class PerfectNumberConstants
public const int PooledArrayThreshold = 64; public const int PooledArrayThreshold = 64;
public const int Pow2WindowSize = 8; public const int Pow2WindowSize = 8;
public const int RollingAccelerators = 298; public const int RollingAccelerators = 298;
public const int ThreadsByAccelerator = 128; public const int ThreadsByAccelerator = 4;
public const int ByDivisorStateSaveInterval = 1_000; public const int ByDivisorFlushAndEvictInterval = 5;
public const int ByDivisorStateSaveInterval = 10_000_000;
public const string ByDivisorStateDirectory = "Checks"; public const string ByDivisorStateDirectory = "Checks";
public const int PollardRhoMilliseconds = 100; public const int PollardRhoMilliseconds = 100;
public const int ByDivisorMersenneTailCount = 8; public const int ByDivisorMersenneTailCount = 8;
public const int ByDivisorMersenneBitLimit = 4096; public const int ByDivisorMersenneBitLimit = 4096;
public const int BitContradictionForcedALowBits = 4096;
public const int BitContradictionGpuBatchCount = 16; public const int BitContradictionGpuBatchCount = 16;
// public const int BitContradictionGpuBatchCount = 512; // public const int BitContradictionGpuBatchCount = 512;
// public const int BitContradictionGpuBatchCount = 131_072; // public const int BitContradictionGpuBatchCount = 131_072;
@@ -13,6 +13,7 @@
<!-- <DefineConstants>$(DefineConstants);OVERRIDE_MIN_K</DefineConstants> --> <!-- <DefineConstants>$(DefineConstants);OVERRIDE_MIN_K</DefineConstants> -->
<!-- <DefineConstants>$(DefineConstants);SELF_TEST</DefineConstants> --> <!-- <DefineConstants>$(DefineConstants);SELF_TEST</DefineConstants> -->
<!-- <DefineConstants>$(DefineConstants);EXPORT_STAGE</DefineConstants> --> <!-- <DefineConstants>$(DefineConstants);EXPORT_STAGE</DefineConstants> -->
<!-- <DefineConstants>$(DefineConstants);WITH_PRUNE_STATS</DefineConstants> -->
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
@@ -68,12 +68,15 @@ public sealed class KStateRepository : IDisposable
session.Upsert(keyString, valueString); session.Upsert(keyString, valueString);
session.CompletePending(true); session.CompletePending(true);
var flushCount = ++_flushCount; var flushCount = ++_flushCount;
if (flushCount >= PerfectNumberConstants.ByDivisorStateSaveInterval) if (flushCount >= PerfectNumberConstants.ByDivisorFlushAndEvictInterval)
{ {
_flushCount = 0; _flushCount = 0;
_store.Log.FlushAndEvict(wait: true); _store.Log.FlushAndEvict(wait: true);
} }
else
{
_store.Log.Flush(wait: false);
}
} }
public bool TryGet(ulong prime, out BigInteger value) public bool TryGet(ulong prime, out BigInteger value)
+2
View File
@@ -70,6 +70,7 @@ namespace PerfectNumbers.Core
61 => BigIntegerNumbers.Pow2Exact61, 61 => BigIntegerNumbers.Pow2Exact61,
62 => BigIntegerNumbers.Pow2Exact62, 62 => BigIntegerNumbers.Pow2Exact62,
63 => BigIntegerNumbers.Pow2Exact63, 63 => BigIntegerNumbers.Pow2Exact63,
_ when i >= 0 => System.Numerics.BigInteger.One << i,
_ => throw new ArgumentOutOfRangeException(nameof(i), $"Parameter value {i} is incorrect"), _ => throw new ArgumentOutOfRangeException(nameof(i), $"Parameter value {i} is incorrect"),
}; };
@@ -140,6 +141,7 @@ namespace PerfectNumbers.Core
62 => BigIntegerNumbers.Pow2MinusOne62, 62 => BigIntegerNumbers.Pow2MinusOne62,
63 => BigIntegerNumbers.Pow2MinusOne63, 63 => BigIntegerNumbers.Pow2MinusOne63,
1024 => BigIntegerNumbers.Pow2MinusOne1024, 1024 => BigIntegerNumbers.Pow2MinusOne1024,
_ when i >= 0 => (System.Numerics.BigInteger.One << i) - System.Numerics.BigInteger.One,
_ => throw new ArgumentOutOfRangeException(nameof(i), $"Parameter value {i} is incorrect"), _ => throw new ArgumentOutOfRangeException(nameof(i), $"Parameter value {i} is incorrect"),
}; };
} }