2

我正在使用Armadillo来简化我的 C++ 开发。项目在 Linux 和 Windows 中都可以正常工作(两者都是 64 位)。我正在使用 Qt Creator + qmake 来构建项目以保持跨平台的单一工具集。

我直接在我的项目中包含了犰狳。由于是模板库,不需要编译;包括标题就足够了。

现在我想使用AMD 的核心数学库 (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.pdf 包含在 acml 的存档中,第 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_是一个 LAPACK 函数,应该由 ACML 提供。

如何正确链接?我是否正确设置 qmake 以使其找到 ACML 库?

非常感谢任何提示!

编辑:我检查了 qmake 生成的 makefile 是如何调用链接器的,并尝试从那里开始工作。当我根本不启用 ACML 时,这就是链接器的调用方式(obj 文件被放入一个 tmp 文件中,该文件在调用 make 后消失,所以我只是放入“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"

但是这些命令中的每个命令都失败,并出现相同的链接器错误。

4

2 回答 2

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
}
于 2013-08-30T13:51:02.997 回答
0

您收到此错误:

File.obj:-1: error: LNK2019: unresolved external symbol sgetrf_

编译器抱怨函数名sgetrf_的地方。请注意,它都是小写的。ACML 是否需要 Blas 和 Lapack 函数名称全部大写?

我建议检查您是否在您的 Linux 和 Armadillo 的 Windows 安装中启用了 ARMA_BLAS_CAPITALS。

于 2013-08-23T05:03:17.907 回答