[SOLVED] Linker error when loading a pre-trained model with torch script and compiling with g++

Hi all,
I am trying to add libtorch library to a c++ project, and I need to compile it with g++. Following this topic [SOLVED] Build the C++ frontend using g++ or any other compiler (no cmake) I have been able to succesfully compile it, and to train a model inside my project.

Now I would like to load a pre-trained model with pytorch, using TorchScript. Let’s take as minimal example the code provided in the tutorial LOADING A PYTORCH MODEL IN C++:

#include <torch/script.h> // One-stop header.
#include <iostream>
#include <memory>

int main(int argc, const char* argv[]) {
  if (argc != 2) {
    std::cerr << "usage: example-app <path-to-exported-script-module>\n";
    return -1;
  }
  // Deserialize the ScriptModule from a file using torch::jit::load().
     std::shared_ptr<torch::jit::script::Module> module = torch::jit::load(argv[1]);

     assert(module != nullptr);
     std::cout << "ok\n";
}

If I try to compile it with g++ I get undefined reference for the jit::load function:

g++ -I ${LIBTORCH}/include/torch/csrc/api/include/ -I ${LIBTORCH}/include/ -I ${LIBTORCH}/include/torch/ -L ${LIBTORCH}/lib -ltorch -lcaffe2 -lc10 -D_GLIBCXX_USE_CXX11_ABI=1 example-app.cpp -o example-app 

example-app.cpp:(.text+0x38e): undefined reference to `torch::jit::load(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, c10::optional<c10::Device>, std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >&)'
/tmp/ccD9MHCS.o: In function `torch::jit::SourceRange::highlight(std::ostream&) const':
example-app.cpp:(.text._ZNK5torch3jit11SourceRange9highlightERSo[_ZNK5torch3jit11SourceRange9highlightERSo]+0x196): undefined reference to `c10::Error::Error(c10::SourceLocation, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
example-app.cpp:(.text._ZNK5torch3jit11SourceRange9highlightERSo[_ZNK5torch3jit11SourceRange9highlightERSo]+0x288): undefined reference to `c10::Error::Error(c10::SourceLocation, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
example-app.cpp:(.text._ZNK5torch3jit11SourceRange9highlightERSo[_ZNK5torch3jit11SourceRange9highlightERSo]+0x3c1): undefined reference to `c10::Error::Error(c10::SourceLocation, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
example-app.cpp:(.text._ZNK5torch3jit11SourceRange9highlightERSo[_ZNK5torch3jit11SourceRange9highlightERSo]+0x50d): undefined reference to `c10::Error::Error(c10::SourceLocation, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
collect2: error: ld returned 1 exit status

It seems like is not able to retrieve the jit functions from the linked libraries. Do you have any suggestion about which library and/or include file is missing?

Any help will be appreciated!

Best,
Luigi

My first two things to check would be:

  • You are using the libraries (.so) and headers from the exact same PyTorch distribution?
  • Do you have C++ -ABI compatibility between the compiler used to compile PyTorch and yours? (i.e. try -D_GLIBCXX_USE_CXX11_ABI=0 as in the linked post)

Note that it appears to find the torch::jit::load all right, but that in turn needs C10 functions that it doesn’t find.

Best regards

Thomas

You are right, the C++ -ABI flag was the issue, turning it off as suggested solves the problem.

Thank you,
Best regards

Luigi

We now have new ABI binaries for libtorch. They can be found on
http://pytorch.org, or at https://github.com/pytorch/pytorch/issues/17492#issuecomment-524692441, which would also resolve this problem.

I tried to use the new ABI binaries as suggested by @yf225.

I downloaded the 1.4.0+cpu stable version but it does not work, even with the minimal example.

g++ -I ${LIBTORCH}/include/torch/csrc/api/include/ -I ${LIBTORCH}/include/ -I ${LIBTORCH}/include/torch/ -L ${LIBTORCH}/lib -ltorch -lc10 example-app.cpp -o example-app 
/tmp/ccNumZyv.o: In function `main':
example-app.cpp:(.text+0x14d): undefined reference to `torch::jit::load(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, c10::optional<c10::Device>, std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >&)'
/tmp/ccNumZyv.o: In function `c10::intrusive_ptr_target::~intrusive_ptr_target()':
example-app.cpp:(.text._ZN3c1020intrusive_ptr_targetD2Ev[_ZN3c1020intrusive_ptr_targetD5Ev]+0x12b): undefined reference to `c10::Error::Error(c10::SourceLocation, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
example-app.cpp:(.text._ZN3c1020intrusive_ptr_targetD2Ev[_ZN3c1020intrusive_ptr_targetD5Ev]+0x259): undefined reference to `c10::Error::Error(c10::SourceLocation, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
/tmp/ccNumZyv.o: In function `c10::intrusive_ptr<c10::intrusive_ptr_target, c10::detail::intrusive_target_default_null_type<c10::intrusive_ptr_target> >::reclaim(c10::intrusive_ptr_target*)':
example-app.cpp:(.text._ZN3c1013intrusive_ptrINS_20intrusive_ptr_targetENS_6detail34intrusive_target_default_null_typeIS1_EEE7reclaimEPS1_[_ZN3c1013intrusive_ptrINS_20intrusive_ptr_targetENS_6detail34intrusive_target_default_null_typeIS1_EEE7reclaimEPS1_]+0x145): undefined reference to `c10::Error::Error(c10::SourceLocation, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
/tmp/ccNumZyv.o: In function `c10::intrusive_ptr<c10::ivalue::Object, c10::detail::intrusive_target_default_null_type<c10::ivalue::Object> >::retain_()':
example-app.cpp:(.text._ZN3c1013intrusive_ptrINS_6ivalue6ObjectENS_6detail34intrusive_target_default_null_typeIS2_EEE7retain_Ev[_ZN3c1013intrusive_ptrINS_6ivalue6ObjectENS_6detail34intrusive_target_default_null_typeIS2_EEE7retain_Ev]+0x118): undefined reference to `c10::Error::Error(c10::SourceLocation, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
collect2: error: ld returned 1 exit status

If I add -D_GLIBCXX_USE_CXX11_ABI=1 it throws the same error. The version of the compiler is the following:

g++ (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0

Any suggestions?
Thank you

Luigi