Initial BitContradiction implementation on GPU

This commit is contained in:
mlemanczyk committed 2026-01-25 16:37:22 +01:00
1 parent e61d166eb1
commit 17763033e1
13 files changed
+1969 -23

No files matched your search

@@ -56,7 +56,11 @@ public sealed class PrimeOrderCalculatorAccelerator
internal static void WarmUp()
{
Accelerator[] accelerators = AcceleratorPool.Shared.Accelerators;
int acceleratorCount = accelerators.Length;
int acceleratorCount = EnvironmentConfiguration.RollingAccelerators;
if (acceleratorCount > accelerators.Length)
{
acceleratorCount = accelerators.Length;
}
for (var i = 0; i < acceleratorCount; i++)
{
Console.WriteLine($"Preparing accelerator {i}...");
@@ -64,6 +68,13 @@ public sealed class PrimeOrderCalculatorAccelerator
AcceleratorStreamPool.WarmUp(i);
// Don't take this from the pool as quick uploads of data to the accelerator consumes much of GPU's memory and throws.
AcceleratorStream stream = accelerator.CreateStream();
if (SkipOrderTablesAndKernels)
{
stream.Synchronize();
stream.Dispose();
continue;
}
// TODO: Review which tables are needed when final execution path is defined.
LastDigitGpuTables.WarmUp(i, stream);
_kernels[i] = new CalculatorKernels(accelerator);
@@ -99,6 +110,9 @@ public sealed class PrimeOrderCalculatorAccelerator
private static readonly Accelerator[] _accelerators = AcceleratorPool.Shared.Accelerators;
public static bool SkipOrderTablesAndKernels;
public readonly Accelerator Accelerator;
public readonly int AcceleratorIndex;
@@ -411,6 +425,28 @@ public sealed class PrimeOrderCalculatorAccelerator
CalculateOrderWideExponentBufferView = CalculateOrderWideExponentBuffer.View;
CalculateOrderWideRemainderBufferView = CalculateOrderWideRemainderBuffer.View;
if (SkipOrderTablesAndKernels)
{
DevicePrimesLastOne = default;
DevicePrimesLastSeven = default;
DevicePrimesLastThree = default;
DevicePrimesLastNine = default;
DevicePrimesPow2LastOne = default;
DevicePrimesPow2LastSeven = default;
DevicePrimesPow2LastThree = default;
DevicePrimesPow2LastNine = default;
SmallPrimeFactorPrimes = default;
SmallPrimeFactorSquares = default;
CheckFactorsKernel = default;
ConvertToStandardKernelLauncher = default;
HeuristicCombinedTrialDivisionKernelLauncher = default;
Pow2ModKernelLauncher = default;
Pow2ModWideKernelLauncher = default;
SmallPrimeFactorKernelLauncher = default;
SpecialMaxKernelLauncher = default;
return;
}
LastDigitGpuTables lastDigitSharedTables = LastDigitGpuTables.GetStaticTables(acceleratorIndex);
DevicePrimesLastOne = lastDigitSharedTables.DevicePrimesLastOne.View;
DevicePrimesLastSeven = lastDigitSharedTables.DevicePrimesLastSeven.View;
+19 -1
View File
@@ -2,6 +2,7 @@ using System.Runtime.CompilerServices;
using ILGPU;
using ILGPU.Runtime;
using PerfectNumbers.Core.Gpu.Accelerators;
using PerfectNumbers.Core.Gpu.Kernels;
namespace PerfectNumbers.Core.Gpu;
@@ -26,7 +27,7 @@ public class GpuKernelPool
internal static KernelContainer GetOrAddKernels(int acceleratorIndex, AcceleratorStream stream, KernelType kernelType)
{
var pool = _pool ??= [];
var pool = _pool ??= new KernelContainer[_accelerators.Length];
if (pool[acceleratorIndex] is not { } kernels)
{
kernels = new();
@@ -58,6 +59,11 @@ public class GpuKernelPool
InitPow2ModOrderKernelScan(accelerator, kernels);
}
if (kernelType.HasFlag(KernelType.BitContradictionScan))
{
InitBitContradictionKernel(accelerator, kernels);
}
PreloadStaticTables(accelerator, kernels, stream, kernelType);
pool[acceleratorIndex] = kernels;
@@ -113,6 +119,18 @@ public class GpuKernelPool
});
}
static void InitBitContradictionKernel(Accelerator accelerator, KernelContainer kernels)
{
InitOnce(ref kernels.BitContradiction, () =>
{
var loaded = accelerator.LoadAutoGroupedStreamKernel<Index1D, ulong, ArrayView1D<ulong, Stride1D.Dense>, int, ArrayView1D<int, Stride1D.Dense>>(BitContradictionKernels.BitContradictionKernelScan);
var kernel = KernelUtil.GetKernel(loaded);
return kernel.CreateLauncherDelegate<Action<AcceleratorStream, Index1D, ulong, ArrayView1D<ulong, Stride1D.Dense>, int, ArrayView1D<int, Stride1D.Dense>>>();
});
}
static void InitPow2ModOrderKernelScan(Accelerator accelerator, KernelContainer kernels)
{
InitOnce(ref kernels.Pow2ModOrder, () =>
@@ -22,6 +22,9 @@ public sealed class KernelContainer
public Action<AcceleratorStream, Index1D, ulong, GpuUInt128, GpuUInt128, byte, ulong,
ResidueAutomatonArgs, ArrayView<int>, ArrayView1D<ulong, Stride1D.Dense>>? Pow2ModOrder;
public Action<AcceleratorStream, Index1D, ulong, ArrayView1D<ulong, Stride1D.Dense>, int,
ArrayView1D<int, Stride1D.Dense>>? BitContradiction;
public Kernel? SmallPrimeFactor;
public Action<AcceleratorStream, Index1D, ulong, ArrayView1D<ulong, Stride1D.Dense>, int, MontgomeryDivisorData, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>>? SpecialMax;
+2 -1
View File
@@ -10,5 +10,6 @@ public enum KernelType
OrderKernelScan,
IncrementalKernelScan,
IncrementalOrderKernelScan,
Pow2ModOrderKernelScan
Pow2ModOrderKernelScan,
BitContradictionScan
}
File diff suppressed because it is too large. Load diff