Error returning c++ tensor to pytorch

alfie-nsugh: <p>I have been trying to get a libtorch tensor to return so that I can use it in pytorch but it keeps failing.</p>
<pre><code class="lang-auto">#include &lt;iostream&gt;
//#include &lt;cuda_runtime.h&gt;
//#include &lt;torch/torch.h&gt;
//#include &lt;ATen/ATen.h&gt;
#include &lt;pybind11/pybind11.h&gt;
#include &lt;torch/extension.h&gt;

struct MyData {
    float x, y, z, w;
};

struct MyMat4{
	MyData rows[4];
};

namespace py = pybind11;

void create_mat(MyMat4&amp; mat);
torch::Tensor create_tensor(){
    //MyMat4 mat;
    //create_mat(mat);

    ////move data to device
    //MyMat4 *d_mat;
    //cudaMalloc((void **)&amp;d_mat, sizeof(MyMat4));
    //cudaMemcpy(d_mat, &amp;mat, sizeof(MyMat4), cudaMemcpyHostToDevice);

    //torch::TensorOptions options_cuda = torch::TensorOptions().dtype(torch::kFloat31).device(torch::kCUDA, 0);
    torch::TensorOptions options_cpu = torch::TensorOptions().dtype(torch::kFloat32);

    ////torch::Tensor tensor_cuda = torch::from_blob(d_mat, {4, 4}, options_cuda);
    //torch::Tensor tensor_cpu = torch::from_blob(mat.rows, {4, 4},options_cpu);

    ////std::cout &lt;&lt; "tensor_cuda: " &lt;&lt; std::endl &lt;&lt; tensor_cuda &lt;&lt; std::endl;

    std::cout &lt;&lt; "libtorch version: " &lt;&lt; TORCH_VERSION &lt;&lt; std::endl;
    //return tensor_cpu;
    return torch::zeros({4,4}, options_cpu);
    //std::cout &lt;&lt; "tensor_zerps: " &lt;&lt; std::endl &lt;&lt; torch::zeros({4,4}) &lt;&lt; std::endl;
    //return 0;
}


void create_mat(MyMat4&amp; mat){

    mat.rows[0].x = 1.0f;
    mat.rows[0].y = 2.0f;
    mat.rows[0].z = 3.0f;
    mat.rows[0].w = 4.0f;

    mat.rows[1].x = 5.0f;
    mat.rows[1].y = 6.0f;
    mat.rows[1].z = 7.0f;
    mat.rows[1].w = 8.0f;

    mat.rows[2].x = 9.0f;
    mat.rows[2].y = 10.0f;
    mat.rows[2].z = 11.0f;
    mat.rows[2].w = 12.0f;

    mat.rows[3].x = 13.0f;
    mat.rows[3].y = 14.0f;
    mat.rows[3].z = 15.0f;
    mat.rows[3].w = 16.0f;
}


PYBIND11_MODULE(tensor_export, m) {
    m.doc() = "pybind11 demo plugin"; // optional module docstring

    m.def("create_tensor", &amp;create_tensor, "A function that creates a tensor from a struct");

    //py::class_&lt;MyMat4&gt;(m, "PyMyMat4")
        //.def(py::init&lt;&gt;())
        //.def_readwrite("rows", &amp;MyMat4::rows);
}
</code></pre>
<p>When I modify the function to return an integer and return zero and just print the torch version it works. But if I return a tensor it fails.<br>
Giving me:</p>
<pre><code class="lang-auto">In [1]: import torch

In [2]: import tensor_export
---------------------------------------------------------------------------
ImportError                               Traceback (most recent call last)
&lt;ipython-input-2-9aca188a181e&gt; in &lt;module&gt;
----&gt; 1 import tensor_export

ImportError: /home/avi/demos/cuda_torch_pybind_demo/build/tensor_export.cpython-310-x86_64-linux-gnu.so: undefined symbol: _ZN8pybind116detail11type_casterIN2at6TensorEvE4castERKS3_NS_19return_value_policyENS_6handleE
</code></pre>
<ul>
<li>I tried the pytorch version using pip and libtorch version that is on the website.</li>
<li>I also tried compiling v2.1.0 from source using python setup.py install, and python setup.py build</li>
<li>And I also tried compiling v2.0.1 from source using python setup.py install, and python setup.py build<br>
This is my cmake:</li>
</ul>
<pre><code class="lang-auto">cmake_minimum_required(VERSION 3.18 FATAL_ERROR)
project(tensor_export LANGUAGES CXX CUDA)
enable_language(CUDA)
add_subdirectory(pybind11)

