aboutsummaryrefslogtreecommitdiffhomepage
path: root/bench/sparse_product.cpp
diff options
context:
space:
mode:
authorGravatar Gael Guennebaud <g.gael@free.fr>2008-06-28 23:07:14 +0000
committerGravatar Gael Guennebaud <g.gael@free.fr>2008-06-28 23:07:14 +0000
commit027818d7392dbb4f12db17bb9f35032727bb1a30 (patch)
tree437f31b0b222f9ad4d8e6351ba8dc6a0e00f1b8b /bench/sparse_product.cpp
parent6917be911311428567bbde2a5db430d8c2c9ef96 (diff)
* added innerSize / outerSize functions to MatrixBase
* added complete implementation of sparse matrix product (with a little glue in Eigen/Core) * added an exhaustive bench of sparse products including GMM++ and MTL4 => Eigen outperforms in all transposed/density configurations !
Diffstat (limited to 'bench/sparse_product.cpp')
-rw-r--r--bench/sparse_product.cpp199
1 files changed, 199 insertions, 0 deletions
diff --git a/bench/sparse_product.cpp b/bench/sparse_product.cpp
new file mode 100644
index 000000000..846301fa5
--- /dev/null
+++ b/bench/sparse_product.cpp
@@ -0,0 +1,199 @@
+
+//g++ -O3 -g0 -DNDEBUG sparse_product.cpp -I.. -I/home/gael/Coding/LinearAlgebra/mtl4/ -DDENSITY=0.005 -DSIZE=10000 && ./a.out
+//g++ -O3 -g0 -DNDEBUG sparse_product.cpp -I.. -I/home/gael/Coding/LinearAlgebra/mtl4/ -DDENSITY=0.05 -DSIZE=2000 && ./a.out
+// -DNOGMM -DNOMTL
+
+#ifndef SIZE
+#define SIZE 10000
+#endif
+
+#ifndef DENSITY
+#define DENSITY 0.01
+#endif
+
+#ifndef REPEAT
+#define REPEAT 1
+#endif
+
+#include "BenchSparseUtil.h"
+
+#ifndef MINDENSITY
+#define MINDENSITY 0.0004
+#endif
+
+int main(int argc, char *argv[])
+{
+ int rows = SIZE;
+ int cols = SIZE;
+ float density = DENSITY;
+
+ EigenSparseMatrix sm1(rows,cols), sm2(rows,cols), sm3(rows,cols), sm4(rows,cols);
+
+ BenchTimer timer;
+ for (float density = DENSITY; density>=MINDENSITY; density*=0.5)
+ {
+ fillMatrix(density, rows, cols, sm1);
+ fillMatrix(density, rows, cols, sm2);
+
+ // dense matrices
+ #ifdef DENSEMATRIX
+ {
+ std::cout << "Eigen Dense\t" << density*100 << "%\n";
+ DenseMatrix m1(rows,cols), m2(rows,cols), m3(rows,cols);
+ eiToDense(sm1, m1);
+ eiToDense(sm2, m2);
+
+ timer.reset();
+ timer.start();
+ for (int k=0; k<REPEAT; ++k)
+ m3 = m1 * m2;
+ timer.stop();
+ std::cout << " a * b:\t" << timer.value() << endl;
+
+ timer.reset();
+ timer.start();
+ for (int k=0; k<REPEAT; ++k)
+ m3 = m1.transpose() * m2;
+ timer.stop();
+ std::cout << " a' * b:\t" << timer.value() << endl;
+
+ timer.reset();
+ timer.start();
+ for (int k=0; k<REPEAT; ++k)
+ m3 = m1.transpose() * m2.transpose();
+ timer.stop();
+ std::cout << " a' * b':\t" << timer.value() << endl;
+
+ timer.reset();
+ timer.start();
+ for (int k=0; k<REPEAT; ++k)
+ m3 = m1 * m2.transpose();
+ timer.stop();
+ std::cout << " a * b':\t" << timer.value() << endl;
+ }
+ #endif
+
+ // eigen sparse matrices
+ {
+ std::cout << "Eigen sparse\t" << density*100 << "%\n";
+
+ timer.reset();
+ timer.start();
+ for (int k=0; k<REPEAT; ++k)
+ sm3 = sm1 * sm2;
+ timer.stop();
+ std::cout << " a * b:\t" << timer.value() << endl;
+
+ timer.reset();
+ timer.start();
+ for (int k=0; k<REPEAT; ++k)
+ sm3 = sm1.transpose() * sm2;
+ timer.stop();
+ std::cout << " a' * b:\t" << timer.value() << endl;
+
+ timer.reset();
+ timer.start();
+ for (int k=0; k<REPEAT; ++k)
+ sm3 = sm1.transpose() * sm2.transpose();
+ timer.stop();
+ std::cout << " a' * b':\t" << timer.value() << endl;
+
+ timer.reset();
+ timer.start();
+ for (int k=0; k<REPEAT; ++k)
+ sm3 = sm1 * sm2.transpose();
+ timer.stop();
+ std::cout << " a * b' :\t" << timer.value() << endl;
+ }
+
+ // GMM++
+ #ifndef NOGMM
+ {
+ std::cout << "GMM++ sparse\t" << density*100 << "%\n";
+ GmmDynSparse gmmT3(rows,cols);
+ GmmSparse m1(rows,cols), m2(rows,cols), m3(rows,cols);
+ eiToGmm(sm1, m1);
+ eiToGmm(sm2, m2);
+
+ timer.reset();
+ timer.start();
+ for (int k=0; k<REPEAT; ++k)
+ gmm::mult(m1, m2, gmmT3);
+ timer.stop();
+ std::cout << " a * b:\t" << timer.value() << endl;
+
+ timer.reset();
+ timer.start();
+ for (int k=0; k<REPEAT; ++k)
+ gmm::mult(gmm::transposed(m1), m2, gmmT3);
+ timer.stop();
+ std::cout << " a' * b:\t" << timer.value() << endl;
+
+ if (rows<500)
+ {
+ timer.reset();
+ timer.start();
+ for (int k=0; k<REPEAT; ++k)
+ gmm::mult(gmm::transposed(m1), gmm::transposed(m2), gmmT3);
+ timer.stop();
+ std::cout << " a' * b':\t" << timer.value() << endl;
+
+ timer.reset();
+ timer.start();
+ for (int k=0; k<REPEAT; ++k)
+ gmm::mult(m1, gmm::transposed(m2), gmmT3);
+ timer.stop();
+ std::cout << " a * b':\t" << timer.value() << endl;
+ }
+ else
+ {
+ std::cout << " a' * b':\t" << "forever" << endl;
+ std::cout << " a * b':\t" << "forever" << endl;
+ }
+ }
+ #endif
+
+ // MTL4
+ #ifndef NOMTL
+ {
+ std::cout << "MTL4\t" << density*100 << "%\n";
+ MtlSparse m1(rows,cols), m2(rows,cols), m3(rows,cols);
+ eiToMtl(sm1, m1);
+ eiToMtl(sm2, m2);
+
+ timer.reset();
+ timer.start();
+ for (int k=0; k<REPEAT; ++k)
+ m3 = m1 * m2;
+ timer.stop();
+ std::cout << " a * b:\t" << timer.value() << endl;
+
+ timer.reset();
+ timer.start();
+ for (int k=0; k<REPEAT; ++k)
+ m3 = trans(m1) * m2;
+ timer.stop();
+ std::cout << " a' * b:\t" << timer.value() << endl;
+
+ timer.reset();
+ timer.start();
+ for (int k=0; k<REPEAT; ++k)
+ m3 = trans(m1) * trans(m2);
+ timer.stop();
+ std::cout << " a' * b':\t" << timer.value() << endl;
+
+ timer.reset();
+ timer.start();
+ for (int k=0; k<REPEAT; ++k)
+ m3 = m1 * trans(m2);
+ timer.stop();
+ std::cout << " a * b' :\t" << timer.value() << endl;
+ }
+ #endif
+
+ std::cout << "\n\n";
+ }
+
+ return 0;
+}
+