Clarify invariants across GPU divisor helpers
This commit is contained in:
1 parent
bccb2f43c9
commit
6e89700f80
5 files changed
+44
-52
No files matched your search
@@ -64,28 +64,22 @@ public sealed class MersenneNumberDivisorByDivisorGpuTester : IMersenneNumberDiv
|
||||
|
||||
public void ConfigureFromMaxPrime(ulong maxPrime)
|
||||
{
|
||||
lock (_sync)
|
||||
{
|
||||
_divisorLimit = ComputeDivisorLimitFromMaxPrime(maxPrime);
|
||||
_isConfigured = true;
|
||||
}
|
||||
// Configuration happens once during startup, so no synchronization is required to cache the divisor limit.
|
||||
_divisorLimit = ComputeDivisorLimitFromMaxPrime(maxPrime);
|
||||
_isConfigured = true;
|
||||
}
|
||||
|
||||
public bool IsPrime(ulong prime, out bool divisorsExhausted, TimeSpan? timeLimit = null)
|
||||
{
|
||||
ulong allowedMax;
|
||||
int batchCapacity;
|
||||
// The CLI always configures the tester during startup, so the historical guard is commented out to avoid branching.
|
||||
// if (!_isConfigured)
|
||||
// {
|
||||
// throw new InvalidOperationException("ConfigureFromMaxPrime must be called before using the tester.");
|
||||
// }
|
||||
|
||||
lock (_sync)
|
||||
{
|
||||
if (!_isConfigured)
|
||||
{
|
||||
throw new InvalidOperationException("ConfigureFromMaxPrime must be called before using the tester.");
|
||||
}
|
||||
|
||||
allowedMax = ComputeAllowedMaxDivisor(prime, _divisorLimit);
|
||||
batchCapacity = _gpuBatchSize;
|
||||
}
|
||||
// Configuration is immutable, so the cached values can be read without locking.
|
||||
ulong allowedMax = ComputeAllowedMaxDivisor(prime, _divisorLimit);
|
||||
int batchCapacity = _gpuBatchSize;
|
||||
|
||||
// The GPU path always receives an allowed maximum well above the minimal divisor, so the legacy
|
||||
// guard stays commented out to document the invariant without branching.
|
||||
|
||||
@@ -75,7 +75,10 @@ internal sealed class MersenneNumberDivisorCandidateGpuEvaluator : IDisposable
|
||||
// return;
|
||||
// }
|
||||
|
||||
EnsureCapacity(count);
|
||||
if (count > _capacity)
|
||||
{
|
||||
EnsureCapacity(count);
|
||||
}
|
||||
|
||||
Span<ulong> hostCandidateSpan = _hostCandidates.AsSpan(0, count);
|
||||
Span<byte> hostMaskSpan = _hostMask.AsSpan(0, count);
|
||||
|
||||
@@ -52,7 +52,7 @@ internal sealed class MersenneNumberDivisorRemainderGpuStepper : IDisposable
|
||||
{
|
||||
if (_disposed)
|
||||
{
|
||||
return;
|
||||
throw new InvalidOperationException("MersenneNumberDivisorRemainderGpuStepper was disposed more than once.");
|
||||
}
|
||||
|
||||
_disposed = true;
|
||||
@@ -78,10 +78,11 @@ internal sealed class MersenneNumberDivisorRemainderGpuStepper : IDisposable
|
||||
// return;
|
||||
// }
|
||||
|
||||
if (remainders.Length != _length)
|
||||
{
|
||||
throw new ArgumentException("Remainder buffer length must match the configured length.");
|
||||
}
|
||||
// Production code always calls the stepper with a fixed-length table, so the historical length guard stays commented.
|
||||
// if (remainders.Length != _length)
|
||||
// {
|
||||
// throw new ArgumentException("Remainder buffer length must match the configured length.");
|
||||
// }
|
||||
|
||||
Span<byte> hostRemainderSpan = _hostRemainders.AsSpan(0, _length);
|
||||
remainders.CopyTo(hostRemainderSpan);
|
||||
|
||||
@@ -33,7 +33,7 @@ internal sealed class MersenneNumberDivisorResidueGpuEvaluator : IDisposable
|
||||
{
|
||||
if (_disposed)
|
||||
{
|
||||
return;
|
||||
throw new InvalidOperationException("MersenneNumberDivisorResidueGpuEvaluator was disposed more than once.");
|
||||
}
|
||||
|
||||
_disposed = true;
|
||||
|
||||
Reference in new issue
Block a user