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.

143 lines
3.2 KiB

  1. #include <iostream>
  2. #include <Eigen/Core>
  3. #include <bench/BenchTimer.h>
  4. using namespace Eigen;
  5. using namespace std;
  6. #define END 9
  7. template<int S> struct map_size { enum { ret = S }; };
  8. template<> struct map_size<10> { enum { ret = 20 }; };
  9. template<> struct map_size<11> { enum { ret = 50 }; };
  10. template<> struct map_size<12> { enum { ret = 100 }; };
  11. template<> struct map_size<13> { enum { ret = 300 }; };
  12. template<int M, int N,int K> struct alt_prod
  13. {
  14. enum {
  15. ret = M==1 && N==1 ? InnerProduct
  16. : K==1 ? OuterProduct
  17. : M==1 ? GemvProduct
  18. : N==1 ? GemvProduct
  19. : GemmProduct
  20. };
  21. };
  22. void print_mode(int mode)
  23. {
  24. if(mode==InnerProduct) std::cout << "i";
  25. if(mode==OuterProduct) std::cout << "o";
  26. if(mode==CoeffBasedProductMode) std::cout << "c";
  27. if(mode==LazyCoeffBasedProductMode) std::cout << "l";
  28. if(mode==GemvProduct) std::cout << "v";
  29. if(mode==GemmProduct) std::cout << "m";
  30. }
  31. template<int Mode, typename Lhs, typename Rhs, typename Res>
  32. EIGEN_DONT_INLINE void prod(const Lhs& a, const Rhs& b, Res& c)
  33. {
  34. c.noalias() += typename ProductReturnType<Lhs,Rhs,Mode>::Type(a,b);
  35. }
  36. template<int M, int N, int K, typename Scalar, int Mode>
  37. EIGEN_DONT_INLINE void bench_prod()
  38. {
  39. typedef Matrix<Scalar,M,K> Lhs; Lhs a; a.setRandom();
  40. typedef Matrix<Scalar,K,N> Rhs; Rhs b; b.setRandom();
  41. typedef Matrix<Scalar,M,N> Res; Res c; c.setRandom();
  42. BenchTimer t;
  43. double n = 2.*double(M)*double(N)*double(K);
  44. int rep = 100000./n;
  45. rep /= 2;
  46. if(rep<1) rep = 1;
  47. do {
  48. rep *= 2;
  49. t.reset();
  50. BENCH(t,1,rep,prod<CoeffBasedProductMode>(a,b,c));
  51. } while(t.best()<0.1);
  52. t.reset();
  53. BENCH(t,5,rep,prod<Mode>(a,b,c));
  54. print_mode(Mode);
  55. std::cout << int(1e-6*n*rep/t.best()) << "\t";
  56. }
  57. template<int N> struct print_n;
  58. template<int M, int N, int K> struct loop_on_m;
  59. template<int M, int N, int K, typename Scalar, int Mode> struct loop_on_n;
  60. template<int M, int N, int K>
  61. struct loop_on_k
  62. {
  63. static void run()
  64. {
  65. std::cout << "K=" << K << "\t";
  66. print_n<N>::run();
  67. std::cout << "\n";
  68. loop_on_m<M,N,K>::run();
  69. std::cout << "\n\n";
  70. loop_on_k<M,N,K+1>::run();
  71. }
  72. };
  73. template<int M, int N>
  74. struct loop_on_k<M,N,END> { static void run(){} };
  75. template<int M, int N, int K>
  76. struct loop_on_m
  77. {
  78. static void run()
  79. {
  80. std::cout << M << "f\t";
  81. loop_on_n<M,N,K,float,CoeffBasedProductMode>::run();
  82. std::cout << "\n";
  83. std::cout << M << "f\t";
  84. loop_on_n<M,N,K,float,-1>::run();
  85. std::cout << "\n";
  86. loop_on_m<M+1,N,K>::run();
  87. }
  88. };
  89. template<int N, int K>
  90. struct loop_on_m<END,N,K> { static void run(){} };
  91. template<int M, int N, int K, typename Scalar, int Mode>
  92. struct loop_on_n
  93. {
  94. static void run()
  95. {
  96. bench_prod<M,N,K,Scalar,Mode==-1? alt_prod<M,N,K>::ret : Mode>();
  97. loop_on_n<M,N+1,K,Scalar,Mode>::run();
  98. }
  99. };
  100. template<int M, int K, typename Scalar, int Mode>
  101. struct loop_on_n<M,END,K,Scalar,Mode> { static void run(){} };
  102. template<int N> struct print_n
  103. {
  104. static void run()
  105. {
  106. std::cout << map_size<N>::ret << "\t";
  107. print_n<N+1>::run();
  108. }
  109. };
  110. template<> struct print_n<END> { static void run(){} };
  111. int main()
  112. {
  113. loop_on_k<1,1,1>::run();
  114. return 0;
  115. }