Remove GPU by-divisor snapshot dependency
This commit is contained in:
1 parent
8637ee8875
commit
cf9d143ca2
1 file changed
+31
-45
@@ -113,8 +113,6 @@ public sealed class MersenneNumberDivisorByDivisorGpuTester : IMersenneNumberDiv
|
|||||||
resources.Divisors,
|
resources.Divisors,
|
||||||
resources.Exponents,
|
resources.Exponents,
|
||||||
resources.DivisorData,
|
resources.DivisorData,
|
||||||
resources.CycleLengths,
|
|
||||||
resources.CycleCapacity,
|
|
||||||
out lastProcessed,
|
out lastProcessed,
|
||||||
out coveredRange,
|
out coveredRange,
|
||||||
out processedCount);
|
out processedCount);
|
||||||
@@ -173,8 +171,6 @@ public sealed class MersenneNumberDivisorByDivisorGpuTester : IMersenneNumberDiv
|
|||||||
in ulong[] divisors,
|
in ulong[] divisors,
|
||||||
ulong[] exponents,
|
ulong[] exponents,
|
||||||
MontgomeryDivisorData[] divisorData,
|
MontgomeryDivisorData[] divisorData,
|
||||||
ulong[] cycleLengths,
|
|
||||||
int cycleCapacity,
|
|
||||||
out ulong lastProcessed,
|
out ulong lastProcessed,
|
||||||
out bool coveredRange,
|
out bool coveredRange,
|
||||||
out ulong processedCount)
|
out ulong processedCount)
|
||||||
@@ -185,8 +181,7 @@ public sealed class MersenneNumberDivisorByDivisorGpuTester : IMersenneNumberDiv
|
|||||||
processedCount = 0UL;
|
processedCount = 0UL;
|
||||||
lastProcessed = 0UL;
|
lastProcessed = 0UL;
|
||||||
|
|
||||||
cycleCapacity = Math.Max(1, cycleCapacity);
|
int chunkCapacity = Math.Max(1, batchCapacity);
|
||||||
int chunkCapacity = Math.Min(batchCapacity, cycleCapacity);
|
|
||||||
|
|
||||||
UInt128 twoP128 = (UInt128)prime << 1;
|
UInt128 twoP128 = (UInt128)prime << 1;
|
||||||
UInt128 allowedMax128 = allowedMax;
|
UInt128 allowedMax128 = allowedMax;
|
||||||
@@ -207,12 +202,9 @@ public sealed class MersenneNumberDivisorByDivisorGpuTester : IMersenneNumberDiv
|
|||||||
|
|
||||||
UInt128 currentDivisor128 = firstDivisor128;
|
UInt128 currentDivisor128 = firstDivisor128;
|
||||||
bool lastIsSeven = (prime & 3UL) == 3UL;
|
bool lastIsSeven = (prime & 3UL) == 3UL;
|
||||||
DivisorCycleCache cycleCache = DivisorCycleCache.Shared;
|
|
||||||
|
|
||||||
ArrayPool<ulong> ulongPool = ThreadStaticPools.UlongPool;
|
ArrayPool<ulong> ulongPool = ThreadStaticPools.UlongPool;
|
||||||
ulong[] filteredDivisors = ulongPool.Rent(chunkCapacity);
|
ulong[] filteredDivisors = ulongPool.Rent(chunkCapacity);
|
||||||
Span<ulong> filteredStorage = filteredDivisors.AsSpan();
|
Span<ulong> filteredStorage = filteredDivisors.AsSpan();
|
||||||
Span<ulong> cycleLengthStorage = cycleLengths.AsSpan();
|
|
||||||
Span<MontgomeryDivisorData> divisorDataStorage = divisorData.AsSpan();
|
Span<MontgomeryDivisorData> divisorDataStorage = divisorData.AsSpan();
|
||||||
Span<ulong> divisorStorage = divisors.AsSpan();
|
Span<ulong> divisorStorage = divisors.AsSpan();
|
||||||
Span<ulong> exponentStorage = exponents.AsSpan();
|
Span<ulong> exponentStorage = exponents.AsSpan();
|
||||||
@@ -261,20 +253,25 @@ public sealed class MersenneNumberDivisorByDivisorGpuTester : IMersenneNumberDiv
|
|||||||
}
|
}
|
||||||
|
|
||||||
Span<ulong> filteredDivisorsSpan = filteredStorage[..filteredCount];
|
Span<ulong> filteredDivisorsSpan = filteredStorage[..filteredCount];
|
||||||
Span<ulong> cycleSpan = cycleLengthStorage[..filteredCount];
|
|
||||||
cycleCache.GetCycleLengths(filteredDivisorsSpan, cycleSpan);
|
Span<MontgomeryDivisorData> divisorDataSpan = divisorDataStorage;
|
||||||
|
Span<ulong> divisorSpan = divisorStorage;
|
||||||
|
Span<ulong> exponentSpan = exponentStorage;
|
||||||
|
|
||||||
int admissibleCount = 0;
|
int admissibleCount = 0;
|
||||||
for (int i = 0; i < filteredCount; i++)
|
for (int i = 0; i < filteredCount; i++)
|
||||||
{
|
{
|
||||||
ulong candidate = filteredDivisorsSpan[i];
|
ulong divisorValue = filteredDivisorsSpan[i];
|
||||||
ulong candidateCycle = cycleSpan[i];
|
MontgomeryDivisorData divisorDataValue = MontgomeryDivisorData.FromModulus(divisorValue);
|
||||||
if (candidateCycle != prime)
|
ulong divisorCycle = ResolveDivisorCycle(divisorValue, prime, divisorDataValue);
|
||||||
|
if (divisorCycle != prime)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
filteredDivisorsSpan[admissibleCount] = candidate;
|
divisorSpan[admissibleCount] = divisorValue;
|
||||||
|
exponentSpan[admissibleCount] = prime;
|
||||||
|
divisorDataSpan[admissibleCount] = divisorDataValue;
|
||||||
admissibleCount++;
|
admissibleCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -283,24 +280,16 @@ public sealed class MersenneNumberDivisorByDivisorGpuTester : IMersenneNumberDiv
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Span<MontgomeryDivisorData> divisorDataSpan = divisorDataStorage[..admissibleCount];
|
Span<ulong> activeDivisors = divisorSpan[..admissibleCount];
|
||||||
Span<ulong> divisorSpan = divisorStorage[..admissibleCount];
|
Span<MontgomeryDivisorData> activeDivisorData = divisorDataSpan[..admissibleCount];
|
||||||
Span<ulong> exponentSpan = exponentStorage[..admissibleCount];
|
Span<ulong> activeExponents = exponentSpan[..admissibleCount];
|
||||||
ArrayView1D<MontgomeryDivisorData, Stride1D.Dense> divisorView = divisorsBuffer.View.SubView(0, admissibleCount);
|
ArrayView1D<MontgomeryDivisorData, Stride1D.Dense> divisorView = divisorsBuffer.View.SubView(0, admissibleCount);
|
||||||
ArrayView1D<ulong, Stride1D.Dense> exponentView = exponentBuffer.View.SubView(0, admissibleCount);
|
ArrayView1D<ulong, Stride1D.Dense> exponentView = exponentBuffer.View.SubView(0, admissibleCount);
|
||||||
ArrayView1D<byte, Stride1D.Dense> hitsView = hitsBuffer.View.SubView(0, admissibleCount);
|
ArrayView1D<byte, Stride1D.Dense> hitsView = hitsBuffer.View.SubView(0, admissibleCount);
|
||||||
ArrayView1D<int, Stride1D.Dense> hitIndexView = hitIndexBuffer.View.SubView(0, 1);
|
ArrayView1D<int, Stride1D.Dense> hitIndexView = hitIndexBuffer.View.SubView(0, 1);
|
||||||
|
|
||||||
for (int i = 0; i < admissibleCount; i++)
|
divisorView.CopyFromCPU(ref MemoryMarshal.GetReference(activeDivisorData), admissibleCount);
|
||||||
{
|
exponentView.CopyFromCPU(ref MemoryMarshal.GetReference(activeExponents), admissibleCount);
|
||||||
ulong divisorValue = filteredDivisorsSpan[i];
|
|
||||||
divisorSpan[i] = divisorValue;
|
|
||||||
exponentSpan[i] = prime;
|
|
||||||
divisorDataSpan[i] = MontgomeryDivisorData.FromModulus(divisorValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
divisorView.CopyFromCPU(ref MemoryMarshal.GetReference(divisorDataSpan), admissibleCount);
|
|
||||||
exponentView.CopyFromCPU(ref MemoryMarshal.GetReference(exponentSpan), admissibleCount);
|
|
||||||
int sentinel = int.MaxValue;
|
int sentinel = int.MaxValue;
|
||||||
hitIndexView.SubView(0, 1).CopyFromCPU(ref sentinel, 1);
|
hitIndexView.SubView(0, 1).CopyFromCPU(ref sentinel, 1);
|
||||||
|
|
||||||
@@ -312,7 +301,7 @@ public sealed class MersenneNumberDivisorByDivisorGpuTester : IMersenneNumberDiv
|
|||||||
bool hitFound = hitIndex >= 0;
|
bool hitFound = hitIndex >= 0;
|
||||||
composite = hitFound;
|
composite = hitFound;
|
||||||
int lastIndex = admissibleCount - 1;
|
int lastIndex = admissibleCount - 1;
|
||||||
lastProcessed = hitFound ? divisorSpan[hitIndex] : divisorSpan[lastIndex];
|
lastProcessed = hitFound ? activeDivisors[hitIndex] : activeDivisors[lastIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
ulongPool.Return(filteredDivisors, clearArray: false);
|
ulongPool.Return(filteredDivisors, clearArray: false);
|
||||||
@@ -321,11 +310,21 @@ public sealed class MersenneNumberDivisorByDivisorGpuTester : IMersenneNumberDiv
|
|||||||
return composite;
|
return composite;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
private static ulong ResolveDivisorCycle(ulong divisor, ulong prime, in MontgomeryDivisorData divisorData)
|
||||||
|
{
|
||||||
|
if (!MersenneDivisorCycles.TryCalculateCycleLengthForExponent(divisor, prime, divisorData, out ulong computedCycle, out bool primeOrderFailed) || computedCycle == 0UL)
|
||||||
|
{
|
||||||
|
return MersenneDivisorCycles.CalculateCycleLength(divisor, divisorData, skipPrimeOrderHeuristic: primeOrderFailed);
|
||||||
|
}
|
||||||
|
|
||||||
|
return computedCycle;
|
||||||
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
private static bool CandidatePassesHeuristics(ulong candidate, bool lastIsSeven)
|
private static bool CandidatePassesHeuristics(ulong candidate, bool lastIsSeven)
|
||||||
{
|
{
|
||||||
// Keep the divisibility filters aligned with the divisor-cycle snapshot so we never
|
// Mirror the CPU heuristics so the GPU path rejects obvious composites before computing cycles.
|
||||||
// request missing entries from the cache.
|
|
||||||
ulong remainder10 = candidate % 10UL;
|
ulong remainder10 = candidate % 10UL;
|
||||||
bool accept10 = lastIsSeven
|
bool accept10 = lastIsSeven
|
||||||
? (remainder10 == 3UL || remainder10 == 7UL || remainder10 == 9UL)
|
? (remainder10 == 3UL || remainder10 == 7UL || remainder10 == 9UL)
|
||||||
@@ -574,13 +573,7 @@ public sealed class MersenneNumberDivisorByDivisorGpuTester : IMersenneNumberDiv
|
|||||||
{
|
{
|
||||||
internal BatchResources(Accelerator accelerator, int capacity)
|
internal BatchResources(Accelerator accelerator, int capacity)
|
||||||
{
|
{
|
||||||
int cycleCapacity = DivisorCycleCache.Shared.PreferredBatchSize;
|
int actualCapacity = Math.Max(1, capacity);
|
||||||
if (cycleCapacity <= 0)
|
|
||||||
{
|
|
||||||
cycleCapacity = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int actualCapacity = Math.Max(capacity, cycleCapacity);
|
|
||||||
|
|
||||||
DivisorsBuffer = accelerator.Allocate1D<MontgomeryDivisorData>(actualCapacity);
|
DivisorsBuffer = accelerator.Allocate1D<MontgomeryDivisorData>(actualCapacity);
|
||||||
ExponentBuffer = accelerator.Allocate1D<ulong>(actualCapacity);
|
ExponentBuffer = accelerator.Allocate1D<ulong>(actualCapacity);
|
||||||
@@ -590,9 +583,7 @@ public sealed class MersenneNumberDivisorByDivisorGpuTester : IMersenneNumberDiv
|
|||||||
Divisors = ulongPool.Rent(actualCapacity);
|
Divisors = ulongPool.Rent(actualCapacity);
|
||||||
Exponents = ulongPool.Rent(actualCapacity);
|
Exponents = ulongPool.Rent(actualCapacity);
|
||||||
DivisorData = ThreadStaticPools.MontgomeryDivisorDataPool.Rent(actualCapacity);
|
DivisorData = ThreadStaticPools.MontgomeryDivisorDataPool.Rent(actualCapacity);
|
||||||
CycleLengths = ulongPool.Rent(cycleCapacity);
|
|
||||||
Capacity = actualCapacity;
|
Capacity = actualCapacity;
|
||||||
CycleCapacity = cycleCapacity;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal readonly MemoryBuffer1D<MontgomeryDivisorData, Stride1D.Dense> DivisorsBuffer;
|
internal readonly MemoryBuffer1D<MontgomeryDivisorData, Stride1D.Dense> DivisorsBuffer;
|
||||||
@@ -609,12 +600,8 @@ public sealed class MersenneNumberDivisorByDivisorGpuTester : IMersenneNumberDiv
|
|||||||
|
|
||||||
internal readonly MontgomeryDivisorData[] DivisorData;
|
internal readonly MontgomeryDivisorData[] DivisorData;
|
||||||
|
|
||||||
internal readonly ulong[] CycleLengths;
|
|
||||||
|
|
||||||
internal readonly int Capacity;
|
internal readonly int Capacity;
|
||||||
|
|
||||||
internal readonly int CycleCapacity;
|
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
DivisorsBuffer.Dispose();
|
DivisorsBuffer.Dispose();
|
||||||
@@ -626,7 +613,6 @@ public sealed class MersenneNumberDivisorByDivisorGpuTester : IMersenneNumberDiv
|
|||||||
ulongPool.Return(Divisors, clearArray: false);
|
ulongPool.Return(Divisors, clearArray: false);
|
||||||
ulongPool.Return(Exponents, clearArray: false);
|
ulongPool.Return(Exponents, clearArray: false);
|
||||||
divisorPool.Return(DivisorData, clearArray: false);
|
divisorPool.Return(DivisorData, clearArray: false);
|
||||||
ulongPool.Return(CycleLengths, clearArray: false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user