CUDAdll的创建与测试

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

CUDAdll的创建与测试创建dll第一步新建一个win32dll项目。选择dll自动生成了dll相关的框架。库函数入口点DllMain:第二步,添加CUDA函数相关的文件CUDAdll.cuh和CUDAdll.cu并设置框架属性。为其设置生成属性:CUDAdll.cuh文件设置项目“生成自定义”选择CUDA4.0并打钩设置CUDAdll.cu文件的生成属性,选择CUDAC/C++。此时如果编译该dll项目,会出现问题,报错如下:1Link:1所有输出均为最新。1正在创建库D:\elec\mymfctest\VS2010p\GPUDemos\CUDAdlltest\Debug\CUDAdlltest.lib和对象D:\elec\mymfctest\VS2010p\GPUDemos\CUDAdlltest\Debug\CUDAdlltest.exp1CUDAdll.cu.obj:errorLNK2019:无法解析的外部符号___cudaRegisterFatBinary@4,该符号在函数void__cdecl__sti____cudaRegisterAll_42_tmpxft_00000e60_00000000_3_CUDAdll_cpp1_ii_564e775d(void)(?__sti____cudaRegisterAll_42_tmpxft_00000e60_00000000_3_CUDAdll_cpp1_ii_564e775d@@YAXXZ)中被引用1CUDAdll.cu.obj:errorLNK2019:无法解析的外部符号___cudaUnregisterFatBinary@4,该符号在函数void__cdecl__cudaUnregisterBinaryUtil(void)(?__cudaUnregisterBinaryUtil@@YAXXZ)中被引用1D:\elec\mymfctest\VS2010p\GPUDemos\CUDAdlltest\Debug\CUDAdlltest.dll:fatalerrorLNK1120:2个无法解析的外部命令11生成失败。意思是链接的时候出错了,找不到链接外部符号,原因是缺少cuda的运行库,通过项目的链接输入中添加CUDA的运行库cudart.lib可以解决。至此,在没有编辑cuda函数实现文件的情况下可以正常将项目编译成功,则表明基本上将CUDAdll的框架搭建成功了。第三步,编辑CUDAdll的实现文件对应的函数。在CUDAdll.cuh中输入内容如下:#includestdio.h//引入C函数库-实际上本程序就是应该以C的方式编译,尽管其后缀为cpp类型#includestdlib.h#includecuda_runtime.h//引入CUDA运行时库头文件#ifdef__cplusplus//指明函数的编译方式,以得到没有任何修饰的函数名externC{#endif#ifdefCUDADLLTEST_EXPORTS#defineCUDADLLTEST_API__declspec(dllexport)//导出符号宏定义#else#defineCUDADLLTEST_API__declspec(dllimport)#endifexternCUDADLLTEST_APIintcount;//要导出的全局变量CUDADLLTEST_APIboolInitCUDA(void);//要导出的CUDA初始化函数CUDADLLTEST_APIvoidshowHelloCuda(void);//要导出的测试函数#ifdef__cplusplus}#endif接着在在CUDAdll.cu中输入内容如下:#includestdafx.h//引入预编译头文件#includeCUDAdll.cuh//引入导出函数声明头文件//初始化CUDAexternintcount=0;boolInitCUDA(void)//CUDA初始化函数{printf(Starttodetectedevices.........\n);//显示检测到的设备数cudaGetDeviceCount(&count);//检测计算能力大于等于1.0的设备数if(count==0){fprintf(stderr,Thereisnodevice.\n);returnfalse;}printf(%ddevice/sdetected.\n,count);//显示检测到的设备数inti;for(i=0;icount;i++){//依次验证检测到的设备是否支持CUDAcudaDevicePropprop;if(cudaGetDeviceProperties(&prop,i)==cudaSuccess){//获得设备属性并验证是否正确if(prop.major=1)//验证主计算能力,即计算能力的第一位数是否大于1{printf(Device%d:%ssupportsCUDA%d.%d.\n,i+1,prop.name,prop.major,prop.minor);//显示检测到的设备支持的CUDA版本break;}}}if(i==count){//没有支持CUDA1.x的设备fprintf(stderr,ThereisnodevicesupportingCUDA1.x.\n);returnfalse;}cudaSetDevice(i);//设置设备为主叫线程的当前设备returntrue;}voidshowHelloCuda(void)//测试CUDA初始化函数{if(!InitCUDA())//初始化失败{printf(Sorry,CUDAhasnotbeeninitialized.\n);return;}printf(HelloGPU!CUDAhasbeeninitialized.\n);}输入完毕保存后进行编译,则将在Debug目录下输出对应的dll文件:通过微软的VC++6.0或者VS2010安装时带的Tools中的Depends工具打开CUDAdlltest.dll,可以看到导出的函数和变量:需要注意的是前面在CUDAdll.cuh中输入内容中红色部分的指定编译方式宏很重要,如果没有该部分就会导出上图中VS在创建工程时默认给出导出示例函数和变量(包含该函数的两个文件CUDAdlltest.h和CUDAdlltest.cpp实际上没有用到仅作为比对,可以删去)都带有VisualC++自己的修饰符号,在win32默认的控制台程序中调用这些函数往往由于有修饰而加载时出现找不到函数的情况,而且在外部C语言程序/编译方式下无法正常运行。测试dll创建一个测试前面生成的dll的工程项目选择win32控制台项目自动生成框架如下:首先使用动态加载DLL的方式:在testCUDAdll.cpp中输入程序如下:#includestdafx.h#includestdio.h//引入C函数库#includestdlib.h#includeWindows.h//显示/动态加载链接测试typedefvoid(*DLLFUNC)(void);//声明需要从dll中调用的函数原型的函数指针int_tmain(intargc,_TCHAR*argv[]){HINSTANCEhcudaDll=LoadLibrary(__T(CUDAdlltest.dll));//动态地加载CUDAdlltest.dllif(hcudaDll){DLLFUNCdllFun=(DLLFUNC)GetProcAddress(hcudaDll,showHelloCuda);//获得函数指针if(dllFun){dllFun();//执行showHelloCuda函数}else{printf(Cannotfindthefunctionindll!);//可能由于函数名错误}FreeLibrary(hcudaDll);//动态地卸载CUDAdlltest.dll}else{printf(Loaddllfail!);}return0;}将CUDAdlltest.dll文件复制到测试程序.exe文件的目录下,编译之后运行结果如下:可见程序执行正确。使用CUDAdlltest.lib静态链接方式测试:在testCUDAdll.cpp中输入程序如下:#includestdafx.h#includestdio.h//引入C函数库#includestdlib.h#includeWindows.h#pragmacomment(lib,CUDAdlltest.lib)//引用库文件//导出函数的声明externC是不可少的externCintcount;//已导出的全局变量externCboolInitCUDA(void);//已导出的CUDA初始化函数externCvoidshowHelloCuda(void);//已导出的测试函数//隐式/静态加载链接测试int_tmain(intargc,_TCHAR*argv[]){showHelloCuda();//调用库中的函数return0;}将CUDAdlltest.lib文件复制到工程目录下以及将CUDAdlltest.dll文件复制到测试程序.exe文件的目录下,编译并运行程序,结果同上:通过在VS平台将CUDA相关的函数(CUDA的编译器windows版本现在只能在VS平台中使用)封装成dll库之后就可以在VisualC++6.0平台中使用了,这是个非常好的方法。例如上面的测试程序在VC6.0的控制台程序中如下:#includestdafx.h#includestdio.h//引入C函数库#includestdlib.h#includeWindows.h#pragmacomment(lib,CUDAdlltest.lib)//引用库文件//导出函数的声明externC是不可少的externCintcount;//已导出的全局变量externCboolInitCUDA(void);//已导出的CUDA初始化函数externCvoidshowHelloCuda(void);//已导出的测试函数intmain(intargc,char*argv[]){showHelloCuda();//调用库中的函数return0;}不过VS平台上创建的工程默认是Unicode字符集的,即前面的那个dll库文件是Unicode字符集的如果直接将其拷贝到VC6.0默认创建的MBCS多字节字符集测试工程中,编译能通过,但是如果有字符操作的函数运行可能会出错,因而需要将字符集也设置为库创建时相同的字符集,程序中也可能要做相应的修改。最后给出本文的三个测试程序(一个是库文件程序,另外两个是VS2010平台和VisualC++6.0平台下的测试程序,可以方便地作为CUDAdll应用程序开发的框架,为了能正确运行这些程序,请确保已经安装了NVIDIAGPUComputingSDK4.0及以上,并且电脑上要有NVIDIA的GPU显卡)的下载地址:参考文献:CUDADLL开发流程,编程资源链接,

1 / 16
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功