c++ - Very slow filling of sparse matrix and no memory gain in Eigen -


i trying implement example given in eigen tutorial pseudocode. far understand, illustrates recommended method filling sparse matrix, provided number of non 0 entries per column known.

the pseudocode found under header "filling sparse matrix"and written follows:

1: sparsematrix<double> mat(rows,cols);         // default column major 2: mat.reserve(vectorxi::constant(cols,6)); 3: each i,j such v_ij != 0 4:   mat.insert(i,j) = v_ij;                    // alternative: mat.coeffref(i,j) += v_ij; 5: mat.makecompressed();                        // optional 

my attempt transform c found below. have (hopefully) written vee() such, create 2500 non-zero elements per column. therefore 2500 should correspond 6 in example. set 3000 test make.compressed well.

unfortunately, don't understand behaviour of programme. i=0...3000 in seconds, stuck minutes. goes 6000 , stuck again minutes. why , how better performance?

furthermore, memory usage strange. can see @ times toward end eigen uses more memory needed corresponding dense matrix in gsl.the memory used fluctuates wildly. in steps bigger 100mb

i compile , run this:

ludi@ludi-m17xr4:~/desktop/tests$ g++ -o eigenfill.x eigenfill.cc -l/usr/local/lib -lgsl -lgslcblas && ./eigenfill.x

#include <iostream> #include <stdio.h> #include <stdlib.h>      #include <eigen/sparse> #include <gsl/gsl_matrix.h> #define rows 1e4 #define cols 1e4    /*-- declarationes --*/ int fillmatrix(eigen::sparsematrix<double> mat); double vee(int i, int j);  int main() { printf("---> watch gsl matrix memory usage!\n");     gsl_matrix *testmat = gsl_matrix_calloc(rows, cols); sleep(20); gsl_matrix_free(testmat); printf("---> watch eigen matrix memory usage!\n");    eigen::sparsematrix<double> mat(rows,cols);         // default column major fillmatrix(mat); printf("------------------------done"); return(0); }  /*-- --*/ int fillmatrix(eigen::sparsematrix<double> mat) { int i, j; eigen::vectorxd vres; mat.reserve(eigen::vectorxi::constant(cols,3000));     for(i=0;i<rows;i++)     {         if(i%500==0){printf("i= %i\n", i);}     for(j=0;j<cols;j++)         {         if (vee(i,j) != 0){mat.insert(i,j) = vee(i,j);    /*alternative: mat.coeffref(i,j) += v_ij;*/ }         }      } printf("--->starting compression");  mat.makecompressed();  return(0); } /*-- --*/ double vee(int i, int j) {     double result = 0.0;      if(j%4 == 0){result =1.0;}      return result; } /*-- --*/ 

edit

one answer reminded me needed use addresses, because local variables of fillmatrix() gone when runs through. tried following, not compile:

#include <iostream> #include <stdio.h> #include <stdlib.h>      #include <eigen/sparse> #include <gsl/gsl_matrix.h> #define rows 1e4 #define cols 1e4    /*-- declarationes --*/ int fillmatrix(eigen::sparsematrix<double> & mat); double vee(int i, int j);  int main() { printf("---> watch gsl matrix memory usage!\n");     gsl_matrix *testmat = gsl_matrix_calloc(rows, cols); sleep(20); gsl_matrix_free(testmat); printf("---> watch eigen matrix memory usage!\n");    eigen::sparsematrix<double> mat(rows,cols);         // default column major fillmatrix(& mat); printf("------------------------>done\n"); return(0); }  /*-- --*/ int fillmatrix(eigen::sparsematrix<double> &mat) { int i, j; eigen::vectorxd vres; mat.reserve(eigen::vectorxi::constant(cols,3000));     for(i=0;i<rows;i++)     {         if(i%500==0){printf("i= %i\n", i);}     for(j=0;j<cols;j++)         {         if (vee(i,j) != 0){mat.insert(i,j) = vee(i,j);    /*alternative: mat.coeffref(i,j) += v_ij;*/ }         }      } printf("--->starting compression\n");    mat.makecompressed();  return(0); } /*-- --*/ double vee(int i, int j) {     double result = 0.0;      if(i%4 == 0){result =1.0;}      return result; } /*-- --*/ 

the error messages are:

ludi@ludi-m17xr4:~/desktop/tests$ g++ -o eigenfill.x eigenfill.cc -l/usr/local/lib -lgsl -lgslcblas && ./eigenfill.x eigenfill.cc: in function ‘int main()’: eigenfill.cc:24:17: error: invalid initialization of non-const reference of type ‘eigen::sparsematrix<double>&’ rvalue of type ‘eigen::sparsematrix<double>*’  fillmatrix(& mat);                  ^ eigenfill.cc:12:5: error: in passing argument 1 of ‘int fillmatrix(eigen::sparsematrix<double>&)’  int fillmatrix(eigen::sparsematrix<double> & mat);      ^ ludi@ludi-m17xr 

edit , compiles if write:

fillmatrix(mat);

instead of

fillmatrix(&mat);

i don't understand. should not last 1 correct?

this because entirely filling 1 column on four. looks following:

1 0 0 0 1 0 0 0 1 ... 1 0 0 0 1 0 0 0 1 ... 1 0 0 0 1 0 0 0 1 ... 1 0 0 0 1 0 0 0 1 ... ... 

replacing j%4 == 0 i%4 == 0 job. memory usage exactly: 2500*cols*(sizeof(double)+sizeof(int)) + cols*sizeof(int).

you must fix prototype of fillmatrix fill real matrix , not temporary:

int fillmatrix(eigen::sparsematrix<double> &mat); 

finally, if goal work sparse matrices having 1/4 of non zeros, dense representation faster.


Comments

Popular posts from this blog

php - Invalid Cofiguration - yii\base\InvalidConfigException - Yii2 -

How to show in django cms breadcrumbs full path? -

ruby on rails - npm error: tunneling socket could not be established, cause=connect ETIMEDOUT -