1*bf2c3715SXin Li
2*bf2c3715SXin Li //g++ -O3 -g0 -DNDEBUG sparse_product.cpp -I.. -I/home/gael/Coding/LinearAlgebra/mtl4/ -DDENSITY=0.005 -DSIZE=10000 && ./a.out
3*bf2c3715SXin Li //g++ -O3 -g0 -DNDEBUG sparse_product.cpp -I.. -I/home/gael/Coding/LinearAlgebra/mtl4/ -DDENSITY=0.05 -DSIZE=2000 && ./a.out
4*bf2c3715SXin Li // -DNOGMM -DNOMTL
5*bf2c3715SXin Li // -I /home/gael/Coding/LinearAlgebra/CSparse/Include/ /home/gael/Coding/LinearAlgebra/CSparse/Lib/libcsparse.a
6*bf2c3715SXin Li
7*bf2c3715SXin Li #ifndef SIZE
8*bf2c3715SXin Li #define SIZE 10000
9*bf2c3715SXin Li #endif
10*bf2c3715SXin Li
11*bf2c3715SXin Li #ifndef DENSITY
12*bf2c3715SXin Li #define DENSITY 0.01
13*bf2c3715SXin Li #endif
14*bf2c3715SXin Li
15*bf2c3715SXin Li #ifndef REPEAT
16*bf2c3715SXin Li #define REPEAT 1
17*bf2c3715SXin Li #endif
18*bf2c3715SXin Li
19*bf2c3715SXin Li #include "BenchSparseUtil.h"
20*bf2c3715SXin Li
21*bf2c3715SXin Li #ifndef MINDENSITY
22*bf2c3715SXin Li #define MINDENSITY 0.0004
23*bf2c3715SXin Li #endif
24*bf2c3715SXin Li
25*bf2c3715SXin Li #ifndef NBTRIES
26*bf2c3715SXin Li #define NBTRIES 10
27*bf2c3715SXin Li #endif
28*bf2c3715SXin Li
29*bf2c3715SXin Li #define BENCH(X) \
30*bf2c3715SXin Li timer.reset(); \
31*bf2c3715SXin Li for (int _j=0; _j<NBTRIES; ++_j) { \
32*bf2c3715SXin Li timer.start(); \
33*bf2c3715SXin Li for (int _k=0; _k<REPEAT; ++_k) { \
34*bf2c3715SXin Li X \
35*bf2c3715SXin Li } timer.stop(); }
36*bf2c3715SXin Li
37*bf2c3715SXin Li typedef SparseMatrix<Scalar,UpperTriangular> EigenSparseTriMatrix;
38*bf2c3715SXin Li typedef SparseMatrix<Scalar,RowMajorBit|UpperTriangular> EigenSparseTriMatrixRow;
39*bf2c3715SXin Li
fillMatrix(float density,int rows,int cols,EigenSparseTriMatrix & dst)40*bf2c3715SXin Li void fillMatrix(float density, int rows, int cols, EigenSparseTriMatrix& dst)
41*bf2c3715SXin Li {
42*bf2c3715SXin Li dst.startFill(rows*cols*density);
43*bf2c3715SXin Li for(int j = 0; j < cols; j++)
44*bf2c3715SXin Li {
45*bf2c3715SXin Li for(int i = 0; i < j; i++)
46*bf2c3715SXin Li {
47*bf2c3715SXin Li Scalar v = (internal::random<float>(0,1) < density) ? internal::random<Scalar>() : 0;
48*bf2c3715SXin Li if (v!=0)
49*bf2c3715SXin Li dst.fill(i,j) = v;
50*bf2c3715SXin Li }
51*bf2c3715SXin Li dst.fill(j,j) = internal::random<Scalar>();
52*bf2c3715SXin Li }
53*bf2c3715SXin Li dst.endFill();
54*bf2c3715SXin Li }
55*bf2c3715SXin Li
main(int argc,char * argv[])56*bf2c3715SXin Li int main(int argc, char *argv[])
57*bf2c3715SXin Li {
58*bf2c3715SXin Li int rows = SIZE;
59*bf2c3715SXin Li int cols = SIZE;
60*bf2c3715SXin Li float density = DENSITY;
61*bf2c3715SXin Li BenchTimer timer;
62*bf2c3715SXin Li #if 1
63*bf2c3715SXin Li EigenSparseTriMatrix sm1(rows,cols);
64*bf2c3715SXin Li typedef Matrix<Scalar,Dynamic,1> DenseVector;
65*bf2c3715SXin Li DenseVector b = DenseVector::Random(cols);
66*bf2c3715SXin Li DenseVector x = DenseVector::Random(cols);
67*bf2c3715SXin Li
68*bf2c3715SXin Li bool densedone = false;
69*bf2c3715SXin Li
70*bf2c3715SXin Li for (float density = DENSITY; density>=MINDENSITY; density*=0.5)
71*bf2c3715SXin Li {
72*bf2c3715SXin Li EigenSparseTriMatrix sm1(rows, cols);
73*bf2c3715SXin Li fillMatrix(density, rows, cols, sm1);
74*bf2c3715SXin Li
75*bf2c3715SXin Li // dense matrices
76*bf2c3715SXin Li #ifdef DENSEMATRIX
77*bf2c3715SXin Li if (!densedone)
78*bf2c3715SXin Li {
79*bf2c3715SXin Li densedone = true;
80*bf2c3715SXin Li std::cout << "Eigen Dense\t" << density*100 << "%\n";
81*bf2c3715SXin Li DenseMatrix m1(rows,cols);
82*bf2c3715SXin Li Matrix<Scalar,Dynamic,Dynamic,Dynamic,Dynamic,RowMajorBit> m2(rows,cols);
83*bf2c3715SXin Li eiToDense(sm1, m1);
84*bf2c3715SXin Li m2 = m1;
85*bf2c3715SXin Li
86*bf2c3715SXin Li BENCH(x = m1.marked<UpperTriangular>().solveTriangular(b);)
87*bf2c3715SXin Li std::cout << " colmajor^-1 * b:\t" << timer.value() << endl;
88*bf2c3715SXin Li // std::cerr << x.transpose() << "\n";
89*bf2c3715SXin Li
90*bf2c3715SXin Li BENCH(x = m2.marked<UpperTriangular>().solveTriangular(b);)
91*bf2c3715SXin Li std::cout << " rowmajor^-1 * b:\t" << timer.value() << endl;
92*bf2c3715SXin Li // std::cerr << x.transpose() << "\n";
93*bf2c3715SXin Li }
94*bf2c3715SXin Li #endif
95*bf2c3715SXin Li
96*bf2c3715SXin Li // eigen sparse matrices
97*bf2c3715SXin Li {
98*bf2c3715SXin Li std::cout << "Eigen sparse\t" << density*100 << "%\n";
99*bf2c3715SXin Li EigenSparseTriMatrixRow sm2 = sm1;
100*bf2c3715SXin Li
101*bf2c3715SXin Li BENCH(x = sm1.solveTriangular(b);)
102*bf2c3715SXin Li std::cout << " colmajor^-1 * b:\t" << timer.value() << endl;
103*bf2c3715SXin Li // std::cerr << x.transpose() << "\n";
104*bf2c3715SXin Li
105*bf2c3715SXin Li BENCH(x = sm2.solveTriangular(b);)
106*bf2c3715SXin Li std::cout << " rowmajor^-1 * b:\t" << timer.value() << endl;
107*bf2c3715SXin Li // std::cerr << x.transpose() << "\n";
108*bf2c3715SXin Li
109*bf2c3715SXin Li // x = b;
110*bf2c3715SXin Li // BENCH(sm1.inverseProductInPlace(x);)
111*bf2c3715SXin Li // std::cout << " colmajor^-1 * b:\t" << timer.value() << " (inplace)" << endl;
112*bf2c3715SXin Li // std::cerr << x.transpose() << "\n";
113*bf2c3715SXin Li //
114*bf2c3715SXin Li // x = b;
115*bf2c3715SXin Li // BENCH(sm2.inverseProductInPlace(x);)
116*bf2c3715SXin Li // std::cout << " rowmajor^-1 * b:\t" << timer.value() << " (inplace)" << endl;
117*bf2c3715SXin Li // std::cerr << x.transpose() << "\n";
118*bf2c3715SXin Li }
119*bf2c3715SXin Li
120*bf2c3715SXin Li
121*bf2c3715SXin Li
122*bf2c3715SXin Li // CSparse
123*bf2c3715SXin Li #ifdef CSPARSE
124*bf2c3715SXin Li {
125*bf2c3715SXin Li std::cout << "CSparse \t" << density*100 << "%\n";
126*bf2c3715SXin Li cs *m1;
127*bf2c3715SXin Li eiToCSparse(sm1, m1);
128*bf2c3715SXin Li
129*bf2c3715SXin Li BENCH(x = b; if (!cs_lsolve (m1, x.data())){std::cerr << "cs_lsolve failed\n"; break;}; )
130*bf2c3715SXin Li std::cout << " colmajor^-1 * b:\t" << timer.value() << endl;
131*bf2c3715SXin Li }
132*bf2c3715SXin Li #endif
133*bf2c3715SXin Li
134*bf2c3715SXin Li // GMM++
135*bf2c3715SXin Li #ifndef NOGMM
136*bf2c3715SXin Li {
137*bf2c3715SXin Li std::cout << "GMM++ sparse\t" << density*100 << "%\n";
138*bf2c3715SXin Li GmmSparse m1(rows,cols);
139*bf2c3715SXin Li gmm::csr_matrix<Scalar> m2;
140*bf2c3715SXin Li eiToGmm(sm1, m1);
141*bf2c3715SXin Li gmm::copy(m1,m2);
142*bf2c3715SXin Li std::vector<Scalar> gmmX(cols), gmmB(cols);
143*bf2c3715SXin Li Map<Matrix<Scalar,Dynamic,1> >(&gmmX[0], cols) = x;
144*bf2c3715SXin Li Map<Matrix<Scalar,Dynamic,1> >(&gmmB[0], cols) = b;
145*bf2c3715SXin Li
146*bf2c3715SXin Li gmmX = gmmB;
147*bf2c3715SXin Li BENCH(gmm::upper_tri_solve(m1, gmmX, false);)
148*bf2c3715SXin Li std::cout << " colmajor^-1 * b:\t" << timer.value() << endl;
149*bf2c3715SXin Li // std::cerr << Map<Matrix<Scalar,Dynamic,1> >(&gmmX[0], cols).transpose() << "\n";
150*bf2c3715SXin Li
151*bf2c3715SXin Li gmmX = gmmB;
152*bf2c3715SXin Li BENCH(gmm::upper_tri_solve(m2, gmmX, false);)
153*bf2c3715SXin Li timer.stop();
154*bf2c3715SXin Li std::cout << " rowmajor^-1 * b:\t" << timer.value() << endl;
155*bf2c3715SXin Li // std::cerr << Map<Matrix<Scalar,Dynamic,1> >(&gmmX[0], cols).transpose() << "\n";
156*bf2c3715SXin Li }
157*bf2c3715SXin Li #endif
158*bf2c3715SXin Li
159*bf2c3715SXin Li // MTL4
160*bf2c3715SXin Li #ifndef NOMTL
161*bf2c3715SXin Li {
162*bf2c3715SXin Li std::cout << "MTL4\t" << density*100 << "%\n";
163*bf2c3715SXin Li MtlSparse m1(rows,cols);
164*bf2c3715SXin Li MtlSparseRowMajor m2(rows,cols);
165*bf2c3715SXin Li eiToMtl(sm1, m1);
166*bf2c3715SXin Li m2 = m1;
167*bf2c3715SXin Li mtl::dense_vector<Scalar> x(rows, 1.0);
168*bf2c3715SXin Li mtl::dense_vector<Scalar> b(rows, 1.0);
169*bf2c3715SXin Li
170*bf2c3715SXin Li BENCH(x = mtl::upper_trisolve(m1,b);)
171*bf2c3715SXin Li std::cout << " colmajor^-1 * b:\t" << timer.value() << endl;
172*bf2c3715SXin Li // std::cerr << x << "\n";
173*bf2c3715SXin Li
174*bf2c3715SXin Li BENCH(x = mtl::upper_trisolve(m2,b);)
175*bf2c3715SXin Li std::cout << " rowmajor^-1 * b:\t" << timer.value() << endl;
176*bf2c3715SXin Li // std::cerr << x << "\n";
177*bf2c3715SXin Li }
178*bf2c3715SXin Li #endif
179*bf2c3715SXin Li
180*bf2c3715SXin Li
181*bf2c3715SXin Li std::cout << "\n\n";
182*bf2c3715SXin Li }
183*bf2c3715SXin Li #endif
184*bf2c3715SXin Li
185*bf2c3715SXin Li #if 0
186*bf2c3715SXin Li // bench small matrices (in-place versus return bye value)
187*bf2c3715SXin Li {
188*bf2c3715SXin Li timer.reset();
189*bf2c3715SXin Li for (int _j=0; _j<10; ++_j) {
190*bf2c3715SXin Li Matrix4f m = Matrix4f::Random();
191*bf2c3715SXin Li Vector4f b = Vector4f::Random();
192*bf2c3715SXin Li Vector4f x = Vector4f::Random();
193*bf2c3715SXin Li timer.start();
194*bf2c3715SXin Li for (int _k=0; _k<1000000; ++_k) {
195*bf2c3715SXin Li b = m.inverseProduct(b);
196*bf2c3715SXin Li }
197*bf2c3715SXin Li timer.stop();
198*bf2c3715SXin Li }
199*bf2c3715SXin Li std::cout << "4x4 :\t" << timer.value() << endl;
200*bf2c3715SXin Li }
201*bf2c3715SXin Li
202*bf2c3715SXin Li {
203*bf2c3715SXin Li timer.reset();
204*bf2c3715SXin Li for (int _j=0; _j<10; ++_j) {
205*bf2c3715SXin Li Matrix4f m = Matrix4f::Random();
206*bf2c3715SXin Li Vector4f b = Vector4f::Random();
207*bf2c3715SXin Li Vector4f x = Vector4f::Random();
208*bf2c3715SXin Li timer.start();
209*bf2c3715SXin Li for (int _k=0; _k<1000000; ++_k) {
210*bf2c3715SXin Li m.inverseProductInPlace(x);
211*bf2c3715SXin Li }
212*bf2c3715SXin Li timer.stop();
213*bf2c3715SXin Li }
214*bf2c3715SXin Li std::cout << "4x4 IP :\t" << timer.value() << endl;
215*bf2c3715SXin Li }
216*bf2c3715SXin Li #endif
217*bf2c3715SXin Li
218*bf2c3715SXin Li return 0;
219*bf2c3715SXin Li }
220*bf2c3715SXin Li
221