How to create a Python package with C++ extension depending on torch and libtorch

Hello,

I am working on an open-source project called ReLab. It is coded in python (package is named relab) but contains a C++ extension (named librelab.so) to take advantage of multi-threading. The python package relab depends on the python package torch, while the C++ extension depends on the C++ extension of pytorch libtorch.so.

I would like to make the project available on PyPI. How can I achieve that?

I am currently using a combination of poetry, cmake, pybind11, and scikit-build. But while I managed to build and publish the package to PyPI, when installing it with pip, I get linker errors:

ImportError: /home/theophile/Desktop/poetry/TestingReLab/relab-venv/lib/python3.12/site-packages/relab/librelab.so: undefined symbol: _ZNK3c1011StorageImpl27throw_data_ptr_access_errorEv

This is caused by the fact that libtorch.so is not linked properly as shown below:

> ldd relab-venv/lib/python3.12/site-packages/relab/librelab.so                        
	linux-vdso.so.1 (0x00007fffc11b1000)
	libtorch.so => not found
	libc10.so => not found
	libc10_cuda.so => not found
	libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007afed882b000)
	libpython3.12.so.1.0 => /lib/x86_64-linux-gnu/libpython3.12.so.1.0 (0x00007afed7e00000)
	libtorch_cpu.so => not found
	libtorch_cuda.so => not found
	libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007afed7a00000)
	libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007afed8740000)
	libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007afed8712000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007afed7600000)
	libexpat.so.1 => /lib/x86_64-linux-gnu/libexpat.so.1 (0x00007afed86e5000)
	/lib64/ld-linux-x86-64.so.2 (0x00007afed88c6000)

What I am trying to achieve is similar to the following post but with pytorch instead of QT.

1 Like

Bundle libtorch.so?

I’ve just downloaded torch-2.6.0-cp313-cp313-manylinux1_x86_64.whl, renamed it to zip and searched inside it. I couldn’t find libtorch.so inside (using Windows 11 explorer, which proves nothing), so don’t you have to ship this file anyway?

It’s possible to dynamically link a .so from another one, as long as the relative dir to it is known. I’d love to learn of a more elegant way of manipulating paths in C++, but in a C++ extension based around .dlls or .sos (packaged into wheels for each platform) I used:

		Dl_info dlInfo;
		dladdr((void *)&a_static_class_function, &dlInfo);

		string path(dlInfo.dli_fname);

		size_t i = path.find_last_of('/');

		string dir = path.substr(0,i);

		string geos_dll_path_w = dir + "/libgeos_c.so";

        // ...

		dlerror();
		hDLL = dlopen(geos_dll_path_w.c_str(), RTLD_LAZY);

        // Check dlerror() for error a second time, and handle hDLL == null


	    initGEOS = (initGEOS_t)GetProcAddress(hDLL,"initGEOS");

This is a PyTorch specific question, so I think Dynamically loading symbols from libtorch.so - C++ - PyTorch Forums (which is the same question as this one, also from you posted in the last 24 hours) is the better place to ask.

Depending on the details of how you’re building the extension depending on libtorch, you’ll need something like torch.ops.load_library or torch.library.* to ensure your extension is registered and finds the necessary pieces.

You may also be able to look at a package like torchvision, which has C++/CUDA extensions that depend on libtorch and ships wheels on PyPI.

Definitely don’t do that - it’s hundreds of MBs.

Definitely don’t do that - it’s hundreds of MBs.

Is it definitely in the Torch Linux wheels then?

yes it will be, it’s a core part of PyTorch itself, and other packages already rely on it

I thought that too. The search function I used just doesn’t work within zip files (I’ve now unzipped the wheel).

If libtorch.so really is all that’s needed, then that it’s only 192kB in this wheel However it itself probably links to either libtorch_cpu.so (430MB) or libtorch_cuda.sp (880MB).

@JamesParrott @rgommers

Thanks so much for your fast reply, it is really helpful! I have been busy with other projects, but a friend of mine will probably try these out shortly, we will keep you posted.

Sorry, for posting here, I wasn’t quite sure where the best place was, and I was hoping that the answer would be general enough to apply to any .so/dll libraries.

1 Like