这篇文章与我之前的帖子非常类似:如何将CUDA代码分成多个文件 我恐怕我犯了一个大错,我实际上要求在那里试图纠正它会太混乱.
我基于CUDA SDK中的cppIntegration示例松散地使用此代码.
我希望有一个main.cpp与我的main()
函数,并让它调用一个单独的.cu文件在GPU上做一些工作.在单独的.cu文件中,我希望它能够调用驻留在另一个.cu文件中的内核代码.我设想了三个文件:Main.cpp,KernelWrapper.cu和MyKernel.cu.出于测试目的,Main.cpp除了调用RunTest()
位于KernelWrapper.cu中的函数之外什么都不做.该RunTest()
方法执行TestDevice(int *deviceArray)
位于MyKernel.cu中的内核
Main.cpp的:
#includevoid RunTest(); //forward declaration??? int main( int argc, char** argv) { RunTest(); std::cout << "blah\n"; return 0; }
KernelWrapper.cu:
#include__global__ void TestDevice(int *deviceArray); //forward declaration void RunTest() { int* hostArray; int* deviceArray; const int arrayLength = 16; const unsigned int memSize = sizeof(int) * arrayLength; hostArray = (int*)malloc(memSize); cudaMalloc((void**) &deviceArray, memSize); std::cout << "Before device\n"; for(int i=0;i >> (deviceArray); cudaMemcpy(hostArray, deviceArray, memSize, cudaMemcpyDeviceToHost); std::cout << "After device\n"; for(int i=0;i MyKernel.cu:
#ifndef _MY_KERNEL_ #define _MY_KERNEL_ __global__ void TestDevice(int *deviceArray) { int idx = blockIdx.x*blockDim.x + threadIdx.x; deviceArray[idx] = deviceArray[idx]*deviceArray[idx]; } #endif产生这些错误:
1>------ Build started: Project: CUDASandbox, Configuration: Debug x64 ------ 1>Compiling with CUDA Build Rule... 1>"C:\CUDA\bin64\nvcc.exe" -arch sm_10 -ccbin "C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\bin" -Xcompiler "/EHsc /W3 /nologo /O2 /Zi /MT " -maxrregcount=32 --compile -o "x64\Debug\KernelWrapper.cu.obj" "d:\Stuff\Programming\Visual Studio 2008\Projects\CUDASandbox\CUDASandbox\KernelWrapper.cu" 1>KernelWrapper.cu 1>tmpxft_00001ab8_00000000-3_KernelWrapper.cudafe1.gpu 1>tmpxft_00001ab8_00000000-8_KernelWrapper.cudafe2.gpu 1>tmpxft_00001ab8_00000000-3_KernelWrapper.cudafe1.cpp 1>tmpxft_00001ab8_00000000-12_KernelWrapper.ii 1>Compiling with CUDA Build Rule... 1>"C:\CUDA\bin64\nvcc.exe" -arch sm_10 -ccbin "C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\bin" -Xcompiler "/EHsc /W3 /nologo /O2 /Zi /MT " -maxrregcount=32 --compile -o "x64\Debug\MyKernel.cu.obj" "d:\Stuff\Programming\Visual Studio 2008\Projects\CUDASandbox\CUDASandbox\MyKernel.cu" 1>MyKernel.cu 1>tmpxft_000017b0_00000000-3_MyKernel.cudafe1.gpu 1>tmpxft_000017b0_00000000-8_MyKernel.cudafe2.gpu 1>tmpxft_000017b0_00000000-3_MyKernel.cudafe1.cpp 1>tmpxft_000017b0_00000000-12_MyKernel.ii 1>Compiling... 1>Main.cpp 1>Compiling manifest to resources... 1>Microsoft (R) Windows (R) Resource Compiler Version 6.1.6723.1 1>Copyright (C) Microsoft Corporation. All rights reserved. 1>Linking... 1>msvcprtd.lib(MSVCP90D.dll) : error LNK2005: "public: void __cdecl std::basic_ios>::setstate(int,bool)" (?setstate@?$basic_ios@DU?$char_traits@D@std@@@std@@QEAAXH_N@Z) already defined in KernelWrapper.cu.obj 1>msvcprtd.lib(MSVCP90D.dll) : error LNK2005: "public: __int64 __cdecl std::ios_base::width(__int64)" (?width@ios_base@std@@QEAA_J_J@Z) already defined in KernelWrapper.cu.obj 1>msvcprtd.lib(MSVCP90D.dll) : error LNK2005: "public: __int64 __cdecl std::basic_streambuf >::sputn(char const *,__int64)" (?sputn@?$basic_streambuf@DU?$char_traits@D@std@@@std@@QEAA_JPEBD_J@Z) already defined in KernelWrapper.cu.obj 1>msvcprtd.lib(MSVCP90D.dll) : error LNK2005: "public: static bool __cdecl std::char_traits ::eq_int_type(int const &,int const &)" (?eq_int_type@?$char_traits@D@std@@SA_NAEBH0@Z) already defined in KernelWrapper.cu.obj 1>msvcprtd.lib(MSVCP90D.dll) : error LNK2005: "public: static int __cdecl std::char_traits ::eof(void)" (?eof@?$char_traits@D@std@@SAHXZ) already defined in KernelWrapper.cu.obj 1>msvcprtd.lib(MSVCP90D.dll) : error LNK2005: "public: int __cdecl std::basic_streambuf >::sputc(char)" (?sputc@?$basic_streambuf@DU?$char_traits@D@std@@@std@@QEAAHD@Z) already defined in KernelWrapper.cu.obj 1>msvcprtd.lib(MSVCP90D.dll) : error LNK2005: "public: class std::basic_streambuf > * __cdecl std::basic_ios >::rdbuf(void)const " (?rdbuf@?$basic_ios@DU?$char_traits@D@std@@@std@@QEBAPEAV?$basic_streambuf@DU?$char_traits@D@std@@@2@XZ) already defined in KernelWrapper.cu.obj 1>msvcprtd.lib(MSVCP90D.dll) : error LNK2005: "public: char __cdecl std::basic_ios >::fill(void)const " (?fill@?$basic_ios@DU?$char_traits@D@std@@@std@@QEBADXZ) already defined in KernelWrapper.cu.obj 1>msvcprtd.lib(MSVCP90D.dll) : error LNK2005: "public: int __cdecl std::ios_base::flags(void)const " (?flags@ios_base@std@@QEBAHXZ) already defined in KernelWrapper.cu.obj 1>msvcprtd.lib(MSVCP90D.dll) : error LNK2005: "public: __int64 __cdecl std::ios_base::width(void)const " (?width@ios_base@std@@QEBA_JXZ) already defined in KernelWrapper.cu.obj 1>msvcprtd.lib(MSVCP90D.dll) : error LNK2005: "public: static unsigned __int64 __cdecl std::char_traits ::length(char const *)" (?length@?$char_traits@D@std@@SA_KPEBD@Z) already defined in KernelWrapper.cu.obj 1>msvcprtd.lib(MSVCP90D.dll) : error LNK2005: "public: class std::basic_ostream > & __cdecl std::basic_ostream >::flush(void)" (?flush@?$basic_ostream@DU?$char_traits@D@std@@@std@@QEAAAEAV12@XZ) already defined in KernelWrapper.cu.obj 1>msvcprtd.lib(MSVCP90D.dll) : error LNK2005: "public: class std::basic_ostream > * __cdecl std::basic_ios >::tie(void)const " (?tie@?$basic_ios@DU?$char_traits@D@std@@@std@@QEBAPEAV?$basic_ostream@DU?$char_traits@D@std@@@2@XZ) already defined in KernelWrapper.cu.obj 1>msvcprtd.lib(MSVCP90D.dll) : error LNK2005: "public: bool __cdecl std::ios_base::good(void)const " (?good@ios_base@std@@QEBA_NXZ) already defined in KernelWrapper.cu.obj 1>msvcprtd.lib(MSVCP90D.dll) : error LNK2005: "public: void __cdecl std::basic_ostream >::_Osfx(void)" (?_Osfx@?$basic_ostream@DU?$char_traits@D@std@@@std@@QEAAXXZ) already defined in KernelWrapper.cu.obj 1>msvcprtd.lib(MSVCP90D.dll) : error LNK2005: "bool __cdecl std::uncaught_exception(void)" (?uncaught_exception@std@@YA_NXZ) already defined in libcpmt.lib(uncaught.obj) 1>msvcprtd.lib(MSVCP90D.dll) : error LNK2005: "public: void __cdecl std::basic_streambuf >::_Lock(void)" (?_Lock@?$basic_streambuf@DU?$char_traits@D@std@@@std@@QEAAXXZ) already defined in KernelWrapper.cu.obj 1>msvcprtd.lib(MSVCP90D.dll) : error LNK2005: "public: void __cdecl std::basic_streambuf >::_Unlock(void)" (?_Unlock@?$basic_streambuf@DU?$char_traits@D@std@@@std@@QEAAXXZ) already defined in KernelWrapper.cu.obj 1>MSVCRTD.lib(ti_inst.obj) : error LNK2005: "private: __cdecl type_info::type_info(class type_info const &)" (??0type_info@@AEAA@AEBV0@@Z) already defined in LIBCMT.lib(typinfo.obj) 1>MSVCRTD.lib(ti_inst.obj) : error LNK2005: "private: class type_info & __cdecl type_info::operator=(class type_info const &)" (??4type_info@@AEAAAEAV0@AEBV0@@Z) already defined in LIBCMT.lib(typinfo.obj) 1>LINK : warning LNK4098: defaultlib 'MSVCRTD' conflicts with use of other libs; use /NODEFAULTLIB:library 1>D:\Stuff\Programming\Visual Studio 2008\Projects\CUDASandbox\x64\Debug\CUDASandbox.exe : fatal error LNK1169: one or more multiply defined symbols found 1>Build log was saved at "file://d:\Stuff\Programming\Visual Studio 2008\Projects\CUDASandbox\CUDASandbox\x64\Debug\BuildLog.htm" 1>CUDASandbox - 21 error(s), 1 warning(s) ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ========== 我在Windows Vista 7 64位上运行Visual Studio 2008
编辑:
Tom,这里是将代码生成设置为/ MT的构建日志
1>------ Build started: Project: CUDASandbox, Configuration: Debug x64 ------ 1>Compiling with CUDA Build Rule... 1>"C:\CUDA\bin64\nvcc.exe" -arch sm_10 -ccbin "C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\bin" -Xcompiler "/EHsc /W3 /nologo /O2 /Zi /MT " -maxrregcount=32 --compile -o "x64\Debug\MyKernel.cu.obj" "d:\Stuff\Programming\Visual Studio 2008\Projects\CUDASandbox\CUDASandbox\MyKernel.cu" 1>MyKernel.cu 1>tmpxft_000019e4_00000000-3_MyKernel.cudafe1.gpu 1>tmpxft_000019e4_00000000-8_MyKernel.cudafe2.gpu 1>tmpxft_000019e4_00000000-3_MyKernel.cudafe1.cpp 1>tmpxft_000019e4_00000000-12_MyKernel.ii 1>Compiling with CUDA Build Rule... 1>"C:\CUDA\bin64\nvcc.exe" -arch sm_10 -ccbin "C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\bin" -Xcompiler "/EHsc /W3 /nologo /O2 /Zi /MT " -maxrregcount=32 --compile -o "x64\Debug\KernelWrapper.cu.obj" "d:\Stuff\Programming\Visual Studio 2008\Projects\CUDASandbox\CUDASandbox\KernelWrapper.cu" 1>KernelWrapper.cu 1>tmpxft_0000078c_00000000-3_KernelWrapper.cudafe1.gpu 1>tmpxft_0000078c_00000000-8_KernelWrapper.cudafe2.gpu 1>tmpxft_0000078c_00000000-3_KernelWrapper.cudafe1.cpp 1>tmpxft_0000078c_00000000-12_KernelWrapper.ii 1>Compiling... 1>Main.cpp 1>Linking... 1>LINK : warning LNK4098: defaultlib 'LIBCMT' conflicts with use of other libs; use /NODEFAULTLIB:library 1>libcpmtd.lib(cout.obj) : error LNK2019: unresolved external symbol _CrtDbgReportW referenced in function "public: char const & __cdecl std::_String_const_iterator,class std::allocator >::operator*(void)const " (??D?$_String_const_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEBAAEBDXZ) 1>libcpmtd.lib(stdthrow.obj) : error LNK2001: unresolved external symbol _CrtDbgReportW 1>libcpmtd.lib(xmbtowc.obj) : error LNK2001: unresolved external symbol _CrtDbgReportW 1>libcpmtd.lib(xdebug.obj) : error LNK2019: unresolved external symbol _malloc_dbg referenced in function "void * __cdecl operator new(unsigned __int64,struct std::_DebugHeapTag_t const &,char *,int)" (??2@YAPEAX_KAEBU_DebugHeapTag_t@std@@PEADH@Z) 1>libcpmtd.lib(xmbtowc.obj) : error LNK2001: unresolved external symbol _malloc_dbg 1>libcpmtd.lib(xdebug.obj) : error LNK2019: unresolved external symbol _free_dbg referenced in function "void __cdecl operator delete(void *,struct std::_DebugHeapTag_t const &,char *,int)" (??3@YAXPEAXAEBU_DebugHeapTag_t@std@@PEADH@Z) 1>libcpmtd.lib(xmbtowc.obj) : error LNK2001: unresolved external symbol _free_dbg 1>libcpmtd.lib(_tolower.obj) : error LNK2019: unresolved external symbol _calloc_dbg referenced in function _Getctype 1>D:\Stuff\Programming\Visual Studio 2008\Projects\CUDASandbox\x64\Debug\CUDASandbox.exe : fatal error LNK1120: 4 unresolved externals 1>Build log was saved at "file://d:\Stuff\Programming\Visual Studio 2008\Projects\CUDASandbox\CUDASandbox\x64\Debug\BuildLog.htm" 1>CUDASandbox - 9 error(s), 1 warning(s) ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
Tom.. 6
看起来您在C运行时的两个不同版本之间存在冲突.CUDA运行时使用静态链接的C运行时,并且您的应用程序使用动态加载的C运行时(通常是Visual Studio中的默认值).
更改代码生成以使用静态加载的C运行时来匹配CUDA运行时:
右键单击项目并选择Properties,然后在C/C++ - > Code Generation中将Runtime Library更改为/ MT
您可以使用/ MTd进行调试,在这种情况下,您需要在CUDA构建规则 - >混合CUDA/C++选项中进行镜像.
请参阅此前面的帖子,了解更多提示.
1> Tom..:看起来您在C运行时的两个不同版本之间存在冲突.CUDA运行时使用静态链接的C运行时,并且您的应用程序使用动态加载的C运行时(通常是Visual Studio中的默认值).
更改代码生成以使用静态加载的C运行时来匹配CUDA运行时:
右键单击项目并选择Properties,然后在C/C++ - > Code Generation中将Runtime Library更改为/ MT
您可以使用/ MTd进行调试,在这种情况下,您需要在CUDA构建规则 - >混合CUDA/C++选项中进行镜像.
请参阅此前面的帖子,了解更多提示.