首页 > 解决方案 > cmake - 链接静态库pytorch在构建期间找不到其内部函数

问题描述

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

  1. 下载并安装 PyTorch 静态库(我libtorch.a在正确的路径中找到,在/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)

仅供参考,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

标签: cmakepytorchstatic-librariesstatic-linkinglibtorch

解决方案


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

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

Pytorch 静态库

预构建的静态 PyTorch

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

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

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

$ wget https://download.pytorch.org/libtorch/cu101/libtorch-shared-with-deps-1.4.0.zip

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

$ wget https://download.pytorch.org/libtorch/cu101/libtorch-static-with-deps-1.4.0.zip

然而,当你下载它时,没有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其中包含您需要的一切。

制作

现在您可以将上面的构建文件复制到/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}")

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

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

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

建造

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

mkdir build && \
  cd build &&  \
  cmake .. && \
  cmake --build . --config Release

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

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


推荐阅读