#set(CMAKE_PREFIX_PATH "/home/avi/libtorch")
set(CMAKE_PREFIX_PATH "/home/avi/pytorch/torch")
find_package(Torch REQUIRED)
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${TORCH_CXX_FLAGS} -fPIC")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${TORCH_CXX_FLAGS}")

find_package(Python3 COMPONENTS Development)
include_directories(${Python3_INCLUDE_DIRS})

pybind11_add_module(tensor_export MODULE libtorchPytorch.cpp)
# Link the PyTorch libraries and include directories
target_link_libraries(tensor_export PRIVATE ${TORCH_LIBRARIES})
target_include_directories(tensor_export PRIVATE ${TORCH_INCLUDE_DIRS})
#set_property(TARGET tensor_export PROPERTY CXX_STANDARD 17)


# The following code block is suggested to be used on Windows.
# According to https://github.com/pytorch/pytorch/issues/25457,
# the DLLs need to be copied to avoid memory errors.
if (MSVC)
  file(GLOB TORCH_DLLS "${TORCH_INSTALL_PREFIX}/lib/*.dll")
  add_custom_command(TARGET tensor_export
                     POST_BUILD
                     COMMAND ${CMAKE_COMMAND} -E copy_if_different
                     ${TORCH_DLLS}
                     $&lt;TARGET_FILE_DIR:tensor_export&gt;)
endif (MSVC)

</code></pre>
<p>I also compiled magma (magma-2.7.2) myself instead of using the conda environment. And I am using cudatoolkit 11.8 on WSL2.</p>

ptrblck: <p>I don’t know what <code>pybind11_add_module</code> does but the unresolved symbol is:</p>
<pre><code class="lang-auto">pybind11::detail::type_caster&lt;at::Tensor, void&gt;::cast(at::Tensor const&amp;, pybind11::return_value_policy, pybind11::handle)
</code></pre>
<p>Maybe you would need to add <code>pybind11</code> to <code>target_link_libraries</code>.</p>

alfie-nsugh: <p>Thanks for the advice, I tried it but unfortunately it didn’t work. However, when using the setup.py:</p>
<pre><code class="lang-auto">from setuptools import setup, Extension
from torch.utils import cpp_extension
from torch.utils.cpp_extension import BuildExtension, CUDAExtension

setup(name='tensor_export',
      ext_modules=[CUDAExtension('tensor_export', ['libtorchPytorch.cpp'])],
      cmdclass={'build_ext': cpp_extension.BuildExtension},
      )
