cmake - связывая библиотеку stati c, pytorch не может найти свои внутренние функции во время сборки - PullRequest
1 голос
/ 11 марта 2020

Я пытаюсь собрать программу, используя cmake. По нескольким причинам, программа должна быть построена с использованием библиотек stati c, а не динамических библиотек c, и мне нужно использовать PyTorch, вот что я сделал:

  1. Скачано и установлено Библиотека PyTorch stati c (я нашел 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)

FYI, example-app.cpp - это файл с основной функцией, а argparse/ - это каталог с некоторым исходным кодом для функций, вызываемых в example-app.cpp

. Он работает до cmake -DCMAKE_PREFIX_PATH=/home/me/pytorch/torch .., но следующий build возникают некоторые ошибки, говоря, что он не может найти ссылку на некоторые функции, а именно функции, начинающиеся с fbgemm::. fbgemm является (насколько мне известно) своего рода библиотекой GEMM, используемой при реализации PyTorch.

Мне кажется, что при связывании библиотеки stati c PyTorch ее внутренние библиотеки, такие как fbgemm stuff не были связаны должным образом, но я не эксперт по cmake и, честно говоря, не совсем уверен.

Я что-то не так делаю, или есть обходной путь для этой проблемы? Любая помощь или pu sh в правильном направлении будет принята с благодарностью.

PS

  1. Точная ошибка не была опубликована, потому что она слишком длинный, но он состоит в основном из undefined reference to ~ ошибок. Если для некоторых людей полезно посмотреть на сообщение об ошибке, я с радостью отредактирую вопрос и опубликую его. удалите части, которые требуют функций библиотеки, из кода без комментария #include <torch/torch.h> из example-app.cpp.

1 Ответ

1 голос
/ 24 марта 2020

В последнее время проходил аналогичный процесс со статическим c связыванием PyTorch, и, честно говоря, это было не слишком красиво.

Я обрисую шаги, которые я предпринял (точный исходный код вы можете найти в torchlambda , здесь равно CMakeLists.txt (также включает AWS SDK и AWS лямбда-стати c сборок), здесь представляет собой сценарий pytorch из исходного кода (клонирование и сборка с помощью /scripts/build_mobile.sh только с поддержкой ЦП)), хотя это только с поддержкой ЦП (хотя подобные шаги должны быть хороши, если вам нужна CUDA, это как минимум поможет вам начать работу).

Pytorch stati c library

Предварительно скомпонованные stati c PyTorch

Прежде всего, вам нужны предварительно скомпилированные файлы stati c library ( all из них нужно указать c, следовательно, .so, только те с расширением .a подходят).

Tbh Я искал те, которые предоставлены PyTorch на страница установки , пока есть только shared версия. В одном выпуске GitHub я нашел способ загрузить их следующим образом:

Вместо загрузки (здесь через wget) общих библиотек:

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

вы переименовываете shared в static (как описано в этом выпуске ), поэтому оно будет выглядеть так:

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

Тем не менее, при загрузке его нет libtorch.a в папке lib (didn не могу найти libcaffe2.a, как указано этой проблемой ), так что я остался с явной сборкой из исходного кода.

Если у вас есть эти файлы каким-либо образом (если да, пожалуйста, предоставьте откуда вы их взяли), вы можете пропустить следующий шаг.

Сборка из источника

Для версии процессора я использовал / pytorch / scripts / build_mobile. sh, вы можете основывать свою версию на этом, если требуется поддержка графического процессора (возможно, вам нужно только передать -DUSE_CUDA=ON в этот скрипт, хотя не уверен).

Наиболее важными являются cmake -DBUILD_SHARED_LIBS=OFF, чтобы собрать все как библиотеку static. Вы также можете проверить скрипт из моего инструмента , который также передает аргументы в build_mobile.sh.

Запуск выше даст вам * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * по умолчанию. вам нужно.

CMake

Теперь вы можете скопировать файлы сборки выше в /usr/local (лучше, если вы не используете Docker в качестве 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, что должно быть (как указано эта проблема , см. связанные вопросы, перечисленные там для дополнительной справки), используемые с -Wl,--whole-archive флагом компоновщика, что привело меня к этому:

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

Вам может не понадобиться ни -lm, -lpthread, ни ${CMAKE_DL_LIBS}, хотя я он понадобился при сборке Amazon Linux AMI .

Building

Теперь вы готовы создавать приложение. Стандартный libtorch способ должен быть в порядке, но вот еще одна команда, которую я использовал:

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

Выше создастся папка build, в которой example-app бинарный файл теперь должен быть безопасно расположен.

Наконец используйте ld build/example-app, чтобы проверить, что все из PyTorch статически связано, см. вышеупомянутую проблему точка 5., ваш вывод должен выглядеть аналогично.

...