This forum has been archived. All content is frozen. Please use KDE Discuss instead.

Eigen 3.3-alpha1: evalTo private SparseMatrix

Tags: None
(comma "," separated)
abdullahtahiri
Registered Member
Posts
9
Karma
0
Hi there!

We have been recently adapting our code that worked with Eigen versions 3.2.2 - 3.2.5 to work with Eigen 3.3-alpha1 (I also tried with the mercurial of today without success). And I am running into issues when assigning (= operator) SparseMatrix, the compiler main complaint being "/usr/include/eigen3/Eigen/src/SparseCore/SparseMatrixBase.h:376:34: error: ‘void Eigen::SparseMatrixBase<Derived>::evalTo(Dest&) const [with Dest = Eigen::Matrix<double, -1, -1>; Derived = Eigen::TriangularView<const Eigen::SparseMatrix<double>, 2u>]’ is private".

A bigger snapshot of the offending code is below, but the compilation problem is in these lines using the = operator:

Code: Select all
           SqrJT=Eigen::SparseQR<Eigen::SparseMatrix<double>, Eigen::COLAMDOrdering<int> >(SJ.topRows(count).transpose());

            if (constrNum >= paramsNum)
                R = SqrJT.matrixR().triangularView<Eigen::Upper>();
            else
                R = SqrJT.matrixR().topRows(constrNum)
                                    .triangularView<Eigen::Upper>();


I think I can get away in the case of SqrJT (first line above), by using the standard constructor and then calling compute(). However, I have not managed to get away with the assignation of the R matrix.

For the sake of completeness, this code does compile perfectly:

Code: Select all
            SqrJT.compute(SJ.topRows(count).transpose());
           
            paramsNum = SqrJT.rows();
            constrNum = SqrJT.cols();
            SqrJT.setPivotThreshold(qrpivotThreshold);
            rank = SqrJT.rank();
           
            if (constrNum >= paramsNum)
                /*R = */SqrJT.matrixR().triangularView<Eigen::Upper>();
            else
                /*R =*/ SqrJT.matrixR().topRows(constrNum)
                .triangularView<Eigen::Upper>(); 


But as you can imagine, my R matrix does not have the result of the QR decomposition, as the assignation is commented out.

This is the larger code snapshot I was referring to:

Code: Select all
    Eigen::MatrixXd J(clist.size(), plist.size());
    int count=0;
    for (std::vector<Constraint *>::iterator constr=clist.begin();
         constr != clist.end(); ++constr) {
        (*constr)->revertParams();
        if ((*constr)->getTag() >= 0) {
            count++;
            for (int j=0; j < int(plist.size()); j++)
                J(count-1,j) = (*constr)->grad(plist[j]);
        }
    }

    Eigen::SparseMatrix<double> SJ;
   
    if(qrAlgorithm==EigenSparseQR){
        // this creation is not optimized (done using triplets)
        // however the time this takes is negligible compared to the
        // time the QR decomposition itself takes
        SJ = J.sparseView();
        SJ.makeCompressed();
    }
   
    Eigen::SparseQR<Eigen::SparseMatrix<double>, Eigen::COLAMDOrdering<int> > SqrJT;

    Eigen::MatrixXd R;
    int paramsNum = 0;
    int constrNum = 0;
    int rank = 0;
    Eigen::FullPivHouseholderQR<Eigen::MatrixXd> qrJT;

     if (SJ.rows() > 0) {
            SqrJT=Eigen::SparseQR<Eigen::SparseMatrix<double>, Eigen::COLAMDOrdering<int> >(SJ.topRows(count).transpose());           
            paramsNum = SqrJT.rows();
            constrNum = SqrJT.cols();
            SqrJT.setPivotThreshold(qrpivotThreshold);
            rank = SqrJT.rank();
           
            if (constrNum >= paramsNum)
                R = SqrJT.matrixR().triangularView<Eigen::Upper>();
            else
                R = SqrJT.matrixR().topRows(constrNum)
                                    .triangularView<Eigen::Upper>();   
        }
    }



In case you find it useful, the whole code file is available here:
https://github.com/abdullahtahiriyo/Fre ... cs/GCS.cpp

The relevant member function is "int System::diagnose(Algorithm alg)" and starts in line 1793.

The whole relevant compiler output is:

Code: Select all
[ 93%] Built target ImportGui
In file included from /usr/include/eigen3/Eigen/SparseCore:30:0,
                 from /usr/include/eigen3/Eigen/Sparse:19,
                 from /home/abdullah/github/free-cad-code/src/Mod/Sketcher/App/planegcs/GCS.cpp:57:
