22 #define CBLAS_GEMM cblas_sgemm 25 #define CBLAS_GEMM cblas_dgemm 34 int main(
int argc,
char *argv[])
42 "orl $32832, %[aux] \n\t" 48 int nbtries=1, nbloops=1,
M,
N,
K;
52 if (std::string(argv[1])==
"check")
55 M = N = K = atoi(argv[1]);
57 else if ((argc==3) && (std::string(argv[1])==
"auto"))
59 M = N = K = atoi(argv[2]);
60 nbloops = 1000000000/(
M*
M*
M);
67 M = N = K = atoi(argv[1]);
68 nbloops = atoi(argv[2]);
69 nbtries = atoi(argv[3]);
76 nbloops = atoi(argv[4]);
77 nbtries = atoi(argv[5]);
81 std::cout <<
"Usage: " << argv[0] <<
" size \n";
82 std::cout <<
"Usage: " << argv[0] <<
" auto size\n";
83 std::cout <<
"Usage: " << argv[0] <<
" size nbloops nbtries\n";
84 std::cout <<
"Usage: " << argv[0] <<
" M N K nbloops nbtries\n";
85 std::cout <<
"Usage: " << argv[0] <<
" check\n";
86 std::cout <<
"Options:\n";
87 std::cout <<
" size unique size of the 2 matrices (integer)\n";
88 std::cout <<
" auto automatically set the number of repetitions and tries\n";
89 std::cout <<
" nbloops number of times the GEMM routines is executed\n";
90 std::cout <<
" nbtries number of times the loop is benched (return the best try)\n";
91 std::cout <<
" M N K sizes of the matrices: MxN = MxK * KxN (integers)\n";
92 std::cout <<
" check check eigen product using cblas as a reference\n";
96 double nbmad = double(
M) * double(N) * double(K) * double(nbloops);
98 if (!(std::string(argv[1])==
"auto"))
99 std::cout <<
M <<
" x " << N <<
" x " << K <<
"\n";
103 ma = MyMatrix::Random(
M,K);
104 mb = MyMatrix::Random(K,N);
105 mc = MyMatrix::Random(
M,N);
115 if (!(std::string(argv[1])==
"auto"))
118 for (uint k=0 ; k<nbtries ; ++k)
121 for (uint
j=0 ;
j<nbloops ; ++
j)
122 #ifdef EIGEN_DEFAULT_TO_ROW_MAJOR
123 CBLAS_GEMM(CblasRowMajor, CblasNoTrans, CblasNoTrans,
M, N, K, alpha, ma.data(),
K, mb.data(),
N, beta, mc.
data(),
N);
125 CBLAS_GEMM(CblasColMajor, CblasNoTrans, CblasNoTrans,
M, N, K, alpha, ma.data(),
M, mb.data(),
K, beta, mc.
data(),
M);
129 if (!(std::string(argv[1])==
"auto"))
130 std::cout <<
"cblas: " << timer.
value() <<
" (" << 1
e-3*
floor(1
e-6*nbmad/timer.
value()) <<
" GFlops/s)\n";
132 std::cout <<
M <<
" : " << timer.
value() <<
" ; " << 1
e-3*
floor(1
e-6*nbmad/timer.
value()) <<
"\n";
136 ma = MyMatrix::Random(
M,K);
137 mb = MyMatrix::Random(K,N);
138 mc = MyMatrix::Random(
M,N);
144 for (uint k=0 ; k<nbtries ; ++k)
150 if (!(std::string(argv[1])==
"auto"))
151 std::cout <<
"eigen : " << timer.
value() <<
" (" << 1
e-3*
floor(1
e-6*nbmad/timer.
value()) <<
" GFlops/s)\n";
153 std::cout <<
M <<
" : " << timer.
value() <<
" ; " << 1
e-3*
floor(1
e-6*nbmad/timer.
value()) <<
"\n";
163 using namespace Eigen;
167 for (uint
j=0 ;
j<nbloops ; ++
j)
168 mc.noalias() += ma * mb;
171 #define MYVERIFY(A,M) if (!(A)) { \ 172 std::cout << "FAIL: " << M << "\n"; \ 176 MyMatrix ma(M,K), mb(K,N), mc(M,N), maT(K,M), mbT(N,K), meigen(M,N), mref(M,N);
177 ma = MyMatrix::Random(M,K);
178 mb = MyMatrix::Random(K,N);
179 maT = ma.transpose();
180 mbT = mb.transpose();
181 mc = MyMatrix::Random(M,N);
186 CBLAS_GEMM(CblasColMajor, CblasNoTrans, CblasNoTrans, M, N, K, 1, ma.data(),
M, mb.data(),
K, 1, mref.
data(),
M);
188 MYVERIFY(meigen.isApprox(mref, eps),
". * .");
191 CBLAS_GEMM(CblasColMajor, CblasTrans, CblasNoTrans, M, N, K, 1, maT.data(),
K, mb.data(),
K, 1, mref.
data(),
M);
192 meigen += maT.transpose() * mb;
193 MYVERIFY(meigen.isApprox(mref, eps),
"T * .");
196 CBLAS_GEMM(CblasColMajor, CblasTrans, CblasTrans, M, N, K, 1, maT.data(),
K, mbT.data(),
N, 1, mref.
data(),
M);
197 meigen += (maT.transpose()) * (mbT.transpose());
198 MYVERIFY(meigen.isApprox(mref, eps),
"T * T");
201 CBLAS_GEMM(CblasColMajor, CblasNoTrans, CblasTrans, M, N, K, 1, ma.data(),
M, mbT.data(),
N, 1, mref.
data(),
M);
202 meigen += ma * mbT.transpose();
203 MYVERIFY(meigen.isApprox(mref, eps),
". * T");
209 for (uint
i=0;
i<1000; ++
i)
211 M = internal::random<int>(1,64);
212 N = internal::random<int>(1,768);
213 K = internal::random<int>(1,768);
215 std::cout << M <<
" x " << N <<
" x " << K <<
"\n";
internal::traits< Derived >::Scalar Scalar
Matrix< RealScalar, Dynamic, Dynamic > M
void check_product(int M, int N, int K)
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar * data() const
Eigen::Matrix< Scalar, Eigen::Dynamic, Eigen::Dynamic > MyMatrix
double value(int TIMER=CPU_TIMER) const
Namespace containing all symbols from the Eigen library.
static Cal3_S2 K(500, 500, 0.1, 640/2, 480/2)
EIGEN_DEVICE_FUNC const FloorReturnType floor() const
std::ptrdiff_t l2CacheSize()
Array< double, 1, 3 > e(1./3., 0.5, 2.)
void bench_eigengemm(MyMatrix &mc, const MyMatrix &ma, const MyMatrix &mb, int nbloops)
int main(int argc, char *argv[])
std::ptrdiff_t l1CacheSize()