aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorVidhya Sudhan Loganathan <vidhyasudhan.loganathan@arm.com>2018-11-16 11:33:12 +0000
committerGeorgios Pinitas <georgios.pinitas@arm.com>2018-11-16 17:37:40 +0000
commita25d16c86f0d870408bc8b941aa755093417b0f0 (patch)
treeb62d145a4e5009d894262a7ffa66cdba8260bb03 /tests
parenta7b54f44e2bf133179f24a34007bc93237dd2265 (diff)
downloadComputeLibrary-a25d16c86f0d870408bc8b941aa755093417b0f0.tar.gz
COMPMID-1266 : Add support for FP16 in CLWinogradConvolutionLayer: 5x5 kernels
Introduced F32 accumulation for F16 winograd gemm and output transform WinogradConvolution will be available for F16 only if fast math flag is enabled Change-Id: I215593c205236a0f9669218437bb40b184ec6a4f
Diffstat (limited to 'tests')
-rw-r--r--tests/SimpleTensor.h39
-rw-r--r--tests/validation/CL/Winograd.cpp21
-rw-r--r--tests/validation/NEON/ConvolutionLayer.cpp2
-rw-r--r--tests/validation/fixtures/WinogradConvolutionLayerFixture.h41
4 files changed, 78 insertions, 25 deletions
diff --git a/tests/SimpleTensor.h b/tests/SimpleTensor.h
index 335ef9130a..dd4a8bee2c 100644
--- a/tests/SimpleTensor.h
+++ b/tests/SimpleTensor.h
@@ -220,6 +220,45 @@ protected:
DataLayout _data_layout{ DataLayout::UNKNOWN };
};
+template <typename T1, typename T2>
+SimpleTensor<T1> copy_tensor(const SimpleTensor<T2> &tensor)
+{
+ SimpleTensor<T1> st(tensor.shape(), tensor.data_type(),
+ tensor.num_channels(),
+ tensor.quantization_info(),
+ tensor.data_layout());
+ for(size_t n = 0; n < size_t(st.num_elements()); n++)
+ {
+ st.data()[n] = static_cast<T1>(tensor.data()[n]);
+ }
+ return st;
+}
+
+template <typename T1, typename T2, typename std::enable_if<std::is_same<T1, T2>::value, int>::type = 0>
+SimpleTensor<T1> copy_tensor(const SimpleTensor<half> &tensor)
+{
+ SimpleTensor<T1> st(tensor.shape(), tensor.data_type(),
+ tensor.num_channels(),
+ tensor.quantization_info(),
+ tensor.data_layout());
+ memcpy((void *)st.data(), (const void *)tensor.data(), size_t(st.num_elements() * sizeof(T1)));
+ return st;
+}
+
+template < typename T1, typename T2, typename std::enable_if < (std::is_same<T1, half>::value || std::is_same<T2, half>::value), int >::type = 0 >
+SimpleTensor<T1> copy_tensor(const SimpleTensor<half> &tensor)
+{
+ SimpleTensor<T1> st(tensor.shape(), tensor.data_type(),
+ tensor.num_channels(),
+ tensor.quantization_info(),
+ tensor.data_layout());
+ for(size_t n = 0; n < size_t(st.num_elements()); n++)
+ {
+ st.data()[n] = half_float::detail::half_cast<T1, T2>(tensor.data()[n]);
+ }
+ return st;
+}
+
template <typename T>
SimpleTensor<T>::SimpleTensor(TensorShape shape, Format format)
: _buffer(nullptr),
diff --git a/tests/validation/CL/Winograd.cpp b/tests/validation/CL/Winograd.cpp
index 930f7aa8ce..f7f06b7f79 100644
--- a/tests/validation/CL/Winograd.cpp
+++ b/tests/validation/CL/Winograd.cpp
@@ -58,6 +58,9 @@ constexpr AbsoluteTolerance<float> tolerance_f32(0.001f);
const AbsoluteTolerance<half> tolerance_f16(half(0.5f));
constexpr AbsoluteTolerance<float> tolerance_convolution_layer_f32(0.1f);
const AbsoluteTolerance<half> tolerance_convolution_layer_f16(half(0.4f));
+RelativeTolerance<half_float::half> rel_tolerance_f16(half(0.2)); /**< Tolerance value for comparing reference's output against implementation's output for FP16 data types */
+constexpr float tolerance_num = 0.05f; /**< Tolerance number */
+constexpr float abs_tolerance_convolution_layer_f16 = 2.5f; /**< Tolerance number */
// Input transform
const auto SmallWinogradInputTransformDatasetNCHW =
@@ -834,10 +837,10 @@ FIXTURE_DATA_TEST_CASE(RunLarge, CLWinogradConvolutionLayerFastMathFixture, fram
TEST_SUITE_END() // Conv1x5
TEST_SUITE_END() // FP32
-#ifdef WINOGRAD_F16_SUPPORT //to be reintroduced after COMPMID-1266 is resolved
+
TEST_SUITE(FP16)
-using CLWinogradConvolutionLayerFastMathFixture16 = WinogradConvolutionLayerFastMathValidationFixture<CLTensor, CLAccessor, CLWinogradConvolutionLayer, half>;
+using CLWinogradConvolutionLayerFastMathFixture16 = WinogradConvolutionLayerFastMathValidationFixture<CLTensor, CLAccessor, CLWinogradConvolutionLayer, half, float>;
TEST_SUITE(Conv3x3)
FIXTURE_DATA_TEST_CASE(RunSmall, CLWinogradConvolutionLayerFastMathFixture16, framework::DatasetMode::PRECOMMIT,
combine(combine(combine(datasets::SmallWinogradConvolutionLayer3x3Dataset(),
@@ -856,7 +859,7 @@ FIXTURE_DATA_TEST_CASE(RunLarge, CLWinogradConvolutionLayerFastMathFixture16, fr
framework::dataset::make("DataLayout", { DataLayout::NCHW, DataLayout::NHWC })))
{
// Validate output
- validate(CLAccessor(_target), _reference, tolerance_convolution_layer_f16);
+ validate(CLAccessor(_target), _reference, rel_tolerance_f16, tolerance_num, abs_tolerance_convolution_layer_f16);
}
TEST_SUITE_END() // Conv3x3
@@ -878,7 +881,7 @@ FIXTURE_DATA_TEST_CASE(RunLarge, CLWinogradConvolutionLayerFastMathFixture16, fr
framework::dataset::make("DataLayout", { DataLayout::NCHW, DataLayout::NHWC })))
{
// Validate output
- validate(CLAccessor(_target), _reference, tolerance_convolution_layer_f16);
+ validate(CLAccessor(_target), _reference, rel_tolerance_f16, tolerance_num, abs_tolerance_convolution_layer_f16);
}
TEST_SUITE_END() // Conv3x1
@@ -900,7 +903,7 @@ FIXTURE_DATA_TEST_CASE(RunLarge, CLWinogradConvolutionLayerFastMathFixture16, fr
framework::dataset::make("DataLayout", { DataLayout::NCHW, DataLayout::NHWC })))
{
// Validate output
- validate(CLAccessor(_target), _reference, tolerance_convolution_layer_f16);
+ validate(CLAccessor(_target), _reference, rel_tolerance_f16, tolerance_num, abs_tolerance_convolution_layer_f16);
}
TEST_SUITE_END() // Conv1x3
@@ -924,7 +927,7 @@ FIXTURE_DATA_TEST_CASE(RunLarge, CLWinogradConvolutionLayerFastMathFixture16, fr
{
// Validate output
- validate(CLAccessor(_target), _reference, tolerance_convolution_layer_f16);
+ validate(CLAccessor(_target), _reference, rel_tolerance_f16, tolerance_num, abs_tolerance_convolution_layer_f16);
}
TEST_SUITE_END() // Conv5x5
@@ -948,7 +951,7 @@ FIXTURE_DATA_TEST_CASE(RunLarge, CLWinogradConvolutionLayerFastMathFixture16, fr
{
// Validate output
- validate(CLAccessor(_target), _reference, tolerance_convolution_layer_f16);
+ validate(CLAccessor(_target), _reference, rel_tolerance_f16, tolerance_num, abs_tolerance_convolution_layer_f16);
}
TEST_SUITE_END() // Conv5x1
@@ -972,12 +975,12 @@ FIXTURE_DATA_TEST_CASE(RunLarge, CLWinogradConvolutionLayerFastMathFixture16, fr
{
// Validate output
- validate(CLAccessor(_target), _reference, tolerance_convolution_layer_f16);
+ validate(CLAccessor(_target), _reference, rel_tolerance_f16, tolerance_num, abs_tolerance_convolution_layer_f16);
}
TEST_SUITE_END() // Conv1x5
TEST_SUITE_END() // FP16
-#endif /*#ifdef WINOGRAD_F16_SUPPORT*/
+
TEST_SUITE_END() // ConvolutionLayer
TEST_SUITE_END() // Winograd
TEST_SUITE_END() // CL
diff --git a/tests/validation/NEON/ConvolutionLayer.cpp b/tests/validation/NEON/ConvolutionLayer.cpp
index d216d9db86..d8710ee91b 100644
--- a/tests/validation/NEON/ConvolutionLayer.cpp
+++ b/tests/validation/NEON/ConvolutionLayer.cpp
@@ -120,7 +120,7 @@ template <typename T>
using NEWinogradConvolutionLayerFixture = WinogradConvolutionLayerFastMathValidationFixture<Tensor, Accessor, NEWinogradConvolutionLayer, T>;
template <typename T>
-using NEWinogradConvolutionLayerNoBiasFixture = WinogradConvolutionLayerFastMathValidationFixture<Tensor, Accessor, NEWinogradConvolutionLayer, T, false>;
+using NEWinogradConvolutionLayerNoBiasFixture = WinogradConvolutionLayerFastMathValidationFixture<Tensor, Accessor, NEWinogradConvolutionLayer, T, T, false>;
TEST_SUITE(FP32)
diff --git a/tests/validation/fixtures/WinogradConvolutionLayerFixture.h b/tests/validation/fixtures/WinogradConvolutionLayerFixture.h
index 15ce201222..9c9e634205 100644
--- a/tests/validation/fixtures/WinogradConvolutionLayerFixture.h
+++ b/tests/validation/fixtures/WinogradConvolutionLayerFixture.h
@@ -39,6 +39,7 @@
#include "tests/validation/reference/Permute.h"
#include "tests/validation/reference/Utils.h"
#include "tests/validation/reference/Winograd.h"
+#include "utils/Utils.h"
#include <random>
@@ -156,7 +157,7 @@ protected:
SimpleTensor<T> _reference{};
};
-template <typename TensorType, typename AccessorType, typename FunctionType, typename T, bool use_bias = true>
+template <typename TensorType, typename AccessorType, typename FunctionType, typename T, typename T1 = T, bool use_bias = true>
class WinogradConvolutionLayerFastMathValidationFixture : public framework::Fixture
{
public:
@@ -177,6 +178,11 @@ protected:
switch(tensor.data_type())
{
case DataType::F16:
+ {
+ arm_compute::utils::uniform_real_distribution_fp16 distribution((half)min, (half)max);
+ library->fill(tensor, distribution, i);
+ break;
+ }
case DataType::F32:
{
std::uniform_real_distribution<> distribution(min, max);
@@ -245,21 +251,25 @@ protected:
DataType data_type, ActivationLayerInfo act_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_t{ input_shape, data_type, 1 };
+ SimpleTensor<T> weights_t{ weights_shape, data_type, 1 };
+ SimpleTensor<T> bias_t{ bias_shape, data_type, 1 };
// Fill reference
- fill(src, 0, -1.f, 1.f);
- fill(weights, 1, -1.f, 1.f);
+ fill(src_t, 0, -1.f, 1.f);
+ SimpleTensor<T1> src_t1(copy_tensor<T1, T>(src_t));
+
+ fill(weights_t, 1, -1.f, 1.f);
+ SimpleTensor<T1> weights_t1(copy_tensor<T1, T>(weights_t));
if(use_bias)
{
- fill(bias, 2, -1.f, 1.f);
+ fill(bias_t, 2, -1.f, 1.f);
}
else
{
- fill(bias, 2, 0.f, 0.f);
+ fill(bias_t, 2, 0.f, 0.f);
}
+ SimpleTensor<T1> bias_t1(copy_tensor<T1, T>(bias_t));
// Set output tile
Size2D output_tile(4U, 4U);
@@ -286,7 +296,7 @@ protected:
Size2D(weights_shape[0], weights_shape[1]),
Size2D(input_shape[0], input_shape[1]),
info,
- src.data_layout());
+ src_t1.data_layout());
// Compute tensor shapes for input, filter and output transforms
TensorShape input_transform_shape = compute_winograd_input_transform_shape(TensorInfo(input_shape, 1, data_type), winograd_info);
@@ -296,15 +306,16 @@ protected:
TensorShape output_transform_shape = compute_winograd_output_transform_shape(TensorInfo(batched_gemm_shape, 1, data_type), winograd_info);
// Dummy matrix C to perform matrix multiplication
- SimpleTensor<T> dummy_c{ batched_gemm_shape, data_type, 1 };
+ SimpleTensor<T1> dummy_c{ batched_gemm_shape, data_type, 1 };
// Compute Winograd-based convolution
- SimpleTensor<T> input_transform_out = reference::winograd_input_transform<T>(src, input_transform_shape, winograd_info);
- SimpleTensor<T> filter_transform_out = reference::winograd_filter_transform<T>(weights, filter_transform_shape, winograd_info);
- SimpleTensor<T> batched_gemm = reference::gemm<T>(input_transform_out, filter_transform_out, dummy_c, 1.0f, 0.0f);
- SimpleTensor<T> conv_out = reference::winograd_output_transform<T>(batched_gemm, bias, output_transform_shape, winograd_info);
+ SimpleTensor<T1> input_transform_out = reference::winograd_input_transform<T1>(src_t1, input_transform_shape, winograd_info);
- return (act_info.enabled()) ? reference::activation_layer<T>(conv_out, act_info) : conv_out;
+ SimpleTensor<T1> filter_transform_out = reference::winograd_filter_transform<T1>(weights_t1, filter_transform_shape, winograd_info);
+ SimpleTensor<T1> batched_gemm = reference::gemm<T1>(input_transform_out, filter_transform_out, dummy_c, 1.0f, 0.0f);
+ SimpleTensor<T1> conv_out = reference::winograd_output_transform<T1>(batched_gemm, bias_t1, output_transform_shape, winograd_info);
+ SimpleTensor<T> conv_out_t(std::move(copy_tensor<T, T1>(conv_out)));
+ return (act_info.enabled()) ? reference::activation_layer<T>(conv_out_t, act_info) : conv_out_t;
}
TensorType _target{};