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
Post a Comment