问题
This is related to this question. I have today experimented a bit with Conjugate Gradient, in particular I experimented with max_iterations
and tolerance
. It is faster but not fast enough. According to the documentation it should be enough to add -fopenmp
in the compilation to enable multi-threading
.
I have tested using both
`omp_set_num_threads(nbrThreads);
Eigen::setNbThreads(nbrThreads);`
It makes no difference in time if I use 5 threads or 1 thread, and that I think is a bit strange.
Secondly, another way to speed up the solution using pre-conditoning
. When I try to do:
Eigen::ConjugateGradient<Eigen::SparseMatrix<float>, Eigen::Lower, Eigen::IncompleteCholesky<float>> cg;
I get the error:
void Eigen::IncompleteCholesky<Scalar, _UpLo, _OrderingType>::_solve_impl(const Rhs&, Dest&) const [with Rhs = Eigen::Matr
ix<float, -1, 1>; Dest = Eigen::Matrix<float, -1, 1>; Scalar = float; int _UpLo = 1; _OrderingType = Eigen::AMDOrdering<int>]: Assertion `m_factorizationIsOk && "factorize() should be called first"' failed.
Given that Eigen::SimplicialLDLT
works which is a Cholesky factorization, then the incomplete should also work?
EDIT: Here is how I call cg:
Eigen::ConjugateGradient<Eigen::SparseMatrix<float>, Eigen::Lower, Eigen::IncompleteCholesky<float>> cg;
cg.setTolerance(0.01);
cg.setMaxIterations(50);
cg.analyzePattern(A_tot);
cg.compute(A_tot);
Eigen::VectorXf opt = cg.solveWithGuess(b_tot, rho_current);
Actually when you read about IterativeSolvers here, then IncompleteCholesky
is not listed. Although IncompleCholesky is defined here.
回答1:
As explained in the documentation, you need to store the full matrix (both upper and lower triangular part), and pass Lower|Upper
to ConjugateGradient
to get multi-threading with cg.
回答2:
The problem seems to be that I had an beta-version of Eigen installed. It runs with pre-conditioner using Eigen 3.3.2
来源:https://stackoverflow.com/questions/42134128/eigen-and-parallellization-makes-no-difference-for-conjugate-gradient-precondit