CMake - 将 Trilinos 与不同的 BLAS 和 LAPACK 实现联系起来

问题描述

我正在为 C++ 项目处理 CMake 输入文件,该项目使用 Trilinos 中的一些库。由于 Trilinos 依赖于(除其他外)BLAS 和 LAPACK,我需要为这些实现。更具体地说,我想将 OpenBLASscaLAPACK 实现与 Trilinos 结合使用。

我已经在我正在使用的系统上安装了 Trilinos。要使用 CMake 查找 Trilinos 安装,我使用了 find_package 功能。找到 Trilinos 后,我可以使用 Trilinos_TPL_LISTTrilinos_TPL_LIBRARIES 变量来查看 CMake 正在使用哪些 TPL。我使用以下脚本执行此操作:

cmake_minimum_required(VERSION 3.13)

project(FindTrilinos
  LANGUAGES CXX
)

set(Trilinos_DIR "/usr/local/include/Trilinos/lib/cmake/Trilinos")
find_package(Trilinos required)

if(Trilinos_FOUND)
  message(STATUS "Trilinos_TPL_LIST = ${Trilinos_TPL_LIST}")
  message(STATUS "Trilinos_TPL_LIBRARIES = ${Trilinos_TPL_LIBRARIES}")
endif()

如您所见,我从设置 Trilinos_DIR 变量开始,以便 CMake 可以找到我的 Trilinos 安装(我需要提供此完整路径,否则找不到它)。然后我简单地使用 Trilinos 作为参数调用 find_package 功能。如果确实找到了 Trilinos,我会打印 Trilinos_TPL_LISTTrilinos_TPL_LIBRARIES 变量的内容

配置上面指定的 CMakeLists.txt 文件后,我得到以下输出

-- Trilinos_TPL_LIST = DLlib;LAPACK;BLAS;MPI
-- Trilinos_TPL_LIBRARIES = /usr/lib/x86_64-linux-gnu/libdl.so;/usr/lib/x86_64-linux-gnu/liblapack.so;/usr/lib/x86_64-linux-gnu/libblas.so;/usr/lib/x86_64-linux-gnu/libdl.so;/usr/lib/x86_64-linux-gnu/liblapack.so;/usr/lib/x86_64-linux-gnu/libblas.so;/usr/lib/x86_64-linux-gnu/libdl.so;/usr/lib/x86_64-linux-gnu/liblapack.so;/usr/lib/x86_64-linux-gnu/libblas.so;/usr/lib/x86_64-linux-gnu/libdl.so;/usr/lib/x86_64-linux-gnu/liblapack.so;/usr/lib/x86_64-linux-gnu/libblas.so;/usr/lib/x86_64-linux-gnu/libdl.so;/usr/lib/x86_64-linux-gnu/liblapack.so;/usr/lib/x86_64-linux-gnu/libblas.so;/usr/lib/x86_64-linux-gnu/libdl.so;/usr/lib/x86_64-linux-gnu/liblapack.so;/usr/lib/x86_64-linux-gnu/libblas.so;/usr/lib/x86_64-linux-gnu/libdl.so;/usr/lib/x86_64-linux-gnu/liblapack.so;/usr/lib/x86_64-linux-gnu/libblas.so;/usr/lib/x86_64-linux-gnu/libdl.so;/usr/lib/x86_64-linux-gnu/liblapack.so;/usr/lib/x86_64-linux-gnu/libblas.so;/usr/lib/x86_64-linux-gnu/libdl.so;/usr/lib/x86_64-linux-gnu/liblapack.so;/usr/lib/x86_64-linux-gnu/libblas.so;/usr/lib/x86_64-linux-gnu/libdl.so;/usr/lib/x86_64-linux-gnu/liblapack.so;/usr/lib/x86_64-linux-gnu/libblas.so;/usr/lib/x86_64-linux-gnu/libdl.so;/usr/lib/x86_64-linux-gnu/liblapack.so;/usr/lib/x86_64-linux-gnu/libblas.so;/usr/lib/x86_64-linux-gnu/libdl.so;/usr/lib/x86_64-linux-gnu/liblapack.so;/usr/lib/x86_64-linux-gnu/libblas.so;/usr/lib/x86_64-linux-gnu/libdl.so;/usr/lib/x86_64-linux-gnu/liblapack.so;/usr/lib/x86_64-linux-gnu/libblas.so;/usr/lib/x86_64-linux-gnu/libdl.so;/usr/lib/x86_64-linux-gnu/liblapack.so;/usr/lib/x86_64-linux-gnu/libblas.so;/usr/lib/x86_64-linux-gnu/libdl.so;/usr/lib/x86_64-linux-gnu/liblapack.so;/usr/lib/x86_64-linux-gnu/libblas.so;/usr/lib/x86_64-linux-gnu/libdl.so;/usr/lib/x86_64-linux-gnu/liblapack.so;/usr/lib/x86_64-linux-gnu/libblas.so;/usr/lib/x86_64-linux-gnu/libdl.so;/usr/lib/x86_64-linux-gnu/liblapack.so;/usr/lib/x86_64-linux-gnu/libblas.so;/usr/lib/x86_64-linux-gnu/libdl.so;/usr/lib/x86_64-linux-gnu/liblapack.so;/usr/lib/x86_64-linux-gnu/libblas.so;/usr/lib/x86_64-linux-gnu/libdl.so;/usr/lib/x86_64-linux-gnu/liblapack.so;/usr/lib/x86_64-linux-gnu/libblas.so;/usr/lib/x86_64-linux-gnu/libdl.so;/usr/lib/x86_64-linux-gnu/liblapack.so;/usr/lib/x86_64-linux-gnu/libblas.so;/usr/lib/x86_64-linux-gnu/libdl.so;/usr/lib/x86_64-linux-gnu/liblapack.so;/usr/lib/x86_64-linux-gnu/libblas.so;/usr/lib/x86_64-linux-gnu/libdl.so;/usr/lib/x86_64-linux-gnu/liblapack.so;/usr/lib/x86_64-linux-gnu/libblas.so;/usr/lib/x86_64-linux-gnu/libdl.so;/usr/lib/x86_64-linux-gnu/liblapack.so;/usr/lib/x86_64-linux-gnu/libblas.so;/usr/lib/x86_64-linux-gnu/libdl.so;/usr/lib/x86_64-linux-gnu/liblapack.so;/usr/lib/x86_64-linux-gnu/libblas.so;/usr/lib/x86_64-linux-gnu/libdl.so;/usr/lib/x86_64-linux-gnu/liblapack.so;/usr/lib/x86_64-linux-gnu/libblas.so;/usr/lib/x86_64-linux-gnu/libdl.so;/usr/lib/x86_64-linux-gnu/liblapack.so;/usr/lib/x86_64-linux-gnu/libblas.so;/usr/lib/x86_64-linux-gnu/libdl.so;/usr/lib/x86_64-linux-gnu/liblapack.so;/usr/lib/x86_64-linux-gnu/libblas.so;/usr/lib/x86_64-linux-gnu/libdl.so;/usr/lib/x86_64-linux-gnu/liblapack.so;/usr/lib/x86_64-linux-gnu/libblas.so;/usr/lib/x86_64-linux-gnu/libdl.so;/usr/lib/x86_64-linux-gnu/liblapack.so;/usr/lib/x86_64-linux-gnu/libblas.so;/usr/lib/x86_64-linux-gnu/libdl.so;/usr/lib/x86_64-linux-gnu/liblapack.so;/usr/lib/x86_64-linux-gnu/libblas.so;/usr/lib/x86_64-linux-gnu/libdl.so;/usr/lib/x86_64-linux-gnu/liblapack.so;/usr/lib/x86_64-linux-gnu/libblas.so;/usr/lib/x86_64-linux-gnu/libdl.so;/usr/lib/x86_64-linux-gnu/liblapack.so;/usr/lib/x86_64-linux-gnu/libblas.so;/usr/lib/x86_64-linux-gnu/libdl.so;/usr/lib/x86_64-linux-gnu/liblapack.so;/usr/lib/x86_64-linux-gnu/libblas.so;/usr/lib/x86_64-linux-gnu/libdl.so;/usr/lib/x86_64-linux-gnu/liblapack.so;/usr/lib/x86_64-linux-gnu/libblas.so;/usr/lib/x86_64-linux-gnu/libdl.so;/usr/lib/x86_64-linux-gnu/libdl.so;/usr/lib/x86_64-linux-gnu/libdl.so;/usr/lib/x86_64-linux-gnu/libdl.so;/usr/lib/x86_64-linux-gnu/liblapack.so;/usr/lib/x86_64-linux-gnu/libblas.so;/usr/lib/x86_64-linux-gnu/libdl.so;/usr/lib/x86_64-linux-gnu/libdl.so;/usr/lib/x86_64-linux-gnu/libdl.so;/usr/lib/x86_64-linux-gnu/libdl.so;/usr/lib/x86_64-linux-gnu/libdl.so;/usr/lib/x86_64-linux-gnu/libdl.so;/usr/lib/x86_64-linux-gnu/libdl.so;/usr/lib/x86_64-linux-gnu/libdl.so

如您所见,Trilinos_TPL_LIBRARIES 已包含 BLAS 和 LAPACK 的认系统实现( /usr/lib/x86_64-linux-gnu/libblas.so/usr/lib/x86_64-linux-gnu/liblapack.so)。但是,正如介绍中所说,我想使用 OpenBLAS 和 scaLAPACK 实现。所以下一步就是找到这些。

在下面的 CMakeLists.txt 文件中,我尝试找到 OpenBLAS 和 LAPACK(最好是 scaLAPACK)实现:

cmake_minimum_required(VERSION 3.13)

project(FindBLASandLAPACK
    LANGUAGES CXX
)

# Set the BLAS vendor
set(BLA_vendOR OpenBLAS)

# Search BLAS 
find_package(BLAS required)
if(BLAS_FOUND)
    message(STATUS "BLAS was found."                         )
    message(STATUS "BLAS_LINKER_FLAGS = ${BLAS_LINKER_FLAGS}")
    message(STATUS "BLAS_LIBRARIES = ${BLAS_LIBRARIES}"      )
else()
    message("BLAS was not found")
endif()
    
# Search LAPACK/scaLAPACK
find_package(LAPACK)
if(LAPACK_FOUND)
    message(STATUS "LAPACK was found."                           )
    message(STATUS "LAPACK_LINKER_FLAGS = ${LAPACK_LINKER_FLAGS}")
    message(STATUS "LAPACK_LIBRARIES = ${LAPACK_LIBRARIES}"      )
else()
    message("LAPACK was not found")
endif()

根据 FindBLAS 的文档,我首先将 BLA_vendOR 指定为 OpenBLAS。如果找到指定的 BLAS 实现,我将打印 BLAS_LINKER_FLAGSBLAS_LIBRARIES内容。我遵循类似的过程来查找 LAPACK。根据 FindLAPACK 的文档,我还需要指定 BLA_vendOR 变量才能找到 LAPACK。由于我希望 LAPACK 实现使用 BLAS 的 OpenBLAS 实现,因此我再次重用该值。如果找到 LAPACK,则打印 LAPACK_LINKER_FLAGSLAPACK_LIBRARIES内容

在配置上面给出的 CMakeLists.txt 文件后,我得到以下输出

-- BLAS was found.
-- BLAS_LINKER_FLAGS =
-- BLAS_LIBRARIES = /usr/lib/x86_64-linux-gnu/libopenblas.so
-- A library with LAPACK API found.
-- LAPACK was found.
-- LAPACK_LINKER_FLAGS =
-- LAPACK_LIBRARIES = /usr/lib/x86_64-linux-gnu/libopenblas.so;/usr/lib/x86_64-linux-gnu/libopenblas.so

幸运的是,BLAS_LIBRARIES 变量确实包含 OpenBLAS 实现。但是,对于 LAPACK,它使用 OpenBLAS 库实现的 LAPACK 接口。这最终不是我想要的,因为我想使用 scaLAPACK 实现。但是,我不知道如何使用 find_package(LAPACK) 命令找到那个。

所以现在我被困在两个部分:

  1. 如何找到 scaLAPACK 实现?
  2. 一旦我找到了正确的 BLAS 和 LAPACK 实现,我如何确保 Trilinos 将实际使用它们(而不是认实现,如 Trilinos_TPL_LIBRARIES 中所述)?

感谢您阅读我的问题。任何帮助表示赞赏。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)