aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSang-Hoon Park <sang-hoon.park@arm.com>2020-01-09 15:27:51 +0000
committerSang-Hoon Park <sang-hoon.park@arm.com>2020-01-10 11:12:39 +0000
commit5b7fd87b6ab73a7206a45d3621d484131c901143 (patch)
tree27ce6a34e0e4f80de4cfc4aabbd72c43ee58d559
parentdaa3aba64d01fd02fc74d0707d50d2571e5f0ce8 (diff)
downloadComputeLibrary-5b7fd87b6ab73a7206a45d3621d484131c901143.tar.gz
MLCE-139 add align_corners parameter handling to CLScale
Change-Id: I9d6047c306d7928258d5168eb4bfb96b09d2608f Signed-off-by: Sang-Hoon Park <sang-hoon.park@arm.com> Reviewed-on: https://review.mlplatform.org/c/2569 Reviewed-by: Pablo Marquez <pablo.tello@arm.com> Comments-Addressed: Arm Jenkins <bsgcomp@arm.com> Tested-by: Arm Jenkins <bsgcomp@arm.com>
-rw-r--r--arm_compute/core/CL/kernels/CLScaleKernel.h8
-rw-r--r--arm_compute/runtime/CL/functions/CLScale.h4
-rw-r--r--src/core/CL/kernels/CLScaleKernel.cpp62
-rw-r--r--src/runtime/CL/functions/CLScale.cpp8
-rw-r--r--tests/validation/CL/Scale.cpp1
5 files changed, 53 insertions, 30 deletions
diff --git a/arm_compute/core/CL/kernels/CLScaleKernel.h b/arm_compute/core/CL/kernels/CLScaleKernel.h
index 7d9ed41305..f93286b07d 100644
--- a/arm_compute/core/CL/kernels/CLScaleKernel.h
+++ b/arm_compute/core/CL/kernels/CLScaleKernel.h
@@ -43,8 +43,9 @@ public:
* @param[in] policy Interpolation type to use
* @param[in] border_mode Selected border mode.
* @param[in] sampling_policy (Optional) Sampling policy used by the interpolation. Defaults to @ref SamplingPolicy::CENTER
+ * @param[in] align_corners (Optional) Align corners of input and output, only affecting bilinear policy with TOP_LEFT sampling policy. Defaults to false.
*/
- void configure(const ICLTensor *input, ICLTensor *output, InterpolationPolicy policy, BorderMode border_mode, SamplingPolicy sampling_policy = SamplingPolicy::CENTER);
+ void configure(const ICLTensor *input, ICLTensor *output, InterpolationPolicy policy, BorderMode border_mode, SamplingPolicy sampling_policy = SamplingPolicy::CENTER, bool align_corners = false);
/** Static function to check if given info will lead to a valid configuration of @ref CLScaleKernel
*
@@ -54,10 +55,12 @@ public:
* @param[in] policy Interpolation type to use
* @param[in] border_mode Selected border mode.
* @param[in] sampling_policy (Optional) Sampling policy used by the interpolation. Defaults to @ref SamplingPolicy::CENTER
+ * @param[in] align_corners (Optional) Align corners of input and output, only affecting bilinear policy with TOP_LEFT sampling policy. Defaults to false.
*
* @return a status
*/
- static Status validate(const ITensorInfo *input, const ITensorInfo *output, InterpolationPolicy policy, BorderMode border_mode, SamplingPolicy sampling_policy = SamplingPolicy::CENTER);
+ static Status validate(const ITensorInfo *input, const ITensorInfo *output, InterpolationPolicy policy, BorderMode border_mode, SamplingPolicy sampling_policy = SamplingPolicy::CENTER,
+ bool align_corners = false);
/** Input tensor accessor.
*
* @return Pointer to input tensor.
@@ -76,6 +79,7 @@ public:
public:
InterpolationPolicy _interpolationPolicy = InterpolationPolicy::BILINEAR;
DataLayout _data_layout = DataLayout::UNKNOWN;
+ bool _align_corners = false;
};
} // namespace arm_compute
#endif /*ARM_COMPUTE_CLSCALEKERNEL_H */
diff --git a/arm_compute/runtime/CL/functions/CLScale.h b/arm_compute/runtime/CL/functions/CLScale.h
index 9a201dc10f..c06c9b629a 100644
--- a/arm_compute/runtime/CL/functions/CLScale.h
+++ b/arm_compute/runtime/CL/functions/CLScale.h
@@ -47,7 +47,7 @@ public:
* @param[in] constant_border_value (Optional) Constant value to use for borders if border_mode is set to CONSTANT.
* @param[in] sampling_policy (Optional) Sampling policy used by the interpolation. Defaults to @ref SamplingPolicy::CENTER
* @param[in] use_padding (Optional) Is padding in use or not. Defaults to true.
- * @param[in] align_corners (Optional) Align corners of input and output, only affecting bilinear policy. Defaults to false.
+ * @param[in] align_corners (Optional) Align corners of input and output, only affecting bilinear policy with TOP_LEFT sampling policy. Defaults to false.
*/
void configure(ICLTensor *input, ICLTensor *output, InterpolationPolicy policy, BorderMode border_mode, PixelValue constant_border_value = PixelValue(),
SamplingPolicy sampling_policy = SamplingPolicy::CENTER, bool use_padding = true, bool align_corners = false);
@@ -62,7 +62,7 @@ public:
* @param[in] constant_border_value (Optional) Constant value to use for borders if border_mode is set to CONSTANT.
* @param[in] sampling_policy (Optional) Sampling policy used by the interpolation. Defaults to @ref SamplingPolicy::CENTER
* @param[in] use_padding (Optional) Is padding in use or not. Defaults to true.
- * @param[in] align_corners (Optional) Align corners of input and output, only affecting bilinear policy. Defaults to false.
+ * @param[in] align_corners (Optional) Align corners of input and output, only affecting bilinear policy with TOP_LEFT sampling policy. Defaults to false.
*
* @return a status
*/
diff --git a/src/core/CL/kernels/CLScaleKernel.cpp b/src/core/CL/kernels/CLScaleKernel.cpp
index a427c79b65..38e07036d0 100644
--- a/src/core/CL/kernels/CLScaleKernel.cpp
+++ b/src/core/CL/kernels/CLScaleKernel.cpp
@@ -41,7 +41,7 @@ using namespace arm_compute;
namespace
{
-inline std::pair<float, float> calculate_scale_factors(const ITensorInfo &input, const ITensorInfo &output)
+inline std::pair<float, float> calculate_scale_factors(const ITensorInfo &input, const ITensorInfo &output, bool align_corners)
{
DataLayout data_layout = input.data_layout();
const int idx_width = get_data_layout_dimension_index(data_layout, DataLayoutDimension::WIDTH);
@@ -53,13 +53,13 @@ inline std::pair<float, float> calculate_scale_factors(const ITensorInfo &input,
const unsigned int output_width = output.dimension(idx_width);
const unsigned int output_height = output.dimension(idx_height);
- float wr = static_cast<float>(input_width) / static_cast<float>(output_width);
- float hr = static_cast<float>(input_height) / static_cast<float>(output_height);
+ float wr = arm_compute::calculate_resize_ratio(input_width, output_width, align_corners);
+ float hr = arm_compute::calculate_resize_ratio(input_height, output_height, align_corners);
return std::make_pair(wr, hr);
}
-Status validate_arguments(const ITensorInfo *input, const ITensorInfo *output, InterpolationPolicy policy)
+Status validate_arguments(const ITensorInfo *input, const ITensorInfo *output, InterpolationPolicy policy, bool align_corners)
{
ARM_COMPUTE_RETURN_ERROR_ON_F16_UNSUPPORTED(input);
ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(input, 1, DataType::QASYMM8, DataType::QASYMM8_SIGNED, DataType::U8, DataType::S16, DataType::F16, DataType::F32);
@@ -68,9 +68,27 @@ Status validate_arguments(const ITensorInfo *input, const ITensorInfo *output, I
ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_QUANTIZATION_INFO(input, output);
ARM_COMPUTE_RETURN_ERROR_ON(output == input);
+ if(align_corners)
+ {
+ // For bilinear method with aligned corners, the resize ratio will
+ // be calculated by (input_size - 1)/(output_size - 1). Belows are
+ // checking possible overflows.
+ const auto data_layout = input->data_layout();
+ const auto width_index = get_data_layout_dimension_index(data_layout, DataLayoutDimension::WIDTH);
+ const auto height_index = get_data_layout_dimension_index(data_layout, DataLayoutDimension::HEIGHT);
+
+ const auto input_width = input->dimension(width_index);
+ const auto input_height = input->dimension(height_index);
+ const auto output_width = output->dimension(width_index);
+ const auto output_height = output->dimension(height_index);
+
+ ARM_COMPUTE_RETURN_ERROR_ON(input_width == 0 || input_height == 0 || output_width == 0 || output_height == 0);
+ ARM_COMPUTE_RETURN_ERROR_ON((output_width - 1 == 0) || (output_height - 1 == 0));
+ }
+
float wr = 0.f;
float hr = 0.f;
- std::tie(wr, hr) = calculate_scale_factors(*input, *output);
+ std::tie(wr, hr) = calculate_scale_factors(*input, *output, align_corners);
ARM_COMPUTE_RETURN_ERROR_ON(policy == InterpolationPolicy::AREA && (wr > 1.f || hr > 1.f));
@@ -139,10 +157,13 @@ BorderSize CLScaleKernel::border_size() const
}
Status CLScaleKernel::validate(const ITensorInfo *input, const ITensorInfo *output, InterpolationPolicy policy,
- BorderMode border_mode, SamplingPolicy sampling_policy)
+ BorderMode border_mode, SamplingPolicy sampling_policy, bool align_corners)
{
- BorderSize border = BorderSize(1);
- ARM_COMPUTE_RETURN_ON_ERROR(validate_arguments(input, output, policy));
+ BorderSize border = BorderSize(1);
+ const bool is_align_corners = policy == InterpolationPolicy::BILINEAR
+ && sampling_policy == SamplingPolicy::TOP_LEFT
+ && align_corners;
+ ARM_COMPUTE_RETURN_ON_ERROR(validate_arguments(input, output, policy, is_align_corners));
ARM_COMPUTE_RETURN_ON_ERROR(validate_and_configure_window(input->clone().get(), output->clone().get(), policy, border_mode, sampling_policy, border).first);
return Status{};
@@ -158,9 +179,13 @@ const ICLTensor *CLScaleKernel::output() const
return _output;
}
-void CLScaleKernel::configure(const ICLTensor *input, ICLTensor *output, InterpolationPolicy policy, BorderMode border_mode, SamplingPolicy sampling_policy)
+void CLScaleKernel::configure(const ICLTensor *input, ICLTensor *output, InterpolationPolicy policy, BorderMode border_mode, SamplingPolicy sampling_policy, bool align_corners)
{
- ARM_COMPUTE_ERROR_THROW_ON(validate_arguments(input->info(), output->info(), policy));
+ _align_corners = policy == InterpolationPolicy::BILINEAR
+ && sampling_policy == SamplingPolicy::TOP_LEFT
+ && align_corners;
+
+ ARM_COMPUTE_ERROR_THROW_ON(validate_arguments(input->info(), output->info(), policy, _align_corners));
_input = input;
_output = output;
@@ -169,7 +194,7 @@ void CLScaleKernel::configure(const ICLTensor *input, ICLTensor *output, Interpo
float wr = 0.f;
float hr = 0.f;
- std::tie(wr, hr) = calculate_scale_factors(*input->info(), *output->info());
+ std::tie(wr, hr) = calculate_scale_factors(*input->info(), *output->info(), _align_corners);
const bool call_quantized_kernel = is_data_type_quantized_asymmetric(input->info()->data_type()) && policy == InterpolationPolicy::BILINEAR;
@@ -177,12 +202,6 @@ void CLScaleKernel::configure(const ICLTensor *input, ICLTensor *output, Interpo
const int idx_height = get_data_layout_dimension_index(_data_layout, DataLayoutDimension::HEIGHT);
const bool is_nhwc = _data_layout == DataLayout::NHWC;
- // Compute the ratio between source width/height and destination width/height
- const unsigned int input_width = input->info()->dimension(idx_width);
- const unsigned int input_height = input->info()->dimension(idx_height);
- const unsigned int output_width = output->info()->dimension(idx_width);
- const unsigned int output_height = output->info()->dimension(idx_height);
-
// Compute actual border size
BorderSize border = border_size();
@@ -220,14 +239,13 @@ void CLScaleKernel::configure(const ICLTensor *input, ICLTensor *output, Interpo
unsigned int idx = is_nhwc ? 2 * num_arguments_per_4D_tensor() : 2 * num_arguments_per_2D_tensor(); //Skip the input and output parameters
- // Set static kernel arguments
- const float scale_x = static_cast<float>(input_width) / output_width;
- const float scale_y = static_cast<float>(input_height) / output_height;
+ const unsigned int input_width = input->info()->dimension(idx_width);
+ const unsigned int input_height = input->info()->dimension(idx_height);
_kernel.setArg<float>(idx++, input_width);
_kernel.setArg<float>(idx++, input_height);
- _kernel.setArg<float>(idx++, scale_x);
- _kernel.setArg<float>(idx++, scale_y);
+ _kernel.setArg<float>(idx++, wr);
+ _kernel.setArg<float>(idx++, hr);
// Set config_id for enabling LWS tuning
_config_id = "scale_";
diff --git a/src/runtime/CL/functions/CLScale.cpp b/src/runtime/CL/functions/CLScale.cpp
index 39d992739c..a3559158a5 100644
--- a/src/runtime/CL/functions/CLScale.cpp
+++ b/src/runtime/CL/functions/CLScale.cpp
@@ -35,10 +35,10 @@ using namespace arm_compute;
void CLScale::configure(ICLTensor *input, ICLTensor *output, InterpolationPolicy policy, BorderMode border_mode, PixelValue constant_border_value, SamplingPolicy sampling_policy, bool use_padding,
bool align_corners)
{
- ARM_COMPUTE_UNUSED(use_padding, align_corners);
+ ARM_COMPUTE_UNUSED(use_padding);
auto k = arm_compute::support::cpp14::make_unique<CLScaleKernel>();
k->set_target(CLScheduler::get().target());
- k->configure(input, output, policy, border_mode, sampling_policy);
+ k->configure(input, output, policy, border_mode, sampling_policy, align_corners);
_kernel = std::move(k);
// Tune kernels
@@ -56,6 +56,6 @@ void CLScale::configure(ICLTensor *input, ICLTensor *output, InterpolationPolicy
Status CLScale::validate(const ITensorInfo *input, const ITensorInfo *output, InterpolationPolicy policy, BorderMode border_mode, PixelValue constant_border_value, SamplingPolicy sampling_policy,
bool use_padding, bool align_corners)
{
- ARM_COMPUTE_UNUSED(constant_border_value, use_padding, align_corners);
- return CLScaleKernel::validate(input, output, policy, border_mode, sampling_policy);
+ ARM_COMPUTE_UNUSED(constant_border_value, use_padding);
+ return CLScaleKernel::validate(input, output, policy, border_mode, sampling_policy, align_corners);
}
diff --git a/tests/validation/CL/Scale.cpp b/tests/validation/CL/Scale.cpp
index c03571ca02..848656a8d1 100644
--- a/tests/validation/CL/Scale.cpp
+++ b/tests/validation/CL/Scale.cpp
@@ -59,6 +59,7 @@ const auto ScaleDataTypes = framework::dataset::make("DataType",
const auto AlignCorners = framework::dataset::make("AlignCorners",
{
false,
+ true,
});
/** Tolerance */