用GCC和NVCC编译时Eigen::矩阵求逆的不同行为 [英] different behavior for eigen::matrix inversion when compiled with gcc and nvcc

查看:0
本文介绍了用GCC和NVCC编译时Eigen::矩阵求逆的不同行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用Eigen(让我们称之为inversion.cpp)进行矩阵求逆(下面提供的代码)。Inversion.cpp使用g++编译并给出正确的倒数。

现在我将代码名更改为Inversion.cu,并尝试使用NVCC进行编译。编译失败,出现一长串错误。

#include <Eigen/Geometry>
using namespace Eigen;
using namespace std;

typedef Matrix<float, 6, 6> Matrix6f;

int main()
{

Matrix6f M;

M<< 0.932322,  0.125848,  -0.85106, -0.313612,  -1.50979, -0.691102,
0.125848,  0.663803, -0.555993,  0.117918, -0.645694, -0.625737,
-0.85106, -0.555993,   1.26442,   0.39079,   1.89422,  0.959306,
-0.313612,  0.117918,   0.39079,   2.70718,   1.84228,   2.12945,
-1.50979, -0.645694,   1.89422,   1.84228,   3.89408,    2.5017,
-0.691102, -0.625737,  0.959306,   2.12945,    2.5017,   3.39874;

cout << "Inverse= " << M.inverse() << endl;

return 0;
}

我尝试使用NVCC编译代码时收到的错误是:

Scanning dependencies of target matrix_inverse
[100%] Linking CXX executable matrix_inverse
CMakeFiles/matrix_inverse.dir/matrix_inverse_generated_matrix_inverse.cu.o: In function `Eigen::internal::compute_inverse<Eigen::Matrix<float, 6, 6, 0, 6, 6>, Eigen::Matrix<float, 6, 6, 0, 6, 6>, 6>::run(Eigen::Matrix<float, 6, 6, 0, 6, 6> const&, Eigen::Matrix<float, 6, 6, 0, 6, 6>&)':
/usr/include/eigen3/Eigen/src/LU/InverseImpl.h:28: undefined reference to `Eigen::MatrixBase<Eigen::Matrix<float, 6, 6, 0, 6, 6> >::partialPivLu() const'
collect2: error: ld returned 1 exit status
CMakeFiles/matrix_inverse.dir/build.make:79: recipe for target 'matrix_inverse' failed
make[2]: *** [matrix_inverse] Error 1
CMakeFiles/Makefile2:67: recipe for target 'CMakeFiles/matrix_inverse.dir/all' failed
make[1]: *** [CMakeFiles/matrix_inverse.dir/all] Error 2
Makefile:83: recipe for target 'all' failed
make: *** [all] Error 2

我的cmakelist:

cmake_minimum_required(VERSION 2.8 FATAL_ERROR)

project(inversion)
INCLUDE_DIRECTORIES (/usr/include/eigen3)

FIND_PACKAGE(CUDA REQUIRED)
INCLUDE_DIRECTORIES(${CUDA_INCLUDE_DIRS})

set(
    CUDA_NVCC_FLAGS
    ${CUDA_NVCC_FLAGS};
    -O3 -gencode arch=compute_52,code=sm_52;
    )

cuda_add_executable (matrix_inverse matrix_inverse.cu)

编译日志很大,我只在下面添加了一些相关部分:

/usr/include/eigen3/Eigen/src/LU/InverseImpl.h(335): warning: calling a __host__ function from a __host__ __device__ function is not allowed
          detected during instantiation of "const Eigen::Inverse<Derived> Eigen::MatrixBase<Derived>::inverse() const [with Derived=Eigen::Matrix<float, 6, 6, 0, 6, 6>]" 
/home/krr/temp_codes/eigen/matrix_inverse/src/matrix_inverse.cu(21): here

/usr/include/eigen3/Eigen/src/Core/Inverse.h(58): warning: calling a __host__ function from a __host__ __device__ function is not allowed
          detected during:
            instantiation of "Eigen::Index Eigen::Inverse<XprType>::cols() const [with XprType=Eigen::PartialPivLU<Eigen::Matrix<float, 6, 6, 0, 6, 6>>]" 
/usr/include/eigen3/Eigen/src/Core/AssignEvaluator.h(733): here
            instantiation of "void Eigen::internal::call_assignment_no_alias(Dst &, const Src &, const Func &) [with Dst=Eigen::Matrix<float, 6, 6, 0, 6, 6>, Src=Eigen::Inverse<Eigen::PartialPivLU<Eigen::Matrix<float, 6, 6, 0, 6, 6>>>, Func=Eigen::internal::assign_op<float>]" 
