aboutsummaryrefslogtreecommitdiff
path: root/arm_compute
diff options
context:
space:
mode:
authorramelg01 <ramy.elgammal@arm.com>2022-02-26 22:06:20 +0000
committerRamy Elgammal <ramy.elgammal@arm.com>2022-03-15 16:18:13 +0000
commit375156937a0783432c5d18e199b5d8d2b3ec33f7 (patch)
tree4c755770ac569c286179e5ce40df1c820baa73d8 /arm_compute
parent4e66d707a292b90a344e32c59eb1dacb67a0e4c1 (diff)
downloadComputeLibrary-375156937a0783432c5d18e199b5d8d2b3ec33f7.tar.gz
Implementation of ClPooling3d
- For NDHWC layout - For F16 and F32 data types - Mixed Precision stil not supported Resolves: COMPMID-4670 Signed-off-by: ramy.elgammal@arm.com Change-Id: I0e14a13e4625569e8e5ee67e6033bd1efe0da469 Reviewed-on: https://review.mlplatform.org/c/ml/ComputeLibrary/+/7262 Comments-Addressed: Arm Jenkins <bsgcomp@arm.com> Reviewed-by: SiCong Li <sicong.li@arm.com> Reviewed-by: Gunes Bayir <gunes.bayir@arm.com> Tested-by: Arm Jenkins <bsgcomp@arm.com>
Diffstat (limited to 'arm_compute')
-rw-r--r--arm_compute/core/Types.h139
-rw-r--r--arm_compute/core/Utils.h34
-rw-r--r--arm_compute/core/Window.h3
-rw-r--r--arm_compute/core/utils/misc/ShapeCalculator.h63
-rw-r--r--arm_compute/runtime/CL/CLFunctions.h1
-rw-r--r--arm_compute/runtime/CL/functions/CLPooling3dLayer.h102
6 files changed, 262 insertions, 80 deletions
diff --git a/arm_compute/core/Types.h b/arm_compute/core/Types.h
index 6c49cc35c0..47b9485d80 100644
--- a/arm_compute/core/Types.h
+++ b/arm_compute/core/Types.h
@@ -1264,6 +1264,109 @@ struct PoolingLayerInfo
bool fp_mixed_precision;
};
+/** Pooling Layer Information struct*/
+struct Pooling3dLayerInfo
+{
+ /** Default Constructor */
+ Pooling3dLayerInfo()
+ : pool_type(PoolingType::MAX),
+ pool_size(Size3D()),
+ stride(Size3D()),
+ padding(Padding3D()),
+ exclude_padding(false),
+ is_global_pooling(false),
+ fp_mixed_precision(false),
+ round_type(DimensionRoundingType::FLOOR)
+ {
+ }
+ /** Constructor
+ *
+ * @param[in] pool_type Pooling type @ref PoolingType.
+ * @param[in] pool_size Pooling size, in elements, across x, y and z.
+ * @param[in] stride (Optional) stride information @ref Size3D
+ * @param[in] padding (Optional) padding information @ref Padding3D
+ * @param[in] exclude_padding (Optional) Strategy when accounting padding in calculations.
+ * True will exclude padding while false will not (Used in AVG/L2 pooling to determine the pooling area).
+ * Defaults to false;
+ * @param[in] fp_mixed_precision (Optional) Use wider accumulators (32 bit instead of 16 for FP16) to improve accuracy.
+ * @param[in] round_type (Optional) Dimensions rounding. Defaults to @ref FLOOR
+ */
+ explicit Pooling3dLayerInfo(PoolingType pool_type,
+ unsigned int pool_size,
+ Size3D stride = Size3D(1U, 1U, 1U),
+ Padding3D padding = Padding3D(),
+ bool exclude_padding = false,
+ bool fp_mixed_precision = false,
+ DimensionRoundingType round_type = DimensionRoundingType::FLOOR)
+ : pool_type(pool_type),
+ pool_size(Size3D(pool_size, pool_size, pool_size)),
+ stride(stride),
+ padding(padding),
+ exclude_padding(exclude_padding),
+ is_global_pooling(false),
+ fp_mixed_precision(fp_mixed_precision),
+ round_type(round_type)
+ {
+ }
+
+ /** Constructor
+ *
+ * @param[in] pool_type Pooling type @ref PoolingType.
+ * @param[in] pool_size Pooling size, in elements, across x, y and z.
+ * @param[in] stride (Optional) stride information @ref Size3D
+ * @param[in] padding (Optional) padding information @ref Padding3D
+ * @param[in] exclude_padding (Optional) Strategy when accounting padding in calculations.
+ * True will exclude padding while false will not (Used in AVG/L2 pooling to determine the pooling area).
+ * Defaults to false;
+ * @param[in] fp_mixed_precision (Optional) Use wider accumulators (32 bit instead of 16 for FP16) to improve accuracy.
+ * @param[in] round_type (Optional) Dimensions rounding. Defaults to @ref FLOOR
+ */
+ explicit Pooling3dLayerInfo(PoolingType pool_type,
+ Size3D pool_size,
+ Size3D stride = Size3D(1U, 1U, 1U),
+ Padding3D padding = Padding3D(),
+ bool exclude_padding = false,
+ bool fp_mixed_precision = false,
+ DimensionRoundingType round_type = DimensionRoundingType::FLOOR)
+ : pool_type(pool_type),
+ pool_size(pool_size),
+ stride(stride),
+ padding(padding),
+ exclude_padding(exclude_padding),
+ is_global_pooling(false),
+ fp_mixed_precision(fp_mixed_precision),
+ round_type(round_type)
+ {
+ }
+
+ /** Constructor
+ *
+ * @note This constructor is used for global pooling
+ *
+ * @param[in] pool_type Pooling type @ref PoolingType.
+ */
+ explicit Pooling3dLayerInfo(PoolingType pool_type)
+ : pool_type(pool_type),
+ pool_size(Size3D()),
+ stride(Size3D(1U, 1U, 1U)),
+ padding(Padding3D(0, 0, 0)),
+ exclude_padding(false),
+ is_global_pooling(true),
+ fp_mixed_precision(false),
+ round_type(DimensionRoundingType::FLOOR)
+ {
+ }
+
+ PoolingType pool_type;
+ Size3D pool_size;
+ Size3D stride;
+ Padding3D padding;
+ bool exclude_padding;
+ bool is_global_pooling;
+ bool fp_mixed_precision;
+ DimensionRoundingType round_type;
+};
+
/** ROI Pooling Layer Information class */
class ROIPoolingLayerInfo final
{
@@ -1307,42 +1410,6 @@ private:
unsigned int _sampling_ratio;
};
-struct Pool3DInfo
-{
- Pool3DInfo() = default;
-
- /** Constructor
- *
- * @param[in] pool_type Pooling type @ref PoolingType.
- * @param[in] pool_size Pooling size, in elements, across x, y and z @ref Size3D
- * @param[in] padding Paddings in x, y and z dimensions
- * @param[in] strides Strides in x, y and z dimensions @ref Size3D
- * @param[in] round_type Dimension rounding type (ceil or floor)
- * @param[in] exclude_padding Strategy when accounting padding in calculations.
- * True will exclude padding while false will not (Used in AVG/L2 pooling to determine the pooling area).
- * @param[in] is_global_pooling Sets the pool size to the input size if True
- */
- Pool3DInfo(const PoolingType pool_type,
- const Size3D pool_size,
- const Padding3D padding,
- const Size3D strides,
- const DimensionRoundingType round_type,
- bool exclude_padding,
- bool is_global_pooling)
- : pool_type(pool_type), pool_size(pool_size), padding(padding), strides(strides), round_type(round_type), exclude_padding(exclude_padding), is_global_pooling(is_global_pooling)
-
- {
- }
-
- PoolingType pool_type{ PoolingType::MAX };
- Size3D pool_size{ 1U, 1U, 1U };
- Padding3D padding{};
- Size3D strides{ 1U, 1U, 1U };
- DimensionRoundingType round_type{ DimensionRoundingType::FLOOR };
- bool exclude_padding{ false };
- bool is_global_pooling{ false };
-};
-
/** Generate Proposals Information class */
class GenerateProposalsInfo
{
diff --git a/arm_compute/core/Utils.h b/arm_compute/core/Utils.h
index 2d774770ae..a47cfbdec6 100644
--- a/arm_compute/core/Utils.h
+++ b/arm_compute/core/Utils.h
@@ -793,6 +793,23 @@ std::pair<int, int> scaled_dimensions_signed(int width, int height,
int kernel_width, int kernel_height,
const PadStrideInfo &pad_stride_info);
+/** Returns calculated width, height and depth of output scaled tensor depending on dimensions rounding mode.
+ *
+ * @param[in] width Width of input tensor
+ * @param[in] height Height of input tensor
+ * @param[in] depth Depth of input tensor
+ * @param[in] kernel_width Kernel width.
+ * @param[in] kernel_height Kernel height.
+ * @param[in] kernel_depth Kernel depth.
+ * @param[in] pool3d_info Pad and stride and round information for 3d pooling
+ *
+ * @return A tuple with the new width in the first position, the new height in the second, and the new depth in the third.
+ * Returned values can be < 1
+ */
+std::tuple<int, int, int> scaled_3d_dimensions_signed(int width, int height, int depth,
+ int kernel_width, int kernel_height, int kernel_depth,
+ const Pooling3dLayerInfo &pool3d_info);
+
/** Check if the given reduction operation should be handled in a serial way.
*
* @param[in] op Reduction operation to perform
@@ -893,6 +910,23 @@ const std::string &string_from_pooling_type(PoolingType type);
* @return True if the pool region is entirely outside the input tensor, False otherwise.
*/
bool is_pool_region_entirely_outside_input(const PoolingLayerInfo &info);
+/** Check if the 3d pool region is entirely outside the input tensor
+ *
+ * @param[in] info @ref Pooling3dLayerInfo to be checked.
+ *
+ * @return True if the pool region is entirely outside the input tensor, False otherwise.
+ */
+bool is_pool_3d_region_entirely_outside_input(const Pooling3dLayerInfo &info);
+/** Check if the 3D padding is symmetric i.e. padding in each opposite sides are euqal (left=right, top=bottom and front=back)
+ *
+ * @param[in] info @ref Padding3D input 3D padding object to check if it is symmetric
+ *
+ * @return True if padding is symmetric
+ */
+inline bool is_symmetric(const Padding3D& info)
+{
+ return ((info.left == info.right) && (info.top == info.bottom) && (info.front == info.back));
+}
/** Translates a given GEMMLowp output stage to a string.
*
* @param[in] output_stage @ref GEMMLowpOutputStageInfo to be translated to string.
diff --git a/arm_compute/core/Window.h b/arm_compute/core/Window.h
index 150320a90e..f603e6c148 100644
--- a/arm_compute/core/Window.h
+++ b/arm_compute/core/Window.h
@@ -47,6 +47,8 @@ public:
static constexpr size_t DimZ = 2;
/** Alias for dimension 3 also known as W dimension */
static constexpr size_t DimW = 3;
+ /** Alias for dimension 4 also known as V dimension */
+ static constexpr size_t DimV = 4;
/** Default constructor: create a window containing a single element. */
constexpr Window()
@@ -348,7 +350,6 @@ public:
{
return slide_window_slice<4>(slice);
}
-
/** Collapse the dimensions between @p first and @p last if possible.
*
* A dimension is collapsable if it starts from 0 and matches the corresponding dimension in the full_window
diff --git a/arm_compute/core/utils/misc/ShapeCalculator.h b/arm_compute/core/utils/misc/ShapeCalculator.h
index ee4fe0c02f..df907c106e 100644
--- a/arm_compute/core/utils/misc/ShapeCalculator.h
+++ b/arm_compute/core/utils/misc/ShapeCalculator.h
@@ -1467,52 +1467,29 @@ inline TensorShape compute_conv3d_shape(const TensorShape &src, const TensorShap
*
* @return the calculated shape
*/
-inline TensorShape compute_pool3d_shape(const TensorShape &src, Pool3DInfo pool3d_info)
+inline TensorShape compute_pool3d_shape(const TensorShape &src, Pooling3dLayerInfo pool3d_info)
{
TensorShape output_shape{ src };
- const int idx_width = 1;
- const int idx_height = 2;
- const int idx_depth = 3;
- const int pool_size_width = pool3d_info.is_global_pooling ? src[idx_width] : pool3d_info.pool_size.width;
- const int pool_size_height = pool3d_info.is_global_pooling ? src[idx_height] : pool3d_info.pool_size.height;
- const int pool_size_depth = pool3d_info.is_global_pooling ? src[idx_depth] : pool3d_info.pool_size.depth;
- const int pool_stride_width = pool3d_info.strides.width;
- const int pool_stride_height = pool3d_info.strides.height;
- const int pool_stride_depth = pool3d_info.strides.depth;
-
- int output_width_size = 0;
- int output_height_size = 0;
- int output_depth_size = 0;
-
- const size_t pad_left = pool3d_info.padding.left;
- const size_t pad_right = pool3d_info.padding.right;
- const size_t pad_top = pool3d_info.padding.top;
- const size_t pad_bottom = pool3d_info.padding.bottom;
- const size_t pad_front = pool3d_info.padding.front;
- const size_t pad_back = pool3d_info.padding.back;
-
- switch(pool3d_info.round_type)
- {
- case DimensionRoundingType::FLOOR:
- output_width_size = static_cast<int>(std::floor((static_cast<float>(src[idx_width] + pad_left + pad_right - pool_size_width)) / pool_stride_width) + 1);
- output_height_size = static_cast<int>(std::floor((static_cast<float>(src[idx_height] + pad_top + pad_bottom - pool_size_height)) / pool_stride_height) + 1);
- output_depth_size = static_cast<int>(std::floor((static_cast<float>(src[idx_depth] + pad_front + pad_back - pool_size_depth)) / pool_stride_depth) + 1);
- break;
- case DimensionRoundingType::CEIL:
- output_width_size = static_cast<int>(std::ceil((static_cast<float>(src[idx_width] + pad_left + pad_right - pool_size_width)) / pool_stride_width) + 1);
- output_height_size = static_cast<int>(std::ceil((static_cast<float>(src[idx_height] + pad_top + pad_bottom - pool_size_height)) / pool_stride_height) + 1);
- output_depth_size = static_cast<int>(std::ceil((static_cast<float>(src[idx_depth] + pad_front + pad_back - pool_size_depth)) / pool_stride_depth) + 1);
- break;
- default:
- ARM_COMPUTE_ERROR("Unsupported rounding type");
- }
-
- ARM_COMPUTE_ERROR_ON_MSG((output_width_size < 1 || output_height_size < 1 || output_depth_size < 1), "Calculated output dimension size is invalid");
-
- output_shape.set(idx_width, static_cast<size_t>(output_width_size));
- output_shape.set(idx_height, static_cast<size_t>(output_height_size));
- output_shape.set(idx_depth, static_cast<size_t>(output_depth_size));
+ const auto data_layout = DataLayout::NDHWC;
+ const int idx_width = get_data_layout_dimension_index(data_layout, DataLayoutDimension::WIDTH);
+ const int idx_height = get_data_layout_dimension_index(data_layout, DataLayoutDimension::HEIGHT);
+ const int idx_depth = get_data_layout_dimension_index(data_layout, DataLayoutDimension::DEPTH);
+ const int pool_size_width = pool3d_info.is_global_pooling ? src[idx_width] : pool3d_info.pool_size.width;
+ const int pool_size_height = pool3d_info.is_global_pooling ? src[idx_height] : pool3d_info.pool_size.height;
+ const int pool_size_depth = pool3d_info.is_global_pooling ? src[idx_depth] : pool3d_info.pool_size.depth;
+ int output_width = 0;
+ int output_height = 0;
+ int output_depth = 0;
+
+ std::tie(output_width, output_height, output_depth) = scaled_3d_dimensions_signed(src[idx_width], src[idx_height], src[idx_depth], pool_size_width, pool_size_height,
+ pool_size_depth, pool3d_info);
+
+ ARM_COMPUTE_ERROR_ON_MSG((output_width < 1 || output_height < 1 || output_depth < 1), "Calculated output dimension size is invalid");
+
+ output_shape.set(idx_width, static_cast<size_t>(output_width));
+ output_shape.set(idx_height, static_cast<size_t>(output_height));
+ output_shape.set(idx_depth, static_cast<size_t>(output_depth));
return output_shape;
}
diff --git a/arm_compute/runtime/CL/CLFunctions.h b/arm_compute/runtime/CL/CLFunctions.h
index 9f67f2e05b..f42da5801c 100644
--- a/arm_compute/runtime/CL/CLFunctions.h
+++ b/arm_compute/runtime/CL/CLFunctions.h
@@ -84,6 +84,7 @@
#include "arm_compute/runtime/CL/functions/CLPadLayer.h"
#include "arm_compute/runtime/CL/functions/CLPermute.h"
#include "arm_compute/runtime/CL/functions/CLPixelWiseMultiplication.h"
+#include "arm_compute/runtime/CL/functions/CLPooling3dLayer.h"
#include "arm_compute/runtime/CL/functions/CLPoolingLayer.h"
#include "arm_compute/runtime/CL/functions/CLPriorBoxLayer.h"
#include "arm_compute/runtime/CL/functions/CLQLSTMLayer.h"
diff --git a/arm_compute/runtime/CL/functions/CLPooling3dLayer.h b/arm_compute/runtime/CL/functions/CLPooling3dLayer.h
new file mode 100644
index 0000000000..2e4823756d
--- /dev/null
+++ b/arm_compute/runtime/CL/functions/CLPooling3dLayer.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2022 Arm Limited.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#ifndef ARM_COMPUTE_CLPOOLING3DLAYER_H
+#define ARM_COMPUTE_CLPOOLING3DLAYER_H
+
+#include "arm_compute/runtime/IFunction.h"
+
+#include "arm_compute/core/Types.h"
+
+#include <memory>
+
+namespace arm_compute
+{
+class CLCompileContext;
+class ICLTensor;
+class ITensorInfo;
+
+/** Basic function to run @ref opencl::ClPool3d */
+class CLPooling3dLayer : public IFunction
+{
+public:
+ /** Default Constructor */
+ CLPooling3dLayer();
+ /** Default Destructor */
+ ~CLPooling3dLayer();
+ /** Prevent instances of this class from being copied (As this class contains pointers) */
+ CLPooling3dLayer(const CLPooling3dLayer &) = delete;
+ /** Default move constructor */
+ CLPooling3dLayer(CLPooling3dLayer &&) = default;
+ /** Prevent instances of this class from being copied (As this class contains pointers) */
+ CLPooling3dLayer &operator=(const CLPooling3dLayer &) = delete;
+ /** Default move assignment operator */
+ CLPooling3dLayer &operator=(CLPooling3dLayer &&) = default;
+ /** Set the input and output tensors.
+ *
+ * Valid data layout:
+ * - NDHWC
+ *
+ * Valid data type configurations:
+ * |src |dst |
+ * |:--------------|:--------------|
+ * |F16 |F16 |
+ * |F32 |F32 |
+ *
+ * @note Source tensor is padded with -inf for MAX pooling and 0 otherwise
+ * Cases where pooling region is completely outside input tensor are not supported
+ *
+ * @note Asymmetric padding is not supported when dimension rounding type == CEIL.
+ *
+ * @param[in,out] input Source tensor. Data types supported: F16/F32.
+ * @param[out] output Destination tensor. Data types supported: Same as @p input.
+ * @param[in] pool_info Contains 3d pooling operation information described in @ref Pooling3dLayerInfo.
+ */
+ void configure(const ICLTensor *input, ICLTensor *output, const Pooling3dLayerInfo &pool_info);
+ /** Set the input and output tensors.
+ *
+ * @param[in] compile_context The compile context to be used.
+ * @param[in,out] input Source tensor. Data types supported: F16/F32.
+ * @param[out] output Destination tensor. Data types supported: Same as @p input.
+ * @param[in] pool_info Contains 3d pooling operation information described in @ref Pooling3dLayerInfo.
+ */
+ void configure(const CLCompileContext &compile_context, const ICLTensor *input, ICLTensor *output, const Pooling3dLayerInfo &pool_info);
+ /** Static function to check if given info will lead to a valid configuration of @ref CLPooling3dLayer
+ *
+ * @param[in] input Source tensor info. Data types supported: F16/F32.
+ * @param[in] output Destination tensor info. Data types supported: Same as @p input.
+ * @param[in] pool_info Contains 3d pooling operation information described in @ref Pooling3dLayerInfo.
+ *
+ * @return a status
+ */
+ static Status validate(const ITensorInfo *input, const ITensorInfo *output, const Pooling3dLayerInfo &pool_info);
+
+ // Inherited methods overridden:
+ void run() override;
+
+private:
+ struct Impl;
+ std::unique_ptr<Impl> _impl;
+};
+} // namespace arm_compute
+#endif /* ARM_COMPUTE_CLPOOLING3DLAYER_H */