From: 김정현/동작제어Lab(SR)/Senior Engineer/삼성전자 Date: Mon, 30 Apr 2018 05:32:00 +0000 (+0900) Subject: Introduce DepthwiseConv2D to support MobileNet (#967) X-Git-Tag: 0.1~78 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=527d7f7146c7ce2d727e98ef78701f271c58cab6;p=platform%2Fcore%2Fml%2Fnnfw.git Introduce DepthwiseConv2D to support MobileNet (#967) This commit introduces DepthwiseConv2D layer to support Mobilenet with a simple test case. Signed-off-by: Junghyun Kim --- diff --git a/include/kernel/acl/DepthwiseConv2D.h b/include/kernel/acl/DepthwiseConv2D.h new file mode 100644 index 0000000..b0fc199 --- /dev/null +++ b/include/kernel/acl/DepthwiseConv2D.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __NNFW_KERNEL_ACL_DEPTHWISECONV2D_H__ +#define __NNFW_KERNEL_ACL_DEPTHWISECONV2D_H__ + +#include + +namespace nnfw { +namespace kernel { +namespace acl { + +bool depthwiseConvFloat32(const float* inputData, const android::nn::Shape& inputShape, + const float* filterData, const android::nn::Shape& filterShape, + const float* biasData, const android::nn::Shape& biasShape, + int32_t padding_left, int32_t padding_right, + int32_t padding_top, int32_t padding_bottom, + int32_t stride_width, int32_t stride_height, + int32_t depth_multiplier, int32_t activation, + float* outputData, const android::nn::Shape& outputShape); + +} // namespace acl +} // namespace kernel +} // namespace nnfw + +#endif // __NNFW_KERNEL_ACL_DEPTHWISECONV2D_H__ diff --git a/libs/kernel/acl/CMakeLists.txt b/libs/kernel/acl/CMakeLists.txt index f45e40e..cbb6a82 100644 --- a/libs/kernel/acl/CMakeLists.txt +++ b/libs/kernel/acl/CMakeLists.txt @@ -28,6 +28,7 @@ set(KERNELACL_SRCS "src/Init_acl.cpp" "src/shape.cpp" "src/support.cpp" "src/cl/Conv2D.cpp" + "src/cl/DepthwiseConv2D.cpp" "src/cl/FullyConnected.cpp" "src/cl/Pooling.cpp" "src/cl/Reshape.cpp" @@ -60,6 +61,7 @@ install(TARGETS ${LIB_KERNELACL} DESTINATION lib) set(KERNELACL_TEST_SRCS "src/util.cpp" "src/gtest_env.cpp" "src/cl/Conv2D.test.cpp" + "src/cl/DepthwiseConv2D.test.cpp" "src/cl/FullyConnected.test.cpp" "src/cl/Pooling.test.cpp" "src/cl/Reshape.test.cpp" diff --git a/libs/kernel/acl/src/DepthwiseConv2D.h b/libs/kernel/acl/src/DepthwiseConv2D.h new file mode 100644 index 0000000..703874c --- /dev/null +++ b/libs/kernel/acl/src/DepthwiseConv2D.h @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __NNFW_KERNEL_ACL_DEPTHWISECONV2D_COMMON_H__ +#define __NNFW_KERNEL_ACL_DEPTHWISECONV2D_COMMON_H__ + +#include +#include +#include +#include + +#include "shape.h" +#include "IO_accessor.h" + +namespace nnfw { +namespace kernel { +namespace acl { + +namespace common { + +typedef std::function sync_scheduler_f; + +template +bool depthwiseConvFloat32(const float* inputData, const android::nn::Shape& inputShape, + const float* filterData, const android::nn::Shape& filterShape, + const float* biasData, const android::nn::Shape& biasShape, + int32_t padding_left, int32_t padding_right, + int32_t padding_top, int32_t padding_bottom, + int32_t stride_width, int32_t stride_height, + int32_t depth_multiplier, int32_t activation, + float* outputData, const android::nn::Shape& outputShape, + sync_scheduler_f sync_scheduler) { + auto inputShapeACL = util::fromNNShape(inputShape); + auto weightsShapeACL = util::fromNNShape(filterShape); + auto biasShapeACL = util::fromNNShape(biasShape); + auto outputShapeACL = util::fromNNShape(outputShape); + + TensorT input(arm_compute::TensorInfo(inputShapeACL, arm_compute::Format::F32)); + TensorT weights(arm_compute::TensorInfo(inputShapeACL, arm_compute::Format::F32)); + TensorT bias(arm_compute::TensorInfo(biasShapeACL, arm_compute::Format::F32)); + TensorT output(arm_compute::TensorInfo(outputShapeACL, arm_compute::Format::F32)); + + arm_compute::PadStrideInfo psinfo = arm_compute::PadStrideInfo(stride_width, stride_height, + padding_left, padding_right, + padding_top, padding_bottom, + arm_compute::DimensionRoundingType::FLOOR); + + auto l = std::make_shared(); + l->configure(input.ptr(), weights.ptr(), bias.ptr(), output.ptr(), psinfo); + + std::vector> fns; + + fns.emplace_back(l); + + if (ANEURALNETWORKS_FUSED_RELU == activation) + { + auto relu_f = std::make_shared(); + + const arm_compute::ActivationLayerInfo relu_info{arm_compute::ActivationLayerInfo::ActivationFunction::RELU}; + + // Do in-place update + relu_f->configure(output.ptr(), nullptr, relu_info); + + fns.emplace_back(relu_f); + } + + input.allocate(); + output.allocate(); + bias.allocate(); + weights.allocate(); + + // TODO: Do we need 2D tensor accessor for the input feature? + TensorAccess(input.ref(), inputData, inputShape); + TensorAccess(bias.ref(), biasData, biasShape); + TensorAccess(weights.ref(), filterData, filterShape); + + for (const auto &fn : fns) + { + fn->run(); + } + + sync_scheduler(); + + TensorAccess(output.ref(), outputData, outputShape); + + return true; +} + +} // namespace common + +} // namespace acl +} // namespace kernel +} // namespace nnfw + +#endif // __NNFW_KERNEL_ACL_DEPTHWISECONV2D_COMMON_H__ diff --git a/libs/kernel/acl/src/DepthwiseConv2D.test.h b/libs/kernel/acl/src/DepthwiseConv2D.test.h new file mode 100644 index 0000000..d19d382 --- /dev/null +++ b/libs/kernel/acl/src/DepthwiseConv2D.test.h @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include + +// TODO: fix include path in CMakeFiles +#include "util.h" + +#ifndef ACL_TEST +#error "ACL_TEST should be defined first!" +#endif // ACL_TEST + +#ifndef ACL_CORE_FUNC_NAME +#error "ACL_CORE_FUNC_NAME should be defined first!" +#endif // ACL_CORE_FUNC_NAME + +using namespace nnfw::kernel::acl; + +ACL_TEST(KernelACL_TC, dwise_conv2d_1) { + uint32_t input_n = 1; + uint32_t input_h = 3; + uint32_t input_w = 3; + uint32_t input_c = 1; + uint32_t filter_h = 3; + uint32_t filter_w = 3; + uint32_t filter_c = 1; + uint32_t out_h = 1; + uint32_t out_w = 1; + + int32_t padding_left = 0; + int32_t padding_right = 0; + int32_t padding_top = 0; + int32_t padding_bottom = 0; + int32_t stride_width = 1; + int32_t stride_height = 1; + int32_t depth_multiplier = 1; + + util::TensorWrapper input({input_n, input_h, input_w, input_c}); + util::TensorWrapper weights({1, filter_h, filter_w, filter_c}); + util::TensorWrapper bias({filter_c}); + util::TensorWrapper output({1, out_h, out_w, filter_c}); + + int32_t activation = static_cast(FusedActivationFunc::RELU); + + input.initValue([&](uint32_t n, uint32_t c, uint32_t h, uint32_t w) { + uint32_t N = input_n; + uint32_t H = input_h; + uint32_t W = input_w; + uint32_t C = input_c; + + return n*H*W*C + h*W*C + w*C + c; + }); + weights.initValue([&](uint32_t n, uint32_t c, uint32_t h, uint32_t w) { + uint32_t N = 1; + uint32_t H = filter_h; + uint32_t W = filter_w; + uint32_t C = filter_c; + + return n*H*W*C + h*W*C + w*C + c; + }); + bias.initValue([](uint32_t w) { + return 0.f; + }); + output.initValue([](uint32_t n, uint32_t c, uint32_t h, uint32_t w) { + return 0.f; + }); + + bool bret = ACL_CORE_FUNC_NAME(input.ptr(), input.shape(), + weights.ptr(), weights.shape(), + bias.ptr(), bias.shape(), + padding_left, padding_right, + padding_top, padding_bottom, + stride_width, stride_height, + depth_multiplier, activation, + output.ptr(), output.shape()); + + EXPECT_EQ(bret, true); + + util::TensorWrapper expected({1, out_h, out_w, filter_c}); + expected.initValue([&](uint32_t n, uint32_t c, uint32_t h, uint32_t w) { + return 204.f; + }); + + EXPECT_EQ(output, expected); +} diff --git a/libs/kernel/acl/src/cl/DepthwiseConv2D.cpp b/libs/kernel/acl/src/cl/DepthwiseConv2D.cpp new file mode 100644 index 0000000..d916429 --- /dev/null +++ b/libs/kernel/acl/src/cl/DepthwiseConv2D.cpp @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#include + +// TODO: fix include path in CMakeFiles +#include "../IO_accessor.h" +#include "../shape.h" +#include "../CLUniqueTensor.h" +#include "../DepthwiseConv2D.h" + +namespace nnfw { +namespace kernel { +namespace acl { + +static void sync_scheduler() { + arm_compute::CLScheduler::get().sync(); +} + +bool depthwiseConvFloat32(const float* inputData, const android::nn::Shape& inputShape, + const float* filterData, const android::nn::Shape& filterShape, + const float* biasData, const android::nn::Shape& biasShape, + int32_t padding_left, int32_t padding_right, + int32_t padding_top, int32_t padding_bottom, + int32_t stride_width, int32_t stride_height, + int32_t depth_multiplier, int32_t activation, + float* outputData, const android::nn::Shape& outputShape) { + return common::depthwiseConvFloat32(inputData, inputShape, + filterData, filterShape, + biasData, biasShape, + padding_left, padding_right, + padding_top, padding_bottom, + stride_width, stride_height, + depth_multiplier, activation, + outputData, outputShape, + sync_scheduler); +} + +} // namespace acl +} // namespace kernel +} // namespace nnfw + diff --git a/libs/kernel/acl/src/cl/DepthwiseConv2D.test.cpp b/libs/kernel/acl/src/cl/DepthwiseConv2D.test.cpp new file mode 100644 index 0000000..6955633 --- /dev/null +++ b/libs/kernel/acl/src/cl/DepthwiseConv2D.test.cpp @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define ACL_CORE_FUNC_NAME depthwiseConvFloat32 +#define ACL_TEST(tc, t) TEST(tc, cl_##t) + +#include "../DepthwiseConv2D.test.h"