Merge pull request #71 from mlemanczyk/codex/review-changes-in-mersennenumberdivisorbydivisorgputester.cs
Fix Mod10 shortcut and restore Mod10_8_5_3Steps accuracy
This commit is contained in:
2 files changed
+91
-88
No files matched your search
@@ -335,84 +335,83 @@ public sealed class MersenneNumberDivisorByDivisorGpuTester
|
|||||||
MersenneDivisorCycles? divisorCycles = useCycles ? MersenneDivisorCycles.Shared : null;
|
MersenneDivisorCycles? divisorCycles = useCycles ? MersenneDivisorCycles.Shared : null;
|
||||||
ulong cycle = useCycles ? divisorCycles!.GetCycle(divisor) : 0UL, primeValue;
|
ulong cycle = useCycles ? divisorCycles!.GetCycle(divisor) : 0UL, primeValue;
|
||||||
MontgomeryDivisorData divisorData = CreateMontgomeryDivisorData(divisor);
|
MontgomeryDivisorData divisorData = CreateMontgomeryDivisorData(divisor);
|
||||||
Span<ulong> primeSpan = primesHost.AsSpan(0, gpuBatchSize);
|
Span<ulong> primeSpan = Span<ulong>.Empty;
|
||||||
ref ulong primesSpanRef = ref MemoryMarshal.GetReference(primeSpan);
|
Span<int> indexSpan = Span<int>.Empty;
|
||||||
Span<int> indexSpan = indexHost.AsSpan(0, gpuBatchSize);
|
Span<byte> hitSpan = Span<byte>.Empty;
|
||||||
Span<byte> hitsSlice, hitSpan = hitsHost.AsSpan(0, gpuBatchSize);
|
Span<byte> hitsSlice;
|
||||||
ref byte hitSpanRef = ref MemoryMarshal.GetReference(hitSpan);
|
int batchSize, currentSpanSize = -1, gpuCount, i, primesLength = primes.Length;
|
||||||
int batchSize, currentSpanSize = gpuBatchSize, gpuCount, i, primesLength = primes.Length;
|
|
||||||
|
|
||||||
while (offset < primesLength)
|
while (offset < primesLength)
|
||||||
{
|
{
|
||||||
batchSize = Math.Min(gpuBatchSize, primesLength - offset);
|
batchSize = Math.Min(gpuBatchSize, primesLength - offset);
|
||||||
if (batchSize != currentSpanSize)
|
ReadOnlySpan<ulong> primesSlice = primes.Slice(offset, batchSize);
|
||||||
{
|
|
||||||
primeSpan = primesHost.AsSpan(0, batchSize);
|
|
||||||
primesSpanRef = ref MemoryMarshal.GetReference(primeSpan);
|
|
||||||
indexSpan = indexHost.AsSpan(0, batchSize);
|
|
||||||
hitSpan = hitsHost.AsSpan(0, batchSize);
|
|
||||||
hitSpanRef = ref MemoryMarshal.GetReference(hitSpan);
|
|
||||||
currentSpanSize = batchSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
// We benefit from the constructor, because CopyTo will be called as static function
|
if (++consoleStatus == PerfectNumberConstants.ConsoleInterval)
|
||||||
primes.Slice(offset, batchSize).CopyTo(primeSpan);
|
{
|
||||||
|
Console.WriteLine($"...processed by-divisor candidate = {primesSlice[0]}");
|
||||||
|
consoleStatus = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (++consoleStatus == PerfectNumberConstants.ConsoleInterval)
|
hitsSlice = hits.Slice(offset, batchSize);
|
||||||
{
|
|
||||||
Console.WriteLine($"...processed by-divisor candidate = {primes[0]}");
|
|
||||||
consoleStatus = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
hitsSlice = hits.Slice(offset, batchSize);
|
if (useCycles)
|
||||||
gpuCount = 0;
|
{
|
||||||
|
if (batchSize != currentSpanSize)
|
||||||
|
{
|
||||||
|
primeSpan = primesHost.AsSpan(0, batchSize);
|
||||||
|
indexSpan = indexHost.AsSpan(0, batchSize);
|
||||||
|
hitSpan = hitsHost.AsSpan(0, batchSize);
|
||||||
|
currentSpanSize = batchSize;
|
||||||
|
}
|
||||||
|
|
||||||
if (useCycles)
|
ref ulong primesSpanRef = ref MemoryMarshal.GetReference(primeSpan);
|
||||||
{
|
ref byte hitSpanRef = ref MemoryMarshal.GetReference(hitSpan);
|
||||||
for (i = 0; i < batchSize; i++)
|
gpuCount = 0;
|
||||||
{
|
|
||||||
primeValue = primeSpan[i];
|
|
||||||
if (cycle == 0UL || primeValue % cycle != 0UL)
|
|
||||||
{
|
|
||||||
hitsSlice[i] = 0;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
indexSpan[gpuCount] = i;
|
for (i = 0; i < batchSize; i++)
|
||||||
primeSpan[gpuCount] = primeValue;
|
{
|
||||||
gpuCount++;
|
primeValue = primesSlice[i];
|
||||||
}
|
if (cycle == 0UL || primeValue % cycle != 0UL)
|
||||||
|
{
|
||||||
|
hitsSlice[i] = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (gpuCount > 0)
|
indexSpan[gpuCount] = i;
|
||||||
{
|
primeSpan[gpuCount] = primeValue;
|
||||||
primesView = primesBufferView.SubView(0, gpuCount);
|
gpuCount++;
|
||||||
hitsView = hitsBufferView.SubView(0, gpuCount);
|
}
|
||||||
|
|
||||||
primesView.CopyFromCPU(ref primesSpanRef, gpuCount);
|
if (gpuCount > 0)
|
||||||
kernel(gpuCount, divisorData, primesView, hitsView);
|
{
|
||||||
accelerator.Synchronize();
|
primesView = primesBufferView.SubView(0, gpuCount);
|
||||||
|
hitsView = hitsBufferView.SubView(0, gpuCount);
|
||||||
|
|
||||||
hitsView.CopyToCPU(ref hitSpanRef, gpuCount);
|
primesView.CopyFromCPU(ref primesSpanRef, gpuCount);
|
||||||
for (i = 0; i < gpuCount; i++)
|
kernel(gpuCount, divisorData, primesView, hitsView);
|
||||||
{
|
accelerator.Synchronize();
|
||||||
hitsSlice[indexSpan[i]] = hitSpan[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
primesView = primesBufferView.SubView(0, batchSize);
|
|
||||||
hitsView = hitsBufferView.SubView(0, batchSize);
|
|
||||||
|
|
||||||
primesView.CopyFromCPU(ref primesSpanRef, batchSize);
|
hitsView.CopyToCPU(ref hitSpanRef, gpuCount);
|
||||||
kernel(batchSize, divisorData, primesView, hitsView);
|
for (i = 0; i < gpuCount; i++)
|
||||||
accelerator.Synchronize();
|
{
|
||||||
|
hitsSlice[indexSpan[i]] = hitSpan[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
primesView = primesBufferView.SubView(0, batchSize);
|
||||||
|
hitsView = hitsBufferView.SubView(0, batchSize);
|
||||||
|
|
||||||
hitsView.CopyToCPU(ref MemoryMarshal.GetReference(hitSpan), batchSize);
|
ref ulong primesSliceRef = ref MemoryMarshal.GetReference(primesSlice);
|
||||||
hitSpan.CopyTo(hitsSlice);
|
primesView.CopyFromCPU(ref primesSliceRef, batchSize);
|
||||||
}
|
kernel(batchSize, divisorData, primesView, hitsView);
|
||||||
|
accelerator.Synchronize();
|
||||||
|
|
||||||
offset += batchSize;
|
hitsView.CopyToCPU(ref MemoryMarshal.GetReference(hitsSlice), batchSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
offset += batchSize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -85,23 +85,27 @@ public static class ULongExtensions
|
|||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static ulong Mod10(this ulong value) => (value & 1UL) == 0UL
|
public static ulong Mod10(this ulong value)
|
||||||
? value % 5UL switch
|
{
|
||||||
{
|
ulong mod5 = value % 5UL;
|
||||||
0UL => 0UL,
|
return (value & 1UL) == 0UL
|
||||||
1UL => 6UL,
|
? mod5 switch
|
||||||
2UL => 2UL,
|
{
|
||||||
3UL => 8UL,
|
0UL => 0UL,
|
||||||
_ => 4UL,
|
1UL => 6UL,
|
||||||
}
|
2UL => 2UL,
|
||||||
: value % 5UL switch
|
3UL => 8UL,
|
||||||
{
|
_ => 4UL,
|
||||||
0UL => 5UL,
|
}
|
||||||
1UL => 1UL,
|
: mod5 switch
|
||||||
2UL => 7UL,
|
{
|
||||||
3UL => 3UL,
|
0UL => 5UL,
|
||||||
_ => 9UL,
|
1UL => 1UL,
|
||||||
};
|
2UL => 7UL,
|
||||||
|
3UL => 3UL,
|
||||||
|
_ => 9UL,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static ulong Mod128(this ulong value) => value & 127UL;
|
public static ulong Mod128(this ulong value) => value & 127UL;
|
||||||
@@ -143,14 +147,14 @@ public static class ULongExtensions
|
|||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static void Mod10_8_5_3Steps(this ulong value, out ulong step10, out ulong step8, out ulong step5, out ulong step3)
|
public static void Mod10_8_5_3Steps(this ulong value, out ulong step10, out ulong step8, out ulong step5, out ulong step3)
|
||||||
{
|
{
|
||||||
value.Mod10_8_5_3(out step10, out step8, out step5, out step3);
|
value.Mod10_8_5_3(out step10, out step8, out step5, out step3);
|
||||||
|
|
||||||
step10 = (step10 << 1).Mod10();
|
step10 = (step10 << 1).Mod10();
|
||||||
step8 = (step8 << 1) & 7UL;
|
step8 = (step8 << 1) & 7UL;
|
||||||
step5 = (step5 << 1) % 5UL;
|
step5 = (step5 << 1) % 5UL;
|
||||||
step3 = (step3 << 1) % 3UL;
|
step3 = (step3 << 1) % 3UL;
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
|||||||
Reference in new issue
Block a user