// g++ -O3 -DNDEBUG -I.. -L /usr/lib64/atlas/ benchBlasGemm.cpp -o benchBlasGemm -lrt -lcblas // possible options: // -DSTORMEIGEN_DONT_VECTORIZE // -msse2 // #define STORMEIGEN_DEFAULT_TO_ROW_MAJOR #define _FLOAT #include #include #include "BenchTimer.h" // include the BLAS headers extern "C" { #include } #include #ifdef _FLOAT typedef float Scalar; #define CBLAS_GEMM cblas_sgemm #else typedef double Scalar; #define CBLAS_GEMM cblas_dgemm #endif typedef StormEigen::Matrix MyMatrix; void bench_eigengemm(MyMatrix& mc, const MyMatrix& ma, const MyMatrix& mb, int nbloops); void check_product(int M, int N, int K); void check_product(void); int main(int argc, char *argv[]) { // disable SSE exceptions #ifdef __GNUC__ { int aux; asm( "stmxcsr %[aux] \n\t" "orl $32832, %[aux] \n\t" "ldmxcsr %[aux] \n\t" : : [aux] "m" (aux)); } #endif int nbtries=1, nbloops=1, M, N, K; if (argc==2) { if (std::string(argv[1])=="check") check_product(); else M = N = K = atoi(argv[1]); } else if ((argc==3) && (std::string(argv[1])=="auto")) { M = N = K = atoi(argv[2]); nbloops = 1000000000/(M*M*M); if (nbloops<1) nbloops = 1; nbtries = 6; } else if (argc==4) { M = N = K = atoi(argv[1]); nbloops = atoi(argv[2]); nbtries = atoi(argv[3]); } else if (argc==6) { M = atoi(argv[1]); N = atoi(argv[2]); K = atoi(argv[3]); nbloops = atoi(argv[4]); nbtries = atoi(argv[5]); } else { std::cout << "Usage: " << argv[0] << " size \n"; std::cout << "Usage: " << argv[0] << " auto size\n"; std::cout << "Usage: " << argv[0] << " size nbloops nbtries\n"; std::cout << "Usage: " << argv[0] << " M N K nbloops nbtries\n"; std::cout << "Usage: " << argv[0] << " check\n"; std::cout << "Options:\n"; std::cout << " size unique size of the 2 matrices (integer)\n"; std::cout << " auto automatically set the number of repetitions and tries\n"; std::cout << " nbloops number of times the GEMM routines is executed\n"; std::cout << " nbtries number of times the loop is benched (return the best try)\n"; std::cout << " M N K sizes of the matrices: MxN = MxK * KxN (integers)\n"; std::cout << " check check eigen product using cblas as a reference\n"; exit(1); } double nbmad = double(M) * double(N) * double(K) * double(nbloops); if (!(std::string(argv[1])=="auto")) std::cout << M << " x " << N << " x " << K << "\n"; Scalar alpha, beta; MyMatrix ma(M,K), mb(K,N), mc(M,N); ma = MyMatrix::Random(M,K); mb = MyMatrix::Random(K,N); mc = MyMatrix::Random(M,N); StormEigen::BenchTimer timer; // we simply compute c += a*b, so: alpha = 1; beta = 1; // bench cblas // ROWS_A, COLS_B, COLS_A, 1.0, A, COLS_A, B, COLS_B, 0.0, C, COLS_B); if (!(std::string(argv[1])=="auto")) { timer.reset(); for (uint k=0 ; k(1,64); N = internal::random(1,768); K = internal::random(1,768); M = (0 + M) * 1; std::cout << M << " x " << N << " x " << K << "\n"; check_product(M, N, K); } }