使用gcc和nvcc编译时,eigen :: matrix反转的行为不同

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用gcc和nvcc编译时,eigen :: matrix反转的行为不同相关的知识,希望对你有一定的参考价值。

我使用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

我的cmakelists:

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 :: matrix反转的行为不同的主要内容,如果未能解决你的问题,请参考以下文章

如何查找和禁用特定的 NVCC 警告?

是否可以在 Windows 中将 nvcc 与 gcc/g++ 集成?

[踩坑]编译CUDA算子时NVCC报错的解决

将 std::ref() 与 nvcc 一起使用时,类没有成员“second_argument_type”[重复]

无法使用 nvcc 找到 Torch 头文件

gcc-via-nvcc 是不是矢量化这些总和和最大减少?