Prime testing using divisor tables depending on the last digit separated to its own class. PrimeTester switched back to standard endings.

This commit is contained in:
mlemanczyk committed 2025-11-27 16:45:02 +01:00
1 parent a296e62d4d
commit c311b27dcc
12 files changed
+526 -215

No files matched your search

@@ -16,10 +16,10 @@ public static class AcceleratorStreamPool
public static AcceleratorStream Rent(int acceleratorIndex)
{
var streamLock = _locks[acceleratorIndex];
// var streamLock = _locks[acceleratorIndex];
var queue = _streams[acceleratorIndex];
streamLock.Wait();
// streamLock.Wait();
return queue.TryDequeue(out var stream)
? stream
@@ -28,10 +28,10 @@ public static class AcceleratorStreamPool
public static void Return(int acceleratorIndex, AcceleratorStream stream)
{
var streamLock = _locks[acceleratorIndex];
// var streamLock = _locks[acceleratorIndex];
var queue = _streams[acceleratorIndex];
queue.Enqueue(stream);
streamLock.Release();
// streamLock.Release();
}
public static void WarmUp(int acceleratorIndex)
@@ -115,7 +115,7 @@ public sealed class PrimeOrderCalculatorAccelerator
public MemoryBuffer1D<ulong, Stride1D.Dense> OutputUlong;
public readonly MemoryBuffer1D<ulong, Stride1D.Dense> OutputUlong2;
public ArrayView1D<ulong, Stride1D.Dense> OutputUlongView;
public readonly ArrayView1D<ulong, Stride1D.Dense> OutputUlongView2;
public readonly ArrayView<ulong> OutputUlongView2;
public MemoryBuffer1D<int, Stride1D.Dense> OutputInt;
public readonly MemoryBuffer1D<int, Stride1D.Dense> OutputInt2;
@@ -159,7 +159,8 @@ public sealed class PrimeOrderCalculatorAccelerator
public readonly Action<AcceleratorStream, Index1D, ArrayView1D<ulong, Stride1D.Dense>, ulong, ulong, ulong, ulong, ulong, ArrayView1D<ulong, Stride1D.Dense>> ConvertToStandardKernelLauncher = KernelUtil.GetKernel(accelerator.LoadAutoGroupedStreamKernel<Index1D, ArrayView1D<ulong, Stride1D.Dense>, ulong, ulong, ulong, ulong, ulong, ArrayView1D<ulong, Stride1D.Dense>>(Pow2MontgomeryKernels.Pow2MontgomeryKernelConvertToStandard)).CreateLauncherDelegate<Action<AcceleratorStream, Index1D, ArrayView1D<ulong, Stride1D.Dense>, ulong, ulong, ulong, ulong, ulong, ArrayView1D<ulong, Stride1D.Dense>>>();
public readonly Action<AcceleratorStream, Index1D, byte, ArrayView<int>, ulong, ulong, HeuristicCombinedGpuViews> HeuristicCombinedTrialDivisionKernelLauncher = KernelUtil.GetKernel(accelerator.LoadAutoGroupedStreamKernel<Index1D, byte, ArrayView<int>, ulong, ulong, HeuristicCombinedGpuViews>(PrimeTesterKernels.HeuristicTrialCombinedDivisionKernel)).CreateLauncherDelegate<Action<AcceleratorStream, Index1D, byte, ArrayView<int>, ulong, ulong, HeuristicCombinedGpuViews>>();
// public readonly Action<AcceleratorStream, Index1D, byte, ArrayView<int>, ulong, ulong, HeuristicCombinedGpuViews> HeuristicCombinedTrialDivisionKernelLauncher = KernelUtil.GetKernel(accelerator.LoadAutoGroupedStreamKernel<Index1D, byte, ArrayView<int>, ulong, ulong, HeuristicCombinedGpuViews>(PrimeTesterKernels.HeuristicTrialCombinedDivisionKernel)).CreateLauncherDelegate<Action<AcceleratorStream, Index1D, byte, ArrayView<int>, ulong, ulong, HeuristicCombinedGpuViews>>();
public readonly Action<AcceleratorStream, Index1D, ArrayView<int>, ulong, ulong, ArrayView<ulong>, ArrayView<ulong>> HeuristicCombinedTrialDivisionKernelLauncher = KernelUtil.GetKernel(accelerator.LoadAutoGroupedStreamKernel<Index1D, ArrayView<int>, ulong, ulong, ArrayView<ulong>, ArrayView<ulong>>(PrimeTesterKernels.HeuristicTrialCombinedDivisionKernel)).CreateLauncherDelegate<Action<AcceleratorStream, Index1D, ArrayView<int>, ulong, ulong, ArrayView<ulong>, ArrayView<ulong>>>();
public readonly Action<AcceleratorStream, Index1D, ArrayView1D<ulong, Stride1D.Dense>, ulong, ulong, ulong, ulong, ulong, ArrayView1D<ulong, Stride1D.Dense>> KeepMontgomeryKernelLauncher = KernelUtil.GetKernel(accelerator.LoadAutoGroupedStreamKernel<Index1D, ArrayView1D<ulong, Stride1D.Dense>, ulong, ulong, ulong, ulong, ulong, ArrayView1D<ulong, Stride1D.Dense>>(Pow2MontgomeryKernels.Pow2MontgomeryKernelKeepMontgomery)).CreateLauncherDelegate<Action<AcceleratorStream, Index1D, ArrayView1D<ulong, Stride1D.Dense>, ulong, ulong, ulong, ulong, ulong, ArrayView1D<ulong, Stride1D.Dense>>>();
@@ -173,17 +174,17 @@ public sealed class PrimeOrderCalculatorAccelerator
// public readonly Action<AcceleratorStream, Index1D, ArrayView<ulong>, ArrayView<byte>> SharesFactorKernelLauncher = KernelUtil.GetKernel(accelerator.LoadAutoGroupedStreamKernel<Index1D, ArrayView<ulong>, ArrayView<byte>>(PrimeTesterKernels.SharesFactorKernel)).CreateLauncherDelegate<Action<AcceleratorStream, Index1D, ArrayView<ulong>, ArrayView<byte>>>();
public readonly Action<AcceleratorStream, Index1D, ulong, uint, ArrayView1D<uint, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>, int, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<int, Stride1D.Dense>, ArrayView1D<int, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>> SmallPrimeFactorKernelLauncher = KernelUtil.GetKernel(accelerator.LoadAutoGroupedStreamKernel<Index1D, ulong, uint, ArrayView1D<uint, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>, int, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<int, Stride1D.Dense>, ArrayView1D<int, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>>(SmallPrimeFactorKernels.SmallPrimeFactorKernelScan)).CreateLauncherDelegate<Action<AcceleratorStream, Index1D, ulong, uint, ArrayView1D<uint, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>, int, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<int, Stride1D.Dense>, ArrayView1D<int, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>>>();
// public readonly Action<AcceleratorStream, Index1D, ulong, uint, ArrayView1D<uint, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>, int, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<int, Stride1D.Dense>, ArrayView1D<int, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>> SmallPrimeFactorKernelLauncher = KernelUtil.GetKernel(accelerator.LoadAutoGroupedStreamKernel<Index1D, ulong, uint, ArrayView1D<uint, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>, int, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<int, Stride1D.Dense>, ArrayView1D<int, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>>(SmallPrimeFactorKernels.SmallPrimeFactorKernelScan)).CreateLauncherDelegate<Action<AcceleratorStream, Index1D, ulong, uint, ArrayView1D<uint, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>, int, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<int, Stride1D.Dense>, ArrayView1D<int, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>>>();
public readonly Action<AcceleratorStream, Index1D, ArrayView<ulong>, ArrayView<uint>, ArrayView<uint>, ArrayView<uint>, ArrayView<uint>, ArrayView<ulong>, ArrayView<ulong>, ArrayView<ulong>, ArrayView<ulong>, ArrayView<byte>> SmallPrimeSieveKernelLauncher = KernelUtil.GetKernel(accelerator.LoadAutoGroupedStreamKernel<Index1D, ArrayView<ulong>, ArrayView<uint>, ArrayView<uint>, ArrayView<uint>, ArrayView<uint>, ArrayView<ulong>, ArrayView<ulong>, ArrayView<ulong>, ArrayView<ulong>, ArrayView<byte>>(PrimeTesterKernels.SmallPrimeSieveKernel)).CreateLauncherDelegate<Action<AcceleratorStream, Index1D, ArrayView<ulong>, ArrayView<uint>, ArrayView<uint>, ArrayView<uint>, ArrayView<uint>, ArrayView<ulong>, ArrayView<ulong>, ArrayView<ulong>, ArrayView<ulong>, ArrayView<byte>>>();
// public readonly Action<AcceleratorStream, Index1D, ArrayView<ulong>, ArrayView<uint>, ArrayView<uint>, ArrayView<uint>, ArrayView<uint>, ArrayView<ulong>, ArrayView<ulong>, ArrayView<ulong>, ArrayView<ulong>, ArrayView<byte>> SmallPrimeSieveKernelLauncher = KernelUtil.GetKernel(accelerator.LoadAutoGroupedStreamKernel<Index1D, ArrayView<ulong>, ArrayView<uint>, ArrayView<uint>, ArrayView<uint>, ArrayView<uint>, ArrayView<ulong>, ArrayView<ulong>, ArrayView<ulong>, ArrayView<ulong>, ArrayView<byte>>(PrimeTesterKernels.SmallPrimeSieveKernel)).CreateLauncherDelegate<Action<AcceleratorStream, Index1D, ArrayView<ulong>, ArrayView<uint>, ArrayView<uint>, ArrayView<uint>, ArrayView<uint>, ArrayView<ulong>, ArrayView<ulong>, ArrayView<ulong>, ArrayView<ulong>, ArrayView<byte>>>();
public readonly Action<AcceleratorStream, Index1D, ulong, ArrayView1D<ulong, Stride1D.Dense>, int, ulong, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>> SpecialMaxKernelLauncher = KernelUtil.GetKernel(accelerator.LoadAutoGroupedStreamKernel<Index1D, ulong, ArrayView1D<ulong, Stride1D.Dense>, int, ulong, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>>(PrimeOrderGpuHeuristics.EvaluateSpecialMaxCandidatesKernel)).CreateLauncherDelegate<Action<AcceleratorStream, Index1D, ulong, ArrayView1D<ulong, Stride1D.Dense>, int, ulong, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>>>();
public readonly Action<AcceleratorStream, Index1D, ulong, ArrayView<ulong>, int, ulong, ArrayView<ulong>> SpecialMaxKernelLauncher = KernelUtil.GetKernel(accelerator.LoadAutoGroupedStreamKernel<Index1D, ulong, ArrayView<ulong>, int, ulong, ArrayView<ulong>>(PrimeOrderGpuHeuristics.EvaluateSpecialMaxCandidatesKernel)).CreateLauncherDelegate<Action<AcceleratorStream, Index1D, ulong, ArrayView<ulong>, int, ulong, ArrayView<ulong>>>();
}
public readonly Action<AcceleratorStream, Index1D, ulong, CalculateOrderKernelConfig, ulong, ulong, ulong, ulong, ulong, ArrayView1D<uint, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>, int, OrderKernelBuffers> CalculateOrderKernelLauncher;
public readonly Kernel CheckFactorsKernel;
public readonly Action<AcceleratorStream, Index1D, ArrayView1D<ulong, Stride1D.Dense>, ulong, ulong, ulong, ulong, ulong, ArrayView1D<ulong, Stride1D.Dense>> ConvertToStandardKernelLauncher;
public readonly Action<AcceleratorStream, Index1D, byte, ArrayView<int>, ulong, ulong, HeuristicCombinedGpuViews> HeuristicCombinedTrialDivisionKernelLauncher;
public readonly Action<AcceleratorStream, Index1D, ArrayView<int>, ulong, ulong, ArrayView<ulong>, ArrayView<ulong>> HeuristicCombinedTrialDivisionKernelLauncher;
public readonly Action<AcceleratorStream, Index1D, ArrayView1D<ulong, Stride1D.Dense>, ulong, ulong, ulong, ulong, ulong, ArrayView1D<ulong, Stride1D.Dense>> KeepMontgomeryKernelLauncher;
public readonly Action<AcceleratorStream, Index1D, ArrayView1D<uint, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>, int, int, ulong, uint, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<int, Stride1D.Dense>, ArrayView1D<int, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<byte, Stride1D.Dense>> PartialFactorKernelLauncher;
public readonly Kernel PollardRhoKernel;
@@ -192,7 +193,7 @@ public sealed class PrimeOrderCalculatorAccelerator
public readonly Action<AcceleratorStream, Index1D, ArrayView<ulong>, ArrayView<byte>> SharesFactorKernelLauncher;
public readonly Action<AcceleratorStream, Index1D, ulong, uint, ArrayView1D<uint, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>, int, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<int, Stride1D.Dense>, ArrayView1D<int, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>> SmallPrimeFactorKernelLauncher;
public readonly Action<AcceleratorStream, Index1D, ArrayView<ulong>, ArrayView<uint>, ArrayView<uint>, ArrayView<uint>, ArrayView<uint>, ArrayView<ulong>, ArrayView<ulong>, ArrayView<ulong>, ArrayView<ulong>, ArrayView<byte>> SmallPrimeSieveKernelLauncher;
public readonly Action<AcceleratorStream, Index1D, ulong, ArrayView1D<ulong, Stride1D.Dense>, int, ulong, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>> SpecialMaxKernelLauncher;
public readonly Action<AcceleratorStream, Index1D, ulong, ArrayView<ulong>, int, ulong, ArrayView<ulong>> SpecialMaxKernelLauncher;
public void EnsureCalculateOrderWideCapacity(int newSize)
{
@@ -442,14 +443,14 @@ public sealed class PrimeOrderCalculatorAccelerator
CheckFactorsKernel = kernels.CheckFactorsKernel;
ConvertToStandardKernelLauncher = kernels.ConvertToStandardKernelLauncher;
HeuristicCombinedTrialDivisionKernelLauncher = kernels.HeuristicCombinedTrialDivisionKernelLauncher;
KeepMontgomeryKernelLauncher = kernels.KeepMontgomeryKernelLauncher;
// KeepMontgomeryKernelLauncher = kernels.KeepMontgomeryKernelLauncher;
// PartialFactorKernelLauncher = kernels.PartialFactorKernelLauncher;
// PollardRhoKernel = kernels.PollardRhoKernel;
Pow2ModKernelLauncher = kernels.Pow2ModKernelLauncher;
Pow2ModWideKernelLauncher = kernels.Pow2ModWideKernelLauncher;
// SharesFactorKernelLauncher = kernels.SharesFactorKernelLauncher;
SmallPrimeFactorKernelLauncher = kernels.SmallPrimeFactorKernelLauncher;
SmallPrimeSieveKernelLauncher = kernels.SmallPrimeSieveKernelLauncher;
// SmallPrimeFactorKernelLauncher = kernels.SmallPrimeFactorKernelLauncher;
// SmallPrimeSieveKernelLauncher = kernels.SmallPrimeSieveKernelLauncher;
SpecialMaxKernelLauncher = kernels.SpecialMaxKernelLauncher;
// }
}
@@ -8,72 +8,49 @@ internal static partial class PrimeOrderGpuHeuristics
internal static void EvaluateSpecialMaxCandidatesKernel(
Index1D index,
ulong phi,
ArrayView1D<ulong, Stride1D.Dense> factors,
ArrayView<ulong> factors,
int factorCount,
ulong divisorModulus,
ArrayView1D<ulong, Stride1D.Dense> candidates,
ArrayView1D<ulong, Stride1D.Dense> resultOut)
ArrayView<ulong> resultOut)
{
if (index != 0)
{
return;
}
int actual = 0;
for (int i = 0; i < factorCount; i++)
{
ulong factor = factors[i];
if (factor <= 1UL)
{
continue;
}
ulong reduced = phi / factor;
if (reduced == 0UL)
{
continue;
}
candidates[actual] = reduced;
actual++;
factors[i] = phi / factors[i];
}
if (actual == 0)
for (int i = 1; i < factorCount; i++)
{
resultOut[0] = 1;
return;
}
for (int i = 1; i < actual; i++)
{
ulong current = candidates[i];
ulong current = factors[i];
int insert = i - 1;
while (insert >= 0 && candidates[insert] > current)
while (insert >= 0 && factors[insert] > current)
{
candidates[insert + 1] = candidates[insert];
factors[insert + 1] = factors[insert];
insert--;
}
candidates[insert + 1] = current;
factors[insert + 1] = current;
}
var divisorPartial = new GpuDivisorPartialData(divisorModulus);
var stepper = new ExponentRemainderStepperGpu(divisorPartial);
if (stepper.InitializeIsUnityGpu(candidates[0]))
if (stepper.InitializeIsUnityGpu(factors[0]))
{
Atomic.Exchange(ref resultOut[0], 0);
resultOut[0] = 0UL;
// Atomic.Exchange(ref resultOut[0], 0);
return;
}
for (int i = 1; i < actual; i++)
for (int i = 1; i < factorCount; i++)
{
if (stepper.ComputeNextIsUnityGpu(candidates[i]))
if (stepper.ComputeNextIsUnityGpu(factors[i]))
{
Atomic.Exchange(ref resultOut[0], 0);
resultOut[0] = 0UL;
// Atomic.Exchange(ref resultOut[0], 0);
return;
}
}
Atomic.Exchange(ref resultOut[0], 1);
resultOut[0] = 1UL;
// Atomic.Exchange(ref resultOut[0], 1);
}
}
@@ -80,21 +80,17 @@ internal static class PrimeTesterKernels
public static void HeuristicTrialCombinedDivisionKernel(
Index1D index,
byte nMod10,
// byte nMod10,
ArrayView<int> resultFlag,
ulong n,
ulong maxDivisorSquare,
HeuristicCombinedGpuViews tables)
ArrayView<ulong> divisors,
ArrayView<ulong> divisorSquares)
{
var (divisors, divisorSquares) = tables.SelectDivisorsAndSquares(nMod10);
// var (divisors, divisorSquares) = tables.SelectDivisorsAndSquares(nMod10);
int threadIndex = index;
if (divisorSquares[threadIndex] > maxDivisorSquare)
{
return;
}
if (n % divisors[threadIndex] == 0UL)
if (divisorSquares[threadIndex] <= maxDivisorSquare && (n % divisors[threadIndex] == 0UL))
{
Atomic.Exchange(ref resultFlag[0], 1);
}