如何将结构传递到 CUDA 设备?

Posted

技术标签:

【中文标题】如何将结构传递到 CUDA 设备?【英文标题】:How to pass structures into CUDA device? 【发布时间】:2013-12-05 08:36:34 【问题描述】:

我已经坚持了一段时间了。当我通过内核参数将我的结构传递给 CUDA 时,它们不包含任何数据,并且它们内部的一切都是未定义的。

在主机全局空间中

struct matl1

    static const double cond;
;

const double matl1::cond = 420.5;

然后在 main() 内部

matl1 * h_matl1 = (matl1*)malloc(sizeof(matl1));
matl1 * d_matl1;
cudaMalloc((void**)&d_matl1, sizeof(matl1));
cudaMemcpy(d_matl1, h_matl1, sizeof(matl1), cudaMemcpyHostToDevice);
kernel<<<1,1>>>(d_matl1,...);

然后在 kernel() 内部

__global__ void kernel(matl1* d_matl1,...)

double cond = d_matl1->cond;

我收到以下错误:

error : identifier "matl1::cond" is undefined in device code

作为一个快速测试,如果我在 main() 中的主机上执行以下操作

cout << h_matl1->cond << endl;

它显示了 420.5 的正确输出。我不确定为什么它没有进入设备。

这是我剩下的输出

uild 开始:项目:test_struct,配置:Debug Win32 ------

正在编译CUDA源文件kernel.cu...

C:\Users\User\Documents\Visual Studio 2012\Projects\test_struct\test_struct>"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v5.5\bin\nvcc.exe" -gencode=arch =compute_35,code=\"sm_35,compute_35\" --use-local-env --cl-version 2012 -ccbin "C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\bin" -I"C :\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v5.5\include" -I"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v5.5\include" -G --keep-dir Debug -maxrregcount =0 --machine 32 --compile -cudart static -g -DWIN32 -D_DEBUG -D_CONSOLE -D_MBCS -Xcompiler "/EHsc /W3 /nologo /Od /Zi /RTC1 /MDd " -o Debug\kernel.cu.obj " C:\Users\User\Documents\Visual Studio 2012\Projects\test_struct\test_struct\kernel.cu" 1>C:/Users/User/Documents/Visual Studio 2012/Projects/test_struct/test_struct/kernel.cu(15): 错误:设备代码中未定义标识符“matl1::cond”

C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V110\BuildCustomizations\CUDA 5.5.targets(592,9): error MSB3721: The command ""C:\Program Files\NVIDIA GPU 计算工具包\CUDA\v5.5\bin\nvcc.exe" -gencode=arch=compute_35,code=\"sm_35,compute_35\" --use-local-env --cl-version 2012 -ccbin "C: \Program Files (x86)\Microsoft Visual Studio 11.0\VC\bin" -I"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v5.5\include" -I"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v5.5\include" -G --keep-dir Debug -maxrregcount=0 --machine 32 --compile -cudart static -g -DWIN32 -D_DEBUG -D_CONSOLE -D_MBCS -Xcompiler "/EHsc /W3 / nologo /Od /Zi /RTC1 /MDd " -o Debug\kernel.cu.obj "C:\Users\User\Documents\Visual Studio 2012\Projects\test_struct\test_struct\kernel.cu"" 退出,代码为 2。

========== 构建:0 成功,1 失败,0 最新,0 跳过 ==========

【问题讨论】:

它看起来对我有用。请参阅here 我正在使用 CUDA 5.5 在 linux 上执行此操作。就像我一样,您需要提供更多细节和一个实际完整的示例,这样我们才能看到编译器的所有代码和输出。识别平台(linux、windows等)、哪个版本的CUDA,并提供完整的代码、编译命令的完整输出,以及完整的编译命令。 【参考方案1】:

如果我这样做,我能够重现您的错误:

struct matl1

    static const double cond;
;



__global__ void kernel(matl1* d_matl1)

double cond = d_matl1->cond;
printf("cond = %lf\n", cond);


const double matl1::cond = 420.5;

但如果我这样做,则不会:

struct matl1

    static const double cond;
;

const double matl1::cond = 420.5;

__global__ void kernel(matl1* d_matl1)

double cond = d_matl1->cond;
printf("cond = %lf\n", cond);

你需要在内核定义之前定义常量初始化器。 Here 是一个适合我的完整示例。

【讨论】:

我不知道我到底出了什么问题。即使使用您的代码(与我的原始代码几乎相同),我也会收到相同的错误:'error : identifier "matl1::cond" is undefined in device code'。我正在使用以下操作系统:Windows 7 Pro x64,GPU:GTX Titan,带有最新的 331 驱动程序,编译器:带有 Nvidia NSight 的 Visual Studio Pro 2012,CUDA 版本:5.5,Compute/SM arch:都设置为 3.5。会不会是我的编译器? 我也会在明天早上发布编译器输出的其余部分。我不能再发布 8 个小时,而且输出太长,无法容纳甚至分解为此处的 cmets 部分。 这是 Windows 工具链的一个特点。未修饰的常量使用基于 gcc 的工具链编译到主机和设备代码中,但不使用 Microsoft 编译器。我之前在这里遇到过类似的问题,在 Linux 和 OS X 上的工作在 Win 32 系统上失败了。 在这种情况下,我认为它在 gcc 中工作的事实是一个意外。我对数据模型的解释是,任何结构或类数据成员仅在定义的主机结构的内存空间中定义。在这种情况下,它应该只是主机内存空间。 @talonmies 你为什么不提供答案,我会删除我的。

以上是关于如何将结构传递到 CUDA 设备?的主要内容,如果未能解决你的问题,请参考以下文章

将包含向量的结构传递给CUDA内核

丢失在 CUDA 设备指针中

分配给设备内存的 CUDA 全局(如 C 语言)动态数组

如何使用推力和 CUDA 流将内存从主机异步复制到设备

如何将动态矩阵复制到 CUDA 中的设备内存?

如何将向量从 Cuda 直接传递到 LibSVM 结构?