Search code examples
c++visual-studio-2013eigeneigen3

Successive pruned product crashing EIGEN


I'm having an error which I do not understand using Eigen and SparseMatrix and Visual Studio Pro 2013

Successive pruned product are perfectly working in DEBUG mode, but they're long. I wanted to switch to RELEASE, without changing anything in code, but the program is crashing with this mode.

I'm having an access violation error c0000005 (French VS, sorry for this) :

Message de résultat  :  Code de l'exception : C0000005
StackTrace de résultat  :   
à Eigen::internal::sparse_sparse_product_with_pruning_impl<Eigen::SparseMatrix<short,0,int>,Eigen::SparseMatrix<short,0,int>,Eigen::SparseMatrix<short,0,int> >() dans [..]\eigen\src\sparsecore\sparsesparseproductwithpruning.h:ligne 61
    à Eigen::internal::sparse_sparse_product_with_pruning_selector<Eigen::SparseMatrix<short,1,int>,Eigen::SparseMatrix<short,1,int>,Eigen::SparseMatrix<short,0,int>,1,1,0>::run() dans [..]\eigen\src\sparsecore\sparsesparseproductwithpruning.h:ligne 143
    à Eigen::internal::unary_evaluator<Eigen::SparseView<Eigen::Product<Eigen::SparseMatrix<short,1,int>,Eigen::SparseMatrix<short,1,int>,2> >,Eigen::internal::IteratorBased,short>::unary_evaluator<Eigen::SparseView<Eigen::Product<Eigen::SparseMatrix<short,1,int>,Eigen::SparseMatrix<short,1,int>,2> >,Eigen::internal::IteratorBased,short>() dans [..]\eigen\src\sparsecore\sparseproduct.h:ligne 158
    à Eigen::SparseMatrix<short,1,int>::operator=<Eigen::SparseView<Eigen::Product<Eigen::SparseMatrix<short,1,int>,Eigen::SparseMatrix<short,1,int>,2> > >() dans [..]\eigen\src\sparsecore\sparsematrix.h:ligne 1080
    à IncMethod_Tester::EigenMatrix_Tests::NullMultiplication() dans [...]\integrity_tests.cpp:ligne 856

The code tested in integrity_test is the following :

        SparseMatrix<short, RowMajor> A(0, 1);
        SparseMatrix<short, RowMajor> B(1, 5);
        SparseMatrix<short, RowMajor> C(5, 4);

        std::vector<Triplet<short>> values;
        values.push_back(Triplet<short>(0, 4, 1));
        values.push_back(Triplet<short>(0, 3, 1));
        values.push_back(Triplet<short>(0, 2, 1));
        B.setFromTriplets(values.begin(), values.end());

        std::vector<Triplet<short>> values2;
        values2.push_back(Triplet<short>(0, 0, 1));
        values2.push_back(Triplet<short>(1, 1, 1));
        values2.push_back(Triplet<short>(2, 2, -1));
        values2.push_back(Triplet<short>(2, 3, -1));
        values2.push_back(Triplet<short>(3, 2, 1));
        values2.push_back(Triplet<short>(4, 3, 1));
        C.setFromTriplets(values2.begin(), values2.end());


        std::fstream f("NULLMULTIPLICATION", std::fstream::out);
        f << "A MATRIX (" << A.rows() << "," << A.cols() << ")" <<std::endl << A << std::endl;
        f << "B MATRIX (" << B.rows() << "," << B.cols() << ")" <<std::endl<< B << std::endl;
        f << "C MATRIX (" << C.rows() << "," << C.cols() << ")" << std::endl << C << std::endl;

        B = (A*B).pruned();
        f << "AB MATRIX (" << B.rows() << "," << B.cols() << ")" << std::endl << A << std::endl;
        B = (B*C).pruned();
        f << "B MATRIX (" << B.rows() << "," << B.cols() << ")" << std::endl << B << std::endl;

And the output in NULLMULTIPLICATION file is :

A MATRIX (0,1)

B MATRIX (1,5)
0 0 1 1 1 

C MATRIX (5,4)
1 0 0 0 
0 1 0 0 
0 0 -1 -1 
0 0 1 0 
0 0 0 1 

AB MATRIX (0,5)

Which means the program is running up to :

B = (A*B).pruned();
B = (B*C).pruned();

Am I doing something wrong here? I tried creating temporary variables but it's stil crashing :

SparseMatrix<short, RowMajor> D = (A*B).pruned();
SparseMatrix<short, RowMajor> E = (D*C).pruned();

Any suggestion for this product? I may be wrong on the syntax for multiple sparse product?

Thanks in advance.


Solution

  • Ok I found what was causing the error. This is due to a 0 dimension in a pruned product, I solved it just by testing before a product if any of the involved matrix has a null dimension, if so, just do a normal product without pruned.