我有一个类似于this的基于类的C ++代码,并且遵循了声明类的__device__
方法的结构。我已经转到Project Properties-> CUDA C/C++ -> Common -> Generate Relocatable Device Code
并将其更改为YES,但here它表示链接选项需要修改,我不明白如何在this information的VS选项中执行此操作。我该怎么做才能让它链接?
**删除原始帖子中的VC studio设置为不相关**
测试代码是:
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'`
答案 0 :(得分:2)
好的,所以带有CUDA插件的VS有两个不同的Item Type
,它的编目方式不同,CUDA C/C++ source/header file
和C/C++ source/header
,你不能简单地通过重命名将一个转换为另一个*.cpp
到*.cu
这是我最初尝试强制它将类编译成我可以链接到的对象。
通过右键单击解决方案资源管理器并转到,我分别使用与Test.cpp
和Test.h
完全相同的源代码重新添加了文件Test.cu
和Test.cuh
Add Item -> CUDA source/header file
现在它将kernel.cu
和 Test.cu/h
构建为两个在链接阶段提供两者的对象和问题消失。
感谢@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>
下,但在此示例中没有给出。
正如Robert的评论所示,您永远不需要直接编辑*.vcxproj
文件,因为VS会根据您在VS中选择的选项为您管理文件。通过(重新)添加文件,我之前做过,这个交换由VS负责。
<强> EDIT2 强>
根据Drop在评论中的建议,您可以通过右键单击解决方案资源管理器中的文件重新添加文件来实现此交换,并在Properties->General
下您可以选择{{1成为Item Type
而不是CUDA C/C++
来正确编目。