/usr/include/eigen3/Eigen/src/Core/AssignEvaluator.h(712): here
            instantiation of "void Eigen::internal::call_assignment(Dst &, const Src &, const Func &, Eigen::internal::enable_if<<expression>, void *>::type) [with Dst=Eigen::Matrix<float, 6, 6, 0, 6, 6>, Src=Eigen::Inverse<Eigen::PartialPivLU<Eigen::Matrix<float, 6, 6, 0, 6, 6>>>, Func=Eigen::internal::assign_op<float>]" 
/usr/include/eigen3/Eigen/src/Core/AssignEvaluator.h(693): here
            instantiation of "void Eigen::internal::call_assignment(Dst &, const Src &) [with Dst=Eigen::Matrix<float, 6, 6, 0, 6, 6>, Src=Eigen::Inverse<Eigen::PartialPivLU<Eigen::Matrix<float, 6, 6, 0, 6, 6>>>]" 
/usr/include/eigen3/Eigen/src/Core/PlainObjectBase.h(682): here
            instantiation of "Derived &Eigen::PlainObjectBase<Derived>::_set(const Eigen::DenseBase<OtherDerived> &) [with Derived=Eigen::Matrix<float, 6, 6, 0, 6, 6>, OtherDerived=Eigen::Inverse<Eigen::PartialPivLU<Eigen::Matrix<float, 6, 6, 0, 6, 6>>>]" 
/usr/include/eigen3/Eigen/src/Core/Matrix.h(225): here
            [ 4 instantiation contexts not shown ]
            instantiation of "Derived &Eigen::PlainObjectBase<Derived>::_set_noalias(const Eigen::DenseBase<OtherDerived> &) [with Derived=Eigen::Matrix<float, 6, 6, 0, 6, 6>, OtherDerived=Eigen::Inverse<Eigen::Matrix<float, 6, 6, 0, 6, 6>>]" 
/usr/include/eigen3/Eigen/src/Core/PlainObjectBase.h(783): here
            instantiation of "void Eigen::PlainObjectBase<Derived>::_init1<T,OtherDerived>(const Eigen::DenseBase<OtherDerived> &) [with Derived=Eigen::Matrix<float, 6, 6, 0, 6, 6>, T=Eigen::Inverse<Eigen::Matrix<float, 6, 6, 0, 6, 6>>, OtherDerived=Eigen::Inverse<Eigen::Matrix<float, 6, 6, 0, 6, 6>>]" 
/usr/include/eigen3/Eigen/src/Core/Matrix.h(296): here
            instantiation of "Eigen::Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::Matrix(const T &) [with _Scalar=float, _Rows=6, _Cols=6, _Options=0, _MaxRows=6, _MaxCols=6, T=Eigen::Inverse<Eigen::Matrix<float, 6, 6, 0, 6, 6>>]" 
/usr/include/eigen3/Eigen/src/Core/DenseBase.h(410): here
            instantiation of "Eigen::DenseBase<Derived>::EvalReturnType Eigen::DenseBase<Derived>::eval() const [with Derived=Eigen::Inverse<Eigen::Matrix<float, 6, 6, 0, 6, 6>>]" 
/usr/include/eigen3/Eigen/src/Core/IO.h(248): here
            instantiation of "std::ostream &Eigen::operator<<(std::ostream &, const Eigen::DenseBase<Derived> &) [with Derived=Eigen::Inverse<Eigen::Matrix<float, 6, 6, 0, 6, 6>>]" 
/home/krr/temp_codes/eigen/matrix_inverse/src/matrix_inverse.cu(21): here

/usr/include/eigen3/Eigen/src/Core/Inverse.h(57): warning: calling a __host__ function from a __host__ __device__ function is not allowed
          detected during:
            instantiation of "Eigen::Index Eigen::Inverse<XprType>::rows() const [with XprType=Eigen::PartialPivLU<Eigen::Matrix<float, 6, 6, 0, 6, 6>>]" 
/usr/include/eigen3/Eigen/src/Core/AssignEvaluator.h(733): here
            instantiation of "void Eigen::internal::call_assignment_no_alias(Dst &, const Src &, const Func &) [with Dst=Eigen::Matrix<float, 6, 6, 0, 6, 6>, Src=Eigen::Inverse<Eigen::PartialPivLU<Eigen::Matrix<float, 6, 6, 0, 6, 6>>>, Func=Eigen::internal::assign_op<float>]" 
