For a project that I am working on, I need to call from C++ a Python function, which has as input a PyTorch Tensor. While searching for a way to achieve this, I found that using a function named THPVariable_Wrap (Information I have found link 1 and link 2) could transform a C++ Pytorch Tensor to a PyObject, which can be used as input for the call to the Python function. However, I have tried importing this function by including the header file directly in my code, but this will always return the error LNK2019, when calling the function, with the following description:
Severity Code Description Project File Line Suppression State Error LNK2019 unresolved external symbol "__declspec(dllimport) struct _object * __cdecl THPVariable_Wrap(class at::TensorBase)" (_imp?THPVariable_Wrap@@YAPEAU_object@@VTensorBase@at@@@Z) referenced in function main pythonCppTorchExp C:\Users\MyName\source\repos\pythonCppTorchExp\pythonCppTorchExp\example-app.obj 1
I believe the problem is in how I import the THPVariable_Wrap function in my C++ file. However, I am still not that skilled with C++ and the information on this is limited. Besides Pytorch, I am also using Boost for calling Python and I am using Microsoft Visual Studio 2019 (v142), with C++ 14. I posted the code I used below.
C++ File
#include <iostream>
#include <iterator>
#include <algorithm>
#include <boost/python.hpp>
#include <Python.h>
#include <string.h>
#include <fstream>
#include <boost/filesystem.hpp>
#include <torch/torch.h>
#include <torch/csrc/autograd/python_variable.h> /* The header file where */
namespace python = boost::python;
namespace fs = boost::filesystem;
using namespace std;
int main() {
string module_path = "Path/to/python/folder";
Py_Initialize();
torch::Tensor cppTensor = torch::ones({ 100 });
PyRun_SimpleString(("import sys\nsys.path.append(\"" + module_path + "\")").c_str());
python::object module = python::import("tensor_test_file");
python::object python_function = module.attr("tensor_equal");
PyObject* castedTensor = THPVariable_Wrap(cppTensor) /* This function call creates the error.*/;
python::handle<> boostHandle(castedTensor);
python::object inputTensor(boostHandle);
python::object result = python_function(inputTensor);
bool succes = python::extract<bool>(result);
if (succes) {
cout << "The tensors match" << endl;
}
else {
cout << "The tensors do not match" << endl;
}
}
Python File
import torch
def tensor_equal(cppTensor):
pyTensor = torch.ones(100)
areEqual = cppTensor.equal(pyTensor)
return areEqual