1c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
2c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//g++ -O3 -g0 -DNDEBUG  sparse_product.cpp -I.. -I/home/gael/Coding/LinearAlgebra/mtl4/ -DDENSITY=0.005 -DSIZE=10000 && ./a.out
3c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//g++ -O3 -g0 -DNDEBUG  sparse_product.cpp -I.. -I/home/gael/Coding/LinearAlgebra/mtl4/ -DDENSITY=0.05 -DSIZE=2000 && ./a.out
4c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// -DNOGMM -DNOMTL -DCSPARSE
5c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// -I /home/gael/Coding/LinearAlgebra/CSparse/Include/ /home/gael/Coding/LinearAlgebra/CSparse/Lib/libcsparse.a
6c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#ifndef SIZE
7c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#define SIZE 650000
8c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#endif
9c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
10c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#ifndef DENSITY
11c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#define DENSITY 0.01
12c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#endif
13c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
14c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#ifndef REPEAT
15c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#define REPEAT 1
16c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#endif
17c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
18c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#include "BenchSparseUtil.h"
19c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
20c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#ifndef MINDENSITY
21c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#define MINDENSITY 0.0004
22c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#endif
23c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
24c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#ifndef NBTRIES
25c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#define NBTRIES 10
26c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#endif
27c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
28c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#define BENCH(X) \
29c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  timer.reset(); \
30c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  for (int _j=0; _j<NBTRIES; ++_j) { \
31c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    timer.start(); \
32c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    for (int _k=0; _k<REPEAT; ++_k) { \
33c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        X  \
34c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  } timer.stop(); }
35c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
36c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
37c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#ifdef CSPARSE
38c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathcs* cs_sorted_multiply(const cs* a, const cs* b)
39c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
40c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  cs* A = cs_transpose (a, 1) ;
41c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  cs* B = cs_transpose (b, 1) ;
42c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  cs* D = cs_multiply (B,A) ;   /* D = B'*A' */
43c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  cs_spfree (A) ;
44c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  cs_spfree (B) ;
45c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  cs_dropzeros (D) ;      /* drop zeros from D */
46c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  cs* C = cs_transpose (D, 1) ;   /* C = D', so that C is sorted */
47c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  cs_spfree (D) ;
48c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  return C;
49c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
50c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#endif
51c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
52c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathint main(int argc, char *argv[])
53c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
54c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  int rows = SIZE;
55c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  int cols = SIZE;
56c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  float density = DENSITY;
57c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
58c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  EigenSparseMatrix sm1(rows,cols);
59c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  DenseVector v1(cols), v2(cols);
60c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  v1.setRandom();
61c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
62c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  BenchTimer timer;
63c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  for (float density = DENSITY; density>=MINDENSITY; density*=0.5)
64c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
65c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    //fillMatrix(density, rows, cols, sm1);
66c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    fillMatrix2(7, rows, cols, sm1);
67c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
68c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    // dense matrices
69c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    #ifdef DENSEMATRIX
70c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
71c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      std::cout << "Eigen Dense\t" << density*100 << "%\n";
72c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      DenseMatrix m1(rows,cols);
73c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      eiToDense(sm1, m1);
74c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
75c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      timer.reset();
76c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      timer.start();
77c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      for (int k=0; k<REPEAT; ++k)
78c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        v2 = m1 * v1;
79c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      timer.stop();
80c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      std::cout << "   a * v:\t" << timer.best() << "  " << double(REPEAT)/timer.best() << " * / sec " << endl;
81c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
82c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      timer.reset();
83c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      timer.start();
84c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      for (int k=0; k<REPEAT; ++k)
85c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        v2 = m1.transpose() * v1;
86c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      timer.stop();
87c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      std::cout << "   a' * v:\t" << timer.best() << endl;
88c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
89c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    #endif
90c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
91c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    // eigen sparse matrices
92c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
93c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      std::cout << "Eigen sparse\t" << sm1.nonZeros()/float(sm1.rows()*sm1.cols())*100 << "%\n";
94c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
95c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      BENCH(asm("#myc"); v2 = sm1 * v1; asm("#myd");)
96c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      std::cout << "   a * v:\t" << timer.best()/REPEAT << "  " << double(REPEAT)/timer.best(REAL_TIMER) << " * / sec " << endl;
97c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
98c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
99c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      BENCH( { asm("#mya"); v2 = sm1.transpose() * v1; asm("#myb"); })
100c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
101c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      std::cout << "   a' * v:\t" << timer.best()/REPEAT << endl;
102c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
103c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
104c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//     {
105c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//       DynamicSparseMatrix<Scalar> m1(sm1);
106c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//       std::cout << "Eigen dyn-sparse\t" << m1.nonZeros()/float(m1.rows()*m1.cols())*100 << "%\n";
107c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//
108c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//       BENCH(for (int k=0; k<REPEAT; ++k) v2 = m1 * v1;)
109c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//       std::cout << "   a * v:\t" << timer.value() << endl;
110c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//
111c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//       BENCH(for (int k=0; k<REPEAT; ++k) v2 = m1.transpose() * v1;)
112c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//       std::cout << "   a' * v:\t" << timer.value() << endl;
113c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//     }
114c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
115c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    // GMM++
116c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    #ifndef NOGMM
117c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
118c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      std::cout << "GMM++ sparse\t" << density*100 << "%\n";
119c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      //GmmDynSparse  gmmT3(rows,cols);
120c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      GmmSparse m1(rows,cols);
121c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      eiToGmm(sm1, m1);
122c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
123c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      std::vector<Scalar> gmmV1(cols), gmmV2(cols);
124c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      Map<Matrix<Scalar,Dynamic,1> >(&gmmV1[0], cols) = v1;
125c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      Map<Matrix<Scalar,Dynamic,1> >(&gmmV2[0], cols) = v2;
126c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
127c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      BENCH( asm("#myx"); gmm::mult(m1, gmmV1, gmmV2); asm("#myy"); )
128c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      std::cout << "   a * v:\t" << timer.value() << endl;
129c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
130c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      BENCH( gmm::mult(gmm::transposed(m1), gmmV1, gmmV2); )
131c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      std::cout << "   a' * v:\t" << timer.value() << endl;
132c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
133c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    #endif
134c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
135c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    #ifndef NOUBLAS
136c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
137c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      std::cout << "ublas sparse\t" << density*100 << "%\n";
138c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      UBlasSparse m1(rows,cols);
139c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      eiToUblas(sm1, m1);
140c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
141c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      boost::numeric::ublas::vector<Scalar> uv1, uv2;
142c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      eiToUblasVec(v1,uv1);
143c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      eiToUblasVec(v2,uv2);
144c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
145c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//       std::vector<Scalar> gmmV1(cols), gmmV2(cols);
146c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//       Map<Matrix<Scalar,Dynamic,1> >(&gmmV1[0], cols) = v1;
147c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//       Map<Matrix<Scalar,Dynamic,1> >(&gmmV2[0], cols) = v2;
148c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
149c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      BENCH( uv2 = boost::numeric::ublas::prod(m1, uv1); )
150c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      std::cout << "   a * v:\t" << timer.value() << endl;
151c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
152c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//       BENCH( boost::ublas::prod(gmm::transposed(m1), gmmV1, gmmV2); )
153c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//       std::cout << "   a' * v:\t" << timer.value() << endl;
154c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
155c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    #endif
156c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
157c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    // MTL4
158c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    #ifndef NOMTL
159c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
160c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      std::cout << "MTL4\t" << density*100 << "%\n";
161c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      MtlSparse m1(rows,cols);
162c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      eiToMtl(sm1, m1);
163c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      mtl::dense_vector<Scalar> mtlV1(cols, 1.0);
164c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      mtl::dense_vector<Scalar> mtlV2(cols, 1.0);
165c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
166c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      timer.reset();
167c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      timer.start();
168c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      for (int k=0; k<REPEAT; ++k)
169c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        mtlV2 = m1 * mtlV1;
170c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      timer.stop();
171c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      std::cout << "   a * v:\t" << timer.value() << endl;
172c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
173c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      timer.reset();
174c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      timer.start();
175c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      for (int k=0; k<REPEAT; ++k)
176c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        mtlV2 = trans(m1) * mtlV1;
177c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      timer.stop();
178c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      std::cout << "   a' * v:\t" << timer.value() << endl;
179c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
180c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    #endif
181c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
182c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    std::cout << "\n\n";
183c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
184c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
185c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  return 0;
186c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
187c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
188