| 275 | #if MEGDNN_WITH_BENCHMARK |
| 276 | namespace { |
| 277 | void benchmark_nchw44_fp32(Handle* handle) { |
| 278 | using Param = param::Pooling; |
| 279 | auto run = [&](size_t n, size_t c, size_t h, size_t w, size_t filter, size_t stride, |
| 280 | size_t pad, Param::Mode mode) { |
| 281 | Param param; |
| 282 | param.window_h = param.window_w = filter; |
| 283 | param.stride_h = param.stride_w = stride; |
| 284 | param.pad_h = param.pad_w = pad; |
| 285 | param.format = Param::Format::NCHW; |
| 286 | param.mode = mode; |
| 287 | TensorShape nchw_shape = {n, c, h, w}; |
| 288 | TensorShape nchw44_shape = {n, c / 4, h, w, 4}; |
| 289 | TensorLayout dst_layout; |
| 290 | auto opr = handle->create_operator<Pooling>(); |
| 291 | opr->param() = param; |
| 292 | opr->deduce_layout({nchw_shape, dtype::Float32()}, dst_layout); |
| 293 | float calc_amount = |
| 294 | dst_layout.total_nr_elems() * param.window_h * param.window_w; |
| 295 | |
| 296 | Benchmarker<Pooling> benchmarker_float_nchw(handle); |
| 297 | Benchmarker<Pooling> benchmarker_float_nchw44(handle); |
| 298 | Benchmarker<Pooling> benchmarker_int_nchw44(handle); |
| 299 | size_t RUN = 500; |
| 300 | auto t1 = benchmarker_float_nchw.set_display(false) |
| 301 | .set_times(RUN) |
| 302 | .set_param(param) |
| 303 | .exec({nchw_shape, {}}); |
| 304 | |
| 305 | param.format = Param::Format::NCHW44; |
| 306 | auto t2 = benchmarker_int_nchw44.set_display(false) |
| 307 | .set_times(RUN) |
| 308 | .set_param(param) |
| 309 | .execl({{nchw44_shape, dtype::QuantizedS8(1.0)}, |
| 310 | {{}, dtype::QuantizedS8(1.0)}}); |
| 311 | auto t3 = benchmarker_float_nchw44.set_display(false) |
| 312 | .set_times(RUN) |
| 313 | .set_param(param) |
| 314 | .exec({nchw44_shape, {}}); |
| 315 | |
| 316 | printf("{%zu %zu %zu %zu} filter = %zu, stride = %zu pad = %zu\n" |
| 317 | "nchw_fp32={%.3f ms, %.3f Mflops}, " |
| 318 | "nchw44_int={%.3f ms, %.3f Mflops}, " |
| 319 | "nchw44_fp32={%.3f ms, %.3f Mflops, speed_up %f}\n\n", |
| 320 | n, c, h, w, filter, stride, pad, t1 / RUN, |
| 321 | calc_amount / (t1 / RUN * 1000), t2 / RUN, |
| 322 | calc_amount / (t2 / RUN * 1000), t3 / RUN, |
| 323 | calc_amount / (t3 / RUN * 1000), t1 / t3); |
| 324 | }; |
| 325 | // Resnet50 |
| 326 | run(1, 64, 112, 112, 3, 2, 1, param::Pooling::Mode::MAX); |
| 327 | run(1, 2048, 7, 7, 7, 1, 0, param::Pooling::Mode::AVERAGE); |
| 328 | |
| 329 | // VGG16 |
| 330 | run(1, 64, 224, 224, 2, 2, 0, param::Pooling::Mode::MAX); |
| 331 | run(1, 128, 112, 112, 2, 2, 0, param::Pooling::Mode::MAX); |
| 332 | run(1, 256, 56, 56, 2, 2, 0, param::Pooling::Mode::MAX); |
| 333 | run(1, 512, 28, 28, 2, 2, 0, param::Pooling::Mode::MAX); |
| 334 | run(1, 512, 14, 14, 2, 2, 0, param::Pooling::Mode::MAX); |
no test coverage detected