2

作成しようとしているかなり複雑なカーネルがあります。結局のところ、16 個を超える引数を渡す必要があり、どうやら Alea GPU には 16 個の引数に対する制限があるようです。( http://quantalea.com/static/app/manual/reference/alea_cuda_il/alea-cuda-il-ilgpumodule.html )

そもそも16個の引数が悪い考えのように聞こえることは知っています...他にどのようなオプションがありますか? 通常のコードでは、もちろん独自のクラスにラップしますが、GPU コードでは何ができるでしょうか?

4

1 に答える 1

2

この場合、GPUModule.GPUEntitiesプロパティを介して型指定されていないカーネル オブジェクトを取得し、それらの引数をObject型のリストに入れると、それを起動できます。

その目的のためにいくつかの拡張メソッドを作成し、それらをタイプ セーフにすることもできます。簡単にするために 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]);
        }
    }
}

この例では を使用Action<T1,T2,T3>していますが、Actiontype には最大 16 の型があるため、16 を超える引数の型を渡すには独自のデリゲートを定義する必要があるかもしれません。

于 2015-03-20T12:54:23.893 に答える