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