/usr/include/eigen3/Eigen/src/Core/AssignEvaluator.h: In instantiation of ‘static void Eigen::internal::Assignment<DstXprType, SrcXprType, Functor, Eigen::internal::EigenBase2EigenBase, Scalar>::run(DstXprType&, const SrcXprType&, const Eigen::internal::assign_op<typename DstXprType::Scalar>&) [with DstXprType = Eigen::Matrix<double, -1, -1>; SrcXprType = Eigen::TriangularView<const Eigen::SparseMatrix<double>, 2u>; Functor = Eigen::internal::assign_op<double>; Scalar = double; typename DstXprType::Scalar = double]’:
/usr/include/eigen3/Eigen/src/Core/AssignEvaluator.h:765:70:   required from ‘void Eigen::internal::call_assignment_no_alias(Dst&, const Src&, const Func&) [with Dst = Eigen::Matrix<double, -1, -1>; Src = Eigen::TriangularView<const Eigen::SparseMatrix<double>, 2u>; Func = Eigen::internal::assign_op<double>]’
/usr/include/eigen3/Eigen/src/Core/AssignEvaluator.h:718:42:   required from ‘void Eigen::internal::call_assignment(Dst&, const Src&, const Func&, typename Eigen::internal::enable_if<(Eigen::internal::evaluator_traits<Rhs>::AssumeAliasing == 0), void*>::type) [with Dst = Eigen::Matrix<double, -1, -1>; Src = Eigen::TriangularView<const Eigen::SparseMatrix<double>, 2u>; Func = Eigen::internal::assign_op<double>; typename Eigen::internal::enable_if<(Eigen::internal::evaluator_traits<Rhs>::AssumeAliasing == 0), void*>::type = void*]’
/usr/include/eigen3/Eigen/src/Core/AssignEvaluator.h:699:72:   required from ‘void Eigen::internal::call_assignment(Dst&, const Src&) [with Dst = Eigen::Matrix<double, -1, -1>; Src = Eigen::TriangularView<const Eigen::SparseMatrix<double>, 2u>]’
/usr/include/eigen3/Eigen/src/Core/Assign.h:75:55:   required from ‘Derived& Eigen::MatrixBase<Derived>::operator=(const Eigen::EigenBase<OtherDerived>&) [with OtherDerived = Eigen::TriangularView<const Eigen::SparseMatrix<double>, 2u>; Derived = Eigen::Matrix<double, -1, -1>]’
/usr/include/eigen3/Eigen/src/Core/PlainObjectBase.h:506:38:   required from ‘Derived& Eigen::PlainObjectBase<Derived>::operator=(const Eigen::EigenBase<OtherDerived>&) [with OtherDerived = Eigen::TriangularView<const Eigen::SparseMatrix<double>, 2u>; Derived = Eigen::Matrix<double, -1, -1>]’
/usr/include/eigen3/Eigen/src/Core/Matrix.h:238:35:   required from ‘Eigen::Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>& Eigen::Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::operator=(const Eigen::EigenBase<OtherDerived>&) [with OtherDerived = Eigen::TriangularView<const Eigen::SparseMatrix<double>, 2u>; _Scalar = double; int _Rows = -1; int _Cols = -1; int _Options = 0; int _MaxRows = -1; int _MaxCols = -1]’
/home/abdullah/github/free-cad-code/src/Mod/Sketcher/App/planegcs/GCS.cpp:1922:19:   required from here
/usr/include/eigen3/Eigen/src/SparseCore/SparseMatrixBase.h:376:34: error: ‘void Eigen::SparseMatrixBase<Derived>::evalTo(Dest&) const [with Dest = Eigen::Matrix<double, -1, -1>; Derived = Eigen::TriangularView<const Eigen::SparseMatrix<double>, 2u>]’ is private
     template<typename Dest> void evalTo(Dest &) const;
                                  ^
In file included from /usr/include/eigen3/Eigen/Core:349:0,
                 from /home/abdullah/github/free-cad-code/src/Mod/Sketcher/App/planegcs/SubSystem.h:29,
                 from /home/abdullah/github/free-cad-code/src/Mod/Sketcher/App/planegcs/GCS.h:26,
                 from /home/abdullah/github/free-cad-code/src/Mod/Sketcher/App/planegcs/GCS.cpp:32:
/usr/include/eigen3/Eigen/src/Core/AssignEvaluator.h:820:5: error: within this context
     src.evalTo(dst);
     ^
make[2]: *** [src/Mod/Sketcher/App/CMakeFiles/Sketcher.dir/planegcs/GCS.cpp.o] Error 1
make[1]: *** [src/Mod/Sketcher/App/CMakeFiles/Sketcher.dir/all] Error 2
make: *** [all] Error 2


I wonder if this is a bug in Eigen 3.3 as this used to work fine in Eigen 3.2, or it is intended and I should change my code somehow.

Thanks in advance,
Abdullah
User avatar
ggael
Moderator
Posts
3447
Karma
19
OS
abdullahtahiri
Registered Member
Posts
9
Karma
0
You are welcome!!

I have just tested it. Thank you very much for fixing it so fast :)

Regards,
Abdullah
abdullahtahiri
Registered Member
Posts
9
Karma
0
Just one thing you might want to fix. This was working in Eigen 3.2.2-3.2.5:

Code: Select all
SqrJT=Eigen::SparseQR<Eigen::SparseMatrix<double>, Eigen::COLAMDOrdering<int> >(SJ.topRows(count).transpose());           


Now it does not, with this compiler error:

