diff --git a/PerfectNumbers.Core/Cpu/MersenneCpuDivisorScanSession.cs b/PerfectNumbers.Core/Cpu/MersenneCpuDivisorScanSession.cs index c6d936e..1279369 100644 --- a/PerfectNumbers.Core/Cpu/MersenneCpuDivisorScanSession.cs +++ b/PerfectNumbers.Core/Cpu/MersenneCpuDivisorScanSession.cs @@ -35,8 +35,8 @@ internal sealed class MersenneCpuDivisorScanSession : IMersenneNumberDivisorByDi divisorCycle = DivisorCycleCache.Shared.GetCycleLength(divisor); if (divisorCycle == 0UL) { - hits.Clear(); - return; + // DivisorCycleCache guarantees a positive cycle for divisors greater than one. + throw new InvalidOperationException($"Divisor cycle solver returned zero for divisor {divisor}."); } } @@ -45,8 +45,7 @@ internal sealed class MersenneCpuDivisorScanSession : IMersenneNumberDivisorByDi var exponentStepper = new ExponentRemainderStepper(cachedData); if (!exponentStepper.IsValidModulus) { - hits.Clear(); - return; + throw new InvalidOperationException($"Invalid modulus {cachedData.Modulus} for divisor scans."); } var cycleStepper = new CycleRemainderStepper(divisorCycle); diff --git a/PerfectNumbers.Core/Gpu/Kernels/DivisorByDivisorKernels.cs b/PerfectNumbers.Core/Gpu/Kernels/DivisorByDivisorKernels.cs index 1540c09..eece679 100644 --- a/PerfectNumbers.Core/Gpu/Kernels/DivisorByDivisorKernels.cs +++ b/PerfectNumbers.Core/Gpu/Kernels/DivisorByDivisorKernels.cs @@ -232,8 +232,10 @@ internal static class DivisorByDivisorKernels int lastLaneMask = globalIndex == length - 1 ? 1 : 0; int countValue = shared[prefixBase + localIndex]; - int storedCount = lastLaneMask != 0 ? countValue : 0; - Atomic.Max(ref compactedCount[0], storedCount); + if (lastLaneMask != 0) + { + compactedCount[0] = countValue; + } } public static void PublishFirstHitKernel( diff --git a/PerfectNumbers.Core/Gpu/MersenneNumberDivisorByDivisorGpuTester.cs b/PerfectNumbers.Core/Gpu/MersenneNumberDivisorByDivisorGpuTester.cs index 0af37c0..33ed320 100644 --- a/PerfectNumbers.Core/Gpu/MersenneNumberDivisorByDivisorGpuTester.cs +++ b/PerfectNumbers.Core/Gpu/MersenneNumberDivisorByDivisorGpuTester.cs @@ -600,7 +600,6 @@ public sealed class MersenneNumberDivisorByDivisorGpuTester : IMersenneNumberDiv // return 0; // } - countView.MemSetToZero(); SharedMemoryConfig sharedMemoryConfig = SharedMemoryConfig.RequestDynamic(count * 3); Index1D gridDim = new Index1D(1); Index1D groupDim = new Index1D(count); diff --git a/PerfectNumbers.Core/MersenneNumberDivisorByDivisorTester.cs b/PerfectNumbers.Core/MersenneNumberDivisorByDivisorTester.cs index ce66960..008ddd5 100644 --- a/PerfectNumbers.Core/MersenneNumberDivisorByDivisorTester.cs +++ b/PerfectNumbers.Core/MersenneNumberDivisorByDivisorTester.cs @@ -73,7 +73,7 @@ public static class MersenneNumberDivisorByDivisorTester candidateCount = candidateSpan.Length; } - pool.Return(recordedCandidates, clearArray: true); + pool.Return(recordedCandidates, clearArray: false); } if (skippedByPreviousResults > 0) @@ -211,8 +211,8 @@ public static class MersenneNumberDivisorByDivisorTester filteredPrimes.Add(prime); } - pool.Return(allowedMaxBatch, clearArray: true); - pool.Return(primeBatch, clearArray: true); + pool.Return(allowedMaxBatch, clearArray: false); + pool.Return(primeBatch, clearArray: false); // The filtered list mirrors primesToTest in the CPU flow, so the guard below never triggers after the earlier // emptiness checks.