ManagedCUDA:将结构参数传递给内核
ManagedCUDA: Pass struct parameter to kernel
今天,我正在尝试从 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++ 程序的主要功能。使用 "do the work for us"
的库
所以我遵循了此页面中的示例:
然后像这样编写我的 C# 程序:
创建上下文的部分:(不太明白这个 "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 中获取数据,必须由内核修改..
如果没有,如何解决?
而且我也想知道,是否可以通过内核函数传递 Class 参数?如果是这样,如何设置 CudaDeviceVariable,因为它表示类型必须是不可空的。这就是为什么我用 struct.
改变 class
好的..我刚刚想出了解决问题的方法。阅读 https://managedcuda.codeplex.com/discussions/659183 上的 "discussion" 部分帮助我完成它。那么如何继续使用 managedCUDA 将结构参数传递给内核?
我做错的第一件事(我猜)是使用 Func<T, T, T>
部分。
您必须在您的 .cu 文件中声明您的 class,如下所示:
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 个参数的内核,我在这里受到限制......但是现在,没有任何问题。
今天,我正在尝试从 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++ 程序的主要功能。使用 "do the work for us"
的库所以我遵循了此页面中的示例:
然后像这样编写我的 C# 程序:
创建上下文的部分:(不太明白这个 "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 中获取数据,必须由内核修改..
如果没有,如何解决?
而且我也想知道,是否可以通过内核函数传递 Class 参数?如果是这样,如何设置 CudaDeviceVariable,因为它表示类型必须是不可空的。这就是为什么我用 struct.
改变 class好的..我刚刚想出了解决问题的方法。阅读 https://managedcuda.codeplex.com/discussions/659183 上的 "discussion" 部分帮助我完成它。那么如何继续使用 managedCUDA 将结构参数传递给内核?
我做错的第一件事(我猜)是使用 Func<T, T, T>
部分。
您必须在您的 .cu 文件中声明您的 class,如下所示:
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 个参数的内核,我在这里受到限制......但是现在,没有任何问题。