diff --git a/PerfectNumbers.Core/Gpu/Accelerators/PrimeOrderCalculatorAccelerator.cs b/PerfectNumbers.Core/Gpu/Accelerators/PrimeOrderCalculatorAccelerator.cs index d743378..dcea11a 100644 --- a/PerfectNumbers.Core/Gpu/Accelerators/PrimeOrderCalculatorAccelerator.cs +++ b/PerfectNumbers.Core/Gpu/Accelerators/PrimeOrderCalculatorAccelerator.cs @@ -115,20 +115,18 @@ public sealed class PrimeOrderCalculatorAccelerator public Dictionary Pow2ModEntriesToTestOnHost = []; - public readonly Kernel CheckFactorsKernel; - public readonly Kernel ConvertToStandardKernel; + public readonly Action, Stride1D.Dense>, MontgomeryDivisorData, ArrayView1D> CheckFactorsKernelLauncher; public readonly Action, MontgomeryDivisorData, ArrayView1D> ConvertToStandardKernelLauncher; - public readonly Kernel HeuristicCombinedTrialDivisionKernel; public readonly Action, ulong, ulong, HeuristicCombinedGpuViews> HeuristicCombinedTrialDivisionKernelLauncher; - public readonly Kernel KeepMontgomeryKernel; - public readonly Kernel PollardRhoKernel; - public readonly Kernel Pow2ModWideKernel; - public readonly Kernel SharesFactorKernel; - public readonly Kernel SmallPrimeFactorKernel; - public readonly Kernel SmallPrimeSieveKernel; - public readonly Kernel SpecialMaxKernel; + public readonly Action, MontgomeryDivisorData, ArrayView1D> KeepMontgomeryKernelLauncher; + public readonly Action, ArrayView1D, ArrayView1D> PollardRhoKernelLauncher; + public readonly Action, GpuUInt128, ArrayView1D> Pow2ModWideKernelLauncher; + public readonly Action, ArrayView> SharesFactorKernelLauncher; + public readonly Action, ArrayView1D, int, ArrayView1D, ArrayView1D, ArrayView1D, ArrayView1D> SmallPrimeFactorKernelLauncher; + public readonly Action, ArrayView, ArrayView, ArrayView, ArrayView, ArrayView, ArrayView, ArrayView, ArrayView, ArrayView> SmallPrimeSieveKernelLauncher; + public readonly Action, int, MontgomeryDivisorData, ArrayView1D, ArrayView1D> SpecialMaxKernelLauncher; public void EnsureCapacity(int factorsCount, int primeTesterCapacity) { @@ -262,31 +260,25 @@ public sealed class PrimeOrderCalculatorAccelerator SmallPrimeFactorSquares = tables.Squares.View; } - CheckFactorsKernel = KernelUtil.GetKernel(accelerator.LoadStreamKernel, Stride1D.Dense>, MontgomeryDivisorData, ArrayView1D>(PrimeOrderGpuHeuristics.CheckFactorsKernel)); + CheckFactorsKernelLauncher = KernelUtil.GetKernel(accelerator.LoadStreamKernel, Stride1D.Dense>, MontgomeryDivisorData, ArrayView1D>(PrimeOrderGpuHeuristics.CheckFactorsKernel)).CreateLauncherDelegate, Stride1D.Dense>, MontgomeryDivisorData, ArrayView1D>>(); - Kernel convertToStandardKernel = KernelUtil.GetKernel(accelerator.LoadAutoGroupedStreamKernel, MontgomeryDivisorData, ArrayView1D>(Pow2MontgomeryKernels.Pow2MontgomeryKernelConvertToStandard)); + ConvertToStandardKernelLauncher = KernelUtil.GetKernel(accelerator.LoadAutoGroupedStreamKernel, MontgomeryDivisorData, ArrayView1D>(Pow2MontgomeryKernels.Pow2MontgomeryKernelConvertToStandard)).CreateLauncherDelegate, MontgomeryDivisorData, ArrayView1D>>(); - ConvertToStandardKernel = convertToStandardKernel; - ConvertToStandardKernelLauncher = convertToStandardKernel.CreateLauncherDelegate, MontgomeryDivisorData, ArrayView1D>>(); + HeuristicCombinedTrialDivisionKernelLauncher = KernelUtil.GetKernel(accelerator.LoadAutoGroupedStreamKernel, ulong, ulong, HeuristicCombinedGpuViews>(PrimeTesterKernels.HeuristicTrialCombinedDivisionKernel)).CreateLauncherDelegate, ulong, ulong, HeuristicCombinedGpuViews>>(); - var heuristicCombinedTrialDivisionKernel = KernelUtil.GetKernel(accelerator.LoadAutoGroupedStreamKernel, ulong, ulong, HeuristicCombinedGpuViews>(PrimeTesterKernels.HeuristicTrialCombinedDivisionKernel)); + KeepMontgomeryKernelLauncher = KernelUtil.GetKernel(accelerator.LoadAutoGroupedStreamKernel, MontgomeryDivisorData, ArrayView1D>(Pow2MontgomeryKernels.Pow2MontgomeryKernelKeepMontgomery)).CreateLauncherDelegate, MontgomeryDivisorData, ArrayView1D>>(); - HeuristicCombinedTrialDivisionKernel = heuristicCombinedTrialDivisionKernel; - HeuristicCombinedTrialDivisionKernelLauncher = heuristicCombinedTrialDivisionKernel.CreateLauncherDelegate, ulong, ulong, HeuristicCombinedGpuViews>>(); + PollardRhoKernelLauncher = KernelUtil.GetKernel(accelerator.LoadStreamKernel, ArrayView1D, ArrayView1D>(Pow2MontgomeryKernels.TryPollardRhoKernel)).CreateLauncherDelegate, ArrayView1D, ArrayView1D>>(); - KeepMontgomeryKernel = KernelUtil.GetKernel(accelerator.LoadAutoGroupedStreamKernel, MontgomeryDivisorData, ArrayView1D>(Pow2MontgomeryKernels.Pow2MontgomeryKernelKeepMontgomery)); + Pow2ModWideKernelLauncher = KernelUtil.GetKernel(accelerator.LoadAutoGroupedStreamKernel, GpuUInt128, ArrayView1D>(PrimeOrderGpuHeuristics.Pow2ModKernelWide)).CreateLauncherDelegate, GpuUInt128, ArrayView1D>>(); - PollardRhoKernel = KernelUtil.GetKernel(accelerator.LoadStreamKernel, ArrayView1D, ArrayView1D>(Pow2MontgomeryKernels.TryPollardRhoKernel)); + SharesFactorKernelLauncher = KernelUtil.GetKernel(accelerator.LoadAutoGroupedStreamKernel, ArrayView>(PrimeTesterKernels.SharesFactorKernel)).CreateLauncherDelegate, ArrayView>>(); - Pow2ModWideKernel = KernelUtil.GetKernel(accelerator.LoadAutoGroupedStreamKernel, GpuUInt128, ArrayView1D>(PrimeOrderGpuHeuristics.Pow2ModKernelWide)); + SmallPrimeFactorKernelLauncher = KernelUtil.GetKernel(accelerator.LoadAutoGroupedStreamKernel, ArrayView1D, int, ArrayView1D, ArrayView1D, ArrayView1D, ArrayView1D>(SmallPrimeFactorKernels.SmallPrimeFactorKernelScan)).CreateLauncherDelegate, ArrayView1D, int, ArrayView1D, ArrayView1D, ArrayView1D, ArrayView1D>>(); - SharesFactorKernel = KernelUtil.GetKernel(accelerator.LoadAutoGroupedStreamKernel, ArrayView>(PrimeTesterKernels.SharesFactorKernel)); + SmallPrimeSieveKernelLauncher = KernelUtil.GetKernel(accelerator.LoadAutoGroupedStreamKernel, ArrayView, ArrayView, ArrayView, ArrayView, ArrayView, ArrayView, ArrayView, ArrayView, ArrayView>(PrimeTesterKernels.SmallPrimeSieveKernel)).CreateLauncherDelegate, ArrayView, ArrayView, ArrayView, ArrayView, ArrayView, ArrayView, ArrayView, ArrayView, ArrayView>>(); - SmallPrimeFactorKernel = KernelUtil.GetKernel(accelerator.LoadAutoGroupedStreamKernel, ArrayView1D, int, ArrayView1D, ArrayView1D, ArrayView1D, ArrayView1D>(SmallPrimeFactorKernels.SmallPrimeFactorKernelScan)); - - SmallPrimeSieveKernel = KernelUtil.GetKernel(accelerator.LoadAutoGroupedStreamKernel, ArrayView, ArrayView, ArrayView, ArrayView, ArrayView, ArrayView, ArrayView, ArrayView, ArrayView>(PrimeTesterKernels.SmallPrimeSieveKernel)); - - SpecialMaxKernel = KernelUtil.GetKernel(accelerator.LoadAutoGroupedStreamKernel, int, MontgomeryDivisorData, ArrayView1D, ArrayView1D>(PrimeOrderGpuHeuristics.EvaluateSpecialMaxCandidatesKernel)); + SpecialMaxKernelLauncher = KernelUtil.GetKernel(accelerator.LoadAutoGroupedStreamKernel, int, MontgomeryDivisorData, ArrayView1D, ArrayView1D>(PrimeOrderGpuHeuristics.EvaluateSpecialMaxCandidatesKernel)).CreateLauncherDelegate, int, MontgomeryDivisorData, ArrayView1D, ArrayView1D>>(); } } diff --git a/PerfectNumbers.Core/Gpu/Pow2MontgomeryGpuCalculator.cs b/PerfectNumbers.Core/Gpu/Pow2MontgomeryGpuCalculator.cs index 1348cc1..31279f5 100644 --- a/PerfectNumbers.Core/Gpu/Pow2MontgomeryGpuCalculator.cs +++ b/PerfectNumbers.Core/Gpu/Pow2MontgomeryGpuCalculator.cs @@ -18,16 +18,13 @@ public static class Pow2MontgomeryGpuCalculator Accelerator? accelerator = gpu.Accelerator; MemoryBuffer1D exponentBuffer = gpu.Input; MemoryBuffer1D resultBuffer = gpu.OutputUlong; - var kernel = gpu.KeepMontgomeryKernel; AcceleratorStream stream = AcceleratorStreamPool.Rent(acceleratorIndex); - exponentBuffer.View.CopyFromCPU(stream, ref exponent, 1); // We don't need to worry about any left-overs here. // resultBuffer.MemSetToZero(stream); - var kernelLauncher = kernel.CreateLauncherDelegate, MontgomeryDivisorData, ArrayView1D>>(); - + var kernelLauncher = gpu.KeepMontgomeryKernelLauncher; kernelLauncher(stream, 1, exponentBuffer.View, divisor, resultBuffer.View); resultBuffer.View.CopyToCPU(stream, ref result, 1); diff --git a/PerfectNumbers.Core/Gpu/PrimeOrderGpuHeuristics.cs b/PerfectNumbers.Core/Gpu/PrimeOrderGpuHeuristics.cs index 22285b7..c3113af 100644 --- a/PerfectNumbers.Core/Gpu/PrimeOrderGpuHeuristics.cs +++ b/PerfectNumbers.Core/Gpu/PrimeOrderGpuHeuristics.cs @@ -604,7 +604,7 @@ internal static partial class PrimeOrderGpuHeuristics } exponentBuffer.View.CopyFromCPU(stream, exponentSpan); - var kernelLauncher = gpu.Pow2ModWideKernel.CreateLauncherDelegate, GpuUInt128, ArrayView1D>>(); + var kernelLauncher = gpu.Pow2ModWideKernelLauncher; kernelLauncher(stream, length, exponentBuffer.View, modulus, remainderBuffer.View); remainderBuffer.View.CopyToCPU(stream, ref MemoryMarshal.GetReference(resultSpan), length); diff --git a/PerfectNumbers.Core/HeuristicCombinedPrimeTester.cs b/PerfectNumbers.Core/HeuristicCombinedPrimeTester.cs index 7d0be22..1f4b2e4 100644 --- a/PerfectNumbers.Core/HeuristicCombinedPrimeTester.cs +++ b/PerfectNumbers.Core/HeuristicCombinedPrimeTester.cs @@ -235,13 +235,12 @@ public sealed class HeuristicCombinedPrimeTester private static bool HeuristicTrialDivisionGpuDetectsDivisor(PrimeOrderCalculatorAccelerator gpu, ulong n, ulong maxDivisorSquare, byte nMod10) { var acceleratorIndex = gpu.AcceleratorIndex; - var stream = AcceleratorStreamPool.Rent(acceleratorIndex); - var kernel = gpu.HeuristicCombinedTrialDivisionKernel; var flagView1D = gpu.OutputInt!.View; - bool compositeDetected; - // int compositeFlag = 0; Span compositeFlag = stackalloc int[1]; + // int compositeFlag = 0; + + var stream = AcceleratorStreamPool.Rent(acceleratorIndex); flagView1D.MemSetToZero(stream); var kernelLauncher = gpu.HeuristicCombinedTrialDivisionKernelLauncher; diff --git a/PerfectNumbers.Core/HeuristicPrimeTester.cs b/PerfectNumbers.Core/HeuristicPrimeTester.cs index c3e0213..0295a49 100644 --- a/PerfectNumbers.Core/HeuristicPrimeTester.cs +++ b/PerfectNumbers.Core/HeuristicPrimeTester.cs @@ -3,7 +3,6 @@ using System.Runtime.CompilerServices; using ILGPU.Runtime; using PerfectNumbers.Core.Gpu; using PerfectNumbers.Core.Gpu.Accelerators; -using ILGPU; namespace PerfectNumbers.Core; @@ -246,7 +245,6 @@ public sealed class HeuristicPrimeTester var gpu = PrimeOrderCalculatorAccelerator.Rent(1); int acceleratorIndex = gpu.AcceleratorIndex; var stream = AcceleratorStreamPool.Rent(acceleratorIndex); - var kernel = gpu.HeuristicCombinedTrialDivisionKernel; var flagView1D = gpu.OutputInt!.View; bool compositeDetected; @@ -261,7 +259,7 @@ public sealed class HeuristicPrimeTester // HeuristicGpuDivisorTableKind tableKind, // HeuristicGpuDivisorTables tables) - var kernelLauncher = kernel.CreateLauncherDelegate, ulong, ulong, HeuristicGpuDivisorTableKind, HeuristicCombinedGpuViews>>(); + var kernelLauncher = gpu.HeuristicCombinedTrialDivisionKernelLauncher; kernelLauncher( stream, 1, @@ -269,7 +267,6 @@ public sealed class HeuristicPrimeTester flagView1D, n, maxDivisorSquare, - HeuristicGpuDivisorTableKind.GroupA, gpu.DivisorTables); flagView1D.CopyToCPU(stream, ref compositeFlag, 1); diff --git a/PerfectNumbers.Core/PrimeOrderCalculator.Gpu.cs b/PerfectNumbers.Core/PrimeOrderCalculator.Gpu.cs index d243a26..aae5691 100644 --- a/PerfectNumbers.Core/PrimeOrderCalculator.Gpu.cs +++ b/PerfectNumbers.Core/PrimeOrderCalculator.Gpu.cs @@ -36,15 +36,13 @@ internal static partial class PrimeOrderCalculator ulong order = phi; var acceleratorIndex = gpu.AcceleratorIndex; - var kernel = gpu.CheckFactorsKernel; gpu.EnsureCapacity(entryCount, 1); // GpuPrimeWorkLimiter.Acquire(); AcceleratorStream stream = AcceleratorStreamPool.Rent(acceleratorIndex); gpu.Pow2ModEntriesToTestOnDevice.View.CopyFromCPU(stream, entries); - var kernelLauncher = kernel.CreateLauncherDelegate, Stride1D.Dense>, MontgomeryDivisorData, ArrayView1D>>(); - + var kernelLauncher = gpu.CheckFactorsKernelLauncher; kernelLauncher(stream, entryCount, phi, gpu.Pow2ModEntriesToTestOnDevice.View, divisorData, gpu.OutputUlong.View); gpu.OutputUlong.View.CopyToCPU(stream, ref order, 1); @@ -67,19 +65,16 @@ internal static partial class PrimeOrderCalculator int acceleratorIndex = gpu.AcceleratorIndex; var accelerator = gpu.Accelerator; - // GpuPrimeWorkLimiter.Acquire(); - var stream = AcceleratorStreamPool.Rent(acceleratorIndex); - - var kernel = gpu.SmallPrimeFactorKernel; - var kernelLauncher = kernel.CreateLauncherDelegate, ArrayView1D, int, ArrayView1D, ArrayView1D, ArrayView1D, ArrayView1D>>(); - + var kernelLauncher = gpu.SmallPrimeFactorKernelLauncher; ArrayView1D smallPrimeFactorCountSlotView = gpu.SmallPrimeFactorCountSlot.View; ArrayView1D smallPrimeFactorRemainingSlotView = gpu.Input.View; ArrayView1D smallPrimeFactorPrimeSlotsView = gpu.OutputUlong.View; ArrayView1D smallPrimeFactorExponentSlotsView = gpu.OutputInt.View; - ArrayView1D smallPrimeFactorsPrimesView = gpu.SmallPrimeFactorPrimes; ArrayView1D smallPrimeFactorsSquaresView = gpu.SmallPrimeFactorSquares; + ArrayView1D smallPrimeFactorsPrimesView = gpu.SmallPrimeFactorPrimes; + // GpuPrimeWorkLimiter.Acquire(); + var stream = AcceleratorStreamPool.Rent(acceleratorIndex); kernelLauncher( stream, 1, @@ -136,17 +131,14 @@ internal static partial class PrimeOrderCalculator int acceleratorIndex = gpu.AcceleratorIndex; // GpuPrimeWorkLimiter.Acquire(); - var stream = AcceleratorStreamPool.Rent(acceleratorIndex); - ArrayView1D specialMaxFactorsView = gpu.Input.View; - specialMaxFactorsView.SubView(0, factorCount).CopyFromCPU(stream, factors); - var kernel = gpu.SpecialMaxKernel; + var stream = AcceleratorStreamPool.Rent(acceleratorIndex); + specialMaxFactorsView.SubView(0, factorCount).CopyFromCPU(stream, factors); ArrayView1D specialMaxResultView = gpu.SpecialMaxResult.View; - var kernelLauncher = kernel.CreateLauncherDelegate, int, MontgomeryDivisorData, ArrayView1D, ArrayView1D>>(); - + var kernelLauncher = gpu.SpecialMaxKernelLauncher; kernelLauncher( stream, 1, @@ -178,7 +170,7 @@ internal static partial class PrimeOrderCalculator AcceleratorStream stream = AcceleratorStreamPool.Rent(acceleratorIndex); gpu.Input.View.CopyFromCPU(stream, randomStateSpan); - var kernelLauncher = gpu.PollardRhoKernel.CreateLauncherDelegate, ArrayView1D, ArrayView1D>>(); + var kernelLauncher = gpu.PollardRhoKernelLauncher; kernelLauncher(stream, n, 1, gpu.Input.View, gpu.OutputByte.View, gpu.OutputUlong.View); diff --git a/PerfectNumbers.Core/PrimeTester.cs b/PerfectNumbers.Core/PrimeTester.cs index ec0a3bb..4aef0da 100644 --- a/PerfectNumbers.Core/PrimeTester.cs +++ b/PerfectNumbers.Core/PrimeTester.cs @@ -90,19 +90,17 @@ public sealed class PrimeTester [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsPrimeGpu(ulong n) { - byte flag = 0; var gpu = PrimeOrderCalculatorAccelerator.Rent(1); int acceleratorIndex = gpu.AcceleratorIndex; var inputView = gpu.Input.View; var outputView = gpu.OutputByte.View; - var kernel = gpu.SmallPrimeSieveKernel!; // GpuPrimeWorkLimiter.Acquire(); AcceleratorStream stream = AcceleratorStreamPool.Rent(acceleratorIndex); inputView.CopyFromCPU(stream, ref n, 1); - var kernelLauncher = kernel.CreateLauncherDelegate, ArrayView, ArrayView, ArrayView, ArrayView, ArrayView, ArrayView, ArrayView, ArrayView, ArrayView>>(); + var kernelLauncher = gpu.SmallPrimeSieveKernelLauncher; kernelLauncher( stream, @@ -118,6 +116,7 @@ public sealed class PrimeTester gpu.DevicePrimesPow2LastNine, outputView); + byte flag = 0; outputView.CopyToCPU(stream, ref flag, 1); stream.Synchronize(); @@ -136,13 +135,12 @@ public sealed class PrimeTester var inputView = input.View; var output = gpu.OutputByte; var outputView = output.View; - Kernel kernel = gpu.SmallPrimeSieveKernel!; int acceleratorIndex = gpu.AcceleratorIndex; AcceleratorStream stream = AcceleratorStreamPool.Rent(acceleratorIndex); inputView.CopyFromCPU(stream, ref n, 1); - var kernelLauncher = kernel.CreateLauncherDelegate, ArrayView, ArrayView, ArrayView, ArrayView, ArrayView, ArrayView, ArrayView, ArrayView, ArrayView>>(); + var kernelLauncher = gpu.SmallPrimeSieveKernelLauncher; kernelLauncher( stream, @@ -196,7 +194,6 @@ public sealed class PrimeTester // GpuPrimeWorkLimiter.Acquire(); var gpu = PrimeOrderCalculatorAccelerator.Rent(GpuBatchSize); int acceleratorIndex = gpu.AcceleratorIndex; - var kernel = gpu.SmallPrimeSieveKernel!; int totalLength = values.Length; int batchSize = GpuBatchSize; @@ -207,7 +204,7 @@ public sealed class PrimeTester int pos = 0; AcceleratorStream stream = AcceleratorStreamPool.Rent(acceleratorIndex); - var kernelLauncher = kernel.CreateLauncherDelegate, ArrayView, ArrayView, ArrayView, ArrayView, ArrayView, ArrayView, ArrayView, ArrayView, ArrayView>>(); + var kernelLauncher = gpu.SmallPrimeSieveKernelLauncher; while (pos < totalLength) { @@ -280,15 +277,14 @@ public sealed class PrimeTester var gpu = PrimeOrderCalculatorAccelerator.Rent(1); int acceleratorIndex = gpu.AcceleratorIndex; - var kernel = gpu.SharesFactorKernel; gpu.EnsureCapacity(0, length); MemoryBuffer1D? inputBuffer = gpu.Input; - MemoryBuffer1D? resultBuffer = gpu.OutputByte; AcceleratorStream stream = AcceleratorStreamPool.Rent(acceleratorIndex); inputBuffer.View.CopyFromCPU(stream, values); - var kernelLauncher = kernel.CreateLauncherDelegate, ArrayView>>(); + MemoryBuffer1D? resultBuffer = gpu.OutputByte; + var kernelLauncher = gpu.SharesFactorKernelLauncher; kernelLauncher(stream, length, inputBuffer.View, resultBuffer.View); resultBuffer.View.CopyToCPU(stream, in results);