Code: Select all
[ 93%] Built target ImportGui
In file included from /usr/include/eigen3/Eigen/Core:295:0,
                 from /home/abdullah/github/free-cad-code/src/Mod/Sketcher/App/planegcs/SubSystem.h:29,
                 from /home/abdullah/github/free-cad-code/src/Mod/Sketcher/App/planegcs/GCS.h:26,
                 from /home/abdullah/github/free-cad-code/src/Mod/Sketcher/App/planegcs/GCS.cpp:32:
/usr/include/eigen3/Eigen/src/Core/util/Meta.h: In member function ‘Eigen::SparseSolverBase<Eigen::SparseQR<Eigen::SparseMatrix<double>, Eigen::COLAMDOrdering<int> > >& Eigen::SparseSolverBase<Eigen::SparseQR<Eigen::SparseMatrix<double>, Eigen::COLAMDOrdering<int> > >::operator=(const Eigen::SparseSolverBase<Eigen::SparseQR<Eigen::SparseMatrix<double>, Eigen::COLAMDOrdering<int> > >&)’:
/usr/include/eigen3/Eigen/src/Core/util/Meta.h:195:40: error: ‘const Eigen::internal::noncopyable& Eigen::internal::noncopyable::operator=(const Eigen::internal::noncopyable&)’ is private
   EIGEN_DEVICE_FUNC const noncopyable& operator=(const noncopyable&);
                                        ^
In file included from /usr/include/eigen3/Eigen/SparseCore:64:0,
                 from /usr/include/eigen3/Eigen/Sparse:26,
                 from /home/abdullah/github/free-cad-code/src/Mod/Sketcher/App/planegcs/GCS.cpp:57:
/usr/include/eigen3/Eigen/src/SparseCore/SparseSolverBase.h:53:7: error: within this context
 class SparseSolverBase : internal::noncopyable
       ^
In file included from /usr/include/eigen3/Eigen/SparseQR:33:0,
                 from /usr/include/eigen3/Eigen/Sparse:30,
                 from /home/abdullah/github/free-cad-code/src/Mod/Sketcher/App/planegcs/GCS.cpp:57:
/usr/include/eigen3/Eigen/src/SparseQR/SparseQR.h: In member function ‘Eigen::SparseQR<Eigen::SparseMatrix<double>, Eigen::COLAMDOrdering<int> >& Eigen::SparseQR<Eigen::SparseMatrix<double>, Eigen::COLAMDOrdering<int> >::operator=(const Eigen::SparseQR<Eigen::SparseMatrix<double>, Eigen::COLAMDOrdering<int> >&)’:
/usr/include/eigen3/Eigen/src/SparseQR/SparseQR.h:71:7: note: synthesized method ‘Eigen::SparseSolverBase<Eigen::SparseQR<Eigen::SparseMatrix<double>, Eigen::COLAMDOrdering<int> > >& Eigen::SparseSolverBase<Eigen::SparseQR<Eigen::SparseMatrix<double>, Eigen::COLAMDOrdering<int> > >::operator=(const Eigen::SparseSolverBase<Eigen::SparseQR<Eigen::SparseMatrix<double>, Eigen::COLAMDOrdering<int> > >&)’ first required here
 class SparseQR : public SparseSolverBase<SparseQR<_MatrixType,_OrderingType> >
       ^
/home/abdullah/github/free-cad-code/src/Mod/Sketcher/App/planegcs/GCS.cpp: In member function ‘int GCS::System::diagnose(GCS::Algorithm)’:
/home/abdullah/github/free-cad-code/src/Mod/Sketcher/App/planegcs/GCS.cpp:1893:18: note: synthesized method ‘Eigen::SparseQR<Eigen::SparseMatrix<double>, Eigen::COLAMDOrdering<int> >& Eigen::SparseQR<Eigen::SparseMatrix<double>, Eigen::COLAMDOrdering<int> >::operator=(const Eigen::SparseQR<Eigen::SparseMatrix<double>, Eigen::COLAMDOrdering<int> >&)’ first required here
             SqrJT=Eigen::SparseQR<Eigen::SparseMatrix<double>, Eigen::COLAMDOrdering<int> >(SJ.topRows(count).transpose());
                  ^
make[2]: *** [src/Mod/Sketcher/App/CMakeFiles/Sketcher.dir/planegcs/GCS.cpp.o] Error 1
make[1]: *** [src/Mod/Sketcher/App/CMakeFiles/Sketcher.dir/all] Error 2
make: *** [all] Error 2


For our project I can get it work-around by using:
Code: Select all
SqrJT.compute(SJ.topRows(count).transpose());

instead, but I think you may consider it a bug :)

Thanks again,
abdullah
User avatar
ggael
Moderator
Posts
3447
Karma
19
OS
This is on purpose. Factorisations are not copyable, the fact it worked with 3.2 is just luck (and that we forgot to make it non-copyable). This syntax is also more expensive in c++98 (memory copy and consumption).
abdullahtahiri
Registered Member
Posts
9
Karma
0
Ok. Thank you very much for the explanation.


Bookmarks



Who is online

Registered users: bartoloni, Bing [Bot], Evergrowing, Google [Bot]