</code></pre>
<p>It did work, so I guess problem solved. Just out of curiosity I tried looking at the compiler options in the make file as well as in the ninja file:</p>
<pre><code class="lang-auto">running build
running build_ext
building 'tensor_export' extension
Emitting ninja build file /home/avi/demos/cuda_torch_pybind_demo/build/temp.linux-x86_64-3.10/build.ninja...
Compiling objects...
Allowing ninja to set a default number of workers... (overridable by setting the environment variable MAX_JOBS=N)
[1/1] c++ -MMD -MF /home/avi/demos/cuda_torch_pybind_demo/build/temp.linux-x86_64-3.10/libtorchPytorch.o.d -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O2 -Wall -g -fstack-protector-strong -Wformat -Werror=format-security -g -fwrapv -O2 -g -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -fPIC -I/usr/local/lib/python3.10/dist-packages/torch/include -I/usr/local/lib/python3.10/dist-packages/torch/include/torch/csrc/api/include -I/usr/local/lib/python3.10/dist-packages/torch/include/TH -I/usr/local/lib/python3.10/dist-packages/torch/include/THC -I/usr/local/cuda/include -I/usr/include/python3.10 -c -c /home/avi/demos/cuda_torch_pybind_demo/libtorchPytorch.cpp -o /home/avi/demos/cuda_torch_pybind_demo/build/temp.linux-x86_64-3.10/libtorchPytorch.o -DTORCH_API_INCLUDE_EXTENSION_H '-DPYBIND11_COMPILER_TYPE="_gcc"' '-DPYBIND11_STDLIB="_libstdcpp"' '-DPYBIND11_BUILD_ABI="_cxxabi1016"' -DTORCH_EXTENSION_NAME=tensor_export -D_GLIBCXX_USE_CXX11_ABI=1 -std=c++17
x86_64-linux-gnu-g++ -shared -Wl,-O1 -Wl,-Bsymbolic-functions -Wl,-Bsymbolic-functions -g -fwrapv -O2 -Wl,-Bsymbolic-functions -g -fwrapv -O2 -g -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 /home/avi/demos/cuda_torch_pybind_demo/build/temp.linux-x86_64-3.10/libtorchPytorch.o -L/usr/local/lib/python3.10/dist-packages/torch/lib -L/usr/local/cuda/lib64 -lc10 -ltorch -ltorch_cpu -ltorch_python -lcudart -lc10_cuda -ltorch_cuda -o build/lib.linux-x86_64-3.10/tensor_export.cpython-310-x86_64-linux-gnu.so
</code></pre>
<pre><code class="lang-auto">/home/avi/.local/lib/python3.10/site-packages/cmake/data/bin/cmake -S/home/avi/demos/cuda_torch_pybind_demo -B/home/avi/demos/cuda_torch_pybind_demo/build --check-build-system CMakeFiles/Makefile.cmake 0
/home/avi/.local/lib/python3.10/site-packages/cmake/data/bin/cmake -E cmake_progress_start /home/avi/demos/cuda_torch_pybind_demo/build/CMakeFiles /home/avi/demos/cuda_torch_pybind_demo/build//CMakeFiles/progress.marks
make  -f CMakeFiles/Makefile2 all
make[1]: Entering directory '/home/avi/demos/cuda_torch_pybind_demo/build'
make  -f CMakeFiles/tensor_export.dir/build.make CMakeFiles/tensor_export.dir/depend
make[2]: Entering directory '/home/avi/demos/cuda_torch_pybind_demo/build'
cd /home/avi/demos/cuda_torch_pybind_demo/build &amp;&amp; /home/avi/.local/lib/python3.10/site-packages/cmake/data/bin/cmake -E cmake_depends "Unix Makefiles" /home/avi/demos/cuda_torch_pybind_demo /home/avi/demos/cuda_torch_pybind_demo /home/avi/demos/cuda_torch_pybind_demo/build /home/avi/demos/cuda_torch_pybind_demo/build /home/avi/demos/cuda_torch_pybind_demo/build/CMakeFiles/tensor_export.dir/DependInfo.cmake "--color="
make[2]: Leaving directory '/home/avi/demos/cuda_torch_pybind_demo/build'
make  -f CMakeFiles/tensor_export.dir/build.make CMakeFiles/tensor_export.dir/build
make[2]: Entering directory '/home/avi/demos/cuda_torch_pybind_demo/build'
[ 50%] Building CXX object CMakeFiles/tensor_export.dir/libtorchPytorch.cpp.o
/usr/bin/c++ -DUSE_C10D_GLOO -DUSE_C10D_MPI -DUSE_C10D_NCCL -DUSE_DISTRIBUTED -DUSE_RPC -DUSE_TENSORPIPE -Dtensor_export_EXPORTS -isystem /usr/include/python3.10 -isystem /usr/local/lib/python3.10/dist-packages/torch/include -isystem /usr/local/lib/python3.10/dist-packages/torch/include/torch/csrc/api/include -isystem /home/avi/demos/cuda_torch_pybind_demo/pybind11/include -isystem /usr/local/cuda/include -D_GLIBCXX_USE_CXX11_ABI=1 -fPIC -fvisibility=hidden -flto -fno-fat-lto-objects -D_GLIBCXX_USE_CXX11_ABI=1 -MD -MT CMakeFiles/tensor_export.dir/libtorchPytorch.cpp.o -MF CMakeFiles/tensor_export.dir/libtorchPytorch.cpp.o.d -o CMakeFiles/tensor_export.dir/libtorchPytorch.cpp.o -c /home/avi/demos/cuda_torch_pybind_demo/libtorchPytorch.cpp
[100%] Linking CXX shared module tensor_export.cpython-310-x86_64-linux-gnu.so
/home/avi/.local/lib/python3.10/site-packages/cmake/data/bin/cmake -E cmake_link_script CMakeFiles/tensor_export.dir/link.txt --verbose=1
/usr/bin/c++ -fPIC  -D_GLIBCXX_USE_CXX11_ABI=1 -flto -shared  -o tensor_export.cpython-310-x86_64-linux-gnu.so CMakeFiles/tensor_export.dir/libtorchPytorch.cpp.o  -Wl,-rpath,/usr/local/lib/python3.10/dist-packages/torch/lib:/usr/lib/wsl/lib:/usr/local/cuda/lib64 /usr/local/lib/python3.10/dist-packages/torch/lib/libtorch.so /usr/local/lib/python3.10/dist-packages/torch/lib/libc10.so /usr/lib/wsl/lib/libcuda.so /usr/local/cuda/lib64/libnvrtc.so /usr/local/cuda/lib64/libnvToolsExt.so /usr/local/cuda/lib64/libcudart.so /usr/local/lib/python3.10/dist-packages/torch/lib/libc10_cuda.so -Wl,--no-as-needed,"/usr/local/lib/python3.10/dist-packages/torch/lib/libtorch_cpu.so" -Wl,--as-needed -Wl,--no-as-needed,"/usr/local/lib/python3.10/dist-packages/torch/lib/libtorch_cuda.so" -Wl,--as-needed /usr/local/lib/python3.10/dist-packages/torch/lib/libc10_cuda.so /usr/local/lib/python3.10/dist-packages/torch/lib/libc10.so /usr/local/cuda/lib64/libcufft.so /usr/local/cuda/lib64/libcurand.so /usr/local/cuda/lib64/libcublas.so /usr/local/cuda/lib64/libcublasLt.so -Wl,--no-as-needed,"/usr/local/lib/python3.10/dist-packages/torch/lib/libtorch.so" -Wl,--as-needed /usr/local/cuda/lib64/libnvToolsExt.so /usr/local/cuda/lib64/libcudart.so 
/usr/bin/strip /home/avi/demos/cuda_torch_pybind_demo/build/tensor_export.cpython-310-x86_64-linux-gnu.so
make[2]: Leaving directory '/home/avi/demos/cuda_torch_pybind_demo/build'
[100%] Built target tensor_export
make[1]: Leaving directory '/home/avi/demos/cuda_torch_pybind_demo/build'
/home/avi/.local/lib/python3.10/site-packages/cmake/data/bin/cmake -E cmake_progress_start /home/avi/demos/cuda_torch_pybind_demo/build/CMakeFiles 0
</code></pre>
<p>But couldn’t really figure out why cmake doesn’t work but the setup.py does, but at least it works now.</p>

