| 213 | #endif |
| 214 | |
| 215 | void benchmark_matrix_mul( |
| 216 | Handle* handle, const std::vector<BenchArgs>& args, DType A_dtype, |
| 217 | DType B_dtype, DType C_dtype, const char* algo = nullptr, |
| 218 | param::MatrixMul::Format format = param::MatrixMul::Format::DEFAULT) { |
| 219 | megdnn_assert(A_dtype.enumv() == B_dtype.enumv()); |
| 220 | CUBenchmarker<MatrixMulForward> benchmarker(handle); |
| 221 | CUBenchmarker<MatrixMulForward> benchmarker_cublas(handle); |
| 222 | size_t RUNS = 1000; |
| 223 | benchmarker.set_display(false).set_times(RUNS); |
| 224 | benchmarker_cublas.set_display(false).set_times(RUNS); |
| 225 | benchmarker_cublas.set_before_exec_callback( |
| 226 | AlgoChecker<MatrixMulForward>("CUBLAS")); |
| 227 | benchmarker.set_dtype(0, A_dtype).set_dtype(1, B_dtype).set_dtype(2, C_dtype); |
| 228 | benchmarker_cublas.set_dtype(0, A_dtype) |
| 229 | .set_dtype(1, B_dtype) |
| 230 | .set_dtype(2, C_dtype); |
| 231 | using Param = MatrixMul::Param; |
| 232 | for (auto&& arg : args) { |
| 233 | size_t m = arg.m, n = arg.n, k = arg.k; |
| 234 | Param param; |
| 235 | param.transposeA = arg.mask & 0x1; |
| 236 | param.transposeB = arg.mask & 0x2; |
| 237 | param.format = format; |
| 238 | size_t A0 = m, A1 = k, B0 = k, B1 = n; |
| 239 | if (param.transposeA) { |
| 240 | std::swap(A0, A1); |
| 241 | } |
| 242 | if (param.transposeB) { |
| 243 | std::swap(B0, B1); |
| 244 | } |
| 245 | |
| 246 | benchmarker.set_param(param); |
| 247 | TensorShape A{A0, A1}, B{B0, B1}, C{m, n}; |
| 248 | float time_in_ms = 0.f; |
| 249 | if (algo) { |
| 250 | time_in_ms = algo_benchmark< |
| 251 | MatrixMulForward, OprProxy<MatrixMulForward>, CUTimer>( |
| 252 | benchmarker, {A, B, C}, algo) / |
| 253 | RUNS; |
| 254 | } else { |
| 255 | time_in_ms = benchmarker.execs({A, B, C}) / RUNS; |
| 256 | } |
| 257 | benchmarker_cublas.set_param(param); |
| 258 | auto time_in_ms_cublas = benchmarker_cublas.execs({A, B, C}) / RUNS; |
| 259 | float flo = 2.0 * m * n * k / (1e12); |
| 260 | printf("A=%s, B=%s, C=%s, time(algo=%s)=%.2f %.2fTops, " |
| 261 | "time(cublas)=%.2f %.2fTops, " |
| 262 | "perf(algo=%s)/perf(cublas)=%.2f\n", |
| 263 | A.to_string().c_str(), B.to_string().c_str(), C.to_string().c_str(), |
| 264 | algo, time_in_ms, (flo / (time_in_ms * 1e-3)), time_in_ms_cublas, |
| 265 | (flo / (time_in_ms_cublas * 1e-3)), algo, |
| 266 | time_in_ms_cublas / time_in_ms); |
| 267 | } |
| 268 | } |
| 269 | #endif |
| 270 | } // namespace |
| 271 | |