| 411 | |
| 412 | #if __ARM_FEATURE_FP16_VECTOR_ARITHMETIC |
| 413 | void benchmark_nchw88_fp16(Handle* handle) { |
| 414 | using Param = param::Pooling; |
| 415 | auto run = [&](size_t n, size_t c, size_t h, size_t w, size_t filter, size_t stride, |
| 416 | size_t pad, Param::Mode mode) { |
| 417 | Param param; |
| 418 | param.window_h = param.window_w = filter; |
| 419 | param.stride_h = param.stride_w = stride; |
| 420 | param.pad_h = param.pad_w = pad; |
| 421 | param.format = Param::Format::NCHW44; |
| 422 | param.mode = mode; |
| 423 | TensorShape nchw44_shape = {n, c / 4, h, w, 4}; |
| 424 | TensorShape nchw88_shape = {n, c / 8, h, w, 8}; |
| 425 | TensorLayout dst_layout; |
| 426 | auto opr = handle->create_operator<Pooling>(); |
| 427 | opr->param() = param; |
| 428 | opr->deduce_layout({nchw44_shape, dtype::Float32()}, dst_layout); |
| 429 | float calc_amount = |
| 430 | dst_layout.total_nr_elems() * param.window_h * param.window_w; |
| 431 | |
| 432 | Benchmarker<Pooling> benchmarker_float16_nchw88(handle); |
| 433 | Benchmarker<Pooling> benchmarker_float32_nchw44(handle); |
| 434 | size_t RUN = 500; |
| 435 | auto t1 = benchmarker_float32_nchw44.set_display(false) |
| 436 | .set_times(RUN) |
| 437 | .set_param(param) |
| 438 | .exec({nchw44_shape, {}}); |
| 439 | |
| 440 | param.format = Param::Format::NCHW88; |
| 441 | auto t2 = benchmarker_float16_nchw88.set_display(false) |
| 442 | .set_dtype(0, dtype::Float16{}) |
| 443 | .set_dtype(1, dtype::Float16{}) |
| 444 | .set_dtype(2, dtype::Float16{}) |
| 445 | .set_dtype(4, dtype::Float16{}) |
| 446 | .set_times(RUN) |
| 447 | .set_param(param) |
| 448 | .exec({nchw88_shape, {}}); |
| 449 | |
| 450 | printf("{%zu %zu %zu %zu} filter = %zu, stride = %zu pad = %zu\n" |
| 451 | "nchw44_fp32={%.3f ms, %.3f Mflops}, " |
| 452 | "nchw88_fp16={%.3f ms, %.3f Mflops, speed_up %f}\n\n", |
| 453 | n, c, h, w, filter, stride, pad, t1 / RUN, |
| 454 | calc_amount / (t1 / RUN * 1000), t2 / RUN, |
| 455 | calc_amount / (t2 / RUN * 1000), t1 / t2); |
| 456 | }; |
| 457 | // Resnet50 |
| 458 | run(1, 64, 112, 112, 3, 2, 1, param::Pooling::Mode::MAX); |
| 459 | run(1, 2048, 7, 7, 7, 1, 0, param::Pooling::Mode::AVERAGE); |
| 460 | |
| 461 | // VGG16 |
| 462 | run(1, 64, 224, 224, 2, 2, 0, param::Pooling::Mode::MAX); |
| 463 | run(1, 128, 112, 112, 2, 2, 0, param::Pooling::Mode::MAX); |
| 464 | run(1, 256, 56, 56, 2, 2, 0, param::Pooling::Mode::MAX); |
| 465 | run(1, 512, 28, 28, 2, 2, 0, param::Pooling::Mode::MAX); |
| 466 | run(1, 512, 14, 14, 2, 2, 0, param::Pooling::Mode::MAX); |
| 467 | } |
| 468 | |
| 469 | TEST_F(ARM_COMMON, BENCHMARK_POOLING_NCHW88_FP16) { |
| 470 | benchmark_nchw88_fp16(handle()); |
no test coverage detected