57 lines
1.3 KiB
C#
57 lines
1.3 KiB
C#
using ILGPU;
|
|
using ILGPU.Runtime;
|
|
|
|
namespace PerfectNumbers.Core.Gpu
|
|
{
|
|
public struct AcceleratorPool
|
|
{
|
|
internal readonly Context Context;
|
|
internal readonly Device Device;
|
|
internal readonly Accelerator[] Accelerators;
|
|
|
|
private int _index;
|
|
|
|
public Accelerator Rent()
|
|
{
|
|
Atomic.CompareExchange(ref _index, Capacity, 0);
|
|
var index = Atomic.Add(ref _index, 1);
|
|
if (index >= Capacity)
|
|
{
|
|
index -= Capacity;
|
|
}
|
|
|
|
return Accelerators[index];
|
|
}
|
|
|
|
public void Return(Accelerator accelerator)
|
|
{
|
|
// Intentionally left empty - there's nothing to do here. We're not really renting anything.
|
|
}
|
|
|
|
public static readonly AcceleratorPool Shared = new(1);
|
|
private readonly int Capacity;
|
|
|
|
public AcceleratorPool(int capacity)
|
|
{
|
|
Capacity = capacity;
|
|
var context = Context.CreateDefault();
|
|
var device = context.GetPreferredDevice(false);
|
|
Context = context;
|
|
Device = device;
|
|
int acceleratorsInContext = 0;
|
|
Accelerators = [.. Enumerable.Range(0, capacity).Select(_ =>
|
|
{
|
|
Accelerator accelerator = device.CreateAccelerator(context);
|
|
acceleratorsInContext++;
|
|
if (acceleratorsInContext >= 128)
|
|
{
|
|
context = Context.CreateDefault();
|
|
device = context.GetPreferredDevice(false);
|
|
acceleratorsInContext = 0;
|
|
}
|
|
|
|
return accelerator;
|
|
})];
|
|
}
|
|
}
|
|
} |