You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

212 lines
5.7 KiB

  1. // g++ -DNDEBUG -O3 -I.. benchEigenSolver.cpp -o benchEigenSolver && ./benchEigenSolver
  2. // options:
  3. // -DBENCH_GMM
  4. // -DBENCH_GSL -lgsl /usr/lib/libcblas.so.3
  5. // -DEIGEN_DONT_VECTORIZE
  6. // -msse2
  7. // -DREPEAT=100
  8. // -DTRIES=10
  9. // -DSCALAR=double
  10. #include <iostream>
  11. #include <Eigen/Core>
  12. #include <Eigen/QR>
  13. #include <bench/BenchUtil.h>
  14. using namespace Eigen;
  15. #ifndef REPEAT
  16. #define REPEAT 1000
  17. #endif
  18. #ifndef TRIES
  19. #define TRIES 4
  20. #endif
  21. #ifndef SCALAR
  22. #define SCALAR float
  23. #endif
  24. typedef SCALAR Scalar;
  25. template <typename MatrixType>
  26. __attribute__ ((noinline)) void benchEigenSolver(const MatrixType& m)
  27. {
  28. int rows = m.rows();
  29. int cols = m.cols();
  30. int stdRepeats = std::max(1,int((REPEAT*1000)/(rows*rows*sqrt(rows))));
  31. int saRepeats = stdRepeats * 4;
  32. typedef typename MatrixType::Scalar Scalar;
  33. typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime> SquareMatrixType;
  34. MatrixType a = MatrixType::Random(rows,cols);
  35. SquareMatrixType covMat = a * a.adjoint();
  36. BenchTimer timerSa, timerStd;
  37. Scalar acc = 0;
  38. int r = internal::random<int>(0,covMat.rows()-1);
  39. int c = internal::random<int>(0,covMat.cols()-1);
  40. {
  41. SelfAdjointEigenSolver<SquareMatrixType> ei(covMat);
  42. for (int t=0; t<TRIES; ++t)
  43. {
  44. timerSa.start();
  45. for (int k=0; k<saRepeats; ++k)
  46. {
  47. ei.compute(covMat);
  48. acc += ei.eigenvectors().coeff(r,c);
  49. }
  50. timerSa.stop();
  51. }
  52. }
  53. {
  54. EigenSolver<SquareMatrixType> ei(covMat);
  55. for (int t=0; t<TRIES; ++t)
  56. {
  57. timerStd.start();
  58. for (int k=0; k<stdRepeats; ++k)
  59. {
  60. ei.compute(covMat);
  61. acc += ei.eigenvectors().coeff(r,c);
  62. }
  63. timerStd.stop();
  64. }
  65. }
  66. if (MatrixType::RowsAtCompileTime==Dynamic)
  67. std::cout << "dyn ";
  68. else
  69. std::cout << "fixed ";
  70. std::cout << covMat.rows() << " \t"
  71. << timerSa.value() * REPEAT / saRepeats << "s \t"
  72. << timerStd.value() * REPEAT / stdRepeats << "s";
  73. #ifdef BENCH_GMM
  74. if (MatrixType::RowsAtCompileTime==Dynamic)
  75. {
  76. timerSa.reset();
  77. timerStd.reset();
  78. gmm::dense_matrix<Scalar> gmmCovMat(covMat.rows(),covMat.cols());
  79. gmm::dense_matrix<Scalar> eigvect(covMat.rows(),covMat.cols());
  80. std::vector<Scalar> eigval(covMat.rows());
  81. eiToGmm(covMat, gmmCovMat);
  82. for (int t=0; t<TRIES; ++t)
  83. {
  84. timerSa.start();
  85. for (int k=0; k<saRepeats; ++k)
  86. {
  87. gmm::symmetric_qr_algorithm(gmmCovMat, eigval, eigvect);
  88. acc += eigvect(r,c);
  89. }
  90. timerSa.stop();
  91. }
  92. // the non-selfadjoint solver does not compute the eigen vectors
  93. // for (int t=0; t<TRIES; ++t)
  94. // {
  95. // timerStd.start();
  96. // for (int k=0; k<stdRepeats; ++k)
  97. // {
  98. // gmm::implicit_qr_algorithm(gmmCovMat, eigval, eigvect);
  99. // acc += eigvect(r,c);
  100. // }
  101. // timerStd.stop();
  102. // }
  103. std::cout << " | \t"
  104. << timerSa.value() * REPEAT / saRepeats << "s"
  105. << /*timerStd.value() * REPEAT / stdRepeats << "s"*/ " na ";
  106. }
  107. #endif
  108. #ifdef BENCH_GSL
  109. if (MatrixType::RowsAtCompileTime==Dynamic)
  110. {
  111. timerSa.reset();
  112. timerStd.reset();
  113. gsl_matrix* gslCovMat = gsl_matrix_alloc(covMat.rows(),covMat.cols());
  114. gsl_matrix* gslCopy = gsl_matrix_alloc(covMat.rows(),covMat.cols());
  115. gsl_matrix* eigvect = gsl_matrix_alloc(covMat.rows(),covMat.cols());
  116. gsl_vector* eigval = gsl_vector_alloc(covMat.rows());
  117. gsl_eigen_symmv_workspace* eisymm = gsl_eigen_symmv_alloc(covMat.rows());
  118. gsl_matrix_complex* eigvectz = gsl_matrix_complex_alloc(covMat.rows(),covMat.cols());
  119. gsl_vector_complex* eigvalz = gsl_vector_complex_alloc(covMat.rows());
  120. gsl_eigen_nonsymmv_workspace* einonsymm = gsl_eigen_nonsymmv_alloc(covMat.rows());
  121. eiToGsl(covMat, &gslCovMat);
  122. for (int t=0; t<TRIES; ++t)
  123. {
  124. timerSa.start();
  125. for (int k=0; k<saRepeats; ++k)
  126. {
  127. gsl_matrix_memcpy(gslCopy,gslCovMat);
  128. gsl_eigen_symmv(gslCopy, eigval, eigvect, eisymm);
  129. acc += gsl_matrix_get(eigvect,r,c);
  130. }
  131. timerSa.stop();
  132. }
  133. for (int t=0; t<TRIES; ++t)
  134. {
  135. timerStd.start();
  136. for (int k=0; k<stdRepeats; ++k)
  137. {
  138. gsl_matrix_memcpy(gslCopy,gslCovMat);
  139. gsl_eigen_nonsymmv(gslCopy, eigvalz, eigvectz, einonsymm);
  140. acc += GSL_REAL(gsl_matrix_complex_get(eigvectz,r,c));
  141. }
  142. timerStd.stop();
  143. }
  144. std::cout << " | \t"
  145. << timerSa.value() * REPEAT / saRepeats << "s \t"
  146. << timerStd.value() * REPEAT / stdRepeats << "s";
  147. gsl_matrix_free(gslCovMat);
  148. gsl_vector_free(gslCopy);
  149. gsl_matrix_free(eigvect);
  150. gsl_vector_free(eigval);
  151. gsl_matrix_complex_free(eigvectz);
  152. gsl_vector_complex_free(eigvalz);
  153. gsl_eigen_symmv_free(eisymm);
  154. gsl_eigen_nonsymmv_free(einonsymm);
  155. }
  156. #endif
  157. std::cout << "\n";
  158. // make sure the compiler does not optimize too much
  159. if (acc==123)
  160. std::cout << acc;
  161. }
  162. int main(int argc, char* argv[])
  163. {
  164. const int dynsizes[] = {4,6,8,12,16,24,32,64,128,256,512,0};
  165. std::cout << "size selfadjoint generic";
  166. #ifdef BENCH_GMM
  167. std::cout << " GMM++ ";
  168. #endif
  169. #ifdef BENCH_GSL
  170. std::cout << " GSL (double + ATLAS) ";
  171. #endif
  172. std::cout << "\n";
  173. for (uint i=0; dynsizes[i]>0; ++i)
  174. benchEigenSolver(Matrix<Scalar,Dynamic,Dynamic>(dynsizes[i],dynsizes[i]));
  175. benchEigenSolver(Matrix<Scalar,2,2>());
  176. benchEigenSolver(Matrix<Scalar,3,3>());
  177. benchEigenSolver(Matrix<Scalar,4,4>());
  178. benchEigenSolver(Matrix<Scalar,6,6>());
  179. benchEigenSolver(Matrix<Scalar,8,8>());
  180. benchEigenSolver(Matrix<Scalar,12,12>());
  181. benchEigenSolver(Matrix<Scalar,16,16>());
  182. return 0;
  183. }