Console logging extended
This commit is contained in:
1 parent
b78f45ec36
commit
198b31f380
2 files changed
+138
-5
No files matched your search
@@ -473,7 +473,7 @@ internal static class Program
|
|||||||
if (!useDivisor && !useByDivisor)
|
if (!useDivisor && !useByDivisor)
|
||||||
{
|
{
|
||||||
MersenneTesters = new ThreadLocal<MersenneNumberTester>(() =>
|
MersenneTesters = new ThreadLocal<MersenneNumberTester>(() =>
|
||||||
{
|
{
|
||||||
var tester = new MersenneNumberTester(
|
var tester = new MersenneNumberTester(
|
||||||
useIncremental: !useLucas,
|
useIncremental: !useLucas,
|
||||||
useOrderCache: false,
|
useOrderCache: false,
|
||||||
@@ -491,7 +491,7 @@ internal static class Program
|
|||||||
}
|
}
|
||||||
|
|
||||||
return tester;
|
return tester;
|
||||||
}, trackAllValues: true);
|
}, trackAllValues: true);
|
||||||
}
|
}
|
||||||
else if (useDivisor)
|
else if (useDivisor)
|
||||||
{
|
{
|
||||||
@@ -616,7 +616,7 @@ internal static class Program
|
|||||||
{
|
{
|
||||||
filter.AddRange(localFilter[..count]);
|
filter.AddRange(localFilter[..count]);
|
||||||
}
|
}
|
||||||
filterList = [..filter];
|
filterList = [.. filter];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (useByDivisor)
|
if (useByDivisor)
|
||||||
@@ -642,6 +642,8 @@ internal static class Program
|
|||||||
// Configure batch size for GPU primality sieve
|
// Configure batch size for GPU primality sieve
|
||||||
PrimeTester.GpuBatchSize = gpuPrimeBatch;
|
PrimeTester.GpuBatchSize = gpuPrimeBatch;
|
||||||
|
|
||||||
|
Console.WriteLine("Starting scan...");
|
||||||
|
|
||||||
if (_useByDivisorMode)
|
if (_useByDivisorMode)
|
||||||
{
|
{
|
||||||
RunByDivisorMode(filterList, divisorCyclesSearchLimit);
|
RunByDivisorMode(filterList, divisorCyclesSearchLimit);
|
||||||
@@ -662,7 +664,6 @@ internal static class Program
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Console.WriteLine("Starting scan...");
|
|
||||||
_state = ((long)currentP << 3) | (long)remainder;
|
_state = ((long)currentP << 3) | (long)remainder;
|
||||||
Task[] tasks = new Task[threadCount];
|
Task[] tasks = new Task[threadCount];
|
||||||
|
|
||||||
@@ -740,7 +741,6 @@ internal static class Program
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
primes.Sort();
|
|
||||||
List<ByDivisorPrimeState> states = new(primes.Count);
|
List<ByDivisorPrimeState> states = new(primes.Count);
|
||||||
|
|
||||||
_byDivisorPrecheckOnly = true;
|
_byDivisorPrecheckOnly = true;
|
||||||
|
|||||||
@@ -17,9 +17,12 @@ public sealed class MersenneNumberDivisorByDivisorGpuTester
|
|||||||
private ulong _lastStatusDivisor;
|
private ulong _lastStatusDivisor;
|
||||||
|
|
||||||
private readonly ConcurrentDictionary<Accelerator, Action<Index1D, ulong, ArrayView<ulong>, ArrayView<byte>>> _kernelCache = new();
|
private readonly ConcurrentDictionary<Accelerator, Action<Index1D, ulong, ArrayView<ulong>, ArrayView<byte>>> _kernelCache = new();
|
||||||
|
private readonly ConcurrentDictionary<Accelerator, Action<Index1D, ulong, ArrayView<ulong>, ArrayView<byte>>> _kernelByPrimeCache = new();
|
||||||
|
|
||||||
private Action<Index1D, ulong, ArrayView<ulong>, ArrayView<byte>> GetKernel(Accelerator accelerator) =>
|
private Action<Index1D, ulong, ArrayView<ulong>, ArrayView<byte>> GetKernel(Accelerator accelerator) =>
|
||||||
_kernelCache.GetOrAdd(accelerator, acc => acc.LoadAutoGroupedStreamKernel<Index1D, ulong, ArrayView<ulong>, ArrayView<byte>>(CheckKernel));
|
_kernelCache.GetOrAdd(accelerator, acc => acc.LoadAutoGroupedStreamKernel<Index1D, ulong, ArrayView<ulong>, ArrayView<byte>>(CheckKernel));
|
||||||
|
private Action<Index1D, ulong, ArrayView<ulong>, ArrayView<byte>> GetKernelByPrime(Accelerator accelerator) =>
|
||||||
|
_kernelByPrimeCache.GetOrAdd(accelerator, acc => acc.LoadAutoGroupedStreamKernel<Index1D, ulong, ArrayView<ulong>, ArrayView<byte>>(CheckKernelByPrime));
|
||||||
|
|
||||||
public int GpuBatchSize
|
public int GpuBatchSize
|
||||||
{
|
{
|
||||||
@@ -110,6 +113,7 @@ public sealed class MersenneNumberDivisorByDivisorGpuTester
|
|||||||
divisors[batchSize++] = current;
|
divisors[batchSize++] = current;
|
||||||
|
|
||||||
ulong next = current + 2UL;
|
ulong next = current + 2UL;
|
||||||
|
ReportStatus(lastProcessed);
|
||||||
if (next <= current)
|
if (next <= current)
|
||||||
{
|
{
|
||||||
reachedEndInBatch = true;
|
reachedEndInBatch = true;
|
||||||
@@ -153,6 +157,7 @@ public sealed class MersenneNumberDivisorByDivisorGpuTester
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ReportStatus(lastProcessed);
|
||||||
if (composite)
|
if (composite)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
@@ -232,6 +237,79 @@ public sealed class MersenneNumberDivisorByDivisorGpuTester
|
|||||||
hits[index] = pow == 1UL ? (byte)1 : (byte)0;
|
hits[index] = pow == 1UL ? (byte)1 : (byte)0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public sealed class DivisorScanSession : IDisposable
|
||||||
|
{
|
||||||
|
private readonly MersenneNumberDivisorByDivisorGpuTester _owner;
|
||||||
|
private readonly GpuContextPool.GpuContextLease _lease;
|
||||||
|
private readonly Accelerator _accelerator;
|
||||||
|
private readonly Action<Index1D, ulong, ArrayView<ulong>, ArrayView<byte>> _kernel;
|
||||||
|
private readonly MemoryBuffer1D<ulong, Stride1D.Dense> _primesBuffer;
|
||||||
|
private readonly MemoryBuffer1D<byte, Stride1D.Dense> _hitsBuffer;
|
||||||
|
private readonly ulong[] _primesHost;
|
||||||
|
private readonly byte[] _hitsHost;
|
||||||
|
private bool _disposed;
|
||||||
|
|
||||||
|
internal DivisorScanSession(MersenneNumberDivisorByDivisorGpuTester owner)
|
||||||
|
{
|
||||||
|
_owner = owner;
|
||||||
|
_lease = GpuContextPool.RentPreferred(preferCpu: false);
|
||||||
|
_accelerator = _lease.Accelerator;
|
||||||
|
_kernel = owner.GetKernelByPrime(_accelerator);
|
||||||
|
_primesBuffer = _accelerator.Allocate1D<ulong>(owner._gpuBatchSize);
|
||||||
|
_hitsBuffer = _accelerator.Allocate1D<byte>(owner._gpuBatchSize);
|
||||||
|
_primesHost = ArrayPool<ulong>.Shared.Rent(owner._gpuBatchSize);
|
||||||
|
_hitsHost = ArrayPool<byte>.Shared.Rent(owner._gpuBatchSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CheckDivisor(ulong divisor, ReadOnlySpan<ulong> primes, Span<byte> hits)
|
||||||
|
{
|
||||||
|
if (_disposed)
|
||||||
|
{
|
||||||
|
throw new ObjectDisposedException(nameof(DivisorScanSession));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (primes.Length == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int offset = 0;
|
||||||
|
while (offset < primes.Length)
|
||||||
|
{
|
||||||
|
int batchSize = Math.Min(_owner._gpuBatchSize, primes.Length - offset);
|
||||||
|
Span<ulong> primeSpan = _primesHost.AsSpan(0, batchSize);
|
||||||
|
primes.Slice(offset, batchSize).CopyTo(primeSpan);
|
||||||
|
|
||||||
|
var primesView = _primesBuffer.View.SubView(0, batchSize);
|
||||||
|
var hitsView = _hitsBuffer.View.SubView(0, batchSize);
|
||||||
|
|
||||||
|
primesView.CopyFromCPU(ref MemoryMarshal.GetReference(primeSpan), batchSize);
|
||||||
|
_kernel(batchSize, divisor, primesView, hitsView);
|
||||||
|
_accelerator.Synchronize();
|
||||||
|
|
||||||
|
Span<byte> hitSpan = _hitsHost.AsSpan(0, batchSize);
|
||||||
|
hitsView.CopyToCPU(ref MemoryMarshal.GetReference(hitSpan), batchSize);
|
||||||
|
hitSpan.CopyTo(hits.Slice(offset, batchSize));
|
||||||
|
offset += batchSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
if (_disposed)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_disposed = true;
|
||||||
|
ArrayPool<ulong>.Shared.Return(_primesHost, clearArray: true);
|
||||||
|
ArrayPool<byte>.Shared.Return(_hitsHost, clearArray: true);
|
||||||
|
_primesBuffer.Dispose();
|
||||||
|
_hitsBuffer.Dispose();
|
||||||
|
_lease.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static ulong Pow2Mod(ulong exponent, ulong modulus)
|
private static ulong Pow2Mod(ulong exponent, ulong modulus)
|
||||||
{
|
{
|
||||||
if (modulus <= 1UL)
|
if (modulus <= 1UL)
|
||||||
@@ -293,5 +371,60 @@ public sealed class MersenneNumberDivisorByDivisorGpuTester
|
|||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void CheckKernelByPrime(Index1D index, ulong divisor, ArrayView<ulong> primes, ArrayView<byte> hits)
|
||||||
|
{
|
||||||
|
ulong prime = primes[index];
|
||||||
|
if (divisor <= 1UL || (divisor & 1UL) == 0UL)
|
||||||
|
{
|
||||||
|
hits[index] = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ulong pow = Pow2Mod(prime, divisor);
|
||||||
|
hits[index] = pow == 1UL ? (byte)1 : (byte)0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ulong DivisorLimit
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
lock (_sync)
|
||||||
|
{
|
||||||
|
if (!_isConfigured)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("ConfigureFromMaxPrime must be called before using the tester.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return _divisorLimit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ulong GetAllowedMaxDivisor(ulong prime)
|
||||||
|
{
|
||||||
|
lock (_sync)
|
||||||
|
{
|
||||||
|
if (!_isConfigured)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("ConfigureFromMaxPrime must be called before using the tester.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return ComputeAllowedMaxDivisor(prime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public DivisorScanSession CreateDivisorSession()
|
||||||
|
{
|
||||||
|
lock (_sync)
|
||||||
|
{
|
||||||
|
if (!_isConfigured)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("ConfigureFromMaxPrime must be called before using the tester.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return new DivisorScanSession(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Reference in new issue
Block a user