使用可重定位设备代码时的 CUDA 8.0 Visual Studio 2012 链接器选项

CUDA 8.0 Visual Studio 2012 linker options when using Relocatable Device Code

我有一个基于 class 的 C++ 代码,类似于 this and have followed the structure for declaring a __device__ method of the class. I have also gone to Project Properties-> CUDA C/C++ -> Common -> Generate Relocatable Device Code and changed it to YES but here it says the linking options need modifying and I do not understand how to do this in the VS options from this information。我该怎么做才能达到 link?

**删除了原始 post 中的 VC 工作室设置,因为不相关**

测试代码为:

kernel.cu

#include "Test.cuh"

// CUDA kernel
__global__ void myKernel(Test* t) {

// Call device function
t->device_function();
}


// Entry point
int main()
{

// Create object (host and device copies)
Test* t = new Test();
Test* t_dev = NULL;
cudaMalloc(&t_dev, sizeof(Test));

// Copy object
cudaMemcpy(t_dev,t,sizeof(Test),cudaMemcpyHostToDevice);

// Call kernel passing pointer to device copy of the object
myKernel<<<1,1>>>(t_dev);

}

Test.cuh

class Test
{
public:
Test(void);
~Test(void);

__device__ void device_function();
};

Test.cu

#include "Test.cuh"
Test::Test(void){}
Test::~Test(void){}

__device__ void Test::device_function() {

// Do something

}

编辑

添加编译日志,因为我认为它可能没有正确编译设备实现。

1> C:\C++ Projects\CudaTest\CudaTest>"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0\bin\nvcc.exe" -ccbin "C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\bin"  -I"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0\include" -I"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0\include"     --keep-dir Release -maxrregcount=0  --machine 32 --compile      -DWIN32 -DNDEBUG -D_CONSOLE -D_MBCS -Xcompiler "/EHsc /W3 /nologo /O2 /Zi  /MD " -o Release\kernel.cu.obj "C:\C++ Projects\CudaTest\CudaTest\kernel.cu" -clean
1>  kernel.cu
1>  Compiling CUDA source file kernel.cu...
1>  
1>  C:\C++ Projects\CudaTest\CudaTest>"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0\bin\nvcc.exe" -gencode=arch=compute_20,code=\"sm_20,compute_20\" --use-local-env --cl-version 2012 -ccbin "C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\bin" -rdc=true -I"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0\include" -I"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0\include"     --keep-dir Release -maxrregcount=0  --machine 32 --compile -cudart static     -DWIN32 -DNDEBUG -D_CONSOLE -D_MBCS -Xcompiler "/EHsc /W3 /nologo /O2 /Zi  /MD " -o Release\kernel.cu.obj "C:\C++ Projects\CudaTest\CudaTest\kernel.cu" 
1>  kernel.cu
1>  Test.cu
1>  
1>  C:\C++ Projects\CudaTest\CudaTest>"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0\bin\nvcc.exe" -dlink -o Release\CudaTest.device-link.obj -Xcompiler "/EHsc /W3 /nologo /O2 /Zi  /MD " -L"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0\lib\Win32" cudart.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib  -gencode=arch=compute_20,code=sm_20  --machine 32 Release\kernel.cu.obj 
1> CUDALINK : nvlink error : Undefined reference to '_ZN4Test15device_functionEv' in 'Release/kernel.cu.obj'`

好的,所以带有 CUDA 插件的 VS 有两个不同的 Item Type,它的目录不同,一个 CUDA C/C++ source/header file 和一个 C/C++ source/header,你不能简单地将一个转换为另一个通过将 *.cpp 重命名为 *.cu,这是我最初所做的,试图强制它将 class 编译成一个我可以 link 的对象。

我通过在解决方案资源管理器中右键单击,重新添加了文件 Test.cppTest.h,其源代码分别与 Test.cuTest.cuh 完全相同转到 Add Item -> CUDA source/header file 现在它将 kernel.cu Test.cu/h 构建成两个对象 both在 linking 阶段提供,问题消失。

感谢@talonmies 帮助我指明了正确的方向。

编辑

正如我在评论中提到的,如果您仍然需要告诉 VS 它们现在是不同的 Item Type,您 可以 简单地重命名文件。最初我设法通过编辑 *.vcxproj 文件告诉 CUDA 编译器编译重命名的文件来做到这一点。这是通过像这样更改 <ItemGroup> 定义来完成的:

<ItemGroup>
  <CudaCompile Include="main.cu" />
  <CudaCompile Include="RenamedSrcFile.cu" />
</ItemGroup>

<ItemGroup>
  <ClInclude Include="RenamedHeaderFile.cuh" />
  <ClInclude Include="myOtherHeader.h" />
</ItemGroup>

这一行<CudaCompile Include="RenamedSrcFile.cu" />是关键,在CUDA编译阶段包含了这个文件。常规 C++ 文件出现在组 <ClCompile> 下,尽管在此示例中给出了 none。

正如 Robert 的评论所指出的,您永远不需要直接编辑 *.vcxproj 文件,因为 VS 将根据您在 VS 中 select 的选项为您管理文件。通过像我之前那样(重新)添加文件,这个交换由 VS 处理。

EDIT2

根据 Drop 在评论中的建议,您可以通过在解决方案资源管理器中右键单击文件并在 Properties->General 下 select Item Type 成为 CUDA C/C++ 而不是 C/C++ 才能正确编目。