Libtorch使用g ++,但使用Intel编译器时失败 [英] Libtorch works with g++, but fails with Intel compiler
问题描述
我想在Fortran程序中使用以Python(PyTorch)开发的神经网络.我的操作系统是Ubuntu 18.04.
I want to use a neural network developed in Python (PyTorch) in a Fortran program. My OS is Ubuntu 18.04.
我在做什么:
- 将其另存为火炬脚本:TurbNN.pt
- 从c ++程序中调用它:call_ts.cpp,call_ts.h
- 从Fortran程序中调用c ++程序(使用bind©):main.f90
我成功使用CMake(3.19.4)和g ++(7.5.0)编译了代码.但是,我无法使用Intel编译器(HPCKit 2021.1.0.2684)对其进行编译:
I successfully compiled the codes using CMake (3.19.4) and g++ (7.5.0). However, I cannot compile them using Intel compilers (HPCKit 2021.1.0.2684):
# downloaded torchlib
export Torch_DIR=/home/aiskhak/nn/fortran_calls_torchscript3/build/libtorch/share/cmake/Torch/
# set environment for Intel compilers
. /opt/intel/oneapi/setvars.sh
# cmake
cmake \
-DCMAKE_CXX_COMPILER=icpc \
-DCMAKE_Fortran_COMPILER=ifort ..
# make
make
在"cmake"之后,一切看起来都很好(就像g ++一样):
After "cmake" everything looks fine (just like for g++):
-- The CXX compiler identification is Intel 20.2.1.20201112
-- The Fortran compiler identification is Intel 20.2.1.20201112
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /opt/intel/oneapi/compiler/2021.1.1/linux/bin/intel64/icpc - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Detecting Fortran compiler ABI info
-- Detecting Fortran compiler ABI info - done
-- Check for working Fortran compiler: /opt/intel/oneapi/compiler/2021.1.1/linux/bin/intel64/ifort - skipped
-- Checking whether /opt/intel/oneapi/compiler/2021.1.1/linux/bin/intel64/ifort supports Fortran 90
-- Checking whether /opt/intel/oneapi/compiler/2021.1.1/linux/bin/intel64/ifort supports Fortran 90 - yes
-- Looking for C++ include pthread.h
-- Looking for C++ include pthread.h - found
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Failed
-- Looking for pthread_create in pthreads
-- Looking for pthread_create in pthreads - not found
-- Looking for pthread_create in pthread
-- Looking for pthread_create in pthread - found
-- Found Threads: TRUE
-- Found Torch: /home/aiskhak/nn/fortran_calls_torchscript3/build/libtorch/lib/libtorch.so
-- Performing Test COMPILER_HAS_HIDDEN_VISIBILITY
-- Performing Test COMPILER_HAS_HIDDEN_VISIBILITY - Success
-- Performing Test COMPILER_HAS_HIDDEN_INLINE_VISIBILITY
-- Performing Test COMPILER_HAS_HIDDEN_INLINE_VISIBILITY - Success
-- Performing Test COMPILER_HAS_DEPRECATED_ATTR
-- Performing Test COMPILER_HAS_DEPRECATED_ATTR - Success
-- Configuring done
-- Generating done
-- Build files have been written to: /home/aiskhak/nn/fortran_calls_torchscript3/build
但是,在"make"之后,我得到了:
However, after "make" I am getting:
Scanning dependencies of target call_ts_cpp
[ 25%] Building CXX object CMakeFiles/call_ts_cpp.dir/src/call_ts.cpp.o
[ 50%] Linking CXX shared library lib/libcall_ts_cpp.so
[ 50%] Built target call_ts_cpp
Scanning dependencies of target fortran_calls_ts.x
[ 75%] Building Fortran object CMakeFiles/fortran_calls_ts.x.dir/src/main.f90.o
[100%] Linking Fortran executable bin/fortran_calls_ts.x
lib/libcall_ts_cpp.so: undefined reference to `c10::Error::Error(c10::SourceLocation, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)'
lib/libcall_ts_cpp.so: undefined reference to `torch::jit::load(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, c10::optional<c10::Device>, std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >&)'
lib/libcall_ts_cpp.so: undefined reference to `c10::DeviceTypeName[abi:cxx11](c10::DeviceType, bool)'
lib/libcall_ts_cpp.so: undefined reference to `torch::jit::Object::find_method(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) const'
lib/libcall_ts_cpp.so: undefined reference to `torch::jit::Method::operator()(std::vector<c10::IValue, std::allocator<c10::IValue> >, std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, c10::IValue, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, c10::IValue> > > const&)'
CMakeFiles/fortran_calls_ts.x.dir/build.make:106: recipe for target 'bin/fortran_calls_ts.x' failed
make[2]: *** [bin/fortran_calls_ts.x] Error 1
CMakeFiles/Makefile2:123: recipe for target 'CMakeFiles/fortran_calls_ts.x.dir/all' failed
make[1]: *** [CMakeFiles/fortran_calls_ts.x.dir/all] Error 2
Makefile:148: recipe for target 'all' failed
make: *** [all] Error 2
我应该怎么做?我有旧的g ++时就解决了类似的问题,但是我的Intel编译器是新的.
What I am supposed to do with? I fixed similar problem when I had old g++, but my Intel compiler is new.
下面是我的代码:
call_ts.cpp
call_ts.cpp
#include "call_ts.h"
#include <torch/script.h>
#include <iostream>
#include <memory>
// c++ function invariant_nn
//
// takes inputs, reads a neural network TurbNN.pt, do a forward pass
// and returns outputs
//
// inputs: 5 tensor invariants I[0:4] (float)
// outputs: 10 tensor basis coefficients G[0:9] (float)
void invariant_nn(float I[], float G[])
{
// deserialize scriptmodule from a .pt file
torch::jit::script::Module module;
const char *arg;
arg = "../src/TurbNN.pt";
module = torch::jit::load(arg);
// create inputs
std::vector<torch::jit::IValue> inputs;
float data[] = {I[0], I[1], I[2], I[3], I[4]};
inputs.push_back(torch::from_blob(data, {1, 5}));
//std::cout << "inputs\n" << inputs;
//std::cout << "\n";
// do forward pass and turn its output into a tensor
at::Tensor outputs = module.forward(inputs).toTensor();
//std::cout << "outputs\n" << outputs;
//std::cout << "\n";
// return values
for (int k = 0; k < 10; k++) {
G[k] = outputs[0][k].item().to<float>();
//std::cout << "G\n" << G[k];
}
return;
}
call_ts.h
call_ts.h
#pragma once
/* export macros for library generated by CMake */
#ifndef CALL_TS_API
#include "call_ts_export.h"
#define CALL_TS_API CALL_TS_EXPORT
#endif
#ifdef __cplusplus
extern "C" {
#endif
CALL_TS_API
void invariant_nn(float I[], float G[]);
#ifdef __cplusplus
}
#endif
主要.f90
! fortran program main
!
! calls c++ function invariant_nn, which calls a torchscript with
! a neural network
!
program main
! define interface to interact with c++
use, intrinsic :: iso_c_binding, only: c_float
implicit none
interface invariant_nn
subroutine invariant_nn(I, G) bind (c)
import :: c_float
real(c_float) :: I(5)
real(c_float) :: G(10)
end subroutine
end interface
! fortran program
real(4) I(5), G(10)
! invariants
I(1) = 1.01
I(2) = 1.01
I(3) = 1.01
I(4) = 1.01
I(5) = 1.01
print *, "Tensor invariants ", I
! tensor basis coefficients
call invariant_nn(I, G)
print *, "Tensor basis coefficients ", G
end program main
CMakeLists.txt
CMakeLists.txt
# stop configuration if cmake version is below 3.0
cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
# project name and enabled languages
project(fortran_calls_ts CXX Fortran)
# find libtorch
find_package(Torch REQUIRED)
# if CMAKE_BUILD_TYPE undefined, set it to Release
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Release")
endif()
# compiler flags for release mode
set(CMAKE_CXX_FLAGS_RELEASE "-O3")
set(CMAKE_Fortran_FLAGS_RELEASE "-O3")
# set default build paths
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib)
# generated export header will be placed here
include_directories(${PROJECT_BINARY_DIR})
# c library
add_library(call_ts_cpp SHARED src/call_ts.cpp)
# fortran executable
add_executable(fortran_calls_ts.x src/main.f90)
# linked against c library
target_link_libraries(fortran_calls_ts.x call_ts_cpp)
target_link_libraries(call_ts_cpp "${TORCH_LIBRARIES}")
# we let cmake generate the export header
include(GenerateExportHeader)
generate_export_header(call_ts_cpp BASE_NAME call_ts)
install(TARGETS call_ts_cpp LIBRARY DESTINATION lib ARCHIVE DESTINATION lib)
install(FILES src/call_ts.h ${PROJECT_BINARY_DIR}/call_ts_export.h DESTINATION include)
set_property(TARGET fortran_calls_ts.x PROPERTY CXX_STANDARD 14)
推荐答案
您是否在链接器错误中看到 cxx11
?看来您的 libcall_ts_cpp
的编译方式期望为std :: string使用新的C ++ 11 ABI,但可能使用旧的ABI编译了实现这些功能的库.这是有关相同问题的PyTorch论坛帖子:
Do you see cxx11
in the linker errors? It looks like your libcall_ts_cpp
is compiled in a way that expects the new C++11 ABI for std::string but perhaps the library where those functions are implemented was compiled with the old ABI. Here's a PyTorch forum post about the same problem: https://discuss.pytorch.org/t/issues-linking-with-libtorch-c-11-abi/29510/11
解决方案是下载使用新的C ++ 11 ABI构建的PyTorch库的新副本.
The solution is to download a new copy of the PyTorch libraries built with the new C++11 ABI.
这篇关于Libtorch使用g ++,但使用Intel编译器时失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!