diff options
author | Sang-Hoon Park <sang-hoon.park@arm.com> | 2019-10-15 16:49:24 +0100 |
---|---|---|
committer | Sang-Hoon Park <sang-hoon.park@arm.com> | 2019-10-30 14:49:34 +0000 |
commit | 2697fd8fa42425f7bfdd60dd486d4c2132b06523 (patch) | |
tree | 098450f7f60211c7e5bfbd41eb1a7a10c1c0437f /src/core | |
parent | df4cf57c7394265b27d051cb1cf0152c53659126 (diff) | |
download | ComputeLibrary-2697fd8fa42425f7bfdd60dd486d4c2132b06523.tar.gz |
COMPMID-2707: add keep_dims parameter to Reduction Operation
The added parameter is used to decide whether or not to keep
the target dimension of reduction operation. ArgMinMax operations
will always remove the reduced dimension. Following things
are updated to support the parameter.
- [CL/NEON] functions and reference kernel
- [CL/NEON] ArgMinMax function to use ReductionOperation function
- [CL/NEON] validation test suite for Reduction and ArgMinMax operations
to validate the added parameter
- ReductionOperationFixture is modified NOT to pre-populate output
tensor and now relies on underlying kernel/function.
- Adjust CL validation test suite for Reduction operation to remove
excessive test cases with axis values beyond input tensor's
dimension.
Change-Id: I3e24d276ed469a4201f323001708f0c525f11c4f
Signed-off-by: Sang-Hoon Park <sang-hoon.park@arm.com>
Reviewed-on: https://review.mlplatform.org/c/2167
Comments-Addressed: Arm Jenkins <bsgcomp@arm.com>
Tested-by: Arm Jenkins <bsgcomp@arm.com>
Reviewed-by: Michele Di Giorgio <michele.digiorgio@arm.com>
Reviewed-by: Georgios Pinitas <georgios.pinitas@arm.com>
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/CL/kernels/CLReductionOperationKernel.cpp | 18 | ||||
-rw-r--r-- | src/core/Utils.cpp | 10 |
2 files changed, 18 insertions, 10 deletions
diff --git a/src/core/CL/kernels/CLReductionOperationKernel.cpp b/src/core/CL/kernels/CLReductionOperationKernel.cpp index 8e92b591d1..a085ab1683 100644 --- a/src/core/CL/kernels/CLReductionOperationKernel.cpp +++ b/src/core/CL/kernels/CLReductionOperationKernel.cpp @@ -33,6 +33,7 @@ #include "arm_compute/core/Utils.h" #include "arm_compute/core/Validate.h" #include "arm_compute/core/Window.h" +#include "arm_compute/core/utils/misc/ShapeCalculator.h" #include "support/ToolchainSupport.h" @@ -80,17 +81,15 @@ Status validate_arguments(const ITensorInfo *input, const ITensorInfo *output, u std::tuple<Status, Window> validate_and_configure_window(ITensorInfo *input, ITensorInfo *output, unsigned int axis, ReductionOperation op) { // Output tensor auto initialization if not yet initialized - TensorShape output_shape{ input->tensor_shape() }; - output_shape.set(axis, 1); - const bool is_arg_min_max = (op == ReductionOperation::ARG_IDX_MIN || op == ReductionOperation::ARG_IDX_MAX); - DataType output_data_type = is_arg_min_max ? DataType::U32 : input->data_type(); + const bool is_arg_min_max = (op == ReductionOperation::ARG_IDX_MIN || op == ReductionOperation::ARG_IDX_MAX); + const TensorShape output_shape = arm_compute::misc::shape_calculator::compute_reduced_shape(input->tensor_shape(), axis, !is_arg_min_max); + const DataType output_data_type = is_arg_min_max ? DataType::U32 : input->data_type(); auto_init_if_empty(*output, input->clone()->set_tensor_shape(output_shape).set_data_type(output_data_type).reset_padding().set_is_resizable(true)); const unsigned int num_elems_processed_per_iteration = (is_data_type_quantized(input->data_type()) && (axis == 0)) ? 1 : 16; Window win = calculate_max_window(*input, Steps(num_elems_processed_per_iteration)); bool window_changed = false; - const bool is_serial_op = (op == ReductionOperation::ARG_IDX_MAX || op == ReductionOperation::ARG_IDX_MIN || op == ReductionOperation::MIN - || op == ReductionOperation::MAX || is_data_type_quantized(input->data_type())); + const bool is_serial_op = needs_serialized_reduction(op, input->data_type(), axis); switch(axis) { @@ -198,8 +197,8 @@ void CLReductionOperationKernel::configure(const ICLTensor *input, ICLTensor *ou // Create kernel cl::NDRange lws_hint = CLKernelLibrary::get().default_ndrange(); std::string kernel_axis_name; - const bool is_serial_op = (op == ReductionOperation::ARG_IDX_MAX || op == ReductionOperation::ARG_IDX_MIN || op == ReductionOperation::MIN || op == ReductionOperation::MAX - || is_data_type_quantized(input->info()->data_type())); + const bool is_serial_op = needs_serialized_reduction(_op, _input->info()->data_type(), _reduction_axis); + switch(axis) { case 0: @@ -264,8 +263,7 @@ void CLReductionOperationKernel::run(const Window &window, cl::CommandQueue &que ARM_COMPUTE_ERROR_ON_UNCONFIGURED_KERNEL(this); ARM_COMPUTE_ERROR_ON_INVALID_SUBWINDOW(IKernel::window(), window); - const bool is_serial_op = (_op == ReductionOperation::ARG_IDX_MAX || _op == ReductionOperation::ARG_IDX_MIN || _op == ReductionOperation::MIN || _op == ReductionOperation::MAX - || is_data_type_quantized(_input->info()->data_type())); + const bool is_serial_op = needs_serialized_reduction(_op, _input->info()->data_type(), _reduction_axis); switch(_reduction_axis) { case 0: diff --git a/src/core/Utils.cpp b/src/core/Utils.cpp index 7e1af0e27d..fa335d757b 100644 --- a/src/core/Utils.cpp +++ b/src/core/Utils.cpp @@ -427,6 +427,16 @@ std::pair<unsigned int, unsigned int> arm_compute::scaled_dimensions(unsigned in return std::make_pair(w, h); } +bool arm_compute::needs_serialized_reduction(ReductionOperation op, DataType dt, unsigned int axis) +{ + const bool is_arg_min_max = (op == ReductionOperation::ARG_IDX_MAX || op == ReductionOperation::ARG_IDX_MIN); + const bool is_min_max = (op == ReductionOperation::MAX || op == ReductionOperation::MIN); + const bool is_quantized_type = is_data_type_quantized(dt); + const bool is_first_dim = (axis == 0); + + return !is_first_dim || is_arg_min_max || is_min_max || is_quantized_type; +} + #ifdef ARM_COMPUTE_ASSERTS_ENABLED void arm_compute::print_consecutive_elements(std::ostream &s, DataType dt, const uint8_t *ptr, unsigned int n, int stream_width, const std::string &element_delim) { |