Guard GPU residue and divisor scans against overflow
This commit is contained in:
1 parent
ff2c516a0e
commit
9f2cf12ce1
2 files changed
+16
-9
No files matched your search
@@ -95,7 +95,8 @@ public sealed class MersenneNumberDivisorGpuTester
|
|||||||
for (k2 = 1UL; k2 <= limit; k2++)
|
for (k2 = 1UL; k2 <= limit; k2++)
|
||||||
{
|
{
|
||||||
kMul2 = (UInt128)k2 << 1;
|
kMul2 = (UInt128)k2 << 1;
|
||||||
d = kMul2 * p + UInt128.One;
|
UInt128 candidate = checked(kMul2 * p);
|
||||||
|
d = checked(candidate + UInt128.One);
|
||||||
if (p < 64UL && d == ((UInt128)1 << (int)p) - UInt128.One)
|
if (p < 64UL && d == ((UInt128)1 << (int)p) - UInt128.One)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -44,20 +44,25 @@ public class MersenneNumberResidueGpuTester(bool useGpuOrder)
|
|||||||
var orderBuffer = accelerator.Allocate1D<ulong>(batchSize);
|
var orderBuffer = accelerator.Allocate1D<ulong>(batchSize);
|
||||||
ulong[] orderArray = ArrayPool<ulong>.Shared.Rent(batchSize);
|
ulong[] orderArray = ArrayPool<ulong>.Shared.Rent(batchSize);
|
||||||
UInt128 batchSize128 = (UInt128)batchSize;
|
UInt128 batchSize128 = (UInt128)batchSize;
|
||||||
UInt128 limitInclusive = overallLimit + UInt128.One;
|
UInt128 limitInclusive = overallLimit == UInt128.MaxValue
|
||||||
|
? overallLimit
|
||||||
|
: checked(overallLimit + UInt128.One);
|
||||||
Span<ulong> orders = orderArray.AsSpan(0, batchSize);
|
Span<ulong> orders = orderArray.AsSpan(0, batchSize);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
for (UInt128 setIndex = UInt128.Zero; setIndex < setCount && Volatile.Read(ref isPrime); setIndex++)
|
for (ulong setIndex = 0; setIndex < setCount && Volatile.Read(ref isPrime); setIndex++)
|
||||||
{
|
{
|
||||||
UInt128 setOffset = perSetLimit * setIndex;
|
UInt128 setOffset = checked(perSetLimit * (UInt128)setIndex);
|
||||||
UInt128 setStart = setOffset + UInt128.One;
|
UInt128 setStart = checked(setOffset + UInt128.One);
|
||||||
if (setStart >= limitInclusive)
|
if (setStart >= limitInclusive)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
UInt128 setLimitExclusive = setOffset + perSetLimit + UInt128.One;
|
UInt128 setLimitExclusive = checked(setOffset + perSetLimit);
|
||||||
|
setLimitExclusive = setLimitExclusive >= limitInclusive
|
||||||
|
? limitInclusive
|
||||||
|
: checked(setLimitExclusive + UInt128.One);
|
||||||
if (setLimitExclusive > limitInclusive)
|
if (setLimitExclusive > limitInclusive)
|
||||||
{
|
{
|
||||||
setLimitExclusive = limitInclusive;
|
setLimitExclusive = limitInclusive;
|
||||||
@@ -66,7 +71,7 @@ public class MersenneNumberResidueGpuTester(bool useGpuOrder)
|
|||||||
UInt128 kStart = setStart;
|
UInt128 kStart = setStart;
|
||||||
while (kStart < setLimitExclusive && Volatile.Read(ref isPrime))
|
while (kStart < setLimitExclusive && Volatile.Read(ref isPrime))
|
||||||
{
|
{
|
||||||
UInt128 remaining = setLimitExclusive - kStart;
|
UInt128 remaining = checked(setLimitExclusive - kStart);
|
||||||
int currentSize = remaining > batchSize128 ? batchSize : (int)remaining;
|
int currentSize = remaining > batchSize128 ? batchSize : (int)remaining;
|
||||||
if (currentSize <= 0)
|
if (currentSize <= 0)
|
||||||
{
|
{
|
||||||
@@ -74,7 +79,8 @@ public class MersenneNumberResidueGpuTester(bool useGpuOrder)
|
|||||||
}
|
}
|
||||||
orders = orderArray.AsSpan(0, currentSize);
|
orders = orderArray.AsSpan(0, currentSize);
|
||||||
|
|
||||||
UInt128 q = twoP * kStart + UInt128.One;
|
UInt128 q = checked(twoP * kStart);
|
||||||
|
q = checked(q + UInt128.One);
|
||||||
q.Mod10_8_5_3(out ulong q0m10, out ulong q0m8, out ulong q0m5, out ulong q0m3);
|
q.Mod10_8_5_3(out ulong q0m10, out ulong q0m8, out ulong q0m5, out ulong q0m3);
|
||||||
var ra = new ResidueAutomatonArgs(q0m10, step10, q0m8, step8, q0m3, step3, q0m5, step5);
|
var ra = new ResidueAutomatonArgs(q0m10, step10, q0m8, step8, q0m3, step3, q0m5, step5);
|
||||||
|
|
||||||
@@ -97,7 +103,7 @@ public class MersenneNumberResidueGpuTester(bool useGpuOrder)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
kStart += batchSize128;
|
kStart = checked(kStart + batchSize128);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user