How to link libs when compiling my own codes based on C API?

I am trying to understand the underlying implementation of Pytorch following this blog and here is a toy example:

// THlearning.c
#include <TH/TH.h>

int main()
{
    THFile *x_file = THDiskFile_new("x", "r", 0);
    THFile *y_file = THDiskFile_new("y", "r", 0);

    THFloatTensor *x = THFloatTensor_newWithSize1d(10);
    THFloatTensor *y = THFloatTensor_newWithSize1d(10);

    THFile_readFloat(x_file, x->storage);
    THFile_readFloat(y_file, y->storage);

    double result = THFloatTensor_dot(x, y) + THFloatTensor_sumall(x);

    printf("%f\n", result);

    THFloatTensor_free(x);
    THFloatTensor_free(y);
    THFile_free(x_file);
    THFile_free(y_file);
    return 0;
}

when I tried to compile this short code, link error occured:

clang: warning: treating ‘c’ input as ‘c++’ when in C++ mode, this behavior is deprecated [-Wdeprecated]
Undefined symbols for architecture x86_64:
“_THDiskFile_new”, referenced from:
_main in THlearning-1f17a7.o
“_THFile_free”, referenced from:
_main in THlearning-1f17a7.o
“_THFile_readFloat”, referenced from:
_main in THlearning-1f17a7.o
“_THFloatTensor_dot”, referenced from:
_main in THlearning-1f17a7.o
“_THFloatTensor_free”, referenced from:
_main in THlearning-1f17a7.o
“_THFloatTensor_newWithSize1d”, referenced from:
_main in THlearning-1f17a7.o
“_THFloatTensor_sumall”, referenced from:
_main in THlearning-1f17a7.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

My platform is MacOS and the version of Pytorch is 0.2, installed through Anaconda on Python2.7

I failed to link the missed libs manually and my modification on .bash_profile is:

# added by Anaconda2 4.4.0 installer
export PATH="/Users/$MYUSERNAME/anaconda/bin:$PATH"

# gcc head files
C_INCLUDE_PATH=$C_INCLUDE_PATH:/Users/$MYUSERNAME/anaconda/lib/python2.7/site-     packages/torch/lib/include:/Users/$MYUSERNAME/anaconda/include:/Users/$MYUSERNAME/anaconda/lib/python2.7/site-packages/torch/utils/ffi/../../lib/include/TH:/Users/$MYUSERNAME/anaconda/include/python2.7
export C_INCLUDE_PATH

# g++ head files
CPLUS_INCLUDE_PATH=$CPLUS_INCLUDE_PATH:/Users/$MYUSERNAME/anaconda/lib/python2.7/site-packages/torch/lib/include:/Users/$MYUSERNAME/anaconda/include:/Users/$MYUSERNAME/anaconda/lib/python2.7/site-packages/torch/utils/ffi/../../lib/include/TH:/Users/$MYUSERNAME/anaconda/include/python2.7
export CPLUS_INCLUDE_PATH

LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/Users/$MYUSERNAME/anaconda/lib/python2.7/site-packages/torch/lib
export LD_LIBRARY_PATH

LIBRARY_PATH=$LIBRARY_PATH:/Users/$MYUSERNAME/anaconda/lib/python2.7/site-packages/torch/lib
export LIBRARY_PATH

I hope someone can help me solve this problem…

you need to link your c++ program against libTH.dylib that is present in /Users/$MYUSERNAME/anaconda/lib/python2.7/site-packages/torch/lib

Hello,
I’m on Ubuntu 16.04, I installed Pytorch from source, following the instructions here GitHub - pytorch/pytorch: Tensors and Dynamic neural networks in Python with strong GPU acceleration.
I was surprised that there is no libTH.* in /home/$MYUSERNAME/anaconda/lib/python3.6/site-packages/torch/lib
The only files there are :

include/
libcaffe2_gpu.so
libcaffe2_gpu.so.1
libcaffe2.so
libcaffe2.so.1
libnccl.so
libnccl.so.1
libshm.so
THCUNN.h
THNN.h
torch_shm_manager

I had to build torch7 from source like described here #include <TH/TH.h>, and I got a libTH.so
Is there a reason that when building torch from pytorch, it doesn’t build the libTH.* library ?
Is there an option that I missed when building pytorch ?
Thank you.

