62 lines
2.3 KiB
C#
62 lines
2.3 KiB
C#
using System.Runtime.CompilerServices;
|
|
using ILGPU.Runtime;
|
|
using PerfectNumbers.Core.Gpu.Accelerators;
|
|
|
|
namespace PerfectNumbers.Core.Gpu;
|
|
|
|
public static class Pow2MontgomeryGpuCalculator
|
|
{
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
|
public static ulong CalculateKeep(PrimeOrderCalculatorAccelerator gpu, ulong exponent, in MontgomeryDivisorData divisor)
|
|
{
|
|
// GpuPrimeWorkLimiter.Acquire();
|
|
|
|
ulong result = 0UL;
|
|
int acceleratorIndex = gpu.AcceleratorIndex;
|
|
Accelerator? accelerator = gpu.Accelerator;
|
|
var exponentBufferView = gpu.InputView;
|
|
var resultBufferView = gpu.OutputUlongView;
|
|
|
|
AcceleratorStream stream = AcceleratorStreamPool.Rent(acceleratorIndex);
|
|
exponentBufferView.CopyFromCPU(stream, ref exponent, 1);
|
|
// We don't need to worry about any left-overs here.
|
|
// resultBuffer.MemSetToZero(stream);
|
|
|
|
var kernelLauncher = gpu.KeepMontgomeryKernelLauncher;
|
|
kernelLauncher(stream, 1, exponentBufferView, divisor.Modulus, divisor.NPrime, divisor.MontgomeryOne, divisor.MontgomeryTwo, divisor.MontgomeryTwoSquared, resultBufferView);
|
|
|
|
resultBufferView.CopyToCPU(stream, ref result, 1);
|
|
stream.Synchronize();
|
|
AcceleratorStreamPool.Return(acceleratorIndex, stream);
|
|
// GpuPrimeWorkLimiter.Release();
|
|
|
|
return result;
|
|
}
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
|
public static ulong CalculateConvert(PrimeOrderCalculatorAccelerator gpu, ulong exponent, in MontgomeryDivisorData divisor)
|
|
{
|
|
ulong result = 0UL;
|
|
var exponentBufferView = gpu.InputView;
|
|
var resultBufferView = gpu.OutputUlongView;
|
|
|
|
int acceleratorIndex = gpu.AcceleratorIndex;
|
|
AcceleratorStream stream = AcceleratorStreamPool.Rent(acceleratorIndex);
|
|
exponentBufferView.CopyFromCPU(stream, ref exponent, 1);
|
|
// We don't need to worry about any left-overs here.
|
|
// resultBuffer.MemSetToZero(stream);
|
|
|
|
|
|
var accelerator = gpu.Accelerator;
|
|
var kernelLauncher = gpu.ConvertToStandardKernelLauncher;
|
|
kernelLauncher(stream, 1, exponentBufferView, divisor.Modulus, divisor.NPrime, divisor.MontgomeryOne, divisor.MontgomeryTwo, divisor.MontgomeryTwoSquared, resultBufferView);
|
|
|
|
resultBufferView.CopyToCPU(stream, ref result, 1);
|
|
stream.Synchronize();
|
|
|
|
AcceleratorStreamPool.Return(acceleratorIndex, stream);
|
|
|
|
return result;
|
|
}
|
|
}
|