anurag
anurag

Reputation: 1932

undefined symbol error when importing libtorch function via pybind11

I am attempting to write a C++ function in libtorch, compile it with pybind11 and then import the .so file in a python file.

The build seems to work fine (no errors are emitted) but, when I try to import it into my python file, execution fails with the error message:

ImportError: /home/cppNpython/MyProj/cpp/build/srcfile.cpython-37m-x86_64-linux-gnu.so: undefined symbol: _ZN3c106detail23torchInternalAssertFailEPKcS2_jS2_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE

demangled version looks as follows:

undefined symbol: c10::detail::torchInternalAssertFail(char const*, char const*, unsigned int, char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)

This is my directory structure:

|-- MyProj
|   |-- cpp
|   |   |-- build
|   |   |   `-- __init__.py
|   |   |-- include
|   |   |   `-- srcfile.h
|   |   |-- lib
|   |   |   |-- libtorch
|   |   |   `-- pybind11
|   |   |-- source
|   |   |   `-- srcfile.cpp
|   |   `-- CMakeLists.txt
|   `-- __init__.py
`-- test.py

Here are the contents of each file:-

srcfile.cpp

#include <srcfile.h>

torch::Tensor test(torch::Tensor t1, torch::Tensor t2) {
  return t1;
}

PYBIND11_MODULE(srcfile, m) {
    m.doc() = "demo function"; // optional module docstring
    m.def("test", &test, "A function giving torch tensor");
}

srcfile.h

#ifndef __SRCFILE_H__
#define __SRCFILE_H__

#include <torch/torch.h>
#include <pybind11/pybind11.h>

torch::Tensor test(torch::Tensor, torch::Tensor);

#endif

CMakeLists.txt

project(srcfile)
cmake_minimum_required(VERSION 3.10)
set(CMAKE_CXX_STANDARD 14)

find_package(PythonLibs REQUIRED)
set(CMAKE_PREFIX_PATH "lib/libtorch/share/cmake/Torch")
find_package(Torch REQUIRED)

include_directories(lib/libtorch)

include_directories(${PYTHON_INCLUDE_DIRS})

add_subdirectory(lib/pybind11)
pybind11_add_module(srcfile src/srcfile.cpp)

target_include_directories(srcfile PRIVATE include/)
target_link_libraries(srcfile PUBLIC ${TORCH_LIBRARIES})

set_property(TARGET srcfile PROPERTY CXX_STANDARD 14)

and at last test.py

import torch
from MyProj.cpp.build import srcfile as j

def main():
    t1 = torch.rand(2,2)
    t2 = torch.rand(2,2)
    print(j.test(t1, t2))


if __name__ == '__main__':
    main()

Inside the build directory I am executing the following command at the terminal:

cmake .. \
-DPYTHON_INCLUDE_DIR=$(python -c "from distutils.sysconfig import get_python_inc; print(get_python_inc())")  \
-DPYTHON_LIBRARY=$(python -c "import distutils.sysconfig as sysconfig; print(sysconfig.get_config_var('LIBDIR'))") \
-DTORCH_LIBRARIES=lib/libtorch && make

which does not emit any error. I get the error only when I am attempting to import.

I am not sure what I am doing wrong here. Any help/suggestion is welcome.

output of ldd srcfile.so

linux-vdso.so.1 (0x00007ffc893da000)
libtorch_cpu.so => /home/cppNpython/MyProj/cpp/lib/libtorch/lib/libtorch_cpu.so (0x00007f0183880000)
libtorch.so => /home/cppNpython/MyProj/cpp/lib/libtorch/lib/libtorch.so (0x00007f0199db7000)
libc10.so => /home/cppNpython/MyProj/cpp/lib/libtorch/lib/libc10.so (0x00007f0199d3a000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f01834f7000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f01832df000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f0182eee000)
libgomp-52f2fd74.so.1 => /home/cppNpython/MyProj/cpp/lib/libtorch/lib/libgomp-52f2fd74.so.1 (0x00007f0182cbb000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f0182a9c000)
librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f0182894000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f0182690000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f01822f2000)
/lib64/ld-linux-x86-64.so.2 (0x00007f0199c2d000)

Upvotes: 1

Views: 4211

Answers (1)

unddoch
unddoch

Reputation: 6004

This seems like an ABI issue - you can see the missing symbol contains std::__cxx11::basic_string which means your library is built with the "new" std::string ABI. To my understanding torch is usually built with D_GLIBCXX_USE_CXX11_ABI=0 and the old ABI.

You can add add_definitions(-D_GLIBCXX_USE_CXX11_ABI=0) to your cmake file or configure your torch compilation to use the new ABI.

Upvotes: 0

Related Questions