From efbb9eb7ee895693ebb1b0f26809097170f1b2f6 Mon Sep 17 00:00:00 2001 From: Liangliang He Date: Tue, 7 Nov 2017 16:58:05 +0800 Subject: [PATCH] Add OpenCL ResizeBilinear empty kernel --- mace/kernels/opencl/resize_bilinear_opencl.cc | 16 +++++ mace/kernels/resize_bilinear.h | 47 +++++++++---- mace/ops/resize_bilinear.cc | 3 + mace/ops/resize_bilinear.h | 19 +---- mace/ops/resize_bilinear_benchmark.cc | 69 +++++++++++++++++++ 5 files changed, 125 insertions(+), 29 deletions(-) create mode 100644 mace/kernels/opencl/resize_bilinear_opencl.cc create mode 100644 mace/ops/resize_bilinear_benchmark.cc diff --git a/mace/kernels/opencl/resize_bilinear_opencl.cc b/mace/kernels/opencl/resize_bilinear_opencl.cc new file mode 100644 index 00000000..62f58d0b --- /dev/null +++ b/mace/kernels/opencl/resize_bilinear_opencl.cc @@ -0,0 +1,16 @@ +// +// Copyright (c) 2017 XiaoMi All rights reserved. +// + +#include "mace/kernels/resize_bilinear.h" +#include "mace/core/tensor.h" + +namespace mace { +namespace kernels { + +template <> +void ResizeBilinearFunctor::operator()( + const Tensor *input, const Tensor *resize_dims, Tensor *output) {} + +} // namespace kernels +} // namespace mace diff --git a/mace/kernels/resize_bilinear.h b/mace/kernels/resize_bilinear.h index 3c9a2b8d..1e59d112 100644 --- a/mace/kernels/resize_bilinear.h +++ b/mace/kernels/resize_bilinear.h @@ -106,16 +106,33 @@ struct ResizeBilinearFunctor { ResizeBilinearFunctor(bool align_corners) : align_corners_(align_corners) {} - void operator()(const T *input, - T *output, - index_t n, - index_t channels, - index_t in_height, - index_t in_width, - index_t out_height, - index_t out_width) { + void operator()(const Tensor *input, + const Tensor *resize_dims, + Tensor *output) { + index_t n = input->dim(0); + index_t channels = input->dim(1); + index_t in_height = input->dim(2); + index_t in_width = input->dim(3); + + index_t out_height; + index_t out_width; + { + MACE_CHECK(resize_dims->dim_size() == 1); + Tensor::MappingGuard resize_dims_mapper(resize_dims); + auto dims_data = resize_dims->data(); + out_height = dims_data[0]; + out_width = dims_data[1]; + } + + vector out_shape{n, channels, out_height, out_width}; + output->Resize(out_shape); + + const T *input_data = input->data(); + T *output_data = output->mutable_data(); + if (out_height == in_height && out_width == in_width) { - std::copy(input, input + channels * in_height * in_width, output); + std::copy(input_data, input_data + channels * in_height * in_width, + output_data); return; } @@ -131,12 +148,16 @@ struct ResizeBilinearFunctor { ComputeInterpolationWeights(out_height, in_height, height_scale, ys.data()); ComputeInterpolationWeights(out_width, in_width, width_scale, xs.data()); - ResizeImage(input, n, in_height, in_width, out_height, out_width, channels, - xs, ys, output); + ResizeImage(input_data, n, in_height, in_width, out_height, out_width, + channels, xs, ys, output_data); } }; -} // namespace kernels -} // namespace mace +template <> +void ResizeBilinearFunctor::operator()( + const Tensor *input, const Tensor *resize_dims, Tensor *output); + +} // namespace kernels +} // namespace mace #endif // MACE_KERNELS_RESIZE_BILINEAR_H_ diff --git a/mace/ops/resize_bilinear.cc b/mace/ops/resize_bilinear.cc index a20c9f13..b8b24ced 100644 --- a/mace/ops/resize_bilinear.cc +++ b/mace/ops/resize_bilinear.cc @@ -13,4 +13,7 @@ REGISTER_NEON_OPERATOR(ResizeBilinear, ResizeBilinearOp); #endif // __ARM_NEON +REGISTER_OPENCL_OPERATOR(ResizeBilinear, + ResizeBilinearOp); + } // namespace mace diff --git a/mace/ops/resize_bilinear.h b/mace/ops/resize_bilinear.h index 6f85b3f1..fd6d95bf 100644 --- a/mace/ops/resize_bilinear.h +++ b/mace/ops/resize_bilinear.h @@ -21,28 +21,15 @@ class ResizeBilinearOp : public Operator { bool Run() override { const Tensor *input = this->Input(0); const Tensor *resize_dims = this->Input(1); + Tensor *output = this->Output(0); MACE_CHECK(input->dim_size() == 4, "input must be 4-dimensional.", input->dim_size()); MACE_CHECK(resize_dims->dim_size() == 1, "resize dim must be 2-dimensional.", resize_dims->dim_size()); - Tensor *output = this->Output(0); - - index_t n = input->dim(0); - index_t channels = input->dim(1); - index_t in_height = input->dim(2); - index_t in_width = input->dim(3); - index_t out_height = resize_dims->data()[0]; - index_t out_width = resize_dims->data()[1]; - vector out_shape{n, channels, out_height, out_width}; - output->Resize(out_shape); - - const T *input_ptr = input->data(); - T *output_ptr = output->mutable_data(); - functor_(input_ptr, output_ptr, n, channels, in_height, in_width, - out_height, out_width); + functor_(input, resize_dims, output); return true; } @@ -50,6 +37,6 @@ class ResizeBilinearOp : public Operator { kernels::ResizeBilinearFunctor functor_; }; -} // namespace mace +} // namespace mace #endif // MACE_RESIZE_BILINEAR_H diff --git a/mace/ops/resize_bilinear_benchmark.cc b/mace/ops/resize_bilinear_benchmark.cc new file mode 100644 index 00000000..c8af5ac7 --- /dev/null +++ b/mace/ops/resize_bilinear_benchmark.cc @@ -0,0 +1,69 @@ +// +// Copyright (c) 2017 XiaoMi All rights reserved. +// + +#include +#include "mace/core/operator.h" +#include "mace/core/testing/test_benchmark.h" +#include "mace/ops/ops_test_util.h" + +namespace mace { +template +static void ResizeBilinearBenchmark(int iters, + int batch, + int channels, + int input_height, + int input_width, + int output_height, + int output_width) { + mace::testing::StopTiming(); + + OpsTestNet net; + OpDefBuilder("ResizeBilinear", "ResizeBilinearBenchmark") + .Input("Input") + .Input("OutSize") + .Output("Output") + .Finalize(net.NewOperatorDef()); + + // Add input data + net.AddRandomInput( + "Input", {batch, channels, input_height, input_width}); + net.AddInputFromArray( + "OutSize", {2}, {output_height, output_width}); + + // Warm-up + for (int i = 0; i < 5; ++i) { + net.RunOp(D); + } + + mace::testing::StartTiming(); + while (iters--) { + net.RunOp(D); + } +} + +#define BM_RESIZE_BILINEAR_MACRO(N, C, H0, W0, H1, W1, TYPE, DEVICE) \ + static void \ + BM_RESIZE_BILINEAR_##N##_##C##_##H0##_##W0##_##H1##_##W1##_##TYPE##_##DEVICE( \ + int iters) { \ + const int64_t tot = static_cast(iters) * N * C * H1 * W1; \ + mace::testing::ItemsProcessed(tot); \ + mace::testing::BytesProcessed(tot *(sizeof(TYPE))); \ + ResizeBilinearBenchmark(iters, N, C, H0, W0, H1, W1); \ + } \ + BENCHMARK( \ + BM_RESIZE_BILINEAR_##N##_##C##_##H0##_##W0##_##H1##_##W1##_##TYPE##_##DEVICE) + +#define BM_RESIZE_BILINEAR(N, C, H0, W0, H1, W1, TYPE) \ + BM_RESIZE_BILINEAR_MACRO(N, C, H0, W0, H1, W1, TYPE, CPU); \ + BM_RESIZE_BILINEAR_MACRO(N, C, H0, W0, H1, W1, TYPE, NEON); \ + BM_RESIZE_BILINEAR_MACRO(N, C, H0, W0, H1, W1, TYPE, OPENCL); + +BM_RESIZE_BILINEAR(1, 256, 7, 7, 15, 15, float); +BM_RESIZE_BILINEAR(1, 256, 15, 15, 30, 30, float); +BM_RESIZE_BILINEAR(1, 128, 30, 30, 60, 60, float); +BM_RESIZE_BILINEAR(1, 128, 240, 240, 480, 480, float); +BM_RESIZE_BILINEAR(1, 3, 4032, 3016, 480, 480, float); +BM_RESIZE_BILINEAR(1, 3, 480, 480, 4032, 3016, float); + +} // namespace mace -- GitLab