alfie-nsugh: <p>The user <strong><a href="https://github.com/woywoy123" rel="noopener nofollow ugc">woywoy123</a></strong> at github linked this project that uses cmake:</p><aside class="onebox githubfolder" data-onebox-src="https://github.com/r-barnes/pytorch_cmake_example/tree/main">
  <header class="source">
      <img src="https://github.githubassets.com/favicons/favicon.svg" class="site-icon" width="32" height="32">

      <a href="https://github.com/r-barnes/pytorch_cmake_example/tree/main" target="_blank" rel="noopener nofollow ugc">github.com</a>
  </header>

  <article class="onebox-body">
    <h3><a href="https://github.com/r-barnes/pytorch_cmake_example/tree/main" target="_blank" rel="noopener nofollow ugc">GitHub - r-barnes/pytorch_cmake_example</a></h3>

  <p><a href="https://github.com/r-barnes/pytorch_cmake_example/tree/main" target="_blank" rel="noopener nofollow ugc">main</a></p>

  <p><span class="label1">Contribute to r-barnes/pytorch_cmake_example development by creating an account on GitHub.</span></p>

  </article>

  <div class="onebox-metadata">
    
    
  </div>

  <div style="clear: both"></div>
</aside>

<p>I just tested it, and got it to work.</p>

1317257555: <p>Such problem is already solved in <a href="https://github.com/pytorch/pytorch/issues/108041#issuecomment-1753895665" rel="noopener nofollow ugc">https://github.com/pytorch/pytorch/issues/108041#issuecomment-1753895665</a></p>