我正在使用Armadillo来简化我的C ++开发。项目在Linux和Windows中都可以正常工作(两者都是64位)。我正在使用Qt Creator + qmake来构建项目,以便跨平台保留单个工具集。
我直接在我的项目中加入了犰狳。由于它是模板库,因此不需要编译;包括标题就足够了。
现在我想使用AMD's Core Math Library (ACML)加速,因为它可以在Linux和Windows上免费使用。因此,我设置了Armadillo的config.hpp,通过ACML使用LAPACK + BLAS:
#define ARMA_USE_LAPACK
#define ARMA_USE_BLAS
#define ARMA_BLAS_CAPITALS
在Linux上,编译+链接正常工作。我的qmake项目文件包含:
unix: {
INCLUDEPATH += /usr/include/acml/gfortran/
LIBS += -L/usr/lib/acml/gfortran/ -lacml_mp
}
在生成的可执行文件上使用 ldd 会显示/usr/lib/acml/gfortran/libacml_mp.so上的共享库依赖项。
在Windows上,我找不到正确的链接标志来链接ACML。我使用了acml5.3.1-ifort64.exe,它使用英特尔的Fortran编译器为64位Windows编译。根据PDF手册(包含在acml的档案中,作为acml.pdf,第2.3.2节),在Windows上动态链接是这样做的:
cl driver.c -Ic:\acml5.3.1\ifort64_mp\include c:\acml5.3.1\ifort64_mp\lib\libacml_mp_dll.lib
当路径改为右路径时( cl 不是链接器而是编译器......)
基本上,它应该只是将* libacml_mp_dll.lib *文件添加到链接命令。
不幸的是,我无法正确链接。我将此添加到Windows上的qmake项目文件中:
LIBS += $$quote(C:\AMD\acml5.3.1\ifort64_mp\lib\libacml_mp_dll.lib)
路径很好,文件存在等等。
我不断收到链接错误,第一个错误(以及所有其他错误):
file.obj:-1: error: LNK2019: unresolved external symbol sgetrf_ referenced in function "void __cdecl arma::lapack::getrf<double>(int *,int *,double *,int *,int *,int *)" (??$getrf@N@lapack@arma@@YAXPEAH0PEAN000@Z)
符号 sgetrf _ 是一个应该由ACML提供的LAPACK函数。
如何正确链接?我是否正确设置qmake以便找到ACML库?
非常感谢任何提示!
编辑:我检查了qmake生成的makefile如何调用链接器并尝试从那里开始工作。这就是当我根本不启用ACML时调用链接器的方式(将obj文件放入调用make后调用的tmp文件中,所以我只是将“debug / * .obj”包含在所有对象中):
link.exe /NOLOGO /DYNAMICBASE /NXCOMPAT /DEBUG /SUBSYSTEM:CONSOLE "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='*******************' language='*' processorArchitecture='*'" /MANIFEST /MANIFESTFILE:debug\project.exe.embed.manifest /OUT:debug\project.exe debug/*.obj /LIBPATH:C:\Boost\1.54.0\lib /LIBPATH:"C:\Program Files\HDF_Group\HDF5\1.8.11\bin" hdf5.lib hdf5_hl.lib /LIBPATH:"C:\Program Files\HDF_Group\HDF5\1.8.11\lib"
然后我手动将库添加到链接器命令。我试过这些:
link.exe /NOLOGO /DYNAMICBASE /NXCOMPAT /DEBUG /SUBSYSTEM:CONSOLE "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='*******************' language='*' processorArchitecture='*'" /MANIFEST /MANIFESTFILE:debug\project.exe.embed.manifest /OUT:debug\project.exe debug/*.obj /LIBPATH:C:\Boost\1.54.0\lib /LIBPATH:"C:\Program Files\HDF_Group\HDF5\1.8.11\bin" hdf5.lib hdf5_hl.lib /LIBPATH:"C:\Program Files\HDF_Group\HDF5\1.8.11\lib" /LIBPATH:C:\AMD\acml5.3.1\ifort64_mp\lib libacml_mp_dll.lib
link.exe /NOLOGO /DYNAMICBASE /NXCOMPAT /DEBUG /SUBSYSTEM:CONSOLE "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='*******************' language='*' processorArchitecture='*'" /MANIFEST /MANIFESTFILE:debug\project.exe.embed.manifest /OUT:debug\project.exe debug/*.obj /LIBPATH:C:\Boost\1.54.0\lib /LIBPATH:"C:\Program Files\HDF_Group\HDF5\1.8.11\bin" hdf5.lib hdf5_hl.lib /LIBPATH:"C:\Program Files\HDF_Group\HDF5\1.8.11\lib" C:\AMD\acml5.3.1\ifort64_mp\lib\libacml_mp_dll.lib
link.exe /NOLOGO /DYNAMICBASE /NXCOMPAT /DEBUG /SUBSYSTEM:CONSOLE "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='*******************' language='*' processorArchitecture='*'" /MANIFEST /MANIFESTFILE:debug\project.exe.embed.manifest /OUT:debug\project.exe C:\AMD\acml5.3.1\ifort64_mp\lib\libacml_mp_dll.lib debug/*.obj /LIBPATH:C:\Boost\1.54.0\lib /LIBPATH:"C:\Program Files\HDF_Group\HDF5\1.8.11\bin" hdf5.lib hdf5_hl.lib /LIBPATH:"C:\Program Files\HDF_Group\HDF5\1.8.11\lib"
但是这些命令中的每个命令都会因相同的链接器错误而失败。
答案 0 :(得分:2)
问题在于ACML附带的BLAS没有下划线作为后缀。因此,犰狳的ARMA_BLAS_UNDERSCORE标志必须在config.hpp中评论:
// #define ARMA_BLAS_UNDERSCORE
我正在使用的qmake配置如下:
win32: {
ACMLDIR = $$quote(C:\AMD\acml5.3.1\ifort64_mp)
INCLUDEPATH += $$quote($$ACMLDIR\include)
LIBS += -L$$quote($$ACMLDIR\lib) -llibacml_mp_dll
}
答案 1 :(得分:0)
您收到此错误:
File.obj:-1: error: LNK2019: unresolved external symbol sgetrf_
编译器在抱怨函数名称 sgetrf _ 。请注意,它全部是小写的。 ACML是否需要Blas和Lapack函数名称都是大写字母?
我建议您检查在Armadillo的Linux和Window安装中是否启用了ARMA_BLAS_CAPITALS。