| 425 | #if MEGDNN_WITH_BENCHMARK |
| 426 | namespace { |
| 427 | void run_elemwise_benchmark( |
| 428 | const TensorShapeArray& shapes, param::Elemwise::Mode mode, |
| 429 | const char* mode_str, DType type, Handle* handle_bench) { |
| 430 | auto handle_fallback = create_cpu_handle(1); |
| 431 | Benchmarker<Elemwise> benchmarker_bench(handle_bench); |
| 432 | Benchmarker<Elemwise> benchmarker_fallback(handle_fallback.get()); |
| 433 | |
| 434 | float throughput = 0; |
| 435 | SmallVector<TensorLayout> layouts; |
| 436 | std::string src_strs; |
| 437 | for (size_t i = 0; i < shapes.size(); i++) { |
| 438 | layouts.emplace_back(shapes[i], type); |
| 439 | throughput += layouts.back().span().dist_byte(); |
| 440 | src_strs += layouts.back().to_string(); |
| 441 | if (i != shapes.size() - 1) { |
| 442 | src_strs += ","; |
| 443 | } |
| 444 | } |
| 445 | constexpr size_t RUN = 50; |
| 446 | benchmarker_fallback.set_times(RUN).set_display(false); |
| 447 | benchmarker_bench.set_times(RUN).set_display(false); |
| 448 | |
| 449 | benchmarker_fallback.set_param(mode); |
| 450 | benchmarker_bench.set_param(mode); |
| 451 | |
| 452 | TensorLayout dst_layout; |
| 453 | auto opr = handle_bench->create_operator<Elemwise>(); |
| 454 | opr->param() = mode; |
| 455 | opr->deduce_layout(layouts, dst_layout); |
| 456 | |
| 457 | float computations = |
| 458 | dst_layout.total_nr_elems() * (std::max<size_t>(shapes.size(), 2) - 1); |
| 459 | throughput += dst_layout.span().dist_byte(); |
| 460 | computations *= (1e3 / (1024.0 * 1024)); |
| 461 | throughput *= (1e3 / (1024.0 * 1024)); |
| 462 | |
| 463 | layouts.emplace_back(dst_layout); |
| 464 | auto fallback_time = benchmarker_fallback.execl(layouts) / RUN; |
| 465 | auto bench_time = benchmarker_bench.execl(layouts) / RUN; |
| 466 | |
| 467 | float fallback_flops = computations / fallback_time; |
| 468 | float bench_flops = computations / bench_time; |
| 469 | float fallback_thr = throughput / fallback_time; |
| 470 | float bench_thr = throughput / bench_time; |
| 471 | |
| 472 | printf("%s = %s (type: %s, mode: %s) cpu=%fMFLOPS %fMB/s, bench=%fMFLOPS " |
| 473 | "%fMB/s " |
| 474 | "computations: %fx, throughput: %fx\n", |
| 475 | src_strs.c_str(), dst_layout.to_string().c_str(), type.name(), mode_str, |
| 476 | fallback_flops, fallback_thr, bench_flops, bench_thr, |
| 477 | bench_flops / fallback_flops, bench_thr / fallback_thr); |
| 478 | } |
| 479 | } // namespace |
| 480 | |
| 481 | TEST_F(ARM_COMMON, BENCHMARK_NCHW_VS_NHWC) { |
nothing calls this directly
no test coverage detected