【问题标题】:ManagedCUDA: Pass struct parameter to kernelManagedCUDA:将结构参数传递给内核
【发布时间】:2016-11-08 16:08:35
【问题描述】:

今天,我正在尝试从 C# 应用程序启动我的 CUDA C/C++ 程序。

所以,我在网上做了一些研究,但没有找到那么多信息。我只看到了“GitHub”,但是,没有……

所以我定义了一个内核,如下所示: (这是一个例子)

__global__ void kernel(Cartesian a, Cartesian b, Cartesian *c)

使用“笛卡尔”:

class Cartesian
{
public:
    double x;
    double y;
    double z;
};

根据我对 managedCUDA 的理解。这就像替换 CUDA C/C++ 程序的主要功能。使用“为我们工作”的库

所以我遵循了这个页面中的一个例子:

https://algoslaves.wordpress.com/2013/08/25/nvidia-cuda-hello-world-in-managed-c-and-f-with-use-of-managedcuda/

然后像这样编写我的 C# 程序:

创建上下文的部分:(不要真正理解这个“概念”)

    static void InitKernels()
    {
        CudaContext cntxt = new CudaContext();
        CUmodule cumodule = cntxt.LoadModule(@"C:\Users\stage\Documents\Visual Studio 2013\Projects\Cs_link_test\Cs_link_test\x64\Release\kernel.ptx");
        addWithCuda = new CudaKernel("kernel", cumodule, cntxt);
    }

启动(我猜)函数并取回内核所做的修改的部分:

    static Func<Cartesian, Cartesian, Cartesian> cudaAdd = (a, b) =>
    {
        CudaDeviceVariable<Cartesian> result_dev;
        Cartesian result_host;
        addWithCuda.Run(a, b, result_dev.DevicePointer);
        result_dev.CopyToHost(ref result_host);
        return result_host;
    };

从这部分我不明白任何东西:

static Func&lt;Cartesian, Cartesian, Cartesian&gt; cudaAdd = (a, b) =&gt;

我不熟悉C#(只是说)

所以我的问题来自result_dev和result_host引起的错误;

错误说:

使用未赋值的局部变量'result_*'

那么,是因为它们没有初始化吗?

如果是这样,为什么 result_host 会导致错误?它必须从 result_dev 中获取数据,这些数据必须由内核修改..

如果没有,如何解决?

我也想知道,是否可以通过内核函数传递 Class 参数?如果是这样,如何设置 CudaDeviceVariable,因为它说该类型必须是不可为空的。这就是为什么我用 struct 改变类。

【问题讨论】:

  • 问题不清楚。您是在尝试编写 C/C++ CUDA 代码还是 C# managedCUDA?
  • CUDA C/C++ 代码已经写好了。我正在尝试编写 C# managedCUDA 来运行这个 CUDA C/C++ 代码

标签: c# cuda managed-cuda


【解决方案1】:

好吧..我刚刚想出了如何解决我的问题。阅读https://managedcuda.codeplex.com/discussions/659183 上的“讨论”部分,帮助我做到这一点。那么如何继续使用 managedCUDA 将结构参数传递给内核呢?

我做错的第一件事(我猜)是使用Func&lt;T, T, T&gt;part。 您必须在 .cu 文件中声明您的类,如下所示:

class Cartesian
{
public:
  double x;
  double y;
  double z;
}

在您的 .cs 文件中也是如此,如下所示:

[StructLayout(LayoutKind.Sequential)]
struct Cartesian
{
   public double x;
   public double y;
   public double z;
   public Cartesian(double x, double y, double z) { this.x = x; this.y = y; this.z = z; }
};

然后你就可以随意初始化你的内核了,我是这样做的:

    static void InitKernels()
    {
        CudaContext ctx = new CudaContext();
        CUmodule cumodule = ctx.LoadModule(@"C:\Users\stage\Documents\Visual Studio 2013\Projects\Cs_link_test\Cs_link_test\x64\Release\kernel.ptx");
        kernel = new CudaKernel("kernelPosGeo", cumodule, ctx);
        kernel.BlockDimensions = 1024;
        kernel.GridDimensions = 614;
    }

而你需要做的只是用你想要的参数调用你的内核。

Cartesian a = new Cartesian(1, 2, 3);
kernel.Run(a);

我想我遇到了问题,因为我使用了Func&lt;T, T,T&gt;,但在我不再使用它之前,它似乎更容易了。 Func 的声明最多有 2 个参数输入和 1 个输出。所以我有一个有 4 或 5 个参数的内核,我在这里受到限制......但现在,没有任何问题。

【讨论】:

    猜你喜欢
    • 2011-05-09
    • 1970-01-01
    • 1970-01-01
    • 2021-06-10
    • 1970-01-01
    • 1970-01-01
    • 2015-07-15
    • 1970-01-01
    • 2013-01-18
    相关资源
    最近更新 更多