Intel compiler is known to use excessively unsafe floating-point optimizations by default. But the latest version (18.0.3) pushes the limits. The following code is designed to verify the correctness of SVD for a rather poorly conditioned matrix A, checking that |A - U S V^T| is small. On most compilers this is the case, but not with icc; what's worse, even setting the option -fp-model:precise does not help (only -fp-model:strict helps). #include "Eigen/SVD" #include <iostream> #include <cmath> int main() { const int N=500; Eigen::MatrixXd mat = Eigen::MatrixXd::Zero(N,N); for(int i=0; i<5000; i++) mat(rand() % N, rand() % N) = rand()*1./RAND_MAX; mat = mat*mat; Eigen::BDCSVD<Eigen::MatrixXd> sv(mat, Eigen::ComputeThinU|Eigen::ComputeThinV); Eigen::VectorXd sing = sv.singularValues(); Eigen::MatrixXd result = sv.matrixU() * sing.asDiagonal() * sv.matrixV().transpose() - mat; std::cout << "norm(A - U S V^T) = " << result.norm() << ", condition number: " << (sing[0]/sing[N-1]) << "\n"; }
Could you try if adding this works: #pragma float_control (strict, on) Ideally, this would be done only locally for some critical functions (and of course, this must be guarded by some #if EIGEN_COMP_ICC)
it does help, but only if I put it at the beginning of the file (before #including "Eigen/SVD"). OTOH it does not seem to slow down the remaining code (compared the same stuff compiled with Intel 15, full optimization, vs. intel 18, -fp-model:strict). what is puzzling that it requires "strict" model, i.e. neither "precise" nor "source" is enough (normally they are designed to prevent unsafe optimizations). Possibly an obscure bug in the compiler...
You could try next putting it somewhere inside `Eigen/SVD` or inside a header included by that file. Then play around with some pragma push and pops (I'd have to look up the syntax for that as well). Of course, we could just always set float_control to strict, if we compile with ICC (very likely there will be issues in other modules as well)
-- GitLab Migration Automatic Message -- This bug has been migrated to gitlab.com's GitLab instance and has been closed from further activity. You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.com/libeigen/eigen/issues/1588.