/usr/include/eigen3/Eigen/src/Core/AssignEvaluator.h(712): here
            instantiation of "void Eigen::internal::call_assignment(Dst &, const Src &, const Func &, Eigen::internal::enable_if<<expression>, void *>::type) [with Dst=Eigen::Matrix<float, 6, 6, 0, 6, 6>, Src=Eigen::Inverse<Eigen::PartialPivLU<Eigen::Matrix<float, 6, 6, 0, 6, 6>>>, Func=Eigen::internal::assign_op<float>]" 
/usr/include/eigen3/Eigen/src/Core/AssignEvaluator.h(693): here
            instantiation of "void Eigen::internal::call_assignment(Dst &, const Src &) [with Dst=Eigen::Matrix<float, 6, 6, 0, 6, 6>, Src=Eigen::Inverse<Eigen::PartialPivLU<Eigen::Matrix<float, 6, 6, 0, 6, 6>>>]" 
/usr/include/eigen3/Eigen/src/Core/PlainObjectBase.h(682): here
            instantiation of "Derived &Eigen::PlainObjectBase<Derived>::_set(const Eigen::DenseBase<OtherDerived> &) [with Derived=Eigen::Matrix<float, 6, 6, 0, 6, 6>, OtherDerived=Eigen::Inverse<Eigen::PartialPivLU<Eigen::Matrix<float, 6, 6, 0, 6, 6>>>]" 
/usr/include/eigen3/Eigen/src/Core/Matrix.h(225): here
            [ 4 instantiation contexts not shown ]
            instantiation of "Derived &Eigen::PlainObjectBase<Derived>::_set_noalias(const Eigen::DenseBase<OtherDerived> &) [with Derived=Eigen::Matrix<float, 6, 6, 0, 6, 6>, OtherDerived=Eigen::Inverse<Eigen::Matrix<float, 6, 6, 0, 6, 6>>]" 
/usr/include/eigen3/Eigen/src/Core/PlainObjectBase.h(783): here
            instantiation of "void Eigen::PlainObjectBase<Derived>::_init1<T,OtherDerived>(const Eigen::DenseBase<OtherDerived> &) [with Derived=Eigen::Matrix<float, 6, 6, 0, 6, 6>, T=Eigen::Inverse<Eigen::Matrix<float, 6, 6, 0, 6, 6>>, OtherDerived=Eigen::Inverse<Eigen::Matrix<float, 6, 6, 0, 6, 6>>]" 
/usr/include/eigen3/Eigen/src/Core/Matrix.h(296): here
            instantiation of "Eigen::Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::Matrix(const T &) [with _Scalar=float, _Rows=6, _Cols=6, _Options=0, _MaxRows=6, _MaxCols=6, T=Eigen::Inverse<Eigen::Matrix<float, 6, 6, 0, 6, 6>>]" 
/usr/include/eigen3/Eigen/src/Core/DenseBase.h(410): here
            instantiation of "Eigen::DenseBase<Derived>::EvalReturnType Eigen::DenseBase<Derived>::eval() const [with Derived=Eigen::Inverse<Eigen::Matrix<float, 6, 6, 0, 6, 6>>]" 
/usr/include/eigen3/Eigen/src/Core/IO.h(248): here
            instantiation of "std::ostream &Eigen::operator<<(std::ostream &, const Eigen::DenseBase<Derived> &) [with Derived=Eigen::Inverse<Eigen::Matrix<float, 6, 6, 0, 6, 6>>]" 
/home/krr/temp_codes/eigen/matrix_inverse/src/matrix_inverse.cu(21): here

/usr/include/eigen3/Eigen/src/Core/Solve.h(72): warning: calling a __host__ function from a __host__ __device__ function is not allowed
          detected during:
            instantiation of "Eigen::Index Eigen::Solve<Decomposition, RhsType>::rows() const [with Decomposition=Eigen::PartialPivLU<Eigen::Matrix<float, 6, 6, 0, 6, 6>>, RhsType=Eigen::CwiseNullaryOp<Eigen::internal::scalar_identity_op<float>, Eigen::Matrix<float, 6, 6, 0, 6, 6>>]" 
/usr/include/eigen3/Eigen/src/Core/AssignEvaluator.h(733): here
            instantiation of "void Eigen::internal::call_assignment_no_alias(Dst &, const Src &, const Func &) [with Dst=Eigen::Matrix<float, 6, 6, 0, 6, 6>, Src=Eigen::Solve<Eigen::PartialPivLU<Eigen::Matrix<float, 6, 6, 0, 6, 6>>, Eigen::CwiseNullaryOp<Eigen::internal::scalar_identity_op<float>, Eigen::Matrix<float, 6, 6, 0, 6, 6>>>, Func=Eigen::internal::assign_op<float>]" 
