Route prime-order pow2 kernel through plain modular helper

This commit is contained in:
Marek Lemańczyk committed 2025-10-13 05:08:34 +02:00
1 parent 7ef0906a9b
commit 716ffcb243
7 files changed
+78 -79

No files matched your search

@@ -35,7 +35,7 @@ public sealed class MersenneNumberDivisorByDivisorGpuTester : IMersenneNumberDiv
_kernelCache.GetOrAdd(accelerator, acc => acc.LoadAutoGroupedStreamKernel<Index1D, ArrayView<MontgomeryDivisorData>, ArrayView<ulong>, ArrayView<byte>>(CheckKernel));
private Action<Index1D, MontgomeryDivisorData, ArrayView<ulong>, ArrayView<ulong>> GetKernelByPrimeExponent(Accelerator accelerator) =>
_kernelExponentCache.GetOrAdd(accelerator, acc => acc.LoadAutoGroupedStreamKernel<Index1D, MontgomeryDivisorData, ArrayView<ulong>, ArrayView<ulong>>(ComputeMontgomeryExponentKernel));
_kernelExponentCache.GetOrAdd(accelerator, acc => acc.LoadAutoGroupedStreamKernel<Index1D, MontgomeryDivisorData, ArrayView<ulong>, ArrayView<ulong>>(ComputeExponentKernel));
private Action<Index1D, ArrayView<ulong>, ArrayView<byte>, byte> GetRemainderDeltaKernel(Accelerator accelerator) =>
_remainderDeltaKernelCache.GetOrAdd(accelerator, acc => acc.LoadAutoGroupedStreamKernel<Index1D, ArrayView<ulong>, ArrayView<byte>, byte>(ComputeRemainderDeltasKernel));
@@ -569,7 +569,7 @@ public sealed class MersenneNumberDivisorByDivisorGpuTester : IMersenneNumberDiv
}
ulong exponent = exponents[index];
hits[index] = exponent.Pow2MontgomeryModWindowedGpu(divisor, keepMontgomery: false) == 1UL ? (byte)1 : (byte)0;
hits[index] = exponent.Pow2ModBinaryGpu(modulus) == 1UL ? (byte)1 : (byte)0;
}
public sealed class DivisorScanSession : IMersenneNumberDivisorByDivisorTester.IDivisorScanSession
@@ -777,7 +777,7 @@ public sealed class MersenneNumberDivisorByDivisorGpuTester : IMersenneNumberDiv
mask[globalIndex] = 1;
}
private static void ComputeMontgomeryExponentKernel(Index1D index, MontgomeryDivisorData divisor, ArrayView<ulong> exponents, ArrayView<ulong> results)
private static void ComputeExponentKernel(Index1D index, MontgomeryDivisorData divisor, ArrayView<ulong> exponents, ArrayView<ulong> results)
{
ulong modulus = divisor.Modulus;
if (modulus <= 1UL || (modulus & 1UL) == 0UL)
@@ -788,7 +788,7 @@ public sealed class MersenneNumberDivisorByDivisorGpuTester : IMersenneNumberDiv
ulong exponent = exponents[index];
results[index] = exponent.Pow2MontgomeryModWindowedGpu(divisor, keepMontgomery: true);
results[index] = exponent.Pow2ModBinaryGpu(modulus);
}
public ulong DivisorLimit
@@ -109,6 +109,13 @@ internal sealed class MersenneNumberDivisorResidueGpuEvaluator : IDisposable
}
ulong exponent = exponents[idx];
results[idx] = exponent.Pow2MontgomeryModWindowedGpu(divisorData, keepMontgomery: true);
ulong modulus = divisorData.Modulus;
if (modulus <= 1UL || (modulus & 1UL) == 0UL)
{
results[idx] = 0UL;
return;
}
results[idx] = exponent.Pow2ModBinaryGpu(modulus);
}
}
@@ -811,7 +811,7 @@ internal static partial class PrimeOrderGpuHeuristics
}
ulong reduced = phi / factor;
if (reduced.Pow2MontgomeryModWindowedGpu(divisor, keepMontgomery: false) == 1UL)
if (reduced.Pow2ModBinaryGpu(divisor.Modulus) == 1UL)
{
return false;
}
@@ -1595,7 +1595,7 @@ internal static partial class PrimeOrderGpuHeuristics
private static bool Pow2EqualsOneKernel(ulong exponent, in MontgomeryDivisorData divisor)
{
return exponent.Pow2MontgomeryModWindowedGpu(divisor, keepMontgomery: false) == 1UL;
return exponent.Pow2ModBinaryGpu(divisor.Modulus) == 1UL;
}
private static ulong CalculateByDoublingKernel(ulong prime)
@@ -1810,58 +1810,15 @@ internal static partial class PrimeOrderGpuHeuristics
private static void Pow2ModKernel(Index1D index, ArrayView1D<ulong, Stride1D.Dense> exponents, MontgomeryDivisorData divisor, ArrayView1D<ulong, Stride1D.Dense> remainders)
{
ulong exponent = exponents[index];
ulong modulus = divisor.Modulus;
// ulong nPrime = divisor.NPrime;
// ulong result = divisor.MontgomeryOne;
// ulong baseValue = divisor.MontgomeryTwo;
// ulong remainingExponent = exponent;
if (modulus <= 1UL || (modulus & 1UL) == 0UL)
{
remainders[index] = 0UL;
return;
}
// if (remainingExponent == 0UL)
// {
// remainders[index] = result.MontgomeryMultiply(1UL, modulus, nPrime);
// return;
// }
// while (remainingExponent != 0UL)
// {
// if ((remainingExponent & 1UL) != 0UL)
// {
// result = result.MontgomeryMultiply(baseValue, modulus, nPrime);
// }
// remainingExponent >>= 1;
// if (remainingExponent == 0UL)
// {
// break;
// }
// // Reusing baseValue to hold base^2 so we avoid allocating another register for the squared term.
// baseValue = baseValue.MontgomeryMultiply(baseValue, modulus, nPrime);
// }
// remainders[index] = result.MontgomeryMultiply(1UL, modulus, nPrime);
// Plain modular exponentiation without Montgomery reduction kept for reference.
ulong plainResult = 1UL;// % modulus;
ulong plainBase = 2UL;// % modulus;
while (exponent != 0UL)
{
if ((exponent & 1UL) != 0UL)
{
plainResult = (plainResult * plainBase) % modulus;
}
exponent >>= 1;
if (exponent == 0UL)
{
break;
}
plainBase = (plainBase * plainBase) % modulus;
}
remainders[index] = plainResult;
ulong exponent = exponents[index];
remainders[index] = exponent.Pow2ModBinaryGpu(modulus);
}
private static Action<AcceleratorStream, Index1D, ArrayView1D<GpuUInt128, Stride1D.Dense>, GpuUInt128, ArrayView1D<GpuUInt128, Stride1D.Dense>> GetPow2ModWideKernel(Accelerator accelerator)