C# 在Alea.GPU中传递超过16个内核参数

C# 在Alea.GPU中传递超过16个内核参数,c#,.net,gpu,aleagpu,C#,.net,Gpu,Aleagpu,我正试图编写一个相当复杂的内核。事实证明,我需要传递16个以上的参数,显然Alea GPU对16个参数有限制。() 我知道16个论点听起来是个坏主意。。。还有什么其他选择?在普通代码中,我当然会将这些内容包装到它自己的类中,但是在GPU代码中我能做什么呢?在这种情况下,您可以通过GPUModule.gpumentities属性检索一个非类型化的内核对象,然后将这些参数放入对象的列表中,然后启动它 您还可以为此目的创建一些扩展方法,并使它们成为类型安全的,下面是一个示例,为了简单起见,我只使用了3

我正试图编写一个相当复杂的内核。事实证明,我需要传递16个以上的参数,显然Alea GPU对16个参数有限制。()


我知道16个论点听起来是个坏主意。。。还有什么其他选择?在普通代码中,我当然会将这些内容包装到它自己的类中,但是在GPU代码中我能做什么呢?

在这种情况下,您可以通过
GPUModule.gpumentities
属性检索一个非类型化的内核对象,然后将这些参数放入
对象的列表中,然后启动它

您还可以为此目的创建一些扩展方法,并使它们成为类型安全的,下面是一个示例,为了简单起见,我只使用了3个参数:

public static class GPUModuleExtensions
{
    public static void MyGPULaunch<T1, T2, T3>(
        this ILGPUModule module,
        Action<T1, T2, T3> kernelD, LaunchParam lp,
        T1 arg1, T2 arg2, T3 arg3)
    {
        // get the kernel object by method name
        var kernel = module.GPUEntities.GetKernel(kernelD.Method.Name).Kernel;
        // create parameter list (which is FSharpList)
        var parameterArray = new object[] {arg1, arg2, arg3};
        var parameterList = ListModule.OfArray(parameterArray);
        // use untyped LaunchRaw to launch the kernel
        kernel.LaunchRaw(lp, parameterList);
    }
}

public class GPUModule : ILGPUModule
{
    public GPUModule() : base(GPUModuleTarget.DefaultWorker)
    {
    }

    [Kernel]
    public void Kernel(deviceptr<int> outputs, int arg1, int arg2)
    {
        var tid = threadIdx.x;
        outputs[tid] = arg1 + arg2;
    }

    [Test]
    public void Test()
    {
        const int n = 32;
        var lp = new LaunchParam(1, n);
        using (var outputs = GPUWorker.Malloc<int>(n))
        {
            this.MyGPULaunch(Kernel, lp, outputs.Ptr, 1, 3);
            Console.WriteLine("{0}", (outputs.Gather())[4]);
        }
    }
}
公共静态类GPUModuleExtensions
{
公共静态void MyGPULaunch(
这个ILGPU模块,
行动kernelD,LaunchParam lp,
T1 arg1、T2 arg2、T3 arg3)
{
//通过方法名获取内核对象
var kernel=module.GPUEntities.GetKernel(kernelD.Method.Name).kernel;
//创建参数列表(即FSharpList)
var parameterArray=新对象[]{arg1,arg2,arg3};
var parameterList=ListModule.OfArray(parameterArray);
//使用非类型化LaunchRaw启动内核
kernel.LaunchRaw(lp,参数列表);
}
}
公共类GPUModule:ILGPUModule
{
public GPUModule():base(GPUModuleTarget.DefaultWorker)
{
}
[内核]
公共无效内核(deviceptr输出,int arg1,int arg2)
{
var tid=threadIdx.x;
输出[tid]=arg1+arg2;
}
[测试]
公开无效测试()
{
常数int n=32;
var lp=新启动参数(1,n);
使用(var输出=GPUWorker.Malloc(n))
{
this.MyGPULaunch(内核,lp,outputs.Ptr,1,3);
WriteLine({0}),(outputs.Gather())[4]);
}
}
}

注意,在本例中,我使用了
Action
,但是
Action
类型最多有16种类型,因此您可能需要定义自己的委托来传递16种以上的参数类型。

您可以传递数组或列表吗?您可以传递向量数据的
deviceptr
s,但这里是关于传递不同的内容,例如2个数字、3个数组等。