aboutsummaryrefslogtreecommitdiff
path: root/tests/validation
diff options
context:
space:
mode:
authorMichele Di Giorgio <michele.digiorgio@arm.com>2018-07-06 18:06:58 +0100
committerAnthony Barbier <anthony.barbier@arm.com>2018-11-02 16:54:54 +0000
commit9fef38ac706aac6ff194fb76e92dcc774e12e115 (patch)
tree1621077931d2db239c93575db6991ad61ac3a1c8 /tests/validation
parent72ccc440b5312160ede96f9c27c747965a5b08bf (diff)
downloadComputeLibrary-9fef38ac706aac6ff194fb76e92dcc774e12e115.tar.gz
COMPMID-1376: Add support for QASYMM8 in CLDeconvolutionLayer
Change-Id: I13ec79b6668e2b9559d3fa789ae0b51ab6975289 Reviewed-on: https://eu-gerrit-1.euhpc.arm.com/139126 Reviewed-by: Michalis Spyrou <michalis.spyrou@arm.com> Tested-by: Jenkins <bsgcomp@arm.com>
Diffstat (limited to 'tests/validation')
-rw-r--r--tests/validation/CL/DeconvolutionLayer.cpp53
-rw-r--r--tests/validation/fixtures/DeconvolutionLayerFixture.h79
-rw-r--r--tests/validation/reference/ConvolutionLayer.cpp2
-rw-r--r--tests/validation/reference/DeconvolutionLayer.cpp17
-rw-r--r--tests/validation/reference/DeconvolutionLayer.h6
5 files changed, 119 insertions, 38 deletions
diff --git a/tests/validation/CL/DeconvolutionLayer.cpp b/tests/validation/CL/DeconvolutionLayer.cpp
index 0fd7ed4ddc..5d10073641 100644
--- a/tests/validation/CL/DeconvolutionLayer.cpp
+++ b/tests/validation/CL/DeconvolutionLayer.cpp
@@ -45,6 +45,7 @@ namespace
{
constexpr AbsoluteTolerance<float> tolerance_fp32(0.001f); /**< Tolerance for floating point tests */
RelativeTolerance<half_float::half> tolerance_f16(half_float::half(0.2)); /**< Tolerance value for comparing reference's for DataType::F16 */
+constexpr AbsoluteTolerance<float> tolerance_qasymm8(1.0); /**< Tolerance value for comparing reference's output against implementation's output for quantized data types */
constexpr float tolerance_num = 0.07f; /**< Tolerance number */
const auto data4x4 = datasets::SmallDeconvolutionShapes() * framework::dataset::make("StrideX", 1, 4) * framework::dataset::make("StrideY", 1, 4) * framework::dataset::make("PadX", 0, 3)
@@ -105,28 +106,25 @@ DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, (combine(datasets::Sm
DATA_TEST_CASE(Validate, framework::DatasetMode::ALL, zip(zip(zip(zip(zip(zip(zip(
framework::dataset::make("InputInfo", { TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::F32), // Mismatching data type
TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::F32), // Invalid weights shape
- TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::QASYMM8), // Non supported data type
TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::F32), // Invalid bias shape
TensorInfo(TensorShape(13U, 11U, 4U, 3U), 1, DataType::F32), // Window shrink
TensorInfo(TensorShape(32U, 16U, 2U), 1, DataType::F32),
}),
framework::dataset::make("WeightsInfo", { TensorInfo(TensorShape(3U, 3U, 2U, 2U), 1, DataType::F16),
TensorInfo(TensorShape(3U, 3U, 2U, 4U), 1, DataType::F32),
- TensorInfo(TensorShape(3U, 3U, 2U, 2U), 1, DataType::QASYMM8),
TensorInfo(TensorShape(3U, 2U, 2U, 2U), 1, DataType::F32),
TensorInfo(TensorShape(3U, 3U, 4U), 1, DataType::F32),
TensorInfo(TensorShape(1U, 1U, 2U, 4U), 1, DataType::F32),
})),
framework::dataset::make("BiasInfo", { TensorInfo(TensorShape(1U), 1, DataType::F16),
TensorInfo(TensorShape(1U), 1, DataType::F32),
- TensorInfo(TensorShape(1U), 1, DataType::F32),
TensorInfo(TensorShape(25U, 11U), 1, DataType::F32),
TensorInfo(TensorShape(1U), 1, DataType::F32),
TensorInfo(TensorShape(4U), 1, DataType::F32),
+ TensorInfo(TensorShape(4U), 1, DataType::S32),
})),
framework::dataset::make("OutputInfo",{ TensorInfo(TensorShape(25U, 11U, 2U), 1, DataType::F16),
TensorInfo(TensorShape(25U, 10U, 2U), 1, DataType::F32),
- TensorInfo(TensorShape(25U, 11U, 2U), 1, DataType::F32),
TensorInfo(TensorShape(13U, 13U, 2U), 1, DataType::F32),
TensorInfo(TensorShape(11U, 9U, 1U, 3U), 1, DataType::F32),
TensorInfo(TensorShape(32U, 16U, 4U), 1, DataType::F32),
@@ -134,25 +132,22 @@ DATA_TEST_CASE(Validate, framework::DatasetMode::ALL, zip(zip(zip(zip(zip(zip(zi
framework::dataset::make("PadStrideInfo", { PadStrideInfo(1, 1, 0, 0),
PadStrideInfo(1, 1, 0, 0),
PadStrideInfo(1, 1, 0, 0),
- PadStrideInfo(1, 1, 0, 0),
PadStrideInfo(1, 1, 1, 1),
PadStrideInfo(1, 1, 0, 0),
})),
framework::dataset::make("ax", { 1U,
1U,
1U,
- 1U,
0U,
0U,
})),
framework::dataset::make("ay", { 1U,
1U,
1U,
- 1U,
0U,
0U,
})),
- framework::dataset::make("Expected", { false, false, false, false, false, true })),
+ framework::dataset::make("Expected", { false, false, false, false, true })),
input_info, weights_info, bias_info, output_info, pad_info, ax, ay, expected)
{
bool is_valid = bool(CLDeconvolutionLayer::validate(&input_info.clone()->set_is_resizable(false), &weights_info.clone()->set_is_resizable(false), &bias_info.clone()->set_is_resizable(false), &output_info.clone()->set_is_resizable(false), pad_info, ax, ay));
@@ -228,6 +223,48 @@ TEST_SUITE_END()
TEST_SUITE_END()
TEST_SUITE_END()
+template <typename T>
+using CLDeconvolutionLayerQuantizedFixture4x4 = DeconvolutionValidationQuantizedFixture<CLTensor, CLAccessor, CLDeconvolutionLayer, T, 4, 4>;
+
+template <typename T>
+using CLDeconvolutionLayerQuantizedFixture3x3 = DeconvolutionValidationQuantizedFixture<CLTensor, CLAccessor, CLDeconvolutionLayer, T, 3, 3>;
+
+template <typename T>
+using CLDeconvolutionLayerQuantizedFixture1x1 = DeconvolutionValidationQuantizedFixture<CLTensor, CLAccessor, CLDeconvolutionLayer, T, 1, 1>;
+
+TEST_SUITE(Quantized)
+TEST_SUITE(QASYMM8)
+
+TEST_SUITE(W4x4)
+FIXTURE_DATA_TEST_CASE(Run, CLDeconvolutionLayerQuantizedFixture4x4<uint8_t>, framework::DatasetMode::ALL, combine(combine(data4x4, framework::dataset::make("DataType", DataType::QASYMM8)),
+ framework::dataset::make("QuantizationInfo", QuantizationInfo(2.f / 255.f, 127))))
+{
+ // Validate output
+ validate(CLAccessor(_target), _reference, tolerance_qasymm8, tolerance_num);
+}
+TEST_SUITE_END()
+
+TEST_SUITE(W3x3)
+FIXTURE_DATA_TEST_CASE(Run, CLDeconvolutionLayerQuantizedFixture3x3<uint8_t>, framework::DatasetMode::ALL, combine(combine(data3x3, framework::dataset::make("DataType", DataType::QASYMM8)),
+ framework::dataset::make("QuantizationInfo", QuantizationInfo(2.f / 255.f, 127))))
+{
+ // Validate output
+ validate(CLAccessor(_target), _reference, tolerance_qasymm8, tolerance_num);
+}
+TEST_SUITE_END()
+
+TEST_SUITE(W1x1)
+FIXTURE_DATA_TEST_CASE(Run, CLDeconvolutionLayerQuantizedFixture1x1<uint8_t>, framework::DatasetMode::ALL, combine(combine(data1x1, framework::dataset::make("DataType", DataType::QASYMM8)),
+ framework::dataset::make("QuantizationInfo", QuantizationInfo(2.f / 255.f, 127))))
+{
+ // Validate output
+ validate(CLAccessor(_target), _reference, tolerance_qasymm8, tolerance_num);
+}
+TEST_SUITE_END()
+
+TEST_SUITE_END()
+TEST_SUITE_END()
+
TEST_SUITE_END()
TEST_SUITE_END()
} // namespace validation
diff --git a/tests/validation/fixtures/DeconvolutionLayerFixture.h b/tests/validation/fixtures/DeconvolutionLayerFixture.h
index 12ce9cefc7..7741557f48 100644
--- a/tests/validation/fixtures/DeconvolutionLayerFixture.h
+++ b/tests/validation/fixtures/DeconvolutionLayerFixture.h
@@ -43,39 +43,57 @@ template <typename TensorType, typename AccessorType, typename FunctionType, typ
class DeconvolutionLayerFixtureBase : public framework::Fixture
{
public:
+ using TBias = typename std::conditional<std::is_same<typename std::decay<T>::type, uint8_t>::value, int32_t, T>::type;
+
+public:
template <typename...>
void setup(TensorShape input_shape, TensorShape weights_shape, TensorShape bias_shape, TensorShape output_shape, PadStrideInfo info,
- const std::pair<unsigned int, unsigned int> &inner_border, DataType data_type)
+ const std::pair<unsigned int, unsigned int> &inner_border, DataType data_type, QuantizationInfo quantization_info)
{
_data_type = data_type;
- _target = compute_target(input_shape, weights_shape, bias_shape, output_shape, info, inner_border, data_type);
- _reference = compute_reference(input_shape, weights_shape, bias_shape, output_shape, info, inner_border, data_type);
+ _target = compute_target(input_shape, weights_shape, bias_shape, output_shape, info, inner_border, data_type, quantization_info);
+ _reference = compute_reference(input_shape, weights_shape, bias_shape, output_shape, info, inner_border, data_type, quantization_info);
}
protected:
template <typename U>
void fill(U &&tensor, int i)
{
- if(is_data_type_float(tensor.data_type()))
+ switch(tensor.data_type())
{
- std::uniform_real_distribution<> distribution(-1.0f, 1.0f);
- library->fill(tensor, distribution, i);
- }
- else
- {
- library->fill_tensor_uniform(tensor, i);
+ case DataType::QASYMM8:
+ {
+ std::uniform_int_distribution<uint8_t> distribution(0, 255);
+ library->fill(tensor, distribution, i);
+ break;
+ }
+ case DataType::S32:
+ {
+ std::uniform_int_distribution<int32_t> distribution(-100, 100);
+ library->fill(tensor, distribution, i);
+ break;
+ }
+ case DataType::F16:
+ case DataType::F32:
+ {
+ std::uniform_real_distribution<> distribution(-1.0f, 1.0f);
+ library->fill(tensor, distribution, i);
+ break;
+ }
+ default:
+ library->fill_tensor_uniform(tensor, i);
}
}
TensorType compute_target(const TensorShape &input_shape, const TensorShape &weights_shape, const TensorShape &bias_shape, const TensorShape &output_shape,
- const PadStrideInfo &info, const std::pair<unsigned int, unsigned int> &inner_border, DataType data_type)
+ const PadStrideInfo &info, const std::pair<unsigned int, unsigned int> &inner_border, DataType data_type, QuantizationInfo quantization_info)
{
// Create tensors
- TensorType src = create_tensor<TensorType>(input_shape, data_type, 1);
- TensorType weights = create_tensor<TensorType>(weights_shape, data_type, 1);
- TensorType bias = create_tensor<TensorType>(bias_shape, data_type, 1);
- TensorType dst = create_tensor<TensorType>(output_shape, data_type, 1);
+ TensorType src = create_tensor<TensorType>(input_shape, data_type, 1, quantization_info);
+ TensorType weights = create_tensor<TensorType>(weights_shape, data_type, 1, quantization_info);
+ TensorType bias = create_tensor<TensorType>(bias_shape, is_data_type_quantized_asymmetric(data_type) ? DataType::S32 : data_type, 1, quantization_info);
+ TensorType dst = create_tensor<TensorType>(output_shape, data_type, 1, quantization_info);
// Create and configure function
FunctionType conv;
@@ -102,19 +120,19 @@ protected:
fill(AccessorType(weights), 1);
fill(AccessorType(bias), 2);
- // Compute NEConvolutionLayer function
+ // Compute DeconvolutionLayer function
conv.run();
return dst;
}
SimpleTensor<T> compute_reference(const TensorShape &input_shape, const TensorShape &weights_shape, const TensorShape &bias_shape, const TensorShape &output_shape,
- const PadStrideInfo &info, const std::pair<unsigned int, unsigned int> inner_border, DataType data_type)
+ const PadStrideInfo &info, const std::pair<unsigned int, unsigned int> inner_border, DataType data_type, QuantizationInfo quantization_info)
{
// Create reference
- SimpleTensor<T> src{ input_shape, data_type, 1 };
- SimpleTensor<T> weights{ weights_shape, data_type, 1 };
- SimpleTensor<T> bias{ bias_shape, data_type, 1 };
+ SimpleTensor<T> src{ input_shape, data_type, 1, quantization_info };
+ SimpleTensor<T> weights{ weights_shape, data_type, 1, quantization_info };
+ SimpleTensor<TBias> bias{ bias_shape, data_type, 1, quantization_info };
// Fill reference
fill(src, 0);
@@ -144,7 +162,26 @@ public:
const std::pair<unsigned int, unsigned int> inner_border(inner_border_right, inner_border_top);
auto out_dim = deconvolution_output_dimensions(input_shape.x(), input_shape.y(), kernel_size_x, kernel_size_y, padx, pady, inner_border.first, inner_border.second, sx, sy);
TensorShape output_shape = deconvolution_output_shape(out_dim, input_shape, weights_shape);
- DeconvolutionLayerFixtureBase<TensorType, AccessorType, FunctionType, T>::setup(input_shape, weights_shape, bias_shape, output_shape, info, inner_border, data_type);
+ DeconvolutionLayerFixtureBase<TensorType, AccessorType, FunctionType, T>::setup(input_shape, weights_shape, bias_shape, output_shape, info, inner_border, data_type, QuantizationInfo());
+ }
+};
+
+template <typename TensorType, typename AccessorType, typename FunctionType, typename T, unsigned int kernel_size_x, unsigned int kernel_size_y>
+class DeconvolutionValidationQuantizedFixture : public DeconvolutionLayerFixtureBase<TensorType, AccessorType, FunctionType, T>
+{
+public:
+ template <typename...>
+ void setup(TensorShape input_shape, unsigned int sx, unsigned int sy, unsigned int padx, unsigned int pady,
+ unsigned int inner_border_right, unsigned int inner_border_top, unsigned int num_kernels, DataType data_type, QuantizationInfo quantization_info)
+ {
+ ARM_COMPUTE_ERROR_ON_MSG(kernel_size_x != kernel_size_y, "Only square kernels supported");
+ const TensorShape weights_shape(kernel_size_x, kernel_size_y, input_shape.z(), num_kernels);
+ const TensorShape bias_shape(num_kernels);
+ const PadStrideInfo info(sx, sy, padx, pady, DimensionRoundingType::CEIL);
+ const std::pair<unsigned int, unsigned int> inner_border(inner_border_right, inner_border_top);
+ auto out_dim = deconvolution_output_dimensions(input_shape.x(), input_shape.y(), kernel_size_x, kernel_size_y, padx, pady, inner_border.first, inner_border.second, sx, sy);
+ TensorShape output_shape = deconvolution_output_shape(out_dim, input_shape, weights_shape);
+ DeconvolutionLayerFixtureBase<TensorType, AccessorType, FunctionType, T>::setup(input_shape, weights_shape, bias_shape, output_shape, info, inner_border, data_type, quantization_info);
}
};
diff --git a/tests/validation/reference/ConvolutionLayer.cpp b/tests/validation/reference/ConvolutionLayer.cpp
index e212e2742f..2d314059dd 100644
--- a/tests/validation/reference/ConvolutionLayer.cpp
+++ b/tests/validation/reference/ConvolutionLayer.cpp
@@ -132,4 +132,4 @@ template SimpleTensor<uint8_t> convolution_layer(const SimpleTensor<uint8_t> &sr
} // namespace reference
} // namespace validation
} // namespace test
-} // namespace arm_compute \ No newline at end of file
+} // namespace arm_compute
diff --git a/tests/validation/reference/DeconvolutionLayer.cpp b/tests/validation/reference/DeconvolutionLayer.cpp
index e73023e419..ba28b46d3a 100644
--- a/tests/validation/reference/DeconvolutionLayer.cpp
+++ b/tests/validation/reference/DeconvolutionLayer.cpp
@@ -33,8 +33,8 @@ namespace validation
{
namespace reference
{
-template <typename T>
-SimpleTensor<T> deconvolution_layer(const SimpleTensor<T> &src, const SimpleTensor<T> &weights, const SimpleTensor<T> &bias, const TensorShape &output_shape,
+template <typename T, typename TB>
+SimpleTensor<T> deconvolution_layer(const SimpleTensor<T> &src, const SimpleTensor<T> &weights, const SimpleTensor<TB> &bias, const TensorShape &output_shape,
const PadStrideInfo &info, const std::pair<unsigned int, unsigned int> &a)
{
// Create reference
@@ -45,7 +45,7 @@ SimpleTensor<T> deconvolution_layer(const SimpleTensor<T> &src, const SimpleTens
int out_y = src.shape().y() + (src.shape().y() - 1) * (stride_y - 1) + a.second + 2 * info.pad().second;
scaled_shape.set(0, out_x);
scaled_shape.set(1, out_y);
- SimpleTensor<T> scaled{ scaled_shape, src.data_type(), 1 };
+ SimpleTensor<T> scaled{ scaled_shape, src.data_type(), 1, src.quantization_info() };
const int width_in = src.shape().x();
const int height_in = src.shape().y();
@@ -59,9 +59,14 @@ SimpleTensor<T> deconvolution_layer(const SimpleTensor<T> &src, const SimpleTens
ARM_COMPUTE_ERROR_ON_MSG(ax > stride_x - 1, "ax must be smaller than stride_x");
ARM_COMPUTE_ERROR_ON_MSG(ay > stride_y - 1, "ay must be smaller than stride_y");
- for(int j = 0; j < scaled.num_elements(); ++j)
+ if(src.data_type() == DataType::QASYMM8)
{
- scaled[j] = T(0);
+ const uint8_t quantized_zero = src.quantization_info().offset;
+ std::fill_n(scaled.data(), scaled.num_elements(), quantized_zero);
+ }
+ else
+ {
+ std::fill_n(scaled.data(), scaled.num_elements(), T(0));
}
for(int slice = 0; slice < num_2d_slices; ++slice)
@@ -88,6 +93,8 @@ SimpleTensor<T> deconvolution_layer(const SimpleTensor<T> &src, const SimpleTens
return convolution_layer(scaled, weights, bias, output_shape, conv_info);
}
+template SimpleTensor<uint8_t> deconvolution_layer(const SimpleTensor<uint8_t> &src, const SimpleTensor<uint8_t> &weights, const SimpleTensor<int32_t> &bias, const TensorShape &output_shape,
+ const PadStrideInfo &info, const std::pair<unsigned int, unsigned int> &a);
template SimpleTensor<float> deconvolution_layer(const SimpleTensor<float> &src, const SimpleTensor<float> &weights, const SimpleTensor<float> &bias, const TensorShape &output_shape,
const PadStrideInfo &info, const std::pair<unsigned int, unsigned int> &a);
template SimpleTensor<half> deconvolution_layer(const SimpleTensor<half> &src, const SimpleTensor<half> &weights, const SimpleTensor<half> &bias, const TensorShape &output_shape,
diff --git a/tests/validation/reference/DeconvolutionLayer.h b/tests/validation/reference/DeconvolutionLayer.h
index c0bc1fa928..95fb416b30 100644
--- a/tests/validation/reference/DeconvolutionLayer.h
+++ b/tests/validation/reference/DeconvolutionLayer.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2018 ARM Limited.
+ * Copyright (c) 2017-2018 ARM Limited.
*
* SPDX-License-Identifier: MIT
*
@@ -45,8 +45,8 @@ namespace reference
* a The number of zeros added to right and top edges of the input.
*
*/
-template <typename T>
-SimpleTensor<T> deconvolution_layer(const SimpleTensor<T> &src, const SimpleTensor<T> &weights, const SimpleTensor<T> &bias, const TensorShape &output_shape, const PadStrideInfo &info,
+template <typename T, typename TB>
+SimpleTensor<T> deconvolution_layer(const SimpleTensor<T> &src, const SimpleTensor<T> &weights, const SimpleTensor<TB> &bias, const TensorShape &output_shape, const PadStrideInfo &info,
const std::pair<unsigned int, unsigned int> &a);
} // namespace reference
} // namespace validation