求助nvmex编译cuda程序,链接出错

我用nvmex编译cuda程序,nvmex在官网上已经不能下了,我在网上找了一个32位的版本,我系统是64位的,所以我自己改了nvmex.pl和bat里面的一些参数,现在能编译了,但是在链接的时候出错了:

nvmex -f nvmexopts.bat nvPowerSeries.cu -Iinclude -Llib\x64 -lcudart -lOpenCL
nvPowerSeries.cu
tmpxft_00000df4_00000000-3_nvPowerSeries.cudafe1.gpu
tmpxft_00000df4_00000000-8_nvPowerSeries.cudafe2.gpu
nvPowerSeries.cu
tmpxft_00000df4_00000000-3_nvPowerSeries.cudafe1.cpp
Microsoft (R) Incremental Linker Version 10.00.30319.01
Copyright (C) Microsoft Corporation. All rights reserved.

nvPowerSeries.obj
正在创建库 C:\Users\tsi\AppData\Local\Temp\mex_S2NkxP\templib.x 和对象 C:\Users\tsi\AppData\Local\Temp\mex_S2NkxP\templib.exp
nvPowerSeries.obj : error LNK2001: 无法解析的外部符号 _fltused
nvPowerSeries.obj : error LNK2019: 无法解析的外部符号 ceilf,该符号在函数 “float __cdecl ceil(float)” (?ceil@@YAMM@Z) 中被引用
nvPowerSeries.obj : error LNK2019: 无法解析的外部符号 pow,该符号在函数 exp10 中被引用
nvPowerSeries.obj : error LNK2019: 无法解析的外部符号 sin,该符号在函数 sincos 中被引用
nvPowerSeries.obj : error LNK2019: 无法解析的外部符号 cos,该符号在函数 sincos 中被引用
nvPowerSeries.obj : error LNK2019: 无法解析的外部符号 log,该符号在函数 log2 中被引用
nvPowerSeries.obj : error LNK2019: 无法解析的外部符号 ceil,该符号在函数 trunc 中被引用
nvPowerSeries.obj : error LNK2019: 无法解析的外部符号 floor,该符号在函数 trunc 中被引用
nvPowerSeries.obj : error LNK2019: 无法解析的外部符号 __imp_ldexp,该符号在函数 scalbn 中被引用
nvPowerSeries.obj : error LNK2019: 无法解析的外部符号 exp,该符号在函数 expm1 中被引用
nvPowerSeries.obj : error LNK2019: 无法解析的外部符号 sqrt,该符号在函数 acosh 中被引用
nvPowerSeries.obj : error LNK2019: 无法解析的外部符号 atexit,该符号在函数 “void __cdecl __sti____cudaRegisterAll_48_tmpxft_00000df4_00000000_6_nvPowerSeries_cpp1_ii_bd473f0d(void)” (?__sti____cudaRegisterAll_48_tmpxft_00000df4_00000000_6_nvPowerSeries_cpp1_ii_bd473f0d@@YAXXZ) 中被引用
LINK : error LNK2001: 无法解析的外部符号 _DllMainCRTStartup
nvPowerSeries.mexw64 : fatal error LNK1120: 13 个无法解析的外部命令

C:\PROGRA~1\MATLAB\R2012A\BIN\NVMEX.PL: Error: Link of ‘nvPowerSeries.mexw64’ failed.

我的cudart.lib是链接上了的,但是sin这些c语言的基本库函数反倒没连上了,是不是这个库也要自己手动链接,还是说我还有cuda的库没连上?有谁遇到过类似的问题么。

楼主您好,看到您的帖子。

但是由于我没有购买和使用过matlab,所以不懂。
不过根据您的现象,似乎是链接过程中,linker在抱怨C库找不到。

建议您尝试连接C库,看到您使用的是link.exe,这是VC的链接器,您可以考虑在命令行上加入对VC的C库的导入库(msvcrt.lib)的链接.(或者链接到libcmt.lib, 这是前者的静态库版本)。

祝您愉快!
如果此问题得不到解决,欢迎继续跟帖。

平时不用MEX,给LZ找个资料看看吧,看看有没有帮助。

[attach]2817[/attach]
[attach]2818[/attach]
[attach]2819[/attach]

还有几个链接,包括matchworks原厂提供的视频教程
http://www.mathworks.cn/company/events/webinars/wbnr59816.html?id=59816&p1=961663913&p2=961663931

http://www.nvidia.com/object/tesla-matlab-accelerations.html

https://developer.nvidia.com/matlab-cuda