/usr/include/eigen3/Eigen/src/Core/AssignEvaluator.h(712): here
            instantiation of "void Eigen::internal::call_assignment(Dst &, const Src &, const Func &, Eigen::internal::enable_if<<expression>, void *>::type) [with Dst=Eigen::Matrix<float, 6, 6, 0, 6, 6>, Src=Eigen::Solve<Eigen::PartialPivLU<Eigen::Matrix<float, 6, 6, 0, 6, 6>>, Eigen::CwiseNullaryOp<Eigen::internal::scalar_identity_op<float>, Eigen::Matrix<float, 6, 6, 0, 6, 6>>>, Func=Eigen::internal::assign_op<float>]" 
/usr/include/eigen3/Eigen/src/Core/AssignEvaluator.h(693): here
            instantiation of "void Eigen::internal::call_assignment(Dst &, const Src &) [with Dst=Eigen::Matrix<float, 6, 6, 0, 6, 6>, Src=Eigen::Solve<Eigen::PartialPivLU<Eigen::Matrix<float, 6, 6, 0, 6, 6>>, Eigen::CwiseNullaryOp<Eigen::internal::scalar_identity_op<float>, Eigen::Matrix<float, 6, 6, 0, 6, 6>>>]" 
/usr/include/eigen3/Eigen/src/Core/PlainObjectBase.h(682): here
            instantiation of "Derived &Eigen::PlainObjectBase<Derived>::_set(const Eigen::DenseBase<OtherDerived> &) [with Derived=Eigen::Matrix<float, 6, 6, 0, 6, 6>, OtherDerived=Eigen::Solve<Eigen::PartialPivLU<Eigen::Matrix<float, 6, 6, 0, 6, 6>>, Eigen::CwiseNullaryOp<Eigen::internal::scalar_identity_op<float>, Eigen::Matrix<float, 6, 6, 0, 6, 6>>>]" 
/usr/include/eigen3/Eigen/src/Core/Matrix.h(225): here
            [ 10 instantiation contexts not shown ]
            instantiation of "Derived &Eigen::PlainObjectBase<Derived>::_set_noalias(const Eigen::DenseBase<OtherDerived> &) [with Derived=Eigen::Matrix<float, 6, 6, 0, 6, 6>, OtherDerived=Eigen::Inverse<Eigen::Matrix<float, 6, 6, 0, 6, 6>>]" 
/usr/include/eigen3/Eigen/src/Core/PlainObjectBase.h(783): here
            instantiation of "void Eigen::PlainObjectBase<Derived>::_init1<T,OtherDerived>(const Eigen::DenseBase<OtherDerived> &) [with Derived=Eigen::Matrix<float, 6, 6, 0, 6, 6>, T=Eigen::Inverse<Eigen::Matrix<float, 6, 6, 0, 6, 6>>, OtherDerived=Eigen::Inverse<Eigen::Matrix<float, 6, 6, 0, 6, 6>>]" 
/usr/include/eigen3/Eigen/src/Core/Matrix.h(296): here
            instantiation of "Eigen::Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::Matrix(const T &) [with _Scalar=float, _Rows=6, _Cols=6, _Options=0, _MaxRows=6, _MaxCols=6, T=Eigen::Inverse<Eigen::Matrix<float, 6, 6, 0, 6, 6>>]" 
/usr/include/eigen3/Eigen/src/Core/DenseBase.h(410): here
            instantiation of "Eigen::DenseBase<Derived>::EvalReturnType Eigen::DenseBase<Derived>::eval() const [with Derived=Eigen::Inverse<Eigen::Matrix<float, 6, 6, 0, 6, 6>>]" 
/usr/include/eigen3/Eigen/src/Core/IO.h(248): here
            instantiation of "std::ostream &Eigen::operator<<(std::ostream &, const Eigen::DenseBase<Derived> &) [with Derived=Eigen::Inverse<Eigen::Matrix<float, 6, 6, 0, 6, 6>>]" 
/home/krr/temp_codes/eigen/matrix_inverse/src/matrix_inverse.cu(21): here

推荐答案

这只是因为CUDA尚不支持大于4的矩阵求逆。

回答Talonmies的评论,因为OP的文件是用NVCC编译的,所以Eigen自动启用CUDA支持。特别是,方法MatrixBase::inverse()被声明为host device,因为如果底层表达式是4x4或更小,那么它将在编译时分支到与CUDA兼容的代码。对于较大的代码,它会分支到非Cuda兼容代码...因此,结果是CUDA和非CUDA重要代码必须在.cu和.cpp文件中很好地分开。

这篇关于用GCC和NVCC编译时Eigen::矩阵求逆的不同行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