1 Like

I think they’ve moved things around, so it’s probably called libcaffe2.so now, following merge with caffe. I too am interested in the reason though. (note: personally, I see libATen.so, but I’m assuming that’s because I have pytorch 0.4, and you maybe have 0.5?)

Oh yes I did build master (c44626956), not the stable 0.4.0.
I tried again with 0.4.0, and yes, libATen.so replaced the libcaffe2* :

include/
libATen.so
libnccl.so
libnccl.so.1
libshm.so
THCUNN.h
THNN.h
torch_shm_manager

So, since I’m trying to implement a function in C/C++, I’m confused about which library I should use.
Right now I use torch, meaning I #include <TH/TH.h> and link against libTH.so (built with torch7 on its own)

I see that ATen is “new” and that it is a C++11 wrapper of pytorch and torch functions.
Should I use ATen then ? But ATen also contains the TH.h header and the torch code it seems like.
What is the difference between ATen and torch ?

If I understand correctly :
torch : the lib is called libTH.so
pytorch 0.4.0 : the lib is called libATen.so
pytorch > 0.4.0 : the libs will be called libcaffe2*

I read about Caffe2 on the blogpost :

On the backend side of things, PyTorch will see some changes, which might affect user-written C and C++ extensions. We are replacing (or refactoring) the backend ATen library to incorporate features and optimizations from Caffe2.

Will Caffe2 still use the same functions as in ATen and torch (e.g. THFloatTensor_newWithSize1d()) ?
Or will I have to change the code completely ?

nm is a very nice tool to inspect .sos:

nm ~/conda/lib/python3.6/site-packages/torch/lib/libATen.so | grep newWithSize1d
0000000001582a20 T THByteTensor_newWithSize1d
0000000001585460 T THCharTensor_newWithSize1d
0000000001b49e20 T THCSByteTensor_newWithSize1d
0000000001b4b2a0 T THCSCharTensor_newWithSize1d
0000000001b52da0 T THCSDoubleTensor_newWithSize1d
0000000001b51920 T THCSFloatTensor_newWithSize1d
0000000001b504a0 T THCSHalfTensor_newWithSize1d
0000000001b4dba0 T THCSIntTensor_newWithSize1d
0000000001b4f020 T THCSLongTensor_newWithSize1d
0000000001b4c720 T THCSShortTensor_newWithSize1d
0000000001b2e0d0 T THCudaByteTensor_newWithSize1d
0000000001b30b70 T THCudaCharTensor_newWithSize1d
0000000001b40b60 T THCudaDoubleTensor_newWithSize1d
0000000001b3b610 T THCudaHalfTensor_newWithSize1d
0000000001b360d0 T THCudaIntTensor_newWithSize1d
0000000001b38b70 T THCudaLongTensor_newWithSize1d
0000000001b33620 T THCudaShortTensor_newWithSize1d
0000000001b3e0b0 T THCudaTensor_newWithSize1d
000000000157ffd0 T THDoubleTensor_newWithSize1d
000000000157d500 T THFloatTensor_newWithSize1d
000000000158f9b0 T THHalfTensor_newWithSize1d
000000000158a8e0 T THIntTensor_newWithSize1d
000000000158d320 T THLongTensor_newWithSize1d
0000000001ad3690 T THSByteTensor_newWithSize1d
0000000001ad4b70 T THSCharTensor_newWithSize1d
0000000001adb450 T THSDoubleTensor_newWithSize1d
0000000001ad9f50 T THSFloatTensor_newWithSize1d
0000000001587ea0 T THShortTensor_newWithSize1d
0000000001ad7550 T THSIntTensor_newWithSize1d
0000000001ad8a50 T THSLongTensor_newWithSize1d
0000000001ad6050 T THSShortTensor_newWithSize1d

The TH level C-API is being nuked, it probably wont be around by the time the next major release of PyTorch happens.

You should move to using the ATen API. Look at examples in https://github.com/pytorch/pytorch/tree/master/aten/src/ATen/native or this page: https://pytorch.org/tutorials/advanced/cpp_extension.html for rough usage of the API.
The ATen API mirrors the PyTorch’s python API pretty closely in C++11.

2 Likes

This is all very helpful, thank you for the update ! :slight_smile: