Remove Montgomery data from GPU divisor flow

This commit is contained in:
Marek Lemańczyk committed 2025-10-24 18:56:28 +02:00
1 parent 69acd3dad9
commit 46a2178d65
4 files changed
+11 -152

No files matched your search

@@ -326,103 +326,6 @@ public class MersenneDivisorCycles
ThreadStaticPools.ReturnFactorCountDictionary(factorCounts);
return success;
}
public static bool TryCalculateCycleLengthForExponentGpu(
ulong divisor,
ulong exponent,
in MontgomeryDivisorData divisorData,
out ulong cycleLength,
out bool primeOrderFailed)
{
cycleLength = 0UL;
primeOrderFailed = false;
if ((divisor & (divisor - 1UL)) == 0UL)
{
cycleLength = 1UL;
return true;
}
if (divisor <= 3UL || exponent <= 1UL)
{
cycleLength = CalculateCycleLength(divisor, divisorData);
return true;
}
ulong computedOrder = PrimeOrderCalculator.Calculate(
divisor,
previousOrder: null,
divisorData,
PrimeOrderCalculator.PrimeOrderSearchConfig.HeuristicDefault,
PrimeOrderCalculator.PrimeOrderHeuristicDevice.Cpu);
if (computedOrder != 0UL)
{
cycleLength = computedOrder;
return true;
}
primeOrderFailed = true;
ulong phi = divisor - 1UL;
// A zero totient would imply divisor == 0, which never occurs on the tested path. Keep the guard documented without
// branching in the hot loop.
// if (phi == 0UL)
// {
// return false;
// }
int twoCount = BitOperations.TrailingZeroCount(phi);
ulong reducedPhi = phi >> twoCount;
if (reducedPhi == 0UL || (reducedPhi % exponent) != 0UL)
{
return false;
}
ulong k = reducedPhi / exponent;
// k == 0 would indicate reducedPhi < exponent, which the EvenPerfectBitScanner call flow prevents. Document the
// assumption instead of branching.
// if (k == 0UL)
// {
// return false;
// }
Dictionary<ulong, int> factorCounts = ThreadStaticPools.RentFactorCountDictionary();
bool success = false;
if (twoCount > 0)
{
factorCounts[2UL] = twoCount;
}
bool exponentAccumulated = AccumulateFactors(exponent, factorCounts);
bool factorsAccumulated = exponentAccumulated && AccumulateFactors(k, factorCounts);
if (factorsAccumulated)
{
cycleLength = ReduceOrder(divisorData, phi, factorCounts);
success = true;
primeOrderFailed = false;
}
factorCounts.Clear();
ThreadStaticPools.ReturnFactorCountDictionary(factorCounts);
return success;
}
internal static bool TryCalculateCycleLengthForExponentGpu(
ulong divisor,
ulong exponent,
in GpuDivisorPartialData divisorData,
out ulong cycleLength,
out bool primeOrderFailed) =>
TryCalculateCycleLengthForExponentGpu(divisor, exponent, divisorData.MontgomeryData, out cycleLength, out primeOrderFailed);
internal static ulong CalculateCycleLengthGpu(
ulong divisor,
in GpuDivisorPartialData divisorData,
bool skipPrimeOrderHeuristic = false)
{
return CalculateCycleLength(divisor, divisorData.MontgomeryData, skipPrimeOrderHeuristic);
}
private static bool AccumulateFactors(
ulong value,