大致翻看了一下介绍资料,简要总结几点个人看法:

1:早期的在matlab上的使用方法是使用NVMEX来编译含有kernel的MEX程序脚本。(NVMEX和matlab的MEX编译器以及其他C编译器等共同作用)现存很多资料是基于此方法的,3楼提供的pdf可以作为配置和使用参考。

2:在matlab新版直接将CUDA支持添加进并行计算工具箱以后,NV放弃了之前NVMEX的支持。matlab方面建议直接使用官方支持的并行工具箱或者Jacket等第三方方案。此种方法可以参考3楼的几个链接提供的信息。

大致如上,个人理解未免有不确切之处,欢迎熟悉MEX的朋友指正。

我用了你给我的nvmex资料,编译成功了,但是有一个小问题:

nvmex -f nvmexopts64.bat nvPowerSeries.cu -Iinclude -Llib\x64 -lcudart
nvPowerSeries.cu
tmpxft_00002590_00000000-8_nvPowerSeries.compute_10.cudafe1.gpu
tmpxft_00002590_00000000-12_nvPowerSeries.compute_10.cudafe2.gpu
nvPowerSeries.cu
tmpxft_00002590_00000000-6_nvPowerSeries.compute_20.cudafe1.gpu
tmpxft_00002590_00000000-16_nvPowerSeries.compute_20.cudafe2.gpu
nvPowerSeries.cu
tmpxft_00002590_00000000-3_nvPowerSeries.compute_13.cudafe1.gpu
tmpxft_00002590_00000000-20_nvPowerSeries.compute_13.cudafe2.gpu
nvPowerSeries.cu
nvPowerSeries.cu
nvPowerSeries.cu
tmpxft_00002590_00000000-8_nvPowerSeries.compute_10.cudafe1.cpp
找不到 C:\SuWork\Work\cuda\nvPowerSeries.mexw64.manifest

最后提示找不到*.mexw64.manifest,不知道是怎么回事,编出来的程序能用,但是结果是错的,因为程序不是我自己写的,所以我现在不知道是程序错了还是编译的时候出错了,我准备自己写一个先试试看这个问题到底有没有影响。你给我的资料帮了我大忙了,我准备等我调好了之后再仔细看看里面的bat文件,深入学习一下。

嗯,我用楼下的方法基本上解决啦~

既然解决了?能否贴出问题所在和解决过程?

以便有利于论坛的发展。谢谢。

善哉,算是有所进展。如果代码量不大的话,倒是可以用CUDA C验证一下算法。

我仔细看了一下nvmexopt.bat文件,之前出错的bat文件库路径设置这一项,vc的函数库路径设错了,我把vc\lib和vc\lib\amd64都写上去了,但是vc\lib放在了vc\lib\amd64之前,可能搜索库函数的时候先进了vc\lib然后找到了所需要的库,但是不是64位的所以出错了,这个时候编译器也不会再回头找amd64位里面的库了,我把amd64位库的路径放到vc\lib前面,就编译成功了。问题就出在这里。

我找到问题所在了,之前mexFunction里面定义plhs[0]的时候用的是
plhs[0] = mxCreateNumericMatrix(m, n, mxSINGLE_CLASS, mxREAL);
但是我整个程序用的数据类型是DOUBLE,改成
plhs[0] = mxCreateNumericMatrix(m, n, mxDOUBLE_CLASS, mxREAL);
之后程序就对了。

没用过mxCreateNumericMatrix这个函数,我之前以为mxSINGLE_CLASS是指单通道之类的意思,mxREAL是指double,调来调去都不对,实在没办法才改了一下这里,竟然就对了。

刚才想起我应该先doc一下mxCreateNumericMatrix看看的,于是看了一下,发现确实,第三个参数是设置数据类型的,最后一个参数是设置实数和复数的。

我仔细看了一下nvmexopt.bat文件,之前出错的bat文件库路径设置这一项,vc的函数库路径设错了,我把vc\lib和vc\lib\amd64都写上去了,但是vc\lib放在了vc\lib\amd64之前,可能搜索库函数的时候先进了vc\lib然后找到了所需要的库,但是不是64位的所以出错了,这个时候编译器也不会再回头找amd64位里面的库了,我把amd64位库的路径放到vc\lib前面,就编译成功了。问题就出在这里。

恭喜楼主!BUG退散,风轻云淡!欢迎经常来论坛相互讨论和帮助。

嘿嘿,先得谢谢两位版主的帮助。我这还只是开了个头,以后有什么问题还得来继续请教~~

欢迎分享问题和经验并回馈论坛!