using System.Buffers; using System.Runtime.CompilerServices; using PerfectNumbers.Core.Cpu; using PerfectNumbers.Core.Gpu; using PeterO.Numbers; namespace PerfectNumbers.Core { public static class ThreadStaticPools { [ThreadStatic] private static ArrayPool? _eintegerPool; public static ArrayPool EIntegerPool { [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] get => _eintegerPool ??= ArrayPool.Create(); } [ThreadStatic] private static FixedCapacityStack>>? _keyValuePairUInt128IntegerPool; public static FixedCapacityStack>> KeyValuePairUInt128IntegerPool { [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] get => _keyValuePairUInt128IntegerPool ??= new(PerfectNumberConstants.DefaultPoolCapacity); } [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] public static List> Rent(this FixedCapacityStack>> pool, int capacity) { if (pool.Pop() is { } pooled) { if (capacity > pooled.Capacity) { pooled.Capacity = capacity; } pooled.Clear(); return pooled; } return new(capacity); } [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] public static void Return(this FixedCapacityStack>> pool, List> list) => pool.Push(list); [ThreadStatic] private static FixedCapacityStack>? _uint128ListPool; public static FixedCapacityStack> UInt128ListPool { [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] get => _uint128ListPool ??= new(PerfectNumberConstants.DefaultPoolCapacity); } [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] public static List Rent(this FixedCapacityStack> pool, int capacity) { if (pool.Pop() is { } pooled) { if (capacity > pooled.Capacity) { pooled.Capacity = capacity; } pooled.Clear(); return pooled; } return new(capacity); } [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] public static void Return(this FixedCapacityStack> pool, List list) => pool.Push(list); [ThreadStatic] private static FixedCapacityStack>? _uint128IntDictionaryPool; public static FixedCapacityStack> UInt128IntDictionaryPool { [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] get => _uint128IntDictionaryPool ??= new(PerfectNumberConstants.DefaultPoolCapacity); } [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] public static Dictionary Rent(this FixedCapacityStack> pool, int capacity) { if (pool.Pop() is { } pooled) { pooled.EnsureCapacity(capacity); pooled.Clear(); return pooled; } return new(capacity); } [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] public static void Return(this FixedCapacityStack> pool, Dictionary dictionary) => pool.Push(dictionary); [ThreadStatic] private static FixedCapacityStack>? _ulongIntDictionaryPool; public static FixedCapacityStack> UlongIntDictionaryPool { [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] get => _ulongIntDictionaryPool ??= new(PerfectNumberConstants.DefaultPoolCapacity); } [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] public static Dictionary Rent(this FixedCapacityStack> pool, int capacity) { if (pool.Pop() is { } pooled) { pooled.EnsureCapacity(capacity); pooled.Clear(); return pooled; } return new(capacity); } [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] public static void Return(this FixedCapacityStack> pool, Dictionary dictionary) => pool.Push(dictionary); [ThreadStatic] private static ArrayPool? _factorEntryPool; public static ArrayPool FactorEntryPool { [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] get => _factorEntryPool ??= ArrayPool.Create(); } [ThreadStatic] private static ArrayPool? _factorEntry128Pool; public static ArrayPool FactorEntry128Pool { [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] get => _factorEntry128Pool ??= ArrayPool.Create(); } [ThreadStatic] private static ArrayPool? _gpuUInt128Pool; public static ArrayPool GpuUInt128Pool { [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] get => _gpuUInt128Pool ??= ArrayPool.Create(); } // [ThreadStatic] // private static MersenneCpuDivisorScanSession? _mersenneCpuDivisorSession; // [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] // internal static MersenneCpuDivisorScanSession RentMersenneCpuDivisorSession(Gpu.Accelerators.PrimeOrderCalculatorAccelerator gpu, ComputationDevice orderDevice) // { // if (_mersenneCpuDivisorSession is { } session) // { // session.Configure(gpu, orderDevice); // _mersenneCpuDivisorSession = null; // return session; // } // return new MersenneCpuDivisorScanSession(gpu, orderDevice); // } // [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] // internal static void ReturnMersenneCpuDivisorSession(MersenneCpuDivisorScanSession session) => _mersenneCpuDivisorSession = session; [ThreadStatic] private static ArrayPool? _uint128Pool; public static ArrayPool UInt128Pool { [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] get => _uint128Pool ??= ArrayPool.Create(); } [ThreadStatic] private static ArrayPool? _ulongPool; public static ArrayPool UlongPool { [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] get => _ulongPool ??= ArrayPool.Create(); } [ThreadStatic] private static ArrayPool? _boolPool; public static ArrayPool BoolPool { [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] get => _boolPool ??= ArrayPool.Create(); } [ThreadStatic] private static ArrayPool? _bytePool; public static ArrayPool BytePool { [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] get => _bytePool ??= ArrayPool.Create(); } [ThreadStatic] private static ArrayPool? _gpuDivisorPartialDataPool; internal static ArrayPool GpuDivisorPartialDataPool { [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] get => _gpuDivisorPartialDataPool ??= ArrayPool.Create(); } [ThreadStatic] private static ArrayPool? _intPool; public static ArrayPool IntPool { [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] get => _intPool ??= ArrayPool.Create(); } [ThreadStatic] private static ArrayPool? _charPool; public static ArrayPool CharPool { [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] get => _charPool ??= ArrayPool.Create(); } [ThreadStatic] private static FixedCapacityStack>? _ulongListPool; [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] public static List RentUlongList(int capacityHint) { FixedCapacityStack>? pool = _ulongListPool; if (pool is not null) { if (pool.Pop() is { } list) { if (list.Capacity < capacityHint) { list.Capacity = capacityHint; } return list; } } else { _ulongListPool = new(capacityHint); } return new List(capacityHint); } [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] public static void ReturnUlongList(List list) => _ulongListPool!.Push(list); [ThreadStatic] private static ArrayPool<(ulong, ulong)>? _ulongUlongTupleArrayPool; [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] public static (ulong, ulong)[] RentUlongUlongArray(int capacityHint) { _ulongUlongTupleArrayPool ??= ArrayPool<(ulong, ulong)>.Create(); ArrayPool<(ulong, ulong)>? pool = _ulongUlongTupleArrayPool; return pool.Rent(capacityHint); } [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] public static void Return((ulong, ulong)[] array) => _ulongUlongTupleArrayPool!.Return(array, clearArray: false); [ThreadStatic] private static FixedCapacityStack>? _primeOrderPendingEntryListPool; [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] internal static List RentPrimeOrderPendingEntryList(int capacityHint) { FixedCapacityStack>? pool = _primeOrderPendingEntryListPool; if (pool is not null) { if (pool.Pop() is { } list) { if (list.Capacity < capacityHint) { list.Capacity = capacityHint; } return list; } } else { _primeOrderPendingEntryListPool = new(PerfectNumberConstants.DefaultPoolCapacity); } return new List(capacityHint); } [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] internal static void ReturnPrimeOrderPendingEntryList(List list) => _primeOrderPendingEntryListPool!.Push(list); [ThreadStatic] private static FixedCapacityStack>? _ulongStackPool; [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] public static FixedCapacityStack RentUlongStack(int capacityHint) { FixedCapacityStack>? pool = _ulongStackPool; if (pool is not null) { if (pool.Pop() is { } stack) { stack.Capacity = capacityHint; return stack; } } else { _ulongStackPool = new(PrimeOrderConstants.GpuSmallPrimeFactorSlots); } return new FixedCapacityStack(capacityHint); } [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] public static void ReturnUlongStack(FixedCapacityStack stack) => _ulongStackPool!.Push(stack); [ThreadStatic] private static Dictionary? _factorCountDictionary; [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] public static Dictionary RentFactorCountDictionary() { Dictionary? dictionary = _factorCountDictionary; if (dictionary is null) { return new Dictionary(8); } _factorCountDictionary = null; return dictionary; } [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] public static void ReturnFactorCountDictionary(Dictionary dictionary) => _factorCountDictionary = dictionary; [ThreadStatic] private static Dictionary? _factorScratchDictionary; [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] public static Dictionary RentFactorScratchDictionary() { if (_factorScratchDictionary is { } dictionary) { _factorScratchDictionary = null; return dictionary; } return new Dictionary(8); } [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] public static void ReturnFactorScratchDictionary(Dictionary dictionary) => _factorScratchDictionary = dictionary; [ThreadStatic] private static ExponentRemainderStepperCpu _exponentRemainderStepperCpu; [ThreadStatic] private static bool _hasExponentRemainderStepperCpu; [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] internal static ExponentRemainderStepperCpu RentExponentStepperCpu(in MontgomeryDivisorData divisorData, ulong cycleLength = 0UL) { if (_hasExponentRemainderStepperCpu && _exponentRemainderStepperCpu.MatchesDivisor(divisorData, cycleLength)) { ExponentRemainderStepperCpu stepper = _exponentRemainderStepperCpu; _hasExponentRemainderStepperCpu = false; stepper.Reset(); return stepper; } return new ExponentRemainderStepperCpu(divisorData, cycleLength); } [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] internal static void ReturnExponentStepperCpu(ExponentRemainderStepperCpu stepper) { _exponentRemainderStepperCpu = stepper; _hasExponentRemainderStepperCpu = true; } } }