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