ManagedCUDA:传递结构参数到内核
本文关键字:参数 内核 结构 ManagedCUDA | 更新日期: 2023-09-27 18:15:01
今天,我试着从c#应用程序中启动我的CUDA C/c++程序。
所以,我在网上做了一些研究,但我没有找到那么多信息。我只看到了"GitHub",但是,没有…
所以我有一个内核定义如下:(这是一个例子)
__global__ void kernel(Cartesian a, Cartesian b, Cartesian *c)
带"Cartesian":
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#程序:
创建上下文的部分:(don ' t really get this "notion")
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<Cartesian, Cartesian, Cartesian> cudaAdd = (a, b) =>
我不熟悉c#(只是说)
所以我的问题来自于result_dev和result_host引起的错误;
错误提示:
未赋值局部变量'result_*'的使用
那么,是因为它们没有初始化吗?
如果是,为什么result_host会导致错误?它必须从result_dev中获取数据,这些数据必须由内核修改。
如果没有,如何修复
我也想知道,是否有可能通过核函数传递类参数?如果是,如何设置cudadevicvariable,因为它说类型必须是不可空的。
好的。我刚刚找到了解决问题的办法。阅读https://managedcuda.codeplex.com/discussions/659183上的"讨论"部分,帮助我做到这一点。那么如何继续使用managedCUDA将结构参数传递给内核呢?
我做错的第一件事(我猜)是使用Func<T, T, T>
部分。您必须在.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<T, T,T>
,但直到我不再使用它,它似乎更容易。Func
的申报最多有2个输入参数和1个输出参数。所以我有一个内核,有4或5个参数,我在这里是有限的。但是现在,没有任何问题。