0

I am trying to build a c++/cuda extension with Pytorch following the tutorial here, (with instructions how to use pytorch with c++ here). My environment details are:

  • Using Microsoft Visual Studio 2019 version 16.6.5
  • Windows 10
  • libtorch c++ debug 1.70 with cuda 11.0 installed from the pytorch website

I am using this cmake code where I set the include directory for python 3.6 and the library for python36.lib

cmake_minimum_required (VERSION 3.8)

project ("DAConvolution")

find_package(Torch REQUIRED)

# Add source to this project's executable.
add_executable (DAConvolution "DAConvolution.cpp" "DAConvolution.h")

include_directories("C:/Users/James/Anaconda3/envs/masters/include")
   
target_link_libraries(DAConvolution "${TORCH_LIBRARIES}" "C:/Users/James/Anaconda3/envs/masters/libs/python36.lib")

if (MSVC)
  file(GLOB TORCH_DLLS "${TORCH_INSTALL_PREFIX}/lib/*.dll")
  add_custom_command(TARGET DAConvolution
                     POST_BUILD
                     COMMAND ${CMAKE_COMMAND} -E copy_if_different
                     ${TORCH_DLLS}
                     $<TARGET_FILE_DIR:DAConvolution>)
endif (MSVC)

I set the CMake command arguments to be -DCMAKE_PREFIX_PATH=C:\libtorch (my path to libtorch debug mentioned above). I am building with the x64-debug option in MSVC version (as building with the x-64 Release option gives me a torch-NOTFOUND error).

The example DAConvolution.cpp file is:

#ifdef _DEBUG
#undef _DEBUG
#include <python.h>
#define _DEBUG
#else
#include <python.h>
#endif

#include <torch/extension.h>

Where I have undefined the _DEBUG flag so that the linker does not look for the python36_d.lib file (which I do not have).

I am getting a linking error:

enter image description here

Simply including torch.h works fine, but when I want to include the extension header thats when I get these problems, as it uses Pybind 11 I believe. Any insights much appreciated. I have tried to include all the info I can, but would be happy to give more information.

IntegrateThis
  • 853
  • 2
  • 16
  • 39
  • 1
    I'm doubtful that `add_executable` is what you want here. You're mixing instructions pertaining to building an extension to pytorch with instructions for building an application that links to pytorch C++ interface. I think it's more likely you want `add_library` – Robert Crovella Nov 02 '20 at 23:33
  • 1
    Undefined main means you are trying to compile an executable out of code not designed to be compiled as an executable – talonmies Nov 02 '20 at 23:39
  • @RobertCrovella ok this makes sense. It just seems that I want to be able to debug the pytorch extension in MSVC (ideally the .cu files as well). Sorry for the confusion. – IntegrateThis Nov 02 '20 at 23:57
  • @RobertCrovella if you post this as an answer I will accept it. – IntegrateThis Nov 03 '20 at 00:07
  • 1
    If you explain what you did to fix the issue or achieve your goal, I'm sure it will be more useful to future readers than my simple comment. I haven't tested anything or tried to recreate what you are doing, so you are in a far better position here than I. On SO, it's OK to answer your own question. – Robert Crovella Nov 03 '20 at 00:11

1 Answers1

2

For Windows and with Visual studio, you are better to work with the Visual Studio rather than the CMake.

Just create a simple Console Application, go to the project's Properties, change the Configuration type to Dynamic Library (dll), Configure the include and Library directories, add the required enteries to your linker in Linker>Input (such as torch.lib, torch_cpu.lib, etc) and you are good to go click build, and if you have done everything correctly you'll get yourself a dll that you can use (e.g loading it using torch.classes.load_library from Python and use it.

The Python debug version is not shipped with Anaconda/ normal python distribution, but if you install the Microsoft Python distribution which I believe can be downloaded/installed from Visual Studio installer, its available.
Also starting from Python 3.8 I guess the debug binaries are also shipped.
In case they are not, see this.
For the cmake part you can follow something like the following. This is a butchered version taken from my own cmake that I made for my python extension some time ago.

Read it and change it based on your own requirements it should be straight forward :

# NOTE:‌
# TORCH_LIB_DIRS needs to be set. When calling cmake you can specify them like this:
# cmake -DCMAKE_PREFIX_PATH="somewhere/libtorch/share/cmake" -DTORCH_LIB_DIRS="/somewhere/lib" ..

cmake_minimum_required(VERSION 3.1 FATAL_ERROR)
project(DAConvolution)

find_package(Torch REQUIRED)
# we are using the C++17, if you are not change this or remove it altogether
set(CMAKE_CXX_STANDARD 17)

#define where your headers and libs are, specify for example where your DaConvolution.h resides!
include_directories( somewhere/Yourinclude_dir ${TORCH_INCLUDE_DIRS})

set(DAConvolution_SRC ./DAConvolution.cpp )

LINK_DIRECTORIES(${TORCH_LIB_DIRS})

add_library(
    DAConvolution
    SHARED
    ${DAConvolution_SRC}
  )

# if you use some custom libs, you previously built, specify its location here
# target_link_directories(DAConvolution PRIVATE somewhere/your_previously_built_stuff/libs)
target_link_libraries(DAConvolution ${TORCH_LIB_DIRS}/libc10.so)
target_link_libraries(DAConvolution ${TORCH_LIB_DIRS}/libtorch_cpu.so)

install(TARGETS DAConvolution LIBRARY DESTINATION lib )

Side note:
I made the cmake for Linux only, so under Windows, I always use Visual Studio (2019 to be exact), in the same way I explained earlier. its by far the best /easiest approach imho. Suit yourself and choose either of them that best fits your problem.

Hossein
  • 24,202
  • 35
  • 119
  • 224
  • Since I am trying ultimately to code/debug a c++ pytorch extension, in particular a custom function (with custom forward and backwards implementations ultimately drawing from CUDA api calls in c++), I am curious why a torchsript dll is what I should be building? Thank you very much for the help, I will study your answer in the next coming days. – IntegrateThis Nov 03 '20 at 05:03
  • 1
    as you already know basically when it comes to building extensions for torch, you either need to go torchscript/torch extension, or pybind11. I myself found the torchscript/extension scenario easier, as you only have to create a class and expose it and everything is built as a dll which in VS is very easy to do. For Pybind11, I had to use a `setup.py` and build the very same extension, which are quit similar(torchextension is basically a pybind11 lookalike). However the setup part was/is kind of a headache for me. – Hossein Nov 03 '20 at 05:27
  • 1
    Also have a look [here](https://pytorch.org/tutorials/advanced/torch_script_custom_ops.html) and [here](https://pytorch.org/tutorials/advanced/torch_script_custom_classes.html). – Hossein Nov 03 '20 at 05:28
  • @Rika I've run into this issue. Any references on the pybind11-based approach, as opposed to the Torchscript extension? – Pranav Vempati Mar 28 '21 at 09:44