cmake - 链接静态库pytorch在构建过程中找不到其内部函数

정진하*_*정진하 6 cmake static-libraries static-linking pytorch libtorch

我正在尝试使用 cmake 构建一个程序。由于多种原因,必须使用静态库而不是动态库构建程序,并且我需要使用 PyTorch,所以这就是我所做的:

  1. libtorch.a下载并安装了 PyTorch 静态库(我在正确的路径中找到了/home/me/pytorch/torch/lib
  2. CMakeLists.txt由以下内容制成:
cmake_minimum_required(VERSION 3.5.1 FATAL_ERROR)
project(example-app LANGUAGES CXX)
find_package(Torch REQUIRED)
add_executable(example-app example-app.cpp argparse/argparse.cpp)
target_link_libraries(example-app "${TORCH_LIBRARIES}" -static -fopenmp)
set_property(TARGET example-app PROPERTY CXX_STANDARD 14)
Run Code Online (Sandbox Code Playgroud)

仅供参考,example-app.cpp是具有主函数的文件,并且argparse/是一个目录,其中包含调用函数的一些源代码example-app.cpp

它一直工作到cmake -DCMAKE_PREFIX_PATH=/home/me/pytorch/torch ..,但是下面build会出现一些错误,说它找不到对某些函数的引用,即以 开头的函数fbgemm::fbgemm是(据我所知)用于实现 PyTorch 的某种 GEMM 库。

在我看来,在链接静态 PyTorch 库时,其内部库(如fbgemm内容)尚未正确链接,但我不是这方面的专家cmake,老实说也不完全确定。

我做错了什么吗,或者这个问题有解决方法吗?任何帮助或推动正确的方向将不胜感激。

聚苯乙烯

  1. 确切的错误尚未发布,因为它太长了,但它主要由undefined reference to ~错误组成。如果查看错误消息可能对某些人有帮助,我很乐意编辑问题并发布它。

  2. build如果我从代码中删除需要库函数的部分而不从.#include <torch/torch.h>example-app.cpp

Szy*_*zke 6

最近使用 PyTorch 的静态链接经历了类似的过程,说实话,它不太漂亮。

我将概述我已采取的步骤(您可以在torchlambda中找到确切的源代码,这里CMakeLists.txt(它还包括 AWS SDK 和 AWS Lambda 静态构建),这里是从源代码构建的脚本pytorch(仅通过 CPU 支持进行克隆和构建/scripts/build_mobile.sh) ),尽管它仅支持 CPU(尽管如果您需要 CUDA,类似的步骤应该没问题,但它至少可以帮助您入门)。

Pytorch静态库

预构建的静态 PyTorch

首先,您需要预先构建的静态库文件(所有这些文件都需要是静态的,因此不需要.so,只有带有.a扩展名的才适合)。

老实说,我一直在寻找安装页面PyTorch上提供的那些,但只有版本。在一个 GitHub 问题中,我找到了一种下载它们的方法,如下所示:shared

而不是下载(此处通过wget)共享库:

$ wget https://download.pytorch.org/libtorch/cu101/libtorch-shared-with-deps-1.4.0.zip
Run Code Online (Sandbox Code Playgroud)

您重命名sharedstatic(如本期所述),因此它将变为:

$ wget https://download.pytorch.org/libtorch/cu101/libtorch-static-with-deps-1.4.0.zip
Run Code Online (Sandbox Code Playgroud)

然而,当您下载它时,没有libtorch.a文件lib夹(没有找到此问题libcaffe2.a所示的文件夹),所以我剩下的就是从源代码中明确构建。

如果您以某种方式拥有这些文件(如果有,请提供您从哪里获取它们),您可以跳过下一步。

从源头构建

对于 CPU 版本,我使用了/pytorch/scripts/build_mobile.sh文件,如果需要 GPU 支持,您可以以此为基础构建您的版本(也许您只需传递-DUSE_CUDA=ON到此脚本,但不确定)。

最重要的是cmake为了-DBUILD_SHARED_LIBS=OFF将一切构建为static库。您还可以从我的工具中检查脚本build_mobile.sh,该工具也传递参数。

在上面运行将/pytorch/build_mobile/install默认为您提供静态文件,其中包含您需要的一切。

CMake

现在您可以将上面的构建文件复制到/usr/local(最好不要这样做,除非您使用Dockeras torchlambda)或从您的内部设置它的路径,CMakeLists.txt如下所示:

set(LIBTORCH "/path/to/pytorch/build_mobile/install")

# Below will append libtorch to path so CMake can see files
set(CMAKE_PREFIX_PATH "${CMAKE_PREFIX_PATH};${LIBTORCH}")
Run Code Online (Sandbox Code Playgroud)

现在剩下的都很好,除了target_link_libraries,它应该(如本期所示,请参阅那里列出的相关问题以获取更多参考)与-Wl,--whole-archive链接器标志一起使用,这让我想到了这一点:

target_link_libraries(example-app PRIVATE -lm
        -Wl,--whole-archive "${TORCH_LIBRARIES}"
        -Wl,--no-whole-archive
        -lpthread
        ${CMAKE_DL_LIBS})
Run Code Online (Sandbox Code Playgroud)

您可能不需要-lm-lpthread或,尽管我在Amazon Linux AMI${CMAKE_DL_LIBS}上构建时需要它。

建筑

现在您可以开始构建您的应用程序了。标准libtorch方法应该没问题,但这是我使用的另一个命令:

mkdir build && \
  cd build &&  \
  cmake .. && \
  cmake --build . --config Release
Run Code Online (Sandbox Code Playgroud)

上面将创建二进制build文件example-app现在应该安全放置的文件夹。

最后用于ld build/example-app验证所有内容是否PyTorch静态链接,请参阅上述问题5.,您的输出